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 filename[MaxTextExtent];
2211 assert(image_info != (ImageInfo *) NULL);
2212 assert(image_info->signature == MagickSignature);
2213 if (image_info->debug != MagickFalse)
2214 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2215 image_info->filename);
2216 assert(image != (Image *) NULL);
2217 assert(image->signature == MagickSignature);
2218 if (image_info->blob != (void *) NULL)
2220 if (image_info->stream != (StreamHandler) NULL)
2221 image->blob->stream=(StreamHandler) image_info->stream;
2222 AttachBlob(image->blob,image_info->blob,image_info->length);
2225 (void) DetachBlob(image->blob);
2228 default: type="r"; break;
2229 case ReadBlobMode: type="r"; break;
2230 case ReadBinaryBlobMode: type="rb"; break;
2231 case WriteBlobMode: type="w"; break;
2232 case WriteBinaryBlobMode: type="w+b"; break;
2233 case AppendBlobMode: type="a"; break;
2234 case AppendBinaryBlobMode: type="a+b"; break;
2237 image->blob->synchronize=image_info->synchronize;
2238 if (image_info->stream != (StreamHandler) NULL)
2240 image->blob->stream=(StreamHandler) image_info->stream;
2243 image->blob->type=FifoStream;
2251 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2252 rights=ReadPolicyRights;
2254 rights=WritePolicyRights;
2255 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2258 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2259 "NotAuthorized","`%s'",filename);
2260 return(MagickFalse);
2262 if ((LocaleCompare(filename,"-") == 0) ||
2263 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2265 image->blob->file=(*type == 'r') ? stdin : stdout;
2266 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2267 if (strchr(type,'b') != (char *) NULL)
2268 setmode(_fileno(image->blob->file),_O_BINARY);
2270 image->blob->type=StandardStream;
2271 image->blob->exempt=MagickTrue;
2274 if (LocaleNCompare(filename,"fd:",3) == 0)
2277 mode[MaxTextExtent];
2281 image->blob->file=fdopen(StringToLong(filename+3),mode);
2282 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2283 if (strchr(type,'b') != (char *) NULL)
2284 setmode(_fileno(image->blob->file),_O_BINARY);
2286 image->blob->type=StandardStream;
2287 image->blob->exempt=MagickTrue;
2290 #if defined(MAGICKCORE_HAVE_POPEN)
2291 if (*filename == '|')
2294 mode[MaxTextExtent];
2297 Pipe image to or from a system command.
2299 #if defined(SIGPIPE)
2301 (void) signal(SIGPIPE,SIG_IGN);
2305 image->blob->file=(FILE *) popen(filename+1,mode);
2306 if (image->blob->file == (FILE *) NULL)
2308 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2309 return(MagickFalse);
2311 image->blob->type=PipeStream;
2312 image->blob->exempt=MagickTrue;
2316 status=GetPathAttributes(filename,&image->blob->properties);
2317 #if defined(S_ISFIFO)
2318 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2320 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2321 if (image->blob->file == (FILE *) NULL)
2323 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2324 return(MagickFalse);
2326 image->blob->type=FileStream;
2327 image->blob->exempt=MagickTrue;
2333 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2334 if ((image_info->adjoin == MagickFalse) ||
2335 (IsGlob(filename) != MagickFalse))
2338 Form filename for multi-part images.
2340 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2341 image->scene,filename);
2342 if ((LocaleCompare(filename,image->filename) == 0) &&
2343 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2344 (GetNextImageInList(image) != (Image *) NULL)))
2347 extension[MaxTextExtent],
2348 path[MaxTextExtent];
2350 GetPathComponent(image->filename,RootPath,path);
2351 GetPathComponent(image->filename,ExtensionPath,extension);
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 defined(MAGICKCORE_ZLIB_DELEGATE)
2366 if (((strlen(filename) > 2) &&
2367 (LocaleCompare(filename+strlen(filename)-2,".Z") == 0)) ||
2368 ((strlen(filename) > 3) &&
2369 (LocaleCompare(filename+strlen(filename)-3,".gz") == 0)) ||
2370 ((strlen(filename) > 4) &&
2371 (LocaleCompare(filename+strlen(filename)-4,".wmz") == 0)) ||
2372 ((strlen(filename) > 5) &&
2373 (LocaleCompare(filename+strlen(filename)-5,".svgz") == 0)))
2375 image->blob->file=(FILE *) gzopen(filename,type);
2376 if (image->blob->file != (FILE *) NULL)
2377 image->blob->type=ZipStream;
2381 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2382 if ((strlen(filename) > 4) &&
2383 (LocaleCompare(filename+strlen(filename)-4,".bz2") == 0))
2385 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2386 if (image->blob->file != (FILE *) NULL)
2387 image->blob->type=BZipStream;
2391 if (image_info->file != (FILE *) NULL)
2393 image->blob->file=image_info->file;
2394 image->blob->type=FileStream;
2395 image->blob->exempt=MagickTrue;
2399 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2400 if (image->blob->file != (FILE *) NULL)
2402 image->blob->type=FileStream;
2403 #if defined(MAGICKCORE_HAVE_SETVBUF)
2404 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2415 (void) ResetMagickMemory(magick,0,sizeof(magick));
2416 count=fread(magick,1,sizeof(magick),image->blob->file);
2417 (void) rewind(image->blob->file);
2418 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2419 " read %.20g magic header bytes",(double) count);
2420 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2421 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2422 ((int) magick[2] == 0x08))
2424 (void) fclose(image->blob->file);
2425 image->blob->file=(FILE *) gzopen(filename,type);
2426 if (image->blob->file != (FILE *) NULL)
2427 image->blob->type=ZipStream;
2430 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2431 if (strncmp((char *) magick,"BZh",3) == 0)
2433 (void) fclose(image->blob->file);
2434 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2435 if (image->blob->file != (FILE *) NULL)
2436 image->blob->type=BZipStream;
2442 if ((image->blob->type == FileStream) && (*type == 'r'))
2453 sans_exception=AcquireExceptionInfo();
2454 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2455 sans_exception=DestroyExceptionInfo(sans_exception);
2456 properties=(&image->blob->properties);
2457 if ((magick_info != (const MagickInfo *) NULL) &&
2458 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2459 (properties->st_size <= MagickMaxBufferExtent))
2467 length=(size_t) properties->st_size;
2468 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2469 if (blob != (void *) NULL)
2472 Format supports blobs-- use memory-mapped I/O.
2474 if (image_info->file != (FILE *) NULL)
2475 image->blob->exempt=MagickFalse;
2478 (void) fclose(image->blob->file);
2479 image->blob->file=(FILE *) NULL;
2481 AttachBlob(image->blob,blob,length);
2482 image->blob->mapped=MagickTrue;
2486 image->blob->status=MagickFalse;
2487 if (image->blob->type != UndefinedStream)
2488 image->blob->size=GetBlobSize(image);
2491 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2492 return(MagickFalse);
2498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2508 % PingBlob() returns all the attributes of an image or image sequence except
2509 % for the pixels. It is much faster and consumes far less memory than
2510 % BlobToImage(). On failure, a NULL image is returned and exception
2511 % describes the reason for the failure.
2513 % The format of the PingBlob method is:
2515 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2516 % const size_t length,ExceptionInfo *exception)
2518 % A description of each parameter follows:
2520 % o image_info: the image info.
2522 % o blob: the address of a character stream in one of the image formats
2523 % understood by ImageMagick.
2525 % o length: This size_t integer reflects the length in bytes of the blob.
2527 % o exception: return any errors or warnings in this structure.
2531 #if defined(__cplusplus) || defined(c_plusplus)
2535 static size_t PingStream(const Image *magick_unused(image),
2536 const void *magick_unused(pixels),const size_t columns)
2541 #if defined(__cplusplus) || defined(c_plusplus)
2545 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2546 const size_t length,ExceptionInfo *exception)
2554 assert(image_info != (ImageInfo *) NULL);
2555 assert(image_info->signature == MagickSignature);
2556 if (image_info->debug != MagickFalse)
2557 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2558 image_info->filename);
2559 assert(exception != (ExceptionInfo *) NULL);
2560 if ((blob == (const void *) NULL) || (length == 0))
2562 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2563 "UnrecognizedImageFormat","`%s'",image_info->magick);
2564 return((Image *) NULL);
2566 ping_info=CloneImageInfo(image_info);
2567 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2568 if (ping_info->blob == (const void *) NULL)
2570 (void) ThrowMagickException(exception,GetMagickModule(),
2571 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2572 return((Image *) NULL);
2574 (void) CopyMagickMemory(ping_info->blob,blob,length);
2575 ping_info->length=length;
2576 ping_info->ping=MagickTrue;
2577 image=ReadStream(ping_info,&PingStream,exception);
2578 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2579 ping_info=DestroyImageInfo(ping_info);
2584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2594 % ReadBlob() reads data from the blob or image file and returns it. It
2595 % returns the number of bytes read.
2597 % The format of the ReadBlob method is:
2599 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2601 % A description of each parameter follows:
2603 % o image: the image.
2605 % o length: Specifies an integer representing the number of bytes to read
2608 % o data: Specifies an area to place the information requested from the
2612 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2613 unsigned char *data)
2618 register unsigned char
2624 assert(image != (Image *) NULL);
2625 assert(image->signature == MagickSignature);
2626 assert(image->blob != (BlobInfo *) NULL);
2627 assert(image->blob->type != UndefinedStream);
2630 assert(data != (void *) NULL);
2633 switch (image->blob->type)
2635 case UndefinedStream:
2638 case StandardStream:
2645 count=(ssize_t) fread(q,1,length,image->blob->file);
2650 c=getc(image->blob->file);
2653 *q++=(unsigned char) c;
2658 c=getc(image->blob->file);
2661 *q++=(unsigned char) c;
2671 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2676 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2681 c=gzgetc(image->blob->file);
2684 *q++=(unsigned char) c;
2689 c=gzgetc(image->blob->file);
2692 *q++=(unsigned char) c;
2703 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2704 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2712 register const unsigned char
2715 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2717 image->blob->eof=MagickTrue;
2720 p=image->blob->data+image->blob->offset;
2721 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2722 image->blob->offset));
2723 image->blob->offset+=count;
2724 if (count != (ssize_t) length)
2725 image->blob->eof=MagickTrue;
2726 (void) CopyMagickMemory(q,p,(size_t) count);
2734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2738 + R e a d B l o b B y t e %
2742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2744 % ReadBlobByte() reads a single byte from the image file and returns it.
2746 % The format of the ReadBlobByte method is:
2748 % int ReadBlobByte(Image *image)
2750 % A description of each parameter follows.
2752 % o image: the image.
2755 MagickExport int ReadBlobByte(Image *image)
2757 register const unsigned char
2766 assert(image != (Image *) NULL);
2767 assert(image->signature == MagickSignature);
2768 p=ReadBlobStream(image,1,buffer,&count);
2775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2779 + R e a d B l o b D o u b l e %
2783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2785 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2786 % specified by the endian member of the image structure.
2788 % The format of the ReadBlobDouble method is:
2790 % double ReadBlobDouble(Image *image)
2792 % A description of each parameter follows.
2794 % o image: the image.
2797 MagickExport double ReadBlobDouble(Image *image)
2808 quantum.double_value=0.0;
2809 quantum.unsigned_value=ReadBlobLongLong(image);
2810 return(quantum.double_value);
2814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2818 + R e a d B l o b F l o a t %
2822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2824 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2825 % specified by the endian member of the image structure.
2827 % The format of the ReadBlobFloat method is:
2829 % float ReadBlobFloat(Image *image)
2831 % A description of each parameter follows.
2833 % o image: the image.
2836 MagickExport float ReadBlobFloat(Image *image)
2847 quantum.float_value=0.0;
2848 quantum.unsigned_value=ReadBlobLong(image);
2849 return(quantum.float_value);
2853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2857 + R e a d B l o b L o n g %
2861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2863 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2864 % specified by the endian member of the image structure.
2866 % The format of the ReadBlobLong method is:
2868 % unsigned int ReadBlobLong(Image *image)
2870 % A description of each parameter follows.
2872 % o image: the image.
2875 MagickExport unsigned int ReadBlobLong(Image *image)
2877 register const unsigned char
2889 assert(image != (Image *) NULL);
2890 assert(image->signature == MagickSignature);
2892 p=ReadBlobStream(image,4,buffer,&count);
2895 if (image->endian == LSBEndian)
2897 value=(unsigned int) (*p++);
2898 value|=((unsigned int) (*p++)) << 8;
2899 value|=((unsigned int) (*p++)) << 16;
2900 value|=((unsigned int) (*p++)) << 24;
2903 value=((unsigned int) (*p++)) << 24;
2904 value|=((unsigned int) (*p++)) << 16;
2905 value|=((unsigned int) (*p++)) << 8;
2906 value|=((unsigned int) (*p++));
2911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2915 + R e a d B l o b L o n g L o n g %
2919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2921 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
2922 % byte-order specified by the endian member of the image structure.
2924 % The format of the ReadBlobLongLong method is:
2926 % MagickSizeType ReadBlobLongLong(Image *image)
2928 % A description of each parameter follows.
2930 % o image: the image.
2933 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
2935 register const unsigned char
2947 assert(image != (Image *) NULL);
2948 assert(image->signature == MagickSignature);
2950 p=ReadBlobStream(image,8,buffer,&count);
2952 return(MagickULLConstant(0));
2953 if (image->endian == LSBEndian)
2955 value=(MagickSizeType) (*p++);
2956 value|=((MagickSizeType) (*p++)) << 8;
2957 value|=((MagickSizeType) (*p++)) << 16;
2958 value|=((MagickSizeType) (*p++)) << 24;
2959 value|=((MagickSizeType) (*p++)) << 32;
2960 value|=((MagickSizeType) (*p++)) << 40;
2961 value|=((MagickSizeType) (*p++)) << 48;
2962 value|=((MagickSizeType) (*p++)) << 56;
2963 return(value & MagickULLConstant(0xffffffffffffffff));
2965 value=((MagickSizeType) (*p++)) << 56;
2966 value|=((MagickSizeType) (*p++)) << 48;
2967 value|=((MagickSizeType) (*p++)) << 40;
2968 value|=((MagickSizeType) (*p++)) << 32;
2969 value|=((MagickSizeType) (*p++)) << 24;
2970 value|=((MagickSizeType) (*p++)) << 16;
2971 value|=((MagickSizeType) (*p++)) << 8;
2972 value|=((MagickSizeType) (*p++));
2973 return(value & MagickULLConstant(0xffffffffffffffff));
2977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2981 + R e a d B l o b S h o r t %
2985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2987 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
2988 % specified by the endian member of the image structure.
2990 % The format of the ReadBlobShort method is:
2992 % unsigned short ReadBlobShort(Image *image)
2994 % A description of each parameter follows.
2996 % o image: the image.
2999 MagickExport unsigned short ReadBlobShort(Image *image)
3001 register const unsigned char
3004 register unsigned int
3013 assert(image != (Image *) NULL);
3014 assert(image->signature == MagickSignature);
3016 p=ReadBlobStream(image,2,buffer,&count);
3018 return((unsigned short) 0U);
3019 if (image->endian == LSBEndian)
3021 value=(unsigned int) (*p++);
3022 value|=((unsigned int) (*p++)) << 8;
3023 return((unsigned short) (value & 0xffff));
3025 value=(unsigned int) ((*p++) << 8);
3026 value|=(unsigned int) (*p++);
3027 return((unsigned short) (value & 0xffff));
3031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3035 + R e a d B l o b L S B L o n g %
3039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3041 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3042 % least-significant byte first order.
3044 % The format of the ReadBlobLSBLong method is:
3046 % unsigned int ReadBlobLSBLong(Image *image)
3048 % A description of each parameter follows.
3050 % o image: the image.
3053 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3055 register const unsigned char
3058 register unsigned int
3067 assert(image != (Image *) NULL);
3068 assert(image->signature == MagickSignature);
3070 p=ReadBlobStream(image,4,buffer,&count);
3073 value=(unsigned int) (*p++);
3074 value|=((unsigned int) (*p++)) << 8;
3075 value|=((unsigned int) (*p++)) << 16;
3076 value|=((unsigned int) (*p++)) << 24;
3081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3085 + R e a d B l o b L S B S h o r t %
3089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3091 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3092 % least-significant byte first order.
3094 % The format of the ReadBlobLSBShort method is:
3096 % unsigned short ReadBlobLSBShort(Image *image)
3098 % A description of each parameter follows.
3100 % o image: the image.
3103 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3105 register const unsigned char
3108 register unsigned int
3117 assert(image != (Image *) NULL);
3118 assert(image->signature == MagickSignature);
3120 p=ReadBlobStream(image,2,buffer,&count);
3122 return((unsigned short) 0U);
3123 value=(unsigned int) (*p++);
3124 value|=((unsigned int) ((*p++)) << 8);
3125 return((unsigned short) (value & 0xffff));
3129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3133 + R e a d B l o b M S B L o n g %
3137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3139 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3140 % most-significant byte first order.
3142 % The format of the ReadBlobMSBLong method is:
3144 % unsigned int ReadBlobMSBLong(Image *image)
3146 % A description of each parameter follows.
3148 % o image: the image.
3151 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3153 register const unsigned char
3156 register unsigned int
3165 assert(image != (Image *) NULL);
3166 assert(image->signature == MagickSignature);
3168 p=ReadBlobStream(image,4,buffer,&count);
3171 value=((unsigned int) (*p++) << 24);
3172 value|=((unsigned int) (*p++) << 16);
3173 value|=((unsigned int) (*p++) << 8);
3174 value|=(unsigned int) (*p++);
3179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3183 + R e a d B l o b M S B L o n g L o n g %
3187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3189 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3190 % most-significant byte first order.
3192 % The format of the ReadBlobMSBLongLong method is:
3194 % unsigned int ReadBlobMSBLongLong(Image *image)
3196 % A description of each parameter follows.
3198 % o image: the image.
3201 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3203 register const unsigned char
3206 register MagickSizeType
3215 assert(image != (Image *) NULL);
3216 assert(image->signature == MagickSignature);
3218 p=ReadBlobStream(image,8,buffer,&count);
3220 return(MagickULLConstant(0));
3221 value=((MagickSizeType) (*p++)) << 56;
3222 value|=((MagickSizeType) (*p++)) << 48;
3223 value|=((MagickSizeType) (*p++)) << 40;
3224 value|=((MagickSizeType) (*p++)) << 32;
3225 value|=((MagickSizeType) (*p++)) << 24;
3226 value|=((MagickSizeType) (*p++)) << 16;
3227 value|=((MagickSizeType) (*p++)) << 8;
3228 value|=((MagickSizeType) (*p++));
3229 return(value & MagickULLConstant(0xffffffffffffffff));
3233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3237 + R e a d B l o b M S B S h o r t %
3241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3243 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3244 % most-significant byte first order.
3246 % The format of the ReadBlobMSBShort method is:
3248 % unsigned short ReadBlobMSBShort(Image *image)
3250 % A description of each parameter follows.
3252 % o image: the image.
3255 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3257 register const unsigned char
3260 register unsigned int
3269 assert(image != (Image *) NULL);
3270 assert(image->signature == MagickSignature);
3272 p=ReadBlobStream(image,2,buffer,&count);
3274 return((unsigned short) 0U);
3275 value=(unsigned int) ((*p++) << 8);
3276 value|=(unsigned int) (*p++);
3277 return((unsigned short) (value & 0xffff));
3281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3285 + R e a d B l o b S t r i n g %
3289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3291 % ReadBlobString() reads characters from a blob or file until a newline
3292 % character is read or an end-of-file condition is encountered.
3294 % The format of the ReadBlobString method is:
3296 % char *ReadBlobString(Image *image,char *string)
3298 % A description of each parameter follows:
3300 % o image: the image.
3302 % o string: the address of a character buffer.
3305 MagickExport char *ReadBlobString(Image *image,char *string)
3307 register const unsigned char
3319 assert(image != (Image *) NULL);
3320 assert(image->signature == MagickSignature);
3321 for (i=0; i < (MaxTextExtent-1L); i++)
3323 p=ReadBlobStream(image,1,buffer,&count);
3327 return((char *) NULL);
3330 string[i]=(char) (*p);
3331 if ((string[i] == '\r') || (string[i] == '\n'))
3334 if (string[i] == '\r')
3335 (void) ReadBlobStream(image,1,buffer,&count);
3341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3345 + R e f e r e n c e B l o b %
3349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3351 % ReferenceBlob() increments the reference count associated with the pixel
3352 % blob returning a pointer to the blob.
3354 % The format of the ReferenceBlob method is:
3356 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3358 % A description of each parameter follows:
3360 % o blob_info: the blob_info.
3363 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3365 assert(blob != (BlobInfo *) NULL);
3366 assert(blob->signature == MagickSignature);
3367 if (blob->debug != MagickFalse)
3368 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3369 LockSemaphoreInfo(blob->semaphore);
3370 blob->reference_count++;
3371 UnlockSemaphoreInfo(blob->semaphore);
3376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3386 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3387 % and returns the resulting offset.
3389 % The format of the SeekBlob method is:
3391 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3394 % A description of each parameter follows:
3396 % o image: the image.
3398 % o offset: Specifies an integer representing the offset in bytes.
3400 % o whence: Specifies an integer representing how the offset is
3401 % treated relative to the beginning of the blob as follows:
3403 % SEEK_SET Set position equal to offset bytes.
3404 % SEEK_CUR Set position to current location plus offset.
3405 % SEEK_END Set position to EOF plus offset.
3408 MagickExport MagickOffsetType SeekBlob(Image *image,
3409 const MagickOffsetType offset,const int whence)
3411 assert(image != (Image *) NULL);
3412 assert(image->signature == MagickSignature);
3413 if (image->debug != MagickFalse)
3414 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3415 assert(image->blob != (BlobInfo *) NULL);
3416 assert(image->blob->type != UndefinedStream);
3417 switch (image->blob->type)
3419 case UndefinedStream:
3423 if (fseek(image->blob->file,(long) offset,whence) < 0)
3425 image->blob->offset=TellBlob(image);
3428 case StandardStream:
3432 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3433 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3436 image->blob->offset=TellBlob(image);
3452 image->blob->offset=offset;
3457 if ((image->blob->offset+offset) < 0)
3459 image->blob->offset+=offset;
3464 if (((MagickOffsetType) image->blob->length+offset) < 0)
3466 image->blob->offset=image->blob->length+offset;
3470 if (image->blob->offset <= (MagickOffsetType)
3471 ((off_t) image->blob->length))
3472 image->blob->eof=MagickFalse;
3474 if (image->blob->mapped != MagickFalse)
3478 image->blob->extent=(size_t) (image->blob->offset+
3479 image->blob->quantum);
3480 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3481 image->blob->data,image->blob->extent+1,
3482 sizeof(*image->blob->data));
3483 (void) SyncBlob(image);
3484 if (image->blob->data == (unsigned char *) NULL)
3486 (void) DetachBlob(image->blob);
3493 return(image->blob->offset);
3497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3501 + S e t B l o b E x e m p t %
3505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3507 % SetBlobExempt() sets the blob exempt status.
3509 % The format of the SetBlobExempt method is:
3511 % MagickBooleanType SetBlobExempt(const Image *image,
3512 % const MagickBooleanType exempt)
3514 % A description of each parameter follows:
3516 % o image: the image.
3518 % o exempt: Set to true if this blob is exempt from being closed.
3521 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3523 assert(image != (const Image *) NULL);
3524 assert(image->signature == MagickSignature);
3525 if (image->debug != MagickFalse)
3526 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3527 image->blob->exempt=exempt;
3531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3535 + S e t B l o b E x t e n t %
3539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3541 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3542 % method is successful, subsequent writes to bytes in the specified range are
3543 % guaranteed not to fail.
3545 % The format of the SetBlobExtent method is:
3547 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3549 % A description of each parameter follows:
3551 % o image: the image.
3553 % o extent: the blob maximum extent.
3556 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3557 const MagickSizeType extent)
3559 assert(image != (Image *) NULL);
3560 assert(image->signature == MagickSignature);
3561 if (image->debug != MagickFalse)
3562 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3563 assert(image->blob != (BlobInfo *) NULL);
3564 assert(image->blob->type != UndefinedStream);
3565 switch (image->blob->type)
3567 case UndefinedStream:
3571 if (extent != (MagickSizeType) ((off_t) extent))
3572 return(MagickFalse);
3573 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3574 return(MagickFalse);
3583 offset=TellBlob(image);
3584 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3585 (off_t) (extent-offset));
3587 return(MagickFalse);
3592 case StandardStream:
3595 return(MagickFalse);
3597 return(MagickFalse);
3599 return(MagickFalse);
3602 if (image->blob->mapped != MagickFalse)
3604 if (image->blob->file == (FILE *) NULL)
3605 return(MagickFalse);
3606 (void) UnmapBlob(image->blob->data,image->blob->length);
3607 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3608 return(MagickFalse);
3617 offset=TellBlob(image);
3618 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3619 (off_t) (extent-offset));
3621 return(MagickFalse);
3623 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3624 WriteMode,0,(size_t) extent);
3625 image->blob->extent=(size_t) extent;
3626 image->blob->length=(size_t) extent;
3627 (void) SyncBlob(image);
3631 if (extent != (MagickSizeType) ((size_t) extent))
3632 return(MagickFalse);
3633 image->blob->extent=(size_t) extent;
3634 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3635 image->blob->extent+1,sizeof(*image->blob->data));
3636 (void) SyncBlob(image);
3637 if (image->blob->data == (unsigned char *) NULL)
3639 (void) DetachBlob(image->blob);
3640 return(MagickFalse);
3649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3659 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3660 % attributes if it is an blob.
3662 % The format of the SyncBlob method is:
3664 % int SyncBlob(Image *image)
3666 % A description of each parameter follows:
3668 % o image: the image.
3671 static int SyncBlob(Image *image)
3676 assert(image != (Image *) NULL);
3677 assert(image->signature == MagickSignature);
3678 if (image->debug != MagickFalse)
3679 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3680 assert(image->blob != (BlobInfo *) NULL);
3681 assert(image->blob->type != UndefinedStream);
3683 switch (image->blob->type)
3685 case UndefinedStream:
3688 case StandardStream:
3691 status=fflush(image->blob->file);
3696 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3697 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3703 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3704 status=BZ2_bzflush((BZFILE *) image->blob->file);
3712 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3713 if (image->blob->mapped != MagickFalse)
3714 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3733 % TellBlob() obtains the current value of the blob or file position.
3735 % The format of the TellBlob method is:
3737 % MagickOffsetType TellBlob(const Image *image)
3739 % A description of each parameter follows:
3741 % o image: the image.
3744 MagickExport MagickOffsetType TellBlob(const Image *image)
3749 assert(image != (Image *) NULL);
3750 assert(image->signature == MagickSignature);
3751 if (image->debug != MagickFalse)
3752 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3753 assert(image->blob != (BlobInfo *) NULL);
3754 assert(image->blob->type != UndefinedStream);
3756 switch (image->blob->type)
3758 case UndefinedStream:
3762 offset=ftell(image->blob->file);
3765 case StandardStream:
3770 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3771 offset=(MagickOffsetType) gztell(image->blob->file);
3781 offset=image->blob->offset;
3789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3793 + U n m a p B l o b %
3797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3799 % UnmapBlob() deallocates the binary large object previously allocated with
3800 % the MapBlob method.
3802 % The format of the UnmapBlob method is:
3804 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3806 % A description of each parameter follows:
3808 % o map: the address of the binary large object.
3810 % o length: the length of the binary large object.
3813 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3815 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3819 status=munmap(map,length);
3820 return(status == -1 ? MagickFalse : MagickTrue);
3824 return(MagickFalse);
3829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3833 + W r i t e B l o b %
3837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3839 % WriteBlob() writes data to a blob or image file. It returns the number of
3842 % The format of the WriteBlob method is:
3844 % ssize_t WriteBlob(Image *image,const size_t length,
3845 % const unsigned char *data)
3847 % A description of each parameter follows:
3849 % o image: the image.
3851 % o length: Specifies an integer representing the number of bytes to
3852 % write to the file.
3854 % o data: The address of the data to write to the blob or file.
3857 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3858 const unsigned char *data)
3863 register const unsigned char
3869 assert(image != (Image *) NULL);
3870 assert(image->signature == MagickSignature);
3871 assert(data != (const unsigned char *) NULL);
3872 assert(image->blob != (BlobInfo *) NULL);
3873 assert(image->blob->type != UndefinedStream);
3878 switch (image->blob->type)
3880 case UndefinedStream:
3883 case StandardStream:
3890 count=(ssize_t) fwrite((const char *) data,1,length,
3896 c=putc((int) *p++,image->blob->file);
3903 c=putc((int) *p++,image->blob->file);
3915 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3920 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
3921 (unsigned int) length);
3926 c=gzputc(image->blob->file,(int) *p++);
3933 c=gzputc(image->blob->file,(int) *p++);
3946 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3947 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
3954 count=(ssize_t) image->blob->stream(image,data,length);
3959 register unsigned char
3962 if ((image->blob->offset+(MagickOffsetType) length) >=
3963 (MagickOffsetType) image->blob->extent)
3965 if (image->blob->mapped != MagickFalse)
3967 image->blob->quantum<<=1;
3968 image->blob->extent+=length+image->blob->quantum;
3969 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3970 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
3971 (void) SyncBlob(image);
3972 if (image->blob->data == (unsigned char *) NULL)
3974 (void) DetachBlob(image->blob);
3978 q=image->blob->data+image->blob->offset;
3979 (void) CopyMagickMemory(q,p,length);
3980 image->blob->offset+=length;
3981 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3982 image->blob->length=(size_t) image->blob->offset;
3983 count=(ssize_t) length;
3990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3994 + W r i t e B l o b B y t e %
3998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4000 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4001 % written (either 0 or 1);
4003 % The format of the WriteBlobByte method is:
4005 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4007 % A description of each parameter follows.
4009 % o image: the image.
4011 % o value: Specifies the value to write.
4014 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4016 assert(image != (Image *) NULL);
4017 assert(image->signature == MagickSignature);
4018 return(WriteBlobStream(image,1,&value));
4022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4026 + W r i t e B l o b F l o a t %
4030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4032 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4033 % specified by the endian member of the image structure.
4035 % The format of the WriteBlobFloat method is:
4037 % ssize_t WriteBlobFloat(Image *image,const float value)
4039 % A description of each parameter follows.
4041 % o image: the image.
4043 % o value: Specifies the value to write.
4046 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4057 quantum.unsigned_value=0U;
4058 quantum.float_value=value;
4059 return(WriteBlobLong(image,quantum.unsigned_value));
4063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4067 + W r i t e B l o b L o n g %
4071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4073 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4074 % specified by the endian member of the image structure.
4076 % The format of the WriteBlobLong method is:
4078 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4080 % A description of each parameter follows.
4082 % o image: the image.
4084 % o value: Specifies the value to write.
4087 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4092 assert(image != (Image *) NULL);
4093 assert(image->signature == MagickSignature);
4094 if (image->endian == LSBEndian)
4096 buffer[0]=(unsigned char) value;
4097 buffer[1]=(unsigned char) (value >> 8);
4098 buffer[2]=(unsigned char) (value >> 16);
4099 buffer[3]=(unsigned char) (value >> 24);
4100 return(WriteBlobStream(image,4,buffer));
4102 buffer[0]=(unsigned char) (value >> 24);
4103 buffer[1]=(unsigned char) (value >> 16);
4104 buffer[2]=(unsigned char) (value >> 8);
4105 buffer[3]=(unsigned char) value;
4106 return(WriteBlobStream(image,4,buffer));
4110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4114 + W r i t e B l o b S h o r t %
4118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4120 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4121 % byte-order specified by the endian member of the image structure.
4123 % The format of the WriteBlobShort method is:
4125 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4127 % A description of each parameter follows.
4129 % o image: the image.
4131 % o value: Specifies the value to write.
4134 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4139 assert(image != (Image *) NULL);
4140 assert(image->signature == MagickSignature);
4141 if (image->endian == LSBEndian)
4143 buffer[0]=(unsigned char) value;
4144 buffer[1]=(unsigned char) (value >> 8);
4145 return(WriteBlobStream(image,2,buffer));
4147 buffer[0]=(unsigned char) (value >> 8);
4148 buffer[1]=(unsigned char) value;
4149 return(WriteBlobStream(image,2,buffer));
4153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4157 + W r i t e B l o b L S B L o n g %
4161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4163 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4164 % least-significant byte first order.
4166 % The format of the WriteBlobLSBLong method is:
4168 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4170 % A description of each parameter follows.
4172 % o image: the image.
4174 % o value: Specifies the value to write.
4177 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4182 assert(image != (Image *) NULL);
4183 assert(image->signature == MagickSignature);
4184 buffer[0]=(unsigned char) value;
4185 buffer[1]=(unsigned char) (value >> 8);
4186 buffer[2]=(unsigned char) (value >> 16);
4187 buffer[3]=(unsigned char) (value >> 24);
4188 return(WriteBlobStream(image,4,buffer));
4192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4196 + W r i t e B l o b L S B S h o r t %
4200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4202 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4203 % least-significant byte first order.
4205 % The format of the WriteBlobLSBShort method is:
4207 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4209 % A description of each parameter follows.
4211 % o image: the image.
4213 % o value: Specifies the value to write.
4216 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4221 assert(image != (Image *) NULL);
4222 assert(image->signature == MagickSignature);
4223 buffer[0]=(unsigned char) value;
4224 buffer[1]=(unsigned char) (value >> 8);
4225 return(WriteBlobStream(image,2,buffer));
4229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4233 + W r i t e B l o b M S B L o n g %
4237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4239 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4240 % most-significant byte first order.
4242 % The format of the WriteBlobMSBLong method is:
4244 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4246 % A description of each parameter follows.
4248 % o value: Specifies the value to write.
4250 % o image: the image.
4253 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4258 assert(image != (Image *) NULL);
4259 assert(image->signature == MagickSignature);
4260 buffer[0]=(unsigned char) (value >> 24);
4261 buffer[1]=(unsigned char) (value >> 16);
4262 buffer[2]=(unsigned char) (value >> 8);
4263 buffer[3]=(unsigned char) value;
4264 return(WriteBlobStream(image,4,buffer));
4268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4272 + W r i t e B l o b M S B L o n g L o n g %
4276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4278 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4279 % most-significant byte first order.
4281 % The format of the WriteBlobMSBLongLong method is:
4283 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4285 % A description of each parameter follows.
4287 % o value: Specifies the value to write.
4289 % o image: the image.
4292 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4293 const MagickSizeType value)
4298 assert(image != (Image *) NULL);
4299 assert(image->signature == MagickSignature);
4300 buffer[0]=(unsigned char) (value >> 56);
4301 buffer[1]=(unsigned char) (value >> 48);
4302 buffer[2]=(unsigned char) (value >> 40);
4303 buffer[3]=(unsigned char) (value >> 32);
4304 buffer[4]=(unsigned char) (value >> 24);
4305 buffer[5]=(unsigned char) (value >> 16);
4306 buffer[6]=(unsigned char) (value >> 8);
4307 buffer[7]=(unsigned char) value;
4308 return(WriteBlobStream(image,8,buffer));
4312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4316 + W r i t e B l o b M S B S h o r t %
4320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4322 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4323 % most-significant byte first order.
4325 % The format of the WriteBlobMSBShort method is:
4327 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4329 % A description of each parameter follows.
4331 % o value: Specifies the value to write.
4333 % o file: Specifies the file to write the data to.
4336 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4341 assert(image != (Image *) NULL);
4342 assert(image->signature == MagickSignature);
4343 buffer[0]=(unsigned char) (value >> 8);
4344 buffer[1]=(unsigned char) value;
4345 return(WriteBlobStream(image,2,buffer));
4349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4353 + W r i t e B l o b S t r i n g %
4357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4359 % WriteBlobString() write a string to a blob. It returns the number of
4360 % characters written.
4362 % The format of the WriteBlobString method is:
4364 % ssize_t WriteBlobString(Image *image,const char *string)
4366 % A description of each parameter follows.
4368 % o image: the image.
4370 % o string: Specifies the string to write.
4373 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4375 assert(image != (Image *) NULL);
4376 assert(image->signature == MagickSignature);
4377 assert(string != (const char *) NULL);
4378 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));