X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=coders%2Fxcf.c;h=746f0daad4e48536dad9a06dfc2cb169a7f9e373;hb=39172408bad7ef2ef00a815fa9abf9979e7857cb;hp=f344832452a2cd6a42bd60eeac27bca054d21f0a;hpb=34d83b21d9284c84cff4126bd5fbb52369efa05c;p=imagemagick diff --git a/coders/xcf.c b/coders/xcf.c index f34483245..746f0daad 100644 --- a/coders/xcf.c +++ b/coders/xcf.c @@ -17,7 +17,7 @@ % November 2001 % % % % % -% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % +% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % @@ -39,25 +39,26 @@ /* Include declarations. */ -#include "magick/studio.h" -#include "magick/blob.h" -#include "magick/blob-private.h" -#include "magick/cache.h" -#include "magick/color.h" -#include "magick/composite.h" -#include "magick/exception.h" -#include "magick/exception-private.h" -#include "magick/image.h" -#include "magick/image-private.h" -#include "magick/list.h" -#include "magick/magick.h" -#include "magick/memory_.h" -#include "magick/pixel.h" -#include "magick/quantize.h" -#include "magick/quantum-private.h" -#include "magick/static.h" -#include "magick/string_.h" -#include "magick/module.h" +#include "MagickCore/studio.h" +#include "MagickCore/blob.h" +#include "MagickCore/blob-private.h" +#include "MagickCore/cache.h" +#include "MagickCore/color.h" +#include "MagickCore/composite.h" +#include "MagickCore/exception.h" +#include "MagickCore/exception-private.h" +#include "MagickCore/image.h" +#include "MagickCore/image-private.h" +#include "MagickCore/list.h" +#include "MagickCore/magick.h" +#include "MagickCore/memory_.h" +#include "MagickCore/pixel.h" +#include "MagickCore/pixel-accessor.h" +#include "MagickCore/quantize.h" +#include "MagickCore/quantum-private.h" +#include "MagickCore/static.h" +#include "MagickCore/string_.h" +#include "MagickCore/module.h" /* Typedef declarations. @@ -136,7 +137,7 @@ typedef struct width, height, type, - opacity, + alpha, visible, linked, preserve_trans, @@ -166,8 +167,8 @@ typedef struct red, green, blue, - opacity; -} XCFPixelPacket; + alpha; +} XCFPixelInfo; /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -242,8 +243,8 @@ static CompositeOperator GIMPBlendModeToCompositeOperator( case GIMP_SCREEN_MODE: return( ScreenCompositeOp ); case GIMP_OVERLAY_MODE: return( OverlayCompositeOp ); case GIMP_DIFFERENCE_MODE: return( DifferenceCompositeOp ); - case GIMP_ADDITION_MODE: return( AddCompositeOp ); - case GIMP_SUBTRACT_MODE: return( SubtractCompositeOp ); + case GIMP_ADDITION_MODE: return( ModulusAddCompositeOp ); + case GIMP_SUBTRACT_MODE: return( ModulusSubtractCompositeOp ); case GIMP_DARKEN_ONLY_MODE: return( DarkenCompositeOp ); case GIMP_LIGHTEN_ONLY_MODE:return( LightenCompositeOp ); case GIMP_HUE_MODE: return( HueCompositeOp ); @@ -252,7 +253,7 @@ static CompositeOperator GIMPBlendModeToCompositeOperator( case GIMP_DODGE_MODE: return( ColorDodgeCompositeOp ); case GIMP_BURN_MODE: return( ColorBurnCompositeOp ); case GIMP_HARDLIGHT_MODE: return( HardLightCompositeOp ); - case GIMP_DIVIDE_MODE: return( DivideCompositeOp ); + case GIMP_DIVIDE_MODE: return( DivideDstCompositeOp ); /* these are the ones we don't support...yet */ case GIMP_BEHIND_MODE: return( OverCompositeOp ); case GIMP_VALUE_MODE: return( OverCompositeOp ); @@ -294,7 +295,8 @@ static inline size_t MagickMin(const size_t x,const size_t y) return(y); } -static char *ReadBlobStringWithLongSize(Image *image,char *string,size_t max) +static char *ReadBlobStringWithLongSize(Image *image,char *string,size_t max, + ExceptionInfo *exception) { int c; @@ -324,24 +326,22 @@ static char *ReadBlobStringWithLongSize(Image *image,char *string,size_t max) string[i]='\0'; offset=SeekBlob(image,(MagickOffsetType) (length-i),SEEK_CUR); if (offset < 0) - (void) ThrowMagickException(&image->exception,GetMagickModule(), + (void) ThrowMagickException(exception,GetMagickModule(), CorruptImageError,"ImproperImageHeader","`%s'",image->filename); return(string); } static MagickBooleanType load_tile(Image *image,Image *tile_image, - XCFDocInfo *inDocInfo,XCFLayerInfo *inLayerInfo,size_t data_length) + XCFDocInfo *inDocInfo,XCFLayerInfo *inLayerInfo,size_t data_length, + ExceptionInfo *exception) { - ExceptionInfo - *exception; - ssize_t y; register ssize_t x; - register PixelPacket + register Quantum *q; ssize_t @@ -350,12 +350,12 @@ static MagickBooleanType load_tile(Image *image,Image *tile_image, unsigned char *graydata; - XCFPixelPacket + XCFPixelInfo *xcfdata, *xcfodata; - xcfdata=(XCFPixelPacket *) AcquireQuantumMemory(data_length,sizeof(*xcfdata)); - if (xcfdata == (XCFPixelPacket *) NULL) + xcfdata=(XCFPixelInfo *) AcquireQuantumMemory(data_length,sizeof(*xcfdata)); + if (xcfdata == (XCFPixelInfo *) NULL) ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", image->filename); xcfodata=xcfdata; @@ -364,23 +364,20 @@ static MagickBooleanType load_tile(Image *image,Image *tile_image, if (count != (ssize_t) data_length) ThrowBinaryException(CorruptImageError,"NotEnoughPixelData", image->filename); - exception=(&image->exception); for (y=0; y < (ssize_t) tile_image->rows; y++) { q=QueueAuthenticPixels(tile_image,0,y,tile_image->columns,1,exception); - if (q == (PixelPacket *) NULL) + if (q == (Quantum *) NULL) break; if (inDocInfo->image_type == GIMP_GRAY) { for (x=0; x < (ssize_t) tile_image->columns; x++) { - SetRedPixelComponent(q,ScaleCharToQuantum(*graydata)); - SetGreenPixelComponent(q,GetRedPixelComponent(q)); - SetBluePixelComponent(q,GetRedPixelComponent(q)); - SetAlphaPixelComponent(q,ScaleCharToQuantum((unsigned char) - inLayerInfo->opacity)); + SetPixelGray(tile_image,ScaleCharToQuantum(*graydata),q); + SetPixelAlpha(tile_image,ScaleCharToQuantum((unsigned char) + inLayerInfo->alpha),q); graydata++; - q++; + q+=GetPixelChannels(tile_image); } } else @@ -388,32 +385,30 @@ static MagickBooleanType load_tile(Image *image,Image *tile_image, { for (x=0; x < (ssize_t) tile_image->columns; x++) { - SetRedPixelComponent(q,ScaleCharToQuantum(xcfdata->red)); - SetGreenPixelComponent(q,ScaleCharToQuantum(xcfdata->green)); - SetBluePixelComponent(q,ScaleCharToQuantum(xcfdata->blue)); - SetAlphaPixelComponent(q,xcfdata->opacity == 0U ? OpaqueOpacity : - ScaleCharToQuantum((unsigned char) inLayerInfo->opacity)); + SetPixelRed(tile_image,ScaleCharToQuantum(xcfdata->red),q); + SetPixelGreen(tile_image,ScaleCharToQuantum(xcfdata->green),q); + SetPixelBlue(tile_image,ScaleCharToQuantum(xcfdata->blue),q); + SetPixelAlpha(tile_image,xcfdata->alpha == 0U ? OpaqueAlpha : + ScaleCharToQuantum((unsigned char) inLayerInfo->alpha),q); xcfdata++; - q++; + q+=GetPixelChannels(tile_image); } } if (SyncAuthenticPixels(tile_image,exception) == MagickFalse) break; } - xcfodata=(XCFPixelPacket *) RelinquishMagickMemory(xcfodata); + xcfodata=(XCFPixelInfo *) RelinquishMagickMemory(xcfodata); return MagickTrue; } static MagickBooleanType load_tile_rle(Image *image,Image *tile_image, - XCFDocInfo *inDocInfo,XCFLayerInfo *inLayerInfo,size_t data_length) + XCFDocInfo *inDocInfo,XCFLayerInfo *inLayerInfo,size_t data_length, + ExceptionInfo *exception) { - ExceptionInfo - *exception; - MagickOffsetType size; - register PixelPacket + register Quantum *q; size_t @@ -440,7 +435,7 @@ static MagickBooleanType load_tile_rle(Image *image,Image *tile_image, xcfodata=xcfdata; count=ReadBlob(image, (size_t) data_length, xcfdata); xcfdatalimit = xcfodata+count-1; - exception=(&image->exception); + exception=(exception); for (i=0; i < (ssize_t) bytes_per_pixel; i++) { q=GetAuthenticPixels(tile_image,0,0,tile_image->columns,tile_image->rows, @@ -474,41 +469,40 @@ static MagickBooleanType load_tile_rle(Image *image,Image *tile_image, { case 0: { - SetRedPixelComponent(q,ScaleCharToQuantum(data)); - if (inDocInfo->image_type == GIMP_GRAY) + if (inDocInfo->image_type != GIMP_GRAY) { - SetGreenPixelComponent(q,ScaleCharToQuantum(data)); - SetBluePixelComponent(q,ScaleCharToQuantum(data)); - SetAlphaPixelComponent(q,ScaleCharToQuantum( - (unsigned char) inLayerInfo->opacity)); + SetPixelRed(tile_image,ScaleCharToQuantum(data),q); + SetPixelGreen(tile_image,ScaleCharToQuantum(data),q); + SetPixelBlue(tile_image,ScaleCharToQuantum(data),q); + SetPixelAlpha(tile_image,ScaleCharToQuantum( + (unsigned char) inLayerInfo->alpha),q); } else { - SetGreenPixelComponent(q,GetRedPixelComponent(q)); - SetBluePixelComponent(q,GetRedPixelComponent(q)); - SetAlphaPixelComponent(q,ScaleCharToQuantum( - (unsigned char) inLayerInfo->opacity)); + SetPixelGray(tile_image,ScaleCharToQuantum(data),q); + SetPixelAlpha(tile_image,ScaleCharToQuantum( + (unsigned char) inLayerInfo->alpha),q); } break; } case 1: { - SetGreenPixelComponent(q,ScaleCharToQuantum(data)); + SetPixelGreen(tile_image,ScaleCharToQuantum(data),q); break; } case 2: { - SetBluePixelComponent(q,ScaleCharToQuantum(data)); + SetPixelBlue(tile_image,ScaleCharToQuantum(data),q); break; } case 3: { - SetAlphaPixelComponent(q,data == 0 ? OpaqueOpacity : - ScaleCharToQuantum((unsigned char) inLayerInfo->opacity)); + SetPixelAlpha(tile_image,data == 0 ? OpaqueAlpha : + ScaleCharToQuantum((unsigned char) inLayerInfo->alpha),q); break; } } - q++; + q+=GetPixelChannels(tile_image); } } else @@ -534,41 +528,40 @@ static MagickBooleanType load_tile_rle(Image *image,Image *tile_image, { case 0: { - SetRedPixelComponent(q,ScaleCharToQuantum(data)); - if (inDocInfo->image_type == GIMP_GRAY) + if (inDocInfo->image_type != GIMP_GRAY) { - SetGreenPixelComponent(q,ScaleCharToQuantum(data)); - SetBluePixelComponent(q,ScaleCharToQuantum(data)); - SetAlphaPixelComponent(q,ScaleCharToQuantum( - (unsigned char) inLayerInfo->opacity)); + SetPixelRed(tile_image,ScaleCharToQuantum(data),q); + SetPixelGreen(tile_image,ScaleCharToQuantum(data),q); + SetPixelBlue(tile_image,ScaleCharToQuantum(data),q); + SetPixelAlpha(tile_image,ScaleCharToQuantum( + (unsigned char) inLayerInfo->alpha),q); } else { - SetGreenPixelComponent(q,GetRedPixelComponent(q)); - SetBluePixelComponent(q,GetRedPixelComponent(q)); - SetAlphaPixelComponent(q,ScaleCharToQuantum( - (unsigned char) inLayerInfo->opacity)); + SetPixelGray(tile_image,ScaleCharToQuantum(data),q); + SetPixelAlpha(tile_image,ScaleCharToQuantum( + (unsigned char) inLayerInfo->alpha),q); } break; } case 1: { - SetGreenPixelComponent(q,ScaleCharToQuantum(data)); + SetPixelGreen(tile_image,ScaleCharToQuantum(data),q); break; } case 2: { - SetBluePixelComponent(q,ScaleCharToQuantum(data)); + SetPixelBlue(tile_image,ScaleCharToQuantum(data),q); break; } case 3: { - SetAlphaPixelComponent(q,data == 0 ? OpaqueOpacity : - ScaleCharToQuantum((unsigned char) inLayerInfo->opacity)); + SetPixelAlpha(tile_image,data == 0 ? OpaqueAlpha : + ScaleCharToQuantum((unsigned char) inLayerInfo->alpha),q); break; } } - q++; + q+=GetPixelChannels(tile_image); } } } @@ -653,15 +646,18 @@ static MagickBooleanType load_level(Image *image,XCFDocInfo *inDocInfo, /* seek to the tile offset */ offset=SeekBlob(image, offset, SEEK_SET); - /* allocate the image for the tile - NOTE: the last tile in a row or column may not be a full tile! + /* + Allocate the image for the tile. NOTE: the last tile in a row or + column may not be a full tile! */ tile_image_width=(size_t) (destLeft == (int) ntile_cols-1 ? (int) width % TILE_WIDTH : TILE_WIDTH); - if (tile_image_width == 0) tile_image_width=TILE_WIDTH; + if (tile_image_width == 0) + tile_image_width=TILE_WIDTH; tile_image_height = (size_t) (destTop == (int) ntile_rows-1 ? (int) height % TILE_HEIGHT : TILE_HEIGHT); - if (tile_image_height == 0) tile_image_height=TILE_HEIGHT; + if (tile_image_height == 0) + tile_image_height=TILE_HEIGHT; tile_image=CloneImage(inLayerInfo->image,tile_image_width, tile_image_height,MagickTrue,exception); @@ -669,12 +665,12 @@ static MagickBooleanType load_level(Image *image,XCFDocInfo *inDocInfo, switch (inDocInfo->compression) { case COMPRESS_NONE: - if (load_tile(image,tile_image,inDocInfo,inLayerInfo,(size_t) (offset2-offset)) == 0) + if (load_tile(image,tile_image,inDocInfo,inLayerInfo,(size_t) (offset2-offset),exception) == 0) status=MagickTrue; break; case COMPRESS_RLE: if (load_tile_rle (image,tile_image,inDocInfo,inLayerInfo, - (int) (offset2-offset)) == 0) + (int) (offset2-offset),exception) == 0) status=MagickTrue; break; case COMPRESS_ZLIB: @@ -686,8 +682,8 @@ static MagickBooleanType load_level(Image *image,XCFDocInfo *inDocInfo, } /* composite the tile onto the layer's image, and then destroy it */ - (void) CompositeImage(inLayerInfo->image,CopyCompositeOp,tile_image, - destLeft * TILE_WIDTH,destTop*TILE_HEIGHT); + (void) CompositeImage(inLayerInfo->image,tile_image,CopyCompositeOp, + MagickTrue,destLeft*TILE_WIDTH,destTop*TILE_HEIGHT,exception); tile_image=DestroyImage(tile_image); /* adjust tile position */ @@ -764,7 +760,7 @@ static MagickBooleanType load_hierarchy(Image *image,XCFDocInfo *inDocInfo, } static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo, - XCFLayerInfo *outLayer ) + XCFLayerInfo *outLayer, ExceptionInfo *exception ) { MagickOffsetType offset; @@ -783,10 +779,10 @@ static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo, outLayer->height = ReadBlobMSBLong(image); outLayer->type = ReadBlobMSBLong(image); (void) ReadBlobStringWithLongSize(image, outLayer->name, - sizeof(outLayer->name)); + sizeof(outLayer->name),exception); /* allocate the image for this layer */ outLayer->image=CloneImage(image,outLayer->width, outLayer->height,MagickTrue, - &image->exception); + exception); if (outLayer->image == (Image *) NULL) return MagickFalse; /* read the layer properties! */ @@ -806,7 +802,7 @@ static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo, outLayer->floating_offset = ReadBlobMSBLong(image); break; case PROP_OPACITY: - outLayer->opacity = ReadBlobMSBLong(image); + outLayer->alpha = ReadBlobMSBLong(image); break; case PROP_VISIBLE: outLayer->visible = ReadBlobMSBLong(image); @@ -839,7 +835,7 @@ static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo, case PROP_PARASITES: { if (DiscardBlobBytes(image,prop_size) == MagickFalse) - ThrowFileException(&image->exception,CorruptImageError, + ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); /* @@ -882,9 +878,9 @@ static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo, if (foundPropEnd == MagickFalse) return(MagickFalse); /* clear the image based on the layer opacity */ - outLayer->image->background_color.opacity= - ScaleCharToQuantum((unsigned char) (255-outLayer->opacity)); - (void) SetImageBackgroundColor(outLayer->image); + outLayer->image->background_color.alpha= + ScaleCharToQuantum((unsigned char) (255-outLayer->alpha)); + (void) SetImageBackgroundColor(outLayer->image,exception); /* set the compositing mode */ outLayer->image->compose = GIMPBlendModeToCompositeOperator( outLayer->mode ); @@ -901,7 +897,7 @@ static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo, /* read in the hierarchy */ offset=SeekBlob(image, (MagickOffsetType) hierarchy_offset, SEEK_SET); if (offset < 0) - (void) ThrowMagickException(&image->exception,GetMagickModule(), + (void) ThrowMagickException(exception,GetMagickModule(), CorruptImageError,"InvalidImageHeader","`%s'",image->filename); if (load_hierarchy (image, inDocInfo, outLayer) == 0) return(MagickFalse); @@ -1009,7 +1005,7 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); - image=AcquireImage(image_info); + image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { @@ -1044,7 +1040,7 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) else if (image_type == GIMP_INDEXED) ThrowReaderException(CoderError,"ColormapTypeNotSupported"); - (void) SetImageBackgroundColor(image); + (void) SetImageBackgroundColor(image,exception); image->matte=MagickTrue; /* Read properties. @@ -1066,7 +1062,7 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) */ size_t num_colours = ReadBlobMSBLong(image); if (DiscardBlobBytes(image,3*num_colours) == MagickFalse) - ThrowFileException(&image->exception,CorruptImageError, + ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); /* if (info->file_version == 0) @@ -1114,7 +1110,7 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) { /* just skip it - we don't care about guides */ if (DiscardBlobBytes(image,prop_size) == MagickFalse) - ThrowFileException(&image->exception,CorruptImageError, + ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); } break; @@ -1137,8 +1133,8 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) /* BOGUS: we don't write these yet because we aren't reading them properly yet :( - image->x_resolution = xres; - image->y_resolution = yres; + image->resolution.x = xres; + image->resolution.y = yres; */ } break; @@ -1154,7 +1150,7 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) { /* BOGUS: we may need these for IPTC stuff */ if (DiscardBlobBytes(image,prop_size) == MagickFalse) - ThrowFileException(&image->exception,CorruptImageError, + ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); /* gssize_t base = info->cp; @@ -1183,8 +1179,8 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) { /* BOGUS: just skip it for now */ if (DiscardBlobBytes(image,prop_size) == MagickFalse) - ThrowFileException(&image->exception,CorruptImageError, - "UnexpectedEndOfFile",image->filename); + ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", + image->filename); /* PathList *paths = xcf_load_bzpaths (gimage, info); @@ -1201,7 +1197,7 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) /* size_t digits = */ (void) ReadBlobMSBLong(image); for (i=0; i<5; i++) (void) ReadBlobStringWithLongSize(image, unit_string, - sizeof(unit_string)); + sizeof(unit_string),exception); } break; @@ -1293,7 +1289,8 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) /* seek to the layer offset */ offset=SeekBlob(image,offset,SEEK_SET); /* read in the layer */ - layer_ok=ReadOneLayer(image,&doc_info,&layer_info[current_layer]); + layer_ok=ReadOneLayer(image,&doc_info,&layer_info[current_layer], + exception); if (layer_ok == MagickFalse) { int j; @@ -1313,8 +1310,8 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) /* Composite the layer data onto the main image, dispose the layer. */ - (void) CompositeImage(image,OverCompositeOp,layer_info[0].image, - layer_info[0].offset_x,layer_info[0].offset_y); + (void) CompositeImage(image,layer_info[0].image,OverCompositeOp, + MagickTrue,layer_info[0].offset_x,layer_info[0].offset_y,exception); layer_info[0].image =DestroyImage( layer_info[0].image); } else @@ -1327,11 +1324,11 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) /* BOGUS: need to consider layer blending modes!! */ if ( layer_info[j].visible ) { /* only visible ones, please! */ - CompositeImage(image, OverCompositeOp, layer_info[j].image, - layer_info[j].offset_x, layer_info[j].offset_y ); + CompositeImage(image, layer_info[j].image, OverCompositeOp, + MagickTrue, layer_info[j].offset_x, layer_info[j].offset_y ); layer_info[j].image =DestroyImage( layer_info[j].image ); - /* Bob says that if we do this, we'll get REAL gray images! */ + /* If we do this, we'll get REAL gray images! */ if ( image_type == GIMP_GRAY ) { QuantizeInfo qi; GetQuantizeInfo(&qi); @@ -1347,12 +1344,11 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) signed int j; /* first we copy the last layer on top of the main image */ - (void) CompositeImage(image,CopyCompositeOp, - layer_info[number_layers-1].image, - layer_info[number_layers-1].offset_x, - layer_info[number_layers-1].offset_y); - layer_info[number_layers-1].image=DestroyImage( - layer_info[number_layers-1].image); + (void) CompositeImage(image,layer_info[number_layers-1].image, + CopyCompositeOp,MagickTrue,layer_info[number_layers-1].offset_x, + layer_info[number_layers-1].offset_y,exception); + layer_info[number_layers-1].image=DestroyImage( + layer_info[number_layers-1].image); /* now reverse the order of the layers as they are put into subimages