2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2013 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_ZLIB_DELEGATE)
70 #if defined(MAGICKCORE_BZLIB_DELEGATE)
77 #define MagickMaxBlobExtent 65541
78 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
79 # define MAP_ANONYMOUS MAP_ANON
81 #if !defined(MAP_FAILED)
82 #define MAP_FAILED ((void *) -1)
89 #define _O_BINARY O_BINARY
95 typedef union FileInfo
100 #if defined(MAGICKCORE_ZLIB_DELEGATE)
105 #if defined(MAGICKCORE_BZLIB_DELEGATE)
163 Forward declarations.
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 + A t t a c h B l o b %
177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179 % AttachBlob() attaches a blob to the BlobInfo structure.
181 % The format of the AttachBlob method is:
183 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
185 % A description of each parameter follows:
187 % o blob_info: Specifies a pointer to a BlobInfo structure.
189 % o blob: the address of a character stream in one of the image formats
190 % understood by ImageMagick.
192 % o length: This size_t integer reflects the length in bytes of the blob.
195 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
198 assert(blob_info != (BlobInfo *) NULL);
199 if (blob_info->debug != MagickFalse)
200 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
201 blob_info->length=length;
202 blob_info->extent=length;
203 blob_info->quantum=(size_t) MagickMaxBlobExtent;
205 blob_info->type=BlobStream;
206 blob_info->file_info.file=(FILE *) NULL;
207 blob_info->data=(unsigned char *) blob;
208 blob_info->mapped=MagickFalse;
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216 + B l o b T o F i l e %
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
223 % occurs otherwise MagickTrue.
225 % The format of the BlobToFile method is:
227 % MagickBooleanType BlobToFile(char *filename,const void *blob,
228 % const size_t length,ExceptionInfo *exception)
230 % A description of each parameter follows:
232 % o filename: Write the blob to this file.
234 % o blob: the address of a blob.
236 % o length: This length in bytes of the blob.
238 % o exception: return any errors or warnings in this structure.
242 static inline MagickSizeType MagickMin(const MagickSizeType x,
243 const MagickSizeType y)
250 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
251 const size_t length,ExceptionInfo *exception)
262 assert(filename != (const char *) NULL);
263 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
264 assert(blob != (const void *) NULL);
265 if (*filename == '\0')
266 file=AcquireUniqueFileResource(filename);
268 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
271 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
274 for (i=0; i < length; i+=count)
276 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
277 i,(MagickSizeType) SSIZE_MAX));
286 if ((file == -1) || (i < length))
288 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299 % B l o b T o I m a g e %
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 % BlobToImage() implements direct to memory image formats. It returns the
308 % The format of the BlobToImage method is:
310 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
311 % const size_t length,ExceptionInfo *exception)
313 % A description of each parameter follows:
315 % o image_info: the image info.
317 % o blob: the address of a character stream in one of the image formats
318 % understood by ImageMagick.
320 % o length: This size_t integer reflects the length in bytes of the blob.
322 % o exception: return any errors or warnings in this structure.
325 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
326 const size_t length,ExceptionInfo *exception)
341 assert(image_info != (ImageInfo *) NULL);
342 assert(image_info->signature == MagickSignature);
343 if (image_info->debug != MagickFalse)
344 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
345 image_info->filename);
346 assert(exception != (ExceptionInfo *) NULL);
347 if ((blob == (const void *) NULL) || (length == 0))
349 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
350 "ZeroLengthBlobNotPermitted","'%s'",image_info->filename);
351 return((Image *) NULL);
353 blob_info=CloneImageInfo(image_info);
354 blob_info->blob=(void *) blob;
355 blob_info->length=length;
356 if (*blob_info->magick == '\0')
357 (void) SetImageInfo(blob_info,0,exception);
358 magick_info=GetMagickInfo(blob_info->magick,exception);
359 if (magick_info == (const MagickInfo *) NULL)
361 blob_info=DestroyImageInfo(blob_info);
362 (void) ThrowMagickException(exception,GetMagickModule(),
363 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
364 image_info->filename);
365 return((Image *) NULL);
367 if (GetMagickBlobSupport(magick_info) != MagickFalse)
370 Native blob support for this image format.
372 (void) CopyMagickString(blob_info->filename,image_info->filename,
374 (void) CopyMagickString(blob_info->magick,image_info->magick,
376 image=ReadImage(blob_info,exception);
377 if (image != (Image *) NULL)
378 (void) DetachBlob(image->blob);
379 blob_info=DestroyImageInfo(blob_info);
383 Write blob to a temporary file on disk.
385 blob_info->blob=(void *) NULL;
387 *blob_info->filename='\0';
388 status=BlobToFile(blob_info->filename,blob,length,exception);
389 if (status == MagickFalse)
391 (void) RelinquishUniqueFileResource(blob_info->filename);
392 blob_info=DestroyImageInfo(blob_info);
393 return((Image *) NULL);
395 clone_info=CloneImageInfo(blob_info);
396 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
397 blob_info->magick,blob_info->filename);
398 image=ReadImage(clone_info,exception);
399 if (image != (Image *) NULL)
405 Restore original filenames.
407 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
409 (void) CopyMagickMemory(images->filename,image_info->filename,
410 sizeof(images->filename));
411 (void) CopyMagickMemory(images->magick_filename,image_info->filename,
412 sizeof(images->magick_filename));
413 images=GetNextImageInList(images);
416 clone_info=DestroyImageInfo(clone_info);
417 (void) RelinquishUniqueFileResource(blob_info->filename);
418 blob_info=DestroyImageInfo(blob_info);
423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
427 + C l o n e B l o b I n f o %
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
434 % blob info is NULL, a new one.
436 % The format of the CloneBlobInfo method is:
438 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
440 % A description of each parameter follows:
442 % o blob_info: the blob info.
445 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
450 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
451 if (clone_info == (BlobInfo *) NULL)
452 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
453 GetBlobInfo(clone_info);
454 if (blob_info == (BlobInfo *) NULL)
456 clone_info->length=blob_info->length;
457 clone_info->extent=blob_info->extent;
458 clone_info->synchronize=blob_info->synchronize;
459 clone_info->quantum=blob_info->quantum;
460 clone_info->mapped=blob_info->mapped;
461 clone_info->eof=blob_info->eof;
462 clone_info->offset=blob_info->offset;
463 clone_info->size=blob_info->size;
464 clone_info->exempt=blob_info->exempt;
465 clone_info->status=blob_info->status;
466 clone_info->temporary=blob_info->temporary;
467 clone_info->type=blob_info->type;
468 clone_info->file_info.file=blob_info->file_info.file;
469 clone_info->properties=blob_info->properties;
470 clone_info->stream=blob_info->stream;
471 clone_info->data=blob_info->data;
472 clone_info->debug=IsEventLogging();
473 clone_info->reference_count=1;
478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482 + C l o s e B l o b %
486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488 % CloseBlob() closes a stream associated with the image.
490 % The format of the CloseBlob method is:
492 % MagickBooleanType CloseBlob(Image *image)
494 % A description of each parameter follows:
496 % o image: the image.
499 MagickExport MagickBooleanType CloseBlob(Image *image)
507 assert(image != (Image *) NULL);
508 assert(image->signature == MagickSignature);
509 if (image->debug != MagickFalse)
510 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
511 assert(image->blob != (BlobInfo *) NULL);
512 if (image->blob->type == UndefinedStream)
514 if (image->blob->synchronize != MagickFalse)
516 image->blob->size=GetBlobSize(image);
517 image->extent=image->blob->size;
518 image->blob->eof=MagickFalse;
520 switch (image->blob->type)
522 case UndefinedStream:
528 status=ferror(image->blob->file_info.file);
533 #if defined(MAGICKCORE_ZLIB_DELEGATE)
534 (void) gzerror(image->blob->file_info.gzfile,&status);
540 #if defined(MAGICKCORE_BZLIB_DELEGATE)
541 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
549 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
550 if (image->blob->exempt != MagickFalse)
552 image->blob->type=UndefinedStream;
553 return(image->blob->status);
555 switch (image->blob->type)
557 case UndefinedStream:
562 if (image->blob->synchronize != MagickFalse)
563 status=fsync(fileno(image->blob->file_info.file));
564 status=fclose(image->blob->file_info.file);
569 #if defined(MAGICKCORE_HAVE_PCLOSE)
570 status=pclose(image->blob->file_info.file);
576 #if defined(MAGICKCORE_ZLIB_DELEGATE)
577 status=gzclose(image->blob->file_info.gzfile);
583 #if defined(MAGICKCORE_BZLIB_DELEGATE)
584 BZ2_bzclose(image->blob->file_info.bzfile);
592 if (image->blob->file_info.file != (FILE *) NULL)
594 if (image->blob->synchronize != MagickFalse)
595 (void) fsync(fileno(image->blob->file_info.file));
596 status=fclose(image->blob->file_info.file);
601 (void) DetachBlob(image->blob);
602 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
603 return(image->blob->status);
607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 + D e s t r o y B l o b %
615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 % DestroyBlob() deallocates memory associated with a blob.
619 % The format of the DestroyBlob method is:
621 % void DestroyBlob(Image *image)
623 % A description of each parameter follows:
625 % o image: the image.
628 MagickExport void DestroyBlob(Image *image)
633 assert(image != (Image *) NULL);
634 assert(image->signature == MagickSignature);
635 if (image->debug != MagickFalse)
636 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
637 assert(image->blob != (BlobInfo *) NULL);
638 assert(image->blob->signature == MagickSignature);
640 LockSemaphoreInfo(image->blob->semaphore);
641 image->blob->reference_count--;
642 assert(image->blob->reference_count >= 0);
643 if (image->blob->reference_count == 0)
645 UnlockSemaphoreInfo(image->blob->semaphore);
646 if (destroy == MagickFalse)
648 (void) CloseBlob(image);
649 if (image->blob->mapped != MagickFalse)
650 (void) UnmapBlob(image->blob->data,image->blob->length);
651 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
652 DestroySemaphoreInfo(&image->blob->semaphore);
653 image->blob->signature=(~MagickSignature);
654 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
662 + D e t a c h B l o b %
666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 % DetachBlob() detaches a blob from the BlobInfo structure.
670 % The format of the DetachBlob method is:
672 % unsigned char *DetachBlob(BlobInfo *blob_info)
674 % A description of each parameter follows:
676 % o blob_info: Specifies a pointer to a BlobInfo structure.
679 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
684 assert(blob_info != (BlobInfo *) NULL);
685 if (blob_info->debug != MagickFalse)
686 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
687 if (blob_info->mapped != MagickFalse)
688 (void) UnmapBlob(blob_info->data,blob_info->length);
689 blob_info->mapped=MagickFalse;
692 blob_info->eof=MagickFalse;
693 blob_info->exempt=MagickFalse;
694 blob_info->type=UndefinedStream;
695 blob_info->file_info.file=(FILE *) NULL;
696 data=blob_info->data;
697 blob_info->data=(unsigned char *) NULL;
698 blob_info->stream=(StreamHandler) NULL;
703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 + D i s c a r d B l o b B y t e s %
711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713 % DiscardBlobBytes() discards bytes in a blob.
715 % The format of the DiscardBlobBytes method is:
717 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
719 % A description of each parameter follows.
721 % o image: the image.
723 % o length: the number of bytes to skip.
727 static inline const unsigned char *ReadBlobStream(Image *image,
728 const size_t length,unsigned char *data,ssize_t *count)
730 assert(count != (ssize_t *) NULL);
731 assert(image->blob != (BlobInfo *) NULL);
732 if (image->blob->type != BlobStream)
734 *count=ReadBlob(image,length,data);
737 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
740 image->blob->eof=MagickTrue;
743 data=image->blob->data+image->blob->offset;
744 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
745 image->blob->offset));
746 image->blob->offset+=(*count);
747 if (*count != (ssize_t) length)
748 image->blob->eof=MagickTrue;
752 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
753 const MagickSizeType length)
755 register MagickOffsetType
767 assert(image != (Image *) NULL);
768 assert(image->signature == MagickSignature);
770 for (i=0; i < (MagickOffsetType) length; i+=count)
772 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
773 (void) ReadBlobStream(image,quantum,buffer,&count);
781 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
789 + D u p l i c a t e s B l o b %
793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 % DuplicateBlob() duplicates a blob descriptor.
797 % The format of the DuplicateBlob method is:
799 % void DuplicateBlob(Image *image,const Image *duplicate)
801 % A description of each parameter follows:
803 % o image: the image.
805 % o duplicate: the duplicate image.
808 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
810 assert(image != (Image *) NULL);
811 assert(image->signature == MagickSignature);
812 if (image->debug != MagickFalse)
813 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
814 assert(duplicate != (Image *) NULL);
815 assert(duplicate->signature == MagickSignature);
817 image->blob=ReferenceBlob(duplicate->blob);
821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831 % EOFBlob() returns a non-zero value when EOF has been detected reading from
834 % The format of the EOFBlob method is:
836 % int EOFBlob(const Image *image)
838 % A description of each parameter follows:
840 % o image: the image.
843 MagickExport int EOFBlob(const Image *image)
845 assert(image != (Image *) NULL);
846 assert(image->signature == MagickSignature);
847 if (image->debug != MagickFalse)
848 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
849 assert(image->blob != (BlobInfo *) NULL);
850 assert(image->blob->type != UndefinedStream);
851 switch (image->blob->type)
853 case UndefinedStream:
859 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
865 image->blob->eof=MagickFalse;
870 #if defined(MAGICKCORE_BZLIB_DELEGATE)
875 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
876 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
882 image->blob->eof=MagickFalse;
888 return((int) image->blob->eof);
892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
896 + F i l e T o B l o b %
900 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
902 % FileToBlob() returns the contents of a file as a buffer terminated with
903 % the '\0' character. The length of the buffer (not including the extra
904 % terminating '\0' character) is returned via the 'length' parameter. Free
905 % the buffer with RelinquishMagickMemory().
907 % The format of the FileToBlob method is:
909 % unsigned char *FileToBlob(const char *filename,const size_t extent,
910 % size_t *length,ExceptionInfo *exception)
912 % A description of each parameter follows:
914 % o blob: FileToBlob() returns the contents of a file as a blob. If
915 % an error occurs NULL is returned.
917 % o filename: the filename.
919 % o extent: The maximum length of the blob.
921 % o length: On return, this reflects the actual length of the blob.
923 % o exception: return any errors or warnings in this structure.
926 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
927 size_t *length,ExceptionInfo *exception)
947 assert(filename != (const char *) NULL);
948 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
949 assert(exception != (ExceptionInfo *) NULL);
952 if (LocaleCompare(filename,"-") != 0)
953 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
956 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
957 return((unsigned char *) NULL);
959 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
961 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
970 Stream is not seekable.
972 quantum=(size_t) MagickMaxBufferExtent;
973 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
974 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
975 MagickMaxBufferExtent);
976 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
977 for (i=0; blob != (unsigned char *) NULL; i+=count)
979 count=(ssize_t) read(file,blob+i,quantum);
986 if (~((size_t) i) < (quantum+1))
988 blob=(unsigned char *) RelinquishMagickMemory(blob);
991 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
993 if ((size_t) (i+count) >= extent)
996 if (LocaleCompare(filename,"-") != 0)
998 if (blob == (unsigned char *) NULL)
1000 (void) ThrowMagickException(exception,GetMagickModule(),
1001 ResourceLimitError,"MemoryAllocationFailed","'%s'",filename);
1002 return((unsigned char *) NULL);
1006 blob=(unsigned char *) RelinquishMagickMemory(blob);
1007 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1008 return((unsigned char *) NULL);
1010 *length=(size_t) MagickMin(i+count,extent);
1014 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
1015 blob=(unsigned char *) NULL;
1016 if (~(*length) >= (MaxTextExtent-1))
1017 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
1019 if (blob == (unsigned char *) NULL)
1022 (void) ThrowMagickException(exception,GetMagickModule(),
1023 ResourceLimitError,"MemoryAllocationFailed","'%s'",filename);
1024 return((unsigned char *) NULL);
1026 map=MapBlob(file,ReadMode,0,*length);
1027 if (map != (unsigned char *) NULL)
1029 (void) memcpy(blob,map,*length);
1030 (void) UnmapBlob(map,*length);
1034 (void) lseek(file,0,SEEK_SET);
1035 for (i=0; i < *length; i+=count)
1037 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1038 (MagickSizeType) SSIZE_MAX));
1049 blob=(unsigned char *) RelinquishMagickMemory(blob);
1050 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1051 return((unsigned char *) NULL);
1055 if (LocaleCompare(filename,"-") != 0)
1059 blob=(unsigned char *) RelinquishMagickMemory(blob);
1060 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070 % F i l e T o I m a g e %
1074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 % FileToImage() write the contents of a file to an image.
1078 % The format of the FileToImage method is:
1080 % MagickBooleanType FileToImage(Image *,const char *filename)
1082 % A description of each parameter follows:
1084 % o image: the image.
1086 % o filename: the filename.
1090 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1091 const unsigned char *data)
1096 register unsigned char
1099 assert(image->blob != (BlobInfo *) NULL);
1100 if (image->blob->type != BlobStream)
1101 return(WriteBlob(image,length,data));
1102 assert(image->blob->type != UndefinedStream);
1103 assert(data != (void *) NULL);
1104 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1105 if (extent >= image->blob->extent)
1107 image->blob->quantum<<=1;
1108 extent=image->blob->extent+image->blob->quantum+length;
1109 if (SetBlobExtent(image,extent) == MagickFalse)
1112 q=image->blob->data+image->blob->offset;
1113 (void) memcpy(q,data,length);
1114 image->blob->offset+=length;
1115 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1116 image->blob->length=(size_t) image->blob->offset;
1117 return((ssize_t) length);
1120 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1121 ExceptionInfo *exception)
1139 assert(image != (const Image *) NULL);
1140 assert(image->signature == MagickSignature);
1141 assert(filename != (const char *) NULL);
1142 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1144 if (LocaleCompare(filename,"-") != 0)
1145 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1148 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1149 return(MagickFalse);
1151 quantum=(size_t) MagickMaxBufferExtent;
1152 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1153 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1154 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1155 if (blob == (unsigned char *) NULL)
1157 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1159 return(MagickFalse);
1163 count=(ssize_t) read(file,blob,quantum);
1170 length=(size_t) count;
1171 count=WriteBlobStream(image,length,blob);
1172 if (count != (ssize_t) length)
1174 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1180 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1181 blob=(unsigned char *) RelinquishMagickMemory(blob);
1186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1190 + G e t B l o b E r r o r %
1194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1196 % GetBlobError() returns MagickTrue if the blob associated with the specified
1197 % image encountered an error.
1199 % The format of the GetBlobError method is:
1201 % MagickBooleanType GetBlobError(const Image *image)
1203 % A description of each parameter follows:
1205 % o image: the image.
1208 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1210 assert(image != (const Image *) NULL);
1211 assert(image->signature == MagickSignature);
1212 if (image->debug != MagickFalse)
1213 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1214 return(image->blob->status);
1218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1222 + G e t B l o b F i l e H a n d l e %
1226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228 % GetBlobFileHandle() returns the file handle associated with the image blob.
1230 % The format of the GetBlobFile method is:
1232 % FILE *GetBlobFileHandle(const Image *image)
1234 % A description of each parameter follows:
1236 % o image: the image.
1239 MagickExport FILE *GetBlobFileHandle(const Image *image)
1241 assert(image != (const Image *) NULL);
1242 assert(image->signature == MagickSignature);
1243 return(image->blob->file_info.file);
1247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1251 + G e t B l o b I n f o %
1255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1257 % GetBlobInfo() initializes the BlobInfo structure.
1259 % The format of the GetBlobInfo method is:
1261 % void GetBlobInfo(BlobInfo *blob_info)
1263 % A description of each parameter follows:
1265 % o blob_info: Specifies a pointer to a BlobInfo structure.
1268 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1270 assert(blob_info != (BlobInfo *) NULL);
1271 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1272 blob_info->type=UndefinedStream;
1273 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1274 blob_info->properties.st_mtime=time((time_t *) NULL);
1275 blob_info->properties.st_ctime=time((time_t *) NULL);
1276 blob_info->debug=IsEventLogging();
1277 blob_info->reference_count=1;
1278 blob_info->semaphore=AllocateSemaphoreInfo();
1279 blob_info->signature=MagickSignature;
1283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1287 % G e t B l o b P r o p e r t i e s %
1291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293 % GetBlobProperties() returns information about an image blob.
1295 % The format of the GetBlobProperties method is:
1297 % const struct stat *GetBlobProperties(const Image *image)
1299 % A description of each parameter follows:
1301 % o image: the image.
1304 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1306 assert(image != (Image *) NULL);
1307 assert(image->signature == MagickSignature);
1308 if (image->debug != MagickFalse)
1309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1310 return(&image->blob->properties);
1314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318 + G e t B l o b S i z e %
1322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1324 % GetBlobSize() returns the current length of the image file or blob; zero is
1325 % returned if the size cannot be determined.
1327 % The format of the GetBlobSize method is:
1329 % MagickSizeType GetBlobSize(const Image *image)
1331 % A description of each parameter follows:
1333 % o image: the image.
1336 MagickExport MagickSizeType GetBlobSize(const Image *image)
1341 assert(image != (Image *) NULL);
1342 assert(image->signature == MagickSignature);
1343 if (image->debug != MagickFalse)
1344 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1345 assert(image->blob != (BlobInfo *) NULL);
1347 switch (image->blob->type)
1349 case UndefinedStream:
1351 extent=image->blob->size;
1354 case StandardStream:
1356 extent=image->blob->size;
1361 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1362 extent=(MagickSizeType) image->blob->properties.st_size;
1367 extent=image->blob->size;
1376 status=GetPathAttributes(image->filename,&image->blob->properties);
1377 if (status != MagickFalse)
1378 extent=(MagickSizeType) image->blob->properties.st_size;
1385 extent=(MagickSizeType) image->blob->length;
1393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1397 + G e t B l o b S t r e a m D a t a %
1401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1403 % GetBlobStreamData() returns the stream data for the image.
1405 % The format of the GetBlobStreamData method is:
1407 % unsigned char *GetBlobStreamData(const Image *image)
1409 % A description of each parameter follows:
1411 % o image: the image.
1414 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1416 assert(image != (const Image *) NULL);
1417 assert(image->signature == MagickSignature);
1418 return(image->blob->data);
1422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1426 + G e t B l o b S t r e a m H a n d l e r %
1430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1432 % GetBlobStreamHandler() returns the stream handler for the image.
1434 % The format of the GetBlobStreamHandler method is:
1436 % StreamHandler GetBlobStreamHandler(const Image *image)
1438 % A description of each parameter follows:
1440 % o image: the image.
1443 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1445 assert(image != (const Image *) NULL);
1446 assert(image->signature == MagickSignature);
1447 if (image->debug != MagickFalse)
1448 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1449 return(image->blob->stream);
1453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1457 % I m a g e T o B l o b %
1461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1463 % ImageToBlob() implements direct to memory image formats. It returns the
1464 % image as a formatted blob and its length. The magick member of the Image
1465 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1466 % etc.). This method is the equivalent of WriteImage(), but writes the
1467 % formatted "file" to a memory buffer rather than to an actual file.
1469 % The format of the ImageToBlob method is:
1471 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1472 % size_t *length,ExceptionInfo *exception)
1474 % A description of each parameter follows:
1476 % o image_info: the image info.
1478 % o image: the image.
1480 % o length: This pointer to a size_t integer sets the initial length of the
1481 % blob. On return, it reflects the actual length of the blob.
1483 % o exception: return any errors or warnings in this structure.
1486 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1487 Image *image,size_t *length,ExceptionInfo *exception)
1501 assert(image_info != (const ImageInfo *) NULL);
1502 assert(image_info->signature == MagickSignature);
1503 if (image_info->debug != MagickFalse)
1504 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1505 image_info->filename);
1506 assert(image != (Image *) NULL);
1507 assert(image->signature == MagickSignature);
1508 assert(exception != (ExceptionInfo *) NULL);
1510 blob=(unsigned char *) NULL;
1511 blob_info=CloneImageInfo(image_info);
1512 blob_info->adjoin=MagickFalse;
1513 (void) SetImageInfo(blob_info,1,exception);
1514 if (*blob_info->magick != '\0')
1515 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1516 magick_info=GetMagickInfo(image->magick,exception);
1517 if (magick_info == (const MagickInfo *) NULL)
1519 (void) ThrowMagickException(exception,GetMagickModule(),
1520 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
1524 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1525 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1528 Native blob support for this image format.
1530 blob_info->length=0;
1531 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1532 sizeof(unsigned char));
1533 if (blob_info->blob == (void *) NULL)
1534 (void) ThrowMagickException(exception,GetMagickModule(),
1535 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
1538 (void) CloseBlob(image);
1539 image->blob->exempt=MagickTrue;
1540 *image->filename='\0';
1541 status=WriteImage(blob_info,image,exception);
1542 *length=image->blob->length;
1543 blob=DetachBlob(image->blob);
1544 if (status == MagickFalse)
1545 blob=(unsigned char *) RelinquishMagickMemory(blob);
1547 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1554 unique[MaxTextExtent];
1560 Write file to disk in blob image format.
1562 file=AcquireUniqueFileResource(unique);
1565 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1566 image_info->filename);
1570 blob_info->file=fdopen(file,"wb");
1571 if (blob_info->file != (FILE *) NULL)
1573 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1574 image->magick,unique);
1575 status=WriteImage(blob_info,image,exception);
1576 (void) fclose(blob_info->file);
1577 if (status != MagickFalse)
1578 blob=FileToBlob(image->filename,~0UL,length,exception);
1580 (void) RelinquishUniqueFileResource(unique);
1583 blob_info=DestroyImageInfo(blob_info);
1588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1592 % I m a g e T o F i l e %
1596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1598 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1599 % occurs otherwise MagickTrue.
1601 % The format of the ImageToFile method is:
1603 % MagickBooleanType ImageToFile(Image *image,char *filename,
1604 % ExceptionInfo *exception)
1606 % A description of each parameter follows:
1608 % o image: the image.
1610 % o filename: Write the image to this file.
1612 % o exception: return any errors or warnings in this structure.
1615 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1616 ExceptionInfo *exception)
1621 register const unsigned char
1640 assert(image != (Image *) NULL);
1641 assert(image->signature == MagickSignature);
1642 assert(image->blob != (BlobInfo *) NULL);
1643 assert(image->blob->type != UndefinedStream);
1644 if (image->debug != MagickFalse)
1645 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1646 assert(filename != (const char *) NULL);
1647 if (*filename == '\0')
1648 file=AcquireUniqueFileResource(filename);
1650 if (LocaleCompare(filename,"-") == 0)
1651 file=fileno(stdout);
1653 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1656 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1657 return(MagickFalse);
1659 quantum=(size_t) MagickMaxBufferExtent;
1660 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1661 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
1662 MagickMaxBufferExtent);
1663 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1664 if (buffer == (unsigned char *) NULL)
1667 (void) ThrowMagickException(exception,GetMagickModule(),
1668 ResourceLimitError,"MemoryAllocationError","'%s'",filename);
1669 return(MagickFalse);
1672 p=ReadBlobStream(image,quantum,buffer,&count);
1673 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1675 length=(size_t) count;
1676 for (i=0; i < length; i+=count)
1678 count=write(file,p+i,(size_t) (length-i));
1689 if (LocaleCompare(filename,"-") != 0)
1691 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1692 if ((file == -1) || (i < length))
1694 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1695 return(MagickFalse);
1701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1705 % I m a g e s T o B l o b %
1709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1711 % ImagesToBlob() implements direct to memory image formats. It returns the
1712 % image sequence as a blob and its length. The magick member of the ImageInfo
1713 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1715 % Note, some image formats do not permit multiple images to the same image
1716 % stream (e.g. JPEG). in this instance, just the first image of the
1717 % sequence is returned as a blob.
1719 % The format of the ImagesToBlob method is:
1721 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1722 % size_t *length,ExceptionInfo *exception)
1724 % A description of each parameter follows:
1726 % o image_info: the image info.
1728 % o images: the image list.
1730 % o length: This pointer to a size_t integer sets the initial length of the
1731 % blob. On return, it reflects the actual length of the blob.
1733 % o exception: return any errors or warnings in this structure.
1736 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1737 Image *images,size_t *length,ExceptionInfo *exception)
1751 assert(image_info != (const ImageInfo *) NULL);
1752 assert(image_info->signature == MagickSignature);
1753 if (image_info->debug != MagickFalse)
1754 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1755 image_info->filename);
1756 assert(images != (Image *) NULL);
1757 assert(images->signature == MagickSignature);
1758 assert(exception != (ExceptionInfo *) NULL);
1760 blob=(unsigned char *) NULL;
1761 blob_info=CloneImageInfo(image_info);
1762 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1764 if (*blob_info->magick != '\0')
1765 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1766 if (blob_info->adjoin == MagickFalse)
1768 blob_info=DestroyImageInfo(blob_info);
1769 return(ImageToBlob(image_info,images,length,exception));
1771 magick_info=GetMagickInfo(images->magick,exception);
1772 if (magick_info == (const MagickInfo *) NULL)
1774 (void) ThrowMagickException(exception,GetMagickModule(),
1775 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
1779 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1780 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1783 Native blob support for this images format.
1785 blob_info->length=0;
1786 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1787 sizeof(unsigned char));
1788 if (blob_info->blob == (void *) NULL)
1789 (void) ThrowMagickException(exception,GetMagickModule(),
1790 ResourceLimitError,"MemoryAllocationFailed","'%s'",images->filename);
1793 images->blob->exempt=MagickTrue;
1794 *images->filename='\0';
1795 status=WriteImages(blob_info,images,images->filename,exception);
1796 if ((status != MagickFalse) && (images->blob->length != 0))
1798 *length=images->blob->length;
1799 blob=DetachBlob(images->blob);
1800 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1808 filename[MaxTextExtent],
1809 unique[MaxTextExtent];
1815 Write file to disk in blob images format.
1817 file=AcquireUniqueFileResource(unique);
1820 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1821 image_info->filename);
1825 blob_info->file=fdopen(file,"wb");
1826 if (blob_info->file != (FILE *) NULL)
1828 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1829 images->magick,unique);
1830 status=WriteImages(blob_info,images,filename,exception);
1831 (void) fclose(blob_info->file);
1832 if (status != MagickFalse)
1833 blob=FileToBlob(images->filename,~0UL,length,exception);
1835 (void) RelinquishUniqueFileResource(unique);
1838 blob_info=DestroyImageInfo(blob_info);
1842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1846 % I n j e c t I m a g e B l o b %
1850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1852 % InjectImageBlob() injects the image with a copy of itself in the specified
1853 % format (e.g. inject JPEG into a PDF image).
1855 % The format of the InjectImageBlob method is:
1857 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1858 % Image *image,Image *inject_image,const char *format,
1859 % ExceptionInfo *exception)
1861 % A description of each parameter follows:
1863 % o image_info: the image info..
1865 % o image: the image.
1867 % o inject_image: inject into the image stream.
1869 % o format: the image format.
1871 % o exception: return any errors or warnings in this structure.
1874 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1875 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1878 filename[MaxTextExtent];
1911 Write inject image to a temporary file.
1913 assert(image_info != (ImageInfo *) NULL);
1914 assert(image_info->signature == MagickSignature);
1915 assert(image != (Image *) NULL);
1916 assert(image->signature == MagickSignature);
1917 if (image->debug != MagickFalse)
1918 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1919 assert(inject_image != (Image *) NULL);
1920 assert(inject_image->signature == MagickSignature);
1921 assert(exception != (ExceptionInfo *) NULL);
1922 unique_file=(FILE *) NULL;
1923 file=AcquireUniqueFileResource(filename);
1925 unique_file=fdopen(file,"wb");
1926 if ((file == -1) || (unique_file == (FILE *) NULL))
1928 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1929 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1931 return(MagickFalse);
1933 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1934 if (byte_image == (Image *) NULL)
1936 (void) fclose(unique_file);
1937 (void) RelinquishUniqueFileResource(filename);
1938 return(MagickFalse);
1940 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1942 DestroyBlob(byte_image);
1943 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1944 write_info=CloneImageInfo(image_info);
1945 SetImageInfoFile(write_info,unique_file);
1946 status=WriteImage(write_info,byte_image,exception);
1947 write_info=DestroyImageInfo(write_info);
1948 byte_image=DestroyImage(byte_image);
1949 (void) fclose(unique_file);
1950 if (status == MagickFalse)
1952 (void) RelinquishUniqueFileResource(filename);
1953 return(MagickFalse);
1956 Inject into image stream.
1958 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1961 (void) RelinquishUniqueFileResource(filename);
1962 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1963 image_info->filename);
1964 return(MagickFalse);
1966 quantum=(size_t) MagickMaxBufferExtent;
1967 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1968 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1969 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1970 if (buffer == (unsigned char *) NULL)
1972 (void) RelinquishUniqueFileResource(filename);
1973 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1976 for (i=0; ; i+=count)
1978 count=(ssize_t) read(file,buffer,quantum);
1985 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1990 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1991 (void) RelinquishUniqueFileResource(filename);
1992 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001 + I s B l o b E x e m p t %
2005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2007 % IsBlobExempt() returns true if the blob is exempt.
2009 % The format of the IsBlobExempt method is:
2011 % MagickBooleanType IsBlobExempt(const Image *image)
2013 % A description of each parameter follows:
2015 % o image: the image.
2018 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
2020 assert(image != (const Image *) NULL);
2021 assert(image->signature == MagickSignature);
2022 if (image->debug != MagickFalse)
2023 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2024 return(image->blob->exempt);
2028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2032 + I s B l o b S e e k a b l e %
2036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2038 % IsBlobSeekable() returns true if the blob is seekable.
2040 % The format of the IsBlobSeekable method is:
2042 % MagickBooleanType IsBlobSeekable(const Image *image)
2044 % A description of each parameter follows:
2046 % o image: the image.
2049 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2054 assert(image != (const Image *) NULL);
2055 assert(image->signature == MagickSignature);
2056 if (image->debug != MagickFalse)
2057 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2058 switch (image->blob->type)
2064 seekable=MagickTrue;
2069 seekable=MagickFalse;
2077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2081 + I s B l o b T e m p o r a r y %
2085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2087 % IsBlobTemporary() returns true if the blob is temporary.
2089 % The format of the IsBlobTemporary method is:
2091 % MagickBooleanType IsBlobTemporary(const Image *image)
2093 % A description of each parameter follows:
2095 % o image: the image.
2098 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2100 assert(image != (const Image *) NULL);
2101 assert(image->signature == MagickSignature);
2102 if (image->debug != MagickFalse)
2103 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2104 return(image->blob->temporary);
2108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2118 % MapBlob() creates a mapping from a file to a binary large object.
2120 % The format of the MapBlob method is:
2122 % unsigned char *MapBlob(int file,const MapMode mode,
2123 % const MagickOffsetType offset,const size_t length)
2125 % A description of each parameter follows:
2127 % o file: map this file descriptor.
2129 % o mode: ReadMode, WriteMode, or IOMode.
2131 % o offset: starting at this offset within the file.
2133 % o length: the length of the mapping is returned in this pointer.
2136 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2137 const MagickOffsetType offset,const size_t length)
2139 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2152 #if defined(MAP_ANONYMOUS)
2153 flags|=MAP_ANONYMOUS;
2155 return((unsigned char *) NULL);
2162 protection=PROT_READ;
2164 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2170 protection=PROT_WRITE;
2172 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2174 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2175 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2176 POSIX_MADV_WILLNEED);
2182 protection=PROT_READ | PROT_WRITE;
2184 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2189 if (map == (unsigned char *) MAP_FAILED)
2190 return((unsigned char *) NULL);
2197 return((unsigned char *) NULL);
2202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2206 + M S B O r d e r L o n g %
2210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2212 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2213 % most-significant byte first.
2215 % The format of the MSBOrderLong method is:
2217 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2219 % A description of each parameter follows.
2221 % o buffer: Specifies a pointer to a buffer of integers.
2223 % o length: Specifies the length of the buffer.
2226 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2231 register unsigned char
2235 assert(buffer != (unsigned char *) NULL);
2242 *buffer++=(unsigned char) c;
2246 *buffer++=(unsigned char) c;
2252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2256 + M S B O r d e r S h o r t %
2260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2262 % MSBOrderShort() converts a least-significant byte first buffer of integers
2263 % to most-significant byte first.
2265 % The format of the MSBOrderShort method is:
2267 % void MSBOrderShort(unsigned char *p,const size_t length)
2269 % A description of each parameter follows.
2271 % o p: Specifies a pointer to a buffer of integers.
2273 % o length: Specifies the length of the buffer.
2276 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2281 register unsigned char
2284 assert(p != (unsigned char *) NULL);
2291 *p++=(unsigned char) c;
2296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2306 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2307 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2308 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2309 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2310 % from a system command.
2312 % The format of the OpenBlob method is:
2314 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2315 % const BlobMode mode,ExceptionInfo *exception)
2317 % A description of each parameter follows:
2319 % o image_info: the image info.
2321 % o image: the image.
2323 % o mode: the mode for opening the file.
2326 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2327 Image *image,const BlobMode mode,ExceptionInfo *exception)
2330 extension[MaxTextExtent],
2331 filename[MaxTextExtent];
2342 assert(image_info != (ImageInfo *) NULL);
2343 assert(image_info->signature == MagickSignature);
2344 if (image_info->debug != MagickFalse)
2345 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2346 image_info->filename);
2347 assert(image != (Image *) NULL);
2348 assert(image->signature == MagickSignature);
2349 if (image_info->blob != (void *) NULL)
2351 if (image_info->stream != (StreamHandler) NULL)
2352 image->blob->stream=(StreamHandler) image_info->stream;
2353 AttachBlob(image->blob,image_info->blob,image_info->length);
2356 (void) DetachBlob(image->blob);
2359 default: type="r"; break;
2360 case ReadBlobMode: type="r"; break;
2361 case ReadBinaryBlobMode: type="rb"; break;
2362 case WriteBlobMode: type="w"; break;
2363 case WriteBinaryBlobMode: type="w+b"; break;
2364 case AppendBlobMode: type="a"; break;
2365 case AppendBinaryBlobMode: type="a+b"; break;
2368 image->blob->synchronize=image_info->synchronize;
2369 if (image_info->stream != (StreamHandler) NULL)
2371 image->blob->stream=(StreamHandler) image_info->stream;
2374 image->blob->type=FifoStream;
2382 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2383 rights=ReadPolicyRights;
2385 rights=WritePolicyRights;
2386 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2389 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2390 "NotAuthorized","'%s'",filename);
2391 return(MagickFalse);
2393 if ((LocaleCompare(filename,"-") == 0) ||
2394 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2396 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2397 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2398 if (strchr(type,'b') != (char *) NULL)
2399 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2401 image->blob->type=StandardStream;
2402 image->blob->exempt=MagickTrue;
2405 if (LocaleNCompare(filename,"fd:",3) == 0)
2408 mode[MaxTextExtent];
2412 image->blob->file_info.file=fdopen(StringToLong(filename+3),mode);
2413 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2414 if (strchr(type,'b') != (char *) NULL)
2415 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2417 image->blob->type=StandardStream;
2418 image->blob->exempt=MagickTrue;
2421 #if defined(MAGICKCORE_HAVE_POPEN)
2422 if (*filename == '|')
2425 mode[MaxTextExtent];
2428 Pipe image to or from a system command.
2430 #if defined(SIGPIPE)
2432 (void) signal(SIGPIPE,SIG_IGN);
2436 image->blob->file_info.file=(FILE *) popen_utf8(filename+1,mode);
2437 if (image->blob->file_info.file == (FILE *) NULL)
2439 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2440 return(MagickFalse);
2442 image->blob->type=PipeStream;
2443 image->blob->exempt=MagickTrue;
2447 status=GetPathAttributes(filename,&image->blob->properties);
2448 #if defined(S_ISFIFO)
2449 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2451 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2452 if (image->blob->file_info.file == (FILE *) NULL)
2454 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2455 return(MagickFalse);
2457 image->blob->type=FileStream;
2458 image->blob->exempt=MagickTrue;
2462 GetPathComponent(image->filename,ExtensionPath,extension);
2465 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2466 if ((image_info->adjoin == MagickFalse) ||
2467 (strchr(filename,'%') != (char *) NULL))
2470 Form filename for multi-part images.
2472 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2473 image->scene,filename,exception);
2474 if ((LocaleCompare(filename,image->filename) == 0) &&
2475 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2476 (GetNextImageInList(image) != (Image *) NULL)))
2479 path[MaxTextExtent];
2481 GetPathComponent(image->filename,RootPath,path);
2482 if (*extension == '\0')
2483 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2484 path,(double) image->scene);
2486 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2487 path,(double) image->scene,extension);
2489 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2490 #if defined(macintosh)
2491 SetApplicationType(filename,image_info->magick,'8BIM');
2495 if (image_info->file != (FILE *) NULL)
2497 image->blob->file_info.file=image_info->file;
2498 image->blob->type=FileStream;
2499 image->blob->exempt=MagickTrue;
2504 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2505 if (image->blob->file_info.file != (FILE *) NULL)
2513 image->blob->type=FileStream;
2514 #if defined(MAGICKCORE_HAVE_SETVBUF)
2515 (void) setvbuf(image->blob->file_info.file,(char *) NULL,
2516 (int) _IOFBF,16384);
2518 (void) ResetMagickMemory(magick,0,sizeof(magick));
2519 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2520 (void) fseek(image->blob->file_info.file,(off_t) -count,SEEK_CUR);
2521 (void) fflush(image->blob->file_info.file);
2522 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2523 " read %.20g magic header bytes",(double) count);
2524 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2525 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2526 ((int) magick[2] == 0x08))
2528 (void) fclose(image->blob->file_info.file);
2529 image->blob->file_info.gzfile=gzopen(filename,type);
2530 if (image->blob->file_info.gzfile != (gzFile) NULL)
2531 image->blob->type=ZipStream;
2534 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2535 if (strncmp((char *) magick,"BZh",3) == 0)
2537 (void) fclose(image->blob->file_info.file);
2538 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2539 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2540 image->blob->type=BZipStream;
2543 if (image->blob->type == FileStream)
2554 sans_exception=AcquireExceptionInfo();
2555 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2556 sans_exception=DestroyExceptionInfo(sans_exception);
2557 properties=(&image->blob->properties);
2558 if ((magick_info != (const MagickInfo *) NULL) &&
2559 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2560 (properties->st_size <= MagickMaxBufferExtent))
2568 length=(size_t) properties->st_size;
2569 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,
2571 if (blob != (void *) NULL)
2574 Format supports blobs-- use memory-mapped I/O.
2576 if (image_info->file != (FILE *) NULL)
2577 image->blob->exempt=MagickFalse;
2580 (void) fclose(image->blob->file_info.file);
2581 image->blob->file_info.file=(FILE *) NULL;
2583 AttachBlob(image->blob,blob,length);
2584 image->blob->mapped=MagickTrue;
2591 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2592 if ((LocaleCompare(extension,"Z") == 0) ||
2593 (LocaleCompare(extension,"gz") == 0) ||
2594 (LocaleCompare(extension,"wmz") == 0) ||
2595 (LocaleCompare(extension,"svgz") == 0))
2597 if (mode == WriteBinaryBlobMode)
2599 image->blob->file_info.gzfile=gzopen(filename,type);
2600 if (image->blob->file_info.gzfile != (gzFile) NULL)
2601 image->blob->type=ZipStream;
2605 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2606 if (LocaleCompare(extension,"bz2") == 0)
2608 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2609 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2610 image->blob->type=BZipStream;
2615 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2616 if (image->blob->file_info.file != (FILE *) NULL)
2618 image->blob->type=FileStream;
2619 #if defined(MAGICKCORE_HAVE_SETVBUF)
2620 (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int) _IOFBF,
2625 image->blob->status=MagickFalse;
2626 if (image->blob->type != UndefinedStream)
2627 image->blob->size=GetBlobSize(image);
2630 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2631 return(MagickFalse);
2637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2647 % PingBlob() returns all the attributes of an image or image sequence except
2648 % for the pixels. It is much faster and consumes far less memory than
2649 % BlobToImage(). On failure, a NULL image is returned and exception
2650 % describes the reason for the failure.
2652 % The format of the PingBlob method is:
2654 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2655 % const size_t length,ExceptionInfo *exception)
2657 % A description of each parameter follows:
2659 % o image_info: the image info.
2661 % o blob: the address of a character stream in one of the image formats
2662 % understood by ImageMagick.
2664 % o length: This size_t integer reflects the length in bytes of the blob.
2666 % o exception: return any errors or warnings in this structure.
2670 #if defined(__cplusplus) || defined(c_plusplus)
2674 static size_t PingStream(const Image *magick_unused(image),
2675 const void *magick_unused(pixels),const size_t columns)
2680 #if defined(__cplusplus) || defined(c_plusplus)
2684 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2685 const size_t length,ExceptionInfo *exception)
2693 assert(image_info != (ImageInfo *) NULL);
2694 assert(image_info->signature == MagickSignature);
2695 if (image_info->debug != MagickFalse)
2696 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2697 image_info->filename);
2698 assert(exception != (ExceptionInfo *) NULL);
2699 if ((blob == (const void *) NULL) || (length == 0))
2701 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2702 "UnrecognizedImageFormat","'%s'",image_info->magick);
2703 return((Image *) NULL);
2705 ping_info=CloneImageInfo(image_info);
2706 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2707 if (ping_info->blob == (const void *) NULL)
2709 (void) ThrowMagickException(exception,GetMagickModule(),
2710 ResourceLimitFatalError,"MemoryAllocationFailed","'%s'","");
2711 return((Image *) NULL);
2713 (void) memcpy(ping_info->blob,blob,length);
2714 ping_info->length=length;
2715 ping_info->ping=MagickTrue;
2716 image=ReadStream(ping_info,&PingStream,exception);
2717 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2718 ping_info=DestroyImageInfo(ping_info);
2723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2733 % ReadBlob() reads data from the blob or image file and returns it. It
2734 % returns the number of bytes read.
2736 % The format of the ReadBlob method is:
2738 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2740 % A description of each parameter follows:
2742 % o image: the image.
2744 % o length: Specifies an integer representing the number of bytes to read
2747 % o data: Specifies an area to place the information requested from the
2751 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2752 unsigned char *data)
2757 register unsigned char
2763 assert(image != (Image *) NULL);
2764 assert(image->signature == MagickSignature);
2765 assert(image->blob != (BlobInfo *) NULL);
2766 assert(image->blob->type != UndefinedStream);
2769 assert(data != (void *) NULL);
2772 switch (image->blob->type)
2774 case UndefinedStream:
2776 case StandardStream:
2782 for (i=0; i < (ssize_t) length; i+=count)
2784 count=read(fileno(image->blob->file_info.file),q+i,(size_t) MagickMin(
2785 length-i,SSIZE_MAX));
2803 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
2808 c=getc(image->blob->file_info.file);
2811 *q++=(unsigned char) c;
2816 c=getc(image->blob->file_info.file);
2819 *q++=(unsigned char) c;
2829 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2834 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
2835 (unsigned int) length);
2840 c=gzgetc(image->blob->file_info.gzfile);
2843 *q++=(unsigned char) c;
2848 c=gzgetc(image->blob->file_info.gzfile);
2851 *q++=(unsigned char) c;
2862 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2863 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,
2872 register const unsigned char
2875 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2877 image->blob->eof=MagickTrue;
2880 p=image->blob->data+image->blob->offset;
2881 count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
2882 image->blob->offset));
2883 image->blob->offset+=count;
2884 if (count != (ssize_t) length)
2885 image->blob->eof=MagickTrue;
2886 (void) memcpy(q,p,(size_t) count);
2894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2898 + R e a d B l o b B y t e %
2902 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2904 % ReadBlobByte() reads a single byte from the image file and returns it.
2906 % The format of the ReadBlobByte method is:
2908 % int ReadBlobByte(Image *image)
2910 % A description of each parameter follows.
2912 % o image: the image.
2915 MagickExport int ReadBlobByte(Image *image)
2917 register const unsigned char
2926 assert(image != (Image *) NULL);
2927 assert(image->signature == MagickSignature);
2928 p=ReadBlobStream(image,1,buffer,&count);
2935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2939 + R e a d B l o b D o u b l e %
2943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2945 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2946 % specified by the endian member of the image structure.
2948 % The format of the ReadBlobDouble method is:
2950 % double ReadBlobDouble(Image *image)
2952 % A description of each parameter follows.
2954 % o image: the image.
2957 MagickExport double ReadBlobDouble(Image *image)
2968 quantum.double_value=0.0;
2969 quantum.unsigned_value=ReadBlobLongLong(image);
2970 return(quantum.double_value);
2974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2978 + R e a d B l o b F l o a t %
2982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2984 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2985 % specified by the endian member of the image structure.
2987 % The format of the ReadBlobFloat method is:
2989 % float ReadBlobFloat(Image *image)
2991 % A description of each parameter follows.
2993 % o image: the image.
2996 MagickExport float ReadBlobFloat(Image *image)
3007 quantum.float_value=0.0;
3008 quantum.unsigned_value=ReadBlobLong(image);
3009 return(quantum.float_value);
3013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3017 + R e a d B l o b L o n g %
3021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3023 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
3024 % specified by the endian member of the image structure.
3026 % The format of the ReadBlobLong method is:
3028 % unsigned int ReadBlobLong(Image *image)
3030 % A description of each parameter follows.
3032 % o image: the image.
3035 MagickExport unsigned int ReadBlobLong(Image *image)
3037 register const unsigned char
3049 assert(image != (Image *) NULL);
3050 assert(image->signature == MagickSignature);
3052 p=ReadBlobStream(image,4,buffer,&count);
3055 if (image->endian == LSBEndian)
3057 value=(unsigned int) (*p++);
3058 value|=((unsigned int) (*p++)) << 8;
3059 value|=((unsigned int) (*p++)) << 16;
3060 value|=((unsigned int) (*p++)) << 24;
3063 value=((unsigned int) (*p++)) << 24;
3064 value|=((unsigned int) (*p++)) << 16;
3065 value|=((unsigned int) (*p++)) << 8;
3066 value|=((unsigned int) (*p++));
3071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3075 + R e a d B l o b L o n g L o n g %
3079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3081 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3082 % byte-order specified by the endian member of the image structure.
3084 % The format of the ReadBlobLongLong method is:
3086 % MagickSizeType ReadBlobLongLong(Image *image)
3088 % A description of each parameter follows.
3090 % o image: the image.
3093 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3098 register const unsigned char
3107 assert(image != (Image *) NULL);
3108 assert(image->signature == MagickSignature);
3110 p=ReadBlobStream(image,8,buffer,&count);
3112 return(MagickULLConstant(0));
3113 if (image->endian == LSBEndian)
3115 value=(MagickSizeType) (*p++);
3116 value|=((MagickSizeType) (*p++)) << 8;
3117 value|=((MagickSizeType) (*p++)) << 16;
3118 value|=((MagickSizeType) (*p++)) << 24;
3119 value|=((MagickSizeType) (*p++)) << 32;
3120 value|=((MagickSizeType) (*p++)) << 40;
3121 value|=((MagickSizeType) (*p++)) << 48;
3122 value|=((MagickSizeType) (*p++)) << 56;
3123 return(value & MagickULLConstant(0xffffffffffffffff));
3125 value=((MagickSizeType) (*p++)) << 56;
3126 value|=((MagickSizeType) (*p++)) << 48;
3127 value|=((MagickSizeType) (*p++)) << 40;
3128 value|=((MagickSizeType) (*p++)) << 32;
3129 value|=((MagickSizeType) (*p++)) << 24;
3130 value|=((MagickSizeType) (*p++)) << 16;
3131 value|=((MagickSizeType) (*p++)) << 8;
3132 value|=((MagickSizeType) (*p++));
3133 return(value & MagickULLConstant(0xffffffffffffffff));
3137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3141 + R e a d B l o b S h o r t %
3145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3147 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3148 % specified by the endian member of the image structure.
3150 % The format of the ReadBlobShort method is:
3152 % unsigned short ReadBlobShort(Image *image)
3154 % A description of each parameter follows.
3156 % o image: the image.
3159 MagickExport unsigned short ReadBlobShort(Image *image)
3161 register const unsigned char
3164 register unsigned int
3173 assert(image != (Image *) NULL);
3174 assert(image->signature == MagickSignature);
3176 p=ReadBlobStream(image,2,buffer,&count);
3178 return((unsigned short) 0U);
3179 if (image->endian == LSBEndian)
3181 value=(unsigned int) (*p++);
3182 value|=((unsigned int) (*p++)) << 8;
3183 return((unsigned short) (value & 0xffff));
3185 value=(unsigned int) ((*p++) << 8);
3186 value|=(unsigned int) (*p++);
3187 return((unsigned short) (value & 0xffff));
3191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3195 + R e a d B l o b L S B L o n g %
3199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3201 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3202 % least-significant byte first order.
3204 % The format of the ReadBlobLSBLong method is:
3206 % unsigned int ReadBlobLSBLong(Image *image)
3208 % A description of each parameter follows.
3210 % o image: the image.
3213 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3215 register const unsigned char
3218 register unsigned int
3227 assert(image != (Image *) NULL);
3228 assert(image->signature == MagickSignature);
3230 p=ReadBlobStream(image,4,buffer,&count);
3233 value=(unsigned int) (*p++);
3234 value|=((unsigned int) (*p++)) << 8;
3235 value|=((unsigned int) (*p++)) << 16;
3236 value|=((unsigned int) (*p++)) << 24;
3241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3245 + R e a d B l o b L S B S h o r t %
3249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3251 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3252 % least-significant byte first order.
3254 % The format of the ReadBlobLSBShort method is:
3256 % unsigned short ReadBlobLSBShort(Image *image)
3258 % A description of each parameter follows.
3260 % o image: the image.
3263 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3265 register const unsigned char
3268 register unsigned int
3277 assert(image != (Image *) NULL);
3278 assert(image->signature == MagickSignature);
3280 p=ReadBlobStream(image,2,buffer,&count);
3282 return((unsigned short) 0U);
3283 value=(unsigned int) (*p++);
3284 value|=((unsigned int) ((*p++)) << 8);
3285 return((unsigned short) (value & 0xffff));
3289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3293 + R e a d B l o b M S B L o n g %
3297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3299 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3300 % most-significant byte first order.
3302 % The format of the ReadBlobMSBLong method is:
3304 % unsigned int ReadBlobMSBLong(Image *image)
3306 % A description of each parameter follows.
3308 % o image: the image.
3311 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3313 register const unsigned char
3316 register unsigned int
3325 assert(image != (Image *) NULL);
3326 assert(image->signature == MagickSignature);
3328 p=ReadBlobStream(image,4,buffer,&count);
3331 value=((unsigned int) (*p++) << 24);
3332 value|=((unsigned int) (*p++) << 16);
3333 value|=((unsigned int) (*p++) << 8);
3334 value|=(unsigned int) (*p++);
3339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3343 + R e a d B l o b M S B L o n g L o n g %
3347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3349 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3350 % most-significant byte first order.
3352 % The format of the ReadBlobMSBLongLong method is:
3354 % unsigned int ReadBlobMSBLongLong(Image *image)
3356 % A description of each parameter follows.
3358 % o image: the image.
3361 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3363 register const unsigned char
3366 register MagickSizeType
3375 assert(image != (Image *) NULL);
3376 assert(image->signature == MagickSignature);
3378 p=ReadBlobStream(image,8,buffer,&count);
3380 return(MagickULLConstant(0));
3381 value=((MagickSizeType) (*p++)) << 56;
3382 value|=((MagickSizeType) (*p++)) << 48;
3383 value|=((MagickSizeType) (*p++)) << 40;
3384 value|=((MagickSizeType) (*p++)) << 32;
3385 value|=((MagickSizeType) (*p++)) << 24;
3386 value|=((MagickSizeType) (*p++)) << 16;
3387 value|=((MagickSizeType) (*p++)) << 8;
3388 value|=((MagickSizeType) (*p++));
3389 return(value & MagickULLConstant(0xffffffffffffffff));
3393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3397 + R e a d B l o b M S B S h o r t %
3401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3403 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3404 % most-significant byte first order.
3406 % The format of the ReadBlobMSBShort method is:
3408 % unsigned short ReadBlobMSBShort(Image *image)
3410 % A description of each parameter follows.
3412 % o image: the image.
3415 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3417 register const unsigned char
3420 register unsigned int
3429 assert(image != (Image *) NULL);
3430 assert(image->signature == MagickSignature);
3432 p=ReadBlobStream(image,2,buffer,&count);
3434 return((unsigned short) 0U);
3435 value=(unsigned int) ((*p++) << 8);
3436 value|=(unsigned int) (*p++);
3437 return((unsigned short) (value & 0xffff));
3441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3445 + R e a d B l o b S t r i n g %
3449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3451 % ReadBlobString() reads characters from a blob or file until a newline
3452 % character is read or an end-of-file condition is encountered.
3454 % The format of the ReadBlobString method is:
3456 % char *ReadBlobString(Image *image,char *string)
3458 % A description of each parameter follows:
3460 % o image: the image.
3462 % o string: the address of a character buffer.
3465 MagickExport char *ReadBlobString(Image *image,char *string)
3467 register const unsigned char
3479 assert(image != (Image *) NULL);
3480 assert(image->signature == MagickSignature);
3481 for (i=0; i < (MaxTextExtent-1L); i++)
3483 p=ReadBlobStream(image,1,buffer,&count);
3487 return((char *) NULL);
3490 string[i]=(char) (*p);
3491 if ((string[i] == '\r') || (string[i] == '\n'))
3494 if (string[i] == '\r')
3495 (void) ReadBlobStream(image,1,buffer,&count);
3501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3505 + R e f e r e n c e B l o b %
3509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3511 % ReferenceBlob() increments the reference count associated with the pixel
3512 % blob returning a pointer to the blob.
3514 % The format of the ReferenceBlob method is:
3516 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3518 % A description of each parameter follows:
3520 % o blob_info: the blob_info.
3523 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3525 assert(blob != (BlobInfo *) NULL);
3526 assert(blob->signature == MagickSignature);
3527 if (blob->debug != MagickFalse)
3528 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3529 LockSemaphoreInfo(blob->semaphore);
3530 blob->reference_count++;
3531 UnlockSemaphoreInfo(blob->semaphore);
3536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3546 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3547 % and returns the resulting offset.
3549 % The format of the SeekBlob method is:
3551 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3554 % A description of each parameter follows:
3556 % o image: the image.
3558 % o offset: Specifies an integer representing the offset in bytes.
3560 % o whence: Specifies an integer representing how the offset is
3561 % treated relative to the beginning of the blob as follows:
3563 % SEEK_SET Set position equal to offset bytes.
3564 % SEEK_CUR Set position to current location plus offset.
3565 % SEEK_END Set position to EOF plus offset.
3568 MagickExport MagickOffsetType SeekBlob(Image *image,
3569 const MagickOffsetType offset,const int whence)
3571 assert(image != (Image *) NULL);
3572 assert(image->signature == MagickSignature);
3573 if (image->debug != MagickFalse)
3574 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3575 assert(image->blob != (BlobInfo *) NULL);
3576 assert(image->blob->type != UndefinedStream);
3577 switch (image->blob->type)
3579 case UndefinedStream:
3581 case StandardStream:
3585 if (fseek(image->blob->file_info.file,offset,whence) < 0)
3587 image->blob->offset=TellBlob(image);
3593 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3594 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
3597 image->blob->offset=TellBlob(image);
3613 image->blob->offset=offset;
3618 if ((image->blob->offset+offset) < 0)
3620 image->blob->offset+=offset;
3625 if (((MagickOffsetType) image->blob->length+offset) < 0)
3627 image->blob->offset=image->blob->length+offset;
3631 if (image->blob->offset <= (MagickOffsetType)
3632 ((off_t) image->blob->length))
3633 image->blob->eof=MagickFalse;
3635 if (image->blob->mapped != MagickFalse)
3639 image->blob->extent=(size_t) (image->blob->offset+
3640 image->blob->quantum);
3641 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3642 image->blob->data,image->blob->extent+1,
3643 sizeof(*image->blob->data));
3644 (void) SyncBlob(image);
3645 if (image->blob->data == (unsigned char *) NULL)
3647 (void) DetachBlob(image->blob);
3654 return(image->blob->offset);
3658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3662 + S e t B l o b E x e m p t %
3666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3668 % SetBlobExempt() sets the blob exempt status.
3670 % The format of the SetBlobExempt method is:
3672 % MagickBooleanType SetBlobExempt(const Image *image,
3673 % const MagickBooleanType exempt)
3675 % A description of each parameter follows:
3677 % o image: the image.
3679 % o exempt: Set to true if this blob is exempt from being closed.
3682 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3684 assert(image != (const Image *) NULL);
3685 assert(image->signature == MagickSignature);
3686 if (image->debug != MagickFalse)
3687 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3688 image->blob->exempt=exempt;
3692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3696 + S e t B l o b E x t e n t %
3700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3702 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3703 % method is successful, subsequent writes to bytes in the specified range are
3704 % guaranteed not to fail.
3706 % The format of the SetBlobExtent method is:
3708 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3710 % A description of each parameter follows:
3712 % o image: the image.
3714 % o extent: the blob maximum extent.
3717 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3718 const MagickSizeType extent)
3720 assert(image != (Image *) NULL);
3721 assert(image->signature == MagickSignature);
3722 if (image->debug != MagickFalse)
3723 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3724 assert(image->blob != (BlobInfo *) NULL);
3725 assert(image->blob->type != UndefinedStream);
3726 switch (image->blob->type)
3728 case UndefinedStream:
3730 case StandardStream:
3731 return(MagickFalse);
3740 if (extent != (MagickSizeType) ((off_t) extent))
3741 return(MagickFalse);
3742 offset=SeekBlob(image,0,SEEK_END);
3744 return(MagickFalse);
3745 if ((MagickSizeType) offset >= extent)
3747 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3748 count=fwrite((const unsigned char *) "",1,1,image->blob->file_info.file);
3749 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3750 if (image->blob->synchronize != MagickFalse)
3755 status=posix_fallocate(fileno(image->blob->file_info.file),offset,
3758 return(MagickFalse);
3761 offset=SeekBlob(image,offset,SEEK_SET);
3762 if (count != (MagickOffsetType) 1)
3763 return(MagickFalse);
3768 return(MagickFalse);
3770 return(MagickFalse);
3772 return(MagickFalse);
3775 if (extent != (MagickSizeType) ((size_t) extent))
3776 return(MagickFalse);
3777 if (image->blob->mapped != MagickFalse)
3785 (void) UnmapBlob(image->blob->data,image->blob->length);
3786 if (extent != (MagickSizeType) ((off_t) extent))
3787 return(MagickFalse);
3788 offset=SeekBlob(image,0,SEEK_END);
3790 return(MagickFalse);
3791 if ((MagickSizeType) offset >= extent)
3793 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3794 count=fwrite((const unsigned char *) "",1,1,
3795 image->blob->file_info.file);
3796 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3797 if (image->blob->synchronize != MagickFalse)
3802 status=posix_fallocate(fileno(image->blob->file_info.file),offset,
3805 return(MagickFalse);
3808 offset=SeekBlob(image,offset,SEEK_SET);
3809 if (count != (MagickOffsetType) 1)
3811 image->blob->data=(unsigned char*) MapBlob(fileno(
3812 image->blob->file_info.file),WriteMode,0,(size_t) extent);
3813 image->blob->extent=(size_t) extent;
3814 image->blob->length=(size_t) extent;
3815 (void) SyncBlob(image);
3818 image->blob->extent=(size_t) extent;
3819 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3820 image->blob->extent+1,sizeof(*image->blob->data));
3821 (void) SyncBlob(image);
3822 if (image->blob->data == (unsigned char *) NULL)
3824 (void) DetachBlob(image->blob);
3825 return(MagickFalse);
3834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3844 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3845 % attributes if it is an blob.
3847 % The format of the SyncBlob method is:
3849 % int SyncBlob(Image *image)
3851 % A description of each parameter follows:
3853 % o image: the image.
3856 static int SyncBlob(Image *image)
3861 assert(image != (Image *) NULL);
3862 assert(image->signature == MagickSignature);
3863 if (image->debug != MagickFalse)
3864 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3865 assert(image->blob != (BlobInfo *) NULL);
3866 assert(image->blob->type != UndefinedStream);
3868 switch (image->blob->type)
3870 case UndefinedStream:
3871 case StandardStream:
3876 status=fflush(image->blob->file_info.file);
3881 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3882 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
3888 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3889 status=BZ2_bzflush(image->blob->file_info.bzfile);
3897 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3898 if (image->blob->mapped != MagickFalse)
3899 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3918 % TellBlob() obtains the current value of the blob or file position.
3920 % The format of the TellBlob method is:
3922 % MagickOffsetType TellBlob(const Image *image)
3924 % A description of each parameter follows:
3926 % o image: the image.
3929 MagickExport MagickOffsetType TellBlob(const Image *image)
3934 assert(image != (Image *) NULL);
3935 assert(image->signature == MagickSignature);
3936 if (image->debug != MagickFalse)
3937 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3938 assert(image->blob != (BlobInfo *) NULL);
3939 assert(image->blob->type != UndefinedStream);
3941 switch (image->blob->type)
3943 case UndefinedStream:
3944 case StandardStream:
3948 offset=ftell(image->blob->file_info.file);
3955 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3956 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
3966 offset=image->blob->offset;
3974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3978 + U n m a p B l o b %
3982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3984 % UnmapBlob() deallocates the binary large object previously allocated with
3985 % the MapBlob method.
3987 % The format of the UnmapBlob method is:
3989 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3991 % A description of each parameter follows:
3993 % o map: the address of the binary large object.
3995 % o length: the length of the binary large object.
3998 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4000 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
4004 status=munmap(map,length);
4005 return(status == -1 ? MagickFalse : MagickTrue);
4009 return(MagickFalse);
4014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4018 + W r i t e B l o b %
4022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4024 % WriteBlob() writes data to a blob or image file. It returns the number of
4027 % The format of the WriteBlob method is:
4029 % ssize_t WriteBlob(Image *image,const size_t length,
4030 % const unsigned char *data)
4032 % A description of each parameter follows:
4034 % o image: the image.
4036 % o length: Specifies an integer representing the number of bytes to
4037 % write to the file.
4039 % o data: The address of the data to write to the blob or file.
4042 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4043 const unsigned char *data)
4048 register const unsigned char
4054 assert(image != (Image *) NULL);
4055 assert(image->signature == MagickSignature);
4056 assert(data != (const unsigned char *) NULL);
4057 assert(image->blob != (BlobInfo *) NULL);
4058 assert(image->blob->type != UndefinedStream);
4063 switch (image->blob->type)
4065 case UndefinedStream:
4067 case StandardStream:
4073 for (i=0; i < (MagickOffsetType) length; i+=count)
4075 count=write(fileno(image->blob->file_info.file),data+i,(size_t)
4076 MagickMin(length-i,SSIZE_MAX));
4094 count=(ssize_t) fwrite((const char *) data,1,length,
4095 image->blob->file_info.file);
4100 c=putc((int) *p++,image->blob->file_info.file);
4107 c=putc((int) *p++,image->blob->file_info.file);
4119 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4124 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4125 (unsigned int) length);
4130 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4137 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4150 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4151 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
4158 count=(ssize_t) image->blob->stream(image,data,length);
4163 register unsigned char
4166 if ((image->blob->offset+(MagickOffsetType) length) >=
4167 (MagickOffsetType) image->blob->extent)
4169 if (image->blob->mapped != MagickFalse)
4171 image->blob->quantum<<=1;
4172 image->blob->extent+=length+image->blob->quantum;
4173 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4174 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4175 (void) SyncBlob(image);
4176 if (image->blob->data == (unsigned char *) NULL)
4178 (void) DetachBlob(image->blob);
4182 q=image->blob->data+image->blob->offset;
4183 (void) memcpy(q,p,length);
4184 image->blob->offset+=length;
4185 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4186 image->blob->length=(size_t) image->blob->offset;
4187 count=(ssize_t) length;
4194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4198 + W r i t e B l o b B y t e %
4202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4204 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4205 % written (either 0 or 1);
4207 % The format of the WriteBlobByte method is:
4209 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4211 % A description of each parameter follows.
4213 % o image: the image.
4215 % o value: Specifies the value to write.
4218 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4220 assert(image != (Image *) NULL);
4221 assert(image->signature == MagickSignature);
4222 return(WriteBlobStream(image,1,&value));
4226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4230 + W r i t e B l o b F l o a t %
4234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4236 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4237 % specified by the endian member of the image structure.
4239 % The format of the WriteBlobFloat method is:
4241 % ssize_t WriteBlobFloat(Image *image,const float value)
4243 % A description of each parameter follows.
4245 % o image: the image.
4247 % o value: Specifies the value to write.
4250 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4261 quantum.unsigned_value=0U;
4262 quantum.float_value=value;
4263 return(WriteBlobLong(image,quantum.unsigned_value));
4267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4271 + W r i t e B l o b L o n g %
4275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4277 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4278 % specified by the endian member of the image structure.
4280 % The format of the WriteBlobLong method is:
4282 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4284 % A description of each parameter follows.
4286 % o image: the image.
4288 % o value: Specifies the value to write.
4291 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4296 assert(image != (Image *) NULL);
4297 assert(image->signature == MagickSignature);
4298 if (image->endian == LSBEndian)
4300 buffer[0]=(unsigned char) value;
4301 buffer[1]=(unsigned char) (value >> 8);
4302 buffer[2]=(unsigned char) (value >> 16);
4303 buffer[3]=(unsigned char) (value >> 24);
4304 return(WriteBlobStream(image,4,buffer));
4306 buffer[0]=(unsigned char) (value >> 24);
4307 buffer[1]=(unsigned char) (value >> 16);
4308 buffer[2]=(unsigned char) (value >> 8);
4309 buffer[3]=(unsigned char) value;
4310 return(WriteBlobStream(image,4,buffer));
4314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4318 + W r i t e B l o b S h o r t %
4322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4324 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4325 % byte-order specified by the endian member of the image structure.
4327 % The format of the WriteBlobShort method is:
4329 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4331 % A description of each parameter follows.
4333 % o image: the image.
4335 % o value: Specifies the value to write.
4338 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4343 assert(image != (Image *) NULL);
4344 assert(image->signature == MagickSignature);
4345 if (image->endian == LSBEndian)
4347 buffer[0]=(unsigned char) value;
4348 buffer[1]=(unsigned char) (value >> 8);
4349 return(WriteBlobStream(image,2,buffer));
4351 buffer[0]=(unsigned char) (value >> 8);
4352 buffer[1]=(unsigned char) value;
4353 return(WriteBlobStream(image,2,buffer));
4357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4361 + W r i t e B l o b L S B L o n g %
4365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4367 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4368 % least-significant byte first order.
4370 % The format of the WriteBlobLSBLong method is:
4372 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4374 % A description of each parameter follows.
4376 % o image: the image.
4378 % o value: Specifies the value to write.
4381 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4386 assert(image != (Image *) NULL);
4387 assert(image->signature == MagickSignature);
4388 buffer[0]=(unsigned char) value;
4389 buffer[1]=(unsigned char) (value >> 8);
4390 buffer[2]=(unsigned char) (value >> 16);
4391 buffer[3]=(unsigned char) (value >> 24);
4392 return(WriteBlobStream(image,4,buffer));
4396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4400 + W r i t e B l o b L S B S h o r t %
4404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4406 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4407 % least-significant byte first order.
4409 % The format of the WriteBlobLSBShort method is:
4411 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4413 % A description of each parameter follows.
4415 % o image: the image.
4417 % o value: Specifies the value to write.
4420 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4425 assert(image != (Image *) NULL);
4426 assert(image->signature == MagickSignature);
4427 buffer[0]=(unsigned char) value;
4428 buffer[1]=(unsigned char) (value >> 8);
4429 return(WriteBlobStream(image,2,buffer));
4433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4437 + W r i t e B l o b M S B L o n g %
4441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4443 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4444 % most-significant byte first order.
4446 % The format of the WriteBlobMSBLong method is:
4448 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4450 % A description of each parameter follows.
4452 % o value: Specifies the value to write.
4454 % o image: the image.
4457 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4462 assert(image != (Image *) NULL);
4463 assert(image->signature == MagickSignature);
4464 buffer[0]=(unsigned char) (value >> 24);
4465 buffer[1]=(unsigned char) (value >> 16);
4466 buffer[2]=(unsigned char) (value >> 8);
4467 buffer[3]=(unsigned char) value;
4468 return(WriteBlobStream(image,4,buffer));
4472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4476 + W r i t e B l o b M S B L o n g L o n g %
4480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4482 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4483 % most-significant byte first order.
4485 % The format of the WriteBlobMSBLongLong method is:
4487 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4489 % A description of each parameter follows.
4491 % o value: Specifies the value to write.
4493 % o image: the image.
4496 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4497 const MagickSizeType value)
4502 assert(image != (Image *) NULL);
4503 assert(image->signature == MagickSignature);
4504 buffer[0]=(unsigned char) (value >> 56);
4505 buffer[1]=(unsigned char) (value >> 48);
4506 buffer[2]=(unsigned char) (value >> 40);
4507 buffer[3]=(unsigned char) (value >> 32);
4508 buffer[4]=(unsigned char) (value >> 24);
4509 buffer[5]=(unsigned char) (value >> 16);
4510 buffer[6]=(unsigned char) (value >> 8);
4511 buffer[7]=(unsigned char) value;
4512 return(WriteBlobStream(image,8,buffer));
4516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4520 + W r i t e B l o b M S B S h o r t %
4524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4526 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4527 % most-significant byte first order.
4529 % The format of the WriteBlobMSBShort method is:
4531 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4533 % A description of each parameter follows.
4535 % o value: Specifies the value to write.
4537 % o file: Specifies the file to write the data to.
4540 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4545 assert(image != (Image *) NULL);
4546 assert(image->signature == MagickSignature);
4547 buffer[0]=(unsigned char) (value >> 8);
4548 buffer[1]=(unsigned char) value;
4549 return(WriteBlobStream(image,2,buffer));
4553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4557 + W r i t e B l o b S t r i n g %
4561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4563 % WriteBlobString() write a string to a blob. It returns the number of
4564 % characters written.
4566 % The format of the WriteBlobString method is:
4568 % ssize_t WriteBlobString(Image *image,const char *string)
4570 % A description of each parameter follows.
4572 % o image: the image.
4574 % o string: Specifies the string to write.
4577 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4579 assert(image != (Image *) NULL);
4580 assert(image->signature == MagickSignature);
4581 assert(string != (const char *) NULL);
4582 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));