2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2012 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 % http://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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #include "MagickCore/nt-base-private.h"
45 #include "MagickCore/blob.h"
46 #include "MagickCore/blob-private.h"
47 #include "MagickCore/cache.h"
48 #include "MagickCore/client.h"
49 #include "MagickCore/constitute.h"
50 #include "MagickCore/delegate.h"
51 #include "MagickCore/exception.h"
52 #include "MagickCore/exception-private.h"
53 #include "MagickCore/image-private.h"
54 #include "MagickCore/list.h"
55 #include "MagickCore/locale_.h"
56 #include "MagickCore/log.h"
57 #include "MagickCore/magick.h"
58 #include "MagickCore/memory_.h"
59 #include "MagickCore/policy.h"
60 #include "MagickCore/resource_.h"
61 #include "MagickCore/semaphore.h"
62 #include "MagickCore/string_.h"
63 #include "MagickCore/string-private.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/utility.h"
66 #include "MagickCore/utility-private.h"
67 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
68 # include <sys/mman.h>
70 #if defined(MAGICKCORE_ZLIB_DELEGATE)
73 #if defined(MAGICKCORE_BZLIB_DELEGATE)
80 #define MagickMaxBlobExtent 65541
81 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
82 # define MAP_ANONYMOUS MAP_ANON
84 #if !defined(MAP_FAILED)
85 #define MAP_FAILED ((void *) -1)
92 #define _O_BINARY O_BINARY
98 typedef union FileInfo
103 #if defined(MAGICKCORE_ZLIB_DELEGATE)
108 #if defined(MAGICKCORE_BZLIB_DELEGATE)
166 Forward declarations.
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176 + A t t a c h B l o b %
180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 % AttachBlob() attaches a blob to the BlobInfo structure.
184 % The format of the AttachBlob method is:
186 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
188 % A description of each parameter follows:
190 % o blob_info: Specifies a pointer to a BlobInfo structure.
192 % o blob: the address of a character stream in one of the image formats
193 % understood by ImageMagick.
195 % o length: This size_t integer reflects the length in bytes of the blob.
198 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
201 assert(blob_info != (BlobInfo *) NULL);
202 if (blob_info->debug != MagickFalse)
203 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
204 blob_info->length=length;
205 blob_info->extent=length;
206 blob_info->quantum=(size_t) MagickMaxBlobExtent;
208 blob_info->type=BlobStream;
209 blob_info->file_info.file=(FILE *) NULL;
210 blob_info->data=(unsigned char *) blob;
211 blob_info->mapped=MagickFalse;
215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219 + B l o b T o F i l e %
223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
225 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
226 % occurs otherwise MagickTrue.
228 % The format of the BlobToFile method is:
230 % MagickBooleanType BlobToFile(char *filename,const void *blob,
231 % const size_t length,ExceptionInfo *exception)
233 % A description of each parameter follows:
235 % o filename: Write the blob to this file.
237 % o blob: the address of a blob.
239 % o length: This length in bytes of the blob.
241 % o exception: return any errors or warnings in this structure.
245 static inline MagickSizeType MagickMin(const MagickSizeType x,
246 const MagickSizeType y)
253 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
254 const size_t length,ExceptionInfo *exception)
265 assert(filename != (const char *) NULL);
266 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
267 assert(blob != (const void *) NULL);
268 if (*filename == '\0')
269 file=AcquireUniqueFileResource(filename);
271 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
274 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
277 for (i=0; i < length; i+=count)
279 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
280 i,(MagickSizeType) SSIZE_MAX));
289 if ((file == -1) || (i < length))
291 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302 % B l o b T o I m a g e %
306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308 % BlobToImage() implements direct to memory image formats. It returns the
311 % The format of the BlobToImage method is:
313 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
314 % const size_t length,ExceptionInfo *exception)
316 % A description of each parameter follows:
318 % o image_info: the image info.
320 % o blob: the address of a character stream in one of the image formats
321 % understood by ImageMagick.
323 % o length: This size_t integer reflects the length in bytes of the blob.
325 % o exception: return any errors or warnings in this structure.
328 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
329 const size_t length,ExceptionInfo *exception)
344 assert(image_info != (ImageInfo *) NULL);
345 assert(image_info->signature == MagickSignature);
346 if (image_info->debug != MagickFalse)
347 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
348 image_info->filename);
349 assert(exception != (ExceptionInfo *) NULL);
350 if ((blob == (const void *) NULL) || (length == 0))
352 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
353 "ZeroLengthBlobNotPermitted","'%s'",image_info->filename);
354 return((Image *) NULL);
356 blob_info=CloneImageInfo(image_info);
357 blob_info->blob=(void *) blob;
358 blob_info->length=length;
359 if (*blob_info->magick == '\0')
360 (void) SetImageInfo(blob_info,0,exception);
361 magick_info=GetMagickInfo(blob_info->magick,exception);
362 if (magick_info == (const MagickInfo *) NULL)
364 blob_info=DestroyImageInfo(blob_info);
365 (void) ThrowMagickException(exception,GetMagickModule(),
366 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
367 image_info->filename);
368 return((Image *) NULL);
370 if (GetMagickBlobSupport(magick_info) != MagickFalse)
373 Native blob support for this image format.
375 (void) CopyMagickString(blob_info->filename,image_info->filename,
377 (void) CopyMagickString(blob_info->magick,image_info->magick,
379 image=ReadImage(blob_info,exception);
380 if (image != (Image *) NULL)
381 (void) DetachBlob(image->blob);
382 blob_info=DestroyImageInfo(blob_info);
386 Write blob to a temporary file on disk.
388 blob_info->blob=(void *) NULL;
390 *blob_info->filename='\0';
391 status=BlobToFile(blob_info->filename,blob,length,exception);
392 if (status == MagickFalse)
394 (void) RelinquishUniqueFileResource(blob_info->filename);
395 blob_info=DestroyImageInfo(blob_info);
396 return((Image *) NULL);
398 clone_info=CloneImageInfo(blob_info);
399 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
400 blob_info->magick,blob_info->filename);
401 image=ReadImage(clone_info,exception);
402 if (image != (Image *) NULL)
408 Restore original filenames.
410 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
412 (void) CopyMagickMemory(images->filename,image_info->filename,
413 sizeof(images->filename));
414 (void) CopyMagickMemory(images->magick_filename,image_info->filename,
415 sizeof(images->magick_filename));
416 images=GetNextImageInList(images);
419 clone_info=DestroyImageInfo(clone_info);
420 (void) RelinquishUniqueFileResource(blob_info->filename);
421 blob_info=DestroyImageInfo(blob_info);
426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430 + C l o n e B l o b I n f o %
434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
436 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
437 % blob info is NULL, a new one.
439 % The format of the CloneBlobInfo method is:
441 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
443 % A description of each parameter follows:
445 % o blob_info: the blob info.
448 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
453 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
454 if (clone_info == (BlobInfo *) NULL)
455 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
456 GetBlobInfo(clone_info);
457 if (blob_info == (BlobInfo *) NULL)
459 clone_info->length=blob_info->length;
460 clone_info->extent=blob_info->extent;
461 clone_info->synchronize=blob_info->synchronize;
462 clone_info->quantum=blob_info->quantum;
463 clone_info->mapped=blob_info->mapped;
464 clone_info->eof=blob_info->eof;
465 clone_info->offset=blob_info->offset;
466 clone_info->size=blob_info->size;
467 clone_info->exempt=blob_info->exempt;
468 clone_info->status=blob_info->status;
469 clone_info->temporary=blob_info->temporary;
470 clone_info->type=blob_info->type;
471 clone_info->file_info.file=blob_info->file_info.file;
472 clone_info->properties=blob_info->properties;
473 clone_info->stream=blob_info->stream;
474 clone_info->data=blob_info->data;
475 clone_info->debug=IsEventLogging();
476 clone_info->reference_count=1;
481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 + C l o s e B l o b %
489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491 % CloseBlob() closes a stream associated with the image.
493 % The format of the CloseBlob method is:
495 % MagickBooleanType CloseBlob(Image *image)
497 % A description of each parameter follows:
499 % o image: the image.
502 MagickExport MagickBooleanType CloseBlob(Image *image)
510 assert(image != (Image *) NULL);
511 assert(image->signature == MagickSignature);
512 if (image->debug != MagickFalse)
513 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
514 assert(image->blob != (BlobInfo *) NULL);
515 if (image->blob->type == UndefinedStream)
517 if (image->blob->synchronize != MagickFalse)
519 image->blob->size=GetBlobSize(image);
520 image->extent=image->blob->size;
521 image->blob->eof=MagickFalse;
522 if (image->blob->exempt != MagickFalse)
524 image->blob->type=UndefinedStream;
528 switch (image->blob->type)
530 case UndefinedStream:
536 status=ferror(image->blob->file_info.file);
541 #if defined(MAGICKCORE_ZLIB_DELEGATE)
542 (void) gzerror(image->blob->file_info.gzfile,&status);
548 #if defined(MAGICKCORE_BZLIB_DELEGATE)
549 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
557 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
558 switch (image->blob->type)
560 case UndefinedStream:
565 if (image->blob->synchronize != MagickFalse)
567 status=fflush(image->blob->file_info.file);
568 status=fsync(fileno(image->blob->file_info.file));
570 status=fclose(image->blob->file_info.file);
575 #if defined(MAGICKCORE_HAVE_PCLOSE)
576 status=pclose(image->blob->file_info.file);
582 #if defined(MAGICKCORE_ZLIB_DELEGATE)
583 status=gzclose(image->blob->file_info.gzfile);
589 #if defined(MAGICKCORE_BZLIB_DELEGATE)
590 BZ2_bzclose(image->blob->file_info.bzfile);
598 if (image->blob->file_info.file != (FILE *) NULL)
600 if (image->blob->synchronize != MagickFalse)
601 (void) fsync(fileno(image->blob->file_info.file));
602 status=fclose(image->blob->file_info.file);
607 (void) DetachBlob(image->blob);
608 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
609 return(image->blob->status);
613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 + D e s t r o y B l o b %
621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623 % DestroyBlob() deallocates memory associated with a blob.
625 % The format of the DestroyBlob method is:
627 % void DestroyBlob(Image *image)
629 % A description of each parameter follows:
631 % o image: the image.
634 MagickExport void DestroyBlob(Image *image)
639 assert(image != (Image *) NULL);
640 assert(image->signature == MagickSignature);
641 if (image->debug != MagickFalse)
642 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
643 assert(image->blob != (BlobInfo *) NULL);
644 assert(image->blob->signature == MagickSignature);
646 LockSemaphoreInfo(image->blob->semaphore);
647 image->blob->reference_count--;
648 assert(image->blob->reference_count >= 0);
649 if (image->blob->reference_count == 0)
651 UnlockSemaphoreInfo(image->blob->semaphore);
652 if (destroy == MagickFalse)
654 (void) CloseBlob(image);
655 if (image->blob->mapped != MagickFalse)
656 (void) UnmapBlob(image->blob->data,image->blob->length);
657 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
658 DestroySemaphoreInfo(&image->blob->semaphore);
659 image->blob->signature=(~MagickSignature);
660 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 + D e t a c h B l o b %
672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
674 % DetachBlob() detaches a blob from the BlobInfo structure.
676 % The format of the DetachBlob method is:
678 % unsigned char *DetachBlob(BlobInfo *blob_info)
680 % A description of each parameter follows:
682 % o blob_info: Specifies a pointer to a BlobInfo structure.
685 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
690 assert(blob_info != (BlobInfo *) NULL);
691 if (blob_info->debug != MagickFalse)
692 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
693 if (blob_info->mapped != MagickFalse)
694 (void) UnmapBlob(blob_info->data,blob_info->length);
695 blob_info->mapped=MagickFalse;
698 blob_info->eof=MagickFalse;
699 blob_info->exempt=MagickFalse;
700 blob_info->type=UndefinedStream;
701 blob_info->file_info.file=(FILE *) NULL;
702 data=blob_info->data;
703 blob_info->data=(unsigned char *) NULL;
704 blob_info->stream=(StreamHandler) NULL;
709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713 + D i s c a r d B l o b B y t e s %
717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719 % DiscardBlobBytes() discards bytes in a blob.
721 % The format of the DiscardBlobBytes method is:
723 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
725 % A description of each parameter follows.
727 % o image: the image.
729 % o length: the number of bytes to skip.
733 static inline const unsigned char *ReadBlobStream(Image *image,
734 const size_t length,unsigned char *data,ssize_t *count)
736 assert(count != (ssize_t *) NULL);
737 assert(image->blob != (BlobInfo *) NULL);
738 if (image->blob->type != BlobStream)
740 *count=ReadBlob(image,length,data);
743 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
746 image->blob->eof=MagickTrue;
749 data=image->blob->data+image->blob->offset;
750 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
751 image->blob->offset));
752 image->blob->offset+=(*count);
753 if (*count != (ssize_t) length)
754 image->blob->eof=MagickTrue;
758 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
759 const MagickSizeType length)
761 register MagickOffsetType
773 assert(image != (Image *) NULL);
774 assert(image->signature == MagickSignature);
776 for (i=0; i < (MagickOffsetType) length; i+=count)
778 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
779 (void) ReadBlobStream(image,quantum,buffer,&count);
787 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 + D u p l i c a t e s B l o b %
799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801 % DuplicateBlob() duplicates a blob descriptor.
803 % The format of the DuplicateBlob method is:
805 % void DuplicateBlob(Image *image,const Image *duplicate)
807 % A description of each parameter follows:
809 % o image: the image.
811 % o duplicate: the duplicate image.
814 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
816 assert(image != (Image *) NULL);
817 assert(image->signature == MagickSignature);
818 if (image->debug != MagickFalse)
819 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
820 assert(duplicate != (Image *) NULL);
821 assert(duplicate->signature == MagickSignature);
823 image->blob=ReferenceBlob(duplicate->blob);
827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
837 % EOFBlob() returns a non-zero value when EOF has been detected reading from
840 % The format of the EOFBlob method is:
842 % int EOFBlob(const Image *image)
844 % A description of each parameter follows:
846 % o image: the image.
849 MagickExport int EOFBlob(const Image *image)
851 assert(image != (Image *) NULL);
852 assert(image->signature == MagickSignature);
853 if (image->debug != MagickFalse)
854 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
855 assert(image->blob != (BlobInfo *) NULL);
856 assert(image->blob->type != UndefinedStream);
857 switch (image->blob->type)
859 case UndefinedStream:
865 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
871 image->blob->eof=MagickFalse;
876 #if defined(MAGICKCORE_BZLIB_DELEGATE)
881 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
882 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
888 image->blob->eof=MagickFalse;
894 return((int) image->blob->eof);
898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
902 + F i l e T o B l o b %
906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 % FileToBlob() returns the contents of a file as a buffer terminated with
909 % the '\0' character. The length of the buffer (not including the extra
910 % terminating '\0' character) is returned via the 'length' parameter. Free
911 % the buffer with RelinquishMagickMemory().
913 % The format of the FileToBlob method is:
915 % unsigned char *FileToBlob(const char *filename,const size_t extent,
916 % size_t *length,ExceptionInfo *exception)
918 % A description of each parameter follows:
920 % o blob: FileToBlob() returns the contents of a file as a blob. If
921 % an error occurs NULL is returned.
923 % o filename: the filename.
925 % o extent: The maximum length of the blob.
927 % o length: On return, this reflects the actual length of the blob.
929 % o exception: return any errors or warnings in this structure.
932 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
933 size_t *length,ExceptionInfo *exception)
953 assert(filename != (const char *) NULL);
954 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
955 assert(exception != (ExceptionInfo *) NULL);
958 if (LocaleCompare(filename,"-") != 0)
959 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
962 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
963 return((unsigned char *) NULL);
965 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
967 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
976 Stream is not seekable.
978 quantum=(size_t) MagickMaxBufferExtent;
979 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
980 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
981 MagickMaxBufferExtent);
982 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
983 for (i=0; blob != (unsigned char *) NULL; i+=count)
985 count=(ssize_t) read(file,blob+i,quantum);
992 if (~((size_t) i) < (quantum+1))
994 blob=(unsigned char *) RelinquishMagickMemory(blob);
997 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
999 if ((size_t) (i+count) >= extent)
1002 if (LocaleCompare(filename,"-") != 0)
1004 if (blob == (unsigned char *) NULL)
1006 (void) ThrowMagickException(exception,GetMagickModule(),
1007 ResourceLimitError,"MemoryAllocationFailed","'%s'",filename);
1008 return((unsigned char *) NULL);
1012 blob=(unsigned char *) RelinquishMagickMemory(blob);
1013 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1014 return((unsigned char *) NULL);
1016 *length=(size_t) MagickMin(i+count,extent);
1020 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
1021 blob=(unsigned char *) NULL;
1022 if (~(*length) >= (MaxTextExtent-1))
1023 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
1025 if (blob == (unsigned char *) NULL)
1028 (void) ThrowMagickException(exception,GetMagickModule(),
1029 ResourceLimitError,"MemoryAllocationFailed","'%s'",filename);
1030 return((unsigned char *) NULL);
1032 map=MapBlob(file,ReadMode,0,*length);
1033 if (map != (unsigned char *) NULL)
1035 (void) memcpy(blob,map,*length);
1036 (void) UnmapBlob(map,*length);
1040 (void) lseek(file,0,SEEK_SET);
1041 for (i=0; i < *length; i+=count)
1043 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1044 (MagickSizeType) SSIZE_MAX));
1055 blob=(unsigned char *) RelinquishMagickMemory(blob);
1056 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1057 return((unsigned char *) NULL);
1061 if (LocaleCompare(filename,"-") != 0)
1065 blob=(unsigned char *) RelinquishMagickMemory(blob);
1066 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 % F i l e T o I m a g e %
1080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1082 % FileToImage() write the contents of a file to an image.
1084 % The format of the FileToImage method is:
1086 % MagickBooleanType FileToImage(Image *,const char *filename)
1088 % A description of each parameter follows:
1090 % o image: the image.
1092 % o filename: the filename.
1096 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1097 const unsigned char *data)
1102 register unsigned char
1105 assert(image->blob != (BlobInfo *) NULL);
1106 if (image->blob->type != BlobStream)
1107 return(WriteBlob(image,length,data));
1108 assert(image->blob->type != UndefinedStream);
1109 assert(data != (void *) NULL);
1110 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1111 if (extent >= image->blob->extent)
1113 image->blob->quantum<<=1;
1114 extent=image->blob->extent+image->blob->quantum+length;
1115 if (SetBlobExtent(image,extent) == MagickFalse)
1118 q=image->blob->data+image->blob->offset;
1119 (void) memcpy(q,data,length);
1120 image->blob->offset+=length;
1121 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1122 image->blob->length=(size_t) image->blob->offset;
1123 return((ssize_t) length);
1126 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1127 ExceptionInfo *exception)
1145 assert(image != (const Image *) NULL);
1146 assert(image->signature == MagickSignature);
1147 assert(filename != (const char *) NULL);
1148 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1149 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1152 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1153 return(MagickFalse);
1155 quantum=(size_t) MagickMaxBufferExtent;
1156 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1157 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1158 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1159 if (blob == (unsigned char *) NULL)
1161 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1163 return(MagickFalse);
1167 count=(ssize_t) read(file,blob,quantum);
1174 length=(size_t) count;
1175 count=WriteBlobStream(image,length,blob);
1176 if (count != (ssize_t) length)
1178 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1184 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1185 blob=(unsigned char *) RelinquishMagickMemory(blob);
1190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1194 + G e t B l o b E r r o r %
1198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1200 % GetBlobError() returns MagickTrue if the blob associated with the specified
1201 % image encountered an error.
1203 % The format of the GetBlobError method is:
1205 % MagickBooleanType GetBlobError(const Image *image)
1207 % A description of each parameter follows:
1209 % o image: the image.
1212 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1214 assert(image != (const Image *) NULL);
1215 assert(image->signature == MagickSignature);
1216 if (image->debug != MagickFalse)
1217 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1218 return(image->blob->status);
1222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226 + G e t B l o b F i l e H a n d l e %
1230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1232 % GetBlobFileHandle() returns the file handle associated with the image blob.
1234 % The format of the GetBlobFile method is:
1236 % FILE *GetBlobFileHandle(const Image *image)
1238 % A description of each parameter follows:
1240 % o image: the image.
1243 MagickExport FILE *GetBlobFileHandle(const Image *image)
1245 assert(image != (const Image *) NULL);
1246 assert(image->signature == MagickSignature);
1247 return(image->blob->file_info.file);
1251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1255 + G e t B l o b I n f o %
1259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1261 % GetBlobInfo() initializes the BlobInfo structure.
1263 % The format of the GetBlobInfo method is:
1265 % void GetBlobInfo(BlobInfo *blob_info)
1267 % A description of each parameter follows:
1269 % o blob_info: Specifies a pointer to a BlobInfo structure.
1272 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1274 assert(blob_info != (BlobInfo *) NULL);
1275 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1276 blob_info->type=UndefinedStream;
1277 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1278 blob_info->properties.st_mtime=time((time_t *) NULL);
1279 blob_info->properties.st_ctime=time((time_t *) NULL);
1280 blob_info->debug=IsEventLogging();
1281 blob_info->reference_count=1;
1282 blob_info->semaphore=AllocateSemaphoreInfo();
1283 blob_info->signature=MagickSignature;
1287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1291 % G e t B l o b P r o p e r t i e s %
1295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1297 % GetBlobProperties() returns information about an image blob.
1299 % The format of the GetBlobProperties method is:
1301 % const struct stat *GetBlobProperties(const Image *image)
1303 % A description of each parameter follows:
1305 % o image: the image.
1308 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1310 assert(image != (Image *) NULL);
1311 assert(image->signature == MagickSignature);
1312 if (image->debug != MagickFalse)
1313 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1314 return(&image->blob->properties);
1318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1322 + G e t B l o b S i z e %
1326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1328 % GetBlobSize() returns the current length of the image file or blob; zero is
1329 % returned if the size cannot be determined.
1331 % The format of the GetBlobSize method is:
1333 % MagickSizeType GetBlobSize(const Image *image)
1335 % A description of each parameter follows:
1337 % o image: the image.
1340 MagickExport MagickSizeType GetBlobSize(const Image *image)
1345 assert(image != (Image *) NULL);
1346 assert(image->signature == MagickSignature);
1347 if (image->debug != MagickFalse)
1348 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1349 assert(image->blob != (BlobInfo *) NULL);
1351 switch (image->blob->type)
1353 case UndefinedStream:
1355 extent=image->blob->size;
1358 case StandardStream:
1360 extent=image->blob->size;
1365 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1366 extent=(MagickSizeType) image->blob->properties.st_size;
1371 extent=image->blob->size;
1380 status=GetPathAttributes(image->filename,&image->blob->properties);
1381 if (status != MagickFalse)
1382 extent=(MagickSizeType) image->blob->properties.st_size;
1389 extent=(MagickSizeType) image->blob->length;
1397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1401 + G e t B l o b S t r e a m D a t a %
1405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1407 % GetBlobStreamData() returns the stream data for the image.
1409 % The format of the GetBlobStreamData method is:
1411 % unsigned char *GetBlobStreamData(const Image *image)
1413 % A description of each parameter follows:
1415 % o image: the image.
1418 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1420 assert(image != (const Image *) NULL);
1421 assert(image->signature == MagickSignature);
1422 return(image->blob->data);
1426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1430 + G e t B l o b S t r e a m H a n d l e r %
1434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1436 % GetBlobStreamHandler() returns the stream handler for the image.
1438 % The format of the GetBlobStreamHandler method is:
1440 % StreamHandler GetBlobStreamHandler(const Image *image)
1442 % A description of each parameter follows:
1444 % o image: the image.
1447 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1449 assert(image != (const Image *) NULL);
1450 assert(image->signature == MagickSignature);
1451 if (image->debug != MagickFalse)
1452 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1453 return(image->blob->stream);
1457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1461 % I m a g e T o B l o b %
1465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1467 % ImageToBlob() implements direct to memory image formats. It returns the
1468 % image as a formatted blob and its length. The magick member of the Image
1469 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1470 % etc.). This method is the equivalent of WriteImage(), but writes the
1471 % formatted "file" to a memory buffer rather than to an actual file.
1473 % The format of the ImageToBlob method is:
1475 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1476 % size_t *length,ExceptionInfo *exception)
1478 % A description of each parameter follows:
1480 % o image_info: the image info.
1482 % o image: the image.
1484 % o length: This pointer to a size_t integer sets the initial length of the
1485 % blob. On return, it reflects the actual length of the blob.
1487 % o exception: return any errors or warnings in this structure.
1490 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1491 Image *image,size_t *length,ExceptionInfo *exception)
1505 assert(image_info != (const ImageInfo *) NULL);
1506 assert(image_info->signature == MagickSignature);
1507 if (image_info->debug != MagickFalse)
1508 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1509 image_info->filename);
1510 assert(image != (Image *) NULL);
1511 assert(image->signature == MagickSignature);
1512 assert(exception != (ExceptionInfo *) NULL);
1514 blob=(unsigned char *) NULL;
1515 blob_info=CloneImageInfo(image_info);
1516 blob_info->adjoin=MagickFalse;
1517 (void) SetImageInfo(blob_info,1,exception);
1518 if (*blob_info->magick != '\0')
1519 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1520 magick_info=GetMagickInfo(image->magick,exception);
1521 if (magick_info == (const MagickInfo *) NULL)
1523 (void) ThrowMagickException(exception,GetMagickModule(),
1524 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
1528 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1529 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1532 Native blob support for this image format.
1534 blob_info->length=0;
1535 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1536 sizeof(unsigned char));
1537 if (blob_info->blob == (void *) NULL)
1538 (void) ThrowMagickException(exception,GetMagickModule(),
1539 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
1542 (void) CloseBlob(image);
1543 image->blob->exempt=MagickTrue;
1544 *image->filename='\0';
1545 status=WriteImage(blob_info,image,exception);
1546 *length=image->blob->length;
1547 blob=DetachBlob(image->blob);
1548 if (status == MagickFalse)
1549 blob=(unsigned char *) RelinquishMagickMemory(blob);
1551 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1558 unique[MaxTextExtent];
1564 Write file to disk in blob image format.
1566 file=AcquireUniqueFileResource(unique);
1569 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1570 image_info->filename);
1574 blob_info->file=fdopen(file,"wb");
1575 if (blob_info->file != (FILE *) NULL)
1577 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1578 image->magick,unique);
1579 status=WriteImage(blob_info,image,exception);
1580 (void) fclose(blob_info->file);
1581 if (status != MagickFalse)
1582 blob=FileToBlob(image->filename,~0UL,length,exception);
1584 (void) RelinquishUniqueFileResource(unique);
1587 blob_info=DestroyImageInfo(blob_info);
1592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596 % I m a g e T o F i l e %
1600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1602 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1603 % occurs otherwise MagickTrue.
1605 % The format of the ImageToFile method is:
1607 % MagickBooleanType ImageToFile(Image *image,char *filename,
1608 % ExceptionInfo *exception)
1610 % A description of each parameter follows:
1612 % o image: the image.
1614 % o filename: Write the image to this file.
1616 % o exception: return any errors or warnings in this structure.
1619 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1620 ExceptionInfo *exception)
1625 register const unsigned char
1644 assert(image != (Image *) NULL);
1645 assert(image->signature == MagickSignature);
1646 assert(image->blob != (BlobInfo *) NULL);
1647 assert(image->blob->type != UndefinedStream);
1648 if (image->debug != MagickFalse)
1649 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1650 assert(filename != (const char *) NULL);
1651 if (*filename == '\0')
1652 file=AcquireUniqueFileResource(filename);
1654 if (LocaleCompare(filename,"-") == 0)
1655 file=fileno(stdout);
1657 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1660 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1661 return(MagickFalse);
1663 quantum=(size_t) MagickMaxBufferExtent;
1664 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1665 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
1666 MagickMaxBufferExtent);
1667 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1668 if (buffer == (unsigned char *) NULL)
1671 (void) ThrowMagickException(exception,GetMagickModule(),
1672 ResourceLimitError,"MemoryAllocationError","'%s'",filename);
1673 return(MagickFalse);
1676 p=ReadBlobStream(image,quantum,buffer,&count);
1677 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1679 length=(size_t) count;
1680 for (i=0; i < length; i+=count)
1682 count=write(file,p+i,(size_t) (length-i));
1693 if (LocaleCompare(filename,"-") != 0)
1695 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1696 if ((file == -1) || (i < length))
1698 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1699 return(MagickFalse);
1705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1709 % I m a g e s T o B l o b %
1713 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1715 % ImagesToBlob() implements direct to memory image formats. It returns the
1716 % image sequence as a blob and its length. The magick member of the ImageInfo
1717 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1719 % Note, some image formats do not permit multiple images to the same image
1720 % stream (e.g. JPEG). in this instance, just the first image of the
1721 % sequence is returned as a blob.
1723 % The format of the ImagesToBlob method is:
1725 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1726 % size_t *length,ExceptionInfo *exception)
1728 % A description of each parameter follows:
1730 % o image_info: the image info.
1732 % o images: the image list.
1734 % o length: This pointer to a size_t integer sets the initial length of the
1735 % blob. On return, it reflects the actual length of the blob.
1737 % o exception: return any errors or warnings in this structure.
1740 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1741 Image *images,size_t *length,ExceptionInfo *exception)
1755 assert(image_info != (const ImageInfo *) NULL);
1756 assert(image_info->signature == MagickSignature);
1757 if (image_info->debug != MagickFalse)
1758 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1759 image_info->filename);
1760 assert(images != (Image *) NULL);
1761 assert(images->signature == MagickSignature);
1762 assert(exception != (ExceptionInfo *) NULL);
1764 blob=(unsigned char *) NULL;
1765 blob_info=CloneImageInfo(image_info);
1766 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1768 if (*blob_info->magick != '\0')
1769 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1770 if (blob_info->adjoin == MagickFalse)
1772 blob_info=DestroyImageInfo(blob_info);
1773 return(ImageToBlob(image_info,images,length,exception));
1775 magick_info=GetMagickInfo(images->magick,exception);
1776 if (magick_info == (const MagickInfo *) NULL)
1778 (void) ThrowMagickException(exception,GetMagickModule(),
1779 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
1783 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1784 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1787 Native blob support for this images format.
1789 blob_info->length=0;
1790 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1791 sizeof(unsigned char));
1792 if (blob_info->blob == (void *) NULL)
1793 (void) ThrowMagickException(exception,GetMagickModule(),
1794 ResourceLimitError,"MemoryAllocationFailed","'%s'",images->filename);
1797 images->blob->exempt=MagickTrue;
1798 *images->filename='\0';
1799 status=WriteImages(blob_info,images,images->filename,exception);
1800 if ((status != MagickFalse) && (images->blob->length != 0))
1802 *length=images->blob->length;
1803 blob=DetachBlob(images->blob);
1804 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1812 filename[MaxTextExtent],
1813 unique[MaxTextExtent];
1819 Write file to disk in blob images format.
1821 file=AcquireUniqueFileResource(unique);
1824 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1825 image_info->filename);
1829 blob_info->file=fdopen(file,"wb");
1830 if (blob_info->file != (FILE *) NULL)
1832 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1833 images->magick,unique);
1834 status=WriteImages(blob_info,images,filename,exception);
1835 (void) fclose(blob_info->file);
1836 if (status != MagickFalse)
1837 blob=FileToBlob(images->filename,~0UL,length,exception);
1839 (void) RelinquishUniqueFileResource(unique);
1842 blob_info=DestroyImageInfo(blob_info);
1846 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1850 % I n j e c t I m a g e B l o b %
1854 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1856 % InjectImageBlob() injects the image with a copy of itself in the specified
1857 % format (e.g. inject JPEG into a PDF image).
1859 % The format of the InjectImageBlob method is:
1861 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1862 % Image *image,Image *inject_image,const char *format,
1863 % ExceptionInfo *exception)
1865 % A description of each parameter follows:
1867 % o image_info: the image info..
1869 % o image: the image.
1871 % o inject_image: inject into the image stream.
1873 % o format: the image format.
1875 % o exception: return any errors or warnings in this structure.
1878 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1879 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1882 filename[MaxTextExtent];
1915 Write inject image to a temporary file.
1917 assert(image_info != (ImageInfo *) NULL);
1918 assert(image_info->signature == MagickSignature);
1919 assert(image != (Image *) NULL);
1920 assert(image->signature == MagickSignature);
1921 if (image->debug != MagickFalse)
1922 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1923 assert(inject_image != (Image *) NULL);
1924 assert(inject_image->signature == MagickSignature);
1925 assert(exception != (ExceptionInfo *) NULL);
1926 unique_file=(FILE *) NULL;
1927 file=AcquireUniqueFileResource(filename);
1929 unique_file=fdopen(file,"wb");
1930 if ((file == -1) || (unique_file == (FILE *) NULL))
1932 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1933 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1935 return(MagickFalse);
1937 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1938 if (byte_image == (Image *) NULL)
1940 (void) fclose(unique_file);
1941 (void) RelinquishUniqueFileResource(filename);
1942 return(MagickFalse);
1944 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1946 DestroyBlob(byte_image);
1947 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1948 write_info=CloneImageInfo(image_info);
1949 SetImageInfoFile(write_info,unique_file);
1950 status=WriteImage(write_info,byte_image,exception);
1951 write_info=DestroyImageInfo(write_info);
1952 byte_image=DestroyImage(byte_image);
1953 (void) fclose(unique_file);
1954 if (status == MagickFalse)
1956 (void) RelinquishUniqueFileResource(filename);
1957 return(MagickFalse);
1960 Inject into image stream.
1962 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1965 (void) RelinquishUniqueFileResource(filename);
1966 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1967 image_info->filename);
1968 return(MagickFalse);
1970 quantum=(size_t) MagickMaxBufferExtent;
1971 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1972 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1973 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1974 if (buffer == (unsigned char *) NULL)
1976 (void) RelinquishUniqueFileResource(filename);
1977 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1980 for (i=0; ; i+=count)
1982 count=(ssize_t) read(file,buffer,quantum);
1989 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1994 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1995 (void) RelinquishUniqueFileResource(filename);
1996 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005 + I s B l o b E x e m p t %
2009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2011 % IsBlobExempt() returns true if the blob is exempt.
2013 % The format of the IsBlobExempt method is:
2015 % MagickBooleanType IsBlobExempt(const Image *image)
2017 % A description of each parameter follows:
2019 % o image: the image.
2022 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
2024 assert(image != (const Image *) NULL);
2025 assert(image->signature == MagickSignature);
2026 if (image->debug != MagickFalse)
2027 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2028 return(image->blob->exempt);
2032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2036 + I s B l o b S e e k a b l e %
2040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2042 % IsBlobSeekable() returns true if the blob is seekable.
2044 % The format of the IsBlobSeekable method is:
2046 % MagickBooleanType IsBlobSeekable(const Image *image)
2048 % A description of each parameter follows:
2050 % o image: the image.
2053 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2058 assert(image != (const Image *) NULL);
2059 assert(image->signature == MagickSignature);
2060 if (image->debug != MagickFalse)
2061 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2062 switch (image->blob->type)
2068 seekable=MagickTrue;
2073 seekable=MagickFalse;
2081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2085 + I s B l o b T e m p o r a r y %
2089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2091 % IsBlobTemporary() returns true if the blob is temporary.
2093 % The format of the IsBlobTemporary method is:
2095 % MagickBooleanType IsBlobTemporary(const Image *image)
2097 % A description of each parameter follows:
2099 % o image: the image.
2102 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2104 assert(image != (const Image *) NULL);
2105 assert(image->signature == MagickSignature);
2106 if (image->debug != MagickFalse)
2107 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2108 return(image->blob->temporary);
2112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2122 % MapBlob() creates a mapping from a file to a binary large object.
2124 % The format of the MapBlob method is:
2126 % unsigned char *MapBlob(int file,const MapMode mode,
2127 % const MagickOffsetType offset,const size_t length)
2129 % A description of each parameter follows:
2131 % o file: map this file descriptor.
2133 % o mode: ReadMode, WriteMode, or IOMode.
2135 % o offset: starting at this offset within the file.
2137 % o length: the length of the mapping is returned in this pointer.
2140 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2141 const MagickOffsetType offset,const size_t length)
2143 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2156 #if defined(MAP_ANONYMOUS)
2157 flags|=MAP_ANONYMOUS;
2159 return((unsigned char *) NULL);
2166 protection=PROT_READ;
2168 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2174 protection=PROT_WRITE;
2176 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2178 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2179 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2180 POSIX_MADV_WILLNEED);
2186 protection=PROT_READ | PROT_WRITE;
2188 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2193 if (map == (unsigned char *) MAP_FAILED)
2194 return((unsigned char *) NULL);
2201 return((unsigned char *) NULL);
2206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2210 + M S B O r d e r L o n g %
2214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2216 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2217 % most-significant byte first.
2219 % The format of the MSBOrderLong method is:
2221 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2223 % A description of each parameter follows.
2225 % o buffer: Specifies a pointer to a buffer of integers.
2227 % o length: Specifies the length of the buffer.
2230 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2235 register unsigned char
2239 assert(buffer != (unsigned char *) NULL);
2246 *buffer++=(unsigned char) c;
2250 *buffer++=(unsigned char) c;
2256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2260 + M S B O r d e r S h o r t %
2264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2266 % MSBOrderShort() converts a least-significant byte first buffer of integers
2267 % to most-significant byte first.
2269 % The format of the MSBOrderShort method is:
2271 % void MSBOrderShort(unsigned char *p,const size_t length)
2273 % A description of each parameter follows.
2275 % o p: Specifies a pointer to a buffer of integers.
2277 % o length: Specifies the length of the buffer.
2280 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2285 register unsigned char
2288 assert(p != (unsigned char *) NULL);
2295 *p++=(unsigned char) c;
2300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2310 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2311 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2312 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2313 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2314 % from a system command.
2316 % The format of the OpenBlob method is:
2318 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2319 % const BlobMode mode,ExceptionInfo *exception)
2321 % A description of each parameter follows:
2323 % o image_info: the image info.
2325 % o image: the image.
2327 % o mode: the mode for opening the file.
2330 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2331 Image *image,const BlobMode mode,ExceptionInfo *exception)
2334 extension[MaxTextExtent],
2335 filename[MaxTextExtent];
2346 assert(image_info != (ImageInfo *) NULL);
2347 assert(image_info->signature == MagickSignature);
2348 if (image_info->debug != MagickFalse)
2349 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2350 image_info->filename);
2351 assert(image != (Image *) NULL);
2352 assert(image->signature == MagickSignature);
2353 if (image_info->blob != (void *) NULL)
2355 if (image_info->stream != (StreamHandler) NULL)
2356 image->blob->stream=(StreamHandler) image_info->stream;
2357 AttachBlob(image->blob,image_info->blob,image_info->length);
2360 (void) DetachBlob(image->blob);
2363 default: type="r"; break;
2364 case ReadBlobMode: type="r"; break;
2365 case ReadBinaryBlobMode: type="rb"; break;
2366 case WriteBlobMode: type="w"; break;
2367 case WriteBinaryBlobMode: type="w+b"; break;
2368 case AppendBlobMode: type="a"; break;
2369 case AppendBinaryBlobMode: type="a+b"; break;
2372 image->blob->synchronize=image_info->synchronize;
2373 if (image_info->stream != (StreamHandler) NULL)
2375 image->blob->stream=(StreamHandler) image_info->stream;
2378 image->blob->type=FifoStream;
2386 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2387 rights=ReadPolicyRights;
2389 rights=WritePolicyRights;
2390 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2393 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2394 "NotAuthorized","'%s'",filename);
2395 return(MagickFalse);
2397 if ((LocaleCompare(filename,"-") == 0) ||
2398 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2400 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2401 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2402 if (strchr(type,'b') != (char *) NULL)
2403 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2405 image->blob->type=StandardStream;
2406 image->blob->exempt=MagickTrue;
2409 if (LocaleNCompare(filename,"fd:",3) == 0)
2412 mode[MaxTextExtent];
2416 image->blob->file_info.file=fdopen(StringToLong(filename+3),mode);
2417 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2418 if (strchr(type,'b') != (char *) NULL)
2419 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2421 image->blob->type=StandardStream;
2422 image->blob->exempt=MagickTrue;
2425 #if defined(MAGICKCORE_HAVE_POPEN)
2426 if (*filename == '|')
2429 mode[MaxTextExtent];
2432 Pipe image to or from a system command.
2434 #if defined(SIGPIPE)
2436 (void) signal(SIGPIPE,SIG_IGN);
2440 image->blob->file_info.file=(FILE *) popen_utf8(filename+1,mode);
2441 if (image->blob->file_info.file == (FILE *) NULL)
2443 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2444 return(MagickFalse);
2446 image->blob->type=PipeStream;
2447 image->blob->exempt=MagickTrue;
2451 status=GetPathAttributes(filename,&image->blob->properties);
2452 #if defined(S_ISFIFO)
2453 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2455 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2456 if (image->blob->file_info.file == (FILE *) NULL)
2458 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2459 return(MagickFalse);
2461 image->blob->type=FileStream;
2462 image->blob->exempt=MagickTrue;
2466 GetPathComponent(image->filename,ExtensionPath,extension);
2469 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2470 if ((image_info->adjoin == MagickFalse) ||
2471 (strchr(filename,'%') != (char *) NULL))
2474 Form filename for multi-part images.
2476 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2477 image->scene,filename,exception);
2478 if ((LocaleCompare(filename,image->filename) == 0) &&
2479 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2480 (GetNextImageInList(image) != (Image *) NULL)))
2483 path[MaxTextExtent];
2485 GetPathComponent(image->filename,RootPath,path);
2486 if (*extension == '\0')
2487 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2488 path,(double) image->scene);
2490 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2491 path,(double) image->scene,extension);
2493 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2494 #if defined(macintosh)
2495 SetApplicationType(filename,image_info->magick,'8BIM');
2499 if (image_info->file != (FILE *) NULL)
2501 image->blob->file_info.file=image_info->file;
2502 image->blob->type=FileStream;
2503 image->blob->exempt=MagickTrue;
2508 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2509 if (image->blob->file_info.file != (FILE *) NULL)
2517 image->blob->type=FileStream;
2518 #if defined(MAGICKCORE_HAVE_SETVBUF)
2519 (void) setvbuf(image->blob->file_info.file,(char *) NULL,
2520 (int) _IOFBF,16384);
2522 (void) ResetMagickMemory(magick,0,sizeof(magick));
2523 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2524 (void) rewind(image->blob->file_info.file);
2525 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2526 " read %.20g magic header bytes",(double) count);
2527 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2528 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2529 ((int) magick[2] == 0x08))
2531 (void) fclose(image->blob->file_info.file);
2532 image->blob->file_info.gzfile=gzopen(filename,type);
2533 if (image->blob->file_info.gzfile != (gzFile) NULL)
2534 image->blob->type=ZipStream;
2537 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2538 if (strncmp((char *) magick,"BZh",3) == 0)
2540 (void) fclose(image->blob->file_info.file);
2541 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2542 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2543 image->blob->type=BZipStream;
2546 if (image->blob->type == FileStream)
2557 sans_exception=AcquireExceptionInfo();
2558 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2559 sans_exception=DestroyExceptionInfo(sans_exception);
2560 properties=(&image->blob->properties);
2561 if ((magick_info != (const MagickInfo *) NULL) &&
2562 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2563 (properties->st_size <= MagickMaxBufferExtent))
2571 length=(size_t) properties->st_size;
2572 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,
2574 if (blob != (void *) NULL)
2577 Format supports blobs-- use memory-mapped I/O.
2579 if (image_info->file != (FILE *) NULL)
2580 image->blob->exempt=MagickFalse;
2583 (void) fclose(image->blob->file_info.file);
2584 image->blob->file_info.file=(FILE *) NULL;
2586 AttachBlob(image->blob,blob,length);
2587 image->blob->mapped=MagickTrue;
2594 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2595 if ((LocaleCompare(extension,"Z") == 0) ||
2596 (LocaleCompare(extension,"gz") == 0) ||
2597 (LocaleCompare(extension,"wmz") == 0) ||
2598 (LocaleCompare(extension,"svgz") == 0))
2600 if (mode == WriteBinaryBlobMode)
2602 image->blob->file_info.gzfile=gzopen(filename,type);
2603 if (image->blob->file_info.gzfile != (gzFile) NULL)
2604 image->blob->type=ZipStream;
2608 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2609 if (LocaleCompare(extension,"bz2") == 0)
2611 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2612 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2613 image->blob->type=BZipStream;
2618 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2619 if (image->blob->file_info.file != (FILE *) NULL)
2621 image->blob->type=FileStream;
2622 #if defined(MAGICKCORE_HAVE_SETVBUF)
2623 (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int) _IOFBF,
2628 image->blob->status=MagickFalse;
2629 if (image->blob->type != UndefinedStream)
2630 image->blob->size=GetBlobSize(image);
2633 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2634 return(MagickFalse);
2640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2650 % PingBlob() returns all the attributes of an image or image sequence except
2651 % for the pixels. It is much faster and consumes far less memory than
2652 % BlobToImage(). On failure, a NULL image is returned and exception
2653 % describes the reason for the failure.
2655 % The format of the PingBlob method is:
2657 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2658 % const size_t length,ExceptionInfo *exception)
2660 % A description of each parameter follows:
2662 % o image_info: the image info.
2664 % o blob: the address of a character stream in one of the image formats
2665 % understood by ImageMagick.
2667 % o length: This size_t integer reflects the length in bytes of the blob.
2669 % o exception: return any errors or warnings in this structure.
2673 #if defined(__cplusplus) || defined(c_plusplus)
2677 static size_t PingStream(const Image *magick_unused(image),
2678 const void *magick_unused(pixels),const size_t columns)
2683 #if defined(__cplusplus) || defined(c_plusplus)
2687 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2688 const size_t length,ExceptionInfo *exception)
2696 assert(image_info != (ImageInfo *) NULL);
2697 assert(image_info->signature == MagickSignature);
2698 if (image_info->debug != MagickFalse)
2699 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2700 image_info->filename);
2701 assert(exception != (ExceptionInfo *) NULL);
2702 if ((blob == (const void *) NULL) || (length == 0))
2704 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2705 "UnrecognizedImageFormat","'%s'",image_info->magick);
2706 return((Image *) NULL);
2708 ping_info=CloneImageInfo(image_info);
2709 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2710 if (ping_info->blob == (const void *) NULL)
2712 (void) ThrowMagickException(exception,GetMagickModule(),
2713 ResourceLimitFatalError,"MemoryAllocationFailed","'%s'","");
2714 return((Image *) NULL);
2716 (void) memcpy(ping_info->blob,blob,length);
2717 ping_info->length=length;
2718 ping_info->ping=MagickTrue;
2719 image=ReadStream(ping_info,&PingStream,exception);
2720 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2721 ping_info=DestroyImageInfo(ping_info);
2726 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2736 % ReadBlob() reads data from the blob or image file and returns it. It
2737 % returns the number of bytes read.
2739 % The format of the ReadBlob method is:
2741 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2743 % A description of each parameter follows:
2745 % o image: the image.
2747 % o length: Specifies an integer representing the number of bytes to read
2750 % o data: Specifies an area to place the information requested from the
2754 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2755 unsigned char *data)
2760 register unsigned char
2766 assert(image != (Image *) NULL);
2767 assert(image->signature == MagickSignature);
2768 assert(image->blob != (BlobInfo *) NULL);
2769 assert(image->blob->type != UndefinedStream);
2772 assert(data != (void *) NULL);
2775 switch (image->blob->type)
2777 case UndefinedStream:
2779 case StandardStream:
2781 count=(ssize_t) read(fileno(image->blob->file_info.file),q,length);
2791 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
2796 c=getc(image->blob->file_info.file);
2799 *q++=(unsigned char) c;
2804 c=getc(image->blob->file_info.file);
2807 *q++=(unsigned char) c;
2817 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2822 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
2823 (unsigned int) length);
2828 c=gzgetc(image->blob->file_info.gzfile);
2831 *q++=(unsigned char) c;
2836 c=gzgetc(image->blob->file_info.gzfile);
2839 *q++=(unsigned char) c;
2850 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2851 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,
2860 register const unsigned char
2863 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2865 image->blob->eof=MagickTrue;
2868 p=image->blob->data+image->blob->offset;
2869 count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
2870 image->blob->offset));
2871 image->blob->offset+=count;
2872 if (count != (ssize_t) length)
2873 image->blob->eof=MagickTrue;
2874 (void) memcpy(q,p,(size_t) count);
2882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2886 + R e a d B l o b B y t e %
2890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2892 % ReadBlobByte() reads a single byte from the image file and returns it.
2894 % The format of the ReadBlobByte method is:
2896 % int ReadBlobByte(Image *image)
2898 % A description of each parameter follows.
2900 % o image: the image.
2903 MagickExport int ReadBlobByte(Image *image)
2905 register const unsigned char
2914 assert(image != (Image *) NULL);
2915 assert(image->signature == MagickSignature);
2916 p=ReadBlobStream(image,1,buffer,&count);
2923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2927 + R e a d B l o b D o u b l e %
2931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2933 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2934 % specified by the endian member of the image structure.
2936 % The format of the ReadBlobDouble method is:
2938 % double ReadBlobDouble(Image *image)
2940 % A description of each parameter follows.
2942 % o image: the image.
2945 MagickExport double ReadBlobDouble(Image *image)
2956 quantum.double_value=0.0;
2957 quantum.unsigned_value=ReadBlobLongLong(image);
2958 return(quantum.double_value);
2962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2966 + R e a d B l o b F l o a t %
2970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2972 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2973 % specified by the endian member of the image structure.
2975 % The format of the ReadBlobFloat method is:
2977 % float ReadBlobFloat(Image *image)
2979 % A description of each parameter follows.
2981 % o image: the image.
2984 MagickExport float ReadBlobFloat(Image *image)
2995 quantum.float_value=0.0;
2996 quantum.unsigned_value=ReadBlobLong(image);
2997 return(quantum.float_value);
3001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3005 + R e a d B l o b L o n g %
3009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3011 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
3012 % specified by the endian member of the image structure.
3014 % The format of the ReadBlobLong method is:
3016 % unsigned int ReadBlobLong(Image *image)
3018 % A description of each parameter follows.
3020 % o image: the image.
3023 MagickExport unsigned int ReadBlobLong(Image *image)
3025 register const unsigned char
3037 assert(image != (Image *) NULL);
3038 assert(image->signature == MagickSignature);
3040 p=ReadBlobStream(image,4,buffer,&count);
3043 if (image->endian == LSBEndian)
3045 value=(unsigned int) (*p++);
3046 value|=((unsigned int) (*p++)) << 8;
3047 value|=((unsigned int) (*p++)) << 16;
3048 value|=((unsigned int) (*p++)) << 24;
3051 value=((unsigned int) (*p++)) << 24;
3052 value|=((unsigned int) (*p++)) << 16;
3053 value|=((unsigned int) (*p++)) << 8;
3054 value|=((unsigned int) (*p++));
3059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3063 + R e a d B l o b L o n g L o n g %
3067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3069 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3070 % byte-order specified by the endian member of the image structure.
3072 % The format of the ReadBlobLongLong method is:
3074 % MagickSizeType ReadBlobLongLong(Image *image)
3076 % A description of each parameter follows.
3078 % o image: the image.
3081 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3086 register const unsigned char
3095 assert(image != (Image *) NULL);
3096 assert(image->signature == MagickSignature);
3098 p=ReadBlobStream(image,8,buffer,&count);
3100 return(MagickULLConstant(0));
3101 if (image->endian == LSBEndian)
3103 value=(MagickSizeType) (*p++);
3104 value|=((MagickSizeType) (*p++)) << 8;
3105 value|=((MagickSizeType) (*p++)) << 16;
3106 value|=((MagickSizeType) (*p++)) << 24;
3107 value|=((MagickSizeType) (*p++)) << 32;
3108 value|=((MagickSizeType) (*p++)) << 40;
3109 value|=((MagickSizeType) (*p++)) << 48;
3110 value|=((MagickSizeType) (*p++)) << 56;
3111 return(value & MagickULLConstant(0xffffffffffffffff));
3113 value=((MagickSizeType) (*p++)) << 56;
3114 value|=((MagickSizeType) (*p++)) << 48;
3115 value|=((MagickSizeType) (*p++)) << 40;
3116 value|=((MagickSizeType) (*p++)) << 32;
3117 value|=((MagickSizeType) (*p++)) << 24;
3118 value|=((MagickSizeType) (*p++)) << 16;
3119 value|=((MagickSizeType) (*p++)) << 8;
3120 value|=((MagickSizeType) (*p++));
3121 return(value & MagickULLConstant(0xffffffffffffffff));
3125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3129 + R e a d B l o b S h o r t %
3133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3135 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3136 % specified by the endian member of the image structure.
3138 % The format of the ReadBlobShort method is:
3140 % unsigned short ReadBlobShort(Image *image)
3142 % A description of each parameter follows.
3144 % o image: the image.
3147 MagickExport unsigned short ReadBlobShort(Image *image)
3149 register const unsigned char
3152 register unsigned int
3161 assert(image != (Image *) NULL);
3162 assert(image->signature == MagickSignature);
3164 p=ReadBlobStream(image,2,buffer,&count);
3166 return((unsigned short) 0U);
3167 if (image->endian == LSBEndian)
3169 value=(unsigned int) (*p++);
3170 value|=((unsigned int) (*p++)) << 8;
3171 return((unsigned short) (value & 0xffff));
3173 value=(unsigned int) ((*p++) << 8);
3174 value|=(unsigned int) (*p++);
3175 return((unsigned short) (value & 0xffff));
3179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3183 + R e a d B l o b L S B L o n g %
3187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3189 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3190 % least-significant byte first order.
3192 % The format of the ReadBlobLSBLong method is:
3194 % unsigned int ReadBlobLSBLong(Image *image)
3196 % A description of each parameter follows.
3198 % o image: the image.
3201 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3203 register const unsigned char
3206 register unsigned int
3215 assert(image != (Image *) NULL);
3216 assert(image->signature == MagickSignature);
3218 p=ReadBlobStream(image,4,buffer,&count);
3221 value=(unsigned int) (*p++);
3222 value|=((unsigned int) (*p++)) << 8;
3223 value|=((unsigned int) (*p++)) << 16;
3224 value|=((unsigned int) (*p++)) << 24;
3229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3233 + R e a d B l o b L S B S h o r t %
3237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3239 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3240 % least-significant byte first order.
3242 % The format of the ReadBlobLSBShort method is:
3244 % unsigned short ReadBlobLSBShort(Image *image)
3246 % A description of each parameter follows.
3248 % o image: the image.
3251 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3253 register const unsigned char
3256 register unsigned int
3265 assert(image != (Image *) NULL);
3266 assert(image->signature == MagickSignature);
3268 p=ReadBlobStream(image,2,buffer,&count);
3270 return((unsigned short) 0U);
3271 value=(unsigned int) (*p++);
3272 value|=((unsigned int) ((*p++)) << 8);
3273 return((unsigned short) (value & 0xffff));
3277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3281 + R e a d B l o b M S B L o n g %
3285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3287 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3288 % most-significant byte first order.
3290 % The format of the ReadBlobMSBLong method is:
3292 % unsigned int ReadBlobMSBLong(Image *image)
3294 % A description of each parameter follows.
3296 % o image: the image.
3299 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3301 register const unsigned char
3304 register unsigned int
3313 assert(image != (Image *) NULL);
3314 assert(image->signature == MagickSignature);
3316 p=ReadBlobStream(image,4,buffer,&count);
3319 value=((unsigned int) (*p++) << 24);
3320 value|=((unsigned int) (*p++) << 16);
3321 value|=((unsigned int) (*p++) << 8);
3322 value|=(unsigned int) (*p++);
3327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3331 + R e a d B l o b M S B L o n g L o n g %
3335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3337 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3338 % most-significant byte first order.
3340 % The format of the ReadBlobMSBLongLong method is:
3342 % unsigned int ReadBlobMSBLongLong(Image *image)
3344 % A description of each parameter follows.
3346 % o image: the image.
3349 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3351 register const unsigned char
3354 register MagickSizeType
3363 assert(image != (Image *) NULL);
3364 assert(image->signature == MagickSignature);
3366 p=ReadBlobStream(image,8,buffer,&count);
3368 return(MagickULLConstant(0));
3369 value=((MagickSizeType) (*p++)) << 56;
3370 value|=((MagickSizeType) (*p++)) << 48;
3371 value|=((MagickSizeType) (*p++)) << 40;
3372 value|=((MagickSizeType) (*p++)) << 32;
3373 value|=((MagickSizeType) (*p++)) << 24;
3374 value|=((MagickSizeType) (*p++)) << 16;
3375 value|=((MagickSizeType) (*p++)) << 8;
3376 value|=((MagickSizeType) (*p++));
3377 return(value & MagickULLConstant(0xffffffffffffffff));
3381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3385 + R e a d B l o b M S B S h o r t %
3389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3391 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3392 % most-significant byte first order.
3394 % The format of the ReadBlobMSBShort method is:
3396 % unsigned short ReadBlobMSBShort(Image *image)
3398 % A description of each parameter follows.
3400 % o image: the image.
3403 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3405 register const unsigned char
3408 register unsigned int
3417 assert(image != (Image *) NULL);
3418 assert(image->signature == MagickSignature);
3420 p=ReadBlobStream(image,2,buffer,&count);
3422 return((unsigned short) 0U);
3423 value=(unsigned int) ((*p++) << 8);
3424 value|=(unsigned int) (*p++);
3425 return((unsigned short) (value & 0xffff));
3429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3433 + R e a d B l o b S t r i n g %
3437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3439 % ReadBlobString() reads characters from a blob or file until a newline
3440 % character is read or an end-of-file condition is encountered.
3442 % The format of the ReadBlobString method is:
3444 % char *ReadBlobString(Image *image,char *string)
3446 % A description of each parameter follows:
3448 % o image: the image.
3450 % o string: the address of a character buffer.
3453 MagickExport char *ReadBlobString(Image *image,char *string)
3455 register const unsigned char
3467 assert(image != (Image *) NULL);
3468 assert(image->signature == MagickSignature);
3469 for (i=0; i < (MaxTextExtent-1L); i++)
3471 p=ReadBlobStream(image,1,buffer,&count);
3475 return((char *) NULL);
3478 string[i]=(char) (*p);
3479 if ((string[i] == '\r') || (string[i] == '\n'))
3482 if (string[i] == '\r')
3483 (void) ReadBlobStream(image,1,buffer,&count);
3489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3493 + R e f e r e n c e B l o b %
3497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3499 % ReferenceBlob() increments the reference count associated with the pixel
3500 % blob returning a pointer to the blob.
3502 % The format of the ReferenceBlob method is:
3504 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3506 % A description of each parameter follows:
3508 % o blob_info: the blob_info.
3511 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3513 assert(blob != (BlobInfo *) NULL);
3514 assert(blob->signature == MagickSignature);
3515 if (blob->debug != MagickFalse)
3516 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3517 LockSemaphoreInfo(blob->semaphore);
3518 blob->reference_count++;
3519 UnlockSemaphoreInfo(blob->semaphore);
3524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3534 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3535 % and returns the resulting offset.
3537 % The format of the SeekBlob method is:
3539 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3542 % A description of each parameter follows:
3544 % o image: the image.
3546 % o offset: Specifies an integer representing the offset in bytes.
3548 % o whence: Specifies an integer representing how the offset is
3549 % treated relative to the beginning of the blob as follows:
3551 % SEEK_SET Set position equal to offset bytes.
3552 % SEEK_CUR Set position to current location plus offset.
3553 % SEEK_END Set position to EOF plus offset.
3556 MagickExport MagickOffsetType SeekBlob(Image *image,
3557 const MagickOffsetType offset,const int whence)
3559 assert(image != (Image *) NULL);
3560 assert(image->signature == MagickSignature);
3561 if (image->debug != MagickFalse)
3562 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3563 assert(image->blob != (BlobInfo *) NULL);
3564 assert(image->blob->type != UndefinedStream);
3565 switch (image->blob->type)
3567 case UndefinedStream:
3569 case StandardStream:
3573 if (fseek(image->blob->file_info.file,offset,whence) < 0)
3575 image->blob->offset=TellBlob(image);
3581 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3582 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
3585 image->blob->offset=TellBlob(image);
3601 image->blob->offset=offset;
3606 if ((image->blob->offset+offset) < 0)
3608 image->blob->offset+=offset;
3613 if (((MagickOffsetType) image->blob->length+offset) < 0)
3615 image->blob->offset=image->blob->length+offset;
3619 if (image->blob->offset <= (MagickOffsetType)
3620 ((off_t) image->blob->length))
3621 image->blob->eof=MagickFalse;
3623 if (image->blob->mapped != MagickFalse)
3627 image->blob->extent=(size_t) (image->blob->offset+
3628 image->blob->quantum);
3629 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3630 image->blob->data,image->blob->extent+1,
3631 sizeof(*image->blob->data));
3632 (void) SyncBlob(image);
3633 if (image->blob->data == (unsigned char *) NULL)
3635 (void) DetachBlob(image->blob);
3642 return(image->blob->offset);
3646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3650 + S e t B l o b E x e m p t %
3654 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3656 % SetBlobExempt() sets the blob exempt status.
3658 % The format of the SetBlobExempt method is:
3660 % MagickBooleanType SetBlobExempt(const Image *image,
3661 % const MagickBooleanType exempt)
3663 % A description of each parameter follows:
3665 % o image: the image.
3667 % o exempt: Set to true if this blob is exempt from being closed.
3670 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3672 assert(image != (const Image *) NULL);
3673 assert(image->signature == MagickSignature);
3674 if (image->debug != MagickFalse)
3675 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3676 image->blob->exempt=exempt;
3680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3684 + S e t B l o b E x t e n t %
3688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3690 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3691 % method is successful, subsequent writes to bytes in the specified range are
3692 % guaranteed not to fail.
3694 % The format of the SetBlobExtent method is:
3696 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3698 % A description of each parameter follows:
3700 % o image: the image.
3702 % o extent: the blob maximum extent.
3705 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3706 const MagickSizeType extent)
3708 assert(image != (Image *) NULL);
3709 assert(image->signature == MagickSignature);
3710 if (image->debug != MagickFalse)
3711 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3712 assert(image->blob != (BlobInfo *) NULL);
3713 assert(image->blob->type != UndefinedStream);
3714 switch (image->blob->type)
3716 case UndefinedStream:
3718 case StandardStream:
3719 return(MagickFalse);
3722 if (extent != (MagickSizeType) ((off_t) extent))
3723 return(MagickFalse);
3724 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3725 return(MagickFalse);
3734 offset=TellBlob(image);
3735 status=posix_fallocate(fileno(image->blob->file_info.file),
3736 (off_t) offset,(off_t) (extent-offset));
3738 return(MagickFalse);
3745 return(MagickFalse);
3747 return(MagickFalse);
3749 return(MagickFalse);
3752 if (image->blob->mapped != MagickFalse)
3754 if (image->blob->file_info.file == (FILE *) NULL)
3755 return(MagickFalse);
3756 (void) UnmapBlob(image->blob->data,image->blob->length);
3757 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3758 return(MagickFalse);
3767 offset=TellBlob(image);
3768 status=posix_fallocate(fileno(image->blob->file_info.file),
3769 (off_t) offset,(off_t) (extent-offset));
3771 return(MagickFalse);
3773 image->blob->data=(unsigned char*) MapBlob(fileno(
3774 image->blob->file_info.file),WriteMode,0,(size_t) extent);
3775 image->blob->extent=(size_t) extent;
3776 image->blob->length=(size_t) extent;
3777 (void) SyncBlob(image);
3781 if (extent != (MagickSizeType) ((size_t) extent))
3782 return(MagickFalse);
3783 image->blob->extent=(size_t) extent;
3784 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3785 image->blob->extent+1,sizeof(*image->blob->data));
3786 (void) SyncBlob(image);
3787 if (image->blob->data == (unsigned char *) NULL)
3789 (void) DetachBlob(image->blob);
3790 return(MagickFalse);
3799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3809 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3810 % attributes if it is an blob.
3812 % The format of the SyncBlob method is:
3814 % int SyncBlob(Image *image)
3816 % A description of each parameter follows:
3818 % o image: the image.
3821 static int SyncBlob(Image *image)
3826 assert(image != (Image *) NULL);
3827 assert(image->signature == MagickSignature);
3828 if (image->debug != MagickFalse)
3829 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3830 assert(image->blob != (BlobInfo *) NULL);
3831 assert(image->blob->type != UndefinedStream);
3833 switch (image->blob->type)
3835 case UndefinedStream:
3836 case StandardStream:
3841 status=fflush(image->blob->file_info.file);
3846 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3847 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
3853 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3854 status=BZ2_bzflush(image->blob->file_info.bzfile);
3862 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3863 if (image->blob->mapped != MagickFalse)
3864 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3883 % TellBlob() obtains the current value of the blob or file position.
3885 % The format of the TellBlob method is:
3887 % MagickOffsetType TellBlob(const Image *image)
3889 % A description of each parameter follows:
3891 % o image: the image.
3894 MagickExport MagickOffsetType TellBlob(const Image *image)
3899 assert(image != (Image *) NULL);
3900 assert(image->signature == MagickSignature);
3901 if (image->debug != MagickFalse)
3902 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3903 assert(image->blob != (BlobInfo *) NULL);
3904 assert(image->blob->type != UndefinedStream);
3906 switch (image->blob->type)
3908 case UndefinedStream:
3909 case StandardStream:
3913 offset=ftell(image->blob->file_info.file);
3920 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3921 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
3931 offset=image->blob->offset;
3939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3943 + U n m a p B l o b %
3947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3949 % UnmapBlob() deallocates the binary large object previously allocated with
3950 % the MapBlob method.
3952 % The format of the UnmapBlob method is:
3954 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3956 % A description of each parameter follows:
3958 % o map: the address of the binary large object.
3960 % o length: the length of the binary large object.
3963 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3965 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3969 status=munmap(map,length);
3970 return(status == -1 ? MagickFalse : MagickTrue);
3974 return(MagickFalse);
3979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3983 + W r i t e B l o b %
3987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3989 % WriteBlob() writes data to a blob or image file. It returns the number of
3992 % The format of the WriteBlob method is:
3994 % ssize_t WriteBlob(Image *image,const size_t length,
3995 % const unsigned char *data)
3997 % A description of each parameter follows:
3999 % o image: the image.
4001 % o length: Specifies an integer representing the number of bytes to
4002 % write to the file.
4004 % o data: The address of the data to write to the blob or file.
4007 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4008 const unsigned char *data)
4013 register const unsigned char
4019 assert(image != (Image *) NULL);
4020 assert(image->signature == MagickSignature);
4021 assert(data != (const unsigned char *) NULL);
4022 assert(image->blob != (BlobInfo *) NULL);
4023 assert(image->blob->type != UndefinedStream);
4028 switch (image->blob->type)
4030 case UndefinedStream:
4032 case StandardStream:
4034 count=(ssize_t) write(fileno(image->blob->file_info.file),data,length);
4044 count=(ssize_t) fwrite((const char *) data,1,length,
4045 image->blob->file_info.file);
4050 c=putc((int) *p++,image->blob->file_info.file);
4057 c=putc((int) *p++,image->blob->file_info.file);
4069 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4074 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4075 (unsigned int) length);
4080 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4087 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4100 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4101 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
4108 count=(ssize_t) image->blob->stream(image,data,length);
4113 register unsigned char
4116 if ((image->blob->offset+(MagickOffsetType) length) >=
4117 (MagickOffsetType) image->blob->extent)
4119 if (image->blob->mapped != MagickFalse)
4121 image->blob->quantum<<=1;
4122 image->blob->extent+=length+image->blob->quantum;
4123 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4124 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4125 (void) SyncBlob(image);
4126 if (image->blob->data == (unsigned char *) NULL)
4128 (void) DetachBlob(image->blob);
4132 q=image->blob->data+image->blob->offset;
4133 (void) memcpy(q,p,length);
4134 image->blob->offset+=length;
4135 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4136 image->blob->length=(size_t) image->blob->offset;
4137 count=(ssize_t) length;
4144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4148 + W r i t e B l o b B y t e %
4152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4154 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4155 % written (either 0 or 1);
4157 % The format of the WriteBlobByte method is:
4159 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4161 % A description of each parameter follows.
4163 % o image: the image.
4165 % o value: Specifies the value to write.
4168 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4170 assert(image != (Image *) NULL);
4171 assert(image->signature == MagickSignature);
4172 return(WriteBlobStream(image,1,&value));
4176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4180 + W r i t e B l o b F l o a t %
4184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4186 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4187 % specified by the endian member of the image structure.
4189 % The format of the WriteBlobFloat method is:
4191 % ssize_t WriteBlobFloat(Image *image,const float value)
4193 % A description of each parameter follows.
4195 % o image: the image.
4197 % o value: Specifies the value to write.
4200 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4211 quantum.unsigned_value=0U;
4212 quantum.float_value=value;
4213 return(WriteBlobLong(image,quantum.unsigned_value));
4217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4221 + W r i t e B l o b L o n g %
4225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4227 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4228 % specified by the endian member of the image structure.
4230 % The format of the WriteBlobLong method is:
4232 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4234 % A description of each parameter follows.
4236 % o image: the image.
4238 % o value: Specifies the value to write.
4241 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4246 assert(image != (Image *) NULL);
4247 assert(image->signature == MagickSignature);
4248 if (image->endian == LSBEndian)
4250 buffer[0]=(unsigned char) value;
4251 buffer[1]=(unsigned char) (value >> 8);
4252 buffer[2]=(unsigned char) (value >> 16);
4253 buffer[3]=(unsigned char) (value >> 24);
4254 return(WriteBlobStream(image,4,buffer));
4256 buffer[0]=(unsigned char) (value >> 24);
4257 buffer[1]=(unsigned char) (value >> 16);
4258 buffer[2]=(unsigned char) (value >> 8);
4259 buffer[3]=(unsigned char) value;
4260 return(WriteBlobStream(image,4,buffer));
4264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4268 + W r i t e B l o b S h o r t %
4272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4274 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4275 % byte-order specified by the endian member of the image structure.
4277 % The format of the WriteBlobShort method is:
4279 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4281 % A description of each parameter follows.
4283 % o image: the image.
4285 % o value: Specifies the value to write.
4288 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4293 assert(image != (Image *) NULL);
4294 assert(image->signature == MagickSignature);
4295 if (image->endian == LSBEndian)
4297 buffer[0]=(unsigned char) value;
4298 buffer[1]=(unsigned char) (value >> 8);
4299 return(WriteBlobStream(image,2,buffer));
4301 buffer[0]=(unsigned char) (value >> 8);
4302 buffer[1]=(unsigned char) value;
4303 return(WriteBlobStream(image,2,buffer));
4307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4311 + W r i t e B l o b L S B L o n g %
4315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4317 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4318 % least-significant byte first order.
4320 % The format of the WriteBlobLSBLong method is:
4322 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4324 % A description of each parameter follows.
4326 % o image: the image.
4328 % o value: Specifies the value to write.
4331 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4336 assert(image != (Image *) NULL);
4337 assert(image->signature == MagickSignature);
4338 buffer[0]=(unsigned char) value;
4339 buffer[1]=(unsigned char) (value >> 8);
4340 buffer[2]=(unsigned char) (value >> 16);
4341 buffer[3]=(unsigned char) (value >> 24);
4342 return(WriteBlobStream(image,4,buffer));
4346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4350 + W r i t e B l o b L S B S h o r t %
4354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4356 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4357 % least-significant byte first order.
4359 % The format of the WriteBlobLSBShort method is:
4361 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4363 % A description of each parameter follows.
4365 % o image: the image.
4367 % o value: Specifies the value to write.
4370 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4375 assert(image != (Image *) NULL);
4376 assert(image->signature == MagickSignature);
4377 buffer[0]=(unsigned char) value;
4378 buffer[1]=(unsigned char) (value >> 8);
4379 return(WriteBlobStream(image,2,buffer));
4383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4387 + W r i t e B l o b M S B L o n g %
4391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4393 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4394 % most-significant byte first order.
4396 % The format of the WriteBlobMSBLong method is:
4398 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4400 % A description of each parameter follows.
4402 % o value: Specifies the value to write.
4404 % o image: the image.
4407 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4412 assert(image != (Image *) NULL);
4413 assert(image->signature == MagickSignature);
4414 buffer[0]=(unsigned char) (value >> 24);
4415 buffer[1]=(unsigned char) (value >> 16);
4416 buffer[2]=(unsigned char) (value >> 8);
4417 buffer[3]=(unsigned char) value;
4418 return(WriteBlobStream(image,4,buffer));
4422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4426 + W r i t e B l o b M S B L o n g L o n g %
4430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4432 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4433 % most-significant byte first order.
4435 % The format of the WriteBlobMSBLongLong method is:
4437 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4439 % A description of each parameter follows.
4441 % o value: Specifies the value to write.
4443 % o image: the image.
4446 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4447 const MagickSizeType value)
4452 assert(image != (Image *) NULL);
4453 assert(image->signature == MagickSignature);
4454 buffer[0]=(unsigned char) (value >> 56);
4455 buffer[1]=(unsigned char) (value >> 48);
4456 buffer[2]=(unsigned char) (value >> 40);
4457 buffer[3]=(unsigned char) (value >> 32);
4458 buffer[4]=(unsigned char) (value >> 24);
4459 buffer[5]=(unsigned char) (value >> 16);
4460 buffer[6]=(unsigned char) (value >> 8);
4461 buffer[7]=(unsigned char) value;
4462 return(WriteBlobStream(image,8,buffer));
4466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4470 + W r i t e B l o b M S B S h o r t %
4474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4476 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4477 % most-significant byte first order.
4479 % The format of the WriteBlobMSBShort method is:
4481 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4483 % A description of each parameter follows.
4485 % o value: Specifies the value to write.
4487 % o file: Specifies the file to write the data to.
4490 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4495 assert(image != (Image *) NULL);
4496 assert(image->signature == MagickSignature);
4497 buffer[0]=(unsigned char) (value >> 8);
4498 buffer[1]=(unsigned char) value;
4499 return(WriteBlobStream(image,2,buffer));
4503 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4507 + W r i t e B l o b S t r i n g %
4511 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4513 % WriteBlobString() write a string to a blob. It returns the number of
4514 % characters written.
4516 % The format of the WriteBlobString method is:
4518 % ssize_t WriteBlobString(Image *image,const char *string)
4520 % A description of each parameter follows.
4522 % o image: the image.
4524 % o string: Specifies the string to write.
4527 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4529 assert(image != (Image *) NULL);
4530 assert(image->signature == MagickSignature);
4531 assert(string != (const char *) NULL);
4532 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));