Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                                                                             %
      7 %                            M   M   AAA    CCCC                              %
      8 %                            MM MM  A   A  C                                  %
      9 %                            M M M  AAAAA  C                                  %
     10 %                            M   M  A   A  C                                  %
     11 %                            M   M  A   A   CCCC                              %
     12 %                                                                             %
     13 %                                                                             %
     14 %                         Read MacPaint Image Format                          %
     15 %                                                                             %
     16 %                              Software Design                                %
     17 %                                   Cristy                                    %
     18 %                                 July 1992                                   %
     19 %                                                                             %
     20 %                                                                             %
     21 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     22 %  dedicated to making software imaging solutions freely available.           %
     23 %                                                                             %
     24 %  You may not use this file except in compliance with the License.  You may  %
     25 %  obtain a copy of the License at                                            %
     26 %                                                                             %
     27 %    http://www.imagemagick.org/script/license.php                            %
     28 %                                                                             %
     29 %  Unless required by applicable law or agreed to in writing, software        %
     30 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     31 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     32 %  See the License for the specific language governing permissions and        %
     33 %  limitations under the License.                                             %
     34 %                                                                             %
     35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     36 %
     37 %
     38 */
     39 
     40 /*
     42   Include declarations.
     43 */
     44 #include "MagickCore/studio.h"
     45 #include "MagickCore/blob.h"
     46 #include "MagickCore/blob-private.h"
     47 #include "MagickCore/cache.h"
     48 #include "MagickCore/colormap.h"
     49 #include "MagickCore/colorspace.h"
     50 #include "MagickCore/exception.h"
     51 #include "MagickCore/exception-private.h"
     52 #include "MagickCore/image.h"
     53 #include "MagickCore/image-private.h"
     54 #include "MagickCore/list.h"
     55 #include "MagickCore/magick.h"
     56 #include "MagickCore/memory_.h"
     57 #include "MagickCore/monitor.h"
     58 #include "MagickCore/monitor-private.h"
     59 #include "MagickCore/pixel-accessor.h"
     60 #include "MagickCore/quantum-private.h"
     61 #include "MagickCore/static.h"
     62 #include "MagickCore/string_.h"
     63 #include "MagickCore/module.h"
     64 
     65 /*
     67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     68 %                                                                             %
     69 %                                                                             %
     70 %                                                                             %
     71 %   R e a d M A C I m a g e                                                   %
     72 %                                                                             %
     73 %                                                                             %
     74 %                                                                             %
     75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     76 %
     77 %  ReadMACImage() reads an MacPaint image file and returns it.  It
     78 %  allocates the memory necessary for the new Image structure and returns a
     79 %  pointer to the new image.
     80 %
     81 %  The format of the ReadMACImage method is:
     82 %
     83 %      Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
     84 %
     85 %  A description of each parameter follows:
     86 %
     87 %    o image_info: the image info.
     88 %
     89 %    o exception: return any errors or warnings in this structure.
     90 %
     91 */
     92 static Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
     93 {
     94   Image
     95     *image;
     96 
     97   MagickBooleanType
     98     status;
     99 
    100   register Quantum
    101     *q;
    102 
    103   register ssize_t
    104     x;
    105 
    106   register unsigned char
    107     *p;
    108 
    109   size_t
    110     length;
    111 
    112   ssize_t
    113     offset,
    114     y;
    115 
    116   unsigned char
    117     count,
    118     bit,
    119     byte,
    120     *pixels;
    121 
    122   /*
    123     Open image file.
    124   */
    125   assert(image_info != (const ImageInfo *) NULL);
    126   assert(image_info->signature == MagickCoreSignature);
    127   if (image_info->debug != MagickFalse)
    128     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    129       image_info->filename);
    130   assert(exception != (ExceptionInfo *) NULL);
    131   assert(exception->signature == MagickCoreSignature);
    132   image=AcquireImage(image_info,exception);
    133   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    134   if (status == MagickFalse)
    135     {
    136       image=DestroyImageList(image);
    137       return((Image *) NULL);
    138     }
    139   /*
    140     Read MAC X image.
    141   */
    142   length=ReadBlobLSBShort(image);
    143   if ((length & 0xff) != 0)
    144     ThrowReaderException(CorruptImageError,"CorruptImage");
    145   for (x=0; x < (ssize_t) 638; x++)
    146     if (ReadBlobByte(image) == EOF)
    147       ThrowReaderException(CorruptImageError,"CorruptImage");
    148   image->columns=576;
    149   image->rows=720;
    150   image->depth=1;
    151   if (AcquireImageColormap(image,2,exception) == MagickFalse)
    152     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    153   if (image_info->ping != MagickFalse)
    154     {
    155       (void) CloseBlob(image);
    156       return(GetFirstImageInList(image));
    157     }
    158   status=SetImageExtent(image,image->columns,image->rows,exception);
    159   if (status == MagickFalse)
    160     return(DestroyImageList(image));
    161   /*
    162     Convert MAC raster image to pixel packets.
    163   */
    164   length=(image->columns+7)/8;
    165   pixels=(unsigned char *) AcquireQuantumMemory(length+1,sizeof(*pixels));
    166   if (pixels == (unsigned char *) NULL)
    167     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    168   p=pixels;
    169   offset=0;
    170   for (y=0; y < (ssize_t) image->rows; )
    171   {
    172     count=(unsigned char) ReadBlobByte(image);
    173     if (EOFBlob(image) != MagickFalse)
    174       break;
    175     if ((count <= 0) || (count >= 128))
    176       {
    177         byte=(unsigned char) (~ReadBlobByte(image));
    178         count=(~count)+2;
    179         while (count != 0)
    180         {
    181           *p++=byte;
    182           offset++;
    183           count--;
    184           if (offset >= (ssize_t) length)
    185             {
    186               q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    187               if (q == (Quantum *) NULL)
    188                 break;
    189               p=pixels;
    190               bit=0;
    191               byte=0;
    192               for (x=0; x < (ssize_t) image->columns; x++)
    193               {
    194                 if (bit == 0)
    195                   byte=(*p++);
    196                 SetPixelIndex(image,((byte & 0x80) != 0 ? 0x01 : 0x00),q);
    197                 bit++;
    198                 byte<<=1;
    199                 if (bit == 8)
    200                   bit=0;
    201                 q+=GetPixelChannels(image);
    202               }
    203               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    204                 break;
    205               offset=0;
    206               p=pixels;
    207               y++;
    208             }
    209         }
    210         continue;
    211       }
    212     count++;
    213     while (count != 0)
    214     {
    215       byte=(unsigned char) (~ReadBlobByte(image));
    216       *p++=byte;
    217       offset++;
    218       count--;
    219       if (offset >= (ssize_t) length)
    220         {
    221           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    222           if (q == (Quantum *) NULL)
    223             break;
    224           p=pixels;
    225           bit=0;
    226           byte=0;
    227           for (x=0; x < (ssize_t) image->columns; x++)
    228           {
    229             if (bit == 0)
    230               byte=(*p++);
    231             SetPixelIndex(image,((byte & 0x80) != 0 ? 0x01 : 0x00),q);
    232             bit++;
    233             byte<<=1;
    234             if (bit == 8)
    235               bit=0;
    236             q+=GetPixelChannels(image);
    237           }
    238           if (SyncAuthenticPixels(image,exception) == MagickFalse)
    239             break;
    240           offset=0;
    241           p=pixels;
    242           y++;
    243         }
    244     }
    245   }
    246   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    247   (void) SyncImage(image,exception);
    248   (void) CloseBlob(image);
    249   return(GetFirstImageInList(image));
    250 }
    251 
    252 /*
    254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    255 %                                                                             %
    256 %                                                                             %
    257 %                                                                             %
    258 %   R e g i s t e r M A C I m a g e                                           %
    259 %                                                                             %
    260 %                                                                             %
    261 %                                                                             %
    262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    263 %
    264 %  RegisterMACImage() adds attributes for the MAC X image format to the list
    265 %  of supported formats.  The attributes include the image format tag, a
    266 %  method to read and/or write the format, whether the format supports the
    267 %  saving of more than one frame to the same file or blob, whether the format
    268 %  supports native in-memory I/O, and a brief description of the format.
    269 %
    270 %  The format of the RegisterMACImage method is:
    271 %
    272 %      size_t RegisterMACImage(void)
    273 %
    274 */
    275 ModuleExport size_t RegisterMACImage(void)
    276 {
    277   MagickInfo
    278     *entry;
    279 
    280   entry=AcquireMagickInfo("MAC","MAC","MAC Paint");
    281   entry->decoder=(DecodeImageHandler *) ReadMACImage;
    282   (void) RegisterMagickInfo(entry);
    283   return(MagickImageCoderSignature);
    284 }
    285 
    286 /*
    288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    289 %                                                                             %
    290 %                                                                             %
    291 %                                                                             %
    292 %   U n r e g i s t e r M A C I m a g e                                       %
    293 %                                                                             %
    294 %                                                                             %
    295 %                                                                             %
    296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    297 %
    298 %  UnregisterMACImage() removes format registrations made by the
    299 %  MAC module from the list of supported formats.
    300 %
    301 %  The format of the UnregisterMACImage method is:
    302 %
    303 %      UnregisterMACImage(void)
    304 %
    305 */
    306 ModuleExport void UnregisterMACImage(void)
    307 {
    308   (void) UnregisterMagickInfo("MAC");
    309 }
    310