On Tue, 12 Jul 2005 08:06:32 -0700, Peter Nilsson wrote:
Mark Feller wrote: I have an embedded application where malloc( ) is not available. So I
declare images as globals, but want to be able to pass image information
including a pointer in a structure, as in the following:
unsigned short image[640][480];
typedef struct{
unsigned short** img_ptr;
unsigned short img_width;
unsigned short img_height;
} IMAGE;
int foo(IMAGE* x);
The "unsigned short**" is the wrong way to do this, but I am still
looking for the correct way.
I'd say...
unsigned short (*img_ptr)[480];
...but since you include img_width and img_height, I'm guessing you may
have more than one image, and those images may have different dimensions.
If so, then you need to resort to the more primitive...
typedef struct{
unsigned short *img_ptr;
unsigned short img_width;
unsigned short img_height;
} IMAGE;
unsigned short image1[640][480];
unsigned short image2[320][240];
IMAGE IMAGE1 = { &image1[0][0], 640, 480 }; IMAGE IMAGE2 = {
&image2[0][0], 320, 240 };
In which case, foo will have to traverse the image rows 'manually'...
int foo(IMAGE* x)
{
unsigned short row, col;
size_t pixel = 0;
for (row = 0; row < x->img_height; row++) for (col = 0; col <
x->img_width ; col++, pixel++) {
/* x->image[pixel] is pixel at (col, row) */
}
}
}
That's a good technique if you are limited to C90. I noticed a couple of
semantic problems with your code though. The loop ordering is inverted
since row varies fastest (your code stores the second dimension into the
img_height member so semantically row indexes the second dimension).
In other words the pixel at (col, row) is...
x->image[col + (size_t) row * x->img_width]
That should be:
x->image[row + (size_t) col * x->img_height]
This is because the fastest varying dimension is the second dimension
(row) so it should not be multiplied by anything, and the first dimension
(col) which varies slowest can be thought of as representing the number of
fully completed 2nd dimensions (rows), so it should be multiplied by the
number of elements in each 2nd dimension (row), and that number of
elements is stored in x->img_height.
What I want to suggest is that if the OP has access to a C99 compatible
compiler or one that otherwise lets you specify an array dimension at
runtime, he could modify your foo function to this:
void foo(IMAGE* x)
{
unsigned short row, col;
unsigned short (*image)[x->img_height] =
(unsigned short(*)[x->img_height])x->img_ptr;
/* Now you can access the image array stored in x->img_ptr as
* image[col][row]; abeit without bounds checking on the first dimension
*/
for (col = 0; col < x->img_width ; col++)
for (row = 0; row < x->img_height; row++)
printf("image[%hu][%hu] == %hu\n", col, row, image[col][row]);
}