Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                             AAA   RRRR   TTTTT                              %
      7 %                            A   A  R   R    T                                %
      8 %                            AAAAA  RRRR     T                                %
      9 %                            A   A  R R      T                                %
     10 %                            A   A  R  R     T                                %
     11 %                                                                             %
     12 %                                                                             %
     13 %                 Support PFS: 1st Publisher Clip Art 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/attribute.h"
     45 #include "MagickCore/blob.h"
     46 #include "MagickCore/blob-private.h"
     47 #include "MagickCore/cache.h"
     48 #include "MagickCore/color-private.h"
     49 #include "MagickCore/colormap.h"
     50 #include "MagickCore/colorspace.h"
     51 #include "MagickCore/colorspace-private.h"
     52 #include "MagickCore/exception.h"
     53 #include "MagickCore/exception-private.h"
     54 #include "MagickCore/image.h"
     55 #include "MagickCore/image-private.h"
     56 #include "MagickCore/list.h"
     57 #include "MagickCore/magick.h"
     58 #include "MagickCore/memory_.h"
     59 #include "MagickCore/monitor.h"
     60 #include "MagickCore/monitor-private.h"
     61 #include "MagickCore/quantum-private.h"
     62 #include "MagickCore/static.h"
     63 #include "MagickCore/string_.h"
     64 #include "MagickCore/module.h"
     65 
     66 /*
     68   Forward declarations.
     69 */
     70 static MagickBooleanType
     71   WriteARTImage(const ImageInfo *,Image *,ExceptionInfo *);
     72 
     73 /*
     75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     76 %                                                                             %
     77 %                                                                             %
     78 %                                                                             %
     79 %   R e a d A R T I m a g e                                                   %
     80 %                                                                             %
     81 %                                                                             %
     82 %                                                                             %
     83 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     84 %
     85 %  ReadARTImage() reads an image of raw bits in LSB order and returns it.
     86 %  It allocates the memory necessary for the new Image structure and returns
     87 %  a pointer to the new image.
     88 %
     89 %  The format of the ReadARTImage method is:
     90 %
     91 %      Image *ReadARTImage(const ImageInfo *image_info,
     92 %        ExceptionInfo *exception)
     93 %
     94 %  A description of each parameter follows:
     95 %
     96 %    o image_info: the image info.
     97 %
     98 %    o exception: return any errors or warnings in this structure.
     99 %
    100 */
    101 static Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception)
    102 {
    103   const unsigned char
    104     *pixels;
    105 
    106   Image
    107     *image;
    108 
    109   QuantumInfo
    110     *quantum_info;
    111 
    112   MagickBooleanType
    113     status;
    114 
    115   size_t
    116     length;
    117 
    118   ssize_t
    119     count,
    120     y;
    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   image->depth=1;
    140   image->endian=MSBEndian;
    141   (void) ReadBlobLSBShort(image);
    142   image->columns=(size_t) ReadBlobLSBShort(image);
    143   (void) ReadBlobLSBShort(image);
    144   image->rows=(size_t) ReadBlobLSBShort(image);
    145   if ((image->columns == 0) || (image->rows == 0))
    146     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    147   if (image_info->ping != MagickFalse)
    148     {
    149       (void) CloseBlob(image);
    150       return(GetFirstImageInList(image));
    151     }
    152   status=SetImageExtent(image,image->columns,image->rows,exception);
    153   if (status == MagickFalse)
    154     return(DestroyImageList(image));
    155   /*
    156     Convert bi-level image to pixel packets.
    157   */
    158   SetImageColorspace(image,GRAYColorspace,exception);
    159   quantum_info=AcquireQuantumInfo(image_info,image);
    160   if (quantum_info == (QuantumInfo *) NULL)
    161     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    162   length=GetQuantumExtent(image,quantum_info,GrayQuantum);
    163   for (y=0; y < (ssize_t) image->rows; y++)
    164   {
    165     register Quantum
    166       *magick_restrict q;
    167 
    168     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    169     if (q == (Quantum *) NULL)
    170       break;
    171     pixels=(const unsigned char *) ReadBlobStream(image,length,
    172       GetQuantumPixels(quantum_info),&count);
    173     if (count != (ssize_t) length)
    174       ThrowReaderException(CorruptImageError,"UnableToReadImageData");
    175     (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
    176       GrayQuantum,pixels,exception);
    177     pixels=(const unsigned char *) ReadBlobStream(image,(size_t) (-(ssize_t)
    178       length) & 0x01,GetQuantumPixels(quantum_info),&count);
    179     if (SyncAuthenticPixels(image,exception) == MagickFalse)
    180       break;
    181     if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
    182       break;
    183   }
    184   SetQuantumImageType(image,GrayQuantum);
    185   quantum_info=DestroyQuantumInfo(quantum_info);
    186   if (EOFBlob(image) != MagickFalse)
    187     ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
    188       image->filename);
    189   (void) CloseBlob(image);
    190   return(GetFirstImageInList(image));
    191 }
    192 
    193 /*
    195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    196 %                                                                             %
    197 %                                                                             %
    198 %                                                                             %
    199 %   R e g i s t e r A R T I m a g e                                           %
    200 %                                                                             %
    201 %                                                                             %
    202 %                                                                             %
    203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    204 %
    205 %  RegisterARTImage() adds attributes for the ART image format to
    206 %  the list of supported formats.  The attributes include the image format
    207 %  tag, a method to read and/or write the format, whether the format
    208 %  supports the saving of more than one frame to the same file or blob,
    209 %  whether the format supports native in-memory I/O, and a brief
    210 %  description of the format.
    211 %
    212 %  The format of the RegisterARTImage method is:
    213 %
    214 %      size_t RegisterARTImage(void)
    215 %
    216 */
    217 ModuleExport size_t RegisterARTImage(void)
    218 {
    219   MagickInfo
    220     *entry;
    221 
    222   entry=AcquireMagickInfo("ART","ART","PFS: 1st Publisher Clip Art");
    223   entry->decoder=(DecodeImageHandler *) ReadARTImage;
    224   entry->encoder=(EncodeImageHandler *) WriteARTImage;
    225   entry->flags|=CoderRawSupportFlag;
    226   entry->flags^=CoderAdjoinFlag;
    227   (void) RegisterMagickInfo(entry);
    228   return(MagickImageCoderSignature);
    229 }
    230 
    231 /*
    233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    234 %                                                                             %
    235 %                                                                             %
    236 %                                                                             %
    237 %   U n r e g i s t e r A R T I m a g e                                       %
    238 %                                                                             %
    239 %                                                                             %
    240 %                                                                             %
    241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    242 %
    243 %  UnregisterARTImage() removes format registrations made by the
    244 %  ART module from the list of supported formats.
    245 %
    246 %  The format of the UnregisterARTImage method is:
    247 %
    248 %      UnregisterARTImage(void)
    249 %
    250 */
    251 ModuleExport void UnregisterARTImage(void)
    252 {
    253   (void) UnregisterMagickInfo("ART");
    254 }
    255 
    256 /*
    258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    259 %                                                                             %
    260 %                                                                             %
    261 %                                                                             %
    262 %   W r i t e A R T I m a g e                                                 %
    263 %                                                                             %
    264 %                                                                             %
    265 %                                                                             %
    266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    267 %
    268 %  WriteARTImage() writes an image of raw bits in LSB order to a file.
    269 %
    270 %  The format of the WriteARTImage method is:
    271 %
    272 %      MagickBooleanType WriteARTImage(const ImageInfo *image_info,
    273 %        Image *image,ExceptionInfo *exception)
    274 %
    275 %  A description of each parameter follows.
    276 %
    277 %    o image_info: the image info.
    278 %
    279 %    o image:  The image.
    280 %
    281 %    o exception: return any errors or warnings in this structure.
    282 %
    283 */
    284 static MagickBooleanType WriteARTImage(const ImageInfo *image_info,Image *image,
    285   ExceptionInfo *exception)
    286 {
    287   MagickBooleanType
    288     status;
    289 
    290   QuantumInfo
    291     *quantum_info;
    292 
    293   register const Quantum
    294     *p;
    295 
    296   size_t
    297     length;
    298 
    299   ssize_t
    300     count,
    301     y;
    302 
    303   unsigned char
    304     *pixels;
    305 
    306   /*
    307     Open output image file.
    308   */
    309   assert(image_info != (const ImageInfo *) NULL);
    310   assert(image_info->signature == MagickCoreSignature);
    311   assert(image != (Image *) NULL);
    312   assert(image->signature == MagickCoreSignature);
    313   if (image->debug != MagickFalse)
    314     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    315   assert(exception != (ExceptionInfo *) NULL);
    316   assert(exception->signature == MagickCoreSignature);
    317   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
    318   if (status == MagickFalse)
    319     return(status);
    320   if ((image->columns > 65535UL) || (image->rows > 65535UL))
    321     ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
    322   (void) TransformImageColorspace(image,sRGBColorspace,exception);
    323   (void) SetImageType(image,BilevelType,exception);
    324   image->endian=MSBEndian;
    325   image->depth=1;
    326   (void) WriteBlobLSBShort(image,0);
    327   (void) WriteBlobLSBShort(image,(unsigned short) image->columns);
    328   (void) WriteBlobLSBShort(image,0);
    329   (void) WriteBlobLSBShort(image,(unsigned short) image->rows);
    330   quantum_info=AcquireQuantumInfo(image_info,image);
    331   pixels=(unsigned char *) GetQuantumPixels(quantum_info);
    332   for (y=0; y < (ssize_t) image->rows; y++)
    333   {
    334     p=GetVirtualPixels(image,0,y,image->columns,1,exception);
    335     if (p == (const Quantum *) NULL)
    336       break;
    337     length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
    338       GrayQuantum,pixels,exception);
    339     count=WriteBlob(image,length,pixels);
    340     if (count != (ssize_t) length)
    341       ThrowWriterException(CorruptImageError,"UnableToWriteImageData");
    342     count=WriteBlob(image,(size_t) (-(ssize_t) length) & 0x01,pixels);
    343     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
    344       image->rows);
    345     if (status == MagickFalse)
    346       break;
    347   }
    348   quantum_info=DestroyQuantumInfo(quantum_info);
    349   (void) CloseBlob(image);
    350   return(status);
    351 }
    352