2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2011 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/locale_.h"
55 #include "magick/log.h"
56 #include "magick/magick.h"
57 #include "magick/memory_.h"
58 #include "magick/policy.h"
59 #include "magick/resource_.h"
60 #include "magick/semaphore.h"
61 #include "magick/string_.h"
62 #include "magick/string-private.h"
63 #include "magick/token.h"
64 #include "magick/utility.h"
65 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
66 # include <sys/mman.h>
68 #if defined(MAGICKCORE_ZLIB_DELEGATE)
71 #if defined(MAGICKCORE_BZLIB_DELEGATE)
78 #define MagickMaxBlobExtent 65541
79 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
80 # define MAP_ANONYMOUS MAP_ANON
82 #if !defined(MAP_FAILED)
83 #define MAP_FAILED ((void *) -1)
90 #define _O_BINARY O_BINARY
148 Forward declarations.
154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 + A t t a c h B l o b %
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 % AttachBlob() attaches a blob to the BlobInfo structure.
166 % The format of the AttachBlob method is:
168 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
170 % A description of each parameter follows:
172 % o blob_info: Specifies a pointer to a BlobInfo structure.
174 % o blob: the address of a character stream in one of the image formats
175 % understood by ImageMagick.
177 % o length: This size_t integer reflects the length in bytes of the blob.
180 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
183 assert(blob_info != (BlobInfo *) NULL);
184 if (blob_info->debug != MagickFalse)
185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
186 blob_info->length=length;
187 blob_info->extent=length;
188 blob_info->quantum=(size_t) MagickMaxBlobExtent;
190 blob_info->type=BlobStream;
191 blob_info->file=(FILE *) NULL;
192 blob_info->data=(unsigned char *) blob;
193 blob_info->mapped=MagickFalse;
197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 + B l o b T o F i l e %
205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
208 % occurs otherwise MagickTrue.
210 % The format of the BlobToFile method is:
212 % MagickBooleanType BlobToFile(char *filename,const void *blob,
213 % const size_t length,ExceptionInfo *exception)
215 % A description of each parameter follows:
217 % o filename: Write the blob to this file.
219 % o blob: the address of a blob.
221 % o length: This length in bytes of the blob.
223 % o exception: return any errors or warnings in this structure.
227 static inline MagickSizeType MagickMin(const MagickSizeType x,
228 const MagickSizeType y)
235 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
236 const size_t length,ExceptionInfo *exception)
247 assert(filename != (const char *) NULL);
248 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
249 assert(blob != (const void *) NULL);
250 if (*filename == '\0')
251 file=AcquireUniqueFileResource(filename);
253 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
256 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
259 for (i=0; i < length; i+=count)
261 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
262 i,(MagickSizeType) SSIZE_MAX));
271 if ((file == -1) || (i < length))
273 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 % B l o b T o I m a g e %
288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290 % BlobToImage() implements direct to memory image formats. It returns the
293 % The format of the BlobToImage method is:
295 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
296 % const size_t length,ExceptionInfo *exception)
298 % A description of each parameter follows:
300 % o image_info: the image info.
302 % o blob: the address of a character stream in one of the image formats
303 % understood by ImageMagick.
305 % o length: This size_t integer reflects the length in bytes of the blob.
307 % o exception: return any errors or warnings in this structure.
310 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
311 const size_t length,ExceptionInfo *exception)
326 assert(image_info != (ImageInfo *) NULL);
327 assert(image_info->signature == MagickSignature);
328 if (image_info->debug != MagickFalse)
329 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
330 image_info->filename);
331 assert(exception != (ExceptionInfo *) NULL);
332 if ((blob == (const void *) NULL) || (length == 0))
334 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
335 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
336 return((Image *) NULL);
338 blob_info=CloneImageInfo(image_info);
339 blob_info->blob=(void *) blob;
340 blob_info->length=length;
341 if (*blob_info->magick == '\0')
342 (void) SetImageInfo(blob_info,0,exception);
343 magick_info=GetMagickInfo(blob_info->magick,exception);
344 if (magick_info == (const MagickInfo *) NULL)
346 blob_info=DestroyImageInfo(blob_info);
347 (void) ThrowMagickException(exception,GetMagickModule(),
348 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
349 image_info->filename);
350 return((Image *) NULL);
352 if (GetMagickBlobSupport(magick_info) != MagickFalse)
355 Native blob support for this image format.
357 (void) CopyMagickString(blob_info->filename,image_info->filename,
359 (void) CopyMagickString(blob_info->magick,image_info->magick,
361 image=ReadImage(blob_info,exception);
362 if (image != (Image *) NULL)
363 (void) DetachBlob(image->blob);
364 blob_info=DestroyImageInfo(blob_info);
368 Write blob to a temporary file on disk.
370 blob_info->blob=(void *) NULL;
372 *blob_info->filename='\0';
373 status=BlobToFile(blob_info->filename,blob,length,exception);
374 if (status == MagickFalse)
376 (void) RelinquishUniqueFileResource(blob_info->filename);
377 blob_info=DestroyImageInfo(blob_info);
378 return((Image *) NULL);
380 clone_info=CloneImageInfo(blob_info);
381 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
382 blob_info->magick,blob_info->filename);
383 image=ReadImage(clone_info,exception);
384 clone_info=DestroyImageInfo(clone_info);
385 (void) RelinquishUniqueFileResource(blob_info->filename);
386 blob_info=DestroyImageInfo(blob_info);
391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 + C l o n e B l o b I n f o %
399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
402 % blob info is NULL, a new one.
404 % The format of the CloneBlobInfo method is:
406 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
408 % A description of each parameter follows:
410 % o blob_info: the blob info.
413 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
418 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
419 if (clone_info == (BlobInfo *) NULL)
420 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
421 GetBlobInfo(clone_info);
422 if (blob_info == (BlobInfo *) NULL)
424 clone_info->length=blob_info->length;
425 clone_info->extent=blob_info->extent;
426 clone_info->synchronize=blob_info->synchronize;
427 clone_info->quantum=blob_info->quantum;
428 clone_info->mapped=blob_info->mapped;
429 clone_info->eof=blob_info->eof;
430 clone_info->offset=blob_info->offset;
431 clone_info->size=blob_info->size;
432 clone_info->exempt=blob_info->exempt;
433 clone_info->status=blob_info->status;
434 clone_info->temporary=blob_info->temporary;
435 clone_info->type=blob_info->type;
436 clone_info->file=blob_info->file;
437 clone_info->properties=blob_info->properties;
438 clone_info->stream=blob_info->stream;
439 clone_info->data=blob_info->data;
440 clone_info->debug=IsEventLogging();
441 clone_info->reference_count=1;
446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450 + C l o s e B l o b %
454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456 % CloseBlob() closes a stream associated with the image.
458 % The format of the CloseBlob method is:
460 % MagickBooleanType CloseBlob(Image *image)
462 % A description of each parameter follows:
464 % o image: the image.
467 MagickExport MagickBooleanType CloseBlob(Image *image)
475 assert(image != (Image *) NULL);
476 assert(image->signature == MagickSignature);
477 if (image->debug != MagickFalse)
478 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
479 assert(image->blob != (BlobInfo *) NULL);
480 if (image->blob->type == UndefinedStream)
482 if (image->blob->synchronize != MagickFalse)
484 image->blob->size=GetBlobSize(image);
485 image->extent=image->blob->size;
486 image->blob->eof=MagickFalse;
487 if (image->blob->exempt != MagickFalse)
489 image->blob->type=UndefinedStream;
493 switch (image->blob->type)
495 case UndefinedStream:
501 status=ferror(image->blob->file);
506 #if defined(MAGICKCORE_ZLIB_DELEGATE)
507 (void) gzerror(image->blob->file,&status);
513 #if defined(MAGICKCORE_BZLIB_DELEGATE)
514 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
522 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
523 switch (image->blob->type)
525 case UndefinedStream:
530 if (image->blob->synchronize != MagickFalse)
532 status=fflush(image->blob->file);
533 status=fsync(fileno(image->blob->file));
535 status=fclose(image->blob->file);
540 #if defined(MAGICKCORE_HAVE_PCLOSE)
541 status=pclose(image->blob->file);
547 #if defined(MAGICKCORE_ZLIB_DELEGATE)
548 status=gzclose(image->blob->file);
554 #if defined(MAGICKCORE_BZLIB_DELEGATE)
555 BZ2_bzclose((BZFILE *) image->blob->file);
563 if (image->blob->file != (FILE *) NULL)
565 if (image->blob->synchronize != MagickFalse)
566 (void) fsync(fileno(image->blob->file));
567 status=fclose(image->blob->file);
572 (void) DetachBlob(image->blob);
573 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
574 return(image->blob->status);
578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 + D e s t r o y B l o b %
586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588 % DestroyBlob() deallocates memory associated with a blob.
590 % The format of the DestroyBlob method is:
592 % void DestroyBlob(Image *image)
594 % A description of each parameter follows:
596 % o image: the image.
599 MagickExport void DestroyBlob(Image *image)
604 assert(image != (Image *) NULL);
605 assert(image->signature == MagickSignature);
606 if (image->debug != MagickFalse)
607 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
608 assert(image->blob != (BlobInfo *) NULL);
609 assert(image->blob->signature == MagickSignature);
611 LockSemaphoreInfo(image->blob->semaphore);
612 image->blob->reference_count--;
613 assert(image->blob->reference_count >= 0);
614 if (image->blob->reference_count == 0)
616 UnlockSemaphoreInfo(image->blob->semaphore);
617 if (destroy == MagickFalse)
619 (void) CloseBlob(image);
620 if (image->blob->mapped != MagickFalse)
621 (void) UnmapBlob(image->blob->data,image->blob->length);
622 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
623 DestroySemaphoreInfo(&image->blob->semaphore);
624 image->blob->signature=(~MagickSignature);
625 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633 + D e t a c h B l o b %
637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 % DetachBlob() detaches a blob from the BlobInfo structure.
641 % The format of the DetachBlob method is:
643 % unsigned char *DetachBlob(BlobInfo *blob_info)
645 % A description of each parameter follows:
647 % o blob_info: Specifies a pointer to a BlobInfo structure.
650 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
655 assert(blob_info != (BlobInfo *) NULL);
656 if (blob_info->debug != MagickFalse)
657 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
658 if (blob_info->mapped != MagickFalse)
659 (void) UnmapBlob(blob_info->data,blob_info->length);
660 blob_info->mapped=MagickFalse;
663 blob_info->eof=MagickFalse;
664 blob_info->exempt=MagickFalse;
665 blob_info->type=UndefinedStream;
666 blob_info->file=(FILE *) NULL;
667 data=blob_info->data;
668 blob_info->data=(unsigned char *) NULL;
669 blob_info->stream=(StreamHandler) NULL;
674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
678 + D i s c a r d B l o b B y t e s %
682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
684 % DiscardBlobBytes() discards bytes in a blob.
686 % The format of the DiscardBlobBytes method is:
688 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
690 % A description of each parameter follows.
692 % o image: the image.
694 % o length: the number of bytes to skip.
698 static inline const unsigned char *ReadBlobStream(Image *image,
699 const size_t length,unsigned char *data,ssize_t *count)
701 assert(count != (ssize_t *) NULL);
702 assert(image->blob != (BlobInfo *) NULL);
703 if (image->blob->type != BlobStream)
705 *count=ReadBlob(image,length,data);
708 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
711 image->blob->eof=MagickTrue;
714 data=image->blob->data+image->blob->offset;
715 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
716 image->blob->offset));
717 image->blob->offset+=(*count);
718 if (*count != (ssize_t) length)
719 image->blob->eof=MagickTrue;
723 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
724 const MagickSizeType length)
726 register MagickOffsetType
738 assert(image != (Image *) NULL);
739 assert(image->signature == MagickSignature);
741 for (i=0; i < (MagickOffsetType) length; i+=count)
743 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
744 (void) ReadBlobStream(image,quantum,buffer,&count);
752 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
760 + D u p l i c a t e s B l o b %
764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 % DuplicateBlob() duplicates a blob descriptor.
768 % The format of the DuplicateBlob method is:
770 % void DuplicateBlob(Image *image,const Image *duplicate)
772 % A description of each parameter follows:
774 % o image: the image.
776 % o duplicate: the duplicate image.
779 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
781 assert(image != (Image *) NULL);
782 assert(image->signature == MagickSignature);
783 if (image->debug != MagickFalse)
784 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
785 assert(duplicate != (Image *) NULL);
786 assert(duplicate->signature == MagickSignature);
788 image->blob=ReferenceBlob(duplicate->blob);
792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 % EOFBlob() returns a non-zero value when EOF has been detected reading from
805 % The format of the EOFBlob method is:
807 % int EOFBlob(const Image *image)
809 % A description of each parameter follows:
811 % o image: the image.
814 MagickExport int EOFBlob(const Image *image)
816 assert(image != (Image *) NULL);
817 assert(image->signature == MagickSignature);
818 if (image->debug != MagickFalse)
819 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
820 assert(image->blob != (BlobInfo *) NULL);
821 assert(image->blob->type != UndefinedStream);
822 switch (image->blob->type)
824 case UndefinedStream:
830 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
835 image->blob->eof=MagickFalse;
840 #if defined(MAGICKCORE_BZLIB_DELEGATE)
845 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
846 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
852 image->blob->eof=MagickFalse;
858 return((int) image->blob->eof);
862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866 + F i l e T o B l o b %
870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872 % FileToBlob() returns the contents of a file as a buffer terminated with
873 % the '\0' character. The length of the buffer (not including the extra
874 % terminating '\0' character) is returned via the 'length' parameter. Free
875 % the buffer with RelinquishMagickMemory().
877 % The format of the FileToBlob method is:
879 % unsigned char *FileToBlob(const char *filename,const size_t extent,
880 % size_t *length,ExceptionInfo *exception)
882 % A description of each parameter follows:
884 % o blob: FileToBlob() returns the contents of a file as a blob. If
885 % an error occurs NULL is returned.
887 % o filename: the filename.
889 % o extent: The maximum length of the blob.
891 % o length: On return, this reflects the actual length of the blob.
893 % o exception: return any errors or warnings in this structure.
896 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
897 size_t *length,ExceptionInfo *exception)
917 assert(filename != (const char *) NULL);
918 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
919 assert(exception != (ExceptionInfo *) NULL);
922 if (LocaleCompare(filename,"-") != 0)
923 file=open(filename,O_RDONLY | O_BINARY);
926 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
927 return((unsigned char *) NULL);
929 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
931 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
940 Stream is not seekable.
942 quantum=(size_t) MagickMaxBufferExtent;
943 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
944 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
945 MagickMaxBufferExtent);
946 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
947 for (i=0; blob != (unsigned char *) NULL; i+=count)
949 count=(ssize_t) read(file,blob+i,quantum);
956 if (~(1UL*i) < (quantum+1))
958 blob=(unsigned char *) RelinquishMagickMemory(blob);
961 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
963 if ((size_t) (i+count) >= extent)
966 if (LocaleCompare(filename,"-") != 0)
968 if (blob == (unsigned char *) NULL)
970 (void) ThrowMagickException(exception,GetMagickModule(),
971 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
972 return((unsigned char *) NULL);
976 blob=(unsigned char *) RelinquishMagickMemory(blob);
977 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
978 return((unsigned char *) NULL);
980 *length=(size_t) MagickMin(i+count,extent);
984 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
985 blob=(unsigned char *) NULL;
986 if (~(*length) >= MaxTextExtent)
987 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
989 if (blob == (unsigned char *) NULL)
992 (void) ThrowMagickException(exception,GetMagickModule(),
993 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
994 return((unsigned char *) NULL);
996 map=MapBlob(file,ReadMode,0,*length);
997 if (map != (unsigned char *) NULL)
999 (void) memcpy(blob,map,*length);
1000 (void) UnmapBlob(map,*length);
1004 (void) lseek(file,0,SEEK_SET);
1005 for (i=0; i < *length; i+=count)
1007 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1008 (MagickSizeType) SSIZE_MAX));
1019 blob=(unsigned char *) RelinquishMagickMemory(blob);
1020 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1021 return((unsigned char *) NULL);
1025 if (LocaleCompare(filename,"-") != 0)
1029 blob=(unsigned char *) RelinquishMagickMemory(blob);
1030 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1040 % F i l e T o I m a g e %
1044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 % FileToImage() write the contents of a file to an image.
1048 % The format of the FileToImage method is:
1050 % MagickBooleanType FileToImage(Image *,const char *filename)
1052 % A description of each parameter follows:
1054 % o image: the image.
1056 % o filename: the filename.
1060 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1061 const unsigned char *data)
1066 register unsigned char
1069 assert(image->blob != (BlobInfo *) NULL);
1070 if (image->blob->type != BlobStream)
1071 return(WriteBlob(image,length,data));
1072 assert(image->blob->type != UndefinedStream);
1073 assert(data != (void *) NULL);
1074 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1075 if (extent >= image->blob->extent)
1077 image->blob->quantum<<=1;
1078 extent=image->blob->extent+image->blob->quantum+length;
1079 if (SetBlobExtent(image,extent) == MagickFalse)
1082 q=image->blob->data+image->blob->offset;
1083 (void) memcpy(q,data,length);
1084 image->blob->offset+=length;
1085 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1086 image->blob->length=(size_t) image->blob->offset;
1087 return((ssize_t) length);
1090 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1108 assert(image != (const Image *) NULL);
1109 assert(image->signature == MagickSignature);
1110 assert(filename != (const char *) NULL);
1111 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1112 file=open(filename,O_RDONLY | O_BINARY);
1115 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1117 return(MagickFalse);
1119 quantum=(size_t) MagickMaxBufferExtent;
1120 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1121 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1122 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1123 if (blob == (unsigned char *) NULL)
1125 ThrowFileException(&image->exception,ResourceLimitError,
1126 "MemoryAllocationFailed",filename);
1127 return(MagickFalse);
1131 count=(ssize_t) read(file,blob,quantum);
1138 length=(size_t) count;
1139 count=WriteBlobStream(image,length,blob);
1140 if (count != (ssize_t) length)
1142 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1149 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1151 blob=(unsigned char *) RelinquishMagickMemory(blob);
1156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1160 + G e t B l o b E r r o r %
1164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1166 % GetBlobError() returns MagickTrue if the blob associated with the specified
1167 % image encountered an error.
1169 % The format of the GetBlobError method is:
1171 % MagickBooleanType GetBlobError(const Image *image)
1173 % A description of each parameter follows:
1175 % o image: the image.
1178 MagickExport MagickBooleanType GetBlobError(const Image *image)
1180 assert(image != (const Image *) NULL);
1181 assert(image->signature == MagickSignature);
1182 if (image->debug != MagickFalse)
1183 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1184 return(image->blob->status);
1188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1192 + G e t B l o b F i l e H a n d l e %
1196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1198 % GetBlobFileHandle() returns the file handle associated with the image blob.
1200 % The format of the GetBlobFile method is:
1202 % FILE *GetBlobFileHandle(const Image *image)
1204 % A description of each parameter follows:
1206 % o image: the image.
1209 MagickExport FILE *GetBlobFileHandle(const Image *image)
1211 assert(image != (const Image *) NULL);
1212 assert(image->signature == MagickSignature);
1213 return(image->blob->file);
1217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1221 + G e t B l o b I n f o %
1225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1227 % GetBlobInfo() initializes the BlobInfo structure.
1229 % The format of the GetBlobInfo method is:
1231 % void GetBlobInfo(BlobInfo *blob_info)
1233 % A description of each parameter follows:
1235 % o blob_info: Specifies a pointer to a BlobInfo structure.
1238 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1240 assert(blob_info != (BlobInfo *) NULL);
1241 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1242 blob_info->type=UndefinedStream;
1243 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1244 blob_info->properties.st_mtime=time((time_t *) NULL);
1245 blob_info->properties.st_ctime=time((time_t *) NULL);
1246 blob_info->debug=IsEventLogging();
1247 blob_info->reference_count=1;
1248 blob_info->semaphore=AllocateSemaphoreInfo();
1249 blob_info->signature=MagickSignature;
1253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1257 % G e t B l o b P r o p e r t i e s %
1261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1263 % GetBlobProperties() returns information about an image blob.
1265 % The format of the GetBlobProperties method is:
1267 % const struct stat *GetBlobProperties(const Image *image)
1269 % A description of each parameter follows:
1271 % o image: the image.
1274 MagickExport const struct stat *GetBlobProperties(const Image *image)
1276 assert(image != (Image *) NULL);
1277 assert(image->signature == MagickSignature);
1278 if (image->debug != MagickFalse)
1279 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1280 return(&image->blob->properties);
1284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1288 + G e t B l o b S i z e %
1292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1294 % GetBlobSize() returns the current length of the image file or blob; zero is
1295 % returned if the size cannot be determined.
1297 % The format of the GetBlobSize method is:
1299 % MagickSizeType GetBlobSize(const Image *image)
1301 % A description of each parameter follows:
1303 % o image: the image.
1306 MagickExport MagickSizeType GetBlobSize(const Image *image)
1311 assert(image != (Image *) NULL);
1312 assert(image->signature == MagickSignature);
1313 if (image->debug != MagickFalse)
1314 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1315 assert(image->blob != (BlobInfo *) NULL);
1317 switch (image->blob->type)
1319 case UndefinedStream:
1321 extent=image->blob->size;
1326 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1327 extent=(MagickSizeType) image->blob->properties.st_size;
1330 case StandardStream:
1333 extent=image->blob->size;
1342 status=GetPathAttributes(image->filename,&image->blob->properties);
1343 if (status != MagickFalse)
1344 extent=(MagickSizeType) image->blob->properties.st_size;
1351 extent=(MagickSizeType) image->blob->length;
1359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1363 + G e t B l o b S t r e a m D a t a %
1367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1369 % GetBlobStreamData() returns the stream data for the image.
1371 % The format of the GetBlobStreamData method is:
1373 % unsigned char *GetBlobStreamData(const Image *image)
1375 % A description of each parameter follows:
1377 % o image: the image.
1380 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1382 assert(image != (const Image *) NULL);
1383 assert(image->signature == MagickSignature);
1384 return(image->blob->data);
1388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1392 + G e t B l o b S t r e a m H a n d l e r %
1396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1398 % GetBlobStreamHandler() returns the stream handler for the image.
1400 % The format of the GetBlobStreamHandler method is:
1402 % StreamHandler GetBlobStreamHandler(const Image *image)
1404 % A description of each parameter follows:
1406 % o image: the image.
1409 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1411 assert(image != (const Image *) NULL);
1412 assert(image->signature == MagickSignature);
1413 if (image->debug != MagickFalse)
1414 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1415 return(image->blob->stream);
1419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1423 % I m a g e T o B l o b %
1427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1429 % ImageToBlob() implements direct to memory image formats. It returns the
1430 % image as a formatted blob and its length. The magick member of the Image
1431 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1432 % etc.). This method is the equivalent of WriteImage(), but writes the
1433 % formatted "file" to a memory buffer rather than to an actual file.
1435 % The format of the ImageToBlob method is:
1437 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1438 % size_t *length,ExceptionInfo *exception)
1440 % A description of each parameter follows:
1442 % o image_info: the image info.
1444 % o image: the image.
1446 % o length: This pointer to a size_t integer sets the initial length of the
1447 % blob. On return, it reflects the actual length of the blob.
1449 % o exception: return any errors or warnings in this structure.
1452 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1453 Image *image,size_t *length,ExceptionInfo *exception)
1467 assert(image_info != (const ImageInfo *) NULL);
1468 assert(image_info->signature == MagickSignature);
1469 if (image_info->debug != MagickFalse)
1470 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1471 image_info->filename);
1472 assert(image != (Image *) NULL);
1473 assert(image->signature == MagickSignature);
1474 assert(exception != (ExceptionInfo *) NULL);
1476 blob=(unsigned char *) NULL;
1477 blob_info=CloneImageInfo(image_info);
1478 blob_info->adjoin=MagickFalse;
1479 (void) SetImageInfo(blob_info,1,exception);
1480 if (*blob_info->magick != '\0')
1481 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1482 magick_info=GetMagickInfo(image->magick,exception);
1483 if (magick_info == (const MagickInfo *) NULL)
1485 (void) ThrowMagickException(exception,GetMagickModule(),
1486 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1490 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1491 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1494 Native blob support for this image format.
1496 blob_info->length=0;
1497 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1498 sizeof(unsigned char));
1499 if (blob_info->blob == (void *) NULL)
1500 (void) ThrowMagickException(exception,GetMagickModule(),
1501 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1504 (void) CloseBlob(image);
1505 image->blob->exempt=MagickTrue;
1506 *image->filename='\0';
1507 status=WriteImage(blob_info,image);
1508 if ((status == MagickFalse) || (image->blob->length == 0))
1509 InheritException(exception,&image->exception);
1512 *length=image->blob->length;
1513 blob=DetachBlob(image->blob);
1514 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1522 unique[MaxTextExtent];
1528 Write file to disk in blob image format.
1530 file=AcquireUniqueFileResource(unique);
1533 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1534 image_info->filename);
1538 blob_info->file=fdopen(file,"wb");
1539 if (blob_info->file != (FILE *) NULL)
1541 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1542 image->magick,unique);
1543 status=WriteImage(blob_info,image);
1544 (void) fclose(blob_info->file);
1545 if (status == MagickFalse)
1546 InheritException(exception,&image->exception);
1548 blob=FileToBlob(image->filename,~0UL,length,exception);
1550 (void) RelinquishUniqueFileResource(unique);
1553 blob_info=DestroyImageInfo(blob_info);
1558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1562 % I m a g e T o F i l e %
1566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1568 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1569 % occurs otherwise MagickTrue.
1571 % The format of the ImageToFile method is:
1573 % MagickBooleanType ImageToFile(Image *image,char *filename,
1574 % ExceptionInfo *exception)
1576 % A description of each parameter follows:
1578 % o image: the image.
1580 % o filename: Write the image to this file.
1582 % o exception: return any errors or warnings in this structure.
1585 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1586 ExceptionInfo *exception)
1591 register const unsigned char
1610 assert(image != (Image *) NULL);
1611 assert(image->signature == MagickSignature);
1612 assert(image->blob != (BlobInfo *) NULL);
1613 assert(image->blob->type != UndefinedStream);
1614 if (image->debug != MagickFalse)
1615 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1616 assert(filename != (const char *) NULL);
1617 if (*filename == '\0')
1618 file=AcquireUniqueFileResource(filename);
1620 if (LocaleCompare(filename,"-") == 0)
1621 file=fileno(stdout);
1623 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1626 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1627 return(MagickFalse);
1629 quantum=(size_t) MagickMaxBufferExtent;
1630 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1631 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
1632 MagickMaxBufferExtent);
1633 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1634 if (buffer == (unsigned char *) NULL)
1637 (void) ThrowMagickException(exception,GetMagickModule(),
1638 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1639 return(MagickFalse);
1642 p=ReadBlobStream(image,quantum,buffer,&count);
1643 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1645 length=(size_t) count;
1646 for (i=0; i < length; i+=count)
1648 count=write(file,p+i,(size_t) (length-i));
1659 if (LocaleCompare(filename,"-") != 0)
1661 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1662 if ((file == -1) || (i < length))
1664 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1665 return(MagickFalse);
1671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1675 % I m a g e s T o B l o b %
1679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1681 % ImagesToBlob() implements direct to memory image formats. It returns the
1682 % image sequence as a blob and its length. The magick member of the ImageInfo
1683 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1685 % Note, some image formats do not permit multiple images to the same image
1686 % stream (e.g. JPEG). in this instance, just the first image of the
1687 % sequence is returned as a blob.
1689 % The format of the ImagesToBlob method is:
1691 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1692 % size_t *length,ExceptionInfo *exception)
1694 % A description of each parameter follows:
1696 % o image_info: the image info.
1698 % o images: the image list.
1700 % o length: This pointer to a size_t integer sets the initial length of the
1701 % blob. On return, it reflects the actual length of the blob.
1703 % o exception: return any errors or warnings in this structure.
1706 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1707 Image *images,size_t *length,ExceptionInfo *exception)
1721 assert(image_info != (const ImageInfo *) NULL);
1722 assert(image_info->signature == MagickSignature);
1723 if (image_info->debug != MagickFalse)
1724 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1725 image_info->filename);
1726 assert(images != (Image *) NULL);
1727 assert(images->signature == MagickSignature);
1728 assert(exception != (ExceptionInfo *) NULL);
1730 blob=(unsigned char *) NULL;
1731 blob_info=CloneImageInfo(image_info);
1732 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1734 if (*blob_info->magick != '\0')
1735 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1736 if (blob_info->adjoin == MagickFalse)
1738 blob_info=DestroyImageInfo(blob_info);
1739 return(ImageToBlob(image_info,images,length,exception));
1741 magick_info=GetMagickInfo(images->magick,exception);
1742 if (magick_info == (const MagickInfo *) NULL)
1744 (void) ThrowMagickException(exception,GetMagickModule(),
1745 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1749 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1750 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1753 Native blob support for this images format.
1755 blob_info->length=0;
1756 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1757 sizeof(unsigned char));
1758 if (blob_info->blob == (void *) NULL)
1759 (void) ThrowMagickException(exception,GetMagickModule(),
1760 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1763 images->blob->exempt=MagickTrue;
1764 *images->filename='\0';
1765 status=WriteImages(blob_info,images,images->filename,exception);
1766 if ((status == MagickFalse) || (images->blob->length == 0))
1767 InheritException(exception,&images->exception);
1770 *length=images->blob->length;
1771 blob=DetachBlob(images->blob);
1772 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1780 filename[MaxTextExtent],
1781 unique[MaxTextExtent];
1787 Write file to disk in blob images format.
1789 file=AcquireUniqueFileResource(unique);
1792 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1793 image_info->filename);
1797 blob_info->file=fdopen(file,"wb");
1798 if (blob_info->file != (FILE *) NULL)
1800 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1801 images->magick,unique);
1802 status=WriteImages(blob_info,images,filename,exception);
1803 (void) fclose(blob_info->file);
1804 if (status == MagickFalse)
1805 InheritException(exception,&images->exception);
1807 blob=FileToBlob(images->filename,~0UL,length,exception);
1809 (void) RelinquishUniqueFileResource(unique);
1812 blob_info=DestroyImageInfo(blob_info);
1816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1820 % I n j e c t I m a g e B l o b %
1824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1826 % InjectImageBlob() injects the image with a copy of itself in the specified
1827 % format (e.g. inject JPEG into a PDF image).
1829 % The format of the InjectImageBlob method is:
1831 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1832 % Image *image,Image *inject_image,const char *format,
1833 % ExceptionInfo *exception)
1835 % A description of each parameter follows:
1837 % o image_info: the image info..
1839 % o image: the image.
1841 % o inject_image: inject into the image stream.
1843 % o format: the image format.
1845 % o exception: return any errors or warnings in this structure.
1848 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1849 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1852 filename[MaxTextExtent];
1885 Write inject image to a temporary file.
1887 assert(image_info != (ImageInfo *) NULL);
1888 assert(image_info->signature == MagickSignature);
1889 assert(image != (Image *) NULL);
1890 assert(image->signature == MagickSignature);
1891 if (image->debug != MagickFalse)
1892 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1893 assert(inject_image != (Image *) NULL);
1894 assert(inject_image->signature == MagickSignature);
1895 assert(exception != (ExceptionInfo *) NULL);
1896 unique_file=(FILE *) NULL;
1897 file=AcquireUniqueFileResource(filename);
1899 unique_file=fdopen(file,"wb");
1900 if ((file == -1) || (unique_file == (FILE *) NULL))
1902 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1903 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1905 return(MagickFalse);
1907 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1908 if (byte_image == (Image *) NULL)
1910 (void) fclose(unique_file);
1911 (void) RelinquishUniqueFileResource(filename);
1912 return(MagickFalse);
1914 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1916 DestroyBlob(byte_image);
1917 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1918 write_info=CloneImageInfo(image_info);
1919 SetImageInfoFile(write_info,unique_file);
1920 status=WriteImage(write_info,byte_image);
1921 write_info=DestroyImageInfo(write_info);
1922 byte_image=DestroyImage(byte_image);
1923 (void) fclose(unique_file);
1924 if (status == MagickFalse)
1926 (void) RelinquishUniqueFileResource(filename);
1927 return(MagickFalse);
1930 Inject into image stream.
1932 file=open(filename,O_RDONLY | O_BINARY);
1935 (void) RelinquishUniqueFileResource(filename);
1936 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1937 image_info->filename);
1938 return(MagickFalse);
1940 quantum=(size_t) MagickMaxBufferExtent;
1941 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1942 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1943 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1944 if (buffer == (unsigned char *) NULL)
1946 (void) RelinquishUniqueFileResource(filename);
1947 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1950 for (i=0; ; i+=count)
1952 count=(ssize_t) read(file,buffer,quantum);
1959 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1964 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1965 (void) RelinquishUniqueFileResource(filename);
1966 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1975 + I s B l o b E x e m p t %
1979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1981 % IsBlobExempt() returns true if the blob is exempt.
1983 % The format of the IsBlobExempt method is:
1985 % MagickBooleanType IsBlobExempt(const Image *image)
1987 % A description of each parameter follows:
1989 % o image: the image.
1992 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1994 assert(image != (const Image *) NULL);
1995 assert(image->signature == MagickSignature);
1996 if (image->debug != MagickFalse)
1997 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1998 return(image->blob->exempt);
2002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2006 + I s B l o b S e e k a b l e %
2010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2012 % IsBlobSeekable() returns true if the blob is seekable.
2014 % The format of the IsBlobSeekable method is:
2016 % MagickBooleanType IsBlobSeekable(const Image *image)
2018 % A description of each parameter follows:
2020 % o image: the image.
2023 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2028 assert(image != (const Image *) NULL);
2029 assert(image->signature == MagickSignature);
2030 if (image->debug != MagickFalse)
2031 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2032 seekable=(image->blob->type == FileStream) ||
2033 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2042 + I s B l o b T e m p o r a r y %
2046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2048 % IsBlobTemporary() returns true if the blob is temporary.
2050 % The format of the IsBlobTemporary method is:
2052 % MagickBooleanType IsBlobTemporary(const Image *image)
2054 % A description of each parameter follows:
2056 % o image: the image.
2059 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2061 assert(image != (const Image *) NULL);
2062 assert(image->signature == MagickSignature);
2063 if (image->debug != MagickFalse)
2064 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2065 return(image->blob->temporary);
2069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2079 % MapBlob() creates a mapping from a file to a binary large object.
2081 % The format of the MapBlob method is:
2083 % unsigned char *MapBlob(int file,const MapMode mode,
2084 % const MagickOffsetType offset,const size_t length)
2086 % A description of each parameter follows:
2088 % o file: map this file descriptor.
2090 % o mode: ReadMode, WriteMode, or IOMode.
2092 % o offset: starting at this offset within the file.
2094 % o length: the length of the mapping is returned in this pointer.
2097 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2098 const MagickOffsetType offset,const size_t length)
2100 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2113 #if defined(MAP_ANONYMOUS)
2114 flags|=MAP_ANONYMOUS;
2116 return((unsigned char *) NULL);
2123 protection=PROT_READ;
2125 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2131 protection=PROT_WRITE;
2133 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2135 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2136 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2137 POSIX_MADV_WILLNEED);
2143 protection=PROT_READ | PROT_WRITE;
2145 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2150 if (map == (unsigned char *) MAP_FAILED)
2151 return((unsigned char *) NULL);
2158 return((unsigned char *) NULL);
2163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2167 + M S B O r d e r L o n g %
2171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2173 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2174 % most-significant byte first.
2176 % The format of the MSBOrderLong method is:
2178 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2180 % A description of each parameter follows.
2182 % o buffer: Specifies a pointer to a buffer of integers.
2184 % o length: Specifies the length of the buffer.
2187 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2192 register unsigned char
2196 assert(buffer != (unsigned char *) NULL);
2203 *buffer++=(unsigned char) c;
2207 *buffer++=(unsigned char) c;
2213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2217 + M S B O r d e r S h o r t %
2221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2223 % MSBOrderShort() converts a least-significant byte first buffer of integers
2224 % to most-significant byte first.
2226 % The format of the MSBOrderShort method is:
2228 % void MSBOrderShort(unsigned char *p,const size_t length)
2230 % A description of each parameter follows.
2232 % o p: Specifies a pointer to a buffer of integers.
2234 % o length: Specifies the length of the buffer.
2237 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2242 register unsigned char
2245 assert(p != (unsigned char *) NULL);
2252 *p++=(unsigned char) c;
2257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2267 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2268 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2269 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2270 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2271 % from a system command.
2273 % The format of the OpenBlob method is:
2275 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2276 % const BlobMode mode,ExceptionInfo *exception)
2278 % A description of each parameter follows:
2280 % o image_info: the image info.
2282 % o image: the image.
2284 % o mode: the mode for opening the file.
2287 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2288 Image *image,const BlobMode mode,ExceptionInfo *exception)
2291 extension[MaxTextExtent],
2292 filename[MaxTextExtent];
2303 assert(image_info != (ImageInfo *) NULL);
2304 assert(image_info->signature == MagickSignature);
2305 if (image_info->debug != MagickFalse)
2306 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2307 image_info->filename);
2308 assert(image != (Image *) NULL);
2309 assert(image->signature == MagickSignature);
2310 if (image_info->blob != (void *) NULL)
2312 if (image_info->stream != (StreamHandler) NULL)
2313 image->blob->stream=(StreamHandler) image_info->stream;
2314 AttachBlob(image->blob,image_info->blob,image_info->length);
2317 (void) DetachBlob(image->blob);
2320 default: type="r"; break;
2321 case ReadBlobMode: type="r"; break;
2322 case ReadBinaryBlobMode: type="rb"; break;
2323 case WriteBlobMode: type="w"; break;
2324 case WriteBinaryBlobMode: type="w+b"; break;
2325 case AppendBlobMode: type="a"; break;
2326 case AppendBinaryBlobMode: type="a+b"; break;
2329 image->blob->synchronize=image_info->synchronize;
2330 if (image_info->stream != (StreamHandler) NULL)
2332 image->blob->stream=(StreamHandler) image_info->stream;
2335 image->blob->type=FifoStream;
2343 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2344 rights=ReadPolicyRights;
2346 rights=WritePolicyRights;
2347 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2350 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2351 "NotAuthorized","`%s'",filename);
2352 return(MagickFalse);
2354 if ((LocaleCompare(filename,"-") == 0) ||
2355 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2357 image->blob->file=(*type == 'r') ? stdin : stdout;
2358 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2359 if (strchr(type,'b') != (char *) NULL)
2360 setmode(_fileno(image->blob->file),_O_BINARY);
2362 image->blob->type=StandardStream;
2363 image->blob->exempt=MagickTrue;
2366 if (LocaleNCompare(filename,"fd:",3) == 0)
2369 mode[MaxTextExtent];
2373 image->blob->file=fdopen(StringToLong(filename+3),mode);
2374 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2375 if (strchr(type,'b') != (char *) NULL)
2376 setmode(_fileno(image->blob->file),_O_BINARY);
2378 image->blob->type=StandardStream;
2379 image->blob->exempt=MagickTrue;
2382 #if defined(MAGICKCORE_HAVE_POPEN)
2383 if (*filename == '|')
2386 mode[MaxTextExtent];
2389 Pipe image to or from a system command.
2391 #if defined(SIGPIPE)
2393 (void) signal(SIGPIPE,SIG_IGN);
2397 image->blob->file=(FILE *) popen(filename+1,mode);
2398 if (image->blob->file == (FILE *) NULL)
2400 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2401 return(MagickFalse);
2403 image->blob->type=PipeStream;
2404 image->blob->exempt=MagickTrue;
2408 status=GetPathAttributes(filename,&image->blob->properties);
2409 #if defined(S_ISFIFO)
2410 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2412 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2413 if (image->blob->file == (FILE *) NULL)
2415 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2416 return(MagickFalse);
2418 image->blob->type=FileStream;
2419 image->blob->exempt=MagickTrue;
2423 GetPathComponent(image->filename,ExtensionPath,extension);
2426 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2427 if ((image_info->adjoin == MagickFalse) ||
2428 (strchr(filename,'%') != (char *) NULL))
2431 Form filename for multi-part images.
2433 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2434 image->scene,filename);
2435 if ((LocaleCompare(filename,image->filename) == 0) &&
2436 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2437 (GetNextImageInList(image) != (Image *) NULL)))
2440 path[MaxTextExtent];
2442 GetPathComponent(image->filename,RootPath,path);
2443 if (*extension == '\0')
2444 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2445 path,(double) image->scene);
2447 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2448 path,(double) image->scene,extension);
2450 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2451 #if defined(macintosh)
2452 SetApplicationType(filename,image_info->magick,'8BIM');
2456 if (image_info->file != (FILE *) NULL)
2458 image->blob->file=image_info->file;
2459 image->blob->type=FileStream;
2460 image->blob->exempt=MagickTrue;
2465 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2466 if (image->blob->file != (FILE *) NULL)
2474 image->blob->type=FileStream;
2475 #if defined(MAGICKCORE_HAVE_SETVBUF)
2476 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2478 (void) ResetMagickMemory(magick,0,sizeof(magick));
2479 count=fread(magick,1,sizeof(magick),image->blob->file);
2480 (void) rewind(image->blob->file);
2481 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2482 " read %.20g magic header bytes",(double) count);
2483 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2484 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2485 ((int) magick[2] == 0x08))
2487 (void) fclose(image->blob->file);
2488 image->blob->file=(FILE *) gzopen(filename,type);
2489 if (image->blob->file != (FILE *) NULL)
2490 image->blob->type=ZipStream;
2493 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2494 if (strncmp((char *) magick,"BZh",3) == 0)
2496 (void) fclose(image->blob->file);
2497 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2498 if (image->blob->file != (FILE *) NULL)
2499 image->blob->type=BZipStream;
2502 if (image->blob->type == FileStream)
2513 sans_exception=AcquireExceptionInfo();
2514 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2515 sans_exception=DestroyExceptionInfo(sans_exception);
2516 properties=(&image->blob->properties);
2517 if ((magick_info != (const MagickInfo *) NULL) &&
2518 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2519 (properties->st_size <= MagickMaxBufferExtent))
2527 length=(size_t) properties->st_size;
2528 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2529 if (blob != (void *) NULL)
2532 Format supports blobs-- use memory-mapped I/O.
2534 if (image_info->file != (FILE *) NULL)
2535 image->blob->exempt=MagickFalse;
2538 (void) fclose(image->blob->file);
2539 image->blob->file=(FILE *) NULL;
2541 AttachBlob(image->blob,blob,length);
2542 image->blob->mapped=MagickTrue;
2549 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2550 if ((LocaleCompare(extension,"Z") == 0) ||
2551 (LocaleCompare(extension,"gz") == 0) ||
2552 (LocaleCompare(extension,"wmz") == 0) ||
2553 (LocaleCompare(extension,"svgz") == 0))
2555 if (mode == WriteBinaryBlobMode)
2557 image->blob->file=(FILE *) gzopen(filename,type);
2558 if (image->blob->file != (FILE *) NULL)
2559 image->blob->type=ZipStream;
2563 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2564 if (LocaleCompare(extension,".bz2") == 0)
2566 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2567 if (image->blob->file != (FILE *) NULL)
2568 image->blob->type=BZipStream;
2573 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2574 if (image->blob->file != (FILE *) NULL)
2576 image->blob->type=FileStream;
2577 #if defined(MAGICKCORE_HAVE_SETVBUF)
2578 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2583 image->blob->status=MagickFalse;
2584 if (image->blob->type != UndefinedStream)
2585 image->blob->size=GetBlobSize(image);
2588 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2589 return(MagickFalse);
2595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2605 % PingBlob() returns all the attributes of an image or image sequence except
2606 % for the pixels. It is much faster and consumes far less memory than
2607 % BlobToImage(). On failure, a NULL image is returned and exception
2608 % describes the reason for the failure.
2610 % The format of the PingBlob method is:
2612 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2613 % const size_t length,ExceptionInfo *exception)
2615 % A description of each parameter follows:
2617 % o image_info: the image info.
2619 % o blob: the address of a character stream in one of the image formats
2620 % understood by ImageMagick.
2622 % o length: This size_t integer reflects the length in bytes of the blob.
2624 % o exception: return any errors or warnings in this structure.
2628 #if defined(__cplusplus) || defined(c_plusplus)
2632 static size_t PingStream(const Image *magick_unused(image),
2633 const void *magick_unused(pixels),const size_t columns)
2638 #if defined(__cplusplus) || defined(c_plusplus)
2642 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2643 const size_t length,ExceptionInfo *exception)
2651 assert(image_info != (ImageInfo *) NULL);
2652 assert(image_info->signature == MagickSignature);
2653 if (image_info->debug != MagickFalse)
2654 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2655 image_info->filename);
2656 assert(exception != (ExceptionInfo *) NULL);
2657 if ((blob == (const void *) NULL) || (length == 0))
2659 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2660 "UnrecognizedImageFormat","`%s'",image_info->magick);
2661 return((Image *) NULL);
2663 ping_info=CloneImageInfo(image_info);
2664 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2665 if (ping_info->blob == (const void *) NULL)
2667 (void) ThrowMagickException(exception,GetMagickModule(),
2668 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2669 return((Image *) NULL);
2671 (void) memcpy(ping_info->blob,blob,length);
2672 ping_info->length=length;
2673 ping_info->ping=MagickTrue;
2674 image=ReadStream(ping_info,&PingStream,exception);
2675 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2676 ping_info=DestroyImageInfo(ping_info);
2681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2691 % ReadBlob() reads data from the blob or image file and returns it. It
2692 % returns the number of bytes read.
2694 % The format of the ReadBlob method is:
2696 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2698 % A description of each parameter follows:
2700 % o image: the image.
2702 % o length: Specifies an integer representing the number of bytes to read
2705 % o data: Specifies an area to place the information requested from the
2709 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2710 unsigned char *data)
2715 register unsigned char
2721 assert(image != (Image *) NULL);
2722 assert(image->signature == MagickSignature);
2723 assert(image->blob != (BlobInfo *) NULL);
2724 assert(image->blob->type != UndefinedStream);
2727 assert(data != (void *) NULL);
2730 switch (image->blob->type)
2732 case UndefinedStream:
2735 case StandardStream:
2742 count=(ssize_t) fread(q,1,length,image->blob->file);
2747 c=getc(image->blob->file);
2750 *q++=(unsigned char) c;
2755 c=getc(image->blob->file);
2758 *q++=(unsigned char) c;
2768 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2773 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2778 c=gzgetc(image->blob->file);
2781 *q++=(unsigned char) c;
2786 c=gzgetc(image->blob->file);
2789 *q++=(unsigned char) c;
2800 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2801 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2809 register const unsigned char
2812 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2814 image->blob->eof=MagickTrue;
2817 p=image->blob->data+image->blob->offset;
2818 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2819 image->blob->offset+=count;
2820 if (count != (ssize_t) length)
2821 image->blob->eof=MagickTrue;
2822 (void) memcpy(q,p,(size_t) count);
2830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2834 + R e a d B l o b B y t e %
2838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2840 % ReadBlobByte() reads a single byte from the image file and returns it.
2842 % The format of the ReadBlobByte method is:
2844 % int ReadBlobByte(Image *image)
2846 % A description of each parameter follows.
2848 % o image: the image.
2851 MagickExport int ReadBlobByte(Image *image)
2853 register const unsigned char
2862 assert(image != (Image *) NULL);
2863 assert(image->signature == MagickSignature);
2864 p=ReadBlobStream(image,1,buffer,&count);
2871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2875 + R e a d B l o b D o u b l e %
2879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2881 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2882 % specified by the endian member of the image structure.
2884 % The format of the ReadBlobDouble method is:
2886 % double ReadBlobDouble(Image *image)
2888 % A description of each parameter follows.
2890 % o image: the image.
2893 MagickExport double ReadBlobDouble(Image *image)
2904 quantum.double_value=0.0;
2905 quantum.unsigned_value=ReadBlobLongLong(image);
2906 return(quantum.double_value);
2910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2914 + R e a d B l o b F l o a t %
2918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2920 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2921 % specified by the endian member of the image structure.
2923 % The format of the ReadBlobFloat method is:
2925 % float ReadBlobFloat(Image *image)
2927 % A description of each parameter follows.
2929 % o image: the image.
2932 MagickExport float ReadBlobFloat(Image *image)
2943 quantum.float_value=0.0;
2944 quantum.unsigned_value=ReadBlobLong(image);
2945 return(quantum.float_value);
2949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2953 + R e a d B l o b L o n g %
2957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2959 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2960 % specified by the endian member of the image structure.
2962 % The format of the ReadBlobLong method is:
2964 % unsigned int ReadBlobLong(Image *image)
2966 % A description of each parameter follows.
2968 % o image: the image.
2971 MagickExport unsigned int ReadBlobLong(Image *image)
2973 register const unsigned char
2985 assert(image != (Image *) NULL);
2986 assert(image->signature == MagickSignature);
2988 p=ReadBlobStream(image,4,buffer,&count);
2991 if (image->endian == LSBEndian)
2993 value=(unsigned int) (*p++);
2994 value|=((unsigned int) (*p++)) << 8;
2995 value|=((unsigned int) (*p++)) << 16;
2996 value|=((unsigned int) (*p++)) << 24;
2999 value=((unsigned int) (*p++)) << 24;
3000 value|=((unsigned int) (*p++)) << 16;
3001 value|=((unsigned int) (*p++)) << 8;
3002 value|=((unsigned int) (*p++));
3007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3011 + R e a d B l o b L o n g L o n g %
3015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3017 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3018 % byte-order specified by the endian member of the image structure.
3020 % The format of the ReadBlobLongLong method is:
3022 % MagickSizeType ReadBlobLongLong(Image *image)
3024 % A description of each parameter follows.
3026 % o image: the image.
3029 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3034 register const unsigned char
3043 assert(image != (Image *) NULL);
3044 assert(image->signature == MagickSignature);
3046 p=ReadBlobStream(image,8,buffer,&count);
3048 return(MagickULLConstant(0));
3049 if (image->endian == LSBEndian)
3051 value=(MagickSizeType) (*p++);
3052 value|=((MagickSizeType) (*p++)) << 8;
3053 value|=((MagickSizeType) (*p++)) << 16;
3054 value|=((MagickSizeType) (*p++)) << 24;
3055 value|=((MagickSizeType) (*p++)) << 32;
3056 value|=((MagickSizeType) (*p++)) << 40;
3057 value|=((MagickSizeType) (*p++)) << 48;
3058 value|=((MagickSizeType) (*p++)) << 56;
3059 return(value & MagickULLConstant(0xffffffffffffffff));
3061 value=((MagickSizeType) (*p++)) << 56;
3062 value|=((MagickSizeType) (*p++)) << 48;
3063 value|=((MagickSizeType) (*p++)) << 40;
3064 value|=((MagickSizeType) (*p++)) << 32;
3065 value|=((MagickSizeType) (*p++)) << 24;
3066 value|=((MagickSizeType) (*p++)) << 16;
3067 value|=((MagickSizeType) (*p++)) << 8;
3068 value|=((MagickSizeType) (*p++));
3069 return(value & MagickULLConstant(0xffffffffffffffff));
3073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3077 + R e a d B l o b S h o r t %
3081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3083 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3084 % specified by the endian member of the image structure.
3086 % The format of the ReadBlobShort method is:
3088 % unsigned short ReadBlobShort(Image *image)
3090 % A description of each parameter follows.
3092 % o image: the image.
3095 MagickExport unsigned short ReadBlobShort(Image *image)
3097 register const unsigned char
3100 register unsigned int
3109 assert(image != (Image *) NULL);
3110 assert(image->signature == MagickSignature);
3112 p=ReadBlobStream(image,2,buffer,&count);
3114 return((unsigned short) 0U);
3115 if (image->endian == LSBEndian)
3117 value=(unsigned int) (*p++);
3118 value|=((unsigned int) (*p++)) << 8;
3119 return((unsigned short) (value & 0xffff));
3121 value=(unsigned int) ((*p++) << 8);
3122 value|=(unsigned int) (*p++);
3123 return((unsigned short) (value & 0xffff));
3127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3131 + R e a d B l o b L S B L o n g %
3135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3137 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3138 % least-significant byte first order.
3140 % The format of the ReadBlobLSBLong method is:
3142 % unsigned int ReadBlobLSBLong(Image *image)
3144 % A description of each parameter follows.
3146 % o image: the image.
3149 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3151 register const unsigned char
3154 register unsigned int
3163 assert(image != (Image *) NULL);
3164 assert(image->signature == MagickSignature);
3166 p=ReadBlobStream(image,4,buffer,&count);
3169 value=(unsigned int) (*p++);
3170 value|=((unsigned int) (*p++)) << 8;
3171 value|=((unsigned int) (*p++)) << 16;
3172 value|=((unsigned int) (*p++)) << 24;
3177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3181 + R e a d B l o b L S B S h o r t %
3185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3187 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3188 % least-significant byte first order.
3190 % The format of the ReadBlobLSBShort method is:
3192 % unsigned short ReadBlobLSBShort(Image *image)
3194 % A description of each parameter follows.
3196 % o image: the image.
3199 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3201 register const unsigned char
3204 register unsigned int
3213 assert(image != (Image *) NULL);
3214 assert(image->signature == MagickSignature);
3216 p=ReadBlobStream(image,2,buffer,&count);
3218 return((unsigned short) 0U);
3219 value=(unsigned int) (*p++);
3220 value|=((unsigned int) ((*p++)) << 8);
3221 return((unsigned short) (value & 0xffff));
3225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3229 + R e a d B l o b M S B L o n g %
3233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3235 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3236 % most-significant byte first order.
3238 % The format of the ReadBlobMSBLong method is:
3240 % unsigned int ReadBlobMSBLong(Image *image)
3242 % A description of each parameter follows.
3244 % o image: the image.
3247 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3249 register const unsigned char
3252 register unsigned int
3261 assert(image != (Image *) NULL);
3262 assert(image->signature == MagickSignature);
3264 p=ReadBlobStream(image,4,buffer,&count);
3267 value=((unsigned int) (*p++) << 24);
3268 value|=((unsigned int) (*p++) << 16);
3269 value|=((unsigned int) (*p++) << 8);
3270 value|=(unsigned int) (*p++);
3275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3279 + R e a d B l o b M S B L o n g L o n g %
3283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3285 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3286 % most-significant byte first order.
3288 % The format of the ReadBlobMSBLongLong method is:
3290 % unsigned int ReadBlobMSBLongLong(Image *image)
3292 % A description of each parameter follows.
3294 % o image: the image.
3297 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3299 register const unsigned char
3302 register MagickSizeType
3311 assert(image != (Image *) NULL);
3312 assert(image->signature == MagickSignature);
3314 p=ReadBlobStream(image,8,buffer,&count);
3316 return(MagickULLConstant(0));
3317 value=((MagickSizeType) (*p++)) << 56;
3318 value|=((MagickSizeType) (*p++)) << 48;
3319 value|=((MagickSizeType) (*p++)) << 40;
3320 value|=((MagickSizeType) (*p++)) << 32;
3321 value|=((MagickSizeType) (*p++)) << 24;
3322 value|=((MagickSizeType) (*p++)) << 16;
3323 value|=((MagickSizeType) (*p++)) << 8;
3324 value|=((MagickSizeType) (*p++));
3325 return(value & MagickULLConstant(0xffffffffffffffff));
3329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3333 + R e a d B l o b M S B S h o r t %
3337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3339 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3340 % most-significant byte first order.
3342 % The format of the ReadBlobMSBShort method is:
3344 % unsigned short ReadBlobMSBShort(Image *image)
3346 % A description of each parameter follows.
3348 % o image: the image.
3351 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3353 register const unsigned char
3356 register unsigned int
3365 assert(image != (Image *) NULL);
3366 assert(image->signature == MagickSignature);
3368 p=ReadBlobStream(image,2,buffer,&count);
3370 return((unsigned short) 0U);
3371 value=(unsigned int) ((*p++) << 8);
3372 value|=(unsigned int) (*p++);
3373 return((unsigned short) (value & 0xffff));
3377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3381 + R e a d B l o b S t r i n g %
3385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3387 % ReadBlobString() reads characters from a blob or file until a newline
3388 % character is read or an end-of-file condition is encountered.
3390 % The format of the ReadBlobString method is:
3392 % char *ReadBlobString(Image *image,char *string)
3394 % A description of each parameter follows:
3396 % o image: the image.
3398 % o string: the address of a character buffer.
3401 MagickExport char *ReadBlobString(Image *image,char *string)
3403 register const unsigned char
3415 assert(image != (Image *) NULL);
3416 assert(image->signature == MagickSignature);
3417 for (i=0; i < (MaxTextExtent-1L); i++)
3419 p=ReadBlobStream(image,1,buffer,&count);
3423 return((char *) NULL);
3426 string[i]=(char) (*p);
3427 if ((string[i] == '\r') || (string[i] == '\n'))
3430 if (string[i] == '\r')
3431 (void) ReadBlobStream(image,1,buffer,&count);
3437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3441 + R e f e r e n c e B l o b %
3445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3447 % ReferenceBlob() increments the reference count associated with the pixel
3448 % blob returning a pointer to the blob.
3450 % The format of the ReferenceBlob method is:
3452 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3454 % A description of each parameter follows:
3456 % o blob_info: the blob_info.
3459 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3461 assert(blob != (BlobInfo *) NULL);
3462 assert(blob->signature == MagickSignature);
3463 if (blob->debug != MagickFalse)
3464 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3465 LockSemaphoreInfo(blob->semaphore);
3466 blob->reference_count++;
3467 UnlockSemaphoreInfo(blob->semaphore);
3472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3482 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3483 % and returns the resulting offset.
3485 % The format of the SeekBlob method is:
3487 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3490 % A description of each parameter follows:
3492 % o image: the image.
3494 % o offset: Specifies an integer representing the offset in bytes.
3496 % o whence: Specifies an integer representing how the offset is
3497 % treated relative to the beginning of the blob as follows:
3499 % SEEK_SET Set position equal to offset bytes.
3500 % SEEK_CUR Set position to current location plus offset.
3501 % SEEK_END Set position to EOF plus offset.
3504 MagickExport MagickOffsetType SeekBlob(Image *image,
3505 const MagickOffsetType offset,const int whence)
3507 assert(image != (Image *) NULL);
3508 assert(image->signature == MagickSignature);
3509 if (image->debug != MagickFalse)
3510 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3511 assert(image->blob != (BlobInfo *) NULL);
3512 assert(image->blob->type != UndefinedStream);
3513 switch (image->blob->type)
3515 case UndefinedStream:
3519 if (fseek(image->blob->file,offset,whence) < 0)
3521 image->blob->offset=TellBlob(image);
3524 case StandardStream:
3528 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3529 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3532 image->blob->offset=TellBlob(image);
3548 image->blob->offset=offset;
3553 if ((image->blob->offset+offset) < 0)
3555 image->blob->offset+=offset;
3560 if (((MagickOffsetType) image->blob->length+offset) < 0)
3562 image->blob->offset=image->blob->length+offset;
3566 if (image->blob->offset <= (MagickOffsetType)
3567 ((off_t) image->blob->length))
3568 image->blob->eof=MagickFalse;
3570 if (image->blob->mapped != MagickFalse)
3574 image->blob->extent=(size_t) (image->blob->offset+
3575 image->blob->quantum);
3576 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3577 image->blob->data,image->blob->extent+1,
3578 sizeof(*image->blob->data));
3579 (void) SyncBlob(image);
3580 if (image->blob->data == (unsigned char *) NULL)
3582 (void) DetachBlob(image->blob);
3589 return(image->blob->offset);
3593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3597 + S e t B l o b E x e m p t %
3601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3603 % SetBlobExempt() sets the blob exempt status.
3605 % The format of the SetBlobExempt method is:
3607 % MagickBooleanType SetBlobExempt(const Image *image,
3608 % const MagickBooleanType exempt)
3610 % A description of each parameter follows:
3612 % o image: the image.
3614 % o exempt: Set to true if this blob is exempt from being closed.
3617 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3619 assert(image != (const Image *) NULL);
3620 assert(image->signature == MagickSignature);
3621 if (image->debug != MagickFalse)
3622 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3623 image->blob->exempt=exempt;
3627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3631 + S e t B l o b E x t e n t %
3635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3637 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3638 % method is successful, subsequent writes to bytes in the specified range are
3639 % guaranteed not to fail.
3641 % The format of the SetBlobExtent method is:
3643 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3645 % A description of each parameter follows:
3647 % o image: the image.
3649 % o extent: the blob maximum extent.
3652 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3653 const MagickSizeType extent)
3655 assert(image != (Image *) NULL);
3656 assert(image->signature == MagickSignature);
3657 if (image->debug != MagickFalse)
3658 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3659 assert(image->blob != (BlobInfo *) NULL);
3660 assert(image->blob->type != UndefinedStream);
3661 switch (image->blob->type)
3663 case UndefinedStream:
3667 if (extent != (MagickSizeType) ((off_t) extent))
3668 return(MagickFalse);
3669 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3670 return(MagickFalse);
3679 offset=TellBlob(image);
3680 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3681 (off_t) (extent-offset));
3683 return(MagickFalse);
3688 case StandardStream:
3691 return(MagickFalse);
3693 return(MagickFalse);
3695 return(MagickFalse);
3698 if (image->blob->mapped != MagickFalse)
3700 if (image->blob->file == (FILE *) NULL)
3701 return(MagickFalse);
3702 (void) UnmapBlob(image->blob->data,image->blob->length);
3703 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3704 return(MagickFalse);
3713 offset=TellBlob(image);
3714 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3715 (off_t) (extent-offset));
3717 return(MagickFalse);
3719 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3720 WriteMode,0,(size_t) extent);
3721 image->blob->extent=(size_t) extent;
3722 image->blob->length=(size_t) extent;
3723 (void) SyncBlob(image);
3727 if (extent != (MagickSizeType) ((size_t) extent))
3728 return(MagickFalse);
3729 image->blob->extent=(size_t) extent;
3730 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3731 image->blob->extent+1,sizeof(*image->blob->data));
3732 (void) SyncBlob(image);
3733 if (image->blob->data == (unsigned char *) NULL)
3735 (void) DetachBlob(image->blob);
3736 return(MagickFalse);
3745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3755 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3756 % attributes if it is an blob.
3758 % The format of the SyncBlob method is:
3760 % int SyncBlob(Image *image)
3762 % A description of each parameter follows:
3764 % o image: the image.
3767 static int SyncBlob(Image *image)
3772 assert(image != (Image *) NULL);
3773 assert(image->signature == MagickSignature);
3774 if (image->debug != MagickFalse)
3775 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3776 assert(image->blob != (BlobInfo *) NULL);
3777 assert(image->blob->type != UndefinedStream);
3779 switch (image->blob->type)
3781 case UndefinedStream:
3784 case StandardStream:
3787 status=fflush(image->blob->file);
3792 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3793 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3799 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3800 status=BZ2_bzflush((BZFILE *) image->blob->file);
3808 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3809 if (image->blob->mapped != MagickFalse)
3810 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3829 % TellBlob() obtains the current value of the blob or file position.
3831 % The format of the TellBlob method is:
3833 % MagickOffsetType TellBlob(const Image *image)
3835 % A description of each parameter follows:
3837 % o image: the image.
3840 MagickExport MagickOffsetType TellBlob(const Image *image)
3845 assert(image != (Image *) NULL);
3846 assert(image->signature == MagickSignature);
3847 if (image->debug != MagickFalse)
3848 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3849 assert(image->blob != (BlobInfo *) NULL);
3850 assert(image->blob->type != UndefinedStream);
3852 switch (image->blob->type)
3854 case UndefinedStream:
3858 offset=ftell(image->blob->file);
3861 case StandardStream:
3866 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3867 offset=(MagickOffsetType) gztell(image->blob->file);
3877 offset=image->blob->offset;
3885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3889 + U n m a p B l o b %
3893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3895 % UnmapBlob() deallocates the binary large object previously allocated with
3896 % the MapBlob method.
3898 % The format of the UnmapBlob method is:
3900 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3902 % A description of each parameter follows:
3904 % o map: the address of the binary large object.
3906 % o length: the length of the binary large object.
3909 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3911 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3915 status=munmap(map,length);
3916 return(status == -1 ? MagickFalse : MagickTrue);
3920 return(MagickFalse);
3925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3929 + W r i t e B l o b %
3933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3935 % WriteBlob() writes data to a blob or image file. It returns the number of
3938 % The format of the WriteBlob method is:
3940 % ssize_t WriteBlob(Image *image,const size_t length,
3941 % const unsigned char *data)
3943 % A description of each parameter follows:
3945 % o image: the image.
3947 % o length: Specifies an integer representing the number of bytes to
3948 % write to the file.
3950 % o data: The address of the data to write to the blob or file.
3953 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3954 const unsigned char *data)
3959 register const unsigned char
3965 assert(image != (Image *) NULL);
3966 assert(image->signature == MagickSignature);
3967 assert(data != (const unsigned char *) NULL);
3968 assert(image->blob != (BlobInfo *) NULL);
3969 assert(image->blob->type != UndefinedStream);
3974 switch (image->blob->type)
3976 case UndefinedStream:
3979 case StandardStream:
3986 count=(ssize_t) fwrite((const char *) data,1,length,
3992 c=putc((int) *p++,image->blob->file);
3999 c=putc((int) *p++,image->blob->file);
4011 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4016 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4017 (unsigned int) length);
4022 c=gzputc(image->blob->file,(int) *p++);
4029 c=gzputc(image->blob->file,(int) *p++);
4042 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4043 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4050 count=(ssize_t) image->blob->stream(image,data,length);
4055 register unsigned char
4058 if ((image->blob->offset+(MagickOffsetType) length) >=
4059 (MagickOffsetType) image->blob->extent)
4061 if (image->blob->mapped != MagickFalse)
4063 image->blob->quantum<<=1;
4064 image->blob->extent+=length+image->blob->quantum;
4065 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4066 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4067 (void) SyncBlob(image);
4068 if (image->blob->data == (unsigned char *) NULL)
4070 (void) DetachBlob(image->blob);
4074 q=image->blob->data+image->blob->offset;
4075 (void) memcpy(q,p,length);
4076 image->blob->offset+=length;
4077 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4078 image->blob->length=(size_t) image->blob->offset;
4079 count=(ssize_t) length;
4086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4090 + W r i t e B l o b B y t e %
4094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4096 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4097 % written (either 0 or 1);
4099 % The format of the WriteBlobByte method is:
4101 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4103 % A description of each parameter follows.
4105 % o image: the image.
4107 % o value: Specifies the value to write.
4110 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4112 assert(image != (Image *) NULL);
4113 assert(image->signature == MagickSignature);
4114 return(WriteBlobStream(image,1,&value));
4118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4122 + W r i t e B l o b F l o a t %
4126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4128 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4129 % specified by the endian member of the image structure.
4131 % The format of the WriteBlobFloat method is:
4133 % ssize_t WriteBlobFloat(Image *image,const float value)
4135 % A description of each parameter follows.
4137 % o image: the image.
4139 % o value: Specifies the value to write.
4142 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4153 quantum.unsigned_value=0U;
4154 quantum.float_value=value;
4155 return(WriteBlobLong(image,quantum.unsigned_value));
4159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4163 + W r i t e B l o b L o n g %
4167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4169 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4170 % specified by the endian member of the image structure.
4172 % The format of the WriteBlobLong method is:
4174 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4176 % A description of each parameter follows.
4178 % o image: the image.
4180 % o value: Specifies the value to write.
4183 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4188 assert(image != (Image *) NULL);
4189 assert(image->signature == MagickSignature);
4190 if (image->endian == LSBEndian)
4192 buffer[0]=(unsigned char) value;
4193 buffer[1]=(unsigned char) (value >> 8);
4194 buffer[2]=(unsigned char) (value >> 16);
4195 buffer[3]=(unsigned char) (value >> 24);
4196 return(WriteBlobStream(image,4,buffer));
4198 buffer[0]=(unsigned char) (value >> 24);
4199 buffer[1]=(unsigned char) (value >> 16);
4200 buffer[2]=(unsigned char) (value >> 8);
4201 buffer[3]=(unsigned char) value;
4202 return(WriteBlobStream(image,4,buffer));
4206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4210 + W r i t e B l o b S h o r t %
4214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4216 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4217 % byte-order specified by the endian member of the image structure.
4219 % The format of the WriteBlobShort method is:
4221 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4223 % A description of each parameter follows.
4225 % o image: the image.
4227 % o value: Specifies the value to write.
4230 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4235 assert(image != (Image *) NULL);
4236 assert(image->signature == MagickSignature);
4237 if (image->endian == LSBEndian)
4239 buffer[0]=(unsigned char) value;
4240 buffer[1]=(unsigned char) (value >> 8);
4241 return(WriteBlobStream(image,2,buffer));
4243 buffer[0]=(unsigned char) (value >> 8);
4244 buffer[1]=(unsigned char) value;
4245 return(WriteBlobStream(image,2,buffer));
4249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4253 + W r i t e B l o b L S B L o n g %
4257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4259 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4260 % least-significant byte first order.
4262 % The format of the WriteBlobLSBLong method is:
4264 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4266 % A description of each parameter follows.
4268 % o image: the image.
4270 % o value: Specifies the value to write.
4273 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4278 assert(image != (Image *) NULL);
4279 assert(image->signature == MagickSignature);
4280 buffer[0]=(unsigned char) value;
4281 buffer[1]=(unsigned char) (value >> 8);
4282 buffer[2]=(unsigned char) (value >> 16);
4283 buffer[3]=(unsigned char) (value >> 24);
4284 return(WriteBlobStream(image,4,buffer));
4288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4292 + W r i t e B l o b L S B S h o r t %
4296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4298 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4299 % least-significant byte first order.
4301 % The format of the WriteBlobLSBShort method is:
4303 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4305 % A description of each parameter follows.
4307 % o image: the image.
4309 % o value: Specifies the value to write.
4312 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4317 assert(image != (Image *) NULL);
4318 assert(image->signature == MagickSignature);
4319 buffer[0]=(unsigned char) value;
4320 buffer[1]=(unsigned char) (value >> 8);
4321 return(WriteBlobStream(image,2,buffer));
4325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4329 + W r i t e B l o b M S B L o n g %
4333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4335 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4336 % most-significant byte first order.
4338 % The format of the WriteBlobMSBLong method is:
4340 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4342 % A description of each parameter follows.
4344 % o value: Specifies the value to write.
4346 % o image: the image.
4349 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4354 assert(image != (Image *) NULL);
4355 assert(image->signature == MagickSignature);
4356 buffer[0]=(unsigned char) (value >> 24);
4357 buffer[1]=(unsigned char) (value >> 16);
4358 buffer[2]=(unsigned char) (value >> 8);
4359 buffer[3]=(unsigned char) value;
4360 return(WriteBlobStream(image,4,buffer));
4364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4368 + W r i t e B l o b M S B L o n g L o n g %
4372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4374 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4375 % most-significant byte first order.
4377 % The format of the WriteBlobMSBLongLong method is:
4379 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4381 % A description of each parameter follows.
4383 % o value: Specifies the value to write.
4385 % o image: the image.
4388 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4389 const MagickSizeType value)
4394 assert(image != (Image *) NULL);
4395 assert(image->signature == MagickSignature);
4396 buffer[0]=(unsigned char) (value >> 56);
4397 buffer[1]=(unsigned char) (value >> 48);
4398 buffer[2]=(unsigned char) (value >> 40);
4399 buffer[3]=(unsigned char) (value >> 32);
4400 buffer[4]=(unsigned char) (value >> 24);
4401 buffer[5]=(unsigned char) (value >> 16);
4402 buffer[6]=(unsigned char) (value >> 8);
4403 buffer[7]=(unsigned char) value;
4404 return(WriteBlobStream(image,8,buffer));
4408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4412 + W r i t e B l o b M S B S h o r t %
4416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4418 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4419 % most-significant byte first order.
4421 % The format of the WriteBlobMSBShort method is:
4423 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4425 % A description of each parameter follows.
4427 % o value: Specifies the value to write.
4429 % o file: Specifies the file to write the data to.
4432 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4437 assert(image != (Image *) NULL);
4438 assert(image->signature == MagickSignature);
4439 buffer[0]=(unsigned char) (value >> 8);
4440 buffer[1]=(unsigned char) value;
4441 return(WriteBlobStream(image,2,buffer));
4445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4449 + W r i t e B l o b S t r i n g %
4453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4455 % WriteBlobString() write a string to a blob. It returns the number of
4456 % characters written.
4458 % The format of the WriteBlobString method is:
4460 % ssize_t WriteBlobString(Image *image,const char *string)
4462 % A description of each parameter follows.
4464 % o image: the image.
4466 % o string: Specifies the string to write.
4469 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4471 assert(image != (Image *) NULL);
4472 assert(image->signature == MagickSignature);
4473 assert(string != (const char *) NULL);
4474 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));