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)
273 if ((file == -1) || (i < length))
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)
871 if (LocaleCompare(filename,"-") != 0)
873 if (blob == (unsigned char *) NULL)
875 (void) ThrowMagickException(exception,GetMagickModule(),
876 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
877 return((unsigned char *) NULL);
881 blob=(unsigned char *) RelinquishMagickMemory(blob);
882 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
883 return((unsigned char *) NULL);
885 *length=MagickMin(i+count,extent);
889 *length=MagickMin((size_t) offset,extent);
890 blob=(unsigned char *) NULL;
891 if (~(*length) >= MaxTextExtent)
892 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
894 if (blob == (unsigned char *) NULL)
897 (void) ThrowMagickException(exception,GetMagickModule(),
898 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
899 return((unsigned char *) NULL);
901 map=MapBlob(file,ReadMode,0,*length);
902 if (map != (unsigned char *) NULL)
904 (void) memcpy(blob,map,*length);
905 (void) UnmapBlob(map,*length);
909 (void) MagickSeek(file,0,SEEK_SET);
910 for (i=0; i < *length; i+=count)
912 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
924 blob=(unsigned char *) RelinquishMagickMemory(blob);
925 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
926 return((unsigned char *) NULL);
930 if (LocaleCompare(filename,"-") != 0)
934 blob=(unsigned char *) RelinquishMagickMemory(blob);
935 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 % F i l e T o I m a g e %
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951 % FileToImage() write the contents of a file to an image.
953 % The format of the FileToImage method is:
955 % MagickBooleanType FileToImage(Image *,const char *filename)
957 % A description of each parameter follows:
959 % o image: the image.
961 % o filename: the filename.
965 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
966 const unsigned char *data)
971 register unsigned char
974 assert(image->blob != (BlobInfo *) NULL);
975 if (image->blob->type != BlobStream)
976 return(WriteBlob(image,length,data));
977 assert(image->blob->type != UndefinedStream);
978 assert(data != (void *) NULL);
979 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
980 if (extent >= image->blob->extent)
982 image->blob->quantum<<=1;
983 extent=image->blob->extent+image->blob->quantum+length;
984 if (SetBlobExtent(image,extent) == MagickFalse)
987 q=image->blob->data+image->blob->offset;
988 (void) memcpy(q,data,length);
989 image->blob->offset+=length;
990 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
991 image->blob->length=(size_t) image->blob->offset;
992 return((ssize_t) length);
995 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1013 assert(image != (const Image *) NULL);
1014 assert(image->signature == MagickSignature);
1015 assert(filename != (const char *) NULL);
1016 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1017 file=open(filename,O_RDONLY | O_BINARY);
1020 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1022 return(MagickFalse);
1024 quantum=(size_t) MagickMaxBufferExtent;
1025 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1026 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1027 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1028 if (blob == (unsigned char *) NULL)
1030 ThrowFileException(&image->exception,ResourceLimitError,
1031 "MemoryAllocationFailed",filename);
1032 return(MagickFalse);
1036 count=(ssize_t) read(file,blob,quantum);
1043 length=(size_t) count;
1044 count=WriteBlobStream(image,length,blob);
1045 if (count != (ssize_t) length)
1047 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1054 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1056 blob=(unsigned char *) RelinquishMagickMemory(blob);
1061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065 + G e t B l o b E r r o r %
1069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071 % GetBlobError() returns MagickTrue if the blob associated with the specified
1072 % image encountered an error.
1074 % The format of the GetBlobError method is:
1076 % MagickBooleanType GetBlobError(const Image *image)
1078 % A description of each parameter follows:
1080 % o image: the image.
1083 MagickExport MagickBooleanType GetBlobError(const Image *image)
1085 assert(image != (const Image *) NULL);
1086 assert(image->signature == MagickSignature);
1087 if (image->debug != MagickFalse)
1088 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1089 return(image->blob->status);
1093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1097 + G e t B l o b F i l e H a n d l e %
1101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1103 % GetBlobFileHandle() returns the file handle associated with the image blob.
1105 % The format of the GetBlobFile method is:
1107 % FILE *GetBlobFileHandle(const Image *image)
1109 % A description of each parameter follows:
1111 % o image: the image.
1114 MagickExport FILE *GetBlobFileHandle(const Image *image)
1116 assert(image != (const Image *) NULL);
1117 assert(image->signature == MagickSignature);
1118 return(image->blob->file);
1122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1126 + G e t B l o b I n f o %
1130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1132 % GetBlobInfo() initializes the BlobInfo structure.
1134 % The format of the GetBlobInfo method is:
1136 % void GetBlobInfo(BlobInfo *blob_info)
1138 % A description of each parameter follows:
1140 % o blob_info: Specifies a pointer to a BlobInfo structure.
1143 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1145 assert(blob_info != (BlobInfo *) NULL);
1146 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1147 blob_info->type=UndefinedStream;
1148 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1149 blob_info->properties.st_mtime=time((time_t *) NULL);
1150 blob_info->properties.st_ctime=time((time_t *) NULL);
1151 blob_info->debug=IsEventLogging();
1152 blob_info->reference_count=1;
1153 blob_info->semaphore=AllocateSemaphoreInfo();
1154 blob_info->signature=MagickSignature;
1158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1162 % G e t B l o b P r o p e r t i e s %
1166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1168 % GetBlobProperties() returns information about an image blob.
1170 % The format of the GetBlobProperties method is:
1172 % const struct stat *GetBlobProperties(const Image *image)
1174 % A description of each parameter follows:
1176 % o image: the image.
1179 MagickExport const struct stat *GetBlobProperties(const Image *image)
1181 assert(image != (Image *) NULL);
1182 assert(image->signature == MagickSignature);
1183 if (image->debug != MagickFalse)
1184 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1185 return(&image->blob->properties);
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 + G e t B l o b S i z e %
1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1199 % GetBlobSize() returns the current length of the image file or blob; zero is
1200 % returned if the size cannot be determined.
1202 % The format of the GetBlobSize method is:
1204 % MagickSizeType GetBlobSize(const Image *image)
1206 % A description of each parameter follows:
1208 % o image: the image.
1211 MagickExport MagickSizeType GetBlobSize(const Image *image)
1216 assert(image != (Image *) NULL);
1217 assert(image->signature == MagickSignature);
1218 if (image->debug != MagickFalse)
1219 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1220 assert(image->blob != (BlobInfo *) NULL);
1222 switch (image->blob->type)
1224 case UndefinedStream:
1226 extent=image->blob->size;
1231 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1232 extent=(MagickSizeType) image->blob->properties.st_size;
1235 case StandardStream:
1238 extent=image->blob->size;
1247 status=GetPathAttributes(image->filename,&image->blob->properties);
1248 if (status != MagickFalse)
1249 extent=(MagickSizeType) image->blob->properties.st_size;
1256 extent=(MagickSizeType) image->blob->length;
1264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1268 + G e t B l o b S t r e a m D a t a %
1272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1274 % GetBlobStreamData() returns the stream data for the image.
1276 % The format of the GetBlobStreamData method is:
1278 % unsigned char *GetBlobStreamData(const Image *image)
1280 % A description of each parameter follows:
1282 % o image: the image.
1285 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1287 assert(image != (const Image *) NULL);
1288 assert(image->signature == MagickSignature);
1289 return(image->blob->data);
1293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1297 + G e t B l o b S t r e a m H a n d l e r %
1301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1303 % GetBlobStreamHandler() returns the stream handler for the image.
1305 % The format of the GetBlobStreamHandler method is:
1307 % StreamHandler GetBlobStreamHandler(const Image *image)
1309 % A description of each parameter follows:
1311 % o image: the image.
1314 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1316 assert(image != (const Image *) NULL);
1317 assert(image->signature == MagickSignature);
1318 if (image->debug != MagickFalse)
1319 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1320 return(image->blob->stream);
1324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1328 % I m a g e T o B l o b %
1332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1334 % ImageToBlob() implements direct to memory image formats. It returns the
1335 % image as a blob and its length. The magick member of the ImageInfo structure
1336 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1338 % The format of the ImageToBlob method is:
1340 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1341 % size_t *length,ExceptionInfo *exception)
1343 % A description of each parameter follows:
1345 % o image_info: the image info.
1347 % o image: the image.
1349 % o length: This pointer to a size_t integer sets the initial length of the
1350 % blob. On return, it reflects the actual length of the blob.
1352 % o exception: return any errors or warnings in this structure.
1355 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1356 Image *image,size_t *length,ExceptionInfo *exception)
1370 assert(image_info != (const ImageInfo *) NULL);
1371 assert(image_info->signature == MagickSignature);
1372 if (image_info->debug != MagickFalse)
1373 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1374 image_info->filename);
1375 assert(image != (Image *) NULL);
1376 assert(image->signature == MagickSignature);
1377 assert(exception != (ExceptionInfo *) NULL);
1379 blob=(unsigned char *) NULL;
1380 blob_info=CloneImageInfo(image_info);
1381 blob_info->adjoin=MagickFalse;
1382 (void) SetImageInfo(blob_info,1,exception);
1383 if (*blob_info->magick != '\0')
1384 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1385 magick_info=GetMagickInfo(image->magick,exception);
1386 if (magick_info == (const MagickInfo *) NULL)
1388 (void) ThrowMagickException(exception,GetMagickModule(),
1389 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1393 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1394 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1397 Native blob support for this image format.
1399 blob_info->length=0;
1400 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1401 sizeof(unsigned char));
1402 if (blob_info->blob == (void *) NULL)
1403 (void) ThrowMagickException(exception,GetMagickModule(),
1404 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1407 (void) CloseBlob(image);
1408 image->blob->exempt=MagickTrue;
1409 *image->filename='\0';
1410 status=WriteImage(blob_info,image);
1411 if ((status == MagickFalse) || (image->blob->length == 0))
1412 InheritException(exception,&image->exception);
1415 *length=image->blob->length;
1416 blob=DetachBlob(image->blob);
1417 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1425 unique[MaxTextExtent];
1431 Write file to disk in blob image format.
1433 file=AcquireUniqueFileResource(unique);
1436 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1437 image_info->filename);
1441 blob_info->file=fdopen(file,"wb");
1442 if (blob_info->file != (FILE *) NULL)
1444 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1445 image->magick,unique);
1446 status=WriteImage(blob_info,image);
1447 (void) fclose(blob_info->file);
1448 if (status == MagickFalse)
1449 InheritException(exception,&image->exception);
1451 blob=FileToBlob(image->filename,~0UL,length,exception);
1453 (void) RelinquishUniqueFileResource(unique);
1456 blob_info=DestroyImageInfo(blob_info);
1461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1465 % I m a g e T o F i l e %
1469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1471 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1472 % occurs otherwise MagickTrue.
1474 % The format of the ImageToFile method is:
1476 % MagickBooleanType ImageToFile(Image *image,char *filename,
1477 % ExceptionInfo *exception)
1479 % A description of each parameter follows:
1481 % o image: the image.
1483 % o filename: Write the image to this file.
1485 % o exception: return any errors or warnings in this structure.
1489 static inline const unsigned char *ReadBlobStream(Image *image,
1490 const size_t length,unsigned char *data,ssize_t *count)
1492 assert(count != (ssize_t *) NULL);
1493 assert(image->blob != (BlobInfo *) NULL);
1494 if (image->blob->type != BlobStream)
1496 *count=ReadBlob(image,length,data);
1499 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1502 image->blob->eof=MagickTrue;
1505 data=image->blob->data+image->blob->offset;
1506 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
1507 image->blob->offset));
1508 image->blob->offset+=(*count);
1509 if (*count != (ssize_t) length)
1510 image->blob->eof=MagickTrue;
1514 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1515 ExceptionInfo *exception)
1520 register const unsigned char
1539 assert(image != (Image *) NULL);
1540 assert(image->signature == MagickSignature);
1541 assert(image->blob != (BlobInfo *) NULL);
1542 assert(image->blob->type != UndefinedStream);
1543 if (image->debug != MagickFalse)
1544 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1545 assert(filename != (const char *) NULL);
1546 if (*filename == '\0')
1547 file=AcquireUniqueFileResource(filename);
1549 if (LocaleCompare(filename,"-") == 0)
1550 file=fileno(stdout);
1552 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1555 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1556 return(MagickFalse);
1558 quantum=(size_t) MagickMaxBufferExtent;
1559 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1560 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1561 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1562 if (buffer == (unsigned char *) NULL)
1565 (void) ThrowMagickException(exception,GetMagickModule(),
1566 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1567 return(MagickFalse);
1570 p=ReadBlobStream(image,quantum,buffer,&count);
1571 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1573 length=(size_t) count;
1574 for (i=0; i < length; i+=count)
1576 count=write(file,p+i,(size_t) (length-i));
1587 if (LocaleCompare(filename,"-") != 0)
1589 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1590 if ((file == -1) || (i < length))
1592 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1593 return(MagickFalse);
1599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1603 % I m a g e s T o B l o b %
1607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1609 % ImagesToBlob() implements direct to memory image formats. It returns the
1610 % image sequence as a blob and its length. The magick member of the ImageInfo
1611 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1613 % Note, some image formats do not permit multiple images to the same image
1614 % stream (e.g. JPEG). in this instance, just the first image of the
1615 % sequence is returned as a blob.
1617 % The format of the ImagesToBlob method is:
1619 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1620 % size_t *length,ExceptionInfo *exception)
1622 % A description of each parameter follows:
1624 % o image_info: the image info.
1626 % o images: the image list.
1628 % o length: This pointer to a size_t integer sets the initial length of the
1629 % blob. On return, it reflects the actual length of the blob.
1631 % o exception: return any errors or warnings in this structure.
1634 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1635 Image *images,size_t *length,ExceptionInfo *exception)
1649 assert(image_info != (const ImageInfo *) NULL);
1650 assert(image_info->signature == MagickSignature);
1651 if (image_info->debug != MagickFalse)
1652 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1653 image_info->filename);
1654 assert(images != (Image *) NULL);
1655 assert(images->signature == MagickSignature);
1656 assert(exception != (ExceptionInfo *) NULL);
1658 blob=(unsigned char *) NULL;
1659 blob_info=CloneImageInfo(image_info);
1660 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1662 if (*blob_info->magick != '\0')
1663 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1664 if (blob_info->adjoin == MagickFalse)
1666 blob_info=DestroyImageInfo(blob_info);
1667 return(ImageToBlob(image_info,images,length,exception));
1669 magick_info=GetMagickInfo(images->magick,exception);
1670 if (magick_info == (const MagickInfo *) NULL)
1672 (void) ThrowMagickException(exception,GetMagickModule(),
1673 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1677 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1678 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1681 Native blob support for this images format.
1683 blob_info->length=0;
1684 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1685 sizeof(unsigned char));
1686 if (blob_info->blob == (void *) NULL)
1687 (void) ThrowMagickException(exception,GetMagickModule(),
1688 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1691 images->blob->exempt=MagickTrue;
1692 *images->filename='\0';
1693 status=WriteImages(blob_info,images,images->filename,exception);
1694 if ((status == MagickFalse) || (images->blob->length == 0))
1695 InheritException(exception,&images->exception);
1698 *length=images->blob->length;
1699 blob=DetachBlob(images->blob);
1700 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1708 filename[MaxTextExtent],
1709 unique[MaxTextExtent];
1715 Write file to disk in blob images format.
1717 file=AcquireUniqueFileResource(unique);
1720 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1721 image_info->filename);
1725 blob_info->file=fdopen(file,"wb");
1726 if (blob_info->file != (FILE *) NULL)
1728 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1729 images->magick,unique);
1730 status=WriteImages(blob_info,images,filename,exception);
1731 (void) fclose(blob_info->file);
1732 if (status == MagickFalse)
1733 InheritException(exception,&images->exception);
1735 blob=FileToBlob(images->filename,~0UL,length,exception);
1737 (void) RelinquishUniqueFileResource(unique);
1740 blob_info=DestroyImageInfo(blob_info);
1744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1748 % I n j e c t I m a g e B l o b %
1752 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1754 % InjectImageBlob() injects the image with a copy of itself in the specified
1755 % format (e.g. inject JPEG into a PDF image).
1757 % The format of the InjectImageBlob method is:
1759 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1760 % Image *image,Image *inject_image,const char *format,
1761 % ExceptionInfo *exception)
1763 % A description of each parameter follows:
1765 % o image_info: the image info..
1767 % o image: the image.
1769 % o inject_image: inject into the image stream.
1771 % o format: the image format.
1773 % o exception: return any errors or warnings in this structure.
1776 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1777 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1780 filename[MaxTextExtent];
1813 Write inject image to a temporary file.
1815 assert(image_info != (ImageInfo *) NULL);
1816 assert(image_info->signature == MagickSignature);
1817 assert(image != (Image *) NULL);
1818 assert(image->signature == MagickSignature);
1819 if (image->debug != MagickFalse)
1820 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1821 assert(inject_image != (Image *) NULL);
1822 assert(inject_image->signature == MagickSignature);
1823 assert(exception != (ExceptionInfo *) NULL);
1824 unique_file=(FILE *) NULL;
1825 file=AcquireUniqueFileResource(filename);
1827 unique_file=fdopen(file,"wb");
1828 if ((file == -1) || (unique_file == (FILE *) NULL))
1830 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1831 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1833 return(MagickFalse);
1835 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1836 if (byte_image == (Image *) NULL)
1838 (void) fclose(unique_file);
1839 (void) RelinquishUniqueFileResource(filename);
1840 return(MagickFalse);
1842 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1844 DestroyBlob(byte_image);
1845 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1846 write_info=CloneImageInfo(image_info);
1847 SetImageInfoFile(write_info,unique_file);
1848 status=WriteImage(write_info,byte_image);
1849 write_info=DestroyImageInfo(write_info);
1850 byte_image=DestroyImage(byte_image);
1851 (void) fclose(unique_file);
1852 if (status == MagickFalse)
1854 (void) RelinquishUniqueFileResource(filename);
1855 return(MagickFalse);
1858 Inject into image stream.
1860 file=open(filename,O_RDONLY | O_BINARY);
1863 (void) RelinquishUniqueFileResource(filename);
1864 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1865 image_info->filename);
1866 return(MagickFalse);
1868 quantum=(size_t) MagickMaxBufferExtent;
1869 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1870 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1871 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1872 if (buffer == (unsigned char *) NULL)
1874 (void) RelinquishUniqueFileResource(filename);
1875 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1878 for (i=0; ; i+=count)
1880 count=(ssize_t) read(file,buffer,quantum);
1887 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1892 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1893 (void) RelinquishUniqueFileResource(filename);
1894 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1903 + I s B l o b E x e m p t %
1907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1909 % IsBlobExempt() returns true if the blob is exempt.
1911 % The format of the IsBlobExempt method is:
1913 % MagickBooleanType IsBlobExempt(const Image *image)
1915 % A description of each parameter follows:
1917 % o image: the image.
1920 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1922 assert(image != (const Image *) NULL);
1923 assert(image->signature == MagickSignature);
1924 if (image->debug != MagickFalse)
1925 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1926 return(image->blob->exempt);
1930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1934 + I s B l o b S e e k a b l e %
1938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1940 % IsBlobSeekable() returns true if the blob is seekable.
1942 % The format of the IsBlobSeekable method is:
1944 % MagickBooleanType IsBlobSeekable(const Image *image)
1946 % A description of each parameter follows:
1948 % o image: the image.
1951 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
1956 assert(image != (const Image *) NULL);
1957 assert(image->signature == MagickSignature);
1958 if (image->debug != MagickFalse)
1959 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1960 seekable=(image->blob->type == FileStream) ||
1961 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
1966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1970 + I s B l o b T e m p o r a r y %
1974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1976 % IsBlobTemporary() returns true if the blob is temporary.
1978 % The format of the IsBlobTemporary method is:
1980 % MagickBooleanType IsBlobTemporary(const Image *image)
1982 % A description of each parameter follows:
1984 % o image: the image.
1987 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
1989 assert(image != (const Image *) NULL);
1990 assert(image->signature == MagickSignature);
1991 if (image->debug != MagickFalse)
1992 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1993 return(image->blob->temporary);
1997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2007 % MapBlob() creates a mapping from a file to a binary large object.
2009 % The format of the MapBlob method is:
2011 % unsigned char *MapBlob(int file,const MapMode mode,
2012 % const MagickOffsetType offset,const size_t length)
2014 % A description of each parameter follows:
2016 % o file: map this file descriptor.
2018 % o mode: ReadMode, WriteMode, or IOMode.
2020 % o offset: starting at this offset within the file.
2022 % o length: the length of the mapping is returned in this pointer.
2025 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2026 const MagickOffsetType offset,const size_t length)
2028 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2041 #if defined(MAP_ANONYMOUS)
2042 flags|=MAP_ANONYMOUS;
2044 return((unsigned char *) NULL);
2051 protection=PROT_READ;
2053 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2059 protection=PROT_WRITE;
2061 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2063 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2064 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2065 POSIX_MADV_WILLNEED);
2071 protection=PROT_READ | PROT_WRITE;
2073 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2078 if (map == (unsigned char *) MAP_FAILED)
2079 return((unsigned char *) NULL);
2086 return((unsigned char *) NULL);
2091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2095 + M S B O r d e r L o n g %
2099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2101 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2102 % most-significant byte first.
2104 % The format of the MSBOrderLong method is:
2106 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2108 % A description of each parameter follows.
2110 % o buffer: Specifies a pointer to a buffer of integers.
2112 % o length: Specifies the length of the buffer.
2115 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2120 register unsigned char
2124 assert(buffer != (unsigned char *) NULL);
2131 *buffer++=(unsigned char) c;
2135 *buffer++=(unsigned char) c;
2141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2145 + M S B O r d e r S h o r t %
2149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2151 % MSBOrderShort() converts a least-significant byte first buffer of integers
2152 % to most-significant byte first.
2154 % The format of the MSBOrderShort method is:
2156 % void MSBOrderShort(unsigned char *p,const size_t length)
2158 % A description of each parameter follows.
2160 % o p: Specifies a pointer to a buffer of integers.
2162 % o length: Specifies the length of the buffer.
2165 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2170 register unsigned char
2173 assert(p != (unsigned char *) NULL);
2180 *p++=(unsigned char) c;
2185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2195 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2196 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2197 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2198 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2199 % from a system command.
2201 % The format of the OpenBlob method is:
2203 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2204 % const BlobMode mode,ExceptionInfo *exception)
2206 % A description of each parameter follows:
2208 % o image_info: the image info.
2210 % o image: the image.
2212 % o mode: the mode for opening the file.
2215 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2216 Image *image,const BlobMode mode,ExceptionInfo *exception)
2219 extension[MaxTextExtent],
2220 filename[MaxTextExtent];
2231 assert(image_info != (ImageInfo *) NULL);
2232 assert(image_info->signature == MagickSignature);
2233 if (image_info->debug != MagickFalse)
2234 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2235 image_info->filename);
2236 assert(image != (Image *) NULL);
2237 assert(image->signature == MagickSignature);
2238 if (image_info->blob != (void *) NULL)
2240 if (image_info->stream != (StreamHandler) NULL)
2241 image->blob->stream=(StreamHandler) image_info->stream;
2242 AttachBlob(image->blob,image_info->blob,image_info->length);
2245 (void) DetachBlob(image->blob);
2248 default: type="r"; break;
2249 case ReadBlobMode: type="r"; break;
2250 case ReadBinaryBlobMode: type="rb"; break;
2251 case WriteBlobMode: type="w"; break;
2252 case WriteBinaryBlobMode: type="w+b"; break;
2253 case AppendBlobMode: type="a"; break;
2254 case AppendBinaryBlobMode: type="a+b"; break;
2257 image->blob->synchronize=image_info->synchronize;
2258 if (image_info->stream != (StreamHandler) NULL)
2260 image->blob->stream=(StreamHandler) image_info->stream;
2263 image->blob->type=FifoStream;
2271 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2272 rights=ReadPolicyRights;
2274 rights=WritePolicyRights;
2275 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2278 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2279 "NotAuthorized","`%s'",filename);
2280 return(MagickFalse);
2282 if ((LocaleCompare(filename,"-") == 0) ||
2283 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2285 image->blob->file=(*type == 'r') ? stdin : stdout;
2286 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2287 if (strchr(type,'b') != (char *) NULL)
2288 setmode(_fileno(image->blob->file),_O_BINARY);
2290 image->blob->type=StandardStream;
2291 image->blob->exempt=MagickTrue;
2294 if (LocaleNCompare(filename,"fd:",3) == 0)
2297 mode[MaxTextExtent];
2301 image->blob->file=fdopen(StringToLong(filename+3),mode);
2302 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2303 if (strchr(type,'b') != (char *) NULL)
2304 setmode(_fileno(image->blob->file),_O_BINARY);
2306 image->blob->type=StandardStream;
2307 image->blob->exempt=MagickTrue;
2310 #if defined(MAGICKCORE_HAVE_POPEN)
2311 if (*filename == '|')
2314 mode[MaxTextExtent];
2317 Pipe image to or from a system command.
2319 #if defined(SIGPIPE)
2321 (void) signal(SIGPIPE,SIG_IGN);
2325 image->blob->file=(FILE *) popen(filename+1,mode);
2326 if (image->blob->file == (FILE *) NULL)
2328 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2329 return(MagickFalse);
2331 image->blob->type=PipeStream;
2332 image->blob->exempt=MagickTrue;
2336 status=GetPathAttributes(filename,&image->blob->properties);
2337 #if defined(S_ISFIFO)
2338 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2340 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2341 if (image->blob->file == (FILE *) NULL)
2343 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2344 return(MagickFalse);
2346 image->blob->type=FileStream;
2347 image->blob->exempt=MagickTrue;
2351 GetPathComponent(image->filename,ExtensionPath,extension);
2354 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2355 if ((image_info->adjoin == MagickFalse) ||
2356 (IsGlob(filename) != MagickFalse))
2359 Form filename for multi-part images.
2361 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2362 image->scene,filename);
2363 if ((LocaleCompare(filename,image->filename) == 0) &&
2364 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2365 (GetNextImageInList(image) != (Image *) NULL)))
2368 path[MaxTextExtent];
2370 GetPathComponent(image->filename,RootPath,path);
2371 if (*extension == '\0')
2372 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2373 path,(double) image->scene);
2375 (void) FormatMagickString(filename,MaxTextExtent,
2376 "%s-%.20g.%s",path,(double) image->scene,extension);
2378 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2379 #if defined(macintosh)
2380 SetApplicationType(filename,image_info->magick,'8BIM');
2384 if (image_info->file != (FILE *) NULL)
2386 image->blob->file=image_info->file;
2387 image->blob->type=FileStream;
2388 image->blob->exempt=MagickTrue;
2393 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2394 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,
2407 (void) ResetMagickMemory(magick,0,sizeof(magick));
2408 count=fread(magick,1,sizeof(magick),image->blob->file);
2409 (void) rewind(image->blob->file);
2410 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2411 " read %.20g magic header bytes",(double) count);
2412 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2413 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2414 ((int) magick[2] == 0x08))
2416 (void) fclose(image->blob->file);
2417 image->blob->file=(FILE *) gzopen(filename,type);
2418 if (image->blob->file != (FILE *) NULL)
2419 image->blob->type=ZipStream;
2422 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2423 if (strncmp((char *) magick,"BZh",3) == 0)
2425 (void) fclose(image->blob->file);
2426 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2427 if (image->blob->file != (FILE *) NULL)
2428 image->blob->type=BZipStream;
2431 if (image->blob->type == FileStream)
2442 sans_exception=AcquireExceptionInfo();
2443 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2444 sans_exception=DestroyExceptionInfo(sans_exception);
2445 properties=(&image->blob->properties);
2446 if ((magick_info != (const MagickInfo *) NULL) &&
2447 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2448 (properties->st_size <= MagickMaxBufferExtent))
2456 length=(size_t) properties->st_size;
2457 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2458 if (blob != (void *) NULL)
2461 Format supports blobs-- use memory-mapped I/O.
2463 if (image_info->file != (FILE *) NULL)
2464 image->blob->exempt=MagickFalse;
2467 (void) fclose(image->blob->file);
2468 image->blob->file=(FILE *) NULL;
2470 AttachBlob(image->blob,blob,length);
2471 image->blob->mapped=MagickTrue;
2478 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2479 if ((LocaleCompare(extension,"Z") == 0) ||
2480 (LocaleCompare(extension,"gz") == 0) ||
2481 (LocaleCompare(extension,"wmz") == 0) ||
2482 (LocaleCompare(extension,"svgz") == 0))
2484 if (mode == WriteBinaryBlobMode)
2486 image->blob->file=(FILE *) gzopen(filename,type);
2487 if (image->blob->file != (FILE *) NULL)
2488 image->blob->type=ZipStream;
2492 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2493 if (LocaleCompare(extension,".bz2") == 0)
2495 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2496 if (image->blob->file != (FILE *) NULL)
2497 image->blob->type=BZipStream;
2502 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2503 if (image->blob->file != (FILE *) NULL)
2505 image->blob->type=FileStream;
2506 #if defined(MAGICKCORE_HAVE_SETVBUF)
2507 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2512 image->blob->status=MagickFalse;
2513 if (image->blob->type != UndefinedStream)
2514 image->blob->size=GetBlobSize(image);
2517 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2518 return(MagickFalse);
2524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2534 % PingBlob() returns all the attributes of an image or image sequence except
2535 % for the pixels. It is much faster and consumes far less memory than
2536 % BlobToImage(). On failure, a NULL image is returned and exception
2537 % describes the reason for the failure.
2539 % The format of the PingBlob method is:
2541 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2542 % const size_t length,ExceptionInfo *exception)
2544 % A description of each parameter follows:
2546 % o image_info: the image info.
2548 % o blob: the address of a character stream in one of the image formats
2549 % understood by ImageMagick.
2551 % o length: This size_t integer reflects the length in bytes of the blob.
2553 % o exception: return any errors or warnings in this structure.
2557 #if defined(__cplusplus) || defined(c_plusplus)
2561 static size_t PingStream(const Image *magick_unused(image),
2562 const void *magick_unused(pixels),const size_t columns)
2567 #if defined(__cplusplus) || defined(c_plusplus)
2571 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2572 const size_t length,ExceptionInfo *exception)
2580 assert(image_info != (ImageInfo *) NULL);
2581 assert(image_info->signature == MagickSignature);
2582 if (image_info->debug != MagickFalse)
2583 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2584 image_info->filename);
2585 assert(exception != (ExceptionInfo *) NULL);
2586 if ((blob == (const void *) NULL) || (length == 0))
2588 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2589 "UnrecognizedImageFormat","`%s'",image_info->magick);
2590 return((Image *) NULL);
2592 ping_info=CloneImageInfo(image_info);
2593 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2594 if (ping_info->blob == (const void *) NULL)
2596 (void) ThrowMagickException(exception,GetMagickModule(),
2597 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2598 return((Image *) NULL);
2600 (void) memcpy(ping_info->blob,blob,length);
2601 ping_info->length=length;
2602 ping_info->ping=MagickTrue;
2603 image=ReadStream(ping_info,&PingStream,exception);
2604 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2605 ping_info=DestroyImageInfo(ping_info);
2610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2620 % ReadBlob() reads data from the blob or image file and returns it. It
2621 % returns the number of bytes read.
2623 % The format of the ReadBlob method is:
2625 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2627 % A description of each parameter follows:
2629 % o image: the image.
2631 % o length: Specifies an integer representing the number of bytes to read
2634 % o data: Specifies an area to place the information requested from the
2638 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2639 unsigned char *data)
2644 register unsigned char
2650 assert(image != (Image *) NULL);
2651 assert(image->signature == MagickSignature);
2652 assert(image->blob != (BlobInfo *) NULL);
2653 assert(image->blob->type != UndefinedStream);
2656 assert(data != (void *) NULL);
2659 switch (image->blob->type)
2661 case UndefinedStream:
2664 case StandardStream:
2671 count=(ssize_t) fread(q,1,length,image->blob->file);
2676 c=getc(image->blob->file);
2679 *q++=(unsigned char) c;
2684 c=getc(image->blob->file);
2687 *q++=(unsigned char) c;
2697 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2702 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2707 c=gzgetc(image->blob->file);
2710 *q++=(unsigned char) c;
2715 c=gzgetc(image->blob->file);
2718 *q++=(unsigned char) c;
2729 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2730 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2738 register const unsigned char
2741 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2743 image->blob->eof=MagickTrue;
2746 p=image->blob->data+image->blob->offset;
2747 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2748 image->blob->offset));
2749 image->blob->offset+=count;
2750 if (count != (ssize_t) length)
2751 image->blob->eof=MagickTrue;
2752 (void) memcpy(q,p,(size_t) count);
2760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2764 + R e a d B l o b B y t e %
2768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2770 % ReadBlobByte() reads a single byte from the image file and returns it.
2772 % The format of the ReadBlobByte method is:
2774 % int ReadBlobByte(Image *image)
2776 % A description of each parameter follows.
2778 % o image: the image.
2781 MagickExport int ReadBlobByte(Image *image)
2783 register const unsigned char
2792 assert(image != (Image *) NULL);
2793 assert(image->signature == MagickSignature);
2794 p=ReadBlobStream(image,1,buffer,&count);
2801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2805 + R e a d B l o b D o u b l e %
2809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2811 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2812 % specified by the endian member of the image structure.
2814 % The format of the ReadBlobDouble method is:
2816 % double ReadBlobDouble(Image *image)
2818 % A description of each parameter follows.
2820 % o image: the image.
2823 MagickExport double ReadBlobDouble(Image *image)
2834 quantum.double_value=0.0;
2835 quantum.unsigned_value=ReadBlobLongLong(image);
2836 return(quantum.double_value);
2840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2844 + R e a d B l o b F l o a t %
2848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2850 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2851 % specified by the endian member of the image structure.
2853 % The format of the ReadBlobFloat method is:
2855 % float ReadBlobFloat(Image *image)
2857 % A description of each parameter follows.
2859 % o image: the image.
2862 MagickExport float ReadBlobFloat(Image *image)
2873 quantum.float_value=0.0;
2874 quantum.unsigned_value=ReadBlobLong(image);
2875 return(quantum.float_value);
2879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2883 + R e a d B l o b L o n g %
2887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2889 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2890 % specified by the endian member of the image structure.
2892 % The format of the ReadBlobLong method is:
2894 % unsigned int ReadBlobLong(Image *image)
2896 % A description of each parameter follows.
2898 % o image: the image.
2901 MagickExport unsigned int ReadBlobLong(Image *image)
2903 register const unsigned char
2915 assert(image != (Image *) NULL);
2916 assert(image->signature == MagickSignature);
2918 p=ReadBlobStream(image,4,buffer,&count);
2921 if (image->endian == LSBEndian)
2923 value=(unsigned int) (*p++);
2924 value|=((unsigned int) (*p++)) << 8;
2925 value|=((unsigned int) (*p++)) << 16;
2926 value|=((unsigned int) (*p++)) << 24;
2929 value=((unsigned int) (*p++)) << 24;
2930 value|=((unsigned int) (*p++)) << 16;
2931 value|=((unsigned int) (*p++)) << 8;
2932 value|=((unsigned int) (*p++));
2937 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2941 + R e a d B l o b L o n g L o n g %
2945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2947 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
2948 % byte-order specified by the endian member of the image structure.
2950 % The format of the ReadBlobLongLong method is:
2952 % MagickSizeType ReadBlobLongLong(Image *image)
2954 % A description of each parameter follows.
2956 % o image: the image.
2959 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
2961 register const unsigned char
2973 assert(image != (Image *) NULL);
2974 assert(image->signature == MagickSignature);
2976 p=ReadBlobStream(image,8,buffer,&count);
2978 return(MagickULLConstant(0));
2979 if (image->endian == LSBEndian)
2981 value=(MagickSizeType) (*p++);
2982 value|=((MagickSizeType) (*p++)) << 8;
2983 value|=((MagickSizeType) (*p++)) << 16;
2984 value|=((MagickSizeType) (*p++)) << 24;
2985 value|=((MagickSizeType) (*p++)) << 32;
2986 value|=((MagickSizeType) (*p++)) << 40;
2987 value|=((MagickSizeType) (*p++)) << 48;
2988 value|=((MagickSizeType) (*p++)) << 56;
2989 return(value & MagickULLConstant(0xffffffffffffffff));
2991 value=((MagickSizeType) (*p++)) << 56;
2992 value|=((MagickSizeType) (*p++)) << 48;
2993 value|=((MagickSizeType) (*p++)) << 40;
2994 value|=((MagickSizeType) (*p++)) << 32;
2995 value|=((MagickSizeType) (*p++)) << 24;
2996 value|=((MagickSizeType) (*p++)) << 16;
2997 value|=((MagickSizeType) (*p++)) << 8;
2998 value|=((MagickSizeType) (*p++));
2999 return(value & MagickULLConstant(0xffffffffffffffff));
3003 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3007 + R e a d B l o b S h o r t %
3011 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3013 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3014 % specified by the endian member of the image structure.
3016 % The format of the ReadBlobShort method is:
3018 % unsigned short ReadBlobShort(Image *image)
3020 % A description of each parameter follows.
3022 % o image: the image.
3025 MagickExport unsigned short ReadBlobShort(Image *image)
3027 register const unsigned char
3030 register unsigned int
3039 assert(image != (Image *) NULL);
3040 assert(image->signature == MagickSignature);
3042 p=ReadBlobStream(image,2,buffer,&count);
3044 return((unsigned short) 0U);
3045 if (image->endian == LSBEndian)
3047 value=(unsigned int) (*p++);
3048 value|=((unsigned int) (*p++)) << 8;
3049 return((unsigned short) (value & 0xffff));
3051 value=(unsigned int) ((*p++) << 8);
3052 value|=(unsigned int) (*p++);
3053 return((unsigned short) (value & 0xffff));
3057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3061 + R e a d B l o b L S B L o n g %
3065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3067 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3068 % least-significant byte first order.
3070 % The format of the ReadBlobLSBLong method is:
3072 % unsigned int ReadBlobLSBLong(Image *image)
3074 % A description of each parameter follows.
3076 % o image: the image.
3079 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3081 register const unsigned char
3084 register unsigned int
3093 assert(image != (Image *) NULL);
3094 assert(image->signature == MagickSignature);
3096 p=ReadBlobStream(image,4,buffer,&count);
3099 value=(unsigned int) (*p++);
3100 value|=((unsigned int) (*p++)) << 8;
3101 value|=((unsigned int) (*p++)) << 16;
3102 value|=((unsigned int) (*p++)) << 24;
3107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3111 + R e a d B l o b L S B S h o r t %
3115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3117 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3118 % least-significant byte first order.
3120 % The format of the ReadBlobLSBShort method is:
3122 % unsigned short ReadBlobLSBShort(Image *image)
3124 % A description of each parameter follows.
3126 % o image: the image.
3129 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3131 register const unsigned char
3134 register unsigned int
3143 assert(image != (Image *) NULL);
3144 assert(image->signature == MagickSignature);
3146 p=ReadBlobStream(image,2,buffer,&count);
3148 return((unsigned short) 0U);
3149 value=(unsigned int) (*p++);
3150 value|=((unsigned int) ((*p++)) << 8);
3151 return((unsigned short) (value & 0xffff));
3155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3159 + R e a d B l o b M S B L o n g %
3163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3165 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3166 % most-significant byte first order.
3168 % The format of the ReadBlobMSBLong method is:
3170 % unsigned int ReadBlobMSBLong(Image *image)
3172 % A description of each parameter follows.
3174 % o image: the image.
3177 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3179 register const unsigned char
3182 register unsigned int
3191 assert(image != (Image *) NULL);
3192 assert(image->signature == MagickSignature);
3194 p=ReadBlobStream(image,4,buffer,&count);
3197 value=((unsigned int) (*p++) << 24);
3198 value|=((unsigned int) (*p++) << 16);
3199 value|=((unsigned int) (*p++) << 8);
3200 value|=(unsigned int) (*p++);
3205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3209 + R e a d B l o b M S B L o n g L o n g %
3213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3215 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3216 % most-significant byte first order.
3218 % The format of the ReadBlobMSBLongLong method is:
3220 % unsigned int ReadBlobMSBLongLong(Image *image)
3222 % A description of each parameter follows.
3224 % o image: the image.
3227 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3229 register const unsigned char
3232 register MagickSizeType
3241 assert(image != (Image *) NULL);
3242 assert(image->signature == MagickSignature);
3244 p=ReadBlobStream(image,8,buffer,&count);
3246 return(MagickULLConstant(0));
3247 value=((MagickSizeType) (*p++)) << 56;
3248 value|=((MagickSizeType) (*p++)) << 48;
3249 value|=((MagickSizeType) (*p++)) << 40;
3250 value|=((MagickSizeType) (*p++)) << 32;
3251 value|=((MagickSizeType) (*p++)) << 24;
3252 value|=((MagickSizeType) (*p++)) << 16;
3253 value|=((MagickSizeType) (*p++)) << 8;
3254 value|=((MagickSizeType) (*p++));
3255 return(value & MagickULLConstant(0xffffffffffffffff));
3259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3263 + R e a d B l o b M S B S h o r t %
3267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3269 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3270 % most-significant byte first order.
3272 % The format of the ReadBlobMSBShort method is:
3274 % unsigned short ReadBlobMSBShort(Image *image)
3276 % A description of each parameter follows.
3278 % o image: the image.
3281 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3283 register const unsigned char
3286 register unsigned int
3295 assert(image != (Image *) NULL);
3296 assert(image->signature == MagickSignature);
3298 p=ReadBlobStream(image,2,buffer,&count);
3300 return((unsigned short) 0U);
3301 value=(unsigned int) ((*p++) << 8);
3302 value|=(unsigned int) (*p++);
3303 return((unsigned short) (value & 0xffff));
3307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3311 + R e a d B l o b S t r i n g %
3315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3317 % ReadBlobString() reads characters from a blob or file until a newline
3318 % character is read or an end-of-file condition is encountered.
3320 % The format of the ReadBlobString method is:
3322 % char *ReadBlobString(Image *image,char *string)
3324 % A description of each parameter follows:
3326 % o image: the image.
3328 % o string: the address of a character buffer.
3331 MagickExport char *ReadBlobString(Image *image,char *string)
3333 register const unsigned char
3345 assert(image != (Image *) NULL);
3346 assert(image->signature == MagickSignature);
3347 for (i=0; i < (MaxTextExtent-1L); i++)
3349 p=ReadBlobStream(image,1,buffer,&count);
3353 return((char *) NULL);
3356 string[i]=(char) (*p);
3357 if ((string[i] == '\r') || (string[i] == '\n'))
3360 if (string[i] == '\r')
3361 (void) ReadBlobStream(image,1,buffer,&count);
3367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3371 + R e f e r e n c e B l o b %
3375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3377 % ReferenceBlob() increments the reference count associated with the pixel
3378 % blob returning a pointer to the blob.
3380 % The format of the ReferenceBlob method is:
3382 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3384 % A description of each parameter follows:
3386 % o blob_info: the blob_info.
3389 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3391 assert(blob != (BlobInfo *) NULL);
3392 assert(blob->signature == MagickSignature);
3393 if (blob->debug != MagickFalse)
3394 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3395 LockSemaphoreInfo(blob->semaphore);
3396 blob->reference_count++;
3397 UnlockSemaphoreInfo(blob->semaphore);
3402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3412 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3413 % and returns the resulting offset.
3415 % The format of the SeekBlob method is:
3417 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3420 % A description of each parameter follows:
3422 % o image: the image.
3424 % o offset: Specifies an integer representing the offset in bytes.
3426 % o whence: Specifies an integer representing how the offset is
3427 % treated relative to the beginning of the blob as follows:
3429 % SEEK_SET Set position equal to offset bytes.
3430 % SEEK_CUR Set position to current location plus offset.
3431 % SEEK_END Set position to EOF plus offset.
3434 MagickExport MagickOffsetType SeekBlob(Image *image,
3435 const MagickOffsetType offset,const int whence)
3437 assert(image != (Image *) NULL);
3438 assert(image->signature == MagickSignature);
3439 if (image->debug != MagickFalse)
3440 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3441 assert(image->blob != (BlobInfo *) NULL);
3442 assert(image->blob->type != UndefinedStream);
3443 switch (image->blob->type)
3445 case UndefinedStream:
3449 if (fseek(image->blob->file,(long) offset,whence) < 0)
3451 image->blob->offset=TellBlob(image);
3454 case StandardStream:
3458 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3459 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3462 image->blob->offset=TellBlob(image);
3478 image->blob->offset=offset;
3483 if ((image->blob->offset+offset) < 0)
3485 image->blob->offset+=offset;
3490 if (((MagickOffsetType) image->blob->length+offset) < 0)
3492 image->blob->offset=image->blob->length+offset;
3496 if (image->blob->offset <= (MagickOffsetType)
3497 ((off_t) image->blob->length))
3498 image->blob->eof=MagickFalse;
3500 if (image->blob->mapped != MagickFalse)
3504 image->blob->extent=(size_t) (image->blob->offset+
3505 image->blob->quantum);
3506 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3507 image->blob->data,image->blob->extent+1,
3508 sizeof(*image->blob->data));
3509 (void) SyncBlob(image);
3510 if (image->blob->data == (unsigned char *) NULL)
3512 (void) DetachBlob(image->blob);
3519 return(image->blob->offset);
3523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3527 + S e t B l o b E x e m p t %
3531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3533 % SetBlobExempt() sets the blob exempt status.
3535 % The format of the SetBlobExempt method is:
3537 % MagickBooleanType SetBlobExempt(const Image *image,
3538 % const MagickBooleanType exempt)
3540 % A description of each parameter follows:
3542 % o image: the image.
3544 % o exempt: Set to true if this blob is exempt from being closed.
3547 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3549 assert(image != (const Image *) NULL);
3550 assert(image->signature == MagickSignature);
3551 if (image->debug != MagickFalse)
3552 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3553 image->blob->exempt=exempt;
3557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3561 + S e t B l o b E x t e n t %
3565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3567 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3568 % method is successful, subsequent writes to bytes in the specified range are
3569 % guaranteed not to fail.
3571 % The format of the SetBlobExtent method is:
3573 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3575 % A description of each parameter follows:
3577 % o image: the image.
3579 % o extent: the blob maximum extent.
3582 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3583 const MagickSizeType extent)
3585 assert(image != (Image *) NULL);
3586 assert(image->signature == MagickSignature);
3587 if (image->debug != MagickFalse)
3588 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3589 assert(image->blob != (BlobInfo *) NULL);
3590 assert(image->blob->type != UndefinedStream);
3591 switch (image->blob->type)
3593 case UndefinedStream:
3597 if (extent != (MagickSizeType) ((off_t) extent))
3598 return(MagickFalse);
3599 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3600 return(MagickFalse);
3609 offset=TellBlob(image);
3610 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3611 (off_t) (extent-offset));
3613 return(MagickFalse);
3618 case StandardStream:
3621 return(MagickFalse);
3623 return(MagickFalse);
3625 return(MagickFalse);
3628 if (image->blob->mapped != MagickFalse)
3630 if (image->blob->file == (FILE *) NULL)
3631 return(MagickFalse);
3632 (void) UnmapBlob(image->blob->data,image->blob->length);
3633 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3634 return(MagickFalse);
3643 offset=TellBlob(image);
3644 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3645 (off_t) (extent-offset));
3647 return(MagickFalse);
3649 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3650 WriteMode,0,(size_t) extent);
3651 image->blob->extent=(size_t) extent;
3652 image->blob->length=(size_t) extent;
3653 (void) SyncBlob(image);
3657 if (extent != (MagickSizeType) ((size_t) extent))
3658 return(MagickFalse);
3659 image->blob->extent=(size_t) extent;
3660 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3661 image->blob->extent+1,sizeof(*image->blob->data));
3662 (void) SyncBlob(image);
3663 if (image->blob->data == (unsigned char *) NULL)
3665 (void) DetachBlob(image->blob);
3666 return(MagickFalse);
3675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3679 + S k i p B l o b B y t e s %
3683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3685 % SkipBlobBytes() skips over bytes in a blob.
3687 % The format of the SkipBlobBytes method is:
3689 % MagickBooleanType SkipBlobBytes(Image *image,const size_t length)
3691 % A description of each parameter follows.
3693 % o image: the image.
3695 % o length: the number of bytes to skip.
3698 MagickExport MagickBooleanType SkipBlobBytes(Image *image,const size_t length)
3712 assert(image != (Image *) NULL);
3713 assert(image->signature == MagickSignature);
3715 for (i=0; i < (ssize_t) length; i+=count)
3717 quantum=MagickMin(length-i,sizeof(buffer));
3718 (void) ReadBlobStream(image,quantum,buffer,&count);
3726 return(i < (ssize_t) length ? MagickFalse : MagickTrue);
3730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3740 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3741 % attributes if it is an blob.
3743 % The format of the SyncBlob method is:
3745 % int SyncBlob(Image *image)
3747 % A description of each parameter follows:
3749 % o image: the image.
3752 static int SyncBlob(Image *image)
3757 assert(image != (Image *) NULL);
3758 assert(image->signature == MagickSignature);
3759 if (image->debug != MagickFalse)
3760 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3761 assert(image->blob != (BlobInfo *) NULL);
3762 assert(image->blob->type != UndefinedStream);
3764 switch (image->blob->type)
3766 case UndefinedStream:
3769 case StandardStream:
3772 status=fflush(image->blob->file);
3777 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3778 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3784 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3785 status=BZ2_bzflush((BZFILE *) image->blob->file);
3793 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3794 if (image->blob->mapped != MagickFalse)
3795 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3814 % TellBlob() obtains the current value of the blob or file position.
3816 % The format of the TellBlob method is:
3818 % MagickOffsetType TellBlob(const Image *image)
3820 % A description of each parameter follows:
3822 % o image: the image.
3825 MagickExport MagickOffsetType TellBlob(const Image *image)
3830 assert(image != (Image *) NULL);
3831 assert(image->signature == MagickSignature);
3832 if (image->debug != MagickFalse)
3833 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3834 assert(image->blob != (BlobInfo *) NULL);
3835 assert(image->blob->type != UndefinedStream);
3837 switch (image->blob->type)
3839 case UndefinedStream:
3843 offset=ftell(image->blob->file);
3846 case StandardStream:
3851 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3852 offset=(MagickOffsetType) gztell(image->blob->file);
3862 offset=image->blob->offset;
3870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3874 + U n m a p B l o b %
3878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3880 % UnmapBlob() deallocates the binary large object previously allocated with
3881 % the MapBlob method.
3883 % The format of the UnmapBlob method is:
3885 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3887 % A description of each parameter follows:
3889 % o map: the address of the binary large object.
3891 % o length: the length of the binary large object.
3894 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3896 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3900 status=munmap(map,length);
3901 return(status == -1 ? MagickFalse : MagickTrue);
3905 return(MagickFalse);
3910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3914 + W r i t e B l o b %
3918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3920 % WriteBlob() writes data to a blob or image file. It returns the number of
3923 % The format of the WriteBlob method is:
3925 % ssize_t WriteBlob(Image *image,const size_t length,
3926 % const unsigned char *data)
3928 % A description of each parameter follows:
3930 % o image: the image.
3932 % o length: Specifies an integer representing the number of bytes to
3933 % write to the file.
3935 % o data: The address of the data to write to the blob or file.
3938 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3939 const unsigned char *data)
3944 register const unsigned char
3950 assert(image != (Image *) NULL);
3951 assert(image->signature == MagickSignature);
3952 assert(data != (const unsigned char *) NULL);
3953 assert(image->blob != (BlobInfo *) NULL);
3954 assert(image->blob->type != UndefinedStream);
3959 switch (image->blob->type)
3961 case UndefinedStream:
3964 case StandardStream:
3971 count=(ssize_t) fwrite((const char *) data,1,length,
3977 c=putc((int) *p++,image->blob->file);
3984 c=putc((int) *p++,image->blob->file);
3996 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4001 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4002 (unsigned int) length);
4007 c=gzputc(image->blob->file,(int) *p++);
4014 c=gzputc(image->blob->file,(int) *p++);
4027 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4028 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4035 count=(ssize_t) image->blob->stream(image,data,length);
4040 register unsigned char
4043 if ((image->blob->offset+(MagickOffsetType) length) >=
4044 (MagickOffsetType) image->blob->extent)
4046 if (image->blob->mapped != MagickFalse)
4048 image->blob->quantum<<=1;
4049 image->blob->extent+=length+image->blob->quantum;
4050 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4051 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4052 (void) SyncBlob(image);
4053 if (image->blob->data == (unsigned char *) NULL)
4055 (void) DetachBlob(image->blob);
4059 q=image->blob->data+image->blob->offset;
4060 (void) memcpy(q,p,length);
4061 image->blob->offset+=length;
4062 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4063 image->blob->length=(size_t) image->blob->offset;
4064 count=(ssize_t) length;
4071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4075 + W r i t e B l o b B y t e %
4079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4081 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4082 % written (either 0 or 1);
4084 % The format of the WriteBlobByte method is:
4086 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4088 % A description of each parameter follows.
4090 % o image: the image.
4092 % o value: Specifies the value to write.
4095 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4097 assert(image != (Image *) NULL);
4098 assert(image->signature == MagickSignature);
4099 return(WriteBlobStream(image,1,&value));
4103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4107 + W r i t e B l o b F l o a t %
4111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4113 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4114 % specified by the endian member of the image structure.
4116 % The format of the WriteBlobFloat method is:
4118 % ssize_t WriteBlobFloat(Image *image,const float value)
4120 % A description of each parameter follows.
4122 % o image: the image.
4124 % o value: Specifies the value to write.
4127 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4138 quantum.unsigned_value=0U;
4139 quantum.float_value=value;
4140 return(WriteBlobLong(image,quantum.unsigned_value));
4144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4148 + W r i t e B l o b L o n g %
4152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4154 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4155 % specified by the endian member of the image structure.
4157 % The format of the WriteBlobLong method is:
4159 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4161 % A description of each parameter follows.
4163 % o image: the image.
4165 % o value: Specifies the value to write.
4168 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4173 assert(image != (Image *) NULL);
4174 assert(image->signature == MagickSignature);
4175 if (image->endian == LSBEndian)
4177 buffer[0]=(unsigned char) value;
4178 buffer[1]=(unsigned char) (value >> 8);
4179 buffer[2]=(unsigned char) (value >> 16);
4180 buffer[3]=(unsigned char) (value >> 24);
4181 return(WriteBlobStream(image,4,buffer));
4183 buffer[0]=(unsigned char) (value >> 24);
4184 buffer[1]=(unsigned char) (value >> 16);
4185 buffer[2]=(unsigned char) (value >> 8);
4186 buffer[3]=(unsigned char) value;
4187 return(WriteBlobStream(image,4,buffer));
4191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4195 + W r i t e B l o b S h o r t %
4199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4201 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4202 % byte-order specified by the endian member of the image structure.
4204 % The format of the WriteBlobShort method is:
4206 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4208 % A description of each parameter follows.
4210 % o image: the image.
4212 % o value: Specifies the value to write.
4215 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4220 assert(image != (Image *) NULL);
4221 assert(image->signature == MagickSignature);
4222 if (image->endian == LSBEndian)
4224 buffer[0]=(unsigned char) value;
4225 buffer[1]=(unsigned char) (value >> 8);
4226 return(WriteBlobStream(image,2,buffer));
4228 buffer[0]=(unsigned char) (value >> 8);
4229 buffer[1]=(unsigned char) value;
4230 return(WriteBlobStream(image,2,buffer));
4234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4238 + W r i t e B l o b L S B L o n g %
4242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4244 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4245 % least-significant byte first order.
4247 % The format of the WriteBlobLSBLong method is:
4249 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4251 % A description of each parameter follows.
4253 % o image: the image.
4255 % o value: Specifies the value to write.
4258 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4263 assert(image != (Image *) NULL);
4264 assert(image->signature == MagickSignature);
4265 buffer[0]=(unsigned char) value;
4266 buffer[1]=(unsigned char) (value >> 8);
4267 buffer[2]=(unsigned char) (value >> 16);
4268 buffer[3]=(unsigned char) (value >> 24);
4269 return(WriteBlobStream(image,4,buffer));
4273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4277 + W r i t e B l o b L S B S h o r t %
4281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4283 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4284 % least-significant byte first order.
4286 % The format of the WriteBlobLSBShort method is:
4288 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4290 % A description of each parameter follows.
4292 % o image: the image.
4294 % o value: Specifies the value to write.
4297 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4302 assert(image != (Image *) NULL);
4303 assert(image->signature == MagickSignature);
4304 buffer[0]=(unsigned char) value;
4305 buffer[1]=(unsigned char) (value >> 8);
4306 return(WriteBlobStream(image,2,buffer));
4310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4314 + W r i t e B l o b M S B L o n g %
4318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4320 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4321 % most-significant byte first order.
4323 % The format of the WriteBlobMSBLong method is:
4325 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4327 % A description of each parameter follows.
4329 % o value: Specifies the value to write.
4331 % o image: the image.
4334 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4339 assert(image != (Image *) NULL);
4340 assert(image->signature == MagickSignature);
4341 buffer[0]=(unsigned char) (value >> 24);
4342 buffer[1]=(unsigned char) (value >> 16);
4343 buffer[2]=(unsigned char) (value >> 8);
4344 buffer[3]=(unsigned char) value;
4345 return(WriteBlobStream(image,4,buffer));
4349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4353 + W r i t e B l o b M S B L o n g L o n g %
4357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4359 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4360 % most-significant byte first order.
4362 % The format of the WriteBlobMSBLongLong method is:
4364 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4366 % A description of each parameter follows.
4368 % o value: Specifies the value to write.
4370 % o image: the image.
4373 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4374 const MagickSizeType value)
4379 assert(image != (Image *) NULL);
4380 assert(image->signature == MagickSignature);
4381 buffer[0]=(unsigned char) (value >> 56);
4382 buffer[1]=(unsigned char) (value >> 48);
4383 buffer[2]=(unsigned char) (value >> 40);
4384 buffer[3]=(unsigned char) (value >> 32);
4385 buffer[4]=(unsigned char) (value >> 24);
4386 buffer[5]=(unsigned char) (value >> 16);
4387 buffer[6]=(unsigned char) (value >> 8);
4388 buffer[7]=(unsigned char) value;
4389 return(WriteBlobStream(image,8,buffer));
4393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4397 + W r i t e B l o b M S B S h o r t %
4401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4403 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4404 % most-significant byte first order.
4406 % The format of the WriteBlobMSBShort method is:
4408 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4410 % A description of each parameter follows.
4412 % o value: Specifies the value to write.
4414 % o file: Specifies the file to write the data to.
4417 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4422 assert(image != (Image *) NULL);
4423 assert(image->signature == MagickSignature);
4424 buffer[0]=(unsigned char) (value >> 8);
4425 buffer[1]=(unsigned char) value;
4426 return(WriteBlobStream(image,2,buffer));
4430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4434 + W r i t e B l o b S t r i n g %
4438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4440 % WriteBlobString() write a string to a blob. It returns the number of
4441 % characters written.
4443 % The format of the WriteBlobString method is:
4445 % ssize_t WriteBlobString(Image *image,const char *string)
4447 % A description of each parameter follows.
4449 % o image: the image.
4451 % o string: Specifies the string to write.
4454 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4456 assert(image != (Image *) NULL);
4457 assert(image->signature == MagickSignature);
4458 assert(string != (const char *) NULL);
4459 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));