Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                             CCCC  IIIII  PPPP                               %
      6 %                            C        I    P   P                              %
      7 %                            C        I    PPPP                               %
      8 %                            C        I    P                                  %
      9 %                             CCCC  IIIII  P                                  %
     10 %                                                                             %
     11 %                                                                             %
     12 %                  Read/Write Cisco IP Phone Image Format                     %
     13 %                                                                             %
     14 %                              Software Design                                %
     15 %                                   Cristy                                    %
     16 %                                April 2004                                   %
     17 %                                                                             %
     18 %                                                                             %
     19 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     20 %  dedicated to making software imaging solutions freely available.           %
     21 %                                                                             %
     22 %  You may not use this file except in compliance with the License.  You may  %
     23 %  obtain a copy of the License at                                            %
     24 %                                                                             %
     25 %    http://www.imagemagick.org/script/license.php                            %
     26 %                                                                             %
     27 %  Unless required by applicable law or agreed to in writing, software        %
     28 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     29 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     30 %  See the License for the specific language governing permissions and        %
     31 %  limitations under the License.                                             %
     32 %                                                                             %
     33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     34 %
     35 %
     36 */
     37 
     38 /*
     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/color-private.h"
     47 #include "MagickCore/colorspace.h"
     48 #include "MagickCore/colorspace-private.h"
     49 #include "MagickCore/constitute.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/property.h"
     61 #include "MagickCore/quantize.h"
     62 #include "MagickCore/quantum-private.h"
     63 #include "MagickCore/static.h"
     64 #include "MagickCore/string_.h"
     65 #include "MagickCore/module.h"
     66 #include "MagickCore/utility.h"
     67 
     68 /*
     70   Forward declarations.
     71 */
     72 static MagickBooleanType
     73   WriteCIPImage(const ImageInfo *,Image *,ExceptionInfo *);
     74 
     75 /*
     77 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     78 %                                                                             %
     79 %                                                                             %
     80 %                                                                             %
     81 %   R e g i s t e r C I P I m a g e                                           %
     82 %                                                                             %
     83 %                                                                             %
     84 %                                                                             %
     85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     86 %
     87 %  RegisterCIPImage() adds properties for the CIP IP phone image format to
     88 %  the list of supported formats.  The properties include the image format
     89 %  tag, a method to read and/or write the format, whether the format
     90 %  supports the saving of more than one frame to the same file or blob,
     91 %  whether the format supports native in-memory I/O, and a brief
     92 %  description of the format.
     93 %
     94 %  The format of the RegisterCIPImage method is:
     95 %
     96 %      size_t RegisterCIPImage(void)
     97 %
     98 */
     99 ModuleExport size_t RegisterCIPImage(void)
    100 {
    101   MagickInfo
    102     *entry;
    103 
    104   entry=AcquireMagickInfo("CIP","CIP","Cisco IP phone image format");
    105   entry->encoder=(EncodeImageHandler *) WriteCIPImage;
    106   entry->flags^=CoderAdjoinFlag;
    107   (void) RegisterMagickInfo(entry);
    108   return(MagickImageCoderSignature);
    109 }
    110 
    111 /*
    113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    114 %                                                                             %
    115 %                                                                             %
    116 %                                                                             %
    117 %   U n r e g i s t e r C I P I m a g e                                       %
    118 %                                                                             %
    119 %                                                                             %
    120 %                                                                             %
    121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    122 %
    123 %  UnregisterCIPImage() removes format registrations made by the
    124 %  CIP module from the list of supported formats.
    125 %
    126 %  The format of the UnregisterCIPImage method is:
    127 %
    128 %      UnregisterCIPImage(void)
    129 %
    130 */
    131 ModuleExport void UnregisterCIPImage(void)
    132 {
    133   (void) UnregisterMagickInfo("CIP");
    134 }
    135 
    136 /*
    138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    139 %                                                                             %
    140 %                                                                             %
    141 %                                                                             %
    142 %   W r i t e C I P I m a g e                                                 %
    143 %                                                                             %
    144 %                                                                             %
    145 %                                                                             %
    146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    147 %
    148 %  Procedure WriteCIPImage() writes an image to a file in the Cisco IP phone
    149 %  image format.
    150 %
    151 %  The format of the WriteCIPImage method is:
    152 %
    153 %      MagickBooleanType WriteCIPImage(const ImageInfo *image_info,
    154 %        Image *image,ExceptionInfo *exception)
    155 %
    156 %  A description of each parameter follows.
    157 %
    158 %    o image_info: the image info.
    159 %
    160 %    o image:  The image.
    161 %
    162 %    o exception: return any errors or warnings in this structure.
    163 %
    164 */
    165 static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
    166   ExceptionInfo *exception)
    167 {
    168   char
    169     buffer[MagickPathExtent];
    170 
    171   const char
    172     *value;
    173 
    174   MagickBooleanType
    175     status;
    176 
    177   register const Quantum
    178     *p;
    179 
    180   register ssize_t
    181     i,
    182     x;
    183 
    184   ssize_t
    185     y;
    186 
    187   unsigned char
    188     byte;
    189 
    190   /*
    191     Open output image file.
    192   */
    193   assert(image_info != (const ImageInfo *) NULL);
    194   assert(image_info->signature == MagickCoreSignature);
    195   assert(image != (Image *) NULL);
    196   assert(image->signature == MagickCoreSignature);
    197   if (image->debug != MagickFalse)
    198     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    199   assert(exception != (ExceptionInfo *) NULL);
    200   assert(exception->signature == MagickCoreSignature);
    201   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
    202   if (status == MagickFalse)
    203     return(status);
    204   (void) WriteBlobString(image,"<CiscoIPPhoneImage>\n");
    205   value=GetImageProperty(image,"label",exception);
    206   if (value != (const char *) NULL)
    207     (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",value);
    208   else
    209     {
    210       char
    211         basename[MagickPathExtent];
    212 
    213       GetPathComponent(image->filename,BasePath,basename);
    214       (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",
    215         basename);
    216     }
    217   (void) WriteBlobString(image,buffer);
    218   (void) FormatLocaleString(buffer,MagickPathExtent,
    219     "<LocationX>%.20g</LocationX>\n",(double) image->page.x);
    220   (void) WriteBlobString(image,buffer);
    221   (void) FormatLocaleString(buffer,MagickPathExtent,
    222     "<LocationY>%.20g</LocationY>\n",(double) image->page.y);
    223   (void) WriteBlobString(image,buffer);
    224   (void) FormatLocaleString(buffer,MagickPathExtent,"<Width>%.20g</Width>\n",
    225     (double) (image->columns+(image->columns % 2)));
    226   (void) WriteBlobString(image,buffer);
    227   (void) FormatLocaleString(buffer,MagickPathExtent,"<Height>%.20g</Height>\n",
    228     (double) image->rows);
    229   (void) WriteBlobString(image,buffer);
    230   (void) FormatLocaleString(buffer,MagickPathExtent,"<Depth>2</Depth>\n");
    231   (void) WriteBlobString(image,buffer);
    232   (void) WriteBlobString(image,"<Data>");
    233   (void) TransformImageColorspace(image,sRGBColorspace,exception);
    234   for (y=0; y < (ssize_t) image->rows; y++)
    235   {
    236     p=GetVirtualPixels(image,0,y,image->columns,1,exception);
    237     if (p == (const Quantum *) NULL)
    238       break;
    239     for (x=0; x < ((ssize_t) image->columns-3); x+=4)
    240     {
    241       byte=(unsigned char)
    242         ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+3))/QuantumRange) & 0x03) << 6) |
    243          (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+2))/QuantumRange) & 0x03) << 4) |
    244          (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+1))/QuantumRange) & 0x03) << 2) |
    245          (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+0))/QuantumRange) & 0x03) << 0));
    246       (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",byte);
    247       (void) WriteBlobString(image,buffer);
    248       p+=4;
    249     }
    250     if ((image->columns % 4) != 0)
    251       {
    252         i=(ssize_t) image->columns % 4;
    253         byte=(unsigned char)
    254           ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,3)))/QuantumRange) & 0x03) << 6) |
    255            (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,2)))/QuantumRange) & 0x03) << 4) |
    256            (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,1)))/QuantumRange) & 0x03) << 2) |
    257            (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,0)))/QuantumRange) & 0x03) << 0));
    258         (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",~byte);
    259         (void) WriteBlobString(image,buffer);
    260       }
    261     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
    262       image->rows);
    263     if (status == MagickFalse)
    264       break;
    265   }
    266   (void) WriteBlobString(image,"</Data>\n");
    267   (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n");
    268   (void) CloseBlob(image);
    269   return(MagickTrue);
    270 }
    271