I am new to android ndk.I have started learning through the image processing example by
ruckus and by IBM blog. I am not getting few lines below.Can any one please help me to understand the code snippet?`
static void brightness(AndroidBitmapInfo* info, void* pixels, float brightnessValue){
int xx, yy, red, green, blue;
uint32_t* line;
for(yy = 0; yy < info->height; yy++){
line = (uint32_t*)pixels;
for(xx =0; xx < info->width; xx++){
//extract the RGB values from the pixel
red = (int) ((line[xx] & 0x00FF0000) >> 16);
green = (int)((line[xx] & 0x0000FF00) >> 8);
blue = (int) (line[xx] & 0x00000FF );
//manipulate each value
red = rgb_clamp((int)(red * brightnessValue));
green = rgb_clamp((int)(green * brightnessValue));
blue = rgb_clamp((int)(blue * brightnessValue));
// set the new pixel back in
line[xx] =
((red << 16) & 0x00FF0000) |
((green << 8) & 0x0000FF00) |
(blue & 0x000000FF);
}
pixels = (char*)pixels + info->stride;
}
}
`
static int rgb_clamp(int value) {
if(value > 255) {
return 255;
}
if(value < 0) {
return 0;
}
return value;
}
How the RGB value are getting extracted and wht does this rgb_clamp do.Why are we setting new Pixell back and how does pixels = (char*)pixels + info->stride; works?
I am not a c/c++ guys and not having much knowledge of Image processing.
Thanks
At first lets talk about one pixel. As far as i can see, it is a composition of at least 3 channels: r,g and b, which are all stored in one
uint32_tvalue and has the format 0x00RRGGBB(32bit / 4 channels = 8bit per channel and thus a value range from 0..255). So, to get the separated r, g and b-values you need to mask them out, which is done in the three lines below//extract the RGB values. For example the red component… With the mask 0x00FF0000 and the&operator, you set every bit to 0 except the bits that are set in the red channel. But when you just mask them out with0x00RRGGBB & 0x00FF0000 = 0x00RR0000, you would get a very big number. To get a value between 0 and 255 you also have to shift the bits to the right and that is what is done with the>>-operator. So for the latter example: After applying the mask, you get 0x00RR0000, and shifting this 16 bit right (>> 16)gives you0x000000RR, which is a number between 0 and 255. The same happens with the green channel, but with an 8bit right shift and since the blue value is already on the “right” bit position, there is no need to shift.Second question: What
rgb_clampdoes is easy to explain. It ensures, that your r,g or b-value, multiplied with your brightness factor, never exceeds the value range 0..255.After the multiplication with the brightness factor, the new values are written back into memory, which happens in the reverse order of the above described extraction, this time shifting them leftwards and removing bits, that we don’t want with the mask.
After one line of your image is processed, the
info->strideis added, since for optimization purposes, the memory probably is aligned to fill 32byte boundaries and thus a single line can be longer than only image width and thus the “rest” of bytes are added to the pointer.