From: cristy Date: Wed, 1 Feb 2012 20:55:21 +0000 (+0000) Subject: (no commit message) X-Git-Tag: 7.0.1-0~6274 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=374b8ad2958410591db2e8c42e9b65ef89655e00;p=imagemagick --- diff --git a/coders/psd.c b/coders/psd.c index 602424999..8f83c5c0c 100644 --- a/coders/psd.c +++ b/coders/psd.c @@ -143,6 +143,7 @@ typedef struct _PSDInfo unsigned short channels, + color_channels, version; unsigned char @@ -696,14 +697,17 @@ static MagickBooleanType ReadPSDLayer(Image *image,const size_t channels, if (image->colorspace == CMYKColorspace) SetPixelBlack(image,pixel,q); else - SetPixelAlpha(image,pixel,q); + if (image->matte != MagickFalse) + SetPixelAlpha(image,pixel,q); break; } case 4: { - if ((IsRGBColorspace(image->colorspace) == MagickTrue) && (channels > 3)) + if ((IsRGBColorspace(image->colorspace) == MagickTrue) && + (channels > 3)) break; - SetPixelAlpha(image,pixel,q); + if (image->matte != MagickFalse) + SetPixelAlpha(image,pixel,q); break; } default: @@ -734,6 +738,7 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) *layer_info; MagickBooleanType + check_background, status; MagickOffsetType @@ -798,6 +803,7 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); count=ReadBlob(image,6,psd_info.reserved); psd_info.channels=ReadBlobMSBShort(image); + psd_info.color_channels=psd_info.channels; if (psd_info.channels > MaxPSDChannels) ThrowReaderException(CorruptImageError,"MaximumChannelsExceeded"); psd_info.rows=ReadBlobMSBLong(image); @@ -829,14 +835,17 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) image->matte=psd_info.channels >= 4 ? MagickTrue : MagickFalse; if (psd_info.mode == LabMode) image->colorspace=LabColorspace; + psd_info.color_channels=3; if (psd_info.mode == CMYKMode) { + psd_info.color_channels=4; image->colorspace=CMYKColorspace; image->matte=psd_info.channels >= 5 ? MagickTrue : MagickFalse; } if ((psd_info.mode == BitmapMode) || (psd_info.mode == GrayscaleMode) || (psd_info.mode == DuotoneMode)) { + psd_info.color_channels=1; if (AcquireImageColormap(image,256,exception) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); image->matte=psd_info.channels >= 2 ? MagickTrue : MagickFalse; @@ -845,9 +854,7 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) " Image colormap allocated"); image->colorspace=GRAYColorspace; } - if (image->debug != MagickFalse) - (void) LogMagickEvent(CoderEvent,GetMagickModule(), - image->matte ? " image has matte" : " image has no matte"); + image->matte=MagickFalse; /* Read PSD raster colormap only present for indexed and duotone images. */ @@ -885,7 +892,7 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) for (i=0; i < (ssize_t) image->colors; i++) image->colormap[i].blue=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); - image->matte=psd_info.channels >= 2 ? MagickTrue : MagickFalse; + image->matte=MagickFalse; } } length=ReadBlobMSBLong(image); @@ -927,12 +934,13 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) length=ReadBlobMSBLong(image); length=ReadBlobMSBLong(image); } + check_background=MagickFalse; if ((image_info->number_scenes == 1) && (image_info->scene == 0)) { - if (DiscardBlobBytes(image,length) == MagickFalse) - ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", - image->filename); - length=0; + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + " read composite only"); + check_background=MagickTrue; } if (length == 0) { @@ -978,6 +986,12 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) } if (size != 0) { + image->matte=psd_info.channels > psd_info.color_channels ? MagickTrue : MagickFalse; + + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + image->matte ? " image has matte" : " image has no matte"); + MagickOffsetType layer_offset; @@ -1025,6 +1039,19 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) layer_info[i].page.width=(ssize_t) (x-layer_info[i].page.x); layer_info[i].page.height=(ssize_t) (y-layer_info[i].page.y); layer_info[i].channels=ReadBlobMSBShort(image); + if (check_background == MagickTrue) + { + size_t + quantum; + + if (layer_info[i].channels == psd_info.color_channels) + image->matte=MagickFalse; + quantum=psd_info.version == 1 ? 4UL : 8UL; + if (DiscardBlobBytes(image,length-20-quantum) == MagickFalse) + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } if (layer_info[i].channels > MaxPSDChannels) ThrowReaderException(CorruptImageError,"MaximumChannelsExceeded"); if (image->debug != MagickFalse) @@ -1232,166 +1259,170 @@ static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) SetImageProperty(layer_info[i].image,"label",(char *) layer_info[i].name,exception); } - if (image->debug != MagickFalse) - (void) LogMagickEvent(CoderEvent,GetMagickModule(), - " reading image data for layers"); - /* - Read pixel data for each layer. - */ - for (i=0; i < number_layers; i++) - { - if (image->debug != MagickFalse) - (void) LogMagickEvent(CoderEvent,GetMagickModule(), - " reading data for layer %.20g",(double) i); - for (j=0; j < (ssize_t) layer_info[i].channels; j++) - { - if (image->debug != MagickFalse) - (void) LogMagickEvent(CoderEvent,GetMagickModule(), - " reading data for channel %.20g",(double) j); -#if 1 - if (layer_info[i].channel_info[j].size <= (2*layer_info[i].image->rows)) - { - ssize_t - k; - - if (image->debug != MagickFalse) - (void) LogMagickEvent(CoderEvent,GetMagickModule(), - " layer data is empty"); - /* - A layer without data. - */ - for (k=0; k < (ssize_t) layer_info[i].channel_info[j].size; k++) - (void) ReadBlobByte(layer_info[i].image); - continue; - } + if (check_background == MagickFalse) + { + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + " reading image data for layers"); + /* + Read pixel data for each layer. + */ + for (i=0; i < number_layers; i++) + { + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + " reading data for layer %.20g",(double) i); + for (j=0; j < (ssize_t) layer_info[i].channels; j++) + { + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + " reading data for channel %.20g",(double) j); +#if 1 + if (layer_info[i].channel_info[j].size <= (2*layer_info[i].image->rows)) + { + ssize_t + k; + + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + " layer data is empty"); + /* + A layer without data. + */ + for (k=0; k < (ssize_t) layer_info[i].channel_info[j].size; k++) + (void) ReadBlobByte(layer_info[i].image); + continue; + } #endif - offsets=(MagickOffsetType *) NULL; - layer_info[i].image->compression=NoCompression; - compression=ReadBlobMSBShort(layer_info[i].image); - if ((layer_info[i].page.height != 0) && - (layer_info[i].page.width != 0)) + offsets=(MagickOffsetType *) NULL; + layer_info[i].image->compression=NoCompression; + compression=ReadBlobMSBShort(layer_info[i].image); + if ((layer_info[i].page.height != 0) && + (layer_info[i].page.width != 0)) + { + if (compression == 1) + { + /* + Read RLE compressed data. + */ + layer_info[i].image->compression=RLECompression; + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + " layer data is RLE compressed"); + offsets=(MagickOffsetType *) AcquireQuantumMemory( + layer_info[i].image->rows,sizeof(*offsets)); + if (offsets == (MagickOffsetType *) NULL) + ThrowReaderException(ResourceLimitError, + "MemoryAllocationFailed"); + for (y=0; y < (ssize_t) layer_info[i].image->rows; y++) + offsets[y]=GetPSDOffset(&psd_info, + layer_info[i].image); + } + status=ReadPSDLayer(layer_info[i].image, + layer_info[i].channels, + layer_info[i].channel_info[j].type,offsets,exception); + if (compression == 1) + offsets=(MagickOffsetType *) RelinquishMagickMemory( + offsets); + if (status == MagickFalse) + break; + } + } + if (layer_info[i].opacity != OpaqueAlpha) + { + /* + Correct for opacity level. + */ + for (y=0; y < (ssize_t) layer_info[i].image->rows; y++) + { + q=GetAuthenticPixels(layer_info[i].image,0,y, + layer_info[i].image->columns,1,exception); + if (q == (Quantum *) NULL) + break; + for (x=0; x < (ssize_t) layer_info[i].image->columns; x++) + { + SetPixelAlpha(layer_info[i].image,(Quantum) + (QuantumScale*(GetPixelAlpha(layer_info[i].image,q))* + layer_info[i].opacity),q); + q+=GetPixelChannels(layer_info[i].image); + } + if (SyncAuthenticPixels(layer_info[i].image,exception) == MagickFalse) + break; + } + } + if (layer_info[i].image->colorspace == CMYKColorspace) + (void) NegateImage(layer_info[i].image,MagickFalse,exception); + status=SetImageProgress(image,LoadImagesTag,i,(MagickSizeType) + number_layers); + if (status == MagickFalse) + break; + } + /* added by palf -> invisible group layer make layer of this group + invisible I consider that all layer with width and height null are + layer for group layer */ + { + short inside_layer = 0; + short layer_visible = 0; + for (i=number_layers-1; i >=0; i--) + { + if ((layer_info[i].page.width == 0) || + (layer_info[i].page.height == 0)) { - if (compression == 1) + if (inside_layer == 0) { - /* - Read RLE compressed data. - */ - layer_info[i].image->compression=RLECompression; - if (image->debug != MagickFalse) - (void) LogMagickEvent(CoderEvent,GetMagickModule(), - " layer data is RLE compressed"); - offsets=(MagickOffsetType *) AcquireQuantumMemory( - layer_info[i].image->rows,sizeof(*offsets)); - if (offsets == (MagickOffsetType *) NULL) - ThrowReaderException(ResourceLimitError, - "MemoryAllocationFailed"); - for (y=0; y < (ssize_t) layer_info[i].image->rows; y++) - offsets[y]=GetPSDOffset(&psd_info,layer_info[i].image); + inside_layer=1; + layer_visible=(short int) layer_info[i].visible; + } + else + { + inside_layer = 0; } - status=ReadPSDLayer(layer_info[i].image, - layer_info[i].channels,layer_info[i].channel_info[j].type, - offsets,exception); - if (compression == 1) - offsets=(MagickOffsetType *) RelinquishMagickMemory( - offsets); - if (status == MagickFalse) - break; } - } - if (layer_info[i].opacity != OpaqueAlpha) - { - /* - Correct for opacity level. - */ - for (y=0; y < (ssize_t) layer_info[i].image->rows; y++) - { - q=GetAuthenticPixels(layer_info[i].image,0,y, - layer_info[i].image->columns,1,exception); - if (q == (Quantum *) NULL) - break; - for (x=0; x < (ssize_t) layer_info[i].image->columns; x++) + else + if ((inside_layer == 1) && (layer_visible == 0)) { - SetPixelAlpha(layer_info[i].image,(Quantum) - (QuantumScale*(GetPixelAlpha(layer_info[i].image,q))* - layer_info[i].opacity),q); - q+=GetPixelChannels(layer_info[i].image); + layer_info[i].visible=(unsigned char) layer_visible; + layer_info[i].image->compose=NoCompositeOp; } - if (SyncAuthenticPixels(layer_info[i].image,exception) == MagickFalse) - break; - } - } - if (layer_info[i].image->colorspace == CMYKColorspace) - (void) NegateImage(layer_info[i].image,MagickFalse,exception); - status=SetImageProgress(image,LoadImagesTag,i,(MagickSizeType) - number_layers); - if (status == MagickFalse) - break; + } } - /* added by palf -> invisible group layer make layer of this group - invisible I consider that all layer with width and height null are - layer for group layer */ - { - short inside_layer = 0; - short layer_visible = 0; - for (i=number_layers-1; i >=0; i--) - { - if ((layer_info[i].page.width == 0) || - (layer_info[i].page.height == 0)) + /* added by palf -> suppression of empty layer */ + /* I consider that all layer with width and height null are layer for group layer */ + for (i=0; i < number_layers; i++) + { + if ((layer_info[i].page.width == 0) || + (layer_info[i].page.height == 0)) + { + if (layer_info[i].image != (Image *) NULL) + layer_info[i].image=DestroyImage(layer_info[i].image); + for (j=i; j < number_layers - 1; j++) + layer_info[j] = layer_info[j+1]; + number_layers--; + i--; + } + } + mask_size = ReadBlobMSBLong(image); /* global mask size: currently ignored */ + (void) mask_size; + if (number_layers > 0) { - if (inside_layer == 0) - { - inside_layer=1; - layer_visible=(short int) layer_info[i].visible; - } - else - { - inside_layer = 0; - } - } - else - if ((inside_layer == 1) && (layer_visible == 0)) + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + " putting layers into image list"); + for (i=0; i < number_layers; i++) { - layer_info[i].visible=(unsigned char) layer_visible; - layer_info[i].image->compose=NoCompositeOp; + if (i > 0) + layer_info[i].image->previous=layer_info[i-1].image; + if (i < (number_layers-1)) + layer_info[i].image->next=layer_info[i+1].image; + layer_info[i].image->page=layer_info[i].page; } + image->next=layer_info[0].image; + layer_info[0].image->previous=image; + layer_info=(LayerInfo *) RelinquishMagickMemory(layer_info); + } + layer_offset-=TellBlob(image); + offset=SeekBlob(image,layer_offset,SEEK_CUR); } - } - /* added by palf -> suppression of empty layer */ - /* I consider that all layer with width and height null are layer for group layer */ - for (i=0; i < number_layers; i++) - { - if ((layer_info[i].page.width == 0) || - (layer_info[i].page.height == 0)) - { - if (layer_info[i].image != (Image *) NULL) - layer_info[i].image=DestroyImage(layer_info[i].image); - for (j=i; j < number_layers - 1; j++) - layer_info[j] = layer_info[j+1]; - number_layers--; - i--; - } - } - mask_size = ReadBlobMSBLong(image); /* global mask size: currently ignored */ - (void) mask_size; - if (number_layers > 0) - { - if (image->debug != MagickFalse) - (void) LogMagickEvent(CoderEvent,GetMagickModule(), - " putting layers into image list"); - for (i=0; i < number_layers; i++) - { - if (i > 0) - layer_info[i].image->previous=layer_info[i-1].image; - if (i < (number_layers-1)) - layer_info[i].image->next=layer_info[i+1].image; - layer_info[i].image->page=layer_info[i].page; - } - image->next=layer_info[0].image; - layer_info[0].image->previous=image; - layer_info=(LayerInfo *) RelinquishMagickMemory(layer_info); - } - layer_offset-=TellBlob(image); - offset=SeekBlob(image,layer_offset,SEEK_CUR); } } /*