开发者

C#/.net bitwise shift left operation over a short[]

Is there a method (in c#/.net) that would left-shift (bitwise) each short in a short[] that would be faster then doing it in a loop?

I am talking about data coming from a digital camera (16bit gray), the camera only uses the lower 12 bits. So to see something when rendering the data it needs to be shifted left by 4.

This is what I am doing so far:

byte开发者_开发问答[] RawData; // from camera along with the other info

if (pf == PixelFormats.Gray16)
{
    fixed (byte* ptr = RawData)
    {
        short* wptr = (short*)ptr;
        short temp;

        for (int line = 0; line < ImageHeight; line++)
        {
            for (int pix = 0; pix < ImageWidth; pix++)
            {
                temp = *(wptr + (pix + line * ImageWidth));
                *(wptr + (pix + line * ImageWidth)) = (short)(temp << 4);
            }
        }
    }
}

Any ideas?


I don't know of a library method that will do it, but I have some suggestions that might help. This will only work if you know that the upper four bits of the pixel are definitely zero (rather than garbage). (If they are garbage, you'd have to add bitmasks to the below). Basically I would propose:

  • Using a shift operator on a larger data type (int or long) so that you are shifting more data at once
  • Getting rid of the multiply operations inside your loop
  • Doing a little loop unrolling

Here is my code:

using System.Diagnostics;

namespace ConsoleApplication9 {
  class Program {
    public static void Main() {
      Crazy();
    }

    private static unsafe void Crazy() {
      short[] RawData={
        0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666, 0x777, 0x888,
        0x999, 0xaaa, 0xbbb, 0xccc, 0xddd, 0xeee, 0xfff, 0x123, 0x456,

        //extra sentinel value which is just here to demonstrate that the algorithm
        //doesn't go too far
        0xbad 
      };

      const int ImageHeight=2;
      const int ImageWidth=9;

      var numShorts=ImageHeight*ImageWidth;

      fixed(short* rawDataAsShortPtr=RawData) {
        var nextLong=(long*)rawDataAsShortPtr;

        //1 chunk of 4 longs
        // ==8 ints
        // ==16 shorts
        while(numShorts>=16) {
          *nextLong=*nextLong<<4;
          nextLong++;
          *nextLong=*nextLong<<4;
          nextLong++;
          *nextLong=*nextLong<<4;
          nextLong++;
          *nextLong=*nextLong<<4;
          nextLong++;

          numShorts-=16;
        }

        var nextShort=(short*)nextLong;
        while(numShorts>0) {
          *nextShort=(short)(*nextShort<<4);
          nextShort++;
          numShorts--;
        }
      }

      foreach(var item in RawData) {
        Debug.Print("{0:X4}", item);
      }
    }
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜