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