Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                     L       AAA   BBBB   EEEEE  L                           %
      7 %                     L      A   A  B   B  E      L                           %
      8 %                     L      AAAAA  BBBB   EEE    L                           %
      9 %                     L      A   A  B   B  E      L                           %
     10 %                     LLLLL  A   A  BBBB   EEEEE  LLLLL                       %
     11 %                                                                             %
     12 %                                                                             %
     13 %                      Read ASCII String As An Image.                         %
     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/annotate.h"
     45 #include "MagickCore/artifact.h"
     46 #include "MagickCore/blob.h"
     47 #include "MagickCore/blob-private.h"
     48 #include "MagickCore/draw.h"
     49 #include "MagickCore/exception.h"
     50 #include "MagickCore/exception-private.h"
     51 #include "MagickCore/image.h"
     52 #include "MagickCore/image-private.h"
     53 #include "MagickCore/list.h"
     54 #include "MagickCore/magick.h"
     55 #include "MagickCore/memory_.h"
     56 #include "MagickCore/property.h"
     57 #include "MagickCore/quantum-private.h"
     58 #include "MagickCore/static.h"
     59 #include "MagickCore/string_.h"
     60 #include "MagickCore/module.h"
     61 #include "MagickCore/utility.h"
     62 
     63 /*
     65 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     66 %                                                                             %
     67 %                                                                             %
     68 %                                                                             %
     69 %   R e a d L A B E L I m a g e                                               %
     70 %                                                                             %
     71 %                                                                             %
     72 %                                                                             %
     73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     74 %
     75 %  ReadLABELImage() reads a LABEL image file and returns it.  It
     76 %  allocates the memory necessary for the new Image structure and returns a
     77 %  pointer to the new image.
     78 %
     79 %  The format of the ReadLABELImage method is:
     80 %
     81 %      Image *ReadLABELImage(const ImageInfo *image_info,
     82 %        ExceptionInfo *exception)
     83 %
     84 %  A description of each parameter follows:
     85 %
     86 %    o image_info: the image info.
     87 %
     88 %    o exception: return any errors or warnings in this structure.
     89 %
     90 */
     91 static Image *ReadLABELImage(const ImageInfo *image_info,
     92   ExceptionInfo *exception)
     93 {
     94   char
     95     geometry[MagickPathExtent],
     96     *property;
     97 
     98   const char
     99     *label;
    100 
    101   DrawInfo
    102     *draw_info;
    103 
    104   Image
    105     *image;
    106 
    107   MagickBooleanType
    108     status;
    109 
    110   TypeMetric
    111     metrics;
    112 
    113   size_t
    114     height,
    115     width;
    116 
    117   /*
    118     Initialize Image structure.
    119   */
    120   assert(image_info != (const ImageInfo *) NULL);
    121   assert(image_info->signature == MagickCoreSignature);
    122   if (image_info->debug != MagickFalse)
    123     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    124       image_info->filename);
    125   assert(exception != (ExceptionInfo *) NULL);
    126   assert(exception->signature == MagickCoreSignature);
    127   image=AcquireImage(image_info,exception);
    128   (void) ResetImagePage(image,"0x0+0+0");
    129   property=InterpretImageProperties((ImageInfo *) image_info,image,
    130     image_info->filename,exception);
    131   (void) SetImageProperty(image,"label",property,exception);
    132   property=DestroyString(property);
    133   label=GetImageProperty(image,"label",exception);
    134   draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
    135   draw_info->text=ConstantString(label);
    136   metrics.width=0;
    137   metrics.ascent=0.0;
    138   status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
    139   if ((image->columns == 0) && (image->rows == 0))
    140     {
    141       image->columns=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
    142       image->rows=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
    143     }
    144   else
    145     if ((strlen(label) > 0) &&
    146         (((image->columns == 0) || (image->rows == 0)) ||
    147          (fabs(image_info->pointsize) < MagickEpsilon)))
    148       {
    149         double
    150           high,
    151           low;
    152 
    153         /*
    154           Auto fit text into bounding box.
    155         */
    156         for ( ; ; draw_info->pointsize*=2.0)
    157         {
    158           (void) FormatLocaleString(geometry,MagickPathExtent,"%+g%+g",
    159             -metrics.bounds.x1,metrics.ascent);
    160           if (draw_info->gravity == UndefinedGravity)
    161             (void) CloneString(&draw_info->geometry,geometry);
    162           status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
    163           width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
    164           height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
    165           if ((image->columns != 0) && (image->rows != 0))
    166             {
    167               if ((width >= image->columns) && (height >= image->rows))
    168                 break;
    169             }
    170           else
    171             if (((image->columns != 0) && (width >= image->columns)) ||
    172                 ((image->rows != 0) && (height >= image->rows)))
    173               break;
    174         }
    175         high=draw_info->pointsize;
    176         for (low=1.0; (high-low) > 0.5; )
    177         {
    178           draw_info->pointsize=(low+high)/2.0;
    179           (void) FormatLocaleString(geometry,MagickPathExtent,"%+g%+g",
    180             -metrics.bounds.x1,metrics.ascent);
    181           if (draw_info->gravity == UndefinedGravity)
    182             (void) CloneString(&draw_info->geometry,geometry);
    183           status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
    184           width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
    185           height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
    186           if ((image->columns != 0) && (image->rows != 0))
    187             {
    188               if ((width < image->columns) && (height < image->rows))
    189                 low=draw_info->pointsize+0.5;
    190               else
    191                 high=draw_info->pointsize-0.5;
    192             }
    193           else
    194             if (((image->columns != 0) && (width < image->columns)) ||
    195                 ((image->rows != 0) && (height < image->rows)))
    196               low=draw_info->pointsize+0.5;
    197             else
    198               high=draw_info->pointsize-0.5;
    199         }
    200         draw_info->pointsize=(low+high)/2.0-0.5;
    201       }
    202    status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
    203    if (status == MagickFalse)
    204      {
    205        draw_info=DestroyDrawInfo(draw_info);
    206        image=DestroyImageList(image);
    207        return((Image *) NULL);
    208      }
    209   if (image->columns == 0)
    210     image->columns=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
    211   if (image->columns == 0)
    212     image->columns=(size_t) floor(draw_info->pointsize+draw_info->stroke_width+
    213       0.5);
    214   if (image->rows == 0)
    215     image->rows=(size_t) floor(metrics.ascent-metrics.descent+
    216       draw_info->stroke_width+0.5);
    217   if (image->rows == 0)
    218     image->rows=(size_t) floor(draw_info->pointsize+draw_info->stroke_width+
    219       0.5);
    220   status=SetImageExtent(image,image->columns,image->rows,exception);
    221   if (status == MagickFalse)
    222     {
    223       draw_info=DestroyDrawInfo(draw_info);
    224       return(DestroyImageList(image));
    225     }
    226   if (SetImageBackgroundColor(image,exception) == MagickFalse)
    227     {
    228       draw_info=DestroyDrawInfo(draw_info);
    229       image=DestroyImageList(image);
    230       return((Image *) NULL);
    231     }
    232   /*
    233     Draw label.
    234   */
    235   (void) FormatLocaleString(geometry,MagickPathExtent,"%+g%+g",
    236     draw_info->direction == RightToLeftDirection ? image->columns-
    237     metrics.bounds.x2 : 0.0,draw_info->gravity == UndefinedGravity ?
    238     metrics.ascent : 0.0);
    239   draw_info->geometry=AcquireString(geometry);
    240   status=AnnotateImage(image,draw_info,exception);
    241   if (image_info->pointsize == 0.0)
    242     {
    243       char
    244         pointsize[MagickPathExtent];
    245 
    246       (void) FormatLocaleString(pointsize,MagickPathExtent,"%.20g",
    247         draw_info->pointsize);
    248       (void) SetImageProperty(image,"label:pointsize",pointsize,exception);
    249     }
    250   draw_info=DestroyDrawInfo(draw_info);
    251   if (status == MagickFalse)
    252     {
    253       image=DestroyImageList(image);
    254       return((Image *) NULL);
    255     }
    256   return(GetFirstImageInList(image));
    257 }
    258 
    259 /*
    261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    262 %                                                                             %
    263 %                                                                             %
    264 %                                                                             %
    265 %   R e g i s t e r L A B E L I m a g e                                       %
    266 %                                                                             %
    267 %                                                                             %
    268 %                                                                             %
    269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    270 %
    271 %  RegisterLABELImage() adds properties for the LABEL image format to
    272 %  the list of supported formats.  The properties include the image format
    273 %  tag, a method to read and/or write the format, whether the format
    274 %  supports the saving of more than one frame to the same file or blob,
    275 %  whether the format supports native in-memory I/O, and a brief
    276 %  description of the format.
    277 %
    278 %  The format of the RegisterLABELImage method is:
    279 %
    280 %      size_t RegisterLABELImage(void)
    281 %
    282 */
    283 ModuleExport size_t RegisterLABELImage(void)
    284 {
    285   MagickInfo
    286     *entry;
    287 
    288   entry=AcquireMagickInfo("LABEL","LABEL","Image label");
    289   entry->decoder=(DecodeImageHandler *) ReadLABELImage;
    290   entry->flags^=CoderAdjoinFlag;
    291   entry->format_type=ImplicitFormatType;
    292   (void) RegisterMagickInfo(entry);
    293   return(MagickImageCoderSignature);
    294 }
    295 
    296 /*
    298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    299 %                                                                             %
    300 %                                                                             %
    301 %                                                                             %
    302 %   U n r e g i s t e r L A B E L I m a g e                                   %
    303 %                                                                             %
    304 %                                                                             %
    305 %                                                                             %
    306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    307 %
    308 %  UnregisterLABELImage() removes format registrations made by the
    309 %  LABEL module from the list of supported formats.
    310 %
    311 %  The format of the UnregisterLABELImage method is:
    312 %
    313 %      UnregisterLABELImage(void)
    314 %
    315 */
    316 ModuleExport void UnregisterLABELImage(void)
    317 {
    318   (void) UnregisterMagickInfo("LABEL");
    319 }
    320