Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %              SSSSS  TTTTT  EEEEE   GGGG   AAA   N   N   OOO                 %
      7 %              SS       T    E      G      A   A  NN  N  O   O                %
      8 %               SSS     T    EEE    G  GG  AAAAA  N N N  O   O                %
      9 %                 SS    T    E      G   G  A   A  N  NN  O   O                %
     10 %              SSSSS    T    EEEEE   GGG   A   A  N   N   OOO                 %
     11 %                                                                             %
     12 %                                                                             %
     13 %                       Write A Steganographic 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/blob.h"
     45 #include "MagickCore/blob-private.h"
     46 #include "MagickCore/cache.h"
     47 #include "MagickCore/colormap.h"
     48 #include "MagickCore/constitute.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/monitor.h"
     57 #include "MagickCore/monitor-private.h"
     58 #include "MagickCore/pixel-accessor.h"
     59 #include "MagickCore/quantum-private.h"
     60 #include "MagickCore/static.h"
     61 #include "MagickCore/string_.h"
     62 #include "MagickCore/module.h"
     63 
     64 /*
     66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     67 %                                                                             %
     68 %                                                                             %
     69 %                                                                             %
     70 %   R e a d S T E G A N O I m a g e                                           %
     71 %                                                                             %
     72 %                                                                             %
     73 %                                                                             %
     74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     75 %
     76 %  ReadSTEGANOImage() reads a steganographic image hidden within another
     77 %  image type.  It allocates the memory necessary for the new Image structure
     78 %  and returns a pointer to the new image.
     79 %
     80 %  The format of the ReadSTEGANOImage method is:
     81 %
     82 %      Image *ReadSTEGANOImage(const ImageInfo *image_info,
     83 %        ExceptionInfo *exception)
     84 %
     85 %  A description of each parameter follows:
     86 %
     87 %    o image_info: the image info.
     88 %
     89 %    o exception: return any errors or warnings in this structure.
     90 %
     91 */
     92 static Image *ReadSTEGANOImage(const ImageInfo *image_info,
     93   ExceptionInfo *exception)
     94 {
     95 #define GetBit(alpha,i) (((size_t) (alpha) >> (size_t) (i)) & 0x01)
     96 #define SetBit(i,set) SetPixelIndex(image,(Quantum) ((set) != 0 ? \
     97   (size_t) GetPixelIndex(image,q) | (one << (size_t) (i)) : \
     98   (size_t) GetPixelIndex(image,q) & ~(one << (size_t) (i))),q)
     99 
    100   Image
    101     *image,
    102     *watermark;
    103 
    104   ImageInfo
    105     *read_info;
    106 
    107   int
    108     c;
    109 
    110   MagickBooleanType
    111     status;
    112 
    113   PixelInfo
    114     pixel;
    115 
    116   register Quantum
    117     *q;
    118 
    119   register ssize_t
    120     x;
    121 
    122   size_t
    123     depth,
    124     one;
    125 
    126   ssize_t
    127     i,
    128     j,
    129     k,
    130     y;
    131 
    132   /*
    133     Initialize Image structure.
    134   */
    135   assert(image_info != (const ImageInfo *) NULL);
    136   assert(image_info->signature == MagickCoreSignature);
    137   if (image_info->debug != MagickFalse)
    138     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    139       image_info->filename);
    140   assert(exception != (ExceptionInfo *) NULL);
    141   assert(exception->signature == MagickCoreSignature);
    142   one=1;
    143   image=AcquireImage(image_info,exception);
    144   if ((image->columns == 0) || (image->rows == 0))
    145     ThrowReaderException(OptionError,"MustSpecifyImageSize");
    146   read_info=CloneImageInfo(image_info);
    147   SetImageInfoBlob(read_info,(void *) NULL,0);
    148   *read_info->magick='\0';
    149   watermark=ReadImage(read_info,exception);
    150   read_info=DestroyImageInfo(read_info);
    151   if (watermark == (Image *) NULL)
    152     return((Image *) NULL);
    153   watermark->depth=MAGICKCORE_QUANTUM_DEPTH;
    154   if (AcquireImageColormap(image,MaxColormapSize,exception) == MagickFalse)
    155     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    156   if (image_info->ping != MagickFalse)
    157     {
    158       (void) CloseBlob(image);
    159       return(GetFirstImageInList(image));
    160     }
    161   status=SetImageExtent(image,image->columns,image->rows,exception);
    162   if (status == MagickFalse)
    163     return(DestroyImageList(image));
    164   for (y=0; y < (ssize_t) image->rows; y++)
    165   {
    166     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    167     if (q == (Quantum *) NULL)
    168       break;
    169     for (x=0; x < (ssize_t) image->columns; x++)
    170     {
    171       SetPixelIndex(image,0,q);
    172       q+=GetPixelChannels(image);
    173     }
    174     if (SyncAuthenticPixels(image,exception) == MagickFalse)
    175       break;
    176   }
    177   /*
    178     Get hidden watermark from low-order bits of image.
    179   */
    180   c=0;
    181   i=0;
    182   j=0;
    183   i=(ssize_t) (watermark->depth-1);
    184   depth=watermark->depth;
    185   for (k=image->offset; (i >= 0) && (j < (ssize_t) depth); i--)
    186   {
    187     for (y=0; (y < (ssize_t) image->rows) && (j < (ssize_t) depth); y++)
    188     {
    189       x=0;
    190       for ( ; (x < (ssize_t) image->columns) && (j < (ssize_t) depth); x++)
    191       {
    192         if ((k/(ssize_t) watermark->columns) >= (ssize_t) watermark->rows)
    193           break;
    194         (void) GetOneVirtualPixelInfo(watermark,UndefinedVirtualPixelMethod,
    195           k % (ssize_t) watermark->columns,k/(ssize_t) watermark->columns,
    196           &pixel,exception);
    197         q=GetAuthenticPixels(image,x,y,1,1,exception);
    198         if (q == (Quantum *) NULL)
    199           break;
    200         switch (c)
    201         {
    202           case 0:
    203           {
    204             SetBit(i,GetBit(pixel.red,j));
    205             break;
    206           }
    207           case 1:
    208           {
    209             SetBit(i,GetBit(pixel.green,j));
    210             break;
    211           }
    212           case 2:
    213           {
    214             SetBit(i,GetBit(pixel.blue,j));
    215             break;
    216           }
    217         }
    218         if (SyncAuthenticPixels(image,exception) == MagickFalse)
    219           break;
    220         c++;
    221         if (c == 3)
    222           c=0;
    223         k++;
    224         if (k == (ssize_t) (watermark->columns*watermark->columns))
    225           k=0;
    226         if (k == image->offset)
    227           j++;
    228       }
    229     }
    230     status=SetImageProgress(image,LoadImagesTag,(MagickOffsetType) i,depth);
    231     if (status == MagickFalse)
    232       break;
    233   }
    234   watermark=DestroyImage(watermark);
    235   (void) SyncImage(image,exception);
    236   return(GetFirstImageInList(image));
    237 }
    238 
    239 /*
    241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    242 %                                                                             %
    243 %                                                                             %
    244 %                                                                             %
    245 %   R e g i s t e r S T E G A N O I m a g e                                   %
    246 %                                                                             %
    247 %                                                                             %
    248 %                                                                             %
    249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    250 %
    251 %  RegisterSTEGANOImage() adds attributes for the STEGANO image format to
    252 %  the list of supported formats.  The attributes include the image format
    253 %  tag, a method to read and/or write the format, whether the format
    254 %  supports the saving of more than one frame to the same file or blob,
    255 %  whether the format supports native in-memory I/O, and a brief
    256 %  description of the format.
    257 %
    258 %  The format of the RegisterSTEGANOImage method is:
    259 %
    260 %      size_t RegisterSTEGANOImage(void)
    261 %
    262 */
    263 ModuleExport size_t RegisterSTEGANOImage(void)
    264 {
    265   MagickInfo
    266     *entry;
    267 
    268   entry=AcquireMagickInfo("STEGANO","STEGANO","Steganographic image");
    269   entry->decoder=(DecodeImageHandler *) ReadSTEGANOImage;
    270   entry->format_type=ImplicitFormatType;
    271   (void) RegisterMagickInfo(entry);
    272   return(MagickImageCoderSignature);
    273 }
    274 
    275 /*
    277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    278 %                                                                             %
    279 %                                                                             %
    280 %                                                                             %
    281 %   U n r e g i s t e r S T E G A N O I m a g e                               %
    282 %                                                                             %
    283 %                                                                             %
    284 %                                                                             %
    285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    286 %
    287 %  UnregisterSTEGANOImage() removes format registrations made by the
    288 %  STEGANO module from the list of supported formats.
    289 %
    290 %  The format of the UnregisterSTEGANOImage method is:
    291 %
    292 %      UnregisterSTEGANOImage(void)
    293 %
    294 */
    295 ModuleExport void UnregisterSTEGANOImage(void)
    296 {
    297   (void) UnregisterMagickInfo("STEGANO");
    298 }
    299