why unsigned char for RGB pixel data?

10,939

Solution 1

RGB images are usually stored in interleaved order (R1, G1, B1, R2, G2, B2, ...), so one pointer (to R1) is enough.

This makes it a bit harder to address individual pixels: pixel with index N is stored at pixels[3*N+0], pixels[3*N+1] and pixels[3*N+2] instead of just red[N], green[N], blue[N].

However, this has the advantage of allowing faster access: less pointers lead to easier programs, improving their speed; interleaved order also makes memory caching more effective.

Solution 2

unsigned char *pixels[3];

declares an array of three pointers to unsigned char. I'm not sure if that's what you wanted.

There are several different ways to represent pixels. The simplest is probably something like:

struct Pixel
{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};

But you may have to (or want to) conform to some external format. Another frequent possibility is to put all three colors in a uint32_t. Also, in some graphic systems, there may be a fourth element, and alpha, representing transparency.

Solution 3

Really whenever you refer to a block of bytes, it's going to be of type unsigned char* because of the fact that unsigned char by the C-specification has no padding in the type itself (i.e., every bit is used for a value in the byte, and there are no padded bits that are not used), and pixel-data is going to be some block of X bytes with no padding (at least not internal padding ... there may be padding at the end of the buffer for alignment purposes). It will also most likely be allocated on the heap somewhere. So no matter if it's going to be monochrome, color-data, etc., you will often find that a pixel buffer will be pointed to via an unsigned char pointer, and you may then cast it to some struct like James mentioned in order to easily access the pixel information. Other times you may have to index into the buffer like anatolyg mentions. But in the end, a buffer of pixels is just a buffer of data, and a general buffer of data bytes should be accessed in C/C++ using type unsigned char*.

Solution 4

With *pixels[3] you've got separate arrays for the three colour components, whereas in files the three colour components for a single pixel are stored together. It also means you can use a single fread()/fwrite() for the whole block of image data,

Share:
10,939
nkint
Author by

nkint

recursive: adjective, see recursive.

Updated on June 30, 2022

Comments

  • nkint
    nkint almost 2 years

    i'm approaching c++ with some basic computer graphics.

    pixels data is usually represented as :

    unsigned char *pixels
    

    and an unsigned char is good because is a value between 0 and 255 (256 = 2^8 because a char is 2 byte and 1 byte is 8 bit?). and this is good because in RGB color are represented with a number between 0 and 255.

    but.. i understand this as a monchromatic image, in a normal image i have RGB, i would have 3 array of unsiged char, one for red, one for green, one for blue. something like:

    unsigned char *pixels[3]
    

    but i never found something similar for RGB pixels data

    • Ishtar
      Ishtar about 13 years
      1 byte is 8 bit. A bit has 2 states. So a byte, 8 bits, has 2^8 states. Thus 1 byte has 2^8=256 distinct possible states. A unsigned char is 1 byte with 256 distinct values, 0 to 255.