]> granicus.if.org Git - imagemagick/blob - coders/rle.c
https://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=31265
[imagemagick] / coders / rle.c
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-2017 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 \f
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 \f
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 */
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 \f
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 */
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 >= 22)
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 (EOFBlob(image) != MagickFalse)
302       {
303         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
304           image->filename);
305         break;
306       }
307     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
308       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
309         break;
310     status=SetImageExtent(image,image->columns,image->rows,exception);
311     if (status == MagickFalse)
312       return(DestroyImageList(image));
313     /*
314       Allocate RLE pixels.
315     */
316     if (image->alpha_trait != UndefinedPixelTrait)
317       number_planes++;
318     number_pixels=(MagickSizeType) image->columns*image->rows;
319     number_planes_filled=(number_planes % 2 == 0) ? number_planes :
320       number_planes+1;
321     if ((number_pixels*number_planes_filled) != (size_t) (number_pixels*
322          number_planes_filled))
323       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
324     pixel_info=AcquireVirtualMemory(image->columns,image->rows*
325       MagickMax(number_planes_filled,4)*sizeof(*pixels));
326     if (pixel_info == (MemoryInfo *) NULL)
327       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
328     pixel_info_length=image->columns*image->rows*
329       MagickMax(number_planes_filled,4);
330     pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
331     if ((flags & 0x01) && !(flags & 0x02))
332       {
333         ssize_t
334           j;
335
336         /*
337           Set background color.
338         */
339         p=pixels;
340         for (i=0; i < (ssize_t) number_pixels; i++)
341         {
342           if (image->alpha_trait == UndefinedPixelTrait)
343             for (j=0; j < (ssize_t) number_planes; j++)
344               *p++=background_color[j];
345           else
346             {
347               for (j=0; j < (ssize_t) (number_planes-1); j++)
348                 *p++=background_color[j];
349               *p++=0;  /* initialize matte channel */
350             }
351         }
352       }
353     /*
354       Read runlength-encoded image.
355     */
356     plane=0;
357     x=0;
358     y=0;
359     opcode=ReadBlobByte(image);
360     do
361     {
362       switch (opcode & 0x3f)
363       {
364         case SkipLinesOp:
365         {
366           operand=ReadBlobByte(image);
367           if (opcode & 0x40)
368             operand=ReadBlobLSBSignedShort(image);
369           x=0;
370           y+=operand;
371           break;
372         }
373         case SetColorOp:
374         {
375           operand=ReadBlobByte(image);
376           plane=(unsigned char) operand;
377           if (plane == 255)
378             plane=(unsigned char) (number_planes-1);
379           x=0;
380           break;
381         }
382         case SkipPixelsOp:
383         {
384           operand=ReadBlobByte(image);
385           if (opcode & 0x40)
386             operand=ReadBlobLSBSignedShort(image);
387           x+=operand;
388           break;
389         }
390         case ByteDataOp:
391         {
392           operand=ReadBlobByte(image);
393           if (opcode & 0x40)
394             operand=ReadBlobLSBSignedShort(image);
395           offset=((image->rows-y-1)*image->columns*number_planes)+x*
396             number_planes+plane;
397           operand++;
398           if ((offset < 0) ||
399               (offset+((size_t) operand*number_planes) > pixel_info_length))
400             {
401               if (number_colormaps != 0)
402                 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
403               pixel_info=RelinquishVirtualMemory(pixel_info);
404               ThrowReaderException(CorruptImageError,"UnableToReadImageData");
405             }
406           p=pixels+offset;
407           for (i=0; i < (ssize_t) operand; i++)
408           {
409             pixel=(unsigned char) ReadBlobByte(image);
410             if ((y < (ssize_t) image->rows) &&
411                 ((x+i) < (ssize_t) image->columns))
412               *p=pixel;
413             p+=number_planes;
414           }
415           if (operand & 0x01)
416             (void) ReadBlobByte(image);
417           x+=operand;
418           break;
419         }
420         case RunDataOp:
421         {
422           operand=ReadBlobByte(image);
423           if (opcode & 0x40)
424             operand=ReadBlobLSBSignedShort(image);
425           pixel=(unsigned char) ReadBlobByte(image);
426           (void) ReadBlobByte(image);
427           offset=((image->rows-y-1)*image->columns*number_planes)+x*
428             number_planes+plane;
429           operand++;
430           if ((offset < 0) ||
431               (offset+((size_t) operand*number_planes) > pixel_info_length))
432             {
433               if (number_colormaps != 0)
434                 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
435               pixel_info=RelinquishVirtualMemory(pixel_info);
436               ThrowReaderException(CorruptImageError,"UnableToReadImageData");
437             }
438           p=pixels+offset;
439           for (i=0; i < (ssize_t) operand; i++)
440           {
441             if ((y < (ssize_t) image->rows) &&
442                 ((x+i) < (ssize_t) image->columns))
443               *p=pixel;
444             p+=number_planes;
445           }
446           x+=operand;
447           break;
448         }
449         default:
450           break;
451       }
452       opcode=ReadBlobByte(image);
453     } while (((opcode & 0x3f) != EOFOp) && (opcode != EOF));
454     if (number_colormaps != 0)
455       {
456         MagickStatusType
457           mask;
458
459         /*
460           Apply colormap affineation to image.
461         */
462         mask=(MagickStatusType) (map_length-1);
463         p=pixels;
464         x=(ssize_t) number_planes;
465         if (number_colormaps == 1)
466           for (i=0; i < (ssize_t) number_pixels; i++)
467           {
468             ValidateColormapValue(image,*p & mask,&index,exception);
469             *p=colormap[(ssize_t) index];
470             p++;
471           }
472         else
473           if ((number_planes >= 3) && (number_colormaps >= 3))
474             for (i=0; i < (ssize_t) number_pixels; i++)
475               for (x=0; x < (ssize_t) number_planes; x++)
476               {
477                 ValidateColormapValue(image,(size_t) (x*map_length+
478                     (*p & mask)),&index,exception);
479                 *p=colormap[(ssize_t) index];
480                 p++;
481               }
482         if ((i < (ssize_t) number_pixels) || (x < (ssize_t) number_planes))
483           {
484             colormap=(unsigned char *) RelinquishMagickMemory(colormap);
485             pixel_info=RelinquishVirtualMemory(pixel_info);
486             ThrowReaderException(CorruptImageError,"UnableToReadImageData");
487           }
488       }
489     /*
490       Initialize image structure.
491     */
492     if (number_planes >= 3)
493       {
494         /*
495           Convert raster image to DirectClass pixel packets.
496         */
497         p=pixels;
498         for (y=0; y < (ssize_t) image->rows; y++)
499         {
500           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
501           if (q == (Quantum *) NULL)
502             break;
503           for (x=0; x < (ssize_t) image->columns; x++)
504           {
505             SetPixelRed(image,ScaleCharToQuantum(*p++),q);
506             SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
507             SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
508             if (image->alpha_trait != UndefinedPixelTrait)
509               SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
510             q+=GetPixelChannels(image);
511           }
512           if (SyncAuthenticPixels(image,exception) == MagickFalse)
513             break;
514           if (image->previous == (Image *) NULL)
515             {
516               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
517                 image->rows);
518               if (status == MagickFalse)
519                 break;
520             }
521         }
522       }
523     else
524       {
525         /*
526           Create colormap.
527         */
528         if (number_colormaps == 0)
529           map_length=256;
530         if (AcquireImageColormap(image,map_length,exception) == MagickFalse)
531           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
532         p=colormap;
533         if (number_colormaps == 1)
534           for (i=0; i < (ssize_t) image->colors; i++)
535           {
536             /*
537               Pseudocolor.
538             */
539             image->colormap[i].red=(MagickRealType)
540               ScaleCharToQuantum((unsigned char) i);
541             image->colormap[i].green=(MagickRealType)
542               ScaleCharToQuantum((unsigned char) i);
543             image->colormap[i].blue=(MagickRealType)
544               ScaleCharToQuantum((unsigned char) i);
545           }
546         else
547           if (number_colormaps > 1)
548             for (i=0; i < (ssize_t) image->colors; i++)
549             {
550               image->colormap[i].red=(MagickRealType)
551                 ScaleCharToQuantum(*p);
552               image->colormap[i].green=(MagickRealType)
553                 ScaleCharToQuantum(*(p+map_length));
554               image->colormap[i].blue=(MagickRealType)
555                 ScaleCharToQuantum(*(p+map_length*2));
556               p++;
557             }
558         p=pixels;
559         if (image->alpha_trait == UndefinedPixelTrait)
560           {
561             /*
562               Convert raster image to PseudoClass pixel packets.
563             */
564             for (y=0; y < (ssize_t) image->rows; y++)
565             {
566               q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
567               if (q == (Quantum *) NULL)
568                 break;
569               for (x=0; x < (ssize_t) image->columns; x++)
570               {
571                 SetPixelIndex(image,*p++,q);
572                 q+=GetPixelChannels(image);
573               }
574               if (SyncAuthenticPixels(image,exception) == MagickFalse)
575                 break;
576               if (image->previous == (Image *) NULL)
577                 {
578                   status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
579                     y,image->rows);
580                   if (status == MagickFalse)
581                     break;
582                 }
583             }
584             (void) SyncImage(image,exception);
585           }
586         else
587           {
588             /*
589               Image has a matte channel-- promote to DirectClass.
590             */
591             for (y=0; y < (ssize_t) image->rows; y++)
592             {
593               q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
594               if (q == (Quantum *) NULL)
595                 break;
596               for (x=0; x < (ssize_t) image->columns; x++)
597               {
598                 ValidateColormapValue(image,(ssize_t) *p++,&index,exception);
599                 SetPixelRed(image,ClampToQuantum(image->colormap[(ssize_t)
600                   index].red),q);
601                 ValidateColormapValue(image,(ssize_t) *p++,&index,exception);
602                 SetPixelGreen(image,ClampToQuantum(image->colormap[(ssize_t)
603                   index].green),q);
604                 ValidateColormapValue(image,(ssize_t) *p++,&index,exception);
605                 SetPixelBlue(image,ClampToQuantum(image->colormap[(ssize_t)
606                   index].blue),q);
607                 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
608                 q+=GetPixelChannels(image);
609               }
610               if (x < (ssize_t) image->columns)
611                 break;
612               if (SyncAuthenticPixels(image,exception) == MagickFalse)
613                 break;
614               if (image->previous == (Image *) NULL)
615                 {
616                   status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
617                     y,image->rows);
618                   if (status == MagickFalse)
619                     break;
620                 }
621             }
622             image->colormap=(PixelInfo *) RelinquishMagickMemory(
623               image->colormap);
624             image->storage_class=DirectClass;
625             image->colors=0;
626           }
627       }
628     if (number_colormaps != 0)
629       colormap=(unsigned char *) RelinquishMagickMemory(colormap);
630     pixel_info=RelinquishVirtualMemory(pixel_info);
631     if (EOFBlob(image) != MagickFalse)
632       {
633         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
634           image->filename);
635         break;
636       }
637     /*
638       Proceed to next image.
639     */
640     if (image_info->number_scenes != 0)
641       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
642         break;
643     (void) ReadBlobByte(image);
644     count=ReadBlob(image,2,(unsigned char *) magick);
645     if ((count != 0) && (memcmp(magick,"\122\314",2) == 0))
646       {
647         /*
648           Allocate next image structure.
649         */
650         AcquireNextImage(image_info,image,exception);
651         if (GetNextImageInList(image) == (Image *) NULL)
652           {
653             image=DestroyImageList(image);
654             return((Image *) NULL);
655           }
656         image=SyncNextImageInList(image);
657         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
658           GetBlobSize(image));
659         if (status == MagickFalse)
660           break;
661       }
662   } while ((count != 0) && (memcmp(magick,"\122\314",2) == 0));
663   (void) CloseBlob(image);
664   return(GetFirstImageInList(image));
665 }
666 \f
667 /*
668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
669 %                                                                             %
670 %                                                                             %
671 %                                                                             %
672 %   R e g i s t e r R L E I m a g e                                           %
673 %                                                                             %
674 %                                                                             %
675 %                                                                             %
676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677 %
678 %  RegisterRLEImage() adds attributes for the RLE image format to
679 %  the list of supported formats.  The attributes include the image format
680 %  tag, a method to read and/or write the format, whether the format
681 %  supports the saving of more than one frame to the same file or blob,
682 %  whether the format supports native in-memory I/O, and a brief
683 %  description of the format.
684 %
685 %  The format of the RegisterRLEImage method is:
686 %
687 %      size_t RegisterRLEImage(void)
688 %
689 */
690 ModuleExport size_t RegisterRLEImage(void)
691 {
692   MagickInfo
693     *entry;
694
695   entry=AcquireMagickInfo("RLE","RLE","Utah Run length encoded image");
696   entry->decoder=(DecodeImageHandler *) ReadRLEImage;
697   entry->magick=(IsImageFormatHandler *) IsRLE;
698   entry->flags^=CoderAdjoinFlag;
699   (void) RegisterMagickInfo(entry);
700   return(MagickImageCoderSignature);
701 }
702 \f
703 /*
704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
705 %                                                                             %
706 %                                                                             %
707 %                                                                             %
708 %   U n r e g i s t e r R L E I m a g e                                       %
709 %                                                                             %
710 %                                                                             %
711 %                                                                             %
712 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713 %
714 %  UnregisterRLEImage() removes format registrations made by the
715 %  RLE module from the list of supported formats.
716 %
717 %  The format of the UnregisterRLEImage method is:
718 %
719 %      UnregisterRLEImage(void)
720 %
721 */
722 ModuleExport void UnregisterRLEImage(void)
723 {
724   (void) UnregisterMagickInfo("RLE");
725 }