Thread: Choice of data structure for storing an image

  1. #1
    Registered User
    Join Date
    Jul 2006
    Posts
    111

    Choice of data structure for storing an image

    Hi all,

    I am currently working on a small project that involves processing images (for fun/to learn the language). While I have already had relative success with the project, I keep finding myself pondering on whether or not I chose the best data structure.

    Currently, I am using a "two dimensional" array of Pixel structs (which contain r, g, b, and alpha). I have seen other code examples, however, that store the raw image data in a single dimensional arrayin which the color channel alternates (for example: int image[] = {r,g,b,r,g,b,r,g,b...}).

    Is there any advantage to storing the image as a single dimensional array (other than the fact that it is a little bit easier to allocate)? I originally chose the "two dimensional" paradigm for the fact that it better resembles an actual image.

    Also, a question about accessing the data stored in these data structures: should I write special functions to retrieve data from the image structs when I write filters/image processing algorithms or is it better to simply access the data directly (e.g. image->data[x][y].r)... The reason I ask is because I come from a java background, where everything is driven by OO and accessor methods, so I am not sure what is the most "C-like" approach.

    If you feel that viewing my code for the image structures would help to better evaluate the situation, I can post it a bit later.

    Thanks,
    Lilrayray

  2. #2
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    When I wrote my image class I used a single dimensional array with the r,g,b,r,g,b,r,g,b.. etc format. I then wrote a function that could access a single pixel and return it as a r, g, or b value, or all three. An example is below. My way is probably not the best, or most accepted, but is a suggestion.

    Code:
    // declaration
    class Image;
    #define IMAGE_RGB 1
    #define IMAGE_R 2
    #define IMAGE_G 3
    #define IMAGE_B 4
    unsigned char* Image::pixel(int x, int y, DWORD pixelType);
    
    // usage
    
    unsigned char rgb[3] = image.pixel(500, 100, IMAGE_RGB); // get all three components of the pixel at (500,100)
    unsigned char r = *(image.pixel(500, 100, IMAGE_R)); // get just red component
    
    // etc...

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Would any of the algorithms you're using really benefit from a 2D subscript method?

    A linear array can always be accessed in a single memory cycle. The array subscripting calculation is small enough that all the interesting values will be in registers.

    But a 2D array starting with something like
    pixel **data;
    always has two memory accesses, one to resolve pixel[row] and then another to get the pixel itself.

    Memory is slow by comparison on modern machines.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Jul 2006
    Posts
    111
    Ok, I had always been hesitant to use the 2D method... I figured that it would be a bit more readable/easier to understand. Also, I kind of figured that since malloc allocates contiguous memory blocks, splitting up the array would prevent any problems when the images became very large (for example, a raw 10,000x5,000 image is >200 mb).

    But from this point forward, I will hide the details of the data structure with accessor functions so that if ever I decided to alter it again, I wont have to refactor all of my code.

    Scwizzo,
    Out of curiousity, why did you decided to use a single method with a parameter that alters the return value as opposed to separate methods? Also, is the memory footprint of an array containing 3 or 4 values considerably smaller than a struct containing 3 or 4 values?


    Thanks a lot for the explanations and the example!
    Last edited by lilrayray; 01-24-2010 at 02:22 AM.

  5. #5
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    Running the following code gives the following output. Hope it answers your question.
    Code:
    #include <iostream> 
    #include <conio.h>
    using namespace std;
    
    struct mystruct
    {
        int someinteger[3];
    };
    
    int main()
    {   
        printf("Size of structure with integer: %i\n", sizeof(mystruct));
        printf("Size of integer: %i\n", sizeof(int[3]));
        while(!_kbhit());
        return 0;	
    }
    Code:
    Size of structure with integer: 12
    Size of integer: 12
    I chose a 1 dimensional array due to simplicity. I can allocate everything in one large chunk, versus having to run two loops to allocate the memory twice. Also, I would rather deal with pointers, and changing a single memory source than having to copy, delete, copy, move, delete, etc...

  6. #6
    Registered User
    Join Date
    Jul 2006
    Posts
    111
    ok cool... so in effect, a struct is really just a way of organizing various memory address?

    I went through the pain of changing my 2D array into a single dimensional array and refactoring everything accordingly (this time I am using accessor methods everywhere as to avoid similar pains if ever I decided to alter it again).

    I have found that changing to the 1D array actually eliminated some deallocation errors that occurred at runtime and also I have found things to run 3% or 4% faster (though I am not sure to what I should attribute this speed increase).

    Ultimately, I decided to stick with an array of Pixel structs as opposed to rgbrgb as I feel a struct will provided more flexibility (for example, the addition of an alpha channel and c, y, m, k color channels would not require any changes in function calls or the underlying data structures.

    Anyway, thanks for the help, Ive learned quite a bit from this!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data structure for storing serial port data in firmware
    By james457 in forum C Programming
    Replies: 4
    Last Post: 06-15-2009, 09:28 AM
  2. pthread question how would I init this data structure?
    By mr_coffee in forum C Programming
    Replies: 2
    Last Post: 02-23-2009, 12:42 PM
  3. Program Crashing
    By Pressure in forum C Programming
    Replies: 3
    Last Post: 04-18-2005, 10:28 PM
  4. C diamonds and perls :°)
    By Carlos in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 05-16-2003, 10:19 PM
  5. vector static abstract data structure in C?
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 11-05-2001, 05:02 PM