2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % ImageMagickObject BLOB Interface. %
20 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % https://www.imagemagick.org/script/license.php %
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. %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
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
72 static MagickBooleanType
73 WriteXTRNImage(const ImageInfo *,Image *,ExceptionInfo *exception);
77 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 % R e a d X T R N I m a g e %
85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
91 % The format of the ReadXTRNImage method is:
93 % Image *ReadXTRNImage(const ImageInfo *image_info,
94 % ExceptionInfo *exception)
96 % A description of each parameter follows:
98 % o image_info: Specifies a pointer to an ImageInfo structure.
100 % o exception: return any errors or warnings in this structure.
103 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
104 static Image *ReadXTRNImage(const ImageInfo *image_info,
105 ExceptionInfo *exception)
109 filename[MagickPathExtent];
133 param1=(void *) NULL;
134 image=(Image *) NULL;
135 clone_info=CloneImageInfo(image_info);
136 if (clone_info->filename == NULL)
138 clone_info=DestroyImageInfo(clone_info);
139 ThrowReaderException(FileOpenWarning,"No filename specified");
142 (void) sscanf(clone_info->filename,"%p,%2048s",¶m1,filename);
144 pSafeArray=(SAFEARRAY *) param1;
147 hr=SafeArrayGetLBound(pSafeArray,1,&lBoundl);
150 hr=SafeArrayGetUBound(pSafeArray,1,&lBoundu);
153 blob_length=lBoundu-lBoundl+1;
154 hr=SafeArrayAccessData(pSafeArray,(void**) &blob_data);
157 *clone_info->filename='\0';
158 *clone_info->magick='\0';
159 if (*filename != '\0')
160 (void) CopyMagickString(clone_info->filename,filename,
162 image=BlobToImage(clone_info,blob_data,blob_length,
164 hr=SafeArrayUnaccessData(pSafeArray);
165 CatchException(exception);
170 clone_info=DestroyImageInfo(clone_info);
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 % R e g i s t e r X T R N I m a g e %
184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
193 % The format of the RegisterXTRNImage method is:
195 % size_t RegisterXTRNImage(void)
198 ModuleExport size_t RegisterXTRNImage(void)
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;
209 entry->flags^=CoderAdjoinFlag;
210 entry->flags|=CoderStealthFlag;
211 RegisterMagickInfo(entry);
212 return(MagickImageCoderSignature);
216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 % U n r e g i s t e r X T R N I m a g e %
224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226 % UnregisterXTRNImage() removes format registrations made by the
227 % XTRN module from the list of supported formats.
229 % The format of the UnregisterXTRNImage method is:
231 % UnregisterXTRNImage(void)
234 ModuleExport void UnregisterXTRNImage(void)
236 UnregisterMagickInfo("XTRNARRAY");
240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244 % W r i t e X T R N I m a g e %
248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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).
254 % The format of the WriteXTRNImage method is:
256 % MagickBooleanType WriteXTRNImage(const ImageInfo *image_info,
257 % Image *image,ExceptionInfo *exception)
259 % A description of each parameter follows.
261 % o image_info: Specifies a pointer to an ImageInfo structure.
263 % o image: A pointer to a Image structure.
265 % o exception: return any errors or warnings in this structure.
269 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
270 static size_t SafeArrayFifo(const Image *image,const void *data,
273 SAFEARRAYBOUND NewArrayBounds[1]; /* 1 Dimension */
275 SAFEARRAY *pSafeArray = (SAFEARRAY *)image->client_data;
276 if (pSafeArray != NULL)
278 long lBoundl, lBoundu, lCount;
280 /* First see how big the buffer currently is */
281 hr = SafeArrayGetLBound(pSafeArray, 1, &lBoundl);
284 hr = SafeArrayGetUBound(pSafeArray, 1, &lBoundu);
287 lCount = lBoundu - lBoundl + 1;
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);
297 hr = SafeArrayAccessData(pSafeArray, (void**)&pReturnBuffer);
300 (void) memcpy(pReturnBuffer+lCount,(unsigned char *) data,length);
301 hr=SafeArrayUnaccessData(pSafeArray);
307 /* Adjust the length of the buffer to fit */
313 static MagickBooleanType WriteXTRNImage(const ImageInfo *image_info,
314 Image *image,ExceptionInfo *exception)
317 filename[MagickPathExtent];
340 param1 = (void *) NULL;
342 clone_info=CloneImageInfo(image_info);
343 if (*clone_info->filename != '\0')
345 (void) sscanf(clone_info->filename,"%p,%2048s",¶m1,filename);
346 image->client_data=param1;
348 (void) CopyMagickString(clone_info->filename,filename,
350 for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
352 (void) CopyMagickString(p->filename,filename,MagickPathExtent);
355 SetImageInfo(clone_info,1,exception);
356 (void) CopyMagickString(image->magick,clone_info->magick,
358 blob_data=ImageToBlob(clone_info,image,&blob_length,
360 if (blob_data == (unsigned char *) NULL)
363 SafeArrayFifo(image,blob_data,blob_length);
364 if (status == MagickFalse)
365 CatchImageException(image);
367 clone_info=DestroyImageInfo(clone_info);