1 /*
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 %
16 % Cristy %
17 % July 1992 %
18 % %
19 % %
20 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
21 % 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 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/colormap.h"
47 #include "MagickCore/colormap-private.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/pixel.h"
59 #include "MagickCore/property.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/static.h"
62 #include "MagickCore/string_.h"
63 #include "MagickCore/module.h"
64
65 /*
66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67 % %
68 % %
69 % %
70 % I s R L E %
71 % %
72 % %
73 % %
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75 %
76 % IsRLE() returns MagickTrue if the image format type, identified by the
77 % magick string, is RLE.
78 %
79 % The format of the ReadRLEImage method is:
80 %
81 % MagickBooleanType IsRLE(const unsigned char *magick,const size_t length)
82 %
83 % A description of each parameter follows:
84 %
85 % o magick: compare image format pattern against these bytes.
86 %
87 % o length: Specifies the length of the magick string.
88 %
89 %
90 */
IsRLE(const unsigned char * magick,const size_t length)91 static MagickBooleanType IsRLE(const unsigned char *magick,const size_t length)
92 {
93 if (length < 2)
94 return(MagickFalse);
95 if (memcmp(magick,"\122\314",2) == 0)
96 return(MagickTrue);
97 return(MagickFalse);
98 }
99
100 /*
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 % %
103 % %
104 % %
105 % R e a d R L E I m a g e %
106 % %
107 % %
108 % %
109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110 %
111 % ReadRLEImage() reads a run-length encoded Utah Raster Toolkit
112 % image file and returns it. It allocates the memory necessary for the new
113 % Image structure and returns a pointer to the new image.
114 %
115 % The format of the ReadRLEImage method is:
116 %
117 % Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
118 %
119 % A description of each parameter follows:
120 %
121 % o image_info: the image info.
122 %
123 % o exception: return any errors or warnings in this structure.
124 %
125 %
126 */
ReadRLEImage(const ImageInfo * image_info,ExceptionInfo * exception)127 static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
128 {
129 #define SkipLinesOp 0x01
130 #define SetColorOp 0x02
131 #define SkipPixelsOp 0x03
132 #define ByteDataOp 0x05
133 #define RunDataOp 0x06
134 #define EOFOp 0x07
135
136 char
137 magick[12];
138
139 Image
140 *image;
141
142 int
143 opcode,
144 operand,
145 status;
146
147 MagickStatusType
148 flags;
149
150 MagickSizeType
151 number_pixels;
152
153 MemoryInfo
154 *pixel_info;
155
156 Quantum
157 index;
158
159 register ssize_t
160 x;
161
162 register Quantum
163 *q;
164
165 register ssize_t
166 i;
167
168 register unsigned char
169 *p;
170
171 size_t
172 bits_per_pixel,
173 map_length,
174 number_colormaps,
175 number_planes,
176 number_planes_filled,
177 one,
178 pixel_info_length;
179
180 ssize_t
181 count,
182 offset,
183 y;
184
185 unsigned char
186 background_color[256],
187 *colormap,
188 pixel,
189 plane,
190 *pixels;
191
192 /*
193 Open image file.
194 */
195 assert(image_info != (const ImageInfo *) NULL);
196 assert(image_info->signature == MagickCoreSignature);
197 if (image_info->debug != MagickFalse)
198 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
199 image_info->filename);
200 assert(exception != (ExceptionInfo *) NULL);
201 assert(exception->signature == MagickCoreSignature);
202 image=AcquireImage(image_info,exception);
203 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
204 if (status == MagickFalse)
205 return(DestroyImageList(image));
206 /*
207 Determine if this a RLE file.
208 */
209 count=ReadBlob(image,2,(unsigned char *) magick);
210 if ((count != 2) || (memcmp(magick,"\122\314",2) != 0))
211 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
212 do
213 {
214 /*
215 Read image header.
216 */
217 image->page.x=ReadBlobLSBShort(image);
218 image->page.y=ReadBlobLSBShort(image);
219 image->columns=ReadBlobLSBShort(image);
220 image->rows=ReadBlobLSBShort(image);
221 flags=(MagickStatusType) ReadBlobByte(image);
222 image->alpha_trait=flags & 0x04 ? BlendPixelTrait : UndefinedPixelTrait;
223 number_planes=(size_t) ReadBlobByte(image);
224 bits_per_pixel=(size_t) ReadBlobByte(image);
225 number_colormaps=(size_t) ReadBlobByte(image);
226 map_length=(unsigned char) ReadBlobByte(image);
227 if (map_length >= 64)
228 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
229 one=1;
230 map_length=one << map_length;
231 if ((number_planes == 0) || (number_planes == 2) ||
232 ((flags & 0x04) && (number_colormaps > 254)) || (bits_per_pixel != 8) ||
233 (image->columns == 0))
234 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
235 if (flags & 0x02)
236 {
237 /*
238 No background color-- initialize to black.
239 */
240 for (i=0; i < (ssize_t) number_planes; i++)
241 background_color[i]=0;
242 (void) ReadBlobByte(image);
243 }
244 else
245 {
246 /*
247 Initialize background color.
248 */
249 p=background_color;
250 for (i=0; i < (ssize_t) number_planes; i++)
251 *p++=(unsigned char) ReadBlobByte(image);
252 }
253 if ((number_planes & 0x01) == 0)
254 (void) ReadBlobByte(image);
255 if (EOFBlob(image) != MagickFalse)
256 {
257 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
258 image->filename);
259 break;
260 }
261 colormap=(unsigned char *) NULL;
262 if (number_colormaps != 0)
263 {
264 /*
265 Read image colormaps.
266 */
267 colormap=(unsigned char *) AcquireQuantumMemory(number_colormaps,
268 3*map_length*sizeof(*colormap));
269 if (colormap == (unsigned char *) NULL)
270 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
271 p=colormap;
272 for (i=0; i < (ssize_t) number_colormaps; i++)
273 for (x=0; x < (ssize_t) map_length; x++)
274 *p++=(unsigned char) ScaleShortToQuantum(ReadBlobLSBShort(image));
275 }
276 if ((flags & 0x08) != 0)
277 {
278 char
279 *comment;
280
281 size_t
282 length;
283
284 /*
285 Read image comment.
286 */
287 length=ReadBlobLSBShort(image);
288 if (length != 0)
289 {
290 comment=(char *) AcquireQuantumMemory(length,sizeof(*comment));
291 if (comment == (char *) NULL)
292 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
293 count=ReadBlob(image,length-1,(unsigned char *) comment);
294 comment[length-1]='\0';
295 (void) SetImageProperty(image,"comment",comment,exception);
296 comment=DestroyString(comment);
297 if ((length & 0x01) == 0)
298 (void) ReadBlobByte(image);
299 }
300 }
301 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
302 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
303 break;
304 status=SetImageExtent(image,image->columns,image->rows,exception);
305 if (status == MagickFalse)
306 return(DestroyImageList(image));
307 /*
308 Allocate RLE pixels.
309 */
310 if (image->alpha_trait != UndefinedPixelTrait)
311 number_planes++;
312 number_pixels=(MagickSizeType) image->columns*image->rows;
313 number_planes_filled=(number_planes % 2 == 0) ? number_planes :
314 number_planes+1;
315 if ((number_pixels*number_planes_filled) != (size_t) (number_pixels*
316 number_planes_filled))
317 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
318 pixel_info=AcquireVirtualMemory(image->columns,image->rows*
319 MagickMax(number_planes_filled,4)*sizeof(*pixels));
320 if (pixel_info == (MemoryInfo *) NULL)
321 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
322 pixel_info_length=image->columns*image->rows*
323 MagickMax(number_planes_filled,4);
324 pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
325 if ((flags & 0x01) && !(flags & 0x02))
326 {
327 ssize_t
328 j;
329
330 /*
331 Set background color.
332 */
333 p=pixels;
334 for (i=0; i < (ssize_t) number_pixels; i++)
335 {
336 if (image->alpha_trait == UndefinedPixelTrait)
337 for (j=0; j < (ssize_t) number_planes; j++)
338 *p++=background_color[j];
339 else
340 {
341 for (j=0; j < (ssize_t) (number_planes-1); j++)
342 *p++=background_color[j];
343 *p++=0; /* initialize matte channel */
344 }
345 }
346 }
347 /*
348 Read runlength-encoded image.
349 */
350 plane=0;
351 x=0;
352 y=0;
353 opcode=ReadBlobByte(image);
354 do
355 {
356 switch (opcode & 0x3f)
357 {
358 case SkipLinesOp:
359 {
360 operand=ReadBlobByte(image);
361 if (opcode & 0x40)
362 operand=ReadBlobLSBSignedShort(image);
363 x=0;
364 y+=operand;
365 break;
366 }
367 case SetColorOp:
368 {
369 operand=ReadBlobByte(image);
370 plane=(unsigned char) operand;
371 if (plane == 255)
372 plane=(unsigned char) (number_planes-1);
373 x=0;
374 break;
375 }
376 case SkipPixelsOp:
377 {
378 operand=ReadBlobByte(image);
379 if (opcode & 0x40)
380 operand=ReadBlobLSBSignedShort(image);
381 x+=operand;
382 break;
383 }
384 case ByteDataOp:
385 {
386 operand=ReadBlobByte(image);
387 if (opcode & 0x40)
388 operand=ReadBlobLSBSignedShort(image);
389 offset=((image->rows-y-1)*image->columns*number_planes)+x*
390 number_planes+plane;
391 operand++;
392 if ((offset < 0) ||
393 (offset+((size_t) operand*number_planes) > pixel_info_length))
394 {
395 if (number_colormaps != 0)
396 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
397 pixel_info=RelinquishVirtualMemory(pixel_info);
398 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
399 }
400 p=pixels+offset;
401 for (i=0; i < (ssize_t) operand; i++)
402 {
403 pixel=(unsigned char) ReadBlobByte(image);
404 if ((y < (ssize_t) image->rows) &&
405 ((x+i) < (ssize_t) image->columns))
406 *p=pixel;
407 p+=number_planes;
408 }
409 if (operand & 0x01)
410 (void) ReadBlobByte(image);
411 x+=operand;
412 break;
413 }
414 case RunDataOp:
415 {
416 operand=ReadBlobByte(image);
417 if (opcode & 0x40)
418 operand=ReadBlobLSBSignedShort(image);
419 pixel=(unsigned char) ReadBlobByte(image);
420 (void) ReadBlobByte(image);
421 offset=((image->rows-y-1)*image->columns*number_planes)+x*
422 number_planes+plane;
423 operand++;
424 if ((offset < 0) ||
425 (offset+((size_t) operand*number_planes) > pixel_info_length))
426 {
427 if (number_colormaps != 0)
428 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
429 pixel_info=RelinquishVirtualMemory(pixel_info);
430 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
431 }
432 p=pixels+offset;
433 for (i=0; i < (ssize_t) operand; i++)
434 {
435 if ((y < (ssize_t) image->rows) &&
436 ((x+i) < (ssize_t) image->columns))
437 *p=pixel;
438 p+=number_planes;
439 }
440 x+=operand;
441 break;
442 }
443 default:
444 break;
445 }
446 opcode=ReadBlobByte(image);
447 } while (((opcode & 0x3f) != EOFOp) && (opcode != EOF));
448 if (number_colormaps != 0)
449 {
450 MagickStatusType
451 mask;
452
453 /*
454 Apply colormap affineation to image.
455 */
456 mask=(MagickStatusType) (map_length-1);
457 p=pixels;
458 x=(ssize_t) number_planes;
459 if (number_colormaps == 1)
460 for (i=0; i < (ssize_t) number_pixels; i++)
461 {
462 ValidateColormapValue(image,*p & mask,&index,exception);
463 *p=colormap[(ssize_t) index];
464 p++;
465 }
466 else
467 if ((number_planes >= 3) && (number_colormaps >= 3))
468 for (i=0; i < (ssize_t) number_pixels; i++)
469 for (x=0; x < (ssize_t) number_planes; x++)
470 {
471 ValidateColormapValue(image,(size_t) (x*map_length+
472 (*p & mask)),&index,exception);
473 *p=colormap[(ssize_t) index];
474 p++;
475 }
476 if ((i < (ssize_t) number_pixels) || (x < (ssize_t) number_planes))
477 {
478 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
479 pixel_info=RelinquishVirtualMemory(pixel_info);
480 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
481 }
482 }
483 /*
484 Initialize image structure.
485 */
486 if (number_planes >= 3)
487 {
488 /*
489 Convert raster image to DirectClass pixel packets.
490 */
491 p=pixels;
492 for (y=0; y < (ssize_t) image->rows; y++)
493 {
494 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
495 if (q == (Quantum *) NULL)
496 break;
497 for (x=0; x < (ssize_t) image->columns; x++)
498 {
499 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
500 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
501 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
502 if (image->alpha_trait != UndefinedPixelTrait)
503 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
504 q+=GetPixelChannels(image);
505 }
506 if (SyncAuthenticPixels(image,exception) == MagickFalse)
507 break;
508 if (image->previous == (Image *) NULL)
509 {
510 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
511 image->rows);
512 if (status == MagickFalse)
513 break;
514 }
515 }
516 }
517 else
518 {
519 /*
520 Create colormap.
521 */
522 if (number_colormaps == 0)
523 map_length=256;
524 if (AcquireImageColormap(image,map_length,exception) == MagickFalse)
525 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
526 p=colormap;
527 if (number_colormaps == 1)
528 for (i=0; i < (ssize_t) image->colors; i++)
529 {
530 /*
531 Pseudocolor.
532 */
533 image->colormap[i].red=(MagickRealType)
534 ScaleCharToQuantum((unsigned char) i);
535 image->colormap[i].green=(MagickRealType)
536 ScaleCharToQuantum((unsigned char) i);
537 image->colormap[i].blue=(MagickRealType)
538 ScaleCharToQuantum((unsigned char) i);
539 }
540 else
541 if (number_colormaps > 1)
542 for (i=0; i < (ssize_t) image->colors; i++)
543 {
544 image->colormap[i].red=(MagickRealType)
545 ScaleCharToQuantum(*p);
546 image->colormap[i].green=(MagickRealType)
547 ScaleCharToQuantum(*(p+map_length));
548 image->colormap[i].blue=(MagickRealType)
549 ScaleCharToQuantum(*(p+map_length*2));
550 p++;
551 }
552 p=pixels;
553 if (image->alpha_trait == UndefinedPixelTrait)
554 {
555 /*
556 Convert raster image to PseudoClass pixel packets.
557 */
558 for (y=0; y < (ssize_t) image->rows; y++)
559 {
560 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
561 if (q == (Quantum *) NULL)
562 break;
563 for (x=0; x < (ssize_t) image->columns; x++)
564 {
565 SetPixelIndex(image,*p++,q);
566 q+=GetPixelChannels(image);
567 }
568 if (SyncAuthenticPixels(image,exception) == MagickFalse)
569 break;
570 if (image->previous == (Image *) NULL)
571 {
572 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
573 y,image->rows);
574 if (status == MagickFalse)
575 break;
576 }
577 }
578 (void) SyncImage(image,exception);
579 }
580 else
581 {
582 /*
583 Image has a matte channel-- promote to DirectClass.
584 */
585 for (y=0; y < (ssize_t) image->rows; y++)
586 {
587 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
588 if (q == (Quantum *) NULL)
589 break;
590 for (x=0; x < (ssize_t) image->columns; x++)
591 {
592 ValidateColormapValue(image,(ssize_t) *p++,&index,exception);
593 SetPixelRed(image,ClampToQuantum(image->colormap[(ssize_t)
594 index].red),q);
595 ValidateColormapValue(image,(ssize_t) *p++,&index,exception);
596 SetPixelGreen(image,ClampToQuantum(image->colormap[(ssize_t)
597 index].green),q);
598 ValidateColormapValue(image,(ssize_t) *p++,&index,exception);
599 SetPixelBlue(image,ClampToQuantum(image->colormap[(ssize_t)
600 index].blue),q);
601 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
602 q+=GetPixelChannels(image);
603 }
604 if (x < (ssize_t) image->columns)
605 break;
606 if (SyncAuthenticPixels(image,exception) == MagickFalse)
607 break;
608 if (image->previous == (Image *) NULL)
609 {
610 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
611 y,image->rows);
612 if (status == MagickFalse)
613 break;
614 }
615 }
616 image->colormap=(PixelInfo *) RelinquishMagickMemory(
617 image->colormap);
618 image->storage_class=DirectClass;
619 image->colors=0;
620 }
621 }
622 if (number_colormaps != 0)
623 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
624 pixel_info=RelinquishVirtualMemory(pixel_info);
625 if (EOFBlob(image) != MagickFalse)
626 {
627 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
628 image->filename);
629 break;
630 }
631 /*
632 Proceed to next image.
633 */
634 if (image_info->number_scenes != 0)
635 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
636 break;
637 (void) ReadBlobByte(image);
638 count=ReadBlob(image,2,(unsigned char *) magick);
639 if ((count != 0) && (memcmp(magick,"\122\314",2) == 0))
640 {
641 /*
642 Allocate next image structure.
643 */
644 AcquireNextImage(image_info,image,exception);
645 if (GetNextImageInList(image) == (Image *) NULL)
646 {
647 image=DestroyImageList(image);
648 return((Image *) NULL);
649 }
650 image=SyncNextImageInList(image);
651 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
652 GetBlobSize(image));
653 if (status == MagickFalse)
654 break;
655 }
656 } while ((count != 0) && (memcmp(magick,"\122\314",2) == 0));
657 (void) CloseBlob(image);
658 return(GetFirstImageInList(image));
659 }
660
661 /*
662 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
663 % %
664 % %
665 % %
666 % R e g i s t e r R L E I m a g e %
667 % %
668 % %
669 % %
670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 %
672 % RegisterRLEImage() adds attributes for the RLE image format to
673 % the list of supported formats. The attributes include the image format
674 % tag, a method to read and/or write the format, whether the format
675 % supports the saving of more than one frame to the same file or blob,
676 % whether the format supports native in-memory I/O, and a brief
677 % description of the format.
678 %
679 % The format of the RegisterRLEImage method is:
680 %
681 % size_t RegisterRLEImage(void)
682 %
683 */
RegisterRLEImage(void)684 ModuleExport size_t RegisterRLEImage(void)
685 {
686 MagickInfo
687 *entry;
688
689 entry=AcquireMagickInfo("RLE","RLE","Utah Run length encoded image");
690 entry->decoder=(DecodeImageHandler *) ReadRLEImage;
691 entry->magick=(IsImageFormatHandler *) IsRLE;
692 entry->flags^=CoderAdjoinFlag;
693 (void) RegisterMagickInfo(entry);
694 return(MagickImageCoderSignature);
695 }
696
697 /*
698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
699 % %
700 % %
701 % %
702 % U n r e g i s t e r R L E I m a g e %
703 % %
704 % %
705 % %
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 %
708 % UnregisterRLEImage() removes format registrations made by the
709 % RLE module from the list of supported formats.
710 %
711 % The format of the UnregisterRLEImage method is:
712 %
713 % UnregisterRLEImage(void)
714 %
715 */
UnregisterRLEImage(void)716 ModuleExport void UnregisterRLEImage(void)
717 {
718 (void) UnregisterMagickInfo("RLE");
719 }
720