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