2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2010 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 "magick/studio.h"
44 #include "magick/blob.h"
45 #include "magick/blob-private.h"
46 #include "magick/cache.h"
47 #include "magick/client.h"
48 #include "magick/constitute.h"
49 #include "magick/delegate.h"
50 #include "magick/exception.h"
51 #include "magick/exception-private.h"
52 #include "magick/image-private.h"
53 #include "magick/list.h"
54 #include "magick/log.h"
55 #include "magick/magick.h"
56 #include "magick/memory_.h"
57 #include "magick/policy.h"
58 #include "magick/resource_.h"
59 #include "magick/semaphore.h"
60 #include "magick/string_.h"
61 #include "magick/string-private.h"
62 #include "magick/token.h"
63 #include "magick/utility.h"
64 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
65 # include <sys/mman.h>
67 #if defined(MAGICKCORE_ZLIB_DELEGATE)
70 #if defined(MAGICKCORE_BZLIB_DELEGATE)
77 #define MagickMaxBlobExtent 65541
78 #if defined(MAGICKCORE_HAVE_FSEEKO)
82 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
83 # define MAP_ANONYMOUS MAP_ANON
85 #if !defined(MAP_FAILED)
86 #define MAP_FAILED ((void *) -1)
93 #define _O_BINARY O_BINARY
151 Forward declarations.
157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161 + A t t a c h B l o b %
165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 % AttachBlob() attaches a blob to the BlobInfo structure.
169 % The format of the AttachBlob method is:
171 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
173 % A description of each parameter follows:
175 % o blob_info: Specifies a pointer to a BlobInfo structure.
177 % o blob: the address of a character stream in one of the image formats
178 % understood by ImageMagick.
180 % o length: This size_t integer reflects the length in bytes of the blob.
183 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
186 assert(blob_info != (BlobInfo *) NULL);
187 if (blob_info->debug != MagickFalse)
188 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
189 blob_info->length=length;
190 blob_info->extent=length;
191 blob_info->quantum=(size_t) MagickMaxBlobExtent;
193 blob_info->type=BlobStream;
194 blob_info->file=(FILE *) NULL;
195 blob_info->data=(unsigned char *) blob;
196 blob_info->mapped=MagickFalse;
200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 + B l o b T o F i l e %
208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
211 % occurs otherwise MagickTrue.
213 % The format of the BlobToFile method is:
215 % MagickBooleanType BlobToFile(char *filename,const void *blob,
216 % const size_t length,ExceptionInfo *exception)
218 % A description of each parameter follows:
220 % o filename: Write the blob to this file.
222 % o blob: the address of a blob.
224 % o length: This length in bytes of the blob.
226 % o exception: return any errors or warnings in this structure.
230 static inline size_t MagickMin(const size_t x,const size_t y)
237 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
238 const size_t length,ExceptionInfo *exception)
249 assert(filename != (const char *) NULL);
250 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
251 assert(blob != (const void *) NULL);
252 if (*filename == '\0')
253 file=AcquireUniqueFileResource(filename);
255 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
258 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
261 for (i=0; i < length; i+=count)
263 count=(ssize_t) write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
275 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286 % B l o b T o I m a g e %
290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292 % BlobToImage() implements direct to memory image formats. It returns the
295 % The format of the BlobToImage method is:
297 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
298 % const size_t length,ExceptionInfo *exception)
300 % A description of each parameter follows:
302 % o image_info: the image info.
304 % o blob: the address of a character stream in one of the image formats
305 % understood by ImageMagick.
307 % o length: This size_t integer reflects the length in bytes of the blob.
309 % o exception: return any errors or warnings in this structure.
312 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
313 const size_t length,ExceptionInfo *exception)
328 assert(image_info != (ImageInfo *) NULL);
329 assert(image_info->signature == MagickSignature);
330 if (image_info->debug != MagickFalse)
331 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
332 image_info->filename);
333 assert(exception != (ExceptionInfo *) NULL);
334 if ((blob == (const void *) NULL) || (length == 0))
336 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
337 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
338 return((Image *) NULL);
340 blob_info=CloneImageInfo(image_info);
341 blob_info->blob=(void *) blob;
342 blob_info->length=length;
343 if (*blob_info->magick == '\0')
344 (void) SetImageInfo(blob_info,0,exception);
345 magick_info=GetMagickInfo(blob_info->magick,exception);
346 if (magick_info == (const MagickInfo *) NULL)
348 blob_info=DestroyImageInfo(blob_info);
349 (void) ThrowMagickException(exception,GetMagickModule(),
350 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
351 image_info->filename);
352 return((Image *) NULL);
354 if (GetMagickBlobSupport(magick_info) != MagickFalse)
357 Native blob support for this image format.
359 (void) CopyMagickString(blob_info->filename,image_info->filename,
361 (void) CopyMagickString(blob_info->magick,image_info->magick,
363 image=ReadImage(blob_info,exception);
364 if (image != (Image *) NULL)
365 (void) DetachBlob(image->blob);
366 blob_info=DestroyImageInfo(blob_info);
370 Write blob to a temporary file on disk.
372 blob_info->blob=(void *) NULL;
374 *blob_info->filename='\0';
375 status=BlobToFile(blob_info->filename,blob,length,exception);
376 if (status == MagickFalse)
378 (void) RelinquishUniqueFileResource(blob_info->filename);
379 blob_info=DestroyImageInfo(blob_info);
380 return((Image *) NULL);
382 clone_info=CloneImageInfo(blob_info);
383 (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
384 blob_info->magick,blob_info->filename);
385 image=ReadImage(clone_info,exception);
386 clone_info=DestroyImageInfo(clone_info);
387 (void) RelinquishUniqueFileResource(blob_info->filename);
388 blob_info=DestroyImageInfo(blob_info);
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 + C l o n e B l o b I n f o %
401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
404 % blob info is NULL, a new one.
406 % The format of the CloneBlobInfo method is:
408 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
410 % A description of each parameter follows:
412 % o blob_info: the blob info.
415 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
420 clone_info=(BlobInfo *) AcquireAlignedMemory(1,sizeof(*clone_info));
421 if (clone_info == (BlobInfo *) NULL)
422 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
423 GetBlobInfo(clone_info);
424 if (blob_info == (BlobInfo *) NULL)
426 clone_info->length=blob_info->length;
427 clone_info->extent=blob_info->extent;
428 clone_info->synchronize=blob_info->synchronize;
429 clone_info->quantum=blob_info->quantum;
430 clone_info->mapped=blob_info->mapped;
431 clone_info->eof=blob_info->eof;
432 clone_info->offset=blob_info->offset;
433 clone_info->size=blob_info->size;
434 clone_info->exempt=blob_info->exempt;
435 clone_info->status=blob_info->status;
436 clone_info->temporary=blob_info->temporary;
437 clone_info->type=blob_info->type;
438 clone_info->file=blob_info->file;
439 clone_info->properties=blob_info->properties;
440 clone_info->stream=blob_info->stream;
441 clone_info->data=blob_info->data;
442 clone_info->debug=IsEventLogging();
443 clone_info->reference_count=1;
448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
452 + C l o s e B l o b %
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458 % CloseBlob() closes a stream associated with the image.
460 % The format of the CloseBlob method is:
462 % MagickBooleanType CloseBlob(Image *image)
464 % A description of each parameter follows:
466 % o image: the image.
469 MagickExport MagickBooleanType CloseBlob(Image *image)
477 assert(image != (Image *) NULL);
478 assert(image->signature == MagickSignature);
479 if (image->debug != MagickFalse)
480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
481 assert(image->blob != (BlobInfo *) NULL);
482 if (image->blob->type == UndefinedStream)
484 if (image->blob->synchronize != MagickFalse)
486 image->blob->size=GetBlobSize(image);
487 image->extent=image->blob->size;
488 image->blob->eof=MagickFalse;
489 if (image->blob->exempt != MagickFalse)
491 image->blob->type=UndefinedStream;
495 switch (image->blob->type)
497 case UndefinedStream:
503 status=ferror(image->blob->file);
508 #if defined(MAGICKCORE_ZLIB_DELEGATE)
509 (void) gzerror(image->blob->file,&status);
515 #if defined(MAGICKCORE_BZLIB_DELEGATE)
516 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
524 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
525 switch (image->blob->type)
527 case UndefinedStream:
532 if (image->blob->synchronize != MagickFalse)
533 status=fsync(fileno(image->blob->file));
534 status=fclose(image->blob->file);
539 #if defined(MAGICKCORE_HAVE_PCLOSE)
540 status=pclose(image->blob->file);
546 #if defined(MAGICKCORE_ZLIB_DELEGATE)
547 status=gzclose(image->blob->file);
553 #if defined(MAGICKCORE_BZLIB_DELEGATE)
554 BZ2_bzclose((BZFILE *) image->blob->file);
562 (void) DetachBlob(image->blob);
563 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
564 return(image->blob->status);
568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572 + D e s t r o y B l o b %
576 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578 % DestroyBlob() deallocates memory associated with a blob.
580 % The format of the DestroyBlob method is:
582 % void DestroyBlob(Image *image)
584 % A description of each parameter follows:
586 % o image: the image.
589 MagickExport void DestroyBlob(Image *image)
594 assert(image != (Image *) NULL);
595 assert(image->signature == MagickSignature);
596 if (image->debug != MagickFalse)
597 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
598 assert(image->blob != (BlobInfo *) NULL);
599 assert(image->blob->signature == MagickSignature);
601 LockSemaphoreInfo(image->blob->semaphore);
602 image->blob->reference_count--;
603 assert(image->blob->reference_count >= 0);
604 if (image->blob->reference_count == 0)
606 UnlockSemaphoreInfo(image->blob->semaphore);
607 if (destroy == MagickFalse)
609 (void) CloseBlob(image);
610 if (image->blob->mapped != MagickFalse)
611 (void) UnmapBlob(image->blob->data,image->blob->length);
612 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
613 DestroySemaphoreInfo(&image->blob->semaphore);
614 image->blob->signature=(~MagickSignature);
615 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623 + D e t a c h B l o b %
627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 % DetachBlob() detaches a blob from the BlobInfo structure.
631 % The format of the DetachBlob method is:
633 % unsigned char *DetachBlob(BlobInfo *blob_info)
635 % A description of each parameter follows:
637 % o blob_info: Specifies a pointer to a BlobInfo structure.
640 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
645 assert(blob_info != (BlobInfo *) NULL);
646 if (blob_info->debug != MagickFalse)
647 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
648 if (blob_info->mapped != MagickFalse)
649 (void) UnmapBlob(blob_info->data,blob_info->length);
650 blob_info->mapped=MagickFalse;
653 blob_info->eof=MagickFalse;
654 blob_info->exempt=MagickFalse;
655 blob_info->type=UndefinedStream;
656 blob_info->file=(FILE *) NULL;
657 data=blob_info->data;
658 blob_info->data=(unsigned char *) NULL;
659 blob_info->stream=(StreamHandler) NULL;
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 + D u p l i c a t e s B l o b %
672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
674 % DuplicateBlob() duplicates a blob descriptor.
676 % The format of the DuplicateBlob method is:
678 % void DuplicateBlob(Image *image,const Image *duplicate)
680 % A description of each parameter follows:
682 % o image: the image.
684 % o duplicate: the duplicate image.
687 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
689 assert(image != (Image *) NULL);
690 assert(image->signature == MagickSignature);
691 if (image->debug != MagickFalse)
692 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
693 assert(duplicate != (Image *) NULL);
694 assert(duplicate->signature == MagickSignature);
696 image->blob=ReferenceBlob(duplicate->blob);
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 % EOFBlob() returns a non-zero value when EOF has been detected reading from
713 % The format of the EOFBlob method is:
715 % int EOFBlob(const Image *image)
717 % A description of each parameter follows:
719 % o image: the image.
722 MagickExport int EOFBlob(const Image *image)
724 assert(image != (Image *) NULL);
725 assert(image->signature == MagickSignature);
726 if (image->debug != MagickFalse)
727 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
728 assert(image->blob != (BlobInfo *) NULL);
729 assert(image->blob->type != UndefinedStream);
730 switch (image->blob->type)
732 case UndefinedStream:
738 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
743 image->blob->eof=MagickFalse;
748 #if defined(MAGICKCORE_BZLIB_DELEGATE)
753 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
754 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
760 image->blob->eof=MagickFalse;
766 return((int) image->blob->eof);
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
774 + F i l e T o B l o b %
778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
780 % FileToBlob() returns the contents of a file as a blob. It returns the
781 % file as a blob and its length. If an error occurs, NULL is returned.
783 % The format of the FileToBlob method is:
785 % unsigned char *FileToBlob(const char *filename,const size_t extent,
786 % size_t *length,ExceptionInfo *exception)
788 % A description of each parameter follows:
790 % o blob: FileToBlob() returns the contents of a file as a blob. If
791 % an error occurs NULL is returned.
793 % o filename: the filename.
795 % o extent: The maximum length of the blob.
797 % o length: On return, this reflects the actual length of the blob.
799 % o exception: return any errors or warnings in this structure.
802 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
803 size_t *length,ExceptionInfo *exception)
823 assert(filename != (const char *) NULL);
824 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
825 assert(exception != (ExceptionInfo *) NULL);
828 if (LocaleCompare(filename,"-") != 0)
829 file=open(filename,O_RDONLY | O_BINARY);
832 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
833 return((unsigned char *) NULL);
835 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
837 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
846 Stream is not seekable.
848 quantum=(size_t) MagickMaxBufferExtent;
849 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
850 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
851 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
852 for (i=0; blob != (unsigned char *) NULL; i+=count)
854 count=(ssize_t) read(file,blob+i,quantum);
861 if (~(1UL*i) < (quantum+1))
863 blob=(unsigned char *) RelinquishMagickMemory(blob);
866 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
868 if ((size_t) (i+count) >= extent)
872 if (blob == (unsigned char *) NULL)
874 (void) ThrowMagickException(exception,GetMagickModule(),
875 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
876 return((unsigned char *) NULL);
878 *length=MagickMin(i+count,extent);
882 *length=MagickMin((size_t) offset,extent);
883 blob=(unsigned char *) NULL;
884 if (~(*length) >= MaxTextExtent)
885 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
887 if (blob == (unsigned char *) NULL)
890 (void) ThrowMagickException(exception,GetMagickModule(),
891 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
892 return((unsigned char *) NULL);
894 map=MapBlob(file,ReadMode,0,*length);
895 if (map != (unsigned char *) NULL)
897 (void) CopyMagickMemory(blob,map,*length);
898 (void) UnmapBlob(map,*length);
902 (void) MagickSeek(file,0,SEEK_SET);
903 for (i=0; i < *length; i+=count)
905 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
917 blob=(unsigned char *) RelinquishMagickMemory(blob);
918 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
919 return((unsigned char *) NULL);
928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932 % F i l e T o I m a g e %
936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
938 % FileToImage() write the contents of a file to an image.
940 % The format of the FileToImage method is:
942 % MagickBooleanType FileToImage(Image *,const char *filename)
944 % A description of each parameter follows:
946 % o image: the image.
948 % o filename: the filename.
952 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
953 const unsigned char *data)
958 register unsigned char
961 assert(image->blob != (BlobInfo *) NULL);
962 if (image->blob->type != BlobStream)
963 return(WriteBlob(image,length,data));
964 assert(image->blob->type != UndefinedStream);
965 assert(data != (void *) NULL);
966 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
967 if (extent >= image->blob->extent)
969 image->blob->quantum<<=1;
970 extent=image->blob->extent+image->blob->quantum+length;
971 if (SetBlobExtent(image,extent) == MagickFalse)
974 q=image->blob->data+image->blob->offset;
975 (void) CopyMagickMemory(q,data,length);
976 image->blob->offset+=length;
977 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
978 image->blob->length=(size_t) image->blob->offset;
979 return((ssize_t) length);
982 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1000 assert(image != (const Image *) NULL);
1001 assert(image->signature == MagickSignature);
1002 assert(filename != (const char *) NULL);
1003 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1004 file=open(filename,O_RDONLY | O_BINARY);
1007 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1009 return(MagickFalse);
1011 quantum=(size_t) MagickMaxBufferExtent;
1012 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1013 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1014 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1015 if (blob == (unsigned char *) NULL)
1017 ThrowFileException(&image->exception,ResourceLimitError,
1018 "MemoryAllocationFailed",filename);
1019 return(MagickFalse);
1023 count=(ssize_t) read(file,blob,quantum);
1030 length=(size_t) count;
1031 count=WriteBlobStream(image,length,blob);
1032 if (count != (ssize_t) length)
1034 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1040 blob=(unsigned char *) RelinquishMagickMemory(blob);
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049 + G e t B l o b E r r o r %
1053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1055 % GetBlobError() returns MagickTrue if the blob associated with the specified
1056 % image encountered an error.
1058 % The format of the GetBlobError method is:
1060 % MagickBooleanType GetBlobError(const Image *image)
1062 % A description of each parameter follows:
1064 % o image: the image.
1067 MagickExport MagickBooleanType GetBlobError(const Image *image)
1069 assert(image != (const Image *) NULL);
1070 assert(image->signature == MagickSignature);
1071 if (image->debug != MagickFalse)
1072 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1073 return(image->blob->status);
1077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081 + G e t B l o b F i l e H a n d l e %
1085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087 % GetBlobFileHandle() returns the file handle associated with the image blob.
1089 % The format of the GetBlobFile method is:
1091 % FILE *GetBlobFileHandle(const Image *image)
1093 % A description of each parameter follows:
1095 % o image: the image.
1098 MagickExport FILE *GetBlobFileHandle(const Image *image)
1100 assert(image != (const Image *) NULL);
1101 assert(image->signature == MagickSignature);
1102 return(image->blob->file);
1106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110 + G e t B l o b I n f o %
1114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1116 % GetBlobInfo() initializes the BlobInfo structure.
1118 % The format of the GetBlobInfo method is:
1120 % void GetBlobInfo(BlobInfo *blob_info)
1122 % A description of each parameter follows:
1124 % o blob_info: Specifies a pointer to a BlobInfo structure.
1127 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1129 assert(blob_info != (BlobInfo *) NULL);
1130 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1131 blob_info->type=UndefinedStream;
1132 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1133 blob_info->properties.st_mtime=time((time_t *) NULL);
1134 blob_info->properties.st_ctime=time((time_t *) NULL);
1135 blob_info->debug=IsEventLogging();
1136 blob_info->reference_count=1;
1137 blob_info->semaphore=AllocateSemaphoreInfo();
1138 blob_info->signature=MagickSignature;
1142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1146 % G e t B l o b P r o p e r t i e s %
1150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1152 % GetBlobProperties() returns information about an image blob.
1154 % The format of the GetBlobProperties method is:
1156 % const struct stat *GetBlobProperties(const Image *image)
1158 % A description of each parameter follows:
1160 % o image: the image.
1163 MagickExport const struct stat *GetBlobProperties(const Image *image)
1165 assert(image != (Image *) NULL);
1166 assert(image->signature == MagickSignature);
1167 if (image->debug != MagickFalse)
1168 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1169 return(&image->blob->properties);
1173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177 + G e t B l o b S i z e %
1181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1183 % GetBlobSize() returns the current length of the image file or blob; zero is
1184 % returned if the size cannot be determined.
1186 % The format of the GetBlobSize method is:
1188 % MagickSizeType GetBlobSize(const Image *image)
1190 % A description of each parameter follows:
1192 % o image: the image.
1195 MagickExport MagickSizeType GetBlobSize(const Image *image)
1200 assert(image != (Image *) NULL);
1201 assert(image->signature == MagickSignature);
1202 if (image->debug != MagickFalse)
1203 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1204 assert(image->blob != (BlobInfo *) NULL);
1206 switch (image->blob->type)
1208 case UndefinedStream:
1210 extent=image->blob->size;
1215 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1216 extent=(MagickSizeType) image->blob->properties.st_size;
1219 case StandardStream:
1222 extent=image->blob->size;
1231 status=GetPathAttributes(image->filename,&image->blob->properties);
1232 if (status != MagickFalse)
1233 extent=(MagickSizeType) image->blob->properties.st_size;
1240 extent=(MagickSizeType) image->blob->length;
1248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1252 + G e t B l o b S t r e a m D a t a %
1256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1258 % GetBlobStreamData() returns the stream data for the image.
1260 % The format of the GetBlobStreamData method is:
1262 % unsigned char *GetBlobStreamData(const Image *image)
1264 % A description of each parameter follows:
1266 % o image: the image.
1269 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1271 assert(image != (const Image *) NULL);
1272 assert(image->signature == MagickSignature);
1273 return(image->blob->data);
1277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1281 + G e t B l o b S t r e a m H a n d l e r %
1285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1287 % GetBlobStreamHandler() returns the stream handler for the image.
1289 % The format of the GetBlobStreamHandler method is:
1291 % StreamHandler GetBlobStreamHandler(const Image *image)
1293 % A description of each parameter follows:
1295 % o image: the image.
1298 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1300 assert(image != (const Image *) NULL);
1301 assert(image->signature == MagickSignature);
1302 if (image->debug != MagickFalse)
1303 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1304 return(image->blob->stream);
1308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1312 % I m a g e T o B l o b %
1316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318 % ImageToBlob() implements direct to memory image formats. It returns the
1319 % image as a blob and its length. The magick member of the ImageInfo structure
1320 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1322 % The format of the ImageToBlob method is:
1324 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1325 % size_t *length,ExceptionInfo *exception)
1327 % A description of each parameter follows:
1329 % o image_info: the image info.
1331 % o image: the image.
1333 % o length: This pointer to a size_t integer sets the initial length of the
1334 % blob. On return, it reflects the actual length of the blob.
1336 % o exception: return any errors or warnings in this structure.
1339 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1340 Image *image,size_t *length,ExceptionInfo *exception)
1354 assert(image_info != (const ImageInfo *) NULL);
1355 assert(image_info->signature == MagickSignature);
1356 if (image_info->debug != MagickFalse)
1357 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1358 image_info->filename);
1359 assert(image != (Image *) NULL);
1360 assert(image->signature == MagickSignature);
1361 assert(exception != (ExceptionInfo *) NULL);
1363 blob=(unsigned char *) NULL;
1364 blob_info=CloneImageInfo(image_info);
1365 blob_info->adjoin=MagickFalse;
1366 (void) SetImageInfo(blob_info,1,exception);
1367 if (*blob_info->magick != '\0')
1368 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1369 magick_info=GetMagickInfo(image->magick,exception);
1370 if (magick_info == (const MagickInfo *) NULL)
1372 (void) ThrowMagickException(exception,GetMagickModule(),
1373 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1377 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1378 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1381 Native blob support for this image format.
1383 blob_info->length=0;
1384 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1385 sizeof(unsigned char));
1386 if (blob_info->blob == (void *) NULL)
1387 (void) ThrowMagickException(exception,GetMagickModule(),
1388 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1391 (void) CloseBlob(image);
1392 image->blob->exempt=MagickTrue;
1393 *image->filename='\0';
1394 status=WriteImage(blob_info,image);
1395 if ((status == MagickFalse) || (image->blob->length == 0))
1396 InheritException(exception,&image->exception);
1399 *length=image->blob->length;
1400 blob=DetachBlob(image->blob);
1401 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1409 unique[MaxTextExtent];
1415 Write file to disk in blob image format.
1417 file=AcquireUniqueFileResource(unique);
1420 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1421 image_info->filename);
1425 blob_info->file=fdopen(file,"wb");
1426 if (blob_info->file != (FILE *) NULL)
1428 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1429 image->magick,unique);
1430 status=WriteImage(blob_info,image);
1431 (void) fclose(blob_info->file);
1432 if (status == MagickFalse)
1433 InheritException(exception,&image->exception);
1435 blob=FileToBlob(image->filename,~0UL,length,exception);
1437 (void) RelinquishUniqueFileResource(unique);
1440 blob_info=DestroyImageInfo(blob_info);
1445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1449 % I m a g e T o F i l e %
1453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1455 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1456 % occurs otherwise MagickTrue.
1458 % The format of the ImageToFile method is:
1460 % MagickBooleanType ImageToFile(Image *image,char *filename,
1461 % ExceptionInfo *exception)
1463 % A description of each parameter follows:
1465 % o image: the image.
1467 % o filename: Write the image to this file.
1469 % o exception: return any errors or warnings in this structure.
1473 static inline const unsigned char *ReadBlobStream(Image *image,
1474 const size_t length,unsigned char *data,ssize_t *count)
1476 assert(count != (ssize_t *) NULL);
1477 assert(image->blob != (BlobInfo *) NULL);
1478 if (image->blob->type != BlobStream)
1480 *count=ReadBlob(image,length,data);
1483 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1486 image->blob->eof=MagickTrue;
1489 data=image->blob->data+image->blob->offset;
1490 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
1491 image->blob->offset));
1492 image->blob->offset+=(*count);
1493 if (*count != (ssize_t) length)
1494 image->blob->eof=MagickTrue;
1498 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1499 ExceptionInfo *exception)
1504 register const unsigned char
1523 assert(image != (Image *) NULL);
1524 assert(image->signature == MagickSignature);
1525 assert(image->blob != (BlobInfo *) NULL);
1526 assert(image->blob->type != UndefinedStream);
1527 if (image->debug != MagickFalse)
1528 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1529 assert(filename != (const char *) NULL);
1530 if (*filename == '\0')
1531 file=AcquireUniqueFileResource(filename);
1533 if (LocaleCompare(filename,"-") == 0)
1534 file=fileno(stdout);
1536 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1539 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1540 return(MagickFalse);
1542 quantum=(size_t) MagickMaxBufferExtent;
1543 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1544 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1545 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1546 if (buffer == (unsigned char *) NULL)
1549 (void) ThrowMagickException(exception,GetMagickModule(),
1550 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1551 return(MagickFalse);
1554 p=ReadBlobStream(image,quantum,buffer,&count);
1555 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1557 length=(size_t) count;
1558 for (i=0; i < length; i+=count)
1560 count=write(file,p+i,(size_t) (length-i));
1572 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1575 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1576 return(MagickFalse);
1582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1586 % I m a g e s T o B l o b %
1590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1592 % ImagesToBlob() implements direct to memory image formats. It returns the
1593 % image sequence as a blob and its length. The magick member of the ImageInfo
1594 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1596 % Note, some image formats do not permit multiple images to the same image
1597 % stream (e.g. JPEG). in this instance, just the first image of the
1598 % sequence is returned as a blob.
1600 % The format of the ImagesToBlob method is:
1602 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1603 % size_t *length,ExceptionInfo *exception)
1605 % A description of each parameter follows:
1607 % o image_info: the image info.
1609 % o images: the image list.
1611 % o length: This pointer to a size_t integer sets the initial length of the
1612 % blob. On return, it reflects the actual length of the blob.
1614 % o exception: return any errors or warnings in this structure.
1617 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1618 Image *images,size_t *length,ExceptionInfo *exception)
1632 assert(image_info != (const ImageInfo *) NULL);
1633 assert(image_info->signature == MagickSignature);
1634 if (image_info->debug != MagickFalse)
1635 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1636 image_info->filename);
1637 assert(images != (Image *) NULL);
1638 assert(images->signature == MagickSignature);
1639 assert(exception != (ExceptionInfo *) NULL);
1641 blob=(unsigned char *) NULL;
1642 blob_info=CloneImageInfo(image_info);
1643 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1645 if (*blob_info->magick != '\0')
1646 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1647 if (blob_info->adjoin == MagickFalse)
1649 blob_info=DestroyImageInfo(blob_info);
1650 return(ImageToBlob(image_info,images,length,exception));
1652 magick_info=GetMagickInfo(images->magick,exception);
1653 if (magick_info == (const MagickInfo *) NULL)
1655 (void) ThrowMagickException(exception,GetMagickModule(),
1656 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1660 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1661 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1664 Native blob support for this images format.
1666 blob_info->length=0;
1667 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1668 sizeof(unsigned char));
1669 if (blob_info->blob == (void *) NULL)
1670 (void) ThrowMagickException(exception,GetMagickModule(),
1671 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1674 images->blob->exempt=MagickTrue;
1675 *images->filename='\0';
1676 status=WriteImages(blob_info,images,images->filename,exception);
1677 if ((status == MagickFalse) || (images->blob->length == 0))
1678 InheritException(exception,&images->exception);
1681 *length=images->blob->length;
1682 blob=DetachBlob(images->blob);
1683 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1691 filename[MaxTextExtent],
1692 unique[MaxTextExtent];
1698 Write file to disk in blob images format.
1700 file=AcquireUniqueFileResource(unique);
1703 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1704 image_info->filename);
1708 blob_info->file=fdopen(file,"wb");
1709 if (blob_info->file != (FILE *) NULL)
1711 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1712 images->magick,unique);
1713 status=WriteImages(blob_info,images,filename,exception);
1714 (void) fclose(blob_info->file);
1715 if (status == MagickFalse)
1716 InheritException(exception,&images->exception);
1718 blob=FileToBlob(images->filename,~0UL,length,exception);
1720 (void) RelinquishUniqueFileResource(unique);
1723 blob_info=DestroyImageInfo(blob_info);
1727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1731 % I n j e c t I m a g e B l o b %
1735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1737 % InjectImageBlob() injects the image with a copy of itself in the specified
1738 % format (e.g. inject JPEG into a PDF image).
1740 % The format of the InjectImageBlob method is:
1742 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1743 % Image *image,Image *inject_image,const char *format,
1744 % ExceptionInfo *exception)
1746 % A description of each parameter follows:
1748 % o image_info: the image info..
1750 % o image: the image.
1752 % o inject_image: inject into the image stream.
1754 % o format: the image format.
1756 % o exception: return any errors or warnings in this structure.
1759 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1760 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1763 filename[MaxTextExtent];
1796 Write inject image to a temporary file.
1798 assert(image_info != (ImageInfo *) NULL);
1799 assert(image_info->signature == MagickSignature);
1800 assert(image != (Image *) NULL);
1801 assert(image->signature == MagickSignature);
1802 if (image->debug != MagickFalse)
1803 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1804 assert(inject_image != (Image *) NULL);
1805 assert(inject_image->signature == MagickSignature);
1806 assert(exception != (ExceptionInfo *) NULL);
1807 unique_file=(FILE *) NULL;
1808 file=AcquireUniqueFileResource(filename);
1810 unique_file=fdopen(file,"wb");
1811 if ((file == -1) || (unique_file == (FILE *) NULL))
1813 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1814 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1816 return(MagickFalse);
1818 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1819 if (byte_image == (Image *) NULL)
1821 (void) fclose(unique_file);
1822 (void) RelinquishUniqueFileResource(filename);
1823 return(MagickFalse);
1825 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1827 DestroyBlob(byte_image);
1828 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1829 write_info=CloneImageInfo(image_info);
1830 SetImageInfoFile(write_info,unique_file);
1831 status=WriteImage(write_info,byte_image);
1832 write_info=DestroyImageInfo(write_info);
1833 byte_image=DestroyImage(byte_image);
1834 (void) fclose(unique_file);
1835 if (status == MagickFalse)
1837 (void) RelinquishUniqueFileResource(filename);
1838 return(MagickFalse);
1841 Inject into image stream.
1843 file=open(filename,O_RDONLY | O_BINARY);
1846 (void) RelinquishUniqueFileResource(filename);
1847 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1848 image_info->filename);
1849 return(MagickFalse);
1851 quantum=(size_t) MagickMaxBufferExtent;
1852 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1853 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1854 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1855 if (buffer == (unsigned char *) NULL)
1857 (void) RelinquishUniqueFileResource(filename);
1858 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1861 for (i=0; ; i+=count)
1863 count=(ssize_t) read(file,buffer,quantum);
1870 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1874 (void) RelinquishUniqueFileResource(filename);
1875 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1884 + I s B l o b E x e m p t %
1888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1890 % IsBlobExempt() returns true if the blob is exempt.
1892 % The format of the IsBlobExempt method is:
1894 % MagickBooleanType IsBlobExempt(const Image *image)
1896 % A description of each parameter follows:
1898 % o image: the image.
1901 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1903 assert(image != (const Image *) NULL);
1904 assert(image->signature == MagickSignature);
1905 if (image->debug != MagickFalse)
1906 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1907 return(image->blob->exempt);
1911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1915 + I s B l o b S e e k a b l e %
1919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1921 % IsBlobSeekable() returns true if the blob is seekable.
1923 % The format of the IsBlobSeekable method is:
1925 % MagickBooleanType IsBlobSeekable(const Image *image)
1927 % A description of each parameter follows:
1929 % o image: the image.
1932 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
1937 assert(image != (const Image *) NULL);
1938 assert(image->signature == MagickSignature);
1939 if (image->debug != MagickFalse)
1940 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1941 seekable=(image->blob->type == FileStream) ||
1942 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
1947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1951 + I s B l o b T e m p o r a r y %
1955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1957 % IsBlobTemporary() returns true if the blob is temporary.
1959 % The format of the IsBlobTemporary method is:
1961 % MagickBooleanType IsBlobTemporary(const Image *image)
1963 % A description of each parameter follows:
1965 % o image: the image.
1968 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
1970 assert(image != (const Image *) NULL);
1971 assert(image->signature == MagickSignature);
1972 if (image->debug != MagickFalse)
1973 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1974 return(image->blob->temporary);
1978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1988 % MapBlob() creates a mapping from a file to a binary large object.
1990 % The format of the MapBlob method is:
1992 % unsigned char *MapBlob(int file,const MapMode mode,
1993 % const MagickOffsetType offset,const size_t length)
1995 % A description of each parameter follows:
1997 % o file: map this file descriptor.
1999 % o mode: ReadMode, WriteMode, or IOMode.
2001 % o offset: starting at this offset within the file.
2003 % o length: the length of the mapping is returned in this pointer.
2006 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2007 const MagickOffsetType offset,const size_t length)
2009 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2022 #if defined(MAP_ANONYMOUS)
2023 flags|=MAP_ANONYMOUS;
2025 return((unsigned char *) NULL);
2032 protection=PROT_READ;
2034 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2040 protection=PROT_WRITE;
2042 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2044 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2045 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2046 POSIX_MADV_WILLNEED);
2052 protection=PROT_READ | PROT_WRITE;
2054 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2059 if (map == (unsigned char *) MAP_FAILED)
2060 return((unsigned char *) NULL);
2067 return((unsigned char *) NULL);
2072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2076 + M S B O r d e r L o n g %
2080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2082 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2083 % most-significant byte first.
2085 % The format of the MSBOrderLong method is:
2087 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2089 % A description of each parameter follows.
2091 % o buffer: Specifies a pointer to a buffer of integers.
2093 % o length: Specifies the length of the buffer.
2096 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2101 register unsigned char
2105 assert(buffer != (unsigned char *) NULL);
2112 *buffer++=(unsigned char) c;
2116 *buffer++=(unsigned char) c;
2122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2126 + M S B O r d e r S h o r t %
2130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2132 % MSBOrderShort() converts a least-significant byte first buffer of integers
2133 % to most-significant byte first.
2135 % The format of the MSBOrderShort method is:
2137 % void MSBOrderShort(unsigned char *p,const size_t length)
2139 % A description of each parameter follows.
2141 % o p: Specifies a pointer to a buffer of integers.
2143 % o length: Specifies the length of the buffer.
2146 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2151 register unsigned char
2154 assert(p != (unsigned char *) NULL);
2161 *p++=(unsigned char) c;
2166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2176 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2177 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2178 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2179 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2180 % from a system command.
2182 % The format of the OpenBlob method is:
2184 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2185 % const BlobMode mode,ExceptionInfo *exception)
2187 % A description of each parameter follows:
2189 % o image_info: the image info.
2191 % o image: the image.
2193 % o mode: the mode for opening the file.
2196 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2197 Image *image,const BlobMode mode,ExceptionInfo *exception)
2200 extension[MaxTextExtent],
2201 filename[MaxTextExtent];
2212 assert(image_info != (ImageInfo *) NULL);
2213 assert(image_info->signature == MagickSignature);
2214 if (image_info->debug != MagickFalse)
2215 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2216 image_info->filename);
2217 assert(image != (Image *) NULL);
2218 assert(image->signature == MagickSignature);
2219 if (image_info->blob != (void *) NULL)
2221 if (image_info->stream != (StreamHandler) NULL)
2222 image->blob->stream=(StreamHandler) image_info->stream;
2223 AttachBlob(image->blob,image_info->blob,image_info->length);
2226 (void) DetachBlob(image->blob);
2229 default: type="r"; break;
2230 case ReadBlobMode: type="r"; break;
2231 case ReadBinaryBlobMode: type="rb"; break;
2232 case WriteBlobMode: type="w"; break;
2233 case WriteBinaryBlobMode: type="w+b"; break;
2234 case AppendBlobMode: type="a"; break;
2235 case AppendBinaryBlobMode: type="a+b"; break;
2238 image->blob->synchronize=image_info->synchronize;
2239 if (image_info->stream != (StreamHandler) NULL)
2241 image->blob->stream=(StreamHandler) image_info->stream;
2244 image->blob->type=FifoStream;
2252 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2253 rights=ReadPolicyRights;
2255 rights=WritePolicyRights;
2256 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2259 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2260 "NotAuthorized","`%s'",filename);
2261 return(MagickFalse);
2263 if ((LocaleCompare(filename,"-") == 0) ||
2264 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2266 image->blob->file=(*type == 'r') ? stdin : stdout;
2267 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2268 if (strchr(type,'b') != (char *) NULL)
2269 setmode(_fileno(image->blob->file),_O_BINARY);
2271 image->blob->type=StandardStream;
2272 image->blob->exempt=MagickTrue;
2275 if (LocaleNCompare(filename,"fd:",3) == 0)
2278 mode[MaxTextExtent];
2282 image->blob->file=fdopen(StringToLong(filename+3),mode);
2283 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2284 if (strchr(type,'b') != (char *) NULL)
2285 setmode(_fileno(image->blob->file),_O_BINARY);
2287 image->blob->type=StandardStream;
2288 image->blob->exempt=MagickTrue;
2291 #if defined(MAGICKCORE_HAVE_POPEN)
2292 if (*filename == '|')
2295 mode[MaxTextExtent];
2298 Pipe image to or from a system command.
2300 #if defined(SIGPIPE)
2302 (void) signal(SIGPIPE,SIG_IGN);
2306 image->blob->file=(FILE *) popen(filename+1,mode);
2307 if (image->blob->file == (FILE *) NULL)
2309 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2310 return(MagickFalse);
2312 image->blob->type=PipeStream;
2313 image->blob->exempt=MagickTrue;
2317 status=GetPathAttributes(filename,&image->blob->properties);
2318 #if defined(S_ISFIFO)
2319 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2321 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2322 if (image->blob->file == (FILE *) NULL)
2324 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2325 return(MagickFalse);
2327 image->blob->type=FileStream;
2328 image->blob->exempt=MagickTrue;
2332 GetPathComponent(image->filename,ExtensionPath,extension);
2335 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2336 if ((image_info->adjoin == MagickFalse) ||
2337 (IsGlob(filename) != MagickFalse))
2340 Form filename for multi-part images.
2342 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2343 image->scene,filename);
2344 if ((LocaleCompare(filename,image->filename) == 0) &&
2345 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2346 (GetNextImageInList(image) != (Image *) NULL)))
2349 path[MaxTextExtent];
2351 GetPathComponent(image->filename,RootPath,path);
2352 if (*extension == '\0')
2353 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2354 path,(double) image->scene);
2356 (void) FormatMagickString(filename,MaxTextExtent,
2357 "%s-%.20g.%s",path,(double) image->scene,extension);
2359 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2360 #if defined(macintosh)
2361 SetApplicationType(filename,image_info->magick,'8BIM');
2365 if (image_info->file != (FILE *) NULL)
2367 image->blob->file=image_info->file;
2368 image->blob->type=FileStream;
2369 image->blob->exempt=MagickTrue;
2374 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2375 if (image->blob->file != (FILE *) NULL)
2383 image->blob->type=FileStream;
2384 #if defined(MAGICKCORE_HAVE_SETVBUF)
2385 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2388 (void) ResetMagickMemory(magick,0,sizeof(magick));
2389 count=fread(magick,1,sizeof(magick),image->blob->file);
2390 (void) rewind(image->blob->file);
2391 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2392 " read %.20g magic header bytes",(double) count);
2393 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2394 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2395 ((int) magick[2] == 0x08))
2397 (void) fclose(image->blob->file);
2398 image->blob->file=(FILE *) gzopen(filename,type);
2399 if (image->blob->file != (FILE *) NULL)
2400 image->blob->type=ZipStream;
2403 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2404 if (strncmp((char *) magick,"BZh",3) == 0)
2406 (void) fclose(image->blob->file);
2407 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2408 if (image->blob->file != (FILE *) NULL)
2409 image->blob->type=BZipStream;
2412 if (image->blob->type == FileStream)
2423 sans_exception=AcquireExceptionInfo();
2424 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2425 sans_exception=DestroyExceptionInfo(sans_exception);
2426 properties=(&image->blob->properties);
2427 if ((magick_info != (const MagickInfo *) NULL) &&
2428 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2429 (properties->st_size <= MagickMaxBufferExtent))
2437 length=(size_t) properties->st_size;
2438 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2439 if (blob != (void *) NULL)
2442 Format supports blobs-- use memory-mapped I/O.
2444 if (image_info->file != (FILE *) NULL)
2445 image->blob->exempt=MagickFalse;
2448 (void) fclose(image->blob->file);
2449 image->blob->file=(FILE *) NULL;
2451 AttachBlob(image->blob,blob,length);
2452 image->blob->mapped=MagickTrue;
2459 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2460 if ((LocaleCompare(extension,"Z") == 0) ||
2461 (LocaleCompare(extension,"gz") == 0) ||
2462 (LocaleCompare(extension,"wmz") == 0) ||
2463 (LocaleCompare(extension,"svgz") == 0))
2465 if (mode == WriteBinaryBlobMode)
2467 image->blob->file=(FILE *) gzopen(filename,type);
2468 if (image->blob->file != (FILE *) NULL)
2469 image->blob->type=ZipStream;
2473 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2474 if (LocaleCompare(extension,".bz2") == 0)
2476 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2477 if (image->blob->file != (FILE *) NULL)
2478 image->blob->type=BZipStream;
2483 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2484 if (image->blob->file != (FILE *) NULL)
2486 image->blob->type=FileStream;
2487 #if defined(MAGICKCORE_HAVE_SETVBUF)
2488 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2493 image->blob->status=MagickFalse;
2494 if (image->blob->type != UndefinedStream)
2495 image->blob->size=GetBlobSize(image);
2498 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2499 return(MagickFalse);
2505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2515 % PingBlob() returns all the attributes of an image or image sequence except
2516 % for the pixels. It is much faster and consumes far less memory than
2517 % BlobToImage(). On failure, a NULL image is returned and exception
2518 % describes the reason for the failure.
2520 % The format of the PingBlob method is:
2522 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2523 % const size_t length,ExceptionInfo *exception)
2525 % A description of each parameter follows:
2527 % o image_info: the image info.
2529 % o blob: the address of a character stream in one of the image formats
2530 % understood by ImageMagick.
2532 % o length: This size_t integer reflects the length in bytes of the blob.
2534 % o exception: return any errors or warnings in this structure.
2538 #if defined(__cplusplus) || defined(c_plusplus)
2542 static size_t PingStream(const Image *magick_unused(image),
2543 const void *magick_unused(pixels),const size_t columns)
2548 #if defined(__cplusplus) || defined(c_plusplus)
2552 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2553 const size_t length,ExceptionInfo *exception)
2561 assert(image_info != (ImageInfo *) NULL);
2562 assert(image_info->signature == MagickSignature);
2563 if (image_info->debug != MagickFalse)
2564 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2565 image_info->filename);
2566 assert(exception != (ExceptionInfo *) NULL);
2567 if ((blob == (const void *) NULL) || (length == 0))
2569 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2570 "UnrecognizedImageFormat","`%s'",image_info->magick);
2571 return((Image *) NULL);
2573 ping_info=CloneImageInfo(image_info);
2574 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2575 if (ping_info->blob == (const void *) NULL)
2577 (void) ThrowMagickException(exception,GetMagickModule(),
2578 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2579 return((Image *) NULL);
2581 (void) CopyMagickMemory(ping_info->blob,blob,length);
2582 ping_info->length=length;
2583 ping_info->ping=MagickTrue;
2584 image=ReadStream(ping_info,&PingStream,exception);
2585 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2586 ping_info=DestroyImageInfo(ping_info);
2591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2601 % ReadBlob() reads data from the blob or image file and returns it. It
2602 % returns the number of bytes read.
2604 % The format of the ReadBlob method is:
2606 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2608 % A description of each parameter follows:
2610 % o image: the image.
2612 % o length: Specifies an integer representing the number of bytes to read
2615 % o data: Specifies an area to place the information requested from the
2619 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2620 unsigned char *data)
2625 register unsigned char
2631 assert(image != (Image *) NULL);
2632 assert(image->signature == MagickSignature);
2633 assert(image->blob != (BlobInfo *) NULL);
2634 assert(image->blob->type != UndefinedStream);
2637 assert(data != (void *) NULL);
2640 switch (image->blob->type)
2642 case UndefinedStream:
2645 case StandardStream:
2652 count=(ssize_t) fread(q,1,length,image->blob->file);
2657 c=getc(image->blob->file);
2660 *q++=(unsigned char) c;
2665 c=getc(image->blob->file);
2668 *q++=(unsigned char) c;
2678 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2683 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2688 c=gzgetc(image->blob->file);
2691 *q++=(unsigned char) c;
2696 c=gzgetc(image->blob->file);
2699 *q++=(unsigned char) c;
2710 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2711 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2719 register const unsigned char
2722 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2724 image->blob->eof=MagickTrue;
2727 p=image->blob->data+image->blob->offset;
2728 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2729 image->blob->offset));
2730 image->blob->offset+=count;
2731 if (count != (ssize_t) length)
2732 image->blob->eof=MagickTrue;
2733 (void) CopyMagickMemory(q,p,(size_t) count);
2741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2745 + R e a d B l o b B y t e %
2749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2751 % ReadBlobByte() reads a single byte from the image file and returns it.
2753 % The format of the ReadBlobByte method is:
2755 % int ReadBlobByte(Image *image)
2757 % A description of each parameter follows.
2759 % o image: the image.
2762 MagickExport int ReadBlobByte(Image *image)
2764 register const unsigned char
2773 assert(image != (Image *) NULL);
2774 assert(image->signature == MagickSignature);
2775 p=ReadBlobStream(image,1,buffer,&count);
2782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2786 + R e a d B l o b D o u b l e %
2790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2792 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2793 % specified by the endian member of the image structure.
2795 % The format of the ReadBlobDouble method is:
2797 % double ReadBlobDouble(Image *image)
2799 % A description of each parameter follows.
2801 % o image: the image.
2804 MagickExport double ReadBlobDouble(Image *image)
2815 quantum.double_value=0.0;
2816 quantum.unsigned_value=ReadBlobLongLong(image);
2817 return(quantum.double_value);
2821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2825 + R e a d B l o b F l o a t %
2829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2831 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2832 % specified by the endian member of the image structure.
2834 % The format of the ReadBlobFloat method is:
2836 % float ReadBlobFloat(Image *image)
2838 % A description of each parameter follows.
2840 % o image: the image.
2843 MagickExport float ReadBlobFloat(Image *image)
2854 quantum.float_value=0.0;
2855 quantum.unsigned_value=ReadBlobLong(image);
2856 return(quantum.float_value);
2860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2864 + R e a d B l o b L o n g %
2868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2870 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2871 % specified by the endian member of the image structure.
2873 % The format of the ReadBlobLong method is:
2875 % unsigned int ReadBlobLong(Image *image)
2877 % A description of each parameter follows.
2879 % o image: the image.
2882 MagickExport unsigned int ReadBlobLong(Image *image)
2884 register const unsigned char
2896 assert(image != (Image *) NULL);
2897 assert(image->signature == MagickSignature);
2899 p=ReadBlobStream(image,4,buffer,&count);
2902 if (image->endian == LSBEndian)
2904 value=(unsigned int) (*p++);
2905 value|=((unsigned int) (*p++)) << 8;
2906 value|=((unsigned int) (*p++)) << 16;
2907 value|=((unsigned int) (*p++)) << 24;
2910 value=((unsigned int) (*p++)) << 24;
2911 value|=((unsigned int) (*p++)) << 16;
2912 value|=((unsigned int) (*p++)) << 8;
2913 value|=((unsigned int) (*p++));
2918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2922 + R e a d B l o b L o n g L o n g %
2926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2928 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
2929 % byte-order specified by the endian member of the image structure.
2931 % The format of the ReadBlobLongLong method is:
2933 % MagickSizeType ReadBlobLongLong(Image *image)
2935 % A description of each parameter follows.
2937 % o image: the image.
2940 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
2942 register const unsigned char
2954 assert(image != (Image *) NULL);
2955 assert(image->signature == MagickSignature);
2957 p=ReadBlobStream(image,8,buffer,&count);
2959 return(MagickULLConstant(0));
2960 if (image->endian == LSBEndian)
2962 value=(MagickSizeType) (*p++);
2963 value|=((MagickSizeType) (*p++)) << 8;
2964 value|=((MagickSizeType) (*p++)) << 16;
2965 value|=((MagickSizeType) (*p++)) << 24;
2966 value|=((MagickSizeType) (*p++)) << 32;
2967 value|=((MagickSizeType) (*p++)) << 40;
2968 value|=((MagickSizeType) (*p++)) << 48;
2969 value|=((MagickSizeType) (*p++)) << 56;
2970 return(value & MagickULLConstant(0xffffffffffffffff));
2972 value=((MagickSizeType) (*p++)) << 56;
2973 value|=((MagickSizeType) (*p++)) << 48;
2974 value|=((MagickSizeType) (*p++)) << 40;
2975 value|=((MagickSizeType) (*p++)) << 32;
2976 value|=((MagickSizeType) (*p++)) << 24;
2977 value|=((MagickSizeType) (*p++)) << 16;
2978 value|=((MagickSizeType) (*p++)) << 8;
2979 value|=((MagickSizeType) (*p++));
2980 return(value & MagickULLConstant(0xffffffffffffffff));
2984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2988 + R e a d B l o b S h o r t %
2992 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2994 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
2995 % specified by the endian member of the image structure.
2997 % The format of the ReadBlobShort method is:
2999 % unsigned short ReadBlobShort(Image *image)
3001 % A description of each parameter follows.
3003 % o image: the image.
3006 MagickExport unsigned short ReadBlobShort(Image *image)
3008 register const unsigned char
3011 register unsigned int
3020 assert(image != (Image *) NULL);
3021 assert(image->signature == MagickSignature);
3023 p=ReadBlobStream(image,2,buffer,&count);
3025 return((unsigned short) 0U);
3026 if (image->endian == LSBEndian)
3028 value=(unsigned int) (*p++);
3029 value|=((unsigned int) (*p++)) << 8;
3030 return((unsigned short) (value & 0xffff));
3032 value=(unsigned int) ((*p++) << 8);
3033 value|=(unsigned int) (*p++);
3034 return((unsigned short) (value & 0xffff));
3038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3042 + R e a d B l o b L S B L o n g %
3046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3048 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3049 % least-significant byte first order.
3051 % The format of the ReadBlobLSBLong method is:
3053 % unsigned int ReadBlobLSBLong(Image *image)
3055 % A description of each parameter follows.
3057 % o image: the image.
3060 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3062 register const unsigned char
3065 register unsigned int
3074 assert(image != (Image *) NULL);
3075 assert(image->signature == MagickSignature);
3077 p=ReadBlobStream(image,4,buffer,&count);
3080 value=(unsigned int) (*p++);
3081 value|=((unsigned int) (*p++)) << 8;
3082 value|=((unsigned int) (*p++)) << 16;
3083 value|=((unsigned int) (*p++)) << 24;
3088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3092 + R e a d B l o b L S B S h o r t %
3096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3098 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3099 % least-significant byte first order.
3101 % The format of the ReadBlobLSBShort method is:
3103 % unsigned short ReadBlobLSBShort(Image *image)
3105 % A description of each parameter follows.
3107 % o image: the image.
3110 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3112 register const unsigned char
3115 register unsigned int
3124 assert(image != (Image *) NULL);
3125 assert(image->signature == MagickSignature);
3127 p=ReadBlobStream(image,2,buffer,&count);
3129 return((unsigned short) 0U);
3130 value=(unsigned int) (*p++);
3131 value|=((unsigned int) ((*p++)) << 8);
3132 return((unsigned short) (value & 0xffff));
3136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3140 + R e a d B l o b M S B L o n g %
3144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3146 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3147 % most-significant byte first order.
3149 % The format of the ReadBlobMSBLong method is:
3151 % unsigned int ReadBlobMSBLong(Image *image)
3153 % A description of each parameter follows.
3155 % o image: the image.
3158 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3160 register const unsigned char
3163 register unsigned int
3172 assert(image != (Image *) NULL);
3173 assert(image->signature == MagickSignature);
3175 p=ReadBlobStream(image,4,buffer,&count);
3178 value=((unsigned int) (*p++) << 24);
3179 value|=((unsigned int) (*p++) << 16);
3180 value|=((unsigned int) (*p++) << 8);
3181 value|=(unsigned int) (*p++);
3186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3190 + R e a d B l o b M S B L o n g L o n g %
3194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3196 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3197 % most-significant byte first order.
3199 % The format of the ReadBlobMSBLongLong method is:
3201 % unsigned int ReadBlobMSBLongLong(Image *image)
3203 % A description of each parameter follows.
3205 % o image: the image.
3208 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3210 register const unsigned char
3213 register MagickSizeType
3222 assert(image != (Image *) NULL);
3223 assert(image->signature == MagickSignature);
3225 p=ReadBlobStream(image,8,buffer,&count);
3227 return(MagickULLConstant(0));
3228 value=((MagickSizeType) (*p++)) << 56;
3229 value|=((MagickSizeType) (*p++)) << 48;
3230 value|=((MagickSizeType) (*p++)) << 40;
3231 value|=((MagickSizeType) (*p++)) << 32;
3232 value|=((MagickSizeType) (*p++)) << 24;
3233 value|=((MagickSizeType) (*p++)) << 16;
3234 value|=((MagickSizeType) (*p++)) << 8;
3235 value|=((MagickSizeType) (*p++));
3236 return(value & MagickULLConstant(0xffffffffffffffff));
3240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3244 + R e a d B l o b M S B S h o r t %
3248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3250 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3251 % most-significant byte first order.
3253 % The format of the ReadBlobMSBShort method is:
3255 % unsigned short ReadBlobMSBShort(Image *image)
3257 % A description of each parameter follows.
3259 % o image: the image.
3262 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3264 register const unsigned char
3267 register unsigned int
3276 assert(image != (Image *) NULL);
3277 assert(image->signature == MagickSignature);
3279 p=ReadBlobStream(image,2,buffer,&count);
3281 return((unsigned short) 0U);
3282 value=(unsigned int) ((*p++) << 8);
3283 value|=(unsigned int) (*p++);
3284 return((unsigned short) (value & 0xffff));
3288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3292 + R e a d B l o b S t r i n g %
3296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3298 % ReadBlobString() reads characters from a blob or file until a newline
3299 % character is read or an end-of-file condition is encountered.
3301 % The format of the ReadBlobString method is:
3303 % char *ReadBlobString(Image *image,char *string)
3305 % A description of each parameter follows:
3307 % o image: the image.
3309 % o string: the address of a character buffer.
3312 MagickExport char *ReadBlobString(Image *image,char *string)
3314 register const unsigned char
3326 assert(image != (Image *) NULL);
3327 assert(image->signature == MagickSignature);
3328 for (i=0; i < (MaxTextExtent-1L); i++)
3330 p=ReadBlobStream(image,1,buffer,&count);
3334 return((char *) NULL);
3337 string[i]=(char) (*p);
3338 if ((string[i] == '\r') || (string[i] == '\n'))
3341 if (string[i] == '\r')
3342 (void) ReadBlobStream(image,1,buffer,&count);
3348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3352 + R e f e r e n c e B l o b %
3356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3358 % ReferenceBlob() increments the reference count associated with the pixel
3359 % blob returning a pointer to the blob.
3361 % The format of the ReferenceBlob method is:
3363 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3365 % A description of each parameter follows:
3367 % o blob_info: the blob_info.
3370 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3372 assert(blob != (BlobInfo *) NULL);
3373 assert(blob->signature == MagickSignature);
3374 if (blob->debug != MagickFalse)
3375 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3376 LockSemaphoreInfo(blob->semaphore);
3377 blob->reference_count++;
3378 UnlockSemaphoreInfo(blob->semaphore);
3383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3393 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3394 % and returns the resulting offset.
3396 % The format of the SeekBlob method is:
3398 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3401 % A description of each parameter follows:
3403 % o image: the image.
3405 % o offset: Specifies an integer representing the offset in bytes.
3407 % o whence: Specifies an integer representing how the offset is
3408 % treated relative to the beginning of the blob as follows:
3410 % SEEK_SET Set position equal to offset bytes.
3411 % SEEK_CUR Set position to current location plus offset.
3412 % SEEK_END Set position to EOF plus offset.
3415 MagickExport MagickOffsetType SeekBlob(Image *image,
3416 const MagickOffsetType offset,const int whence)
3418 assert(image != (Image *) NULL);
3419 assert(image->signature == MagickSignature);
3420 if (image->debug != MagickFalse)
3421 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3422 assert(image->blob != (BlobInfo *) NULL);
3423 assert(image->blob->type != UndefinedStream);
3424 switch (image->blob->type)
3426 case UndefinedStream:
3430 if (fseek(image->blob->file,(long) offset,whence) < 0)
3432 image->blob->offset=TellBlob(image);
3435 case StandardStream:
3439 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3440 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3443 image->blob->offset=TellBlob(image);
3459 image->blob->offset=offset;
3464 if ((image->blob->offset+offset) < 0)
3466 image->blob->offset+=offset;
3471 if (((MagickOffsetType) image->blob->length+offset) < 0)
3473 image->blob->offset=image->blob->length+offset;
3477 if (image->blob->offset <= (MagickOffsetType)
3478 ((off_t) image->blob->length))
3479 image->blob->eof=MagickFalse;
3481 if (image->blob->mapped != MagickFalse)
3485 image->blob->extent=(size_t) (image->blob->offset+
3486 image->blob->quantum);
3487 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3488 image->blob->data,image->blob->extent+1,
3489 sizeof(*image->blob->data));
3490 (void) SyncBlob(image);
3491 if (image->blob->data == (unsigned char *) NULL)
3493 (void) DetachBlob(image->blob);
3500 return(image->blob->offset);
3504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3508 + S e t B l o b E x e m p t %
3512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3514 % SetBlobExempt() sets the blob exempt status.
3516 % The format of the SetBlobExempt method is:
3518 % MagickBooleanType SetBlobExempt(const Image *image,
3519 % const MagickBooleanType exempt)
3521 % A description of each parameter follows:
3523 % o image: the image.
3525 % o exempt: Set to true if this blob is exempt from being closed.
3528 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3530 assert(image != (const Image *) NULL);
3531 assert(image->signature == MagickSignature);
3532 if (image->debug != MagickFalse)
3533 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3534 image->blob->exempt=exempt;
3538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3542 + S e t B l o b E x t e n t %
3546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3548 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3549 % method is successful, subsequent writes to bytes in the specified range are
3550 % guaranteed not to fail.
3552 % The format of the SetBlobExtent method is:
3554 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3556 % A description of each parameter follows:
3558 % o image: the image.
3560 % o extent: the blob maximum extent.
3563 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3564 const MagickSizeType extent)
3566 assert(image != (Image *) NULL);
3567 assert(image->signature == MagickSignature);
3568 if (image->debug != MagickFalse)
3569 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3570 assert(image->blob != (BlobInfo *) NULL);
3571 assert(image->blob->type != UndefinedStream);
3572 switch (image->blob->type)
3574 case UndefinedStream:
3578 if (extent != (MagickSizeType) ((off_t) extent))
3579 return(MagickFalse);
3580 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3581 return(MagickFalse);
3590 offset=TellBlob(image);
3591 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3592 (off_t) (extent-offset));
3594 return(MagickFalse);
3599 case StandardStream:
3602 return(MagickFalse);
3604 return(MagickFalse);
3606 return(MagickFalse);
3609 if (image->blob->mapped != MagickFalse)
3611 if (image->blob->file == (FILE *) NULL)
3612 return(MagickFalse);
3613 (void) UnmapBlob(image->blob->data,image->blob->length);
3614 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3615 return(MagickFalse);
3624 offset=TellBlob(image);
3625 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3626 (off_t) (extent-offset));
3628 return(MagickFalse);
3630 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3631 WriteMode,0,(size_t) extent);
3632 image->blob->extent=(size_t) extent;
3633 image->blob->length=(size_t) extent;
3634 (void) SyncBlob(image);
3638 if (extent != (MagickSizeType) ((size_t) extent))
3639 return(MagickFalse);
3640 image->blob->extent=(size_t) extent;
3641 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3642 image->blob->extent+1,sizeof(*image->blob->data));
3643 (void) SyncBlob(image);
3644 if (image->blob->data == (unsigned char *) NULL)
3646 (void) DetachBlob(image->blob);
3647 return(MagickFalse);
3656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3666 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3667 % attributes if it is an blob.
3669 % The format of the SyncBlob method is:
3671 % int SyncBlob(Image *image)
3673 % A description of each parameter follows:
3675 % o image: the image.
3678 static int SyncBlob(Image *image)
3683 assert(image != (Image *) NULL);
3684 assert(image->signature == MagickSignature);
3685 if (image->debug != MagickFalse)
3686 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3687 assert(image->blob != (BlobInfo *) NULL);
3688 assert(image->blob->type != UndefinedStream);
3690 switch (image->blob->type)
3692 case UndefinedStream:
3695 case StandardStream:
3698 status=fflush(image->blob->file);
3703 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3704 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3710 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3711 status=BZ2_bzflush((BZFILE *) image->blob->file);
3719 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3720 if (image->blob->mapped != MagickFalse)
3721 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3740 % TellBlob() obtains the current value of the blob or file position.
3742 % The format of the TellBlob method is:
3744 % MagickOffsetType TellBlob(const Image *image)
3746 % A description of each parameter follows:
3748 % o image: the image.
3751 MagickExport MagickOffsetType TellBlob(const Image *image)
3756 assert(image != (Image *) NULL);
3757 assert(image->signature == MagickSignature);
3758 if (image->debug != MagickFalse)
3759 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3760 assert(image->blob != (BlobInfo *) NULL);
3761 assert(image->blob->type != UndefinedStream);
3763 switch (image->blob->type)
3765 case UndefinedStream:
3769 offset=ftell(image->blob->file);
3772 case StandardStream:
3777 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3778 offset=(MagickOffsetType) gztell(image->blob->file);
3788 offset=image->blob->offset;
3796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3800 + U n m a p B l o b %
3804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3806 % UnmapBlob() deallocates the binary large object previously allocated with
3807 % the MapBlob method.
3809 % The format of the UnmapBlob method is:
3811 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3813 % A description of each parameter follows:
3815 % o map: the address of the binary large object.
3817 % o length: the length of the binary large object.
3820 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3822 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3826 status=munmap(map,length);
3827 return(status == -1 ? MagickFalse : MagickTrue);
3831 return(MagickFalse);
3836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3840 + W r i t e B l o b %
3844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3846 % WriteBlob() writes data to a blob or image file. It returns the number of
3849 % The format of the WriteBlob method is:
3851 % ssize_t WriteBlob(Image *image,const size_t length,
3852 % const unsigned char *data)
3854 % A description of each parameter follows:
3856 % o image: the image.
3858 % o length: Specifies an integer representing the number of bytes to
3859 % write to the file.
3861 % o data: The address of the data to write to the blob or file.
3864 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3865 const unsigned char *data)
3870 register const unsigned char
3876 assert(image != (Image *) NULL);
3877 assert(image->signature == MagickSignature);
3878 assert(data != (const unsigned char *) NULL);
3879 assert(image->blob != (BlobInfo *) NULL);
3880 assert(image->blob->type != UndefinedStream);
3885 switch (image->blob->type)
3887 case UndefinedStream:
3890 case StandardStream:
3897 count=(ssize_t) fwrite((const char *) data,1,length,
3903 c=putc((int) *p++,image->blob->file);
3910 c=putc((int) *p++,image->blob->file);
3922 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3927 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
3928 (unsigned int) length);
3933 c=gzputc(image->blob->file,(int) *p++);
3940 c=gzputc(image->blob->file,(int) *p++);
3953 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3954 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
3961 count=(ssize_t) image->blob->stream(image,data,length);
3966 register unsigned char
3969 if ((image->blob->offset+(MagickOffsetType) length) >=
3970 (MagickOffsetType) image->blob->extent)
3972 if (image->blob->mapped != MagickFalse)
3974 image->blob->quantum<<=1;
3975 image->blob->extent+=length+image->blob->quantum;
3976 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3977 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
3978 (void) SyncBlob(image);
3979 if (image->blob->data == (unsigned char *) NULL)
3981 (void) DetachBlob(image->blob);
3985 q=image->blob->data+image->blob->offset;
3986 (void) CopyMagickMemory(q,p,length);
3987 image->blob->offset+=length;
3988 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3989 image->blob->length=(size_t) image->blob->offset;
3990 count=(ssize_t) length;
3997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4001 + W r i t e B l o b B y t e %
4005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4007 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4008 % written (either 0 or 1);
4010 % The format of the WriteBlobByte method is:
4012 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4014 % A description of each parameter follows.
4016 % o image: the image.
4018 % o value: Specifies the value to write.
4021 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4023 assert(image != (Image *) NULL);
4024 assert(image->signature == MagickSignature);
4025 return(WriteBlobStream(image,1,&value));
4029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4033 + W r i t e B l o b F l o a t %
4037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4039 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4040 % specified by the endian member of the image structure.
4042 % The format of the WriteBlobFloat method is:
4044 % ssize_t WriteBlobFloat(Image *image,const float value)
4046 % A description of each parameter follows.
4048 % o image: the image.
4050 % o value: Specifies the value to write.
4053 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4064 quantum.unsigned_value=0U;
4065 quantum.float_value=value;
4066 return(WriteBlobLong(image,quantum.unsigned_value));
4070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4074 + W r i t e B l o b L o n g %
4078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4080 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4081 % specified by the endian member of the image structure.
4083 % The format of the WriteBlobLong method is:
4085 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4087 % A description of each parameter follows.
4089 % o image: the image.
4091 % o value: Specifies the value to write.
4094 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4099 assert(image != (Image *) NULL);
4100 assert(image->signature == MagickSignature);
4101 if (image->endian == LSBEndian)
4103 buffer[0]=(unsigned char) value;
4104 buffer[1]=(unsigned char) (value >> 8);
4105 buffer[2]=(unsigned char) (value >> 16);
4106 buffer[3]=(unsigned char) (value >> 24);
4107 return(WriteBlobStream(image,4,buffer));
4109 buffer[0]=(unsigned char) (value >> 24);
4110 buffer[1]=(unsigned char) (value >> 16);
4111 buffer[2]=(unsigned char) (value >> 8);
4112 buffer[3]=(unsigned char) value;
4113 return(WriteBlobStream(image,4,buffer));
4117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4121 + W r i t e B l o b S h o r t %
4125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4127 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4128 % byte-order specified by the endian member of the image structure.
4130 % The format of the WriteBlobShort method is:
4132 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4134 % A description of each parameter follows.
4136 % o image: the image.
4138 % o value: Specifies the value to write.
4141 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4146 assert(image != (Image *) NULL);
4147 assert(image->signature == MagickSignature);
4148 if (image->endian == LSBEndian)
4150 buffer[0]=(unsigned char) value;
4151 buffer[1]=(unsigned char) (value >> 8);
4152 return(WriteBlobStream(image,2,buffer));
4154 buffer[0]=(unsigned char) (value >> 8);
4155 buffer[1]=(unsigned char) value;
4156 return(WriteBlobStream(image,2,buffer));
4160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4164 + W r i t e B l o b L S B L o n g %
4168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4170 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4171 % least-significant byte first order.
4173 % The format of the WriteBlobLSBLong method is:
4175 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4177 % A description of each parameter follows.
4179 % o image: the image.
4181 % o value: Specifies the value to write.
4184 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4189 assert(image != (Image *) NULL);
4190 assert(image->signature == MagickSignature);
4191 buffer[0]=(unsigned char) value;
4192 buffer[1]=(unsigned char) (value >> 8);
4193 buffer[2]=(unsigned char) (value >> 16);
4194 buffer[3]=(unsigned char) (value >> 24);
4195 return(WriteBlobStream(image,4,buffer));
4199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4203 + W r i t e B l o b L S B S h o r t %
4207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4209 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4210 % least-significant byte first order.
4212 % The format of the WriteBlobLSBShort method is:
4214 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4216 % A description of each parameter follows.
4218 % o image: the image.
4220 % o value: Specifies the value to write.
4223 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4228 assert(image != (Image *) NULL);
4229 assert(image->signature == MagickSignature);
4230 buffer[0]=(unsigned char) value;
4231 buffer[1]=(unsigned char) (value >> 8);
4232 return(WriteBlobStream(image,2,buffer));
4236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4240 + W r i t e B l o b M S B L o n g %
4244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4246 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4247 % most-significant byte first order.
4249 % The format of the WriteBlobMSBLong method is:
4251 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4253 % A description of each parameter follows.
4255 % o value: Specifies the value to write.
4257 % o image: the image.
4260 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4265 assert(image != (Image *) NULL);
4266 assert(image->signature == MagickSignature);
4267 buffer[0]=(unsigned char) (value >> 24);
4268 buffer[1]=(unsigned char) (value >> 16);
4269 buffer[2]=(unsigned char) (value >> 8);
4270 buffer[3]=(unsigned char) value;
4271 return(WriteBlobStream(image,4,buffer));
4275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4279 + W r i t e B l o b M S B L o n g L o n g %
4283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4285 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4286 % most-significant byte first order.
4288 % The format of the WriteBlobMSBLongLong method is:
4290 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4292 % A description of each parameter follows.
4294 % o value: Specifies the value to write.
4296 % o image: the image.
4299 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4300 const MagickSizeType value)
4305 assert(image != (Image *) NULL);
4306 assert(image->signature == MagickSignature);
4307 buffer[0]=(unsigned char) (value >> 56);
4308 buffer[1]=(unsigned char) (value >> 48);
4309 buffer[2]=(unsigned char) (value >> 40);
4310 buffer[3]=(unsigned char) (value >> 32);
4311 buffer[4]=(unsigned char) (value >> 24);
4312 buffer[5]=(unsigned char) (value >> 16);
4313 buffer[6]=(unsigned char) (value >> 8);
4314 buffer[7]=(unsigned char) value;
4315 return(WriteBlobStream(image,8,buffer));
4319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4323 + W r i t e B l o b M S B S h o r t %
4327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4329 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4330 % most-significant byte first order.
4332 % The format of the WriteBlobMSBShort method is:
4334 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4336 % A description of each parameter follows.
4338 % o value: Specifies the value to write.
4340 % o file: Specifies the file to write the data to.
4343 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4348 assert(image != (Image *) NULL);
4349 assert(image->signature == MagickSignature);
4350 buffer[0]=(unsigned char) (value >> 8);
4351 buffer[1]=(unsigned char) value;
4352 return(WriteBlobStream(image,2,buffer));
4356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4360 + W r i t e B l o b S t r i n g %
4364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4366 % WriteBlobString() write a string to a blob. It returns the number of
4367 % characters written.
4369 % The format of the WriteBlobString method is:
4371 % ssize_t WriteBlobString(Image *image,const char *string)
4373 % A description of each parameter follows.
4375 % o image: the image.
4377 % o string: Specifies the string to write.
4380 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4382 assert(image != (Image *) NULL);
4383 assert(image->signature == MagickSignature);
4384 assert(string != (const char *) NULL);
4385 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));