1 |
--- a/coders/pcx.c |
2 |
+++ b/coders/pcx.c |
3 |
@@ -39,6 +39,7 @@ |
4 |
#include "magick/analyze.h" |
5 |
#include "magick/blob.h" |
6 |
#include "magick/colormap.h" |
7 |
+#include "magick/log.h" |
8 |
#include "magick/magick.h" |
9 |
#include "magick/monitor.h" |
10 |
#include "magick/pixel_cache.h" |
11 |
@@ -69,7 +70,9 @@ |
12 |
|
13 |
unsigned short |
14 |
bytes_per_line, |
15 |
- palette_info; |
16 |
+ palette_info, |
17 |
+ horizontal_screen_size, |
18 |
+ vertical_screen_size; |
19 |
|
20 |
unsigned char |
21 |
colormap_signature; |
22 |
@@ -190,13 +193,20 @@ |
23 |
% |
24 |
% |
25 |
*/ |
26 |
+#define ThrowPCXReaderException(code_,reason_,image_) \ |
27 |
+{ \ |
28 |
+ MagickFreeMemory(page_table) \ |
29 |
+ MagickFreeMemory(pcx_pixels); \ |
30 |
+ MagickFreeMemory(scanline); \ |
31 |
+ ThrowReaderException(code_,reason_,image_); \ |
32 |
+} |
33 |
static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception) |
34 |
{ |
35 |
Image |
36 |
*image; |
37 |
|
38 |
ExtendedSignedIntegralType |
39 |
- *page_table; |
40 |
+ *page_table = (ExtendedSignedIntegralType *) NULL; |
41 |
|
42 |
int |
43 |
bits, |
44 |
@@ -230,14 +240,14 @@ |
45 |
|
46 |
unsigned char |
47 |
packet, |
48 |
- *pcx_colormap = 0, |
49 |
- *pcx_pixels, |
50 |
- *scanline; |
51 |
+ pcx_colormap[256*3], |
52 |
+ *pcx_pixels = (unsigned char *) NULL, |
53 |
+ *scanline = (unsigned char *) NULL; |
54 |
|
55 |
unsigned int |
56 |
status; |
57 |
|
58 |
- unsigned long |
59 |
+ size_t |
60 |
pcx_packets; |
61 |
|
62 |
/* |
63 |
@@ -250,7 +260,7 @@ |
64 |
image=AllocateImage(image_info); |
65 |
status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
66 |
if (status == False) |
67 |
- ThrowReaderException(FileOpenError,UnableToOpenFile,image); |
68 |
+ ThrowPCXReaderException(FileOpenError,UnableToOpenFile,image); |
69 |
/* |
70 |
Determine if this is a PCX file. |
71 |
*/ |
72 |
@@ -265,11 +275,11 @@ |
73 |
*/ |
74 |
magic=ReadBlobLSBLong(image); |
75 |
if (magic != 987654321) |
76 |
- ThrowReaderException(CorruptImageError,ImproperImageHeader,image); |
77 |
- page_table=MagickAllocateMemory(ExtendedSignedIntegralType *, |
78 |
- 1024*sizeof(ExtendedSignedIntegralType)); |
79 |
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image); |
80 |
+ page_table=MagickAllocateArray(ExtendedSignedIntegralType *, |
81 |
+ 1024,sizeof(ExtendedSignedIntegralType)); |
82 |
if (page_table == (ExtendedSignedIntegralType *) NULL) |
83 |
- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
84 |
+ ThrowPCXReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
85 |
for (id=0; id < 1024; id++) |
86 |
{ |
87 |
page_table[id]=(ExtendedSignedIntegralType) ReadBlobLSBLong(image); |
88 |
@@ -280,7 +290,7 @@ |
89 |
if (page_table != (ExtendedSignedIntegralType *) NULL) |
90 |
if (SeekBlob(image,(ExtendedSignedIntegralType) page_table[0],SEEK_SET) |
91 |
== -1) |
92 |
- ThrowReaderException(CorruptImageError,ImproperImageHeader,image); |
93 |
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image); |
94 |
count=ReadBlob(image,1,(char *) &pcx_info.identifier); |
95 |
for (id=1; id < 1024; id++) |
96 |
{ |
97 |
@@ -289,7 +299,7 @@ |
98 |
*/ |
99 |
pcx_info.version=ReadBlobByte(image); |
100 |
if ((count == 0) || (pcx_info.identifier != 0x0aU)) |
101 |
- ThrowReaderException(CorruptImageError,ImproperImageHeader,image); |
102 |
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image); |
103 |
pcx_info.encoding=ReadBlobByte(image); |
104 |
pcx_info.bits_per_pixel=ReadBlobByte(image); |
105 |
pcx_info.left=ReadBlobLSBShort(image); |
106 |
@@ -305,15 +315,12 @@ |
107 |
image->rows=(pcx_info.bottom-pcx_info.top)+1; |
108 |
if ((image->columns == 0) || (image->rows == 0) || |
109 |
(pcx_info.bits_per_pixel == 0)) |
110 |
- ThrowReaderException(CorruptImageError,ImproperImageHeader,image); |
111 |
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image); |
112 |
image->depth=pcx_info.bits_per_pixel <= 8 ? 8 : QuantumDepth; |
113 |
image->units=PixelsPerInchResolution; |
114 |
image->x_resolution=pcx_info.horizontal_resolution; |
115 |
image->y_resolution=pcx_info.vertical_resolution; |
116 |
image->colors=16; |
117 |
- pcx_colormap=MagickAllocateMemory(unsigned char *,3*256); |
118 |
- if (pcx_colormap == (unsigned char *) NULL) |
119 |
- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
120 |
(void) ReadBlob(image,3*image->colors,(char *) pcx_colormap); |
121 |
pcx_info.reserved=ReadBlobByte(image); |
122 |
pcx_info.planes=ReadBlobByte(image); |
123 |
@@ -326,7 +333,7 @@ |
124 |
image->colors = 256; |
125 |
} |
126 |
if (!AllocateImageColormap(image,image->colors)) |
127 |
- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
128 |
+ ThrowPCXReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
129 |
if ((pcx_info.bits_per_pixel >= 8) && (pcx_info.planes != 1)) |
130 |
image->storage_class=DirectClass; |
131 |
p=pcx_colormap; |
132 |
@@ -338,7 +345,44 @@ |
133 |
} |
134 |
pcx_info.bytes_per_line=ReadBlobLSBShort(image); |
135 |
pcx_info.palette_info=ReadBlobLSBShort(image); |
136 |
- for (i=0; i < 58; i++) |
137 |
+ pcx_info.horizontal_screen_size=ReadBlobLSBShort(image); |
138 |
+ pcx_info.vertical_screen_size=ReadBlobLSBShort(image); |
139 |
+ |
140 |
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
141 |
+ "PCX Header (%d):\n" |
142 |
+ " version=%u\n" |
143 |
+ " encoding=%u\n" |
144 |
+ " bits_per_pixel=%u\n" |
145 |
+ " left=%u\n" |
146 |
+ " top=%u\n" |
147 |
+ " right=%u\n" |
148 |
+ " bottom=%u\n" |
149 |
+ " horizontal_resolution=%u\n" |
150 |
+ " vertical_resolution=%u\n" |
151 |
+ " reserved=%u\n" |
152 |
+ " planes=%u\n" |
153 |
+ " bytes_per_line=%u\n" |
154 |
+ " palette_info=%u\n" |
155 |
+ " horizontal_screen_size=%u\n" |
156 |
+ " vertical_screen_size=%u", |
157 |
+ id, |
158 |
+ (unsigned int) pcx_info.version, |
159 |
+ (unsigned int) pcx_info.encoding, |
160 |
+ (unsigned int) pcx_info.bits_per_pixel, |
161 |
+ (unsigned int) pcx_info.left, |
162 |
+ (unsigned int) pcx_info.top, |
163 |
+ (unsigned int) pcx_info.right, |
164 |
+ (unsigned int) pcx_info.bottom, |
165 |
+ (unsigned int) pcx_info.horizontal_resolution, |
166 |
+ (unsigned int) pcx_info.vertical_resolution, |
167 |
+ (unsigned int) pcx_info.reserved, |
168 |
+ (unsigned int) pcx_info.planes, |
169 |
+ (unsigned int) pcx_info.bytes_per_line, |
170 |
+ (unsigned int) pcx_info.palette_info, |
171 |
+ (unsigned int) pcx_info.horizontal_screen_size, |
172 |
+ (unsigned int) pcx_info.vertical_screen_size |
173 |
+ ); |
174 |
+ for (i=0; i < 54; i++) |
175 |
(void) ReadBlobByte(image); |
176 |
if (image_info->ping && (image_info->subrange != 0)) |
177 |
if (image->scene >= (image_info->subimage+image_info->subrange-1)) |
178 |
@@ -346,13 +390,16 @@ |
179 |
/* |
180 |
Read image data. |
181 |
*/ |
182 |
- pcx_packets=(unsigned long) image->rows*pcx_info.bytes_per_line*pcx_info.planes; |
183 |
+ pcx_packets=(size_t) image->rows*pcx_info.bytes_per_line*pcx_info.planes; |
184 |
+ if ((size_t) (pcx_info.bits_per_pixel*pcx_info.planes*image->columns) > |
185 |
+ (pcx_packets*8U)) |
186 |
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image); |
187 |
pcx_pixels=MagickAllocateMemory(unsigned char *,pcx_packets); |
188 |
- scanline=MagickAllocateMemory(unsigned char *,Max(image->columns, |
189 |
- (unsigned long) pcx_info.bytes_per_line)*Max(pcx_info.planes,8)); |
190 |
+ scanline=MagickAllocateArray(unsigned char *,Max(image->columns, |
191 |
+ (size_t) pcx_info.bytes_per_line),Max(pcx_info.planes,8)); |
192 |
if ((pcx_pixels == (unsigned char *) NULL) || |
193 |
(scanline == (unsigned char *) NULL)) |
194 |
- ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
195 |
+ ThrowPCXReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
196 |
if (pcx_info.encoding == 0) |
197 |
{ |
198 |
/* |
199 |
@@ -363,7 +410,7 @@ |
200 |
{ |
201 |
packet=ReadBlobByte(image); |
202 |
if (EOFBlob(image)) |
203 |
- ThrowReaderException(CorruptImageError,CorruptImage,image); |
204 |
+ ThrowPCXReaderException(CorruptImageError,CorruptImage,image); |
205 |
*p++=packet; |
206 |
pcx_packets--; |
207 |
continue; |
208 |
@@ -379,7 +426,7 @@ |
209 |
{ |
210 |
packet=ReadBlobByte(image); |
211 |
if (EOFBlob(image)) |
212 |
- ThrowReaderException(CorruptImageError,CorruptImage,image); |
213 |
+ ThrowPCXReaderException(CorruptImageError,CorruptImage,image); |
214 |
if ((packet & 0xc0) != 0xc0) |
215 |
{ |
216 |
*p++=packet; |
217 |
@@ -389,7 +436,7 @@ |
218 |
count=packet & 0x3f; |
219 |
packet=ReadBlobByte(image); |
220 |
if (EOFBlob(image)) |
221 |
- ThrowReaderException(CorruptImageError,CorruptImage,image); |
222 |
+ ThrowPCXReaderException(CorruptImageError,CorruptImage,image); |
223 |
for (; count != 0; count--) |
224 |
{ |
225 |
*p++=packet; |
226 |
@@ -409,7 +456,7 @@ |
227 |
Initialize image colormap. |
228 |
*/ |
229 |
if (image->colors > 256) |
230 |
- ThrowReaderException(CorruptImageError,ColormapExceeds256Colors, |
231 |
+ ThrowPCXReaderException(CorruptImageError,ColormapExceeds256Colors, |
232 |
image); |
233 |
if ((pcx_info.bits_per_pixel*pcx_info.planes) == 1) |
234 |
{ |
235 |
@@ -439,7 +486,6 @@ |
236 |
image->colormap[i].blue=ScaleCharToQuantum(*p++); |
237 |
} |
238 |
} |
239 |
- MagickFreeMemory(pcx_colormap); |
240 |
} |
241 |
/* |
242 |
Convert PCX raster image to pixel packets. |
243 |
@@ -594,7 +640,6 @@ |
244 |
} |
245 |
if (image->storage_class == PseudoClass) |
246 |
(void) SyncImage(image); |
247 |
- MagickFreeMemory(pcx_colormap); |
248 |
MagickFreeMemory(scanline); |
249 |
MagickFreeMemory(pcx_pixels); |
250 |
if (EOFBlob(image)) |
251 |
@@ -615,7 +660,7 @@ |
252 |
break; |
253 |
if (SeekBlob(image,(ExtendedSignedIntegralType) page_table[id],SEEK_SET) |
254 |
== -1) |
255 |
- ThrowReaderException(CorruptImageError,ImproperImageHeader,image); |
256 |
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image); |
257 |
count=ReadBlob(image,1,(char *) &pcx_info.identifier); |
258 |
if ((count != 0) && (pcx_info.identifier == 0x0a)) |
259 |
{ |