Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                            U   U  IIIII  L                                  %
      7 %                            U   U    I    L                                  %
      8 %                            U   U    I    L                                  %
      9 %                            U   U    I    L                                  %
     10 %                             UUU   IIIII  LLLLL                              %
     11 %                                                                             %
     12 %                                                                             %
     13 %                          Write X-Motif UIL Table.                           %
     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.h"
     49 #include "MagickCore/color-private.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-private.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 #include "MagickCore/utility.h"
     65 
     66 /*
     68   Forward declarations.
     69 */
     70 static MagickBooleanType
     71   WriteUILImage(const ImageInfo *,Image *,ExceptionInfo *);
     72 
     73 /*
     75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     76 %                                                                             %
     77 %                                                                             %
     78 %                                                                             %
     79 %   R e g i s t e r U I L I m a g e                                           %
     80 %                                                                             %
     81 %                                                                             %
     82 %                                                                             %
     83 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     84 %
     85 %  RegisterUILImage() adds attributes for the UIL image format to
     86 %  the list of supported formats.  The attributes include the image format
     87 %  tag, a method to read and/or write the format, whether the format
     88 %  supports the saving of more than one frame to the same file or blob,
     89 %  whether the format supports native in-memory I/O, and a brief
     90 %  description of the format.
     91 %
     92 %  The format of the RegisterUILImage method is:
     93 %
     94 %      size_t RegisterUILImage(void)
     95 %
     96 */
     97 ModuleExport size_t RegisterUILImage(void)
     98 {
     99   MagickInfo
    100     *entry;
    101 
    102   entry=AcquireMagickInfo("UIL","UIL","X-Motif UIL table");
    103   entry->encoder=(EncodeImageHandler *) WriteUILImage;
    104   entry->flags^=CoderAdjoinFlag;
    105   (void) RegisterMagickInfo(entry);
    106   return(MagickImageCoderSignature);
    107 }
    108 
    109 /*
    111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    112 %                                                                             %
    113 %                                                                             %
    114 %                                                                             %
    115 %   U n r e g i s t e r U I L I m a g e                                       %
    116 %                                                                             %
    117 %                                                                             %
    118 %                                                                             %
    119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    120 %
    121 %  UnregisterUILImage() removes format registrations made by the
    122 %  UIL module from the list of supported formats.
    123 %
    124 %  The format of the UnregisterUILImage method is:
    125 %
    126 %      UnregisterUILImage(void)
    127 %
    128 */
    129 ModuleExport void UnregisterUILImage(void)
    130 {
    131   (void) UnregisterMagickInfo("UIL");
    132 }
    133 
    134 /*
    136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    137 %                                                                             %
    138 %                                                                             %
    139 %                                                                             %
    140 %   W r i t e U I L I m a g e                                                 %
    141 %                                                                             %
    142 %                                                                             %
    143 %                                                                             %
    144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    145 %
    146 %  Procedure WriteUILImage() writes an image to a file in the X-Motif UIL table
    147 %  format.
    148 %
    149 %  The format of the WriteUILImage method is:
    150 %
    151 %      MagickBooleanType WriteUILImage(const ImageInfo *image_info,
    152 %        Image *image,ExceptionInfo *exception)
    153 %
    154 %  A description of each parameter follows.
    155 %
    156 %    o image_info: the image info.
    157 %
    158 %    o image:  The image.
    159 %
    160 %    o exception: return any errors or warnings in this structure.
    161 %
    162 */
    163 static MagickBooleanType WriteUILImage(const ImageInfo *image_info,Image *image,
    164   ExceptionInfo *exception)
    165 {
    166 #define MaxCixels  92
    167 
    168   char
    169     basename[MagickPathExtent],
    170     buffer[MagickPathExtent],
    171     name[MagickPathExtent],
    172     *symbol;
    173 
    174   int
    175     j;
    176 
    177   MagickBooleanType
    178     status,
    179     transparent;
    180 
    181   MagickSizeType
    182     number_pixels;
    183 
    184   PixelInfo
    185     pixel;
    186 
    187   register const Quantum
    188     *p;
    189 
    190   register ssize_t
    191     i,
    192     x;
    193 
    194   size_t
    195     characters_per_pixel,
    196     colors;
    197 
    198   ssize_t
    199     k,
    200     y;
    201 
    202   static const char
    203     Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk"
    204                          "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
    205 
    206   /*
    207     Open output image file.
    208   */
    209   assert(image_info != (const ImageInfo *) NULL);
    210   assert(image_info->signature == MagickCoreSignature);
    211   assert(image != (Image *) NULL);
    212   assert(image->signature == MagickCoreSignature);
    213   if (image->debug != MagickFalse)
    214     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    215   assert(exception != (ExceptionInfo *) NULL);
    216   assert(exception->signature == MagickCoreSignature);
    217   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
    218   if (status == MagickFalse)
    219     return(status);
    220   (void) TransformImageColorspace(image,sRGBColorspace,exception);
    221   transparent=MagickFalse;
    222   i=0;
    223   p=(const Quantum *) NULL;
    224   if (image->storage_class == PseudoClass)
    225     colors=image->colors;
    226   else
    227     {
    228       unsigned char
    229         *matte_image;
    230 
    231       /*
    232         Convert DirectClass to PseudoClass image.
    233       */
    234       matte_image=(unsigned char *) NULL;
    235       if (image->alpha_trait != UndefinedPixelTrait)
    236         {
    237           /*
    238             Map all the transparent pixels.
    239           */
    240           number_pixels=(MagickSizeType) image->columns*image->rows;
    241           if (number_pixels != ((MagickSizeType) (size_t) number_pixels))
    242             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    243           matte_image=(unsigned char *) AcquireQuantumMemory(image->columns,
    244             image->rows*sizeof(*matte_image));
    245           if (matte_image == (unsigned char *) NULL)
    246             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    247           for (y=0; y < (ssize_t) image->rows; y++)
    248           {
    249             p=GetVirtualPixels(image,0,y,image->columns,1,exception);
    250             if (p == (const Quantum *) NULL)
    251               break;
    252             for (x=0; x < (ssize_t) image->columns; x++)
    253             {
    254               matte_image[i]=(unsigned char) (GetPixelAlpha(image,p) ==
    255                 (Quantum) TransparentAlpha ? 1 : 0);
    256               if (matte_image[i] != 0)
    257                 transparent=MagickTrue;
    258               i++;
    259               p+=GetPixelChannels(image);
    260             }
    261           }
    262         }
    263       (void) SetImageType(image,PaletteType,exception);
    264       colors=image->colors;
    265       if (transparent != MagickFalse)
    266         {
    267           register Quantum
    268             *q;
    269 
    270           colors++;
    271           for (y=0; y < (ssize_t) image->rows; y++)
    272           {
    273             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    274             if (q == (Quantum *) NULL)
    275               break;
    276             for (x=0; x < (ssize_t) image->columns; x++)
    277             {
    278               if (matte_image[i] != 0)
    279                 SetPixelIndex(image,(Quantum) image->colors,q);
    280               q+=GetPixelChannels(image);
    281             }
    282           }
    283         }
    284       if (matte_image != (unsigned char *) NULL)
    285         matte_image=(unsigned char *) RelinquishMagickMemory(matte_image);
    286     }
    287   /*
    288     Compute the character per pixel.
    289   */
    290   characters_per_pixel=1;
    291   for (k=MaxCixels; (ssize_t) colors > k; k*=MaxCixels)
    292     characters_per_pixel++;
    293   /*
    294     UIL header.
    295   */
    296   symbol=AcquireString("");
    297   (void) WriteBlobString(image,"/* UIL */\n");
    298   GetPathComponent(image->filename,BasePath,basename);
    299   (void) FormatLocaleString(buffer,MagickPathExtent,
    300     "value\n  %s_ct : color_table(\n",basename);
    301   (void) WriteBlobString(image,buffer);
    302   GetPixelInfo(image,&pixel);
    303   for (i=0; i < (ssize_t) colors; i++)
    304   {
    305     /*
    306       Define UIL color.
    307     */
    308     pixel=image->colormap[i];
    309     pixel.colorspace=sRGBColorspace;
    310     pixel.depth=8;
    311     pixel.alpha=(double) OpaqueAlpha;
    312     GetColorTuple(&pixel,MagickTrue,name);
    313     if (transparent != MagickFalse)
    314       if (i == (ssize_t) (colors-1))
    315         (void) CopyMagickString(name,"None",MagickPathExtent);
    316     /*
    317       Write UIL color.
    318     */
    319     k=i % MaxCixels;
    320     symbol[0]=Cixel[k];
    321     for (j=1; j < (int) characters_per_pixel; j++)
    322     {
    323       k=((i-k)/MaxCixels) % MaxCixels;
    324       symbol[j]=Cixel[k];
    325     }
    326     symbol[j]='\0';
    327     (void) SubstituteString(&symbol,"'","''");
    328     if (LocaleCompare(name,"None") == 0)
    329       (void) FormatLocaleString(buffer,MagickPathExtent,
    330         "    background color = '%s'",symbol);
    331     else
    332       (void) FormatLocaleString(buffer,MagickPathExtent,
    333         "    color('%s',%s) = '%s'",name,
    334         GetPixelInfoIntensity(image,image->colormap+i) <
    335         (QuantumRange/2.0) ? "background" : "foreground",symbol);
    336     (void) WriteBlobString(image,buffer);
    337     (void) FormatLocaleString(buffer,MagickPathExtent,"%s",
    338       (i == (ssize_t) (colors-1) ? ");\n" : ",\n"));
    339     (void) WriteBlobString(image,buffer);
    340   }
    341   /*
    342     Define UIL pixels.
    343   */
    344   GetPathComponent(image->filename,BasePath,basename);
    345   (void) FormatLocaleString(buffer,MagickPathExtent,
    346     "  %s_icon : icon(color_table = %s_ct,\n",basename,basename);
    347   (void) WriteBlobString(image,buffer);
    348   for (y=0; y < (ssize_t) image->rows; y++)
    349   {
    350     p=GetVirtualPixels(image,0,y,image->columns,1,exception);
    351     if (p == (const Quantum *) NULL)
    352       break;
    353     (void) WriteBlobString(image,"    \"");
    354     for (x=0; x < (ssize_t) image->columns; x++)
    355     {
    356       k=((ssize_t) GetPixelIndex(image,p) % MaxCixels);
    357       symbol[0]=Cixel[k];
    358       for (j=1; j < (int) characters_per_pixel; j++)
    359       {
    360         k=(((int) GetPixelIndex(image,p)-k)/MaxCixels) %
    361           MaxCixels;
    362         symbol[j]=Cixel[k];
    363       }
    364       symbol[j]='\0';
    365       (void) CopyMagickString(buffer,symbol,MagickPathExtent);
    366       (void) WriteBlobString(image,buffer);
    367       p+=GetPixelChannels(image);
    368     }
    369     (void) FormatLocaleString(buffer,MagickPathExtent,"\"%s\n",
    370       (y == (ssize_t) (image->rows-1) ? ");" : ","));
    371     (void) WriteBlobString(image,buffer);
    372     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
    373       image->rows);
    374     if (status == MagickFalse)
    375       break;
    376   }
    377   symbol=DestroyString(symbol);
    378   (void) CloseBlob(image);
    379   return(MagickTrue);
    380 }
    381