Structured data types An elegant way to deal with the rgb image is to employ structured data types. A Java class is a generalization of a C struct. A structure is an aggregation of basic and structured data elements, possibly including pointers, but unlike a class, it contains no embedded methods (functions). Structures and “typedef
A C structure is declared as follows: struct pix_type { unsigned char r; unsigned char g; unsigned char b; }; As with Java, it is important to be aware that struct pix_type is the name of a user defined structure type. It is not the name of a variable. Structures and “typedef
To declare an instance (variable) of type struct pix_type use: struct pix_type pixel; struct pix_type is the name of the type pixel is the name of a variable of type struct pix_type To set or reference components of the pixel use: pixel.r = 250; // make Mr. Pixel yellow pixel.g = 250; pixel.b = 0; Structures and “typedef
To declare a pointer to a struct pix_type use: struct pix_type *pixptr; Before using the pointer we must always make it point to something: pixptr = (struct pix_type *)malloc(sizeof(struct pix_type)); Pointers to structures
To set or reference components of the pix_type to which it points use: (*pixptr).r = 250; // make Mr. *pixptr magenta (*pixptr).g = 0; (*pixptr).b = 250; Warning: the C compiler is very picky about the location of the parentheses here. Perhaps because of the painful nature of the above syntax, an alteranative “short hand” notation has evolved for accessing elements of structures through a pointer: pixptr->r = 0; // make Mr. pixptr-> cyan pixptr->g = 250; pixptr->b = 250; This shorthand form is almost universally used. Pointers to structures:
To enhance the readability of a program, C provides the “typedef” statement as a way to define new data types. An example of the typedef statement is: typedef int boolean; This defines the new data type “boolean” as being equivalent to the existing type “int”. After defining this equivalence, the programmer can declare variables that will be used to represent a TRUE or FALSE value as follows: boolean flag; boolean doneTest; Declaring a variable as boolean as opposed to int can help the reader understand the role of the variable in the program. typedef statement:
Another common use of typedef is to define a data type that is equivalent to a structure. For example, consider the “pixel” structure that was defined earlier. We could define a new data type called “pixel_t” as follows: typedef struct pix_type { unsigned char r; unsigned char g; unsigned char b; } pixel_t; typedef statement:
In this case we are equating the name “pixel_t” to the structure definition. Now in a program instead of having to say: struct pix_type newpixel; to declare the structure variable “newpixel”, we can instead simply say: pixel_t newpixel; Functionally there is NO difference – the advantage comes through readability and a little less typing. typedef statement:
Other examples of declaring pixel variables are: pixel_t *pixelPtr; /* Declare a pointer to a pixel */ pixel_t image[100][100]; /* Declare a pixel matrix */ typedef statement:
Space for a color image in binary rgb format can be allocated by: pixel_t *pixptr; : pixptr = (pixel_t *)malloc(sizeof(pixel_t) *numrows * numcols); To read the image data pixcount = fread(pixptr, sizeof(pixel_t), numrows * numcols, stdin); if (pixcount != numrows * numcols) { fprintf(stderr, “pix count err - wanted %d got %d \n”, numrows * numcols, pixcount); exit(1); } The Color Image:
To access a specific pixel red = *(pixptr + row * numcols + col).r; green = *(pixptr + row * numcols + col).b; blue = *(pixptr + row * numcols + col).g; or red = (pixptr + row * numcols + col)->r; green = (pixptr + row * numcols + col)->g; blue = (pixptr + row * numcols + col)->b; or even but not in class assignments red = pixptr[row * numcols + col].r; Pointers to structures:
typedef struct img_type { int numrows; int numcols; unsigned char pixval[1024][768]; } image_t; image_t image; Elements of the array are accessed in the usual way: image.pixval[5][10] = 125; Structures and Arrays:
It is also possible to create an array of structures typedef struct pixel_type { unsigned char r; unsigned char g; unsigned char b; } pixel_t; pixel_t pixmap[100]; To access an individual element of the array place the subscript next to the name it indexes pixmap[15].r = 250; Structures and Arrays:
It is common for structures to contain elements which are themselves structures or arrays of structures. In these cases the structure definitions should appear in “inside-out” order. This is done to comply with the usual rule of not referencing a name before it is defined. typedef struct pixel_type { unsigned char r; unsigned char g; unsigned char b; } pixel_t; typedef struct img_type { int numrows; int numcols; pixel_t pixdata[1024][768]; } img_t; Structures containing structures:
img_t image; image.pixdata[4][14].r = 222; Structures containing structures: