Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                        X   X  TTTTT  RRRR   N   N                           %
      7 %                         X X     T    R   R  NN  N                           %
      8 %                          X      T    RRRR   N N N                           %
      9 %                         X X     T    R R    N  NN                           %
     10 %                        X   X    T    R  R   N   N                           %
     11 %                                                                             %
     12 %                                                                             %
     13 %                    ImageMagickObject BLOB Interface.                        %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                             William Radcliffe                               %
     17 %                                 May 2001                                    %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2019 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 %    https://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 %  This coder is a kind of backdoor used by the COM object that allows it to  %
     38 %  pass blobs back and forth using the coder interface. It simply encodes and %
     39 %  decodes the filename as a comma delimited string and extracts the info it  %
     40 %  needs.                                                                     %
     41 %
     42 %
     43 */
     44 
     45 /*
     47   Include declarations.
     48 */
     49 #include "MagickCore/studio.h"
     50 #include "MagickCore/blob.h"
     51 #include "MagickCore/blob-private.h"
     52 #include "MagickCore/constitute.h"
     53 #include "MagickCore/delegate.h"
     54 #include "MagickCore/exception.h"
     55 #include "MagickCore/exception-private.h"
     56 #include "MagickCore/image.h"
     57 #include "MagickCore/image-private.h"
     58 #include "MagickCore/list.h"
     59 #include "MagickCore/magick.h"
     60 #include "MagickCore/magick-private.h"
     61 #include "MagickCore/memory_.h"
     62 #include "MagickCore/module.h"
     63 #include "MagickCore/static.h"
     64 #include "MagickCore/string_.h"
     65 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
     66 #define WIN32_LEAN_AND_MEAN
     67 #define VC_EXTRALEAN
     68 #include <windows.h>
     69 #include <ole2.h>
     70 
     71 /*
     73   Forward declarations.
     74 */
     75 static MagickBooleanType
     76   WriteXTRNImage(const ImageInfo *,Image *,ExceptionInfo *exception);
     77 #endif
     78 
     79 /*
     81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     82 %                                                                             %
     83 %                                                                             %
     84 %                                                                             %
     85 %   R e a d X T R N I m a g e                                                 %
     86 %                                                                             %
     87 %                                                                             %
     88 %                                                                             %
     89 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     90 %
     91 %  ReadXTRNImage() reads a XTRN image file and returns it.  It
     92 %  allocates the memory necessary for the new Image structure and returns a
     93 %  pointer to the new image.
     94 %
     95 %  The format of the ReadXTRNImage method is:
     96 %
     97 %      Image *ReadXTRNImage(const ImageInfo *image_info,
     98 %        ExceptionInfo *exception)
     99 %
    100 %  A description of each parameter follows:
    101 %
    102 %    o image_info: Specifies a pointer to an ImageInfo structure.
    103 %
    104 %    o exception: return any errors or warnings in this structure.
    105 %
    106 */
    107 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
    108 static Image *ReadXTRNImage(const ImageInfo *image_info,
    109   ExceptionInfo *exception)
    110 {
    111   char
    112     *blob_data,
    113     filename[MagickPathExtent];
    114 
    115   HRESULT
    116     hr;
    117 
    118   Image
    119     *image;
    120 
    121   ImageInfo
    122     *clone_info;
    123 
    124   long
    125     lBoundl,
    126     lBoundu;
    127 
    128   SAFEARRAY
    129     *pSafeArray;
    130 
    131   size_t
    132     blob_length;
    133 
    134   void
    135     *param1;
    136 
    137   param1=(void *) NULL;
    138   image=(Image *) NULL;
    139   clone_info=CloneImageInfo(image_info);
    140   if (clone_info->filename == NULL)
    141     {
    142       clone_info=DestroyImageInfo(clone_info);
    143       ThrowReaderException(FileOpenWarning,"No filename specified");
    144     }
    145   *filename='\0';
    146   (void) sscanf(clone_info->filename,"%p,%2048s",&param1,filename);
    147   hr=S_OK;
    148   pSafeArray=(SAFEARRAY *) param1;
    149   if (pSafeArray)
    150     {
    151       hr=SafeArrayGetLBound(pSafeArray,1,&lBoundl);
    152       if (SUCCEEDED(hr))
    153         {
    154           hr=SafeArrayGetUBound(pSafeArray,1,&lBoundu);
    155           if (SUCCEEDED(hr))
    156             {
    157               blob_length=lBoundu-lBoundl+1;
    158               hr=SafeArrayAccessData(pSafeArray,(void**) &blob_data);
    159               if (SUCCEEDED(hr))
    160                 {
    161                   *clone_info->filename='\0';
    162                   *clone_info->magick='\0';
    163                   if (*filename != '\0')
    164                     (void) CopyMagickString(clone_info->filename,filename,
    165                       MagickPathExtent);
    166                   image=BlobToImage(clone_info,blob_data,blob_length,
    167                     exception);
    168                   hr=SafeArrayUnaccessData(pSafeArray);
    169                   CatchException(exception);
    170                 }
    171             }
    172         }
    173     }
    174   clone_info=DestroyImageInfo(clone_info);
    175   return(image);
    176 }
    177 #endif
    178 
    179 /*
    181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    182 %                                                                             %
    183 %                                                                             %
    184 %                                                                             %
    185 %   R e g i s t e r X T R N I m a g e                                         %
    186 %                                                                             %
    187 %                                                                             %
    188 %                                                                             %
    189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    190 %
    191 %  RegisterXTRNImage() adds attributes for the XTRN image format to
    192 %  the list of supported formats.  The attributes include the image format
    193 %  tag, a method to read and/or write the format, whether the format
    194 %  supports the saving of more than one frame to the same file or blob,
    195 %  whether the format supports native in-memory I/O, and a brief
    196 %  description of the format.
    197 %
    198 %  The format of the RegisterXTRNImage method is:
    199 %
    200 %      size_t RegisterXTRNImage(void)
    201 %
    202 */
    203 ModuleExport size_t RegisterXTRNImage(void)
    204 {
    205   MagickInfo
    206     *entry;
    207 
    208   entry=AcquireMagickInfo("XTRN","XTRNARRAY",
    209     "External transfer via a smart array interface");
    210 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
    211   entry->decoder=ReadXTRNImage;
    212   entry->encoder=WriteXTRNImage;
    213 #endif
    214   entry->flags^=CoderAdjoinFlag;
    215   entry->flags|=CoderStealthFlag;
    216   RegisterMagickInfo(entry);
    217   return(MagickImageCoderSignature);
    218 }
    219 
    220 /*
    222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    223 %                                                                             %
    224 %                                                                             %
    225 %                                                                             %
    226 %   U n r e g i s t e r X T R N I m a g e                                     %
    227 %                                                                             %
    228 %                                                                             %
    229 %                                                                             %
    230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    231 %
    232 %  UnregisterXTRNImage() removes format registrations made by the
    233 %  XTRN module from the list of supported formats.
    234 %
    235 %  The format of the UnregisterXTRNImage method is:
    236 %
    237 %      UnregisterXTRNImage(void)
    238 %
    239 */
    240 ModuleExport void UnregisterXTRNImage(void)
    241 {
    242   UnregisterMagickInfo("XTRNARRAY");
    243 }
    244 
    245 /*
    247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    248 %                                                                             %
    249 %                                                                             %
    250 %                                                                             %
    251 %   W r i t e X T R N I m a g e                                               %
    252 %                                                                             %
    253 %                                                                             %
    254 %                                                                             %
    255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    256 %
    257 %  WriteXTRNImage() writes an image in the XTRN encoded image format.
    258 %  We use GIF because it is the only format that is compressed without
    259 %  requiring additional optional delegates (TIFF, ZIP, etc).
    260 %
    261 %  The format of the WriteXTRNImage method is:
    262 %
    263 %      MagickBooleanType WriteXTRNImage(const ImageInfo *image_info,
    264 %        Image *image,ExceptionInfo *exception)
    265 %
    266 %  A description of each parameter follows.
    267 %
    268 %    o image_info: Specifies a pointer to an ImageInfo structure.
    269 %
    270 %    o image:  A pointer to a Image structure.
    271 %
    272 %    o exception: return any errors or warnings in this structure.
    273 %
    274 */
    275 
    276 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
    277 static size_t SafeArrayFifo(const Image *image,const void *data,
    278   const size_t length)
    279 {
    280   SAFEARRAYBOUND NewArrayBounds[1];  /* 1 Dimension */
    281   size_t tlen=length;
    282   SAFEARRAY *pSafeArray = (SAFEARRAY *)image->client_data;
    283   if (pSafeArray != NULL)
    284   {
    285     long lBoundl, lBoundu, lCount;
    286     HRESULT hr = S_OK;
    287     /* First see how big the buffer currently is */
    288     hr = SafeArrayGetLBound(pSafeArray, 1, &lBoundl);
    289     if (FAILED(hr))
    290       return MagickFalse;
    291     hr = SafeArrayGetUBound(pSafeArray, 1, &lBoundu);
    292     if (FAILED(hr))
    293       return MagickFalse;
    294     lCount = lBoundu - lBoundl + 1;
    295 
    296     if (length>0)
    297     {
    298       unsigned char       *pReturnBuffer = NULL;
    299       NewArrayBounds[0].lLbound = 0;   /* Start-Index 0 */
    300       NewArrayBounds[0].cElements = (unsigned long) (length+lCount);  /* # Elemente */
    301       hr = SafeArrayRedim(pSafeArray, NewArrayBounds);
    302       if (FAILED(hr))
    303         return 0;
    304       hr = SafeArrayAccessData(pSafeArray, (void**)&pReturnBuffer);
    305       if( FAILED(hr) )
    306         return 0;
    307       (void) memcpy(pReturnBuffer+lCount,(unsigned char *) data,length);
    308       hr=SafeArrayUnaccessData(pSafeArray);
    309       if(FAILED(hr))
    310         return 0;
    311     }
    312     else
    313     {
    314       /* Adjust the length of the buffer to fit */
    315     }
    316   }
    317   return(tlen);
    318 }
    319 
    320 static MagickBooleanType WriteXTRNImage(const ImageInfo *image_info,
    321   Image *image,ExceptionInfo *exception)
    322 {
    323   char
    324     filename[MagickPathExtent];
    325 
    326   Image
    327     *p;
    328 
    329   ImageInfo
    330     *clone_info;
    331 
    332   int
    333     scene;
    334 
    335   MagickBooleanType
    336     status;
    337 
    338   size_t
    339     blob_length;
    340 
    341   unsigned char
    342     *blob_data;
    343 
    344   void
    345     *param1;
    346 
    347   param1 = (void *) NULL;
    348   status=MagickTrue;
    349   clone_info=CloneImageInfo(image_info);
    350   if (*clone_info->filename != '\0')
    351     {
    352       (void) sscanf(clone_info->filename,"%p,%2048s",&param1,filename);
    353       image->client_data=param1;
    354       scene=0;
    355       (void) CopyMagickString(clone_info->filename,filename,
    356         MagickPathExtent);
    357       for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
    358       {
    359         (void) CopyMagickString(p->filename,filename,MagickPathExtent);
    360         p->scene=scene++;
    361       }
    362       SetImageInfo(clone_info,1,exception);
    363       (void) CopyMagickString(image->magick,clone_info->magick,
    364         MagickPathExtent);
    365       blob_data=ImageToBlob(clone_info,image,&blob_length,
    366         exception);
    367       if (blob_data == (unsigned char *) NULL)
    368         status=MagickFalse;
    369       else
    370         SafeArrayFifo(image,blob_data,blob_length);
    371       if (status == MagickFalse)
    372         CatchImageException(image);
    373     }
    374   clone_info=DestroyImageInfo(clone_info);
    375   return(MagickTrue);
    376 }
    377 #endif
    378