Image conversion from 24 bpp to 16 bpp format

1

I have an image i.e. drawn using Windows GDI calls (24 bpp) and I need to convert this image to 16 bpp. This is on Windows Mobile.

 24 bpp - RGB (rrrrrrrr gggggggg bbbbbbbb)
 16 bpp - RGB (rrrrr gggggg bbbbb)

For this I am using the below code

for (int x = 0; x < iScreenSize; x++)
{
    *iPixel1= (*iPixel & 0x0000001F) |
              (*iPixel & 0x00003F00) >> 3 | 
              (*iPixel & 0x001F0000) >> 5;
}

The code works fine but the performance is not that good since I am modifying pixel by pixel. Can you suggest any possible improvements to this conversion?

Thanks in advance

c++
windows
graphics
windows-mobile
gdi
asked on Stack Overflow Nov 2, 2011 by AndroidDev • edited Nov 2, 2011 by AndroidDev

1 Answer

6

Your code isn't complete; you don't show the types of the pointers or how you're incrementing them. The number of operations you perform per pixel looks pretty optimal, so I'm going to guess that any slowness comes from unaligned memory access. You can fix this by unrolling the loop and doing 4 pixels at a time. Also the compiler should be smart enough to optimize multiple accesses to the same pointer, but lets assume it doesn't and copy them to temporary variables instead. I'm also going to assume you want to keep the upper bits of each color channel rather than the lower bits in your sample code.

UINT32 * iPixel;
UINT16 * iPixel1;
for (int x = 0; x < iScreenSize; x+=4)
{
    UINT32 dw1 = *iPixel++;
    UINT32 dw2 = *iPixel++;
    UINT32 dw3 = *iPixel++;
    *iPixel1++ = (dw1 & 0x000000F8) >> 3 |
                 (dw1 & 0x0000FC00) >> 5 |
                 (dw1 & 0x00F80000) >> 8;
    *iPixel1++ = (dw1 & 0xF8000000) >> 27 |
                 (dw2 & 0x000000FC) << 3 |
                 (dw2 & 0x0000F800);
    *iPixel1++ = (dw2 & 0x00F80000) >> 19 |
                 (dw2 & 0xFC000000) >> 21 |
                 (dw3 & 0x000000F8) << 8;
    *iPixel1++ = (dw3 & 0x0000F800) >> 11 |
                 (dw3 & 0x00FC0000) >> 13 |
                 (dw3 & 0xF8000000) >> 16;
}
answered on Stack Overflow Nov 2, 2011 by Mark Ransom

User contributions licensed under CC BY-SA 3.0