blob: a8ddac43df618fd2815992846d06ad3c83d22e5c [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% RRRR L EEEEE %
7% R R L E %
8% RRRR L EEE %
9% R R L E %
10% R R LLLLL EEEEE %
11% %
12% %
13% Read URT RLE Image Format %
14% %
15% Software Design %
cristyde984cd2013-12-01 14:49:27 +000016% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000017% July 1992 %
18% %
19% %
cristyb56bb242014-11-25 17:12:48 +000020% Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40 Include declarations.
41*/
cristy4c08aed2011-07-01 19:47:50 +000042#include "MagickCore/studio.h"
43#include "MagickCore/property.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
46#include "MagickCore/cache.h"
47#include "MagickCore/colormap.h"
48#include "MagickCore/exception.h"
49#include "MagickCore/exception-private.h"
50#include "MagickCore/image.h"
51#include "MagickCore/image-private.h"
52#include "MagickCore/list.h"
53#include "MagickCore/magick.h"
54#include "MagickCore/memory_.h"
55#include "MagickCore/monitor.h"
56#include "MagickCore/monitor-private.h"
57#include "MagickCore/pixel-accessor.h"
58#include "MagickCore/quantum-private.h"
59#include "MagickCore/pixel.h"
60#include "MagickCore/static.h"
61#include "MagickCore/string_.h"
62#include "MagickCore/module.h"
cristy3ed852e2009-09-05 21:47:34 +000063
64/*
65%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66% %
67% %
68% %
69% I s R L E %
70% %
71% %
72% %
73%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74%
75% IsRLE() returns MagickTrue if the image format type, identified by the
76% magick string, is RLE.
77%
78% The format of the ReadRLEImage method is:
79%
80% MagickBooleanType IsRLE(const unsigned char *magick,const size_t length)
81%
82% A description of each parameter follows:
83%
84% o magick: compare image format pattern against these bytes.
85%
86% o length: Specifies the length of the magick string.
87%
88%
89*/
90static MagickBooleanType IsRLE(const unsigned char *magick,const size_t length)
91{
92 if (length < 2)
93 return(MagickFalse);
94 if (memcmp(magick,"\122\314",2) == 0)
95 return(MagickTrue);
96 return(MagickFalse);
97}
98
99/*
100%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101% %
102% %
103% %
104% R e a d R L E I m a g e %
105% %
106% %
107% %
108%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109%
110% ReadRLEImage() reads a run-length encoded Utah Raster Toolkit
111% image file and returns it. It allocates the memory necessary for the new
112% Image structure and returns a pointer to the new image.
113%
114% The format of the ReadRLEImage method is:
115%
116% Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
117%
118% A description of each parameter follows:
119%
120% o image_info: the image info.
121%
122% o exception: return any errors or warnings in this structure.
123%
124%
125*/
126static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
127{
128#define SkipLinesOp 0x01
129#define SetColorOp 0x02
130#define SkipPixelsOp 0x03
131#define ByteDataOp 0x05
132#define RunDataOp 0x06
133#define EOFOp 0x07
134
135 char
136 magick[12];
137
138 Image
139 *image;
140
141 int
142 opcode,
143 operand,
144 status;
145
cristy3ed852e2009-09-05 21:47:34 +0000146 MagickStatusType
147 flags;
148
149 MagickSizeType
150 number_pixels;
151
cristyb64823d2013-06-30 20:58:24 +0000152 MemoryInfo
153 *pixel_info;
154
cristybb503372010-05-27 20:51:26 +0000155 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000156 x;
157
cristy4c08aed2011-07-01 19:47:50 +0000158 register Quantum
cristy3ed852e2009-09-05 21:47:34 +0000159 *q;
160
cristybb503372010-05-27 20:51:26 +0000161 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000162 i;
163
164 register unsigned char
165 *p;
166
cristyc6da28e2011-04-28 01:41:35 +0000167 size_t
168 bits_per_pixel,
169 map_length,
170 number_colormaps,
171 number_planes,
172 one;
173
cristy3ed852e2009-09-05 21:47:34 +0000174 ssize_t
cristyc6da28e2011-04-28 01:41:35 +0000175 count,
176 y;
cristy3ed852e2009-09-05 21:47:34 +0000177
178 unsigned char
179 background_color[256],
180 *colormap,
181 pixel,
182 plane,
cristyb64823d2013-06-30 20:58:24 +0000183 *pixels;
cristy3ed852e2009-09-05 21:47:34 +0000184
cristy3ed852e2009-09-05 21:47:34 +0000185 /*
186 Open image file.
187 */
188 assert(image_info != (const ImageInfo *) NULL);
189 assert(image_info->signature == MagickSignature);
190 if (image_info->debug != MagickFalse)
191 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
192 image_info->filename);
193 assert(exception != (ExceptionInfo *) NULL);
194 assert(exception->signature == MagickSignature);
cristy9950d572011-10-01 18:22:35 +0000195 image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +0000196 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
197 if (status == MagickFalse)
198 {
199 image=DestroyImageList(image);
200 return((Image *) NULL);
201 }
202 /*
203 Determine if this a RLE file.
204 */
205 count=ReadBlob(image,2,(unsigned char *) magick);
206 if ((count == 0) || (memcmp(magick,"\122\314",2) != 0))
207 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
208 do
209 {
210 /*
211 Read image header.
212 */
213 (void) ReadBlobLSBShort(image);
214 (void) ReadBlobLSBShort(image);
215 image->columns=ReadBlobLSBShort(image);
216 image->rows=ReadBlobLSBShort(image);
217 flags=(MagickStatusType) ReadBlobByte(image);
cristyb0a657e2012-08-29 00:45:37 +0000218 image->alpha_trait=flags & 0x04 ? BlendPixelTrait : UndefinedPixelTrait;
cristy3ed852e2009-09-05 21:47:34 +0000219 number_planes=1UL*ReadBlobByte(image);
220 bits_per_pixel=1UL*ReadBlobByte(image);
221 number_colormaps=1UL*ReadBlobByte(image);
cristycaf07b02014-05-24 23:26:25 +0000222 map_length=(unsigned char) ReadBlobByte(image);
223 if (map_length >= 64)
224 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
cristyeaedf062010-05-29 22:36:02 +0000225 one=1;
cristycaf07b02014-05-24 23:26:25 +0000226 map_length=one << map_length;
cristy3ed852e2009-09-05 21:47:34 +0000227 if ((number_planes == 0) || (number_planes == 2) || (bits_per_pixel != 8) ||
228 (image->columns == 0))
229 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
230 if (flags & 0x02)
231 {
232 /*
233 No background color-- initialize to black.
234 */
cristybb503372010-05-27 20:51:26 +0000235 for (i=0; i < (ssize_t) number_planes; i++)
cristy3ed852e2009-09-05 21:47:34 +0000236 background_color[i]=0;
237 (void) ReadBlobByte(image);
238 }
239 else
240 {
241 /*
242 Initialize background color.
243 */
244 p=background_color;
cristybb503372010-05-27 20:51:26 +0000245 for (i=0; i < (ssize_t) number_planes; i++)
cristy3ed852e2009-09-05 21:47:34 +0000246 *p++=(unsigned char) ReadBlobByte(image);
247 }
248 if ((number_planes & 0x01) == 0)
249 (void) ReadBlobByte(image);
250 colormap=(unsigned char *) NULL;
251 if (number_colormaps != 0)
252 {
253 /*
254 Read image colormaps.
255 */
256 colormap=(unsigned char *) AcquireQuantumMemory(number_colormaps,
257 map_length*sizeof(*colormap));
258 if (colormap == (unsigned char *) NULL)
259 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
260 p=colormap;
cristybb503372010-05-27 20:51:26 +0000261 for (i=0; i < (ssize_t) number_colormaps; i++)
262 for (x=0; x < (ssize_t) map_length; x++)
cristy3ed852e2009-09-05 21:47:34 +0000263 *p++=(unsigned char) ScaleShortToQuantum(ReadBlobLSBShort(image));
264 }
265 if ((flags & 0x08) != 0)
266 {
267 char
268 *comment;
269
cristybb503372010-05-27 20:51:26 +0000270 size_t
cristy3ed852e2009-09-05 21:47:34 +0000271 length;
272
273 /*
274 Read image comment.
275 */
276 length=ReadBlobLSBShort(image);
277 if (length != 0)
278 {
279 comment=(char *) AcquireQuantumMemory(length,sizeof(*comment));
280 if (comment == (char *) NULL)
281 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
282 count=ReadBlob(image,length-1,(unsigned char *) comment);
283 comment[length-1]='\0';
cristyd15e6592011-10-15 00:13:06 +0000284 (void) SetImageProperty(image,"comment",comment,exception);
cristy3ed852e2009-09-05 21:47:34 +0000285 comment=DestroyString(comment);
286 if ((length & 0x01) == 0)
287 (void) ReadBlobByte(image);
288 }
289 }
290 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
291 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
292 break;
293 /*
294 Allocate RLE pixels.
295 */
cristy35553db2014-11-23 15:43:29 +0000296 if (image->alpha_trait == BlendPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +0000297 number_planes++;
298 number_pixels=(MagickSizeType) image->columns*image->rows;
299 if ((number_pixels*number_planes) != (size_t) (number_pixels*number_planes))
300 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristyb64823d2013-06-30 20:58:24 +0000301 pixel_info=AcquireVirtualMemory(image->columns,image->rows*number_planes*
302 sizeof(*pixels));
303 if (pixel_info == (MemoryInfo *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000304 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristyb64823d2013-06-30 20:58:24 +0000305 pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
cristy3ed852e2009-09-05 21:47:34 +0000306 if ((flags & 0x01) && !(flags & 0x02))
307 {
cristybb503372010-05-27 20:51:26 +0000308 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000309 j;
310
311 /*
312 Set background color.
313 */
cristyb64823d2013-06-30 20:58:24 +0000314 p=pixels;
cristybb503372010-05-27 20:51:26 +0000315 for (i=0; i < (ssize_t) number_pixels; i++)
cristy3ed852e2009-09-05 21:47:34 +0000316 {
cristy35553db2014-11-23 15:43:29 +0000317 if (image->alpha_trait != BlendPixelTrait)
cristybb503372010-05-27 20:51:26 +0000318 for (j=0; j < (ssize_t) number_planes; j++)
cristy3ed852e2009-09-05 21:47:34 +0000319 *p++=background_color[j];
320 else
321 {
cristybb503372010-05-27 20:51:26 +0000322 for (j=0; j < (ssize_t) (number_planes-1); j++)
cristy3ed852e2009-09-05 21:47:34 +0000323 *p++=background_color[j];
324 *p++=0; /* initialize matte channel */
325 }
326 }
327 }
328 /*
329 Read runlength-encoded image.
330 */
331 plane=0;
332 x=0;
333 y=0;
334 opcode=ReadBlobByte(image);
335 do
336 {
337 switch (opcode & 0x3f)
338 {
339 case SkipLinesOp:
340 {
341 operand=ReadBlobByte(image);
342 if (opcode & 0x40)
343 operand=(int) ReadBlobLSBShort(image);
344 x=0;
345 y+=operand;
346 break;
347 }
348 case SetColorOp:
349 {
350 operand=ReadBlobByte(image);
351 plane=(unsigned char) operand;
352 if (plane == 255)
353 plane=(unsigned char) (number_planes-1);
354 x=0;
355 break;
356 }
357 case SkipPixelsOp:
358 {
359 operand=ReadBlobByte(image);
360 if (opcode & 0x40)
361 operand=(int) ReadBlobLSBShort(image);
362 x+=operand;
363 break;
364 }
365 case ByteDataOp:
366 {
367 operand=ReadBlobByte(image);
368 if (opcode & 0x40)
369 operand=(int) ReadBlobLSBShort(image);
cristyb64823d2013-06-30 20:58:24 +0000370 p=pixels+((image->rows-y-1)*image->columns*number_planes)+
cristy3ed852e2009-09-05 21:47:34 +0000371 x*number_planes+plane;
372 operand++;
cristybb503372010-05-27 20:51:26 +0000373 for (i=0; i < (ssize_t) operand; i++)
cristy3ed852e2009-09-05 21:47:34 +0000374 {
375 pixel=(unsigned char) ReadBlobByte(image);
cristyc6da28e2011-04-28 01:41:35 +0000376 if ((y < (ssize_t) image->rows) &&
377 ((x+i) < (ssize_t) image->columns))
cristy3ed852e2009-09-05 21:47:34 +0000378 *p=pixel;
379 p+=number_planes;
380 }
381 if (operand & 0x01)
382 (void) ReadBlobByte(image);
383 x+=operand;
384 break;
385 }
386 case RunDataOp:
387 {
388 operand=ReadBlobByte(image);
389 if (opcode & 0x40)
390 operand=(int) ReadBlobLSBShort(image);
391 pixel=(unsigned char) ReadBlobByte(image);
392 (void) ReadBlobByte(image);
393 operand++;
cristyb64823d2013-06-30 20:58:24 +0000394 p=pixels+((image->rows-y-1)*image->columns*number_planes)+
cristy3ed852e2009-09-05 21:47:34 +0000395 x*number_planes+plane;
cristybb503372010-05-27 20:51:26 +0000396 for (i=0; i < (ssize_t) operand; i++)
cristy3ed852e2009-09-05 21:47:34 +0000397 {
cristyc6da28e2011-04-28 01:41:35 +0000398 if ((y < (ssize_t) image->rows) &&
399 ((x+i) < (ssize_t) image->columns))
cristy3ed852e2009-09-05 21:47:34 +0000400 *p=pixel;
401 p+=number_planes;
402 }
403 x+=operand;
404 break;
405 }
406 default:
407 break;
408 }
409 opcode=ReadBlobByte(image);
410 } while (((opcode & 0x3f) != EOFOp) && (opcode != EOF));
411 if (number_colormaps != 0)
412 {
413 MagickStatusType
414 mask;
415
416 /*
417 Apply colormap affineation to image.
418 */
419 mask=(MagickStatusType) (map_length-1);
cristyb64823d2013-06-30 20:58:24 +0000420 p=pixels;
cristy3ed852e2009-09-05 21:47:34 +0000421 if (number_colormaps == 1)
cristybb503372010-05-27 20:51:26 +0000422 for (i=0; i < (ssize_t) number_pixels; i++)
cristy3ed852e2009-09-05 21:47:34 +0000423 {
424 *p=colormap[*p & mask];
425 p++;
426 }
427 else
428 if ((number_planes >= 3) && (number_colormaps >= 3))
cristybb503372010-05-27 20:51:26 +0000429 for (i=0; i < (ssize_t) number_pixels; i++)
430 for (x=0; x < (ssize_t) number_planes; x++)
cristy3ed852e2009-09-05 21:47:34 +0000431 {
432 *p=colormap[x*map_length+(*p & mask)];
433 p++;
434 }
435 }
436 /*
437 Initialize image structure.
438 */
439 if (number_planes >= 3)
440 {
441 /*
442 Convert raster image to DirectClass pixel packets.
443 */
cristyb64823d2013-06-30 20:58:24 +0000444 p=pixels;
cristybb503372010-05-27 20:51:26 +0000445 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000446 {
447 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000448 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000449 break;
cristybb503372010-05-27 20:51:26 +0000450 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000451 {
cristy4c08aed2011-07-01 19:47:50 +0000452 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
453 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
454 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
cristy35553db2014-11-23 15:43:29 +0000455 if (image->alpha_trait == BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +0000456 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
cristyed231572011-07-14 02:18:59 +0000457 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000458 }
459 if (SyncAuthenticPixels(image,exception) == MagickFalse)
460 break;
461 if (image->previous == (Image *) NULL)
462 {
cristycee97112010-05-28 00:44:52 +0000463 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
464 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000465 if (status == MagickFalse)
466 break;
467 }
468 }
469 }
470 else
471 {
472 /*
473 Create colormap.
474 */
475 if (number_colormaps == 0)
476 map_length=256;
cristy018f07f2011-09-04 21:15:19 +0000477 if (AcquireImageColormap(image,map_length,exception) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000478 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
479 p=colormap;
480 if (number_colormaps == 1)
cristybb503372010-05-27 20:51:26 +0000481 for (i=0; i < (ssize_t) image->colors; i++)
cristy3ed852e2009-09-05 21:47:34 +0000482 {
483 /*
484 Pseudocolor.
485 */
486 image->colormap[i].red=ScaleCharToQuantum((unsigned char) i);
487 image->colormap[i].green=ScaleCharToQuantum((unsigned char) i);
488 image->colormap[i].blue=ScaleCharToQuantum((unsigned char) i);
489 }
490 else
491 if (number_colormaps > 1)
cristybb503372010-05-27 20:51:26 +0000492 for (i=0; i < (ssize_t) image->colors; i++)
cristy3ed852e2009-09-05 21:47:34 +0000493 {
494 image->colormap[i].red=ScaleCharToQuantum(*p);
495 image->colormap[i].green=ScaleCharToQuantum(*(p+map_length));
496 image->colormap[i].blue=ScaleCharToQuantum(*(p+map_length*2));
497 p++;
498 }
cristyb64823d2013-06-30 20:58:24 +0000499 p=pixels;
cristy35553db2014-11-23 15:43:29 +0000500 if (image->alpha_trait != BlendPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +0000501 {
502 /*
503 Convert raster image to PseudoClass pixel packets.
504 */
cristybb503372010-05-27 20:51:26 +0000505 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000506 {
507 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000508 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000509 break;
cristybb503372010-05-27 20:51:26 +0000510 for (x=0; x < (ssize_t) image->columns; x++)
cristy4c08aed2011-07-01 19:47:50 +0000511 {
512 SetPixelIndex(image,*p++,q);
cristyed231572011-07-14 02:18:59 +0000513 q+=GetPixelChannels(image);
cristy4c08aed2011-07-01 19:47:50 +0000514 }
cristy3ed852e2009-09-05 21:47:34 +0000515 if (SyncAuthenticPixels(image,exception) == MagickFalse)
516 break;
517 if (image->previous == (Image *) NULL)
518 {
cristyc6da28e2011-04-28 01:41:35 +0000519 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
520 y,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000521 if (status == MagickFalse)
522 break;
523 }
524 }
cristyea1a8aa2011-10-20 13:24:06 +0000525 (void) SyncImage(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000526 }
527 else
528 {
529 /*
530 Image has a matte channel-- promote to DirectClass.
531 */
cristybb503372010-05-27 20:51:26 +0000532 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000533 {
534 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000535 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000536 break;
cristybb503372010-05-27 20:51:26 +0000537 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000538 {
cristy4c08aed2011-07-01 19:47:50 +0000539 SetPixelRed(image,image->colormap[*p++].red,q);
540 SetPixelGreen(image,image->colormap[*p++].green,q);
541 SetPixelBlue(image,image->colormap[*p++].blue,q);
542 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
cristyed231572011-07-14 02:18:59 +0000543 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000544 }
545 if (SyncAuthenticPixels(image,exception) == MagickFalse)
546 break;
547 if (image->previous == (Image *) NULL)
548 {
cristyc6da28e2011-04-28 01:41:35 +0000549 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
550 y,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000551 if (status == MagickFalse)
552 break;
553 }
554 }
cristy101ab702011-10-13 13:06:32 +0000555 image->colormap=(PixelInfo *) RelinquishMagickMemory(
cristy3da0b402011-05-29 21:13:36 +0000556 image->colormap);
cristy3ed852e2009-09-05 21:47:34 +0000557 image->storage_class=DirectClass;
558 image->colors=0;
559 }
560 }
561 if (number_colormaps != 0)
562 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
cristyb64823d2013-06-30 20:58:24 +0000563 pixel_info=RelinquishVirtualMemory(pixel_info);
cristy3ed852e2009-09-05 21:47:34 +0000564 if (EOFBlob(image) != MagickFalse)
565 {
566 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
567 image->filename);
568 break;
569 }
570 /*
571 Proceed to next image.
572 */
573 if (image_info->number_scenes != 0)
574 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
575 break;
576 (void) ReadBlobByte(image);
577 count=ReadBlob(image,2,(unsigned char *) magick);
578 if ((count != 0) && (memcmp(magick,"\122\314",2) == 0))
579 {
580 /*
581 Allocate next image structure.
582 */
cristy9950d572011-10-01 18:22:35 +0000583 AcquireNextImage(image_info,image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000584 if (GetNextImageInList(image) == (Image *) NULL)
585 {
586 image=DestroyImageList(image);
587 return((Image *) NULL);
588 }
589 image=SyncNextImageInList(image);
590 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
591 GetBlobSize(image));
592 if (status == MagickFalse)
593 break;
594 }
595 } while ((count != 0) && (memcmp(magick,"\122\314",2) == 0));
596 (void) CloseBlob(image);
597 return(GetFirstImageInList(image));
598}
599
600/*
601%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602% %
603% %
604% %
605% R e g i s t e r R L E I m a g e %
606% %
607% %
608% %
609%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610%
611% RegisterRLEImage() adds attributes for the RLE image format to
612% the list of supported formats. The attributes include the image format
613% tag, a method to read and/or write the format, whether the format
614% supports the saving of more than one frame to the same file or blob,
615% whether the format supports native in-memory I/O, and a brief
616% description of the format.
617%
618% The format of the RegisterRLEImage method is:
619%
cristybb503372010-05-27 20:51:26 +0000620% size_t RegisterRLEImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000621%
622*/
cristybb503372010-05-27 20:51:26 +0000623ModuleExport size_t RegisterRLEImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000624{
625 MagickInfo
626 *entry;
627
628 entry=SetMagickInfo("RLE");
629 entry->decoder=(DecodeImageHandler *) ReadRLEImage;
630 entry->magick=(IsImageFormatHandler *) IsRLE;
631 entry->adjoin=MagickFalse;
632 entry->description=ConstantString("Utah Run length encoded image");
633 entry->module=ConstantString("RLE");
634 (void) RegisterMagickInfo(entry);
635 return(MagickImageCoderSignature);
636}
637
638/*
639%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640% %
641% %
642% %
643% U n r e g i s t e r R L E I m a g e %
644% %
645% %
646% %
647%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648%
649% UnregisterRLEImage() removes format registrations made by the
650% RLE module from the list of supported formats.
651%
652% The format of the UnregisterRLEImage method is:
653%
654% UnregisterRLEImage(void)
655%
656*/
657ModuleExport void UnregisterRLEImage(void)
658{
659 (void) UnregisterMagickInfo("RLE");
660}