Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 311575 Details for
Bug 454982
CVE-2008-3134 GraphicsMagick/ImageMagick: multiple crash or DoS issues
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
The relevant GraphicsMagick changes extraced from GM's CVS
GraphicsMagick-security-fixes.patch (text/plain), 127.12 KB, created by
Hans de Goede
on 2008-07-11 13:51:46 UTC
(
hide
)
Description:
The relevant GraphicsMagick changes extraced from GM's CVS
Filename:
MIME Type:
Creator:
Hans de Goede
Created:
2008-07-11 13:51:46 UTC
Size:
127.12 KB
patch
obsolete
>Index: coders/avi.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/avi.c,v >retrieving revision 1.103 >retrieving revision 1.104 >diff -u -u -r1.103 -r1.104 >--- coders/avi.c 5 May 2008 02:32:49 -0000 1.103 >+++ coders/avi.c 7 Jun 2008 23:30:46 -0000 1.104 >@@ -137,7 +137,7 @@ > % > % > */ >-static unsigned int DecodeImage(Image *image,const unsigned int compression, >+static MagickPassFail DecodeImage(Image *image,const unsigned int compression, > unsigned char *pixels) > { > int >@@ -166,16 +166,16 @@ > { > if (q < pixels || q >= end) > break; >- count=ReadBlobByte(image); >- if (count == EOF) >- break; >+ if ((count=ReadBlobByte(image)) == EOF) >+ goto unexpected_eof; > if (count != 0) > { > count=Min(count, end - q); > /* > Encoded mode. > */ >- byte=ReadBlobByte(image); >+ if ((byte=ReadBlobByte(image)) == EOF) >+ goto unexpected_eof; > for (i=0; i < count; i++) > { > if (compression == 1) >@@ -191,9 +191,10 @@ > /* > Escape mode. > */ >- count=ReadBlobByte(image); >+ if ((count=ReadBlobByte(image)) == EOF) >+ goto unexpected_eof; > if (count == 0x01) >- return(True); >+ return(MagickPass); > switch (count) > { > case 0x00: >@@ -211,8 +212,17 @@ > /* > Delta mode. > */ >- x+=ReadBlobByte(image); >- y+=ReadBlobByte(image); >+ if ((byte=ReadBlobByte(image)) == EOF) >+ goto unexpected_eof; >+ x+=byte; >+ if ((byte=ReadBlobByte(image)) == EOF) >+ goto unexpected_eof; >+ y+=byte; >+ if ((x >= (long) image->columns) || (y >= (long) image->rows)) >+ { >+ ThrowException(&image->exception,CorruptImageError,CorruptImage,NULL); >+ return MagickFail; >+ } > q=pixels+y*image->columns+x; > break; > } >@@ -225,11 +235,18 @@ > for (i=0; i < count; i++) > { > if (compression == 1) >- *q++=ReadBlobByte(image); >+ { >+ if ((byte=ReadBlobByte(image)) == EOF) >+ goto unexpected_eof; >+ *q++=byte; >+ } > else > { > if ((i & 0x01) == 0) >- byte=ReadBlobByte(image); >+ { >+ if ((byte=ReadBlobByte(image)) == EOF) >+ goto unexpected_eof; >+ } > *q++=(unsigned char) > ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f)); > } >@@ -241,11 +258,17 @@ > if (compression == 1) > { > if (count & 0x01) >- (void) ReadBlobByte(image); >+ { >+ if (ReadBlobByte(image) == EOF) >+ goto unexpected_eof; >+ } > } > else > if (((count & 0x03) == 1) || ((count & 0x03) == 2)) >- (void) ReadBlobByte(image); >+ { >+ if (ReadBlobByte(image) == EOF) >+ goto unexpected_eof; >+ } > break; > } > } >@@ -254,9 +277,15 @@ > if (!MagickMonitor(LoadImageText,y,image->rows,&image->exception)) > break; > } >- (void) ReadBlobByte(image); /* end of line */ >- (void) ReadBlobByte(image); >- return(True); >+ if (ReadBlobByte(image) == EOF) /* end of line */ >+ goto unexpected_eof; >+ if (ReadBlobByte(image) == EOF) >+ goto unexpected_eof; >+ return(MagickPass); >+ >+ unexpected_eof: >+ ThrowException(&image->exception,CorruptImageError,UnexpectedEndOfFile,NULL); >+ return MagickFail; > } > > /* >@@ -383,6 +412,9 @@ > count, > number_colors; > >+ MagickBool >+ first_chunk; >+ > /* > Open image file. > */ >@@ -398,13 +430,22 @@ > (void) memset(&bmp_info,0,sizeof(BMPInfo)); > colormap=(PixelPacket *) NULL; > number_colors=0; >+ first_chunk=MagickTrue; > for ( ; ; ) > { > count=ReadBlob(image,4,id); >- if (count == 0) >- break; >+ if (count != 4) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > id[4]='\0'; >+ if (first_chunk) >+ { >+ if (memcmp(id,"RIFF",4) != 0) >+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image); >+ first_chunk=MagickFalse; >+ } > chunk_size=ReadBlobLSBLong(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > if (chunk_size == 0) > break; > if (chunk_size & 0x01) >@@ -422,7 +463,8 @@ > bmp_info.compression); > ThrowException2(exception,CorruptImageError,message,image->filename); > for ( ; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > continue; > } > /* >@@ -450,11 +492,18 @@ > ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, > image); > if (LocaleCompare(id,"00db") == 0) >- (void) ReadBlob(image,bytes_per_line*image->rows,(char *) pixels); >+ { >+ size_t >+ size; >+ >+ size=bytes_per_line*image->rows; >+ if (ReadBlob(image,bytes_per_line*image->rows,(char *) pixels) != size) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } > else > { > status=DecodeImage(image,1,pixels); >- if (status == False) >+ if (status == MagickFail) > ThrowReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image); > } > /* >@@ -706,18 +755,22 @@ > avi_info.data_rate=ReadBlobLSBLong(image); > avi_info.start_time=ReadBlobLSBLong(image); > avi_info.data_length=ReadBlobLSBLong(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > continue; > } > if (LocaleCompare(id,"idx1") == 0) > { > for ( ; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > continue; > } > if (LocaleCompare(id,"JUNK") == 0) > { > for ( ; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > continue; > } > if (LocaleCompare(id,"LIST") == 0) >@@ -725,7 +778,8 @@ > /* > List of chunks. > */ >- (void) ReadBlob(image,4,id); >+ if (ReadBlob(image,4,id) != 4) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > if (image_info->verbose) > (void) fprintf(stdout," List type %.1024s\n",id); > continue; >@@ -735,7 +789,8 @@ > /* > File header. > */ >- (void) ReadBlob(image,4,id); >+ if (ReadBlob(image,4,id) != 4) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > if (image_info->verbose) > (void) fprintf(stdout," RIFF form type %.1024s\n",id); > continue; >@@ -754,13 +809,16 @@ > bmp_info.height=ReadBlobLSBLong(image); > bmp_info.planes=ReadBlobLSBShort(image); > bmp_info.bits_per_pixel=ReadBlobLSBShort(image); >- (void) ReadBlob(image,4,bmp_info.compression); >+ if (ReadBlob(image,4,bmp_info.compression) != 4) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > bmp_info.compression[4]='\0'; > bmp_info.image_size=ReadBlobLSBLong(image); > bmp_info.x_pixels=ReadBlobLSBLong(image); > bmp_info.y_pixels=ReadBlobLSBLong(image); > bmp_info.number_colors=ReadBlobLSBLong(image); > bmp_info.important_colors=ReadBlobLSBLong(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > chunk_size-=40; > number_colors=bmp_info.number_colors; > if ((number_colors == 0) && (bmp_info.bits_per_pixel <= 8)) >@@ -776,28 +834,33 @@ > colormap[i].blue=ScaleCharToQuantum(ReadBlobByte(image)); > colormap[i].green=ScaleCharToQuantum(ReadBlobByte(image)); > colormap[i].red=ScaleCharToQuantum(ReadBlobByte(image)); >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > chunk_size-=4; > } > } > for ( ; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > if (image_info->verbose) > (void) fprintf(stdout,"Video compression: %.1024s\n", > bmp_info.compression); > continue; > } > for ( ; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > continue; > } > if (LocaleCompare(id,"strh") == 0) > { > if (image_info->verbose) > (void) fprintf(stdout," Stream header\n"); >- (void) ReadBlob(image,4,stream_info.data_type); >+ if (ReadBlob(image,4,stream_info.data_type) != 4) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > stream_info.data_type[4]='\0'; >- (void) ReadBlob(image,4,stream_info.data_handler); >+ if (ReadBlob(image,4,stream_info.data_handler) != 4) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > stream_info.data_handler[4]='\0'; > stream_info.flags=ReadBlobLSBLong(image); > stream_info.priority=ReadBlobLSBLong(image); >@@ -809,10 +872,13 @@ > stream_info.buffer_size=ReadBlobLSBLong(image); > stream_info.quality=ReadBlobLSBLong(image); > stream_info.sample_size=ReadBlobLSBLong(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > if (chunk_size & 0x01) > chunk_size++; > for (chunk_size-=48; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > if (image_info->verbose) > (void) fprintf(stdout,"AVI Test handler: %.1024s\n", > stream_info.data_handler); >@@ -821,19 +887,22 @@ > if (LocaleCompare(id,"strn") == 0) > { > for ( ; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > continue; > } > if (LocaleCompare(id,"vedt") == 0) > { > for ( ; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > continue; > } > FormatString(message,"AVI chunk %.1024s not yet supported",id); > ThrowException2(exception,CorruptImageError,message,image->filename); > for ( ; chunk_size != 0; chunk_size--) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > continue; > } > while (image->previous != (Image *) NULL) >Index: coders/avs.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/avs.c,v >retrieving revision 1.93 >retrieving revision 1.94 >diff -u -u -r1.93 -r1.94 >--- coders/avs.c 5 May 2008 02:32:49 -0000 1.93 >+++ coders/avs.c 11 Jun 2008 00:19:58 -0000 1.94 >@@ -62,7 +62,8 @@ > % > % Method ReadAVSImage reads an AVS X image file and returns it. It > % allocates the memory necessary for the new Image structure and returns a >-% pointer to the new image. >+% pointer to the new image. Note that these files often have the extension >+% 'X' which conflicts with our X11 support coder. > % > % The format of the ReadAVSImage method is: > % >@@ -80,6 +81,8 @@ > % > % > */ >+#define AVS_WIDTH_LIMIT 65536 /* Artificially limit width to 64K pixels */ >+#define AVS_HEIGHT_LIMIT 65536 /* Artificially limit height to 64K pixels */ > static Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception) > { > Image >@@ -97,9 +100,6 @@ > register unsigned char > *p; > >- size_t >- count; >- > unsigned char > *pixels; > >@@ -119,17 +119,26 @@ > assert(exception->signature == MagickSignature); > image=AllocateImage(image_info); > status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); >- if (status == False) >+ if (status == MagickFail) > ThrowReaderException(FileOpenError,UnableToOpenFile,image); > /* > Read AVS image. > */ > width=ReadBlobMSBLong(image); > height=ReadBlobMSBLong(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ > (void) LogMagickEvent(CoderEvent,GetMagickModule(), > "AVS dimensions %ldx%ld",width,height); >- if (EOFBlob(image)) >- ThrowReaderException(CorruptImageError,ImproperImageHeader,image); >+ >+ /* >+ Impose a maximum width and height limit in order to avoid >+ incredibly huge allocations. >+ */ >+ if ((width > AVS_WIDTH_LIMIT) || (height > AVS_HEIGHT_LIMIT)) >+ ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image); >+ > do > { > /* >@@ -144,19 +153,25 @@ > if (image_info->ping && (image_info->subrange != 0)) > if (image->scene >= (image_info->subimage+image_info->subrange-1)) > break; >- row_bytes=4*image->columns; >- pixels=MagickAllocateMemory(unsigned char *,row_bytes); >+ pixels=MagickAllocateArray(unsigned char *,image->columns,4); > if (pixels == (unsigned char *) NULL) > ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >+ row_bytes=4*image->columns; > for (y=0; y < (long) image->rows; y++) > { >- count=ReadBlob(image,row_bytes,pixels); >- if (count == 0) >- ThrowReaderException(CorruptImageError,UnableToReadImageData,image); >+ if (ReadBlob(image,row_bytes,pixels) != row_bytes) >+ { >+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, >+ image->filename); >+ status=MagickFail; >+ } > p=pixels; > q=SetImagePixels(image,0,y,image->columns,1); > if (q == (PixelPacket *) NULL) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > for (x=0; x < (long) image->columns; x++) > { > q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p++)); >@@ -167,19 +182,25 @@ > q++; > } > if (!SyncImagePixels(image)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > if (image->previous == (Image *) NULL) > if (QuantumTick(y,image->rows)) > if (!MagickMonitor(LoadImageText,y,image->rows,exception)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } >+ if (MagickFail == status) >+ break; > } > MagickFreeMemory(pixels); >- if (EOFBlob(image)) >- { >- ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, >- image->filename); >- break; >- } >+ >+ if (MagickFail == status) >+ break; >+ > /* > Proceed to next image. > */ >@@ -188,7 +209,8 @@ > break; > width=ReadBlobMSBLong(image); > height=ReadBlobMSBLong(image); >- if (!(EOFBlob(image))) >+ if (!(EOFBlob(image)) && (width <= AVS_WIDTH_LIMIT) && >+ (height <= AVS_HEIGHT_LIMIT)) > { > /* > Allocate next image structure. >@@ -202,13 +224,20 @@ > image=SyncNextImageInList(image); > status=MagickMonitor(LoadImagesText,TellBlob(image),GetBlobSize(image), > exception); >- if (status == False) >+ if (status == MagickFail) > break; > } > } while (!(EOFBlob(image))); > while (image->previous != (Image *) NULL) > image=image->previous; > CloseBlob(image); >+ >+ if (MagickFail == status) >+ { >+ DestroyImageList(image); >+ image=(Image *) NULL; >+ } >+ > return(image); > } > >Index: coders/cineon.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/cineon.c,v >retrieving revision 1.24 >retrieving revision 1.25 >diff -u -u -r1.24 -r1.25 >--- coders/cineon.c 5 May 2008 02:32:49 -0000 1.24 >+++ coders/cineon.c 31 May 2008 22:53:40 -0000 1.25 >@@ -592,14 +592,29 @@ > unsigned char > *user_data; > >+ const size_t >+ block_size = 65536UL; >+ > size_t >+ read_size, > user_data_length; >- >- user_data_length=cin_file_info.user_defined_length; >- user_data=MagickAllocateMemory(unsigned char *,user_data_length); >- if (user_data == (unsigned char *) NULL) >- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >- offset += ReadBlob(image,user_data_length,user_data); >+ >+ user_data_length=0UL; >+ user_data=(unsigned char *) NULL; >+ while (user_data_length < cin_file_info.user_defined_length) >+ { >+ read_size=Min(block_size,cin_file_info.user_defined_length-user_data_length); >+ MagickReallocMemory(unsigned char *,user_data,user_data_length+read_size); >+ if (user_data == (unsigned char *) NULL) >+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >+ if (ReadBlob(image,read_size,user_data+user_data_length) != read_size) >+ { >+ MagickFreeMemory(user_data); >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } >+ user_data_length += read_size; >+ offset += read_size; >+ } > if (!SetImageProfile(image,"CINEONUSERDATA",user_data,user_data_length)) > { > MagickFreeMemory(user_data); >@@ -618,7 +633,8 @@ > Read remainder of header. > */ > for ( ; offset < pixels_offset ; offset++ ) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > > if (image->logging) > (void) LogMagickEvent(CoderEvent,GetMagickModule(), >Index: coders/dcm.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/dcm.c,v >retrieving revision 1.138 >retrieving revision 1.139 >diff -u -u -r1.138 -r1.139 >--- coders/dcm.c 5 May 2008 02:32:49 -0000 1.138 >+++ coders/dcm.c 7 Jun 2008 23:30:46 -0000 1.139 >@@ -42,6 +42,7 @@ > #include "magick/color.h" > #include "magick/constitute.h" > #include "magick/enhance.h" >+#include "magick/log.h" > #include "magick/magick.h" > #include "magick/monitor.h" > #include "magick/tempfile.h" >@@ -2746,9 +2747,14 @@ > /* > Read DCM preamble. > */ >- count=ReadBlob(image,128,(char *) magick); >- count=ReadBlob(image,4,(char *) magick); >- if ((count == 0) || (LocaleNCompare((char *) magick,"DICM",4) != 0)) >+ if ((count=ReadBlob(image,128,(char *) magick)) != 128) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ if ((count=ReadBlob(image,4,(char *) magick)) != 4) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "magick: \"%.4s\"",magick); >+ if (LocaleNCompare((char *) magick,"DICM",4) != 0) > (void) SeekBlob(image,0L,SEEK_SET); > /* > Read DCM Medical image. >@@ -2780,6 +2786,8 @@ > group=ReadBlobLSBShort(image); > element=ReadBlobLSBShort(image); > quantum=0; >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > /* > Find corresponding VR for this group and element. > */ >@@ -2788,7 +2796,8 @@ > (element == dicom_info[i].element)) > break; > (void) strlcpy(implicit_vr,dicom_info[i].vr,MaxTextExtent); >- count=ReadBlob(image,2,(char *) explicit_vr); >+ if ((count=ReadBlob(image,2,(char *) explicit_vr)) != 2) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > /* > Check for "explicitness", but meta-file headers always explicit. > */ >@@ -2814,15 +2823,24 @@ > (strcmp(explicit_vr,"OW") == 0) || (strcmp(explicit_vr,"SQ") == 0)) > { > (void) ReadBlobLSBShort(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > quantum=4; > } > } > datum=0; > if (quantum == 4) >- datum=(long) ReadBlobLSBLong(image); >- else >- if (quantum == 2) >+ { >+ datum=(long) ReadBlobLSBLong(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } >+ else if (quantum == 2) >+ { > datum=(long) ReadBlobLSBShort(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } > quantum=0; > length=1; > if (datum != 0) >@@ -2880,24 +2898,37 @@ > */ > data=(unsigned char *) NULL; > if ((length == 1) && (quantum == 1)) >- datum=ReadBlobByte(image); >- else >- if ((length == 1) && (quantum == 2)) >+ { >+ if ((datum=ReadBlobByte(image)) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } >+ else if ((length == 1) && (quantum == 2)) >+ { > datum=ReadBlobLSBShort(image); >- else >- if ((length == 1) && (quantum == 4)) >- datum=(long) ReadBlobLSBLong(image); >- else >- if ((quantum != 0) && (length != 0)) >- { >- if (length > ((~0UL)/quantum)) >- ThrowReaderException(CorruptImageError,ImproperImageHeader,image); >- data=MagickAllocateArray(unsigned char *,(length+1),quantum); >- if (data == (unsigned char *) NULL) >- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >- (void) ReadBlob(image,quantum*length,(char *) data); >- data[length*quantum]=0; >- } >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } >+ else if ((length == 1) && (quantum == 4)) >+ { >+ datum=(long) ReadBlobLSBLong(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } >+ else if ((quantum != 0) && (length != 0)) >+ { >+ size_t >+ size; >+ >+ if (length > ((~0UL)/quantum)) >+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image); >+ data=MagickAllocateArray(unsigned char *,(length+1),quantum); >+ if (data == (unsigned char *) NULL) >+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >+ size=quantum*length; >+ if (ReadBlob(image,size,(char *) data) != size) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ data[size]=0; >+ } > switch (group) > { > case 0x0002: >@@ -3279,7 +3310,10 @@ > { > q=GetImagePixels(image,0,y,image->columns,1); > if (q == (PixelPacket *) NULL) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > for (x=0; x < (long) image->columns; x++) > { > switch ((int) i) >@@ -3291,15 +3325,31 @@ > (MaxRGB-ScaleCharToQuantum(ReadBlobByte(image))); break; > default: break; > } >+ if (EOFBlob(image)) >+ { >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ status=MagickFail; >+ break; >+ } > q++; > } > if (!SyncImagePixels(image)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > if (image->previous == (Image *) NULL) > if (QuantumTick(y,image->rows)) > if (!MagickMonitor(LoadImageText,y,image->rows,exception)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } >+ if (status == MagickFail) >+ break; > } >+ if (status == MagickFail) >+ break; > } > } > else >@@ -3319,7 +3369,10 @@ > { > q=SetImagePixels(image,0,y,image->columns,1); > if (q == (PixelPacket *) NULL) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > indexes=GetIndexes(image); > for (x=0; x < (long) image->columns; x++) > { >@@ -3399,24 +3452,37 @@ > q->green=(Quantum) green; > q->blue=(Quantum) blue; > q++; >+ if (EOFBlob(image)) >+ { >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ status=MagickFail; >+ } > } > if (!SyncImagePixels(image)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > if (image->previous == (Image *) NULL) > if (QuantumTick(y,image->rows)) > if (!MagickMonitor(LoadImageText,y,image->rows,exception)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > } >- if (image->storage_class == PseudoClass) >- { >- if (bytes_per_pixel == 2) >- (void) NormalizeImage(image); >- } >+ if (status == MagickPass) >+ if (image->storage_class == PseudoClass) >+ { >+ if (bytes_per_pixel == 2) >+ (void) NormalizeImage(image); >+ } > } > if (EOFBlob(image)) > { > ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, > image->filename); >+ status=MagickFail; > break; > } > /* >@@ -3439,7 +3505,7 @@ > image=SyncNextImageInList(image); > status=MagickMonitor(LoadImagesText,TellBlob(image),GetBlobSize(image), > exception); >- if (status == False) >+ if (status == MagickFail) > break; > } > } >Index: coders/dpx.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/dpx.c,v >retrieving revision 1.131 >retrieving revision 1.132 >diff -u -u -r1.131 -r1.132 >--- coders/dpx.c 18 May 2008 23:57:33 -0000 1.131 >+++ coders/dpx.c 31 May 2008 22:53:40 -0000 1.132 >@@ -1857,23 +1857,35 @@ > */ > unsigned char > *user_data; >- >+ >+ const size_t >+ block_size = 65536UL; >+ > size_t >+ read_size, > user_data_length; > > DPXUserDefinedData > *dpx_user_data; >+ >+ user_data_length=0UL; >+ user_data=(unsigned char *) NULL; > >- user_data_length=dpx_file_info.user_defined_length; >- user_data=MagickAllocateMemory(unsigned char *,user_data_length); >- if (user_data == (unsigned char *) NULL) >- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >- offset += ReadBlob(image,user_data_length,user_data); >- if (offset != (2048U+user_data_length)) >+ while (user_data_length < dpx_file_info.user_defined_length) > { >- MagickFreeMemory(user_data); >- ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ read_size=Min(block_size,dpx_file_info.user_defined_length-user_data_length); >+ MagickReallocMemory(unsigned char *,user_data,user_data_length+read_size); >+ if (user_data == (unsigned char *) NULL) >+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >+ if (ReadBlob(image,read_size,user_data+user_data_length) != read_size) >+ { >+ MagickFreeMemory(user_data); >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } >+ user_data_length += read_size; >+ offset += read_size; > } >+ > dpx_user_data=(DPXUserDefinedData *) user_data; > StringToAttribute(image,"DPX:user.data.id",dpx_user_data->user_id); > if (!SetImageProfile(image,"DPXUSERDATA",user_data,user_data_length)) >@@ -2017,7 +2029,8 @@ > Read remainder of header. > */ > for ( ; offset < pixels_offset ; offset++ ) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > /* > Allocate row samples. > */ >Index: coders/ept.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/ept.c,v >retrieving revision 1.114 >retrieving revision 1.115 >diff -u -u -r1.114 -r1.115 >--- coders/ept.c 5 May 2008 02:32:50 -0000 1.114 >+++ coders/ept.c 11 Jun 2008 00:19:58 -0000 1.115 >@@ -206,14 +206,6 @@ > if (status == False) > ThrowReaderException(FileOpenError,UnableToOpenFile,image); > /* >- Open temporary output file. >- */ >- file=AcquireTemporaryFileStream(postscript_filename,BinaryFileIOMode); >- if (file == (FILE *) NULL) >- ThrowReaderTemporaryFileException(postscript_filename); >- FormatString(translate_geometry,"%g %g translate\n ",0.0,0.0); >- (void) fputs(translate_geometry,file); >- /* > Set the page geometry. > */ > dx_resolution=72.0; >@@ -227,6 +219,9 @@ > image->y_resolution=image->x_resolution; > } > FormatString(density,"%gx%g",image->x_resolution,image->y_resolution); >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Density: %s", density); > SetGeometry(image,&page); > page.width=612; > page.height=792; >@@ -237,18 +232,36 @@ > (void) ReadBlobLSBLong(image); > count=ReadBlobLSBLong(image); > filesize=ReadBlobLSBLong(image); >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "File Size: %lu, Offset: %lu", >+ (unsigned long) filesize, (unsigned long) count); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > for (i=0; i < (long) (count-12); i++) >- (void) ReadBlobByte(image); >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ /* >+ Open temporary output file. >+ */ >+ file=AcquireTemporaryFileStream(postscript_filename,BinaryFileIOMode); >+ if (file == (FILE *) NULL) >+ ThrowReaderTemporaryFileException(postscript_filename); >+ FormatString(translate_geometry,"%g %g translate\n ",0.0,0.0); >+ (void) fputs(translate_geometry,file); > /* > Copy Postscript to temporary file. > */ > box.width=0; > box.height=0; > p=command; >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Copying Postscript to temporary file \"%s\" ...", >+ postscript_filename); > for (i=0; i < (long) filesize; i++) > { >- c=ReadBlobByte(image); >- if (c == EOF) >+ if ((c=ReadBlobByte(image)) == EOF) > break; > (void) fputc(c,file); > *p++=c; >@@ -286,12 +299,18 @@ > page.height=height; > box=page; > } >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Done copying."); > if (image_info->page != (char *) NULL) > (void) GetGeometry(image_info->page,&page.x,&page.y,&page.width, > &page.height); > FormatString(geometry,"%lux%lu", > (unsigned long) ceil(page.width*image->x_resolution/dx_resolution-0.5), > (unsigned long) ceil(page.height*image->y_resolution/dy_resolution-0.5)); >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Page geometry: %s",geometry); > if (ferror(file)) > { > (void) fclose(file); >@@ -335,7 +354,11 @@ > ThrowReaderException(FileOpenError,UnableToWriteFile,image); > (void) fputs("showpage\n",file); > (void) fclose(file); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Invoking Postscript delegate ..."); > status=InvokePostscriptDelegate(image_info->verbose,command); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Returned from Postscript delegate (status=%d) ...", status); > } > (void) LiberateTemporaryFile(postscript_filename); > (void) MagickMonitor(RenderPostscriptText,7,8,&image->exception); >Index: coders/fits.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/fits.c,v >retrieving revision 1.108 >retrieving revision 1.109 >diff -u -u -r1.108 -r1.109 >--- coders/fits.c 5 May 2008 02:32:50 -0000 1.108 >+++ coders/fits.c 11 Jun 2008 00:19:58 -0000 1.109 >@@ -190,7 +190,7 @@ > *p; > > size_t >- count; >+ row_octets; > > unsigned char > *fits_pixels, >@@ -230,12 +230,8 @@ > /* > Decode image header. > */ >- c=ReadBlobByte(image); >- if (c == EOF) >- { >- DestroyImage(image); >- return((Image *) NULL); >- } >+ if ((c=ReadBlobByte(image)) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > for ( ; ; ) > { > if (!isalnum((int) c)) >@@ -253,7 +249,8 @@ > { > if ((p-keyword) < (MaxTextExtent-1)) > *p++=c; >- c=ReadBlobByte(image); >+ if ((c=ReadBlobByte(image)) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > } while (isalnum(c) || (c == '_')); > *p='\0'; > if (LocaleCompare(keyword,"END") == 0) >@@ -263,7 +260,8 @@ > { > if (c == '=') > value_expected=True; >- c=ReadBlobByte(image); >+ if ((c=ReadBlobByte(image)) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > } > if (value_expected == False) > continue; >@@ -272,7 +270,8 @@ > { > if ((p-value) < (MaxTextExtent-1)) > *p++=c; >- c=ReadBlobByte(image); >+ if ((c=ReadBlobByte(image)) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > } > *p='\0'; > /* >@@ -300,11 +299,14 @@ > fits_info.scale=atof(value); > } > while ((TellBlob(image) % 80) != 0) >- c=ReadBlobByte(image); >- c=ReadBlobByte(image); >+ if ((c=ReadBlobByte(image)) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ if ((c=ReadBlobByte(image)) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > } > while ((TellBlob(image) % 2880) != 0) >- c=ReadBlobByte(image); >+ if ((c=ReadBlobByte(image)) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > /* > Verify that required image information is defined. > */ >@@ -350,14 +352,16 @@ > if (packet_size < 0) > packet_size=(-packet_size); > number_pixels=image->columns*image->rows; >- fits_pixels=MagickAllocateMemory(unsigned char *,packet_size*number_pixels); >+ if ((number_pixels / image->columns) != image->rows) >+ ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image); >+ fits_pixels=MagickAllocateArray(unsigned char *,number_pixels,packet_size); > if (fits_pixels == (unsigned char *) NULL) > ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); > /* > Convert FITS pixels to pixel packets. > */ >- count=ReadBlob(image,packet_size*number_pixels,fits_pixels); >- if (count == 0) >+ row_octets=packet_size*number_pixels; >+ if (ReadBlob(image,row_octets,fits_pixels) != row_octets) > ThrowReaderException(CorruptImageError,InsufficientImageDataInFile, > image); > if ((fits_info.min_data == 0.0) && (fits_info.max_data == 0.0)) >Index: coders/mtv.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/mtv.c,v >retrieving revision 1.85 >retrieving revision 1.86 >diff -u -u -r1.85 -r1.86 >--- coders/mtv.c 5 May 2008 02:32:51 -0000 1.85 >+++ coders/mtv.c 11 Jun 2008 00:19:58 -0000 1.86 >@@ -125,11 +125,16 @@ > Read MTV image. > */ > (void) ReadBlobString(image,buffer); >+ columns=0; >+ rows=0; > count=sscanf(buffer,"%lu %lu\n",&columns,&rows); >- if (count <= 0) >+ if (count != 2) > ThrowReaderException(CorruptImageError,ImproperImageHeader,image); > do > { >+ size_t >+ row_size; >+ > /* > Initialize image structure. > */ >@@ -142,15 +147,14 @@ > /* > Convert MTV raster image to pixel packets. > */ >- pixels=MagickAllocateMemory(unsigned char *,3*image->columns); >+ pixels=MagickAllocateArray(unsigned char *,image->columns,3); > if (pixels == (unsigned char *) NULL) > ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >+ row_size=image->columns*3; > for (y=0; y < (long) image->rows; y++) > { >- count=(long) ReadBlob(image,3*image->columns,pixels); >- if (count == 0) >- ThrowReaderException(CorruptImageError,UnableToReadImageData, >- image); >+ if (ReadBlob(image,row_size,pixels) != row_size) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > p=pixels; > q=SetImagePixels(image,0,y,image->columns,1); > if (q == (PixelPacket *) NULL) >@@ -185,7 +189,7 @@ > *buffer='\0'; > (void) ReadBlobString(image,buffer); > count=sscanf(buffer,"%lu %lu\n",&columns,&rows); >- if (count > 0) >+ if (count == 2) > { > /* > Allocate next image structure. >@@ -200,7 +204,7 @@ > if (!MagickMonitor(LoadImagesText,TellBlob(image),GetBlobSize(image),exception)) > break; > } >- } while (count > 0); >+ } while (count == 2); > while (image->previous != (Image *) NULL) > image=image->previous; > CloseBlob(image); >Index: coders/palm.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/palm.c,v >retrieving revision 1.77 >retrieving revision 1.79 >diff -u -u -r1.77 -r1.79 >--- coders/palm.c 5 May 2008 02:32:51 -0000 1.77 >+++ coders/palm.c 11 Jun 2008 00:19:58 -0000 1.79 >@@ -22,7 +22,7 @@ > % % > % Software Design % > % Christopher R. Hawks % >- December 2001 % >+% December 2001 % > % % > % % > % % >@@ -466,6 +466,23 @@ > transparentIndex = ReadBlobByte(image); > compressionType = ReadBlobByte(image); > (void) ReadBlobMSBShort(image); /* pad */ >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Size=%lux%lu, bytes_per_row=%lu, flags=%lu, bits_per_pixel=%lu", >+ image->columns, image->rows, bytes_per_row, flags, bits_per_pixel); >+ >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "transparentIndex=%lu, compressionType=%lu", >+ transparentIndex, compressionType); >+ >+ /* >+ Validate bits per pixel. >+ */ >+ if ((bits_per_pixel < 1) || >+ ((bits_per_pixel > 8) && (bits_per_pixel != 16))) >+ ThrowReaderException(CorruptImageError,UnrecognizedBitsPerPixel,image); > > /* > Initialize image colormap. >@@ -479,6 +496,8 @@ > (void) ReadBlobMSBLong(image); /* size */ > else > (void) ReadBlobMSBShort(image); /* size */ >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > } > else /* is color */ > if(bits_per_pixel == 8) >@@ -490,9 +509,13 @@ > for(i = 0; i < (long) count; i++) > { > (void) ReadBlobByte(image); >- image->colormap[255 - i].red = ScaleCharToQuantum(ReadBlobByte(image)); >- image->colormap[255 - i].green = ScaleCharToQuantum(ReadBlobByte(image)); >- image->colormap[255 - i].blue = ScaleCharToQuantum(ReadBlobByte(image)); >+ index=255 - i; >+ VerifyColormapIndex(image,index); >+ image->colormap[index].red = ScaleCharToQuantum(ReadBlobByte(image)); >+ image->colormap[index].green = ScaleCharToQuantum(ReadBlobByte(image)); >+ image->colormap[index].blue = ScaleCharToQuantum(ReadBlobByte(image)); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > } > } > for(; i < (long) (1L << bits_per_pixel); i++) >@@ -508,9 +531,13 @@ > transpix.green = (unsigned char) (ReadBlobByte(image) * MaxRGB / 63); > transpix.blue = (unsigned char) (ReadBlobByte(image) * MaxRGB / 31); > } >- image->colormap[255 - i].red = ScaleCharToQuantum(PalmPalette[i][0]); >- image->colormap[255 - i].green = ScaleCharToQuantum(PalmPalette[i][1]); >- image->colormap[255 - i].blue = ScaleCharToQuantum(PalmPalette[i][2]); >+ index=255 - i; >+ VerifyColormapIndex(image,index); >+ image->colormap[index].red = ScaleCharToQuantum(PalmPalette[i][0]); >+ image->colormap[index].green = ScaleCharToQuantum(PalmPalette[i][1]); >+ image->colormap[index].blue = ScaleCharToQuantum(PalmPalette[i][2]); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > } > } > >@@ -603,6 +630,7 @@ > if ((unsigned long) (ptr - one_row) >= bytes_per_row) > ThrowReaderException(CorruptImageError,CorruptImage,image); > index =(IndexPacket) (mask - (((*ptr) & (mask << bit)) >> bit)); >+ VerifyColormapIndex(image,index); > indexes[x] = index; > *q++ = image->colormap[index]; > if (!bit) >@@ -618,6 +646,8 @@ > if (!SyncImagePixels(image)) > break; > } >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > } > > if(flags & PALM_HAS_TRANSPARENCY_FLAG) >Index: coders/pict.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/pict.c,v >retrieving revision 1.160 >retrieving revision 1.161 >diff -u -u -r1.160 -r1.161 >--- coders/pict.c 5 May 2008 02:32:51 -0000 1.160 >+++ coders/pict.c 30 May 2008 04:57:41 -0000 1.161 >@@ -420,15 +420,14 @@ > *q; > > size_t >- length; >+ allocated_pixels, >+ length, >+ row_bytes; > > unsigned char > *pixels, > *scanline; > >- unsigned short >- row_bytes; >- > unsigned long > bytes_per_pixel, > number_pixels, >@@ -452,16 +451,17 @@ > width*=image->matte ? 4 : 3; > if (bytes_per_line == 0) > bytes_per_line=width; >- row_bytes=(unsigned short) (image->columns | 0x8000); >+ row_bytes=(size_t) (image->columns | 0x8000); > if (image->storage_class == DirectClass) >- row_bytes=(unsigned short) ((4*image->columns) | 0x8000); >+ row_bytes=(size_t) ((4*image->columns) | 0x8000); > /* > Allocate pixel and scanline buffer. > */ >- pixels=MagickAllocateMemory(unsigned char *,row_bytes*image->rows); >+ pixels=MagickAllocateArray(unsigned char *,image->rows,row_bytes); > if (pixels == (unsigned char *) NULL) > return((unsigned char *) NULL); >- (void) memset(pixels,0,row_bytes*image->rows); >+ allocated_pixels=image->rows*row_bytes; >+ (void) memset(pixels,0,allocated_pixels); > scanline=MagickAllocateMemory(unsigned char *,row_bytes); > if (scanline == (unsigned char *) NULL) > return((unsigned char *) NULL); >@@ -493,7 +493,8 @@ > scanline_length=ReadBlobByte(blob); > if (scanline_length >= row_bytes) > { >- ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage,"scanline length exceeds row bytes"); >+ ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage, >+ "scanline length exceeds row bytes"); > break; > } > (void) ReadBlob(blob,scanline_length,(char *) scanline); >@@ -503,6 +504,13 @@ > length=(scanline[j] & 0xff)+1; > number_pixels=length*bytes_per_pixel; > p=ExpandBuffer(scanline+j+1,&number_pixels,bits_per_pixel); >+ if ((q+number_pixels > pixels+allocated_pixels)) >+ { >+ ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage, >+ "Decoded RLE pixels exceeds allocation!"); >+ break; >+ } >+ > (void) memcpy(q,p,number_pixels); > q+=number_pixels; > j+=length*bytes_per_pixel+1; >@@ -514,6 +522,12 @@ > p=ExpandBuffer(scanline+j+1,&number_pixels,bits_per_pixel); > for (i=0; i < (long) length; i++) > { >+ if ((q+number_pixels > pixels+allocated_pixels)) >+ { >+ ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage, >+ "Decoded RLE pixels exceeds allocation!"); >+ break; >+ } > (void) memcpy(q,p,number_pixels); > q+=number_pixels; > } >@@ -800,11 +814,25 @@ > if (version != 1) > ThrowReaderException(CorruptImageError,ImproperImageHeader,image); > /* >+ Validate dimensions >+ */ >+ if ((frame.left < 0) || (frame.right < 0) || (frame.top < 0) || (frame.bottom < 0) || >+ (frame.left >= frame.right) || (frame.top >= frame.bottom)) >+ { >+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image); >+ } >+ >+ /* > Create black canvas. > */ > flags=0; > image->columns=frame.right-frame.left; > image->rows=frame.bottom-frame.top; >+ >+ if (IsEventLogging()) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Dimensions: %lux%lu",image->columns,image->rows); >+ > /* > Interpret PICT opcodes. > */ >@@ -821,12 +849,12 @@ > if (code > 0xa1) > { > if (IsEventLogging()) >- (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%04X:",code); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Code %04X:",code); > } > else > { > if (IsEventLogging()) >- (void) LogMagickEvent(CoderEvent,GetMagickModule()," %04X %.1024s: %.1024s",code, >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Code %04X %.1024s: %.1024s",code, > codes[code].name,codes[code].description); > switch (code) > { >Index: coders/rla.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/rla.c,v >retrieving revision 1.60 >retrieving revision 1.61 >diff -u -u -r1.60 -r1.61 >--- coders/rla.c 5 May 2008 02:32:52 -0000 1.60 >+++ coders/rla.c 11 Jun 2008 00:19:58 -0000 1.61 >@@ -39,6 +39,7 @@ > #include "magick/attribute.h" > #include "magick/blob.h" > #include "magick/pixel_cache.h" >+#include "magick/log.h" > #include "magick/magick.h" > #include "magick/monitor.h" > #include "magick/utility.h" >@@ -93,13 +94,13 @@ > window, > active_window; > >- short >+ magick_uint16_t > frame, > storage_type, > number_channels, > number_matte_channels, > number_auxiliary_channels, >- revision; >+ revision; /* aux_mask in RLB */ > > char > gamma[16], >@@ -108,7 +109,7 @@ > blue_primary[24], > white_point[24]; > >- long >+ magick_uint32_t > job_number; > > char >@@ -122,14 +123,20 @@ > aspect_ratio[8], > chan[32]; > >- short >+ magick_uint16_t > field; > >+ /* RLB varies after this point */ >+ >+ } RLAInfo; >+ >+ typedef struct _RLA3ExtraInfo >+ { > char > time[12], > filter[32]; > >- short >+ magick_uint16_t > bits_per_channel, > matte_type, > matte_bits, >@@ -140,9 +147,30 @@ > auxiliary[32], > space[36]; > >- long >+ magick_uint32_t > next; >- } RLAInfo; >+ } RLA3ExtraInfo; >+ >+ typedef struct _RLBExtraInfo >+ { >+ magick_uint16_t >+ filter_type; >+ >+ magick_uint32_t >+ magic_number, >+ lut_size, >+ user_space_size, >+ wf_space_size; >+ >+ magick_uint16_t >+ lut_type, >+ mix_type, >+ encode_type, >+ padding; >+ >+ char >+ space[100]; >+ } RLBExtraInfo; > > Image > *image; >@@ -150,17 +178,15 @@ > int > channel, > length, >+ number_channels, > runlength; > > long > y; > >- long >+ magick_uint32_t > *scanlines; > >- register IndexPacket >- *indexes; >- > register long > i, > x; >@@ -171,10 +197,19 @@ > RLAInfo > rla_info; > >- unsigned char >+ RLA3ExtraInfo >+ rla3_extra_info; >+ >+ RLBExtraInfo >+ rlb_extra_info; >+ >+ MagickBool >+ is_rla3; >+ >+ int > byte; > >- unsigned int >+ MagickPassFail > status; > > /* >@@ -186,8 +221,12 @@ > assert(exception->signature == MagickSignature); > image=AllocateImage(image_info); > status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); >- if (status == False) >+ if (status == MagickFail) > ThrowReaderException(FileOpenError,UnableToOpenFile,image); >+ is_rla3=MagickFalse; >+ memset(&rla_info,0,sizeof(rla_info)); >+ memset(&rla3_extra_info,0,sizeof(rla3_extra_info)); >+ memset(&rlb_extra_info,0,sizeof(rlb_extra_info)); > rla_info.window.left=ReadBlobMSBShort(image); > rla_info.window.right=ReadBlobMSBShort(image); > rla_info.window.bottom=ReadBlobMSBShort(image); >@@ -202,9 +241,10 @@ > rla_info.number_matte_channels=ReadBlobMSBShort(image); > if (rla_info.number_channels == 0) > rla_info.number_channels=3; >- rla_info.number_channels+=rla_info.number_matte_channels; > rla_info.number_auxiliary_channels=ReadBlobMSBShort(image); > rla_info.revision=ReadBlobMSBShort(image); >+ if (rla_info.revision == 0xFFFE) >+ is_rla3=MagickTrue; > (void) ReadBlob(image,16,(char *) rla_info.gamma); > (void) ReadBlob(image,24,(char *) rla_info.red_primary); > (void) ReadBlob(image,24,(char *) rla_info.green_primary); >@@ -221,29 +261,195 @@ > (void) ReadBlob(image,8,(char *) rla_info.aspect_ratio); > (void) ReadBlob(image,32,(char *) rla_info.chan); > rla_info.field=ReadBlobMSBShort(image); >- (void) ReadBlob(image,12,(char *) rla_info.time); >- (void) ReadBlob(image,32,(char *) rla_info.filter); >- rla_info.bits_per_channel=ReadBlobMSBShort(image); >- rla_info.matte_type=ReadBlobMSBShort(image); >- rla_info.matte_bits=ReadBlobMSBShort(image); >- rla_info.auxiliary_type=ReadBlobMSBShort(image); >- rla_info.auxiliary_bits=ReadBlobMSBShort(image); >- (void) ReadBlob(image,32,(char *) rla_info.auxiliary); >- (void) ReadBlob(image,36,(char *) rla_info.space); >- rla_info.next=(long) ReadBlobMSBLong(image); >+ if (is_rla3) >+ { >+ (void) ReadBlob(image,12,(char *) rla3_extra_info.time); >+ (void) ReadBlob(image,32,(char *) rla3_extra_info.filter); >+ rla3_extra_info.bits_per_channel=ReadBlobMSBShort(image); >+ rla3_extra_info.matte_type=ReadBlobMSBShort(image); >+ rla3_extra_info.matte_bits=ReadBlobMSBShort(image); >+ rla3_extra_info.auxiliary_type=ReadBlobMSBShort(image); >+ rla3_extra_info.auxiliary_bits=ReadBlobMSBShort(image); >+ (void) ReadBlob(image,32,(char *) rla3_extra_info.auxiliary); >+ (void) ReadBlob(image,36,(char *) rla3_extra_info.space); >+ rla3_extra_info.next=(long) ReadBlobMSBLong(image); >+ } >+ else >+ { >+ rlb_extra_info.filter_type=ReadBlobMSBShort(image); >+ rlb_extra_info.magic_number=ReadBlobMSBLong(image); >+ rlb_extra_info.lut_size=ReadBlobMSBLong(image); >+ rlb_extra_info.user_space_size=ReadBlobMSBLong(image); >+ rlb_extra_info.wf_space_size=ReadBlobMSBLong(image); >+ rlb_extra_info.lut_type=ReadBlobMSBShort(image); >+ rlb_extra_info.mix_type=ReadBlobMSBShort(image); >+ rlb_extra_info.encode_type=ReadBlobMSBShort(image); >+ rlb_extra_info.padding=ReadBlobMSBShort(image); >+ (void) ReadBlob(image,100,(char *) rlb_extra_info.space); >+ } >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ >+ /* >+ Verify revision. >+ */ >+ >+/* if (rla3_extra_info.revision != 0xFFFE) */ >+/* ThrowReaderException(CorruptImageError,ImproperImageHeader,image); */ >+ >+ /* >+ Verify dimensions. >+ */ >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Active Window : Left=%d Right=%d Top=%d, Bottom=%d", >+ (int) rla_info.active_window.left, >+ (int) rla_info.active_window.right, >+ (int) rla_info.active_window.top, >+ (int) rla_info.active_window.bottom); >+ if ((((long) rla_info.active_window.right - rla_info.active_window.left) < 0) || >+ (((long) rla_info.active_window.top-rla_info.active_window.bottom) < 0)) >+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image); >+ >+ if (image->logging) >+ { >+ const char >+ *storage_type = "Unknown"; >+ >+ switch (rla_info.storage_type) >+ { >+ case 0: >+ storage_type = "INT8"; >+ break; >+ case 1: >+ storage_type = "INT16"; >+ break; >+ case 2: >+ storage_type = "INT32"; >+ break; >+ case 3: >+ storage_type = "FLOAT32"; >+ break; >+ } >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Storage Type : %s",storage_type); >+ >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Color Channels : %u", (unsigned int) rla_info.number_channels); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Matte Channels : %u", (unsigned int) rla_info.number_matte_channels); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Aux Channels : %u", (unsigned int) rla_info.number_auxiliary_channels); >+ if (is_rla3) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Format Revision: 0x%04X", rla_info.revision); >+ else >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Aux Mask : 0x%04X", rla_info.revision); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Gamma : %.16s", rla_info.gamma); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Red Primary : %.24s", rla_info.red_primary); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Green Primary : %.24s", rla_info.green_primary); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Blue Primary : %.24s", rla_info.blue_primary); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "White Point : %.24s", rla_info.white_point); >+ >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Job Number : %u", (unsigned int) rla_info.job_number); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Name : %.128s", rla_info.name); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Description : %.128s", rla_info.description); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Program : %.64s", rla_info.program); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Machine : %.32s", rla_info.machine); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "User : %.32s", rla_info.user); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Date : %.20s", rla_info.date); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Aspect : %.128s", rla_info.aspect); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Aspect Ratio : %.8s", rla_info.aspect_ratio); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Colorspace : %.32s", rla_info.chan); >+ >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Field : %u", (unsigned int) rla_info.field); >+ >+ if (is_rla3) >+ { >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Time : %.12s", rla3_extra_info.time); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Filter : %.32s", rla3_extra_info.filter); >+ >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "BitsPerChannel : %u", rla3_extra_info.bits_per_channel); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "MatteType : %u", rla3_extra_info.matte_type); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "MatteBits : %u", rla3_extra_info.matte_bits); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "AuxType : %u", rla3_extra_info.auxiliary_type); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "AuxBits : %u", rla3_extra_info.auxiliary_bits); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "AuxData : %.32s", rla3_extra_info.auxiliary); >+ } >+ else >+ { >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "FilterType : %u", rlb_extra_info.filter_type); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "MagickNumber : %u", rlb_extra_info.magic_number); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "LUT Size : %u", rlb_extra_info.lut_size); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "User Space : %u", rlb_extra_info.user_space_size); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "WF Space : %u", rlb_extra_info.wf_space_size); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "LUT Type : %u", rlb_extra_info.lut_type); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "MIX Type : %u", rlb_extra_info.mix_type); >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Encode Type : %u", rlb_extra_info.encode_type); >+ } >+ } >+ >+ if ((rla_info.storage_type != 0) || (rla_info.storage_type > 3)) >+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image); >+ >+ if (rla_info.storage_type != 0) >+ ThrowReaderException(CoderError,DataStorageTypeIsNotSupported,image); >+ >+ if (LocaleNCompare(rla_info.chan,"rgb",3) != 0) >+ ThrowReaderException(CoderError,ColorTypeNotSupported,image); >+ > /* > Initialize image structure. > */ >- image->matte=rla_info.number_matte_channels != 0; >- image->columns=rla_info.active_window.right-rla_info.active_window.left; >- image->rows=rla_info.active_window.top-rla_info.active_window.bottom; >+ image->matte=(rla_info.number_matte_channels != 0 ? MagickTrue: MagickFalse); >+ image->columns=rla_info.active_window.right-rla_info.active_window.left+1; >+ image->rows=rla_info.active_window.top-rla_info.active_window.bottom+1; >+ >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Dimensions : %lux%lu",image->columns,image->rows); >+ > if (image_info->ping) > { > CloseBlob(image); > return(image); > } >- scanlines=MagickAllocateMemory(long *,image->rows*sizeof(long)); >- if (scanlines == (long *) NULL) >+ number_channels=rla_info.number_channels+rla_info.number_matte_channels; >+ scanlines=MagickAllocateArray(magick_uint32_t *,image->rows,sizeof(magick_uint32_t)); >+ if (scanlines == (magick_uint32_t *) NULL) > ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); > if (*rla_info.description != '\0') > (void) SetImageAttribute(image,"comment",rla_info.description); >@@ -251,44 +457,69 @@ > Read offsets to each scanline data. > */ > for (i=0; i < (long) image->rows; i++) >- scanlines[i]=(long) ReadBlobMSBLong(image); >+ { >+ scanlines[i]=(magick_uint32_t) ReadBlobMSBLong(image); >+#if 0 >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "scanline[%ld] = %lu",i,(unsigned long) scanlines[i]); >+#endif >+ } >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > /* > Read image data. > */ > x=0; >- indexes=(IndexPacket *) NULL; > for (y=0; y < (long) image->rows; y++) > { >- (void) SeekBlob(image,scanlines[image->rows-y-1],SEEK_SET); >- for (channel=0; channel < (int) rla_info.number_channels; channel++) >+ if (SeekBlob(image,scanlines[image->rows-y-1],SEEK_SET) == -1) >+ { >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Failed seek to %lu", >+ (unsigned long) image->rows-y-1); >+ status=MagickFail; >+ break; >+ } >+ for (channel=0; channel < number_channels; channel++) > { > length=ReadBlobMSBShort(image); > while (length > 0) > { >- byte=ReadBlobByte(image); >+ if ((byte=ReadBlobByte(image)) == EOF) >+ { >+ status=MagickFail; >+ break; >+ } > runlength=byte; >- if (byte > 127U) >+ if (byte > 127) > runlength=byte-256; > length--; > if (length == 0) > break; > if (runlength < 0) > { >- q=GetImagePixels(image,(long) (x % image->columns), >- (long) (y/image->columns),1,1); >- if (q == (PixelPacket *) NULL) >- break; >- indexes=GetIndexes(image); > while (runlength < 0) > { >- byte=ReadBlobByte(image); >+ q=GetImagePixels(image,(long) (x % image->columns), >+ (long) (y % image->columns),1,1); >+ if (q == (PixelPacket *) NULL) >+ { >+ status=MagickFail; >+ break; >+ } >+ if ((byte=ReadBlobByte(image)) == EOF) >+ { >+ status=MagickFail; >+ break; >+ } > length--; > switch (channel) > { > case 0: > { > q->red=ScaleCharToQuantum(byte); >- *indexes=0; > break; > } > case 1: >@@ -302,34 +533,47 @@ > break; > } > case 3: >- default: > { > q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(byte)); > break; > } >+ default: >+ { >+ /* Depth channel ? */ >+ break; >+ } > } > if (!SyncImagePixels(image)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > x++; > runlength++; > } > continue; > } >- byte=ReadBlobByte(image); >+ if ((byte=ReadBlobByte(image)) == EOF) >+ { >+ status=MagickFail; >+ break; >+ } > length--; > runlength++; > do > { > q=GetImagePixels(image,(long) (x % image->columns), >- (long) (y/image->columns),1,1); >+ (long) (y % image->columns),1,1); > if (q == (PixelPacket *) NULL) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > switch (channel) > { > case 0: > { > q->red=ScaleCharToQuantum(byte); >- *indexes=0; > break; > } > case 1: >@@ -343,27 +587,43 @@ > break; > } > case 3: >- default: > { > q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(byte)); > break; > } >+ default: >+ { >+ /* Depth channel ? */ >+ break; >+ } > } > if (!SyncImagePixels(image)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } > x++; > runlength--; > } > while (runlength > 0); >+ >+ if (MagickFail == status) >+ break; > } >+ if (MagickFail == status) >+ break; > } > if (QuantumTick(y,image->rows)) > if (!MagickMonitor(LoadImageText,y,image->rows,exception)) >- break; >+ { >+ status=MagickFail; >+ break; >+ } >+ if (MagickFail == status) >+ break; > } > if (EOFBlob(image)) >- ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, >- image->filename); >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > CloseBlob(image); > return(image); > } >Index: coders/tga.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/tga.c,v >retrieving revision 1.126 >retrieving revision 1.127 >diff -u -u -r1.126 -r1.127 >--- coders/tga.c 5 May 2008 02:32:52 -0000 1.126 >+++ coders/tga.c 11 Jun 2008 00:19:58 -0000 1.127 >@@ -119,7 +119,7 @@ > Image > *image; > >- IndexPacket >+ unsigned int > index; > > long >@@ -175,13 +175,14 @@ > /* > Read TGA header information. > */ >- count=ReadBlob(image,1,(char *) &tga_info.id_length); >+ (void) ReadBlob(image,1,(char *) &tga_info.id_length); > tga_info.colormap_type=ReadBlobByte(image); > tga_info.image_type=ReadBlobByte(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > do > { >- if ((count == 0) || >- ((tga_info.image_type != TGAColormap) && >+ if (((tga_info.image_type != TGAColormap) && > (tga_info.image_type != TGARGB) && > (tga_info.image_type != TGAMonochrome) && > (tga_info.image_type != TGARLEColormap) && >@@ -200,6 +201,8 @@ > tga_info.height=ReadBlobLSBShort(image); > tga_info.bits_per_pixel=ReadBlobByte(image); > tga_info.attributes=ReadBlobByte(image); >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > (void) LogMagickEvent(CoderEvent,GetMagickModule(), > "ImageType=%s CMapType=%u CMapStart=%u CMapLength=%u CMapDepth=%u\n XOffset=%u YOffset=%u Width=%u Height=%u PixelDepth=%u Attributes=0x%.2x", > ((tga_info.image_type == TGAColormap) ? "Colormapped" : >@@ -209,14 +212,23 @@ > (tga_info.image_type == TGARLERGB) ? "Truecolor-RLE" : > (tga_info.image_type == TGARLEMonochrome) ? "Monochrome-RLE" : > "Unknown"), >- (unsigned int) tga_info.colormap_type, >- (unsigned int) tga_info.colormap_index, >- (unsigned int) tga_info.colormap_length, >- (unsigned int) tga_info.colormap_size, >- tga_info.x_origin, tga_info.y_origin, tga_info.width, tga_info.height, >+ (unsigned int) tga_info.colormap_type, /* Colormap type */ >+ (unsigned int) tga_info.colormap_index, /* Index of first colormap entry to use */ >+ (unsigned int) tga_info.colormap_length, /* # of elements in colormap */ >+ (unsigned int) tga_info.colormap_size, /* Bits in each palette entry */ >+ tga_info.x_origin, tga_info.y_origin, >+ tga_info.width, tga_info.height, > (unsigned int) tga_info.bits_per_pixel, > tga_info.attributes); >- >+ >+ /* >+ Validate depth. >+ */ >+ if (!(((tga_info.bits_per_pixel > 1) && (tga_info.bits_per_pixel < 17)) || >+ (tga_info.bits_per_pixel == 24 ) || >+ (tga_info.bits_per_pixel == 32 ))) >+ ThrowReaderException(CoderError,DataStorageTypeIsNotSupported,image); >+ > /* > Initialize image structure. > */ >@@ -304,7 +316,8 @@ > if (comment == (char *) NULL) > ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, > image); >- (void) ReadBlob(image,tga_info.id_length,comment); >+ if(ReadBlob(image,tga_info.id_length,comment) != tga_info.id_length) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > comment[tga_info.id_length]='\0'; > (void) SetImageAttribute(image,"comment",comment); > MagickFreeMemory(comment); >@@ -369,6 +382,8 @@ > image->colormap[i]=pixel; > } > } >+ if (EOFBlob(image)) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); > if (image_info->ping && (image_info->subrange != 0)) > if (image->scene >= (image_info->subimage+image_info->subrange-1)) > break; >@@ -405,9 +420,11 @@ > } > else > { >- count=ReadBlob(image,1,(char *) &runlength); >- if (count == 0) >- ThrowReaderException(CorruptImageError,UnableToReadImageData,image); >+ if (ReadBlob(image,1,(char *) &runlength) != 1) >+ { >+ status=MagickFail; >+ break; >+ } > flag=runlength & 0x80; > if (flag != 0) > runlength-=128; >@@ -488,7 +505,9 @@ > break; > } > } >- if (status == False) >+ if (EOFBlob(image)) >+ status = MagickFail; >+ if (status == MagickFail) > ThrowReaderException(CorruptImageError,UnableToReadImageData,image); > if (image->storage_class == PseudoClass) > indexes[x]=index; >@@ -535,7 +554,7 @@ > (tga_info.image_type == TGARLEColormap) || > (tga_info.image_type == TGARLERGB) || > (tga_info.image_type == TGARLEMonochrome)); >- if (status == True) >+ if (!EOFBlob(image) && (status == True)) > { > /* > Allocate next image structure. >@@ -683,25 +702,25 @@ > typedef struct _TargaInfo > { > unsigned char >- id_length, >+ id_length, > colormap_type, > image_type; > > unsigned short >- colormap_index, >+ colormap_index, > colormap_length; > > unsigned char >- colormap_size; >+ colormap_size; > > unsigned short >- x_origin, >+ x_origin, > y_origin, > width, > height; > > unsigned char >- bits_per_pixel, >+ bits_per_pixel, > attributes; > } TargaInfo; > >Index: coders/xcf.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/coders/xcf.c,v >retrieving revision 1.74 >retrieving revision 1.77 >diff -u -u -r1.74 -r1.77 >--- coders/xcf.c 5 May 2008 02:32:53 -0000 1.74 >+++ coders/xcf.c 3 Jun 2008 01:09:56 -0000 1.77 >@@ -38,6 +38,7 @@ > #include "magick/blob.h" > #include "magick/pixel_cache.h" > #include "magick/composite.h" >+#include "magick/log.h" > #include "magick/magick.h" > #include "magick/quantize.h" > #include "magick/utility.h" >@@ -102,6 +103,10 @@ > /* not really part of the doc, but makes it easy to pass around! */ > ExceptionInfo > *exception; >+ >+ /* File size */ >+ magick_off_t >+ file_size; > } XCFDocInfo; > > typedef struct { >@@ -302,13 +307,16 @@ > } > > >-static int load_tile (Image* image, Image* tile_image, XCFDocInfo* inDocInfo, >- XCFLayerInfo* inLayerInfo, size_t data_length) >+static MagickPassFail load_tile (Image* image, Image* tile_image, XCFDocInfo* inDocInfo, >+ XCFLayerInfo* inLayerInfo, size_t data_length) > { >- int >- i, >+ size_t > nmemb_read_successfully; > >+ unsigned long >+ x, >+ y; >+ > PixelPacket > *q; > >@@ -320,61 +328,84 @@ > *graydata; > > xcfdata = xcfodata = MagickAllocateMemory(XCFPixelPacket *,data_length); >- graydata = (unsigned char *)xcfdata; /* used by gray and indexed */ >+ graydata = (unsigned char *) xcfdata; /* used by gray and indexed */ >+ >+ if (xcfdata == (XCFPixelPacket *) NULL) >+ { >+ ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,NULL); >+ return MagickFail; >+ } >+ > nmemb_read_successfully = ReadBlob(image, data_length, xcfdata); >+ if (nmemb_read_successfully != data_length) >+ { >+ MagickFreeMemory(xcfodata); >+ ThrowException(&image->exception,CorruptImageError,UnexpectedEndOfFile, >+ NULL); >+ return MagickFail; >+ } > > q=SetImagePixels(tile_image,0,0,tile_image->columns,tile_image->rows); >+ if (q == (PixelPacket *) NULL) >+ { >+ CopyException(&image->exception,&tile_image->exception); >+ MagickFreeMemory(xcfodata); >+ return MagickFail; >+ } > >- /* we have to copy the pixels individually since IM uses a different >- format PixelPacket on different platforms - not to mention >- different QuantumDepths! >- */ >- for( i=0; i<nmemb_read_successfully;i++ ) >+ for (x=0; x < tile_image->columns; x++) > { >- if ( inDocInfo->image_type == GIMP_GRAY ) >+ if (inDocInfo->image_type == GIMP_GRAY) > { >- q->red = ScaleCharToQuantum(*graydata); >- q->green = ScaleCharToQuantum(*graydata); >- q->blue = ScaleCharToQuantum(*graydata); >- q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >- graydata++; >+ for (y=tile_image->rows; y != 0; y--) >+ { >+ q->red =q->green=q->blue=ScaleCharToQuantum(*graydata); >+ q->opacity = ScaleCharToQuantum(255U-inLayerInfo->opacity); >+ graydata++; >+ q++; >+ } >+ } >+ else if (inDocInfo->image_type == GIMP_RGB) >+ { >+ for (y=tile_image->rows; y != 0; y--) >+ { >+ q->red = ScaleCharToQuantum(xcfdata->red); >+ q->green = ScaleCharToQuantum(xcfdata->green); >+ q->blue = ScaleCharToQuantum(xcfdata->blue); >+ q->opacity = (Quantum) (xcfdata->opacity==0U ? TransparentOpacity : >+ ScaleCharToQuantum(255U-inLayerInfo->opacity)); >+ xcfdata++; >+ q++; >+ } > } >- else >- if ( inDocInfo->image_type == GIMP_RGB ) >- { >- q->red = ScaleCharToQuantum(xcfdata->red); >- q->green = ScaleCharToQuantum(xcfdata->green); >- q->blue = ScaleCharToQuantum(xcfdata->blue); >- q->opacity = (Quantum) (xcfdata->opacity==0 ? TransparentOpacity : >- ScaleCharToQuantum(255-inLayerInfo->opacity)); >- >- xcfdata++; >- }; >- >- q++; > } > > MagickFreeMemory(xcfodata); >- return True; >+ return MagickPass; > } > >-static int load_tile_rle (Image* image, Image* tile_image, XCFDocInfo* inDocInfo, >- XCFLayerInfo* inLayerInfo, size_t data_length) >+static MagickPassFail load_tile_rle (Image* image, >+ Image* tile_image, >+ XCFDocInfo* inDocInfo, >+ XCFLayerInfo* inLayerInfo, >+ size_t data_length) > { > unsigned char > data, > val; > >- ExtendedSignedIntegralType >+ magick_int64_t > size; > >+ size_t >+ nmemb_read_successfully; >+ > int > count, > length, > bpp, /* BYTES per pixel! */ > i, >- j, >- nmemb_read_successfully; >+ j; > > unsigned char > *xcfdata, >@@ -385,16 +416,38 @@ > *q; > > bpp = (int) inDocInfo->bpp; >- >+ > xcfdata = xcfodata = MagickAllocateMemory(unsigned char *,data_length); >+ if (xcfdata == (unsigned char *) NULL) >+ { >+ ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,NULL); >+ return MagickFail; >+ } > > nmemb_read_successfully = ReadBlob(image, data_length, xcfdata); >+ if (nmemb_read_successfully != data_length) >+ { >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Read %lu bytes, expected %lu bytes", >+ (unsigned long) nmemb_read_successfully, >+ (unsigned long) data_length); >+ MagickFreeMemory(xcfodata); >+ ThrowException(&image->exception,CorruptImageError,UnexpectedEndOfFile, >+ NULL); >+ return MagickFail; >+ } > > xcfdatalimit = &xcfodata[nmemb_read_successfully - 1]; > > for (i = 0; i < bpp; i++) > { > q=SetImagePixels(tile_image,0,0,tile_image->columns,tile_image->rows); >+ if (q == (PixelPacket *) NULL) >+ { >+ CopyException(&image->exception,&tile_image->exception); >+ goto bogus_rle; >+ } > size = tile_image->rows * tile_image->columns; > count = 0; > >@@ -440,29 +493,42 @@ > while (length-- > 0) > { > data = *xcfdata++; >- switch (i) { >- case 0: >- q->red = ScaleCharToQuantum(data); >- if ( inDocInfo->image_type == GIMP_GRAY ) >+ switch (i) >+ { >+ case 0: > { >- q->green = ScaleCharToQuantum(data); >- q->blue = ScaleCharToQuantum(data); >- q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >+ q->red = ScaleCharToQuantum(data); >+ if ( inDocInfo->image_type == GIMP_GRAY ) >+ { >+ q->green = ScaleCharToQuantum(data); >+ q->blue = ScaleCharToQuantum(data); >+ q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >+ } >+ else >+ { >+ q->green = q->red; >+ q->blue = q->red; >+ q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >+ } >+ break; > } >- else >+ case 1: > { >- q->green = q->red; >- q->blue = q->red; >- q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >+ q->green = ScaleCharToQuantum(data); >+ break; > } >- break; >- case 1: q->green = ScaleCharToQuantum(data); break; >- case 2: q->blue = ScaleCharToQuantum(data); break; >- case 3: >- q->opacity = (Quantum) (data==0 ? TransparentOpacity : >- ScaleCharToQuantum(255-inLayerInfo->opacity)); >- break; >- } >+ case 2: >+ { >+ q->blue = ScaleCharToQuantum(data); >+ break; >+ } >+ case 3: >+ { >+ q->opacity = (Quantum) (data==0 ? TransparentOpacity : >+ ScaleCharToQuantum(255-inLayerInfo->opacity)); >+ break; >+ } >+ } > q++; > } > } >@@ -498,59 +564,80 @@ > for (j = 0; j < length; j++) > { > data = val; >- switch (i) { >- case 0: >- q->red = ScaleCharToQuantum(data); >- if ( inDocInfo->image_type == GIMP_GRAY ) >+ switch (i) >+ { >+ case 0: > { >- q->green = ScaleCharToQuantum(data); >- q->blue = ScaleCharToQuantum(data); >- q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >+ q->red = ScaleCharToQuantum(data); >+ if ( inDocInfo->image_type == GIMP_GRAY ) >+ { >+ q->green = ScaleCharToQuantum(data); >+ q->blue = ScaleCharToQuantum(data); >+ q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >+ } >+ else >+ { >+ q->green = q->red; >+ q->blue = q->red; >+ q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >+ } >+ break; > } >- else >+ case 1: > { >- q->green = q->red; >- q->blue = q->red; >- q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity); >+ q->green = ScaleCharToQuantum(data); >+ break; > } >- break; >- case 1: q->green = ScaleCharToQuantum(data); break; >- case 2: q->blue = ScaleCharToQuantum(data); break; >- case 3: >- q->opacity = (Quantum) (data==0 ? TransparentOpacity : >- ScaleCharToQuantum(255-inLayerInfo->opacity)); >- break; >- } >+ case 2: >+ { >+ q->blue = ScaleCharToQuantum(data); >+ break; >+ } >+ case 3: >+ { >+ q->opacity = (Quantum) (data==0 ? TransparentOpacity : >+ ScaleCharToQuantum(255-inLayerInfo->opacity)); >+ break; >+ } >+ } > q++; > } > } > } > } > MagickFreeMemory(xcfodata); >- return True; >+ return MagickPass; > > bogus_rle: > if (xcfodata) > MagickFreeMemory(xcfodata); >- return False; >+ return MagickFail; > } > >-static int load_level (Image* image, XCFDocInfo* inDocInfo, XCFLayerInfo* >- inLayerInfo) >+static MagickPassFail load_level (Image* image, >+ XCFDocInfo* inDocInfo, >+ XCFLayerInfo* >+ inLayerInfo) > { >- ExtendedSignedIntegralType >+ magick_off_t > saved_pos, > offset, > offset2; > > unsigned long >+ width, >+ height; >+ >+ unsigned long > ntiles, > ntile_rows, > ntile_cols; > >+ size_t >+ tile_data_size; >+ > int >- i, >- fail; >+ i; > > Image* > tile_image; >@@ -561,12 +648,15 @@ > tile_image_width, > tile_image_height; > >+ MagickPassFail >+ status = MagickPass; >+ > ExceptionInfo > *exception = inDocInfo->exception; > > /* start reading the data */ >- (void) ReadBlobMSBLong(image); /* width */ >- (void) ReadBlobMSBLong(image); /* height */ >+ width = ReadBlobMSBLong(image); /* width */ >+ height = ReadBlobMSBLong(image); /* height */ > > /* read in the first tile offset. > * if it is '0', then this tile level is empty >@@ -574,36 +664,67 @@ > */ > offset = ReadBlobMSBLong(image); > if (offset == 0) >- return 1; >+ return MagickPass; > >- /* Initialise the reference for the in-memory tile-compression >+ if (offset >= inDocInfo->file_size) >+ { >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Tile offset %ld (file size %lu)!", >+ (long) offset, (unsigned long) inDocInfo->file_size); >+ ThrowBinaryException(CorruptImageError,CorruptImage,image->filename); >+ } >+ >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "load_level: dimensions %lux%lu, bpp %lu, offset %ld", >+ width,height,(unsigned long) inDocInfo->bpp, >+ (long) offset); >+ >+ /* >+ Initialise the reference for the in-memory tile-compression > */ > ntile_rows = (inDocInfo->height + TILE_HEIGHT - 1) / TILE_HEIGHT; > ntile_cols = (inDocInfo->width + TILE_WIDTH - 1) / TILE_WIDTH; > ntiles = ntile_rows * ntile_cols; >+ >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Tile: dimensions %lux%lu, number of tiles %lu", >+ ntile_cols,ntile_rows,ntiles); >+ > for (i = 0; i < (long) ntiles; i++) > { >- fail = False; >+ status = MagickPass; > > if (offset == 0) >- ThrowBinaryException(CorruptImageError,NotEnoughTiles,image->filename); >+ { >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Tile: offset %ld!", (long) offset); >+ ThrowBinaryException(CorruptImageError,NotEnoughTiles,image->filename); >+ } > >- /* save the current position as it is where the >- * next tile offset is stored. >+ /* >+ save the current position as it is where the next tile offset >+ is stored. > */ > saved_pos = TellBlob(image); > >- /* read in the offset of the next tile so we can calculate the amount >- of data needed for this tile*/ >+ /* >+ read in the offset of the next tile so we can calculate the >+ amount of data needed for this tile >+ */ > offset2 = ReadBlobMSBLong(image); >+ if (offset2 >= inDocInfo->file_size) >+ { >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Tile: offset %ld (file size %lu)!", >+ (long) offset2, (unsigned long) inDocInfo->file_size); >+ ThrowBinaryException(CorruptImageError,CorruptImage,image->filename); >+ } > >- /* if the offset is 0 then we need to read in the maximum possible >- allowing for negative compression */ >- if (offset2 == 0) >- offset2 = (unsigned long) (offset + TILE_WIDTH * TILE_WIDTH * 4* 1.5); >- /* 1.5 is probably more >- than we need to allow */ >- > /* seek to the tile offset */ > (void) SeekBlob(image, offset, SEEK_SET); > >@@ -619,29 +740,86 @@ > tile_image=CloneImage(inLayerInfo->image, tile_image_width, > tile_image_height,True,exception); > >+ /* >+ Compute the tile data size. >+ */ >+ if (offset2 > offset) >+ { >+ /* >+ Tile data size is simply the difference in file offsets. >+ */ >+ tile_data_size=offset2-offset; >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Tile: start offset=%ld, end offset=%ld, data size=%lu", >+ (long) offset,(long) offset2, >+ (unsigned long) tile_data_size); >+ } >+ else >+ { >+ size_t >+ packet_size=4; >+ >+ if (inDocInfo->image_type == GIMP_GRAY) >+ packet_size=1; >+ >+ if (COMPRESS_NONE == inDocInfo->compression) >+ { >+ /* >+ If compression is not used then enforce expected tile size. >+ */ >+ tile_data_size = tile_image->columns*tile_image->rows*packet_size; >+ } >+ else >+ { >+ /* >+ Estimate the tize size. First we estimate the tile >+ size, allowing for a possible expansion factor of 1.5. >+ Then we truncate to the file length, whichever is >+ smallest. >+ */ >+ offset2 = offset + tile_image->columns*tile_image->rows * packet_size * 1.5; >+ tile_data_size = (size_t) offset2-offset; >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "We estimated tile data size: %lu", >+ (unsigned long) tile_data_size); >+ offset2 = Min(offset2,GetBlobSize(image)); >+ tile_data_size = (size_t) offset2-offset; >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Final tile data size: %lu", >+ (unsigned long) tile_data_size); >+ if (offset2 <= offset) >+ ThrowBinaryException(CorruptImageError,UnexpectedEndOfFile,image->filename); >+ } >+ } >+ > /* read in the tile */ > switch (inDocInfo->compression) > { > case COMPRESS_NONE: >- if (!load_tile (image,tile_image,inDocInfo,inLayerInfo,(size_t) (offset2-offset))) >- fail = True; >+ status=load_tile(image,tile_image,inDocInfo,inLayerInfo, >+ tile_data_size); > break; > case COMPRESS_RLE: >- if (!load_tile_rle (image,tile_image,inDocInfo,inLayerInfo, >- (size_t) (offset2-offset))) >- fail = True; >+ status=load_tile_rle(image,tile_image,inDocInfo,inLayerInfo, >+ tile_data_size); > break; > case COMPRESS_ZLIB: > ThrowBinaryException(CoderError,ZipCompressionNotSupported, >- image->filename) >- case COMPRESS_FRACTAL: >+ image->filename); >+ case COMPRESS_FRACTAL: > ThrowBinaryException(CoderError,FractalCompressionNotSupported, >- image->filename) >- } >+ image->filename); >+ } > >- /* 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); >+ if (MagickPass == status) >+ { >+ /* 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); >+ } > DestroyImage(tile_image); > > /* adjust tile position */ >@@ -652,8 +830,8 @@ > destTop++; > } > >- if (fail) >- return False; >+ if (MagickPass != status) >+ return status; > > /* restore the saved position so we'll be ready to > * read the next offset. >@@ -666,21 +844,27 @@ > > > if (offset != 0) >- ThrowBinaryException(CorruptImageError,CorruptImage,image->filename) >+ ThrowBinaryException(CorruptImageError,CorruptImage,image->filename); > >- return 1; >+ return MagickPass; > } > >-static int load_hierarchy (Image *image, XCFDocInfo* inDocInfo, XCFLayerInfo* >- inLayer) >+static MagickPassFail load_hierarchy (Image *image, XCFDocInfo* inDocInfo, XCFLayerInfo* >+ inLayer) > { >- ExtendedSignedIntegralType >+ unsigned long >+ width, >+ height; >+ >+ magick_off_t > saved_pos, >- offset, >+ offset; >+ >+ unsigned long > junk; > >- (void) ReadBlobMSBLong(image); /* width */ >- (void) ReadBlobMSBLong(image); /* height */ >+ width=ReadBlobMSBLong(image); /* width */ >+ height=ReadBlobMSBLong(image); /* height */ > inDocInfo->bpp = ReadBlobMSBLong(image); /* bpp */ > > /* load in the levels...we make sure that the number of levels >@@ -689,13 +873,22 @@ > */ > offset = ReadBlobMSBLong(image); /* top level */ > >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "load_hierarchy: dimensions %lux%lu, bpp=%lu, offset=%lu", >+ width,height,(unsigned long) inDocInfo->bpp, >+ (unsigned long) offset); >+ > /* discard offsets for layers below first, if any. > */ > do > { > junk = ReadBlobMSBLong(image); > } >- while (junk != 0); >+ while ((junk != 0) && (!EOFBlob(image))); >+ >+ if (EOFBlob(image)) >+ return MagickFail; > > /* save the current position as it is where the > * next level offset is stored. >@@ -706,20 +899,20 @@ > (void) SeekBlob(image, offset, SEEK_SET); > > /* read in the level */ >- if (!load_level (image, inDocInfo, inLayer)) >- return 0; >+ if (load_level (image, inDocInfo, inLayer) == MagickFail) >+ return MagickFail; > > /* restore the saved position so we'll be ready to > * read the next offset. > */ > (void) SeekBlob(image, saved_pos, SEEK_SET); > >- return 1; >+ return MagickPass; > } > > >-static int ReadOneLayer( Image* image, XCFDocInfo* inDocInfo, XCFLayerInfo* >- outLayer ) >+static MagickPassFail ReadOneLayer( Image* image, XCFDocInfo* inDocInfo, XCFLayerInfo* >+ outLayer ) > { > int > i; >@@ -741,102 +934,113 @@ > (void) ReadBlobStringWithLongSize(image, outLayer->name, > sizeof(outLayer->name)); > >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "Loading layer \"%s\", dimensions %lux%lu, type %lu", >+ outLayer->name, >+ (unsigned long) outLayer->width, >+ (unsigned long) outLayer->height, >+ (unsigned long) outLayer->type); >+ > /* allocate the image for this layer */ > outLayer->image=CloneImage(image,outLayer->width, outLayer->height,True, > &image->exception); > if (outLayer->image == (Image *) NULL) >- return False; >+ return MagickFail; > > /* read the layer properties! */ > foundPropEnd = 0; >- while ( !foundPropEnd && !EOFBlob(image) ) { >- PropType prop_type = (PropType) ReadBlobMSBLong(image); >- unsigned long prop_size = ReadBlobMSBLong(image); >- >- switch (prop_type) >- { >- case PROP_END: >- foundPropEnd = 1; >- break; >- case PROP_ACTIVE_LAYER: >- outLayer->active = 1; >- break; >- case PROP_FLOATING_SELECTION: >- outLayer->floating_offset = ReadBlobMSBLong(image); >- break; >- case PROP_OPACITY: >- outLayer->opacity = ReadBlobMSBLong(image); >- break; >- case PROP_VISIBLE: >- outLayer->visible = ReadBlobMSBLong(image); >- break; >- case PROP_LINKED: >- outLayer->linked = ReadBlobMSBLong(image); >- break; >- case PROP_PRESERVE_TRANSPARENCY: >- outLayer->preserve_trans = ReadBlobMSBLong(image); >- break; >- case PROP_APPLY_MASK: >- outLayer->apply_mask = ReadBlobMSBLong(image); >- break; >- case PROP_EDIT_MASK: >- outLayer->edit_mask = ReadBlobMSBLong(image); >- break; >- case PROP_SHOW_MASK: >- outLayer->show_mask = ReadBlobMSBLong(image); >- break; >- case PROP_OFFSETS: >- outLayer->offset_x = (magick_int32_t) ReadBlobMSBLong(image); >- outLayer->offset_y = (magick_int32_t) ReadBlobMSBLong(image); >- break; >- case PROP_MODE: >- outLayer->mode = ReadBlobMSBLong(image); >- break; >- case PROP_TATTOO: >- outLayer->preserve_trans = ReadBlobMSBLong(image); >- break; >- case PROP_PARASITES: >- { >- for (i=0; i<(long) prop_size; i++ ) >- (void) ReadBlobByte(image); >- >- /* >- long base = info->cp; >- GimpParasite *p; >- while (info->cp - base < prop_size) >- { >- p = xcf_load_parasite(info); >- gimp_drawable_parasite_attach(GIMP_DRAWABLE(layer), p); >- gimp_parasite_free(p); >- } >- if (info->cp - base != prop_size) >- g_message ("Error detected while loading a layer's parasites"); >- */ >- } >- break; >- default: >- /* g_message ("unexpected/unknown layer property: %d (skipping)", >- prop_type); */ >+ while ( !foundPropEnd && !EOFBlob(image) ) >+ { >+ PropType prop_type = (PropType) ReadBlobMSBLong(image); >+ unsigned long prop_size = ReadBlobMSBLong(image); > >+ switch (prop_type) > { >- int buf[16]; >- unsigned int amount; >+ case PROP_END: >+ foundPropEnd = 1; >+ break; >+ case PROP_ACTIVE_LAYER: >+ outLayer->active = 1; >+ break; >+ case PROP_FLOATING_SELECTION: >+ outLayer->floating_offset = ReadBlobMSBLong(image); >+ break; >+ case PROP_OPACITY: >+ outLayer->opacity = ReadBlobMSBLong(image); >+ break; >+ case PROP_VISIBLE: >+ outLayer->visible = ReadBlobMSBLong(image); >+ break; >+ case PROP_LINKED: >+ outLayer->linked = ReadBlobMSBLong(image); >+ break; >+ case PROP_PRESERVE_TRANSPARENCY: >+ outLayer->preserve_trans = ReadBlobMSBLong(image); >+ break; >+ case PROP_APPLY_MASK: >+ outLayer->apply_mask = ReadBlobMSBLong(image); >+ break; >+ case PROP_EDIT_MASK: >+ outLayer->edit_mask = ReadBlobMSBLong(image); >+ break; >+ case PROP_SHOW_MASK: >+ outLayer->show_mask = ReadBlobMSBLong(image); >+ break; >+ case PROP_OFFSETS: >+ outLayer->offset_x = (magick_int32_t) ReadBlobMSBLong(image); >+ outLayer->offset_y = (magick_int32_t) ReadBlobMSBLong(image); >+ break; >+ case PROP_MODE: >+ outLayer->mode = ReadBlobMSBLong(image); >+ break; >+ case PROP_TATTOO: >+ outLayer->preserve_trans = ReadBlobMSBLong(image); >+ break; >+ case PROP_PARASITES: >+ { >+ for (i=0; i < (long) prop_size; i++ ) >+ if (ReadBlobByte(image) == EOF) >+ break; >+ >+ /* >+ long base = info->cp; >+ GimpParasite *p; >+ while (info->cp - base < prop_size) >+ { >+ p = xcf_load_parasite(info); >+ gimp_drawable_parasite_attach(GIMP_DRAWABLE(layer), p); >+ gimp_parasite_free(p); >+ } >+ if (info->cp - base != prop_size) >+ g_message ("Error detected while loading a layer's parasites"); >+ */ >+ } >+ break; >+ default: >+ /* g_message ("unexpected/unknown layer property: %d (skipping)", >+ prop_type); */ > >- /* read over it... */ >- while (prop_size > 0 && !EOFBlob(image)) >- { >- amount = Min (16, prop_size); >- for (i=0; i<(long)amount; i++) >- amount = ReadBlob(image, amount, &buf); >- prop_size -= Min (16, amount); >- } >+ { >+ int buf[16]; >+ size_t amount; >+ >+ /* read over it... */ >+ while (prop_size > 0 && !EOFBlob(image)) >+ { >+ amount = Min (16, prop_size); >+ for (i=0; i < (long) amount; i++) >+ if (ReadBlob(image, amount, &buf) != amount) >+ break; >+ prop_size -= Min (16, amount); >+ } >+ } >+ break; > } >- break; >- } >- } >+ } > > if (!foundPropEnd) >- return False; >+ return MagickFail; > > /* clear the image based on the layer opacity */ > (void) SetImage(outLayer->image,(Quantum)(255-outLayer->opacity)); >@@ -855,8 +1059,8 @@ > > /* read in the hierarchy */ > (void) SeekBlob(image, hierarchy_offset, SEEK_SET); >- if (!load_hierarchy (image, inDocInfo, outLayer)) >- return 0; >+ if (load_hierarchy (image, inDocInfo, outLayer) == MagickFail) >+ return MagickFail; > > /* read in the layer mask */ > if (layer_mask_offset != 0) >@@ -891,7 +1095,7 @@ > } > #endif > >- return True; >+ return MagickPass; > } > > /* >@@ -958,7 +1162,7 @@ > assert(exception->signature == MagickSignature); > image=AllocateImage(image_info); > status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); >- if (status == False) >+ if (status == MagickFail) > ThrowReaderException(FileOpenError,UnableToOpenFile,image); > count=ReadBlob(image,14,(char *) magick); > if ((count == 0) || >@@ -972,392 +1176,405 @@ > image->columns = doc_info.width = ReadBlobMSBLong(image); > image->rows = doc_info.height = ReadBlobMSBLong(image); > image_type = doc_info.image_type = ReadBlobMSBLong(image); >+ >+ /* >+ Get file size to use for validation later. >+ */ >+ doc_info.file_size=GetBlobSize(image); >+ >+ if (image->logging) >+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), >+ "XCF dimensions %lux%lu, type %s", >+ image->columns,image->rows, >+ (image_type == GIMP_RGB ? "RGB" : >+ (image_type == GIMP_GRAY ? "GRAY" : >+ (image_type == GIMP_INDEXED ? "INDEXED" : >+ "unknown")))); > > /* setup some things about the image...*/ > image->compression=NoCompression; > image->depth = 8; >- if ( image_type == GIMP_RGB ) { >- image->colorspace=RGBColorspace; >- } else if ( image_type == GIMP_GRAY ) { >- image->colorspace=GRAYColorspace; >- } else if ( image_type == GIMP_INDEXED ) >- ThrowReaderException(CoderError,ColormapTypeNotSupported,image); >+ if ( image_type == GIMP_RGB ) >+ { >+ image->colorspace=RGBColorspace; >+ } >+ else if ( image_type == GIMP_GRAY ) >+ { >+ image->colorspace=GRAYColorspace; >+ } >+ else if ( image_type == GIMP_INDEXED ) >+ { >+ ThrowReaderException(CoderError,ColormapTypeNotSupported,image); >+ } > (void) SetImage(image,OpaqueOpacity); /* until we know otherwise...*/ > image->matte=True; /* XCF always has a matte! */ > > /* read properties */ >- while ( !foundPropEnd && !EOFBlob(image) ) { >- PropType prop_type = (PropType) ReadBlobMSBLong(image); >- unsigned long prop_size = ReadBlobMSBLong(image); >- >- switch ( prop_type ) { >- case PROP_END: >- foundPropEnd = 1; >- >- case PROP_COLORMAP: >- /* BOGUS: just skip it for now */ >- for (i=0; i<prop_size; i++ ) >- (void) ReadBlobByte(image); >- /* >- if (info->file_version == 0) >- { >- gint i; >+ while ( !foundPropEnd && !EOFBlob(image) ) >+ { >+ PropType prop_type = (PropType) ReadBlobMSBLong(image); >+ unsigned long prop_size = ReadBlobMSBLong(image); > >- g_message (_("XCF warning: version 0 of XCF file format\n" >- "did not save indexed colormaps correctly.\n" >- "Substituting grayscale map.")); >- info->cp += >- xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1); >- gimage->cmap = g_new (guchar, gimage->num_cols*3); >- xcf_seek_pos (info, info->cp + gimage->num_cols); >- for (i = 0; i<gimage->num_cols; i++) >- { >- gimage->cmap[i*3+0] = i; >- gimage->cmap[i*3+1] = i; >- gimage->cmap[i*3+2] = i; >- } >- } >- else >+ switch ( prop_type ) > { >- info->cp += >- xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1); >- gimage->cmap = g_new (guchar, gimage->num_cols*3); >- info->cp += >- xcf_read_int8 (info->fp, >- (guint8*) gimage->cmap, gimage->num_cols*3); >- } >- */ >- break; >+ case PROP_END: >+ foundPropEnd = 1; > >- case PROP_COMPRESSION: >- { >- doc_info.compression = ReadBlobByte(image); >- >- if ((doc_info.compression != COMPRESS_NONE) && >- (doc_info.compression != COMPRESS_RLE) && >- (doc_info.compression != COMPRESS_ZLIB) && >- (doc_info.compression != COMPRESS_FRACTAL)) >- ThrowReaderException(CorruptImageWarning,CompressionNotValid,image); >- } >- break; >+ case PROP_COLORMAP: >+ /* BOGUS: just skip it for now */ >+ for (i=0; i <prop_size; i++ ) >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ /* >+ if (info->file_version == 0) >+ { >+ gint i; > >- case PROP_GUIDES: >- { >- /* just skip it - we don't care about guides */ >- for (i=0; i<prop_size; i++ ) >- (void) ReadBlobByte(image); >- } >- break; >+ g_message (_("XCF warning: version 0 of XCF file format\n" >+ "did not save indexed colormaps correctly.\n" >+ "Substituting grayscale map.")); >+ info->cp += >+ xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1); >+ gimage->cmap = g_new (guchar, gimage->num_cols*3); >+ xcf_seek_pos (info, info->cp + gimage->num_cols); >+ for (i = 0; i<gimage->num_cols; i++) >+ { >+ gimage->cmap[i*3+0] = i; >+ gimage->cmap[i*3+1] = i; >+ gimage->cmap[i*3+2] = i; >+ } >+ } >+ else >+ { >+ info->cp += >+ xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1); >+ gimage->cmap = g_new (guchar, gimage->num_cols*3); >+ info->cp += >+ xcf_read_int8 (info->fp, >+ (guint8*) gimage->cmap, gimage->num_cols*3); >+ } >+ */ >+ break; > >- case PROP_RESOLUTION: >- { >- /* float xres = (float) */ (void) ReadBlobMSBLong(image); >- /* float yres = (float) */ (void) ReadBlobMSBLong(image); >- >- /* >- if (xres < GIMP_MIN_RESOLUTION || xres > GIMP_MAX_RESOLUTION || >- yres < GIMP_MIN_RESOLUTION || yres > GIMP_MAX_RESOLUTION) >+ case PROP_COMPRESSION: > { >- g_message ("Warning, resolution out of range in XCF file"); >- xres = gimage->gimp->config->default_xresolution; >- yres = gimage->gimp->config->default_yresolution; >+ doc_info.compression = ReadBlobByte(image); >+ >+ if ((doc_info.compression != COMPRESS_NONE) && >+ (doc_info.compression != COMPRESS_RLE) && >+ (doc_info.compression != COMPRESS_ZLIB) && >+ (doc_info.compression != COMPRESS_FRACTAL)) >+ ThrowReaderException(CorruptImageWarning,CompressionNotValid,image); > } >- */ >+ break; > >- >- /* BOGUS: we don't write these yet because we aren't >- // reading them properly yet :( >- //image->x_resolution = xres; >- //image->y_resolution = yres; >- */ >- } >- break; >+ case PROP_GUIDES: >+ { >+ /* just skip it - we don't care about guides */ >+ for (i=0; i < prop_size; i++ ) >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ } >+ break; > >- case PROP_TATTOO: >- { >- /* we need to read it, even if we ignore it */ >- /*unsigned long tattoo_state = */ (void) ReadBlobMSBLong(image); >- } >- break; >+ case PROP_RESOLUTION: >+ { >+ /* float xres = (float) */ (void) ReadBlobMSBLong(image); >+ /* float yres = (float) */ (void) ReadBlobMSBLong(image); >+ >+ /* >+ if (xres < GIMP_MIN_RESOLUTION || xres > GIMP_MAX_RESOLUTION || >+ yres < GIMP_MIN_RESOLUTION || yres > GIMP_MAX_RESOLUTION) >+ { >+ g_message ("Warning, resolution out of range in XCF file"); >+ xres = gimage->gimp->config->default_xresolution; >+ yres = gimage->gimp->config->default_yresolution; >+ } >+ */ > >- case PROP_PARASITES: >- { >- /* BOGUS: we may need these for IPTC stuff */ >- for (i=0; i<prop_size; i++ ) >- (void) ReadBlobByte(image); >- >- /* >- glong base = info->cp; >- GimpParasite *p; >+ >+ /* BOGUS: we don't write these yet because we aren't >+ // reading them properly yet :( >+ //image->x_resolution = xres; >+ //image->y_resolution = yres; >+ */ >+ } >+ break; > >- while (info->cp - base < prop_size) >+ case PROP_TATTOO: > { >- p = xcf_load_parasite (info); >- gimp_image_parasite_attach (gimage, p); >- gimp_parasite_free (p); >+ /* we need to read it, even if we ignore it */ >+ /*unsigned long tattoo_state = */ (void) ReadBlobMSBLong(image); > } >- if (info->cp - base != prop_size) >- g_message ("Error detected while loading an image's parasites"); >- */ >- } >- break; >+ break; > >- case PROP_UNIT: >- { >- /* BOGUS: ignore for now... */ >- /*unsigned long unit = */ (void) ReadBlobMSBLong(image); >- } >- break; >+ case PROP_PARASITES: >+ { >+ /* BOGUS: we may need these for IPTC stuff */ >+ for (i=0; i<prop_size; i++ ) >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ >+ /* >+ glong base = info->cp; >+ GimpParasite *p; >+ >+ while (info->cp - base < prop_size) >+ { >+ p = xcf_load_parasite (info); >+ gimp_image_parasite_attach (gimage, p); >+ gimp_parasite_free (p); >+ } >+ if (info->cp - base != prop_size) >+ g_message ("Error detected while loading an image's parasites"); >+ */ >+ } >+ break; > >- case PROP_PATHS: >- { >- /* BOGUS: just skip it for now */ >- for (i=0; i<prop_size; i++ ) >- (void) ReadBlobByte(image); >- >- /* >- PathList *paths = xcf_load_bzpaths (gimage, info); >- gimp_image_set_paths (gimage, paths); >- */ >- } >- break; >+ case PROP_UNIT: >+ { >+ /* BOGUS: ignore for now... */ >+ /*unsigned long unit = */ (void) ReadBlobMSBLong(image); >+ } >+ break; > >- case PROP_USER_UNIT: >- { >- char unit_string[1000]; >- /*BOGUS: ignored for now */ >- /*float factor = (float) */ (void) ReadBlobMSBLong(image); >- /* unsigned long digits = */ (void) ReadBlobMSBLong(image); >- for (i=0; i<5; i++) >- (void) ReadBlobStringWithLongSize(image, unit_string, >- sizeof(unit_string)); >- } >- break; >+ case PROP_PATHS: >+ { >+ /* BOGUS: just skip it for now */ >+ for (i=0; i<prop_size; i++ ) >+ if (ReadBlobByte(image) == EOF) >+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); >+ >+ /* >+ PathList *paths = xcf_load_bzpaths (gimage, info); >+ gimp_image_set_paths (gimage, paths); >+ */ >+ } >+ break; > >- default: >- /* g_message ("unexpected/unknown image property: %d (skipping)", >- prop_type); */ >+ case PROP_USER_UNIT: >+ { >+ char unit_string[1000]; >+ /*BOGUS: ignored for now */ >+ /*float factor = (float) */ (void) ReadBlobMSBLong(image); >+ /* unsigned long digits = */ (void) ReadBlobMSBLong(image); >+ for (i=0; i < 5; i++) >+ (void) ReadBlobStringWithLongSize(image, unit_string, >+ sizeof(unit_string)); >+ } >+ break; > >- { >- int buf[16]; >- long amount; >+ default: >+ /* g_message ("unexpected/unknown image property: %d (skipping)", >+ prop_type); */ > >- /* read over it... */ >- while (prop_size > 0 && !EOFBlob(image)) > { >- amount = (long) Min (16, prop_size); >- for (i=0; i<(unsigned long) amount; i++) >- amount = (long) ReadBlob(image, amount, &buf); >- prop_size -= Min (16, amount); >+ int buf[16]; >+ long amount; >+ >+ /* read over it... */ >+ while (prop_size > 0 && !EOFBlob(image)) >+ { >+ amount = (long) Min (16, prop_size); >+ for (i=0; i<(unsigned long) amount; i++) >+ amount = (long) ReadBlob(image, amount, &buf); >+ prop_size -= Min (16, amount); >+ } > } >- } >- break; >+ break; >+ } > } >- } > > if (!foundPropEnd) > ThrowReaderException(CorruptImageError,ImproperImageHeader,image); > >- if (image_info->ping && (image_info->subrange != 0)) { >- ; /* do nothing, we were just pinging! */ >- } else { >- XCFLayerInfo* layer_info; >- int number_layers = 0, >- current_layer = 0, >- foundAllLayers = False; >- >- /* BIG HACK >- because XCF doesn't include the layer count, and we >- want to know it in advance in order to allocate memory, >- we have to scan the layer offset list, and then reposition >- the read pointer >- */ >- ExtendedSignedIntegralType oldPos = TellBlob(image); >- do { >- long offset = (long) ReadBlobMSBLong(image); >- if ( offset == 0 ) >- foundAllLayers = True; >- else >- number_layers++; >- } while ( !foundAllLayers ); >- (void) SeekBlob(image, oldPos, SEEK_SET); /* restore the position! */ >- >- >- /* allocate our array of layer info blocks */ >- layer_info=MagickAllocateArray(XCFLayerInfo *, >- number_layers, >- sizeof(XCFLayerInfo)); >- if (layer_info == (XCFLayerInfo *) NULL) >- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >- (void) memset(layer_info,0,number_layers*sizeof(XCFLayerInfo)); >- >- for ( ; ; ) >- { >- ExtendedSignedIntegralType >- offset, >- saved_pos; >- int >- layer_ok; >- >- /* read in the offset of the next layer */ >- offset = ReadBlobMSBLong(image); >- >- /* if the offset is 0 then we are at the end >- * of the layer list. >- */ >- if (offset == 0) >- break; >- >- /* save the current position as it is where the >- * next layer offset is stored. >- */ >- saved_pos = TellBlob(image); >- >- /* seek to the layer offset */ >- (void) SeekBlob(image, offset, SEEK_SET); >- >- /* read in the layer */ >- layer_ok = ReadOneLayer( image, &doc_info, &layer_info[current_layer] ); >- if (!layer_ok) { >- int j; >- for (j=0; j < current_layer; j++) >- DestroyImage(layer_info[j].image); >- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image) >- } >+ if (image_info->ping && (image_info->subrange != 0)) >+ { >+ ; /* do nothing, we were just pinging! */ >+ } >+ else >+ { >+ XCFLayerInfo >+ *layer_info; > >- /* restore the saved position so we'll be ready to >- * read the next offset. >- */ >- (void) SeekBlob(image, saved_pos, SEEK_SET); >+ int >+ number_layers = 0, >+ current_layer = 0, >+ foundAllLayers = False; >+ >+ /* BIG HACK >+ because XCF doesn't include the layer count, and we >+ want to know it in advance in order to allocate memory, >+ we have to scan the layer offset list, and then reposition >+ the read pointer >+ */ >+ magick_off_t oldPos = TellBlob(image); >+ do >+ { >+ long >+ offset = (long) ReadBlobMSBLong(image); > >- current_layer++; >- } >+ if ( offset == 0 ) >+ foundAllLayers = True; >+ else >+ number_layers++; >+ } while ( !foundAllLayers ); >+ (void) SeekBlob(image, oldPos, SEEK_SET); /* restore the position! */ > >- if ( number_layers == 1 ) { >- /* composite the layer data onto the main image & then dispose the layer */ >- (void) CompositeImage(image, OverCompositeOp, layer_info[0].image, >- layer_info[0].offset_x, layer_info[0].offset_y ); >- DestroyImage( layer_info[0].image ); >- >- /* Bob says that if we do this, we'll get REAL gray images! */ >- if ( image_type == GIMP_GRAY ) { >- QuantizeInfo qi; >- GetQuantizeInfo(&qi); >- qi.colorspace = GRAYColorspace; >- (void) QuantizeImage( &qi, image ); >- } >- } else { >+ >+ /* allocate our array of layer info blocks */ >+ layer_info=MagickAllocateArray(XCFLayerInfo *, >+ number_layers, >+ sizeof(XCFLayerInfo)); >+ if (layer_info == (XCFLayerInfo *) NULL) >+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); >+ (void) memset(layer_info,0,number_layers*sizeof(XCFLayerInfo)); >+ >+ for ( ; ; ) >+ { >+ magick_off_t >+ offset, >+ saved_pos; >+ >+ MagickPassFail >+ layer_ok; >+ >+ /* read in the offset of the next layer */ >+ offset = ReadBlobMSBLong(image); >+ >+ /* if the offset is 0 then we are at the end >+ * of the layer list. >+ */ >+ if (offset == 0) >+ break; >+ >+ /* save the current position as it is where the >+ * next layer offset is stored. >+ */ >+ saved_pos = TellBlob(image); >+ >+ /* seek to the layer offset */ >+ (void) SeekBlob(image, offset, SEEK_SET); >+ >+ /* read in the layer */ >+ layer_ok = ReadOneLayer( image, &doc_info, &layer_info[current_layer] ); >+ if (!layer_ok) { >+ int >+ j; >+ >+ for (j=0; j < current_layer; j++) >+ DestroyImage(layer_info[j].image); >+ MagickFreeMemory(layer_info); >+ CopyException(exception,&image->exception); >+ CloseBlob(image); >+ DestroyImageList(image); >+ return (Image *) NULL; >+ } >+ >+ /* restore the saved position so we'll be ready to >+ * read the next offset. >+ */ >+ (void) SeekBlob(image, saved_pos, SEEK_SET); >+ >+ current_layer++; >+ } >+ >+ if ( number_layers == 1 ) { >+ /* composite the layer data onto the main image & then dispose the layer */ >+ (void) CompositeImage(image, OverCompositeOp, layer_info[0].image, >+ layer_info[0].offset_x, layer_info[0].offset_y ); >+ DestroyImage( layer_info[0].image ); >+ >+ } else { > #if 0 >- { >- /* NOTE: XCF layers are REVERSED from composite order! */ >- signed int j; >- for (j=number_layers-1; j>=0; j--) { >- /* BOGUS: need to consider layer blending modes!! */ >+ { >+ /* NOTE: XCF layers are REVERSED from composite order! */ >+ signed int j; >+ for (j=number_layers-1; j>=0; j--) { >+ /* 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 ); >- DestroyImage( layer_info[j].image ); >- >- /* Bob says that if we do this, we'll get REAL gray images! */ >- if ( image_type == GIMP_GRAY ) { >- QuantizeInfo qi; >- GetQuantizeInfo(&qi); >- qi.colorspace = GRAYColorspace; >- QuantizeImage( &qi, layer_info[j].image ); >+ 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 ); >+ DestroyImage( layer_info[j].image ); > } > } > } >- } > #else >- { >- /* NOTE: XCF layers are REVERSED from composite order! */ >- 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 ); >- DestroyImage( layer_info[number_layers-1].image ); >- >- /* Bob says that if we do this, we'll get REAL gray images! */ >- if ( image_type == GIMP_GRAY ) { >- QuantizeInfo qi; >- GetQuantizeInfo(&qi); >- qi.colorspace = GRAYColorspace; >- (void) QuantizeImage( &qi, image ); >- } >+ { >+ /* NOTE: XCF layers are REVERSED from composite order! */ >+ signed int j; > >- /* now reverse the order of the layers as they are put >- into subimages >- */ >- image->next=layer_info[number_layers-2].image; >- layer_info[number_layers-2].image->previous=image; >- for (j=number_layers-2; j>=0; j--) >- { >- if (j > 0) >- layer_info[j].image->next=layer_info[j-1].image; >- if (j < (number_layers-1)) >- layer_info[j].image->previous=layer_info[j+1].image; >- layer_info[j].image->page.x = layer_info[j].offset_x; >- layer_info[j].image->page.y = layer_info[j].offset_y; >- layer_info[j].image->page.width = layer_info[j].width; >- layer_info[j].image->page.height = layer_info[j].height; >- >- /* Bob says that if we do this, we'll get REAL gray images! */ >- if ( image_type == GIMP_GRAY ) { >- QuantizeInfo qi; >- GetQuantizeInfo(&qi); >- qi.colorspace = GRAYColorspace; >- (void) QuantizeImage( &qi, layer_info[j].image ); >+ /* 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 ); >+ DestroyImage( layer_info[number_layers-1].image ); >+ >+ /* now reverse the order of the layers as they are put >+ into subimages >+ */ >+ image->next=layer_info[number_layers-2].image; >+ layer_info[number_layers-2].image->previous=image; >+ for (j=number_layers-2; j>=0; j--) >+ { >+ if (j > 0) >+ layer_info[j].image->next=layer_info[j-1].image; >+ if (j < (number_layers-1)) >+ layer_info[j].image->previous=layer_info[j+1].image; >+ layer_info[j].image->page.x = layer_info[j].offset_x; >+ layer_info[j].image->page.y = layer_info[j].offset_y; >+ layer_info[j].image->page.width = layer_info[j].width; >+ layer_info[j].image->page.height = layer_info[j].height; > } >- } >- } >+ } > #endif >- } >+ } > >- MagickFreeMemory(layer_info); >+ MagickFreeMemory(layer_info); > > #if 0 /* BOGUS: do we need the channels?? */ >- while (True) >- { >- /* read in the offset of the next channel */ >- info->cp += xcf_read_int32 (info->fp, &offset, 1); >- >- /* if the offset is 0 then we are at the end >- * of the channel list. >- */ >- if (offset == 0) >- break; >- >- /* save the current position as it is where the >- * next channel offset is stored. >- */ >- saved_pos = info->cp; >- >- /* seek to the channel offset */ >- xcf_seek_pos (info, offset); >- >- /* read in the layer */ >- channel = xcf_load_channel (info, gimage); >- if (!channel) >- goto error; >- >- num_successful_elements++; >- >- /* add the channel to the image if its not the selection */ >- if (channel != gimage->selection_mask) >- gimp_image_add_channel (gimage, channel, -1); >- >- /* restore the saved position so we'll be ready to >- * read the next offset. >- */ >- xcf_seek_pos (info, saved_pos); >- } >+ while (True) >+ { >+ /* read in the offset of the next channel */ >+ info->cp += xcf_read_int32 (info->fp, &offset, 1); >+ >+ /* if the offset is 0 then we are at the end >+ * of the channel list. >+ */ >+ if (offset == 0) >+ break; >+ >+ /* save the current position as it is where the >+ * next channel offset is stored. >+ */ >+ saved_pos = info->cp; >+ >+ /* seek to the channel offset */ >+ xcf_seek_pos (info, offset); >+ >+ /* read in the layer */ >+ channel = xcf_load_channel (info, gimage); >+ if (!channel) >+ goto error; >+ >+ num_successful_elements++; >+ >+ /* add the channel to the image if its not the selection */ >+ if (channel != gimage->selection_mask) >+ gimp_image_add_channel (gimage, channel, -1); >+ >+ /* restore the saved position so we'll be ready to >+ * read the next offset. >+ */ >+ xcf_seek_pos (info, saved_pos); >+ } > #endif >- } >+ } > > CloseBlob(image); >+ if ( image_type == GIMP_GRAY ) >+ image->is_grayscale=MagickTrue; > return(image); > } > >Index: magick/image.c >=================================================================== >RCS file: /GraphicsMagick/GraphicsMagick/magick/image.c,v >retrieving revision 1.1277 >retrieving revision 1.1278 >diff -u -u -r1.1277 -r1.1278 >--- magick/image.c 27 May 2008 23:37:43 -0000 1.1277 >+++ magick/image.c 11 Jun 2008 00:19:58 -0000 1.1278 >@@ -2996,7 +2996,7 @@ > characteristics->opaque = (image->matte ? MagickFalse : MagickTrue); > characteristics->palette = (image->storage_class == PseudoClass ? MagickTrue : MagickFalse); > >- if ((optimize)) >+ if ((optimize) && (GetPixelCachePresent(image))) > { > MagickBool > grayscale,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 454982
: 311575