Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                         M   M   AAA   SSSSS  K   K                          %
      7 %                         MM MM  A   A  SS     K  K                           %
      8 %                         M M M  AAAAA   SSS   KKK                            %
      9 %                         M   M  A   A     SS  K  K                           %
     10 %                         M   M  A   A  SSSSS  K   K                          %
     11 %                                                                             %
     12 %                                                                             %
     13 %                              Write Mask File.                               %
     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/constitute.h"
     48 #include "MagickCore/enhance.h"
     49 #include "MagickCore/exception.h"
     50 #include "MagickCore/exception-private.h"
     51 #include "MagickCore/list.h"
     52 #include "MagickCore/magick.h"
     53 #include "MagickCore/memory_.h"
     54 #include "MagickCore/monitor.h"
     55 #include "MagickCore/monitor-private.h"
     56 #include "MagickCore/pixel-accessor.h"
     57 #include "MagickCore/quantum-private.h"
     58 #include "MagickCore/static.h"
     59 #include "MagickCore/string_.h"
     60 #include "MagickCore/module.h"
     61 
     62 /*
     64   Forward declarations.
     65 */
     66 static MagickBooleanType
     67   WriteMASKImage(const ImageInfo *,Image *,ExceptionInfo *);
     68 
     69 /*
     71 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     72 %                                                                             %
     73 %                                                                             %
     74 %                                                                             %
     75 %   R e a d M A S K I m a g e                                                 %
     76 %                                                                             %
     77 %                                                                             %
     78 %                                                                             %
     79 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     80 %
     81 %  ReadMASKImage returns the image mask associated with the image.
     82 %
     83 %  The format of the ReadMASKImage method is:
     84 %
     85 %      Image *ReadMASKImage(const ImageInfo *image_info,
     86 %        ExceptionInfo *exception)
     87 %
     88 %  A description of each parameter follows:
     89 %
     90 %    o image_info: the image info.
     91 %
     92 %    o exception: return any errors or warnings in this structure.
     93 %
     94 */
     95 static Image *ReadMASKImage(const ImageInfo *image_info,
     96   ExceptionInfo *exception)
     97 {
     98   Image
     99     *image;
    100 
    101   ImageInfo
    102     *read_info;
    103 
    104   /*
    105     Initialize Image structure.
    106   */
    107   assert(image_info != (const ImageInfo *) NULL);
    108   assert(image_info->signature == MagickCoreSignature);
    109   if (image_info->debug != MagickFalse)
    110     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    111       image_info->filename);
    112   assert(exception != (ExceptionInfo *) NULL);
    113   assert(exception->signature == MagickCoreSignature);
    114   read_info=CloneImageInfo(image_info);
    115   SetImageInfoBlob(read_info,(void *) NULL,0);
    116   (void) CopyMagickString(read_info->magick,"MIFF",MagickPathExtent);
    117   image=ReadImage(read_info,exception);
    118   read_info=DestroyImageInfo(read_info);
    119   if (image != (Image *) NULL)
    120     {
    121       MagickBooleanType
    122         status;
    123 
    124       status=GrayscaleImage(image,image->intensity,exception);
    125       if (status == MagickFalse)
    126         image=DestroyImage(image);
    127     }
    128   return(GetFirstImageInList(image));
    129 }
    130 
    131 /*
    133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    134 %                                                                             %
    135 %                                                                             %
    136 %                                                                             %
    137 %   R e g i s t e r M A S K I m a g e                                         %
    138 %                                                                             %
    139 %                                                                             %
    140 %                                                                             %
    141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    142 %
    143 %  RegisterMASKImage() adds attributes for the MASK image format to
    144 %  the list of supported formats.  The attributes include the image format
    145 %  tag, a method to read and/or write the format, whether the format
    146 %  supports the saving of more than one frame to the same file or blob,
    147 %  whether the format supports native in-memory I/O, and a brief
    148 %  description of the format.
    149 %
    150 %  The format of the RegisterMASKImage method is:
    151 %
    152 %      size_t RegisterMASKImage(void)
    153 %
    154 */
    155 ModuleExport size_t RegisterMASKImage(void)
    156 {
    157   MagickInfo
    158     *entry;
    159 
    160   entry=AcquireMagickInfo("MASK","MASK","Image Clip Mask");
    161   entry->decoder=(DecodeImageHandler *) ReadMASKImage;
    162   entry->encoder=(EncodeImageHandler *) WriteMASKImage;
    163   (void) RegisterMagickInfo(entry);
    164   return(MagickImageCoderSignature);
    165 }
    166 
    167 /*
    169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    170 %                                                                             %
    171 %                                                                             %
    172 %                                                                             %
    173 %   U n r e g i s t e r M A S K I m a g e                                     %
    174 %                                                                             %
    175 %                                                                             %
    176 %                                                                             %
    177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    178 %
    179 %  UnregisterMASKImage() removes format registrations made by the
    180 %  MASK module from the list of supported formats.
    181 %
    182 %  The format of the UnregisterMASKImage method is:
    183 %
    184 %      UnregisterMASKImage(void)
    185 %
    186 */
    187 ModuleExport void UnregisterMASKImage(void)
    188 {
    189   (void) UnregisterMagickInfo("MASK");
    190 }
    191 
    192 /*
    194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    195 %                                                                             %
    196 %                                                                             %
    197 %                                                                             %
    198 %   W r i t e M A S K I m a g e                                               %
    199 %                                                                             %
    200 %                                                                             %
    201 %                                                                             %
    202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    203 %
    204 %  WriteMASKImage() writes an image mask to a file.
    205 %
    206 %  The format of the WriteMASKImage method is:
    207 %
    208 %      MagickBooleanType WriteMASKImage(const ImageInfo *image_info,
    209 %        Image *image,ExceptionInfo *exception)
    210 %
    211 %  A description of each parameter follows.
    212 %
    213 %    o image_info: the image info.
    214 %
    215 %    o image:  The image.
    216 %
    217 %    o exception: return any errors or warnings in this structure.
    218 %
    219 */
    220 
    221 static Image *MaskImage(const Image *image,ExceptionInfo *exception)
    222 {
    223   CacheView
    224     *image_view,
    225     *mask_view;
    226 
    227   Image
    228     *mask_image;
    229 
    230   MagickBooleanType
    231     status;
    232 
    233   ssize_t
    234     y;
    235 
    236   mask_image=CloneImage(image,image->columns,image->rows,MagickTrue,
    237     exception);
    238   if (mask_image == (Image *) NULL)
    239     return((Image *) NULL);
    240   if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
    241     {
    242       mask_image=DestroyImage(mask_image);
    243       return((Image *) NULL);
    244     }
    245   mask_image->alpha_trait=UndefinedPixelTrait;
    246   (void) SetImageColorspace(mask_image,GRAYColorspace,exception);
    247   /*
    248     Mask image.
    249   */
    250   status=MagickTrue;
    251   image_view=AcquireVirtualCacheView(image,exception);
    252   mask_view=AcquireAuthenticCacheView(mask_image,exception);
    253   for (y=0; y < (ssize_t) image->rows; y++)
    254   {
    255     register const Quantum
    256       *magick_restrict p;
    257 
    258     register Quantum
    259       *magick_restrict q;
    260 
    261     register ssize_t
    262       x;
    263 
    264     if (status == MagickFalse)
    265       continue;
    266     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
    267     q=QueueCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
    268       exception);
    269     if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
    270       {
    271         status=MagickFalse;
    272         continue;
    273       }
    274     for (x=0; x < (ssize_t) image->columns; x++)
    275     {
    276       SetPixelChannel(mask_image,GrayPixelChannel,0,q);
    277       SetPixelChannel(mask_image,GrayPixelChannel,GetPixelReadMask(image,p),q);
    278       p+=GetPixelChannels(image);
    279       q+=GetPixelChannels(mask_image);
    280     }
    281     if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
    282       status=MagickFalse;
    283   }
    284   mask_view=DestroyCacheView(mask_view);
    285   image_view=DestroyCacheView(image_view);
    286   if (status == MagickFalse)
    287     mask_image=DestroyImage(mask_image);
    288   return(mask_image);
    289 }
    290 
    291 static MagickBooleanType WriteMASKImage(const ImageInfo *image_info,
    292   Image *image,ExceptionInfo *exception)
    293 {
    294   Image
    295     *mask_image;
    296 
    297   ImageInfo
    298     *write_info;
    299 
    300   MagickBooleanType
    301     status;
    302 
    303   mask_image=MaskImage(image,exception);
    304   if (mask_image == (Image *) NULL)
    305     return(MagickFalse);
    306   (void) CopyMagickString(mask_image->filename,image->filename,
    307     MagickPathExtent);
    308   write_info=CloneImageInfo(image_info);
    309   *write_info->magick='\0';
    310   (void) SetImageInfo(write_info,1,exception);
    311   if ((*write_info->magick == '\0') ||
    312       (LocaleCompare(write_info->magick,"MASK") == 0))
    313     (void) FormatLocaleString(mask_image->filename,MagickPathExtent,"miff:%s",
    314       write_info->filename);
    315   status=WriteImage(write_info,mask_image,exception);
    316   mask_image=DestroyImage(mask_image);
    317   write_info=DestroyImageInfo(write_info);
    318   return(status);
    319 }
    320