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

Topic revision: r1 - 16 Oct 2009 - MattWalsh
 
This site is powered by the TWiki collaboration platformCopyright © 2008-2012 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback