+ /* Finish the image */
+ return image_io_read_data_finish(&rdi, io);
+}
+
+int
+libmagick_write(struct image_io *io)
+{
+ DBG("libmagick_write()");
+
+ /* Initialize GraphicsMagick */
+ int result = 0;
+ ExceptionInfo exception;
+ ImageInfo *info;
+ GetExceptionInfo(&exception);
+ info = CloneImageInfo(NULL);
+
+ /* Setup image parameters and allocate the image*/
+ struct image *img = io->image;
+ switch (img->flags & IMAGE_COLOR_SPACE)
+ {
+ case COLOR_SPACE_GRAYSCALE:
+ info->colorspace = GRAYColorspace;
+ break;
+ case COLOR_SPACE_RGB:
+ info->colorspace = RGBColorspace;
+ break;
+ default:
+ IMAGE_ERROR(io->context, IMAGE_ERROR_WRITE_FAILED, "Unsupported color space.");
+ goto err;
+ }
+ switch (io->format)
+ {
+ case IMAGE_FORMAT_JPEG:
+ strcpy(info->magick, "JPEG");
+ if (io->jpeg_quality)
+ info->quality = MIN(io->jpeg_quality, 100);
+ break;
+ case IMAGE_FORMAT_PNG:
+ strcpy(info->magick, "PNG");
+ break;
+ case IMAGE_FORMAT_GIF:
+ strcpy(info->magick, "GIF");
+ break;
+ default:
+ ASSERT(0);
+ }
+ Image *image = AllocateImage(info);
+ if (unlikely(!image))
+ {
+ IMAGE_ERROR(io->context, IMAGE_ERROR_WRITE_FAILED, "GraphicsMagick failed to allocate the image.");
+ goto err;
+ }
+ image->columns = img->cols;
+ image->rows = img->rows;
+
+ /* Get pixels */
+ PixelPacket *pixels = SetImagePixels(image, 0, 0, img->cols, img->rows), *dest = pixels;
+ if (unlikely(!pixels))
+ {
+ IMAGE_ERROR(io->context, IMAGE_ERROR_WRITE_FAILED, "Cannot get GraphicsMagick pixels.");
+ goto err2;
+ }
+
+ /* Convert pixels */
+ switch (img->pixel_size)
+ {
+ case 1:
+# define IMAGE_WALK_PREFIX(x) walk_##x
+# define IMAGE_WALK_INLINE
+# define IMAGE_WALK_IMAGE img
+# define IMAGE_WALK_UNROLL 4
+# define IMAGE_WALK_COL_STEP 1
+# define IMAGE_WALK_DO_STEP do{ \
+ dest->red = BYTE_TO_QUANTUM(walk_pos[0]); \
+ dest->green = BYTE_TO_QUANTUM(walk_pos[0]); \
+ dest->blue = BYTE_TO_QUANTUM(walk_pos[0]); \
+ dest->opacity = 0; \
+ dest++; }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 img
+# define IMAGE_WALK_UNROLL 4
+# define IMAGE_WALK_COL_STEP 2
+# define IMAGE_WALK_DO_STEP do{ \
+ dest->red = BYTE_TO_QUANTUM(walk_pos[0]); \
+ dest->green = BYTE_TO_QUANTUM(walk_pos[0]); \
+ dest->blue = BYTE_TO_QUANTUM(walk_pos[0]); \
+ dest->opacity = BYTE_TO_ALPHA(walk_pos[1]); \
+ dest++; }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 img
+# define IMAGE_WALK_UNROLL 4
+# define IMAGE_WALK_COL_STEP 3
+# define IMAGE_WALK_DO_STEP do{ \
+ dest->red = BYTE_TO_QUANTUM(walk_pos[0]); \
+ dest->green = BYTE_TO_QUANTUM(walk_pos[1]); \
+ dest->blue = BYTE_TO_QUANTUM(walk_pos[2]); \
+ dest->opacity = 0; \
+ dest++; }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 img
+# define IMAGE_WALK_UNROLL 4
+# define IMAGE_WALK_COL_STEP 4
+# define IMAGE_WALK_DO_STEP do{ \
+ dest->red = BYTE_TO_QUANTUM(walk_pos[0]); \
+ dest->green = BYTE_TO_QUANTUM(walk_pos[1]); \
+ dest->blue = BYTE_TO_QUANTUM(walk_pos[2]); \
+ dest->opacity = BYTE_TO_ALPHA(walk_pos[3]); \
+ dest++; }while(0)
+# include "images/image-walk.h"
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ /* Store pixels */
+ if (unlikely(!SyncImagePixels(image)))