3

I am trying to convert a rgb565 image (video stream from the Android phone camera) into a greyscale (8 bits) image.

So far I got to the following code (the conversion is computed in native code using the Android NDK). Note that my input image is 640*480 and I want to crop it to make it fit in a 128*128 buffer.

#define RED(a)      ((((a) & 0xf800) >> 11) << 3)
#define GREEN(a)    ((((a) & 0x07e0) >> 5) << 2)
#define BLUE(a)     (((a) & 0x001f) << 3)

typedef unsigned char byte;

void toGreyscale(byte *rgbs, int widthIn, int heightIn, byte *greyscales)
{
    const int textSize = 128;
    int x,y;
    short* rgbPtr = (short*)rgbs;
    byte *greyPtr = greyscales;

    // rgbs arrives in RGB565 (16 bits) format
    for (y=0; y<textSize; y++)
    {
        for (x=0; x<textSize; x++)
        {
            short pixel = *(rgbPtr++);
            int r = RED(pixel);
            int g = GREEN(pixel);
            int b = BLUE(pixel);

            *(greyPtr++) = (byte)((r+g+b) / 3);
        }
        rgbPtr += widthIn - textSize;
    }
}

The image is sent to the function like this

jbyte* cImageIn = env->GetByteArrayElements(imageIn, &b);
jbyte* cImageOut = (jbyte*)env->GetDirectBufferAddress(imageOut);
toGreyscale((byte*)cImageIn, widthIn, heightIn, (byte*)cImageOut);

The result I get is a horizontally-reversed image (no idea why...the UVs to display the result are correct...), but the biggest problem is that only the red channel is actually correct when I display them separately. The green and blue channels are all messed up and I have no idea why. I checked on the Internet and all the resources I found showed that the masks I am using are correct. Any idea where the mistake could be?

Thanks!

pot2mayo
  • 403
  • 1
  • 5
  • 9

1 Answers1

0

May be an endianess issue?

You could check quickly by reversing the two bytes of your 16 bits word before shifting out the RGB components.

MoonSilex
  • 61
  • 2