Source
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* ImageMagick header
*/
#include <magick/api.h>
static inline int max(int a, int b) { return a > b ? a : b; }
/* simple container struct for pixel data returned by load_image
*/
typedef struct image_data_tag
{ void *pixels;
unsigned char* soa_pixels;
unsigned int width;
unsigned int height;
unsigned int total_pix;
} image_data;
/* struct for an RGBA pixel - used in aos mode
* (I don't use a struct in soa mode)
*/
typedef struct pix_tag
{ unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} pix;
int load_image(char* theImageName, image_data* img_data, int aos_mode)
{
int i, j;
register const PixelPacket* thePixels;
ExceptionInfo exception;
/* Initialize the image info structure and read the image.
*/
GetExceptionInfo(&exception);
ImageInfo* image_info = CloneImageInfo( (ImageInfo *) NULL );
(void) strcpy(image_info->filename, theImageName);
Image* image = ReadImage(image_info, &exception);
if (image == (Image *) NULL)
{ printf("ERROR: %s ; %s\n", exception.reason, exception.description);
return 0;
}
/* record size of the image
*/
img_data->width = image->rows;
img_data->height = image->columns;
img_data->total_pix = image->columns*image->rows;
/* allocate space for the pixel data. Needs to be free'd by the caller
*/
img_data->pixels = (unsigned int *)
malloc (img_data->width * img_data->height * sizeof(pix));
pix* aos_ptr = (pix*)img_data->pixels;
unsigned char* soa_ptr = (unsigned char*)img_data->pixels;
for(i = 0; i < img_data->height; i++)
{
/* get the pixel data
*/
thePixels =
AcquireImagePixels(image, 0, i, img_data->width, 1, &exception);
/* walk down the row - thePixels is one row's worth
*/
for (j = 0; j < img_data->width; j++)
{
if (thePixels == (PixelPacket*) NULL)
{ printf("ERROR reading pixels: %s ; %s\n",
exception.reason, exception.description);
free(img_data->pixels);
return 0;
}
else
{
/* ImageMagick returns pixels @ 16 bits / channel
*/
unsigned int r, g, b, a;
r = thePixels->red >> 8;
g = thePixels->green >> 8;
b = thePixels->blue >> 8;
a = 0;
if (aos_mode)
{ aos_ptr = aos_ptr;
aos_ptr->r = r;
aos_ptr->g = g;
aos_ptr->b = b;
aos_ptr->a = a;
aos_ptr++;
}
else
{ *soa_ptr = r;
*(soa_ptr + 1*img_data->total_pix) = g;
*(soa_ptr + 2*img_data->total_pix) = b;
*(soa_ptr + 3*img_data->total_pix) = a;
soa_ptr++;
}
/* increment to next pixel on this row
*/
thePixels++;
} } }
DestroyImageInfo(image_info);
return 1;
}
int main (int argc, char *argv[])
{
image_data img_data;
int retval = 0;
int aos_mode = 0;
/* initialize IMagick w/ my path;
* initialize ImageMagic exception object
*/
InitializeMagick(argv[0]);
if (argc < 2)
{ printf("no image filename specified\n");
retval = 1;
}
else if (!load_image(argv[1], &img_data, aos_mode))
{ retval = 1; // error message printed by func
}
else
{
printf("size = %d x %d\n", img_data.width, img_data.height);
unsigned char max_r = 0;
unsigned char max_g = 0;
unsigned char max_b = 0;
if (aos_mode)
{
int rows, cols;
pix* aos_ptr = (pix*)img_data.pixels;
for (rows = 0; rows < img_data.height; rows++)
{
for (cols = 0; cols < img_data.width; cols++)
{
/* for fun, for tiny images dump out the RGB
*/
if (img_data.width < 10)
{
printf("{%d,%d,%d}", aos_ptr->r, aos_ptr->g, aos_ptr->b);
}
max_r = max(aos_ptr->r, max_r);
max_g = max(aos_ptr->g, max_g);
max_b = max(aos_ptr->b, max_b);
aos_ptr++;
}
if (img_data.width < 10)
{
printf("\n");
}
}
free(img_data.pixels);
}
else
{
int i;
unsigned char* soa_ptr = (unsigned char*)img_data.pixels;
// RED
if (img_data.width < 10) printf("r: ");
for (i = 0; i < img_data.height*img_data.width; i++)
{ unsigned char this_r = *(soa_ptr + i);
max_r = max(this_r, max_r);
if (img_data.width < 10) printf("%03d,", this_r);
}
if (img_data.width < 10) printf("\n");
// GREEN
if (img_data.width < 10) printf("r: ");
for (i = 0; i < img_data.height*img_data.width; i++)
{ unsigned char this_g = *(soa_ptr + i + 1*img_data.total_pix);
max_g = max(this_g, max_g); // <------- GREEN pixel
if (img_data.width < 10) printf("%03d,", this_g);
}
if (img_data.width < 10) printf("\n");
// BLUE
if (img_data.width < 10) printf("b: ");
for (i = 0; i < img_data.height*img_data.width; i++)
{ unsigned char this_b = *(soa_ptr + i + 2*img_data.total_pix);
max_b = max(this_b, max_b);
if (img_data.width < 10) printf("%03d,", this_b);
}
if (img_data.width < 10) printf("\n");
soa_ptr++;
}
printf("max r=%d, g=%d, b=%d\n", max_r, max_g, max_b);
}
/* cleanup
*/
DestroyMagick();
exit(retval);
}
Makefile
all: magick
magick: im_test.c
rm -f im_test
gcc -g `Magick-config --cflags --cppflags` im_test.c `Magick-config --ldflags --libs` -o im_test
--
MattWalsh - 16 Oct 2009