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);
          }
        }
      }
    }
    
    链接地址: http://www.djcxy.com/p/72500.html

    上一篇: 安全左移

    下一篇: C#/。net通过短[]按位左移操作