+ /* Quantize image */
+ switch (rd->image->colorspace)
+ {
+ case RGBColorspace:
+ case GRAYColorspace:
+ break;
+ default: ;
+ QuantizeInfo quantize;
+ GetQuantizeInfo(&quantize);
+ quantize.colorspace = RGBColorspace;
+ QuantizeImage(&quantize, rd->image);
+ break;
+ }
+
+ /* Prepare the image */
+ struct image_io_read_data_internals rdi;
+ uint read_flags = io->flags;
+ uint cs = read_flags & IMAGE_COLOR_SPACE;
+ if (cs != COLOR_SPACE_GRAYSCALE && cs != COLOR_SPACE_RGB)
+ read_flags = (read_flags & ~IMAGE_COLOR_SPACE & IMAGE_PIXEL_FORMAT) | COLOR_SPACE_RGB;
+ if ((read_flags & IMAGE_IO_USE_BACKGROUND) && !(read_flags & IMAGE_ALPHA))
+ read_flags = (read_flags & IMAGE_CHANNELS_FORMAT) | IMAGE_ALPHA;
+ if (unlikely(!image_io_read_data_prepare(&rdi, io, rd->image->columns, rd->image->rows, read_flags)))
+ {
+ libmagick_destroy_read_data(rd);
+ return 0;
+ }
+
+ /* Acquire pixels */
+ PixelPacket *src = (PixelPacket *)AcquireImagePixels(rd->image, 0, 0, rd->image->columns, rd->image->rows, &rd->exception);
+ if (unlikely(!src))
+ {
+ IMAGE_ERROR(io->context, IMAGE_ERROR_READ_FAILED, "Cannot acquire image pixels.");
+ libmagick_destroy_read_data(rd);
+ image_io_read_data_break(&rdi, io);
+ return 0;
+ }
+
+ /* Convert pixels */
+ switch (rdi.image->pixel_size)
+ {
+ case 1:
+# define IMAGE_WALK_PREFIX(x) walk_##x
+# define IMAGE_WALK_INLINE
+# define IMAGE_WALK_IMAGE (rdi.image)
+# define IMAGE_WALK_UNROLL 4
+# define IMAGE_WALK_COL_STEP 1
+# define IMAGE_WALK_DO_STEP do{ \
+ walk_pos[0] = libmagick_pixel_to_gray(src); \
+ src++; }while(0)
+# include <images/image-walk.h>
+ break;
+
+ case 2:
+# define IMAGE_WALK_PREFIX(x) walk_##x
+# define IMAGE_WALK_INLINE
+# define IMAGE_WALK_IMAGE (rdi.image)
+# define IMAGE_WALK_UNROLL 4
+# define IMAGE_WALK_COL_STEP 2
+# define IMAGE_WALK_DO_STEP do{ \
+ walk_pos[0] = libmagick_pixel_to_gray(src); \
+ walk_pos[1] = ALPHA_TO_BYTE(src->opacity); \
+ src++; }while(0)
+# include <images/image-walk.h>
+ break;
+
+ case 3:
+# define IMAGE_WALK_PREFIX(x) walk_##x
+# define IMAGE_WALK_INLINE
+# define IMAGE_WALK_IMAGE (rdi.image)
+# define IMAGE_WALK_UNROLL 4
+# define IMAGE_WALK_COL_STEP 3
+# define IMAGE_WALK_DO_STEP do{ \
+ walk_pos[0] = QUANTUM_TO_BYTE(src->red); \
+ walk_pos[1] = QUANTUM_TO_BYTE(src->green); \
+ walk_pos[2] = QUANTUM_TO_BYTE(src->blue); \
+ src++; }while(0)
+# include <images/image-walk.h>
+ break;
+
+ case 4:
+# define IMAGE_WALK_PREFIX(x) walk_##x
+# define IMAGE_WALK_INLINE
+# define IMAGE_WALK_IMAGE (rdi.image)
+# define IMAGE_WALK_UNROLL 4
+# define IMAGE_WALK_COL_STEP 4
+# define IMAGE_WALK_DO_STEP do{ \
+ walk_pos[0] = QUANTUM_TO_BYTE(src->red); \
+ walk_pos[1] = QUANTUM_TO_BYTE(src->green); \
+ walk_pos[2] = QUANTUM_TO_BYTE(src->blue); \
+ walk_pos[3] = ALPHA_TO_BYTE(src->opacity); \
+ src++; }while(0)
+# include <images/image-walk.h>
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ /* Free GraphicsMagick structures */
+ libmagick_destroy_read_data(rd);
+
+ /* Finish the image */
+ return image_io_read_data_finish(&rdi, io);