Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                            PPPP   IIIII  X   X                              %
      7 %                            P   P    I     X X                               %
      8 %                            PPPP     I      X                                %
      9 %                            P        I     X X                               %
     10 %                            P      IIIII  X   X                              %
     11 %                                                                             %
     12 %                                                                             %
     13 %                    Read Alias/Wavefront 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 /*
     41   Include declarations.
     42 */
     43 #include "MagickCore/studio.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/static.h"
     60 #include "MagickCore/string_.h"
     61 #include "MagickCore/module.h"
     62 
     63 /*
     65 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     66 %                                                                             %
     67 %                                                                             %
     68 %                                                                             %
     69 %   R e a d P I X I m a g e                                                   %
     70 %                                                                             %
     71 %                                                                             %
     72 %                                                                             %
     73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     74 %
     75 %  ReadPIXImage() reads a Alias/Wavefront RLE image file and returns it.
     76 %  It allocates the memory necessary for the new Image structure and returns a
     77 %  pointer to the new image.
     78 %
     79 %  The format of the ReadPIXImage method is:
     80 %
     81 %      Image *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     82 %
     83 %  A description of each parameter follows:
     84 %
     85 %    o image_info: the image info.
     86 %
     87 %    o exception: return any errors or warnings in this structure.
     88 %
     89 %
     90 */
     91 static Image *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     92 {
     93   Image
     94     *image;
     95 
     96   MagickBooleanType
     97     status;
     98 
     99   Quantum
    100     blue,
    101     green,
    102     index,
    103     red;
    104 
    105   register ssize_t
    106     x;
    107 
    108   register Quantum
    109     *q;
    110 
    111   size_t
    112     bits_per_pixel,
    113     height,
    114     length,
    115     width;
    116 
    117   ssize_t
    118     y;
    119 
    120   /*
    121     Open image file.
    122   */
    123   assert(image_info != (const ImageInfo *) NULL);
    124   assert(image_info->signature == MagickCoreSignature);
    125   if (image_info->debug != MagickFalse)
    126     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    127       image_info->filename);
    128   assert(exception != (ExceptionInfo *) NULL);
    129   assert(exception->signature == MagickCoreSignature);
    130   image=AcquireImage(image_info,exception);
    131   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    132   if (status == MagickFalse)
    133     {
    134       image=DestroyImageList(image);
    135       return((Image *) NULL);
    136     }
    137   /*
    138     Read PIX image.
    139   */
    140   width=ReadBlobMSBShort(image);
    141   height=ReadBlobMSBShort(image);
    142   (void) ReadBlobMSBShort(image);  /* x-offset */
    143   (void) ReadBlobMSBShort(image);  /* y-offset */
    144   bits_per_pixel=ReadBlobMSBShort(image);
    145   if ((width == 0UL) || (height == 0UL) || ((bits_per_pixel != 8) &&
    146       (bits_per_pixel != 24)))
    147     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    148   do
    149   {
    150     /*
    151       Initialize image structure.
    152     */
    153     image->columns=width;
    154     image->rows=height;
    155     if (bits_per_pixel == 8)
    156       if (AcquireImageColormap(image,256,exception) == MagickFalse)
    157         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    158     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
    159       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
    160         break;
    161     status=SetImageExtent(image,image->columns,image->rows,exception);
    162     if (status == MagickFalse)
    163       return(DestroyImageList(image));
    164     /*
    165       Convert PIX raster image to pixel packets.
    166     */
    167     red=(Quantum) 0;
    168     green=(Quantum) 0;
    169     blue=(Quantum) 0;
    170     index=0;
    171     length=0;
    172     for (y=0; y < (ssize_t) image->rows; y++)
    173     {
    174       q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    175       if (q == (Quantum *) NULL)
    176         break;
    177       for (x=0; x < (ssize_t) image->columns; x++)
    178       {
    179         if (length == 0)
    180           {
    181             length=(size_t) ReadBlobByte(image);
    182             if (bits_per_pixel == 8)
    183               index=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
    184             else
    185               {
    186                 blue=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
    187                 green=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
    188                 red=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
    189               }
    190           }
    191         if (image->storage_class == PseudoClass)
    192           SetPixelIndex(image,index,q);
    193         SetPixelBlue(image,blue,q);
    194         SetPixelGreen(image,green,q);
    195         SetPixelRed(image,red,q);
    196         length--;
    197         q+=GetPixelChannels(image);
    198       }
    199       if (SyncAuthenticPixels(image,exception) == MagickFalse)
    200         break;
    201       if (image->previous == (Image *) NULL)
    202         {
    203           status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
    204             image->rows);
    205           if (status == MagickFalse)
    206             break;
    207         }
    208     }
    209     if (image->storage_class == PseudoClass)
    210       (void) SyncImage(image,exception);
    211     if (EOFBlob(image) != MagickFalse)
    212       {
    213         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
    214           image->filename);
    215         break;
    216       }
    217     /*
    218       Proceed to next image.
    219     */
    220     if (image_info->number_scenes != 0)
    221       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
    222         break;
    223     width=ReadBlobMSBLong(image);
    224     height=ReadBlobMSBLong(image);
    225     (void) ReadBlobMSBShort(image);
    226     (void) ReadBlobMSBShort(image);
    227     bits_per_pixel=ReadBlobMSBShort(image);
    228     status=(width != 0UL) && (height == 0UL) && ((bits_per_pixel == 8) ||
    229       (bits_per_pixel == 24)) ? MagickTrue : MagickFalse;
    230     if (status != MagickFalse)
    231       {
    232         /*
    233           Allocate next image structure.
    234         */
    235         AcquireNextImage(image_info,image,exception);
    236         if (GetNextImageInList(image) == (Image *) NULL)
    237           {
    238             image=DestroyImageList(image);
    239             return((Image *) NULL);
    240           }
    241         image=SyncNextImageInList(image);
    242         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
    243           GetBlobSize(image));
    244         if (status == MagickFalse)
    245           break;
    246       }
    247   } while (status != MagickFalse);
    248   (void) CloseBlob(image);
    249   return(GetFirstImageInList(image));
    250 }
    251 
    252 /*
    254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    255 %                                                                             %
    256 %                                                                             %
    257 %                                                                             %
    258 %   R e g i s t e r P I X I m a g e                                           %
    259 %                                                                             %
    260 %                                                                             %
    261 %                                                                             %
    262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    263 %
    264 %  RegisterPIXImage() adds attributes for the PIX image format to
    265 %  the list of supported formats.  The attributes include the image format
    266 %  tag, a method to read and/or write the format, whether the format
    267 %  supports the saving of more than one frame to the same file or blob,
    268 %  whether the format supports native in-memory I/O, and a brief
    269 %  description of the format.
    270 %
    271 %  The format of the RegisterPIXImage method is:
    272 %
    273 %      size_t RegisterPIXImage(void)
    274 %
    275 */
    276 ModuleExport size_t RegisterPIXImage(void)
    277 {
    278   MagickInfo
    279     *entry;
    280 
    281   entry=AcquireMagickInfo("PIX","PIX","Alias/Wavefront RLE image format");
    282   entry->decoder=(DecodeImageHandler *) ReadPIXImage;
    283   (void) RegisterMagickInfo(entry);
    284   return(MagickImageCoderSignature);
    285 }
    286 
    287 /*
    289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    290 %                                                                             %
    291 %                                                                             %
    292 %                                                                             %
    293 %   U n r e g i s t e r P I X I m a g e                                       %
    294 %                                                                             %
    295 %                                                                             %
    296 %                                                                             %
    297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    298 %
    299 %  UnregisterPIXImage() removes format registrations made by the
    300 %  PIX module from the list of supported formats.
    301 %
    302 %  The format of the UnregisterPIXImage method is:
    303 %
    304 %      UnregisterPIXImage(void)
    305 %
    306 */
    307 ModuleExport void UnregisterPIXImage(void)
    308 {
    309   (void) UnregisterMagickInfo("PIX");
    310 }
    311