Parallel rotate

Feb 21, 2015 at 11:36 AM
Hi all,
Finally managed to paralleliize the Rotate function by expressing the destination index in terms of x, y, h and w of the source. Here’s the codes:
public static WriteableBitmap Rotate(this WriteableBitmap bmp, int angle)
  {          
      using (var context = bmp.GetBitmapContext())
     {
        // Use refs for faster access (really important!) speeds up a lot!
        var w = context.Width;
        var h = context.Height;
        var p = context.Pixels;
        //var i = 0;
        WriteableBitmap result = null;
        //angle %= 360;

        if (angle == 90) //90CW
        {
           result = BitmapFactory.New(h, w);
           using (var destContext = result.GetBitmapContext())
           {
              var rp = destContext.Pixels;
              //for (var x = 0; x < w; x++)
               Parallel.For(0, w, x=>
              {
                 //for (var y = h - 1; y >= 0; y--)                                            
                  Parallel.For(0, h, y=>
                 {
                     var srcInd = y * w + x;
                     var DestId = h - 1 - y + h * x;
                     rp[DestId] = p[srcInd];
                     //i++;
                 });
              });
           }
        }
        if (angle == 180)
        {
           result = BitmapFactory.New(w, h);
           using (var destContext = result.GetBitmapContext())
           {
              var rp = destContext.Pixels;
              //for (var y = h - 1; y >= 0; y--)
              Parallel.For(0, h, y=>
             {
                 //for (var x = w - 1; x >= 0; x--)                     
                 Parallel.For(0, w, x=>
                 {
                     var srcInd = y * w + x;
                     var DestId = w - 1 - x + w * (h - 1 - y);
                     rp[DestId] = p[srcInd];
                     //i++;
                 });
             });
           }
        }
        if (angle == 270) //90CCW
        {
           result = BitmapFactory.New(h, w);
           using (var destContext = result.GetBitmapContext())
           {
              var rp = destContext.Pixels;
              //for (var x = w - 1; x >= 0; x--)
               Parallel.For(0, w, x=>
              {
                 //for (var y = 0; y < h; y++)                      
                  Parallel.For(0, h, y =>
                 {
                     var srcInd = y * w + x;
                     var DestId = y + h * (w - 1 - x);
                     rp[DestId] = p[srcInd];
                     //i++;
                 });
              });
           }
        }
        else
        {
           result = bmp.Clone();
        }
        return result;
     }          
           Would the team consider this for the wpf  and perhaps Silverlight platforms? Oh.. please also help me vex through the codes for any errors. I’ve tried it out, it seems to work fine.. but then, dealing with millions of pixels, missing 1 or 2 lines isn’t obvious. :P
  }
Feb 22, 2015 at 11:47 AM
sorry, found an error in the codes. Should be if-else-if statement instead of if-if for rotation logic based on angle of rotation. here's the corrected codes:
public static WriteableBitmap Rotate(this WriteableBitmap bmp, int angle)
  {          
      using (var context = bmp.GetBitmapContext())
     {
        // Use refs for faster access (really important!) speeds up a lot!
        var w = context.Width;
        var h = context.Height;
        var p = context.Pixels;
        //var i = 0;
        WriteableBitmap result = null;
        //angle %= 360;

        if (angle == 90) //90CW
        {
           result = BitmapFactory.New(h, w);
           using (var destContext = result.GetBitmapContext())
           {
              var rp = destContext.Pixels;
              //for (var x = 0; x < w; x++)
               Parallel.For(0, w, x=>
              {
                 //for (var y = h - 1; y >= 0; y--)                                            
                  Parallel.For(0, h, y=>
                 {
                     var srcInd = y * w + x;
                     var DestId = h - 1 - y + h * x;
                     rp[DestId] = p[srcInd];
                     //i++;
                 });
              });
           }
        }
        else if (angle == 180)
        {
           result = BitmapFactory.New(w, h);
           using (var destContext = result.GetBitmapContext())
           {
              var rp = destContext.Pixels;
              //for (var y = h - 1; y >= 0; y--)
              Parallel.For(0, h, y=>
             {
                 //for (var x = w - 1; x >= 0; x--)                     
                 Parallel.For(0, w, x=>
                 {
                     var srcInd = y * w + x;
                     var DestId = w - 1 - x + w * (h - 1 - y);
                     rp[DestId] = p[srcInd];
                     //i++;
                 });
             });
           }
        }
        else if (angle == 270) //90CCW
        {
           result = BitmapFactory.New(h, w);
           using (var destContext = result.GetBitmapContext())
           {
              var rp = destContext.Pixels;
              //for (var x = w - 1; x >= 0; x--)
               Parallel.For(0, w, x=>
              {
                 //for (var y = 0; y < h; y++)                      
                  Parallel.For(0, h, y =>
                 {
                     var srcInd = y * w + x;
                     var DestId = y + h * (w - 1 - x);
                     rp[DestId] = p[srcInd];
                     //i++;
                 });
              });
           }
        }
        else
        {
           result = bmp.Clone();
        }
        return result;
     }          

  }