2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/client.h"
48 #include "MagickCore/constitute.h"
49 #include "MagickCore/delegate.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image-private.h"
53 #include "MagickCore/list.h"
54 #include "MagickCore/locale_.h"
55 #include "MagickCore/log.h"
56 #include "MagickCore/magick.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/policy.h"
59 #include "MagickCore/resource_.h"
60 #include "MagickCore/semaphore.h"
61 #include "MagickCore/string_.h"
62 #include "MagickCore/string-private.h"
63 #include "MagickCore/token.h"
64 #include "MagickCore/utility.h"
65 #include "MagickCore/utility-private.h"
66 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
67 # include <sys/mman.h>
69 #if defined(MAGICKCORE_ZLIB_DELEGATE)
72 #if defined(MAGICKCORE_BZLIB_DELEGATE)
79 #define MagickMaxBlobExtent 65541
80 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
81 # define MAP_ANONYMOUS MAP_ANON
83 #if !defined(MAP_FAILED)
84 #define MAP_FAILED ((void *) -1)
91 #define _O_BINARY O_BINARY
127 #if defined(MAGICKCORE_ZLIB_DELEGATE)
132 #if defined(MAGICKCORE_BZLIB_DELEGATE)
161 Forward declarations.
167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 + A t t a c h B l o b %
175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 % AttachBlob() attaches a blob to the BlobInfo structure.
179 % The format of the AttachBlob method is:
181 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
183 % A description of each parameter follows:
185 % o blob_info: Specifies a pointer to a BlobInfo structure.
187 % o blob: the address of a character stream in one of the image formats
188 % understood by ImageMagick.
190 % o length: This size_t integer reflects the length in bytes of the blob.
193 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
196 assert(blob_info != (BlobInfo *) NULL);
197 if (blob_info->debug != MagickFalse)
198 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
199 blob_info->length=length;
200 blob_info->extent=length;
201 blob_info->quantum=(size_t) MagickMaxBlobExtent;
203 blob_info->type=BlobStream;
204 blob_info->file=(FILE *) NULL;
205 blob_info->data=(unsigned char *) blob;
206 blob_info->mapped=MagickFalse;
210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214 + B l o b T o F i l e %
218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
221 % occurs otherwise MagickTrue.
223 % The format of the BlobToFile method is:
225 % MagickBooleanType BlobToFile(char *filename,const void *blob,
226 % const size_t length,ExceptionInfo *exception)
228 % A description of each parameter follows:
230 % o filename: Write the blob to this file.
232 % o blob: the address of a blob.
234 % o length: This length in bytes of the blob.
236 % o exception: return any errors or warnings in this structure.
240 static inline MagickSizeType MagickMin(const MagickSizeType x,
241 const MagickSizeType y)
248 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
249 const size_t length,ExceptionInfo *exception)
260 assert(filename != (const char *) NULL);
261 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
262 assert(blob != (const void *) NULL);
263 if (*filename == '\0')
264 file=AcquireUniqueFileResource(filename);
266 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
269 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
272 for (i=0; i < length; i+=count)
274 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
275 i,(MagickSizeType) SSIZE_MAX));
284 if ((file == -1) || (i < length))
286 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297 % B l o b T o I m a g e %
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303 % BlobToImage() implements direct to memory image formats. It returns the
306 % The format of the BlobToImage method is:
308 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
309 % const size_t length,ExceptionInfo *exception)
311 % A description of each parameter follows:
313 % o image_info: the image info.
315 % o blob: the address of a character stream in one of the image formats
316 % understood by ImageMagick.
318 % o length: This size_t integer reflects the length in bytes of the blob.
320 % o exception: return any errors or warnings in this structure.
323 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
324 const size_t length,ExceptionInfo *exception)
339 assert(image_info != (ImageInfo *) NULL);
340 assert(image_info->signature == MagickSignature);
341 if (image_info->debug != MagickFalse)
342 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
343 image_info->filename);
344 assert(exception != (ExceptionInfo *) NULL);
345 if ((blob == (const void *) NULL) || (length == 0))
347 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
348 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
349 return((Image *) NULL);
351 blob_info=CloneImageInfo(image_info);
352 blob_info->blob=(void *) blob;
353 blob_info->length=length;
354 if (*blob_info->magick == '\0')
355 (void) SetImageInfo(blob_info,0,exception);
356 magick_info=GetMagickInfo(blob_info->magick,exception);
357 if (magick_info == (const MagickInfo *) NULL)
359 blob_info=DestroyImageInfo(blob_info);
360 (void) ThrowMagickException(exception,GetMagickModule(),
361 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
362 image_info->filename);
363 return((Image *) NULL);
365 if (GetMagickBlobSupport(magick_info) != MagickFalse)
368 Native blob support for this image format.
370 (void) CopyMagickString(blob_info->filename,image_info->filename,
372 (void) CopyMagickString(blob_info->magick,image_info->magick,
374 image=ReadImage(blob_info,exception);
375 if (image != (Image *) NULL)
376 (void) DetachBlob(image->blob);
377 blob_info=DestroyImageInfo(blob_info);
381 Write blob to a temporary file on disk.
383 blob_info->blob=(void *) NULL;
385 *blob_info->filename='\0';
386 status=BlobToFile(blob_info->filename,blob,length,exception);
387 if (status == MagickFalse)
389 (void) RelinquishUniqueFileResource(blob_info->filename);
390 blob_info=DestroyImageInfo(blob_info);
391 return((Image *) NULL);
393 clone_info=CloneImageInfo(blob_info);
394 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
395 blob_info->magick,blob_info->filename);
396 image=ReadImage(clone_info,exception);
397 clone_info=DestroyImageInfo(clone_info);
398 (void) RelinquishUniqueFileResource(blob_info->filename);
399 blob_info=DestroyImageInfo(blob_info);
404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 + C l o n e B l o b I n f o %
412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
414 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
415 % blob info is NULL, a new one.
417 % The format of the CloneBlobInfo method is:
419 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
421 % A description of each parameter follows:
423 % o blob_info: the blob info.
426 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
431 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
432 if (clone_info == (BlobInfo *) NULL)
433 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
434 GetBlobInfo(clone_info);
435 if (blob_info == (BlobInfo *) NULL)
437 clone_info->length=blob_info->length;
438 clone_info->extent=blob_info->extent;
439 clone_info->synchronize=blob_info->synchronize;
440 clone_info->quantum=blob_info->quantum;
441 clone_info->mapped=blob_info->mapped;
442 clone_info->eof=blob_info->eof;
443 clone_info->offset=blob_info->offset;
444 clone_info->size=blob_info->size;
445 clone_info->exempt=blob_info->exempt;
446 clone_info->status=blob_info->status;
447 clone_info->temporary=blob_info->temporary;
448 clone_info->type=blob_info->type;
449 clone_info->file=blob_info->file;
450 clone_info->properties=blob_info->properties;
451 clone_info->stream=blob_info->stream;
452 clone_info->data=blob_info->data;
453 clone_info->debug=IsEventLogging();
454 clone_info->reference_count=1;
459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
463 + C l o s e B l o b %
467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
469 % CloseBlob() closes a stream associated with the image.
471 % The format of the CloseBlob method is:
473 % MagickBooleanType CloseBlob(Image *image)
475 % A description of each parameter follows:
477 % o image: the image.
480 MagickExport MagickBooleanType CloseBlob(Image *image)
488 assert(image != (Image *) NULL);
489 assert(image->signature == MagickSignature);
490 if (image->debug != MagickFalse)
491 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
492 assert(image->blob != (BlobInfo *) NULL);
493 if (image->blob->type == UndefinedStream)
495 if (image->blob->synchronize != MagickFalse)
497 image->blob->size=GetBlobSize(image);
498 image->extent=image->blob->size;
499 image->blob->eof=MagickFalse;
500 if (image->blob->exempt != MagickFalse)
502 image->blob->type=UndefinedStream;
506 switch (image->blob->type)
508 case UndefinedStream:
514 status=ferror(image->blob->file);
519 #if defined(MAGICKCORE_ZLIB_DELEGATE)
520 (void) gzerror(image->blob->gzfile,&status);
526 #if defined(MAGICKCORE_BZLIB_DELEGATE)
527 (void) BZ2_bzerror(image->blob->bzfile,&status);
535 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
536 switch (image->blob->type)
538 case UndefinedStream:
543 if (image->blob->synchronize != MagickFalse)
545 status=fflush(image->blob->file);
546 status=fsync(fileno(image->blob->file));
548 status=fclose(image->blob->file);
553 #if defined(MAGICKCORE_HAVE_PCLOSE)
554 status=pclose(image->blob->file);
560 #if defined(MAGICKCORE_ZLIB_DELEGATE)
561 status=gzclose(image->blob->gzfile);
567 #if defined(MAGICKCORE_BZLIB_DELEGATE)
568 BZ2_bzclose(image->blob->bzfile);
576 if (image->blob->file != (FILE *) NULL)
578 if (image->blob->synchronize != MagickFalse)
579 (void) fsync(fileno(image->blob->file));
580 status=fclose(image->blob->file);
585 (void) DetachBlob(image->blob);
586 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
587 return(image->blob->status);
591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595 + D e s t r o y B l o b %
599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601 % DestroyBlob() deallocates memory associated with a blob.
603 % The format of the DestroyBlob method is:
605 % void DestroyBlob(Image *image)
607 % A description of each parameter follows:
609 % o image: the image.
612 MagickExport void DestroyBlob(Image *image)
617 assert(image != (Image *) NULL);
618 assert(image->signature == MagickSignature);
619 if (image->debug != MagickFalse)
620 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
621 assert(image->blob != (BlobInfo *) NULL);
622 assert(image->blob->signature == MagickSignature);
624 LockSemaphoreInfo(image->blob->semaphore);
625 image->blob->reference_count--;
626 assert(image->blob->reference_count >= 0);
627 if (image->blob->reference_count == 0)
629 UnlockSemaphoreInfo(image->blob->semaphore);
630 if (destroy == MagickFalse)
632 (void) CloseBlob(image);
633 if (image->blob->mapped != MagickFalse)
634 (void) UnmapBlob(image->blob->data,image->blob->length);
635 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
636 DestroySemaphoreInfo(&image->blob->semaphore);
637 image->blob->signature=(~MagickSignature);
638 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
646 + D e t a c h B l o b %
650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652 % DetachBlob() detaches a blob from the BlobInfo structure.
654 % The format of the DetachBlob method is:
656 % unsigned char *DetachBlob(BlobInfo *blob_info)
658 % A description of each parameter follows:
660 % o blob_info: Specifies a pointer to a BlobInfo structure.
663 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
668 assert(blob_info != (BlobInfo *) NULL);
669 if (blob_info->debug != MagickFalse)
670 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
671 if (blob_info->mapped != MagickFalse)
672 (void) UnmapBlob(blob_info->data,blob_info->length);
673 blob_info->mapped=MagickFalse;
676 blob_info->eof=MagickFalse;
677 blob_info->exempt=MagickFalse;
678 blob_info->type=UndefinedStream;
679 blob_info->file=(FILE *) NULL;
680 data=blob_info->data;
681 blob_info->data=(unsigned char *) NULL;
682 blob_info->stream=(StreamHandler) NULL;
687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
691 + D i s c a r d B l o b B y t e s %
695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697 % DiscardBlobBytes() discards bytes in a blob.
699 % The format of the DiscardBlobBytes method is:
701 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
703 % A description of each parameter follows.
705 % o image: the image.
707 % o length: the number of bytes to skip.
711 static inline const unsigned char *ReadBlobStream(Image *image,
712 const size_t length,unsigned char *data,ssize_t *count)
714 assert(count != (ssize_t *) NULL);
715 assert(image->blob != (BlobInfo *) NULL);
716 if (image->blob->type != BlobStream)
718 *count=ReadBlob(image,length,data);
721 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
724 image->blob->eof=MagickTrue;
727 data=image->blob->data+image->blob->offset;
728 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
729 image->blob->offset));
730 image->blob->offset+=(*count);
731 if (*count != (ssize_t) length)
732 image->blob->eof=MagickTrue;
736 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
737 const MagickSizeType length)
739 register MagickOffsetType
751 assert(image != (Image *) NULL);
752 assert(image->signature == MagickSignature);
754 for (i=0; i < (MagickOffsetType) length; i+=count)
756 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
757 (void) ReadBlobStream(image,quantum,buffer,&count);
765 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773 + D u p l i c a t e s B l o b %
777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779 % DuplicateBlob() duplicates a blob descriptor.
781 % The format of the DuplicateBlob method is:
783 % void DuplicateBlob(Image *image,const Image *duplicate)
785 % A description of each parameter follows:
787 % o image: the image.
789 % o duplicate: the duplicate image.
792 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
794 assert(image != (Image *) NULL);
795 assert(image->signature == MagickSignature);
796 if (image->debug != MagickFalse)
797 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
798 assert(duplicate != (Image *) NULL);
799 assert(duplicate->signature == MagickSignature);
801 image->blob=ReferenceBlob(duplicate->blob);
805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
815 % EOFBlob() returns a non-zero value when EOF has been detected reading from
818 % The format of the EOFBlob method is:
820 % int EOFBlob(const Image *image)
822 % A description of each parameter follows:
824 % o image: the image.
827 MagickExport int EOFBlob(const Image *image)
829 assert(image != (Image *) NULL);
830 assert(image->signature == MagickSignature);
831 if (image->debug != MagickFalse)
832 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
833 assert(image->blob != (BlobInfo *) NULL);
834 assert(image->blob->type != UndefinedStream);
835 switch (image->blob->type)
837 case UndefinedStream:
843 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
848 image->blob->eof=MagickFalse;
853 #if defined(MAGICKCORE_BZLIB_DELEGATE)
858 (void) BZ2_bzerror(image->blob->bzfile,&status);
859 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
865 image->blob->eof=MagickFalse;
871 return((int) image->blob->eof);
875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879 + F i l e T o B l o b %
883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885 % FileToBlob() returns the contents of a file as a buffer terminated with
886 % the '\0' character. The length of the buffer (not including the extra
887 % terminating '\0' character) is returned via the 'length' parameter. Free
888 % the buffer with RelinquishMagickMemory().
890 % The format of the FileToBlob method is:
892 % unsigned char *FileToBlob(const char *filename,const size_t extent,
893 % size_t *length,ExceptionInfo *exception)
895 % A description of each parameter follows:
897 % o blob: FileToBlob() returns the contents of a file as a blob. If
898 % an error occurs NULL is returned.
900 % o filename: the filename.
902 % o extent: The maximum length of the blob.
904 % o length: On return, this reflects the actual length of the blob.
906 % o exception: return any errors or warnings in this structure.
909 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
910 size_t *length,ExceptionInfo *exception)
930 assert(filename != (const char *) NULL);
931 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
932 assert(exception != (ExceptionInfo *) NULL);
935 if (LocaleCompare(filename,"-") != 0)
936 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
939 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
940 return((unsigned char *) NULL);
942 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
944 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
953 Stream is not seekable.
955 quantum=(size_t) MagickMaxBufferExtent;
956 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
957 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
958 MagickMaxBufferExtent);
959 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
960 for (i=0; blob != (unsigned char *) NULL; i+=count)
962 count=(ssize_t) read(file,blob+i,quantum);
969 if (~(1UL*i) < (quantum+1))
971 blob=(unsigned char *) RelinquishMagickMemory(blob);
974 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
976 if ((size_t) (i+count) >= extent)
979 if (LocaleCompare(filename,"-") != 0)
981 if (blob == (unsigned char *) NULL)
983 (void) ThrowMagickException(exception,GetMagickModule(),
984 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
985 return((unsigned char *) NULL);
989 blob=(unsigned char *) RelinquishMagickMemory(blob);
990 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
991 return((unsigned char *) NULL);
993 *length=(size_t) MagickMin(i+count,extent);
997 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
998 blob=(unsigned char *) NULL;
999 if (~(*length) >= (MaxTextExtent-1))
1000 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
1002 if (blob == (unsigned char *) NULL)
1005 (void) ThrowMagickException(exception,GetMagickModule(),
1006 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1007 return((unsigned char *) NULL);
1009 map=MapBlob(file,ReadMode,0,*length);
1010 if (map != (unsigned char *) NULL)
1012 (void) memcpy(blob,map,*length);
1013 (void) UnmapBlob(map,*length);
1017 (void) lseek(file,0,SEEK_SET);
1018 for (i=0; i < *length; i+=count)
1020 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1021 (MagickSizeType) SSIZE_MAX));
1032 blob=(unsigned char *) RelinquishMagickMemory(blob);
1033 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1034 return((unsigned char *) NULL);
1038 if (LocaleCompare(filename,"-") != 0)
1042 blob=(unsigned char *) RelinquishMagickMemory(blob);
1043 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1053 % F i l e T o I m a g e %
1057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1059 % FileToImage() write the contents of a file to an image.
1061 % The format of the FileToImage method is:
1063 % MagickBooleanType FileToImage(Image *,const char *filename)
1065 % A description of each parameter follows:
1067 % o image: the image.
1069 % o filename: the filename.
1073 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1074 const unsigned char *data)
1079 register unsigned char
1082 assert(image->blob != (BlobInfo *) NULL);
1083 if (image->blob->type != BlobStream)
1084 return(WriteBlob(image,length,data));
1085 assert(image->blob->type != UndefinedStream);
1086 assert(data != (void *) NULL);
1087 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1088 if (extent >= image->blob->extent)
1090 image->blob->quantum<<=1;
1091 extent=image->blob->extent+image->blob->quantum+length;
1092 if (SetBlobExtent(image,extent) == MagickFalse)
1095 q=image->blob->data+image->blob->offset;
1096 (void) memcpy(q,data,length);
1097 image->blob->offset+=length;
1098 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1099 image->blob->length=(size_t) image->blob->offset;
1100 return((ssize_t) length);
1103 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1104 ExceptionInfo *exception)
1122 assert(image != (const Image *) NULL);
1123 assert(image->signature == MagickSignature);
1124 assert(filename != (const char *) NULL);
1125 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1126 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1129 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1130 return(MagickFalse);
1132 quantum=(size_t) MagickMaxBufferExtent;
1133 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1134 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1135 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1136 if (blob == (unsigned char *) NULL)
1138 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1140 return(MagickFalse);
1144 count=(ssize_t) read(file,blob,quantum);
1151 length=(size_t) count;
1152 count=WriteBlobStream(image,length,blob);
1153 if (count != (ssize_t) length)
1155 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1161 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1162 blob=(unsigned char *) RelinquishMagickMemory(blob);
1167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1171 + G e t B l o b E r r o r %
1175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177 % GetBlobError() returns MagickTrue if the blob associated with the specified
1178 % image encountered an error.
1180 % The format of the GetBlobError method is:
1182 % MagickBooleanType GetBlobError(const Image *image)
1184 % A description of each parameter follows:
1186 % o image: the image.
1189 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1191 assert(image != (const Image *) NULL);
1192 assert(image->signature == MagickSignature);
1193 if (image->debug != MagickFalse)
1194 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1195 return(image->blob->status);
1199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1203 + G e t B l o b F i l e H a n d l e %
1207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1209 % GetBlobFileHandle() returns the file handle associated with the image blob.
1211 % The format of the GetBlobFile method is:
1213 % FILE *GetBlobFileHandle(const Image *image)
1215 % A description of each parameter follows:
1217 % o image: the image.
1220 MagickExport FILE *GetBlobFileHandle(const Image *image)
1222 assert(image != (const Image *) NULL);
1223 assert(image->signature == MagickSignature);
1224 return(image->blob->file);
1228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1232 + G e t B l o b I n f o %
1236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1238 % GetBlobInfo() initializes the BlobInfo structure.
1240 % The format of the GetBlobInfo method is:
1242 % void GetBlobInfo(BlobInfo *blob_info)
1244 % A description of each parameter follows:
1246 % o blob_info: Specifies a pointer to a BlobInfo structure.
1249 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1251 assert(blob_info != (BlobInfo *) NULL);
1252 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1253 blob_info->type=UndefinedStream;
1254 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1255 blob_info->properties.st_mtime=time((time_t *) NULL);
1256 blob_info->properties.st_ctime=time((time_t *) NULL);
1257 blob_info->debug=IsEventLogging();
1258 blob_info->reference_count=1;
1259 blob_info->semaphore=AllocateSemaphoreInfo();
1260 blob_info->signature=MagickSignature;
1264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1268 % G e t B l o b P r o p e r t i e s %
1272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1274 % GetBlobProperties() returns information about an image blob.
1276 % The format of the GetBlobProperties method is:
1278 % const struct stat *GetBlobProperties(const Image *image)
1280 % A description of each parameter follows:
1282 % o image: the image.
1285 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1287 assert(image != (Image *) NULL);
1288 assert(image->signature == MagickSignature);
1289 if (image->debug != MagickFalse)
1290 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1291 return(&image->blob->properties);
1295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1299 + G e t B l o b S i z e %
1303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1305 % GetBlobSize() returns the current length of the image file or blob; zero is
1306 % returned if the size cannot be determined.
1308 % The format of the GetBlobSize method is:
1310 % MagickSizeType GetBlobSize(const Image *image)
1312 % A description of each parameter follows:
1314 % o image: the image.
1317 MagickExport MagickSizeType GetBlobSize(const Image *image)
1322 assert(image != (Image *) NULL);
1323 assert(image->signature == MagickSignature);
1324 if (image->debug != MagickFalse)
1325 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1326 assert(image->blob != (BlobInfo *) NULL);
1328 switch (image->blob->type)
1330 case UndefinedStream:
1332 extent=image->blob->size;
1337 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1338 extent=(MagickSizeType) image->blob->properties.st_size;
1341 case StandardStream:
1344 extent=image->blob->size;
1353 status=GetPathAttributes(image->filename,&image->blob->properties);
1354 if (status != MagickFalse)
1355 extent=(MagickSizeType) image->blob->properties.st_size;
1362 extent=(MagickSizeType) image->blob->length;
1370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1374 + G e t B l o b S t r e a m D a t a %
1378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1380 % GetBlobStreamData() returns the stream data for the image.
1382 % The format of the GetBlobStreamData method is:
1384 % unsigned char *GetBlobStreamData(const Image *image)
1386 % A description of each parameter follows:
1388 % o image: the image.
1391 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1393 assert(image != (const Image *) NULL);
1394 assert(image->signature == MagickSignature);
1395 return(image->blob->data);
1399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1403 + G e t B l o b S t r e a m H a n d l e r %
1407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409 % GetBlobStreamHandler() returns the stream handler for the image.
1411 % The format of the GetBlobStreamHandler method is:
1413 % StreamHandler GetBlobStreamHandler(const Image *image)
1415 % A description of each parameter follows:
1417 % o image: the image.
1420 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1422 assert(image != (const Image *) NULL);
1423 assert(image->signature == MagickSignature);
1424 if (image->debug != MagickFalse)
1425 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1426 return(image->blob->stream);
1430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1434 % I m a g e T o B l o b %
1438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1440 % ImageToBlob() implements direct to memory image formats. It returns the
1441 % image as a formatted blob and its length. The magick member of the Image
1442 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1443 % etc.). This method is the equivalent of WriteImage(), but writes the
1444 % formatted "file" to a memory buffer rather than to an actual file.
1446 % The format of the ImageToBlob method is:
1448 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1449 % size_t *length,ExceptionInfo *exception)
1451 % A description of each parameter follows:
1453 % o image_info: the image info.
1455 % o image: the image.
1457 % o length: This pointer to a size_t integer sets the initial length of the
1458 % blob. On return, it reflects the actual length of the blob.
1460 % o exception: return any errors or warnings in this structure.
1463 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1464 Image *image,size_t *length,ExceptionInfo *exception)
1478 assert(image_info != (const ImageInfo *) NULL);
1479 assert(image_info->signature == MagickSignature);
1480 if (image_info->debug != MagickFalse)
1481 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1482 image_info->filename);
1483 assert(image != (Image *) NULL);
1484 assert(image->signature == MagickSignature);
1485 assert(exception != (ExceptionInfo *) NULL);
1487 blob=(unsigned char *) NULL;
1488 blob_info=CloneImageInfo(image_info);
1489 blob_info->adjoin=MagickFalse;
1490 (void) SetImageInfo(blob_info,1,exception);
1491 if (*blob_info->magick != '\0')
1492 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1493 magick_info=GetMagickInfo(image->magick,exception);
1494 if (magick_info == (const MagickInfo *) NULL)
1496 (void) ThrowMagickException(exception,GetMagickModule(),
1497 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1501 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1502 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1505 Native blob support for this image format.
1507 blob_info->length=0;
1508 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1509 sizeof(unsigned char));
1510 if (blob_info->blob == (void *) NULL)
1511 (void) ThrowMagickException(exception,GetMagickModule(),
1512 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1515 (void) CloseBlob(image);
1516 image->blob->exempt=MagickTrue;
1517 *image->filename='\0';
1518 status=WriteImage(blob_info,image,exception);
1519 if ((status != MagickFalse) && (image->blob->length != 0))
1521 *length=image->blob->length;
1522 blob=DetachBlob(image->blob);
1523 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1531 unique[MaxTextExtent];
1537 Write file to disk in blob image format.
1539 file=AcquireUniqueFileResource(unique);
1542 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1543 image_info->filename);
1547 blob_info->file=fdopen(file,"wb");
1548 if (blob_info->file != (FILE *) NULL)
1550 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1551 image->magick,unique);
1552 status=WriteImage(blob_info,image,exception);
1553 (void) fclose(blob_info->file);
1554 if (status != MagickFalse)
1555 blob=FileToBlob(image->filename,~0UL,length,exception);
1557 (void) RelinquishUniqueFileResource(unique);
1560 blob_info=DestroyImageInfo(blob_info);
1565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1569 % I m a g e T o F i l e %
1573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1575 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1576 % occurs otherwise MagickTrue.
1578 % The format of the ImageToFile method is:
1580 % MagickBooleanType ImageToFile(Image *image,char *filename,
1581 % ExceptionInfo *exception)
1583 % A description of each parameter follows:
1585 % o image: the image.
1587 % o filename: Write the image to this file.
1589 % o exception: return any errors or warnings in this structure.
1592 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1593 ExceptionInfo *exception)
1598 register const unsigned char
1617 assert(image != (Image *) NULL);
1618 assert(image->signature == MagickSignature);
1619 assert(image->blob != (BlobInfo *) NULL);
1620 assert(image->blob->type != UndefinedStream);
1621 if (image->debug != MagickFalse)
1622 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1623 assert(filename != (const char *) NULL);
1624 if (*filename == '\0')
1625 file=AcquireUniqueFileResource(filename);
1627 if (LocaleCompare(filename,"-") == 0)
1628 file=fileno(stdout);
1630 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1633 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1634 return(MagickFalse);
1636 quantum=(size_t) MagickMaxBufferExtent;
1637 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1638 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
1639 MagickMaxBufferExtent);
1640 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1641 if (buffer == (unsigned char *) NULL)
1644 (void) ThrowMagickException(exception,GetMagickModule(),
1645 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1646 return(MagickFalse);
1649 p=ReadBlobStream(image,quantum,buffer,&count);
1650 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1652 length=(size_t) count;
1653 for (i=0; i < length; i+=count)
1655 count=write(file,p+i,(size_t) (length-i));
1666 if (LocaleCompare(filename,"-") != 0)
1668 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1669 if ((file == -1) || (i < length))
1671 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1672 return(MagickFalse);
1678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1682 % I m a g e s T o B l o b %
1686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1688 % ImagesToBlob() implements direct to memory image formats. It returns the
1689 % image sequence as a blob and its length. The magick member of the ImageInfo
1690 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1692 % Note, some image formats do not permit multiple images to the same image
1693 % stream (e.g. JPEG). in this instance, just the first image of the
1694 % sequence is returned as a blob.
1696 % The format of the ImagesToBlob method is:
1698 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1699 % size_t *length,ExceptionInfo *exception)
1701 % A description of each parameter follows:
1703 % o image_info: the image info.
1705 % o images: the image list.
1707 % o length: This pointer to a size_t integer sets the initial length of the
1708 % blob. On return, it reflects the actual length of the blob.
1710 % o exception: return any errors or warnings in this structure.
1713 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1714 Image *images,size_t *length,ExceptionInfo *exception)
1728 assert(image_info != (const ImageInfo *) NULL);
1729 assert(image_info->signature == MagickSignature);
1730 if (image_info->debug != MagickFalse)
1731 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1732 image_info->filename);
1733 assert(images != (Image *) NULL);
1734 assert(images->signature == MagickSignature);
1735 assert(exception != (ExceptionInfo *) NULL);
1737 blob=(unsigned char *) NULL;
1738 blob_info=CloneImageInfo(image_info);
1739 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1741 if (*blob_info->magick != '\0')
1742 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1743 if (blob_info->adjoin == MagickFalse)
1745 blob_info=DestroyImageInfo(blob_info);
1746 return(ImageToBlob(image_info,images,length,exception));
1748 magick_info=GetMagickInfo(images->magick,exception);
1749 if (magick_info == (const MagickInfo *) NULL)
1751 (void) ThrowMagickException(exception,GetMagickModule(),
1752 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1756 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1757 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1760 Native blob support for this images format.
1762 blob_info->length=0;
1763 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1764 sizeof(unsigned char));
1765 if (blob_info->blob == (void *) NULL)
1766 (void) ThrowMagickException(exception,GetMagickModule(),
1767 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1770 images->blob->exempt=MagickTrue;
1771 *images->filename='\0';
1772 status=WriteImages(blob_info,images,images->filename,exception);
1773 if ((status != MagickFalse) && (images->blob->length != 0))
1775 *length=images->blob->length;
1776 blob=DetachBlob(images->blob);
1777 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1785 filename[MaxTextExtent],
1786 unique[MaxTextExtent];
1792 Write file to disk in blob images format.
1794 file=AcquireUniqueFileResource(unique);
1797 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1798 image_info->filename);
1802 blob_info->file=fdopen(file,"wb");
1803 if (blob_info->file != (FILE *) NULL)
1805 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1806 images->magick,unique);
1807 status=WriteImages(blob_info,images,filename,exception);
1808 (void) fclose(blob_info->file);
1809 if (status != MagickFalse)
1810 blob=FileToBlob(images->filename,~0UL,length,exception);
1812 (void) RelinquishUniqueFileResource(unique);
1815 blob_info=DestroyImageInfo(blob_info);
1819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1823 % I n j e c t I m a g e B l o b %
1827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1829 % InjectImageBlob() injects the image with a copy of itself in the specified
1830 % format (e.g. inject JPEG into a PDF image).
1832 % The format of the InjectImageBlob method is:
1834 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1835 % Image *image,Image *inject_image,const char *format,
1836 % ExceptionInfo *exception)
1838 % A description of each parameter follows:
1840 % o image_info: the image info..
1842 % o image: the image.
1844 % o inject_image: inject into the image stream.
1846 % o format: the image format.
1848 % o exception: return any errors or warnings in this structure.
1851 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1852 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1855 filename[MaxTextExtent];
1888 Write inject image to a temporary file.
1890 assert(image_info != (ImageInfo *) NULL);
1891 assert(image_info->signature == MagickSignature);
1892 assert(image != (Image *) NULL);
1893 assert(image->signature == MagickSignature);
1894 if (image->debug != MagickFalse)
1895 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1896 assert(inject_image != (Image *) NULL);
1897 assert(inject_image->signature == MagickSignature);
1898 assert(exception != (ExceptionInfo *) NULL);
1899 unique_file=(FILE *) NULL;
1900 file=AcquireUniqueFileResource(filename);
1902 unique_file=fdopen(file,"wb");
1903 if ((file == -1) || (unique_file == (FILE *) NULL))
1905 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1906 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1908 return(MagickFalse);
1910 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1911 if (byte_image == (Image *) NULL)
1913 (void) fclose(unique_file);
1914 (void) RelinquishUniqueFileResource(filename);
1915 return(MagickFalse);
1917 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1919 DestroyBlob(byte_image);
1920 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1921 write_info=CloneImageInfo(image_info);
1922 SetImageInfoFile(write_info,unique_file);
1923 status=WriteImage(write_info,byte_image,exception);
1924 write_info=DestroyImageInfo(write_info);
1925 byte_image=DestroyImage(byte_image);
1926 (void) fclose(unique_file);
1927 if (status == MagickFalse)
1929 (void) RelinquishUniqueFileResource(filename);
1930 return(MagickFalse);
1933 Inject into image stream.
1935 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1938 (void) RelinquishUniqueFileResource(filename);
1939 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1940 image_info->filename);
1941 return(MagickFalse);
1943 quantum=(size_t) MagickMaxBufferExtent;
1944 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1945 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1946 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1947 if (buffer == (unsigned char *) NULL)
1949 (void) RelinquishUniqueFileResource(filename);
1950 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1953 for (i=0; ; i+=count)
1955 count=(ssize_t) read(file,buffer,quantum);
1962 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1967 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1968 (void) RelinquishUniqueFileResource(filename);
1969 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1978 + I s B l o b E x e m p t %
1982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1984 % IsBlobExempt() returns true if the blob is exempt.
1986 % The format of the IsBlobExempt method is:
1988 % MagickBooleanType IsBlobExempt(const Image *image)
1990 % A description of each parameter follows:
1992 % o image: the image.
1995 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
1997 assert(image != (const Image *) NULL);
1998 assert(image->signature == MagickSignature);
1999 if (image->debug != MagickFalse)
2000 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2001 return(image->blob->exempt);
2005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2009 + I s B l o b S e e k a b l e %
2013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2015 % IsBlobSeekable() returns true if the blob is seekable.
2017 % The format of the IsBlobSeekable method is:
2019 % MagickBooleanType IsBlobSeekable(const Image *image)
2021 % A description of each parameter follows:
2023 % o image: the image.
2026 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2031 assert(image != (const Image *) NULL);
2032 assert(image->signature == MagickSignature);
2033 if (image->debug != MagickFalse)
2034 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2035 switch (image->blob->type)
2041 seekable=MagickTrue;
2046 seekable=MagickFalse;
2054 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2058 + I s B l o b T e m p o r a r y %
2062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2064 % IsBlobTemporary() returns true if the blob is temporary.
2066 % The format of the IsBlobTemporary method is:
2068 % MagickBooleanType IsBlobTemporary(const Image *image)
2070 % A description of each parameter follows:
2072 % o image: the image.
2075 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2077 assert(image != (const Image *) NULL);
2078 assert(image->signature == MagickSignature);
2079 if (image->debug != MagickFalse)
2080 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2081 return(image->blob->temporary);
2085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2095 % MapBlob() creates a mapping from a file to a binary large object.
2097 % The format of the MapBlob method is:
2099 % unsigned char *MapBlob(int file,const MapMode mode,
2100 % const MagickOffsetType offset,const size_t length)
2102 % A description of each parameter follows:
2104 % o file: map this file descriptor.
2106 % o mode: ReadMode, WriteMode, or IOMode.
2108 % o offset: starting at this offset within the file.
2110 % o length: the length of the mapping is returned in this pointer.
2113 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2114 const MagickOffsetType offset,const size_t length)
2116 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2129 #if defined(MAP_ANONYMOUS)
2130 flags|=MAP_ANONYMOUS;
2132 return((unsigned char *) NULL);
2139 protection=PROT_READ;
2141 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2147 protection=PROT_WRITE;
2149 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2151 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2152 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2153 POSIX_MADV_WILLNEED);
2159 protection=PROT_READ | PROT_WRITE;
2161 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2166 if (map == (unsigned char *) MAP_FAILED)
2167 return((unsigned char *) NULL);
2174 return((unsigned char *) NULL);
2179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2183 + M S B O r d e r L o n g %
2187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2189 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2190 % most-significant byte first.
2192 % The format of the MSBOrderLong method is:
2194 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2196 % A description of each parameter follows.
2198 % o buffer: Specifies a pointer to a buffer of integers.
2200 % o length: Specifies the length of the buffer.
2203 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2208 register unsigned char
2212 assert(buffer != (unsigned char *) NULL);
2219 *buffer++=(unsigned char) c;
2223 *buffer++=(unsigned char) c;
2229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2233 + M S B O r d e r S h o r t %
2237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2239 % MSBOrderShort() converts a least-significant byte first buffer of integers
2240 % to most-significant byte first.
2242 % The format of the MSBOrderShort method is:
2244 % void MSBOrderShort(unsigned char *p,const size_t length)
2246 % A description of each parameter follows.
2248 % o p: Specifies a pointer to a buffer of integers.
2250 % o length: Specifies the length of the buffer.
2253 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2258 register unsigned char
2261 assert(p != (unsigned char *) NULL);
2268 *p++=(unsigned char) c;
2273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2283 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2284 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2285 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2286 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2287 % from a system command.
2289 % The format of the OpenBlob method is:
2291 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2292 % const BlobMode mode,ExceptionInfo *exception)
2294 % A description of each parameter follows:
2296 % o image_info: the image info.
2298 % o image: the image.
2300 % o mode: the mode for opening the file.
2303 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2304 Image *image,const BlobMode mode,ExceptionInfo *exception)
2307 extension[MaxTextExtent],
2308 filename[MaxTextExtent];
2319 assert(image_info != (ImageInfo *) NULL);
2320 assert(image_info->signature == MagickSignature);
2321 if (image_info->debug != MagickFalse)
2322 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2323 image_info->filename);
2324 assert(image != (Image *) NULL);
2325 assert(image->signature == MagickSignature);
2326 if (image_info->blob != (void *) NULL)
2328 if (image_info->stream != (StreamHandler) NULL)
2329 image->blob->stream=(StreamHandler) image_info->stream;
2330 AttachBlob(image->blob,image_info->blob,image_info->length);
2333 (void) DetachBlob(image->blob);
2336 default: type="r"; break;
2337 case ReadBlobMode: type="r"; break;
2338 case ReadBinaryBlobMode: type="rb"; break;
2339 case WriteBlobMode: type="w"; break;
2340 case WriteBinaryBlobMode: type="w+b"; break;
2341 case AppendBlobMode: type="a"; break;
2342 case AppendBinaryBlobMode: type="a+b"; break;
2345 image->blob->synchronize=image_info->synchronize;
2346 if (image_info->stream != (StreamHandler) NULL)
2348 image->blob->stream=(StreamHandler) image_info->stream;
2351 image->blob->type=FifoStream;
2359 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2360 rights=ReadPolicyRights;
2362 rights=WritePolicyRights;
2363 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2366 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2367 "NotAuthorized","`%s'",filename);
2368 return(MagickFalse);
2370 if ((LocaleCompare(filename,"-") == 0) ||
2371 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2373 image->blob->file=(*type == 'r') ? stdin : stdout;
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 (LocaleNCompare(filename,"fd:",3) == 0)
2385 mode[MaxTextExtent];
2389 image->blob->file=fdopen(StringToLong(filename+3),mode);
2390 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2391 if (strchr(type,'b') != (char *) NULL)
2392 setmode(_fileno(image->blob->file),_O_BINARY);
2394 image->blob->type=StandardStream;
2395 image->blob->exempt=MagickTrue;
2398 #if defined(MAGICKCORE_HAVE_POPEN)
2399 if (*filename == '|')
2402 mode[MaxTextExtent];
2405 Pipe image to or from a system command.
2407 #if defined(SIGPIPE)
2409 (void) signal(SIGPIPE,SIG_IGN);
2413 image->blob->file=(FILE *) popen_utf8(filename+1,mode);
2414 if (image->blob->file == (FILE *) NULL)
2416 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2417 return(MagickFalse);
2419 image->blob->type=PipeStream;
2420 image->blob->exempt=MagickTrue;
2424 status=GetPathAttributes(filename,&image->blob->properties);
2425 #if defined(S_ISFIFO)
2426 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2428 image->blob->file=(FILE *) fopen_utf8(filename,type);
2429 if (image->blob->file == (FILE *) NULL)
2431 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2432 return(MagickFalse);
2434 image->blob->type=FileStream;
2435 image->blob->exempt=MagickTrue;
2439 GetPathComponent(image->filename,ExtensionPath,extension);
2442 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2443 if ((image_info->adjoin == MagickFalse) ||
2444 (strchr(filename,'%') != (char *) NULL))
2447 Form filename for multi-part images.
2449 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2450 image->scene,filename,exception);
2451 if ((LocaleCompare(filename,image->filename) == 0) &&
2452 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2453 (GetNextImageInList(image) != (Image *) NULL)))
2456 path[MaxTextExtent];
2458 GetPathComponent(image->filename,RootPath,path);
2459 if (*extension == '\0')
2460 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2461 path,(double) image->scene);
2463 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2464 path,(double) image->scene,extension);
2466 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2467 #if defined(macintosh)
2468 SetApplicationType(filename,image_info->magick,'8BIM');
2472 if (image_info->file != (FILE *) NULL)
2474 image->blob->file=image_info->file;
2475 image->blob->type=FileStream;
2476 image->blob->exempt=MagickTrue;
2481 image->blob->file=(FILE *) fopen_utf8(filename,type);
2482 if (image->blob->file != (FILE *) NULL)
2490 image->blob->type=FileStream;
2491 #if defined(MAGICKCORE_HAVE_SETVBUF)
2492 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2494 (void) ResetMagickMemory(magick,0,sizeof(magick));
2495 count=fread(magick,1,sizeof(magick),image->blob->file);
2496 (void) rewind(image->blob->file);
2497 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2498 " read %.20g magic header bytes",(double) count);
2499 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2500 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2501 ((int) magick[2] == 0x08))
2503 (void) fclose(image->blob->file);
2504 image->blob->gzfile=gzopen(filename,type);
2505 if (image->blob->gzfile != (gzFile) NULL)
2506 image->blob->type=ZipStream;
2509 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2510 if (strncmp((char *) magick,"BZh",3) == 0)
2512 (void) fclose(image->blob->file);
2513 image->blob->bzfile=BZ2_bzopen(filename,type);
2514 if (image->blob->bzfile != (BZFILE *) NULL)
2515 image->blob->type=BZipStream;
2518 if (image->blob->type == FileStream)
2529 sans_exception=AcquireExceptionInfo();
2530 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2531 sans_exception=DestroyExceptionInfo(sans_exception);
2532 properties=(&image->blob->properties);
2533 if ((magick_info != (const MagickInfo *) NULL) &&
2534 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2535 (properties->st_size <= MagickMaxBufferExtent))
2543 length=(size_t) properties->st_size;
2544 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2545 if (blob != (void *) NULL)
2548 Format supports blobs-- use memory-mapped I/O.
2550 if (image_info->file != (FILE *) NULL)
2551 image->blob->exempt=MagickFalse;
2554 (void) fclose(image->blob->file);
2555 image->blob->file=(FILE *) NULL;
2557 AttachBlob(image->blob,blob,length);
2558 image->blob->mapped=MagickTrue;
2565 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2566 if ((LocaleCompare(extension,"Z") == 0) ||
2567 (LocaleCompare(extension,"gz") == 0) ||
2568 (LocaleCompare(extension,"wmz") == 0) ||
2569 (LocaleCompare(extension,"svgz") == 0))
2571 if (mode == WriteBinaryBlobMode)
2573 image->blob->gzfile=gzopen(filename,type);
2574 if (image->blob->gzfile != (gzFile) NULL)
2575 image->blob->type=ZipStream;
2579 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2580 if (LocaleCompare(extension,"bz2") == 0)
2582 image->blob->bzfile=BZ2_bzopen(filename,type);
2583 if (image->blob->bzfile != (BZFILE *) NULL)
2584 image->blob->type=BZipStream;
2589 image->blob->file=(FILE *) fopen_utf8(filename,type);
2590 if (image->blob->file != (FILE *) NULL)
2592 image->blob->type=FileStream;
2593 #if defined(MAGICKCORE_HAVE_SETVBUF)
2594 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2599 image->blob->status=MagickFalse;
2600 if (image->blob->type != UndefinedStream)
2601 image->blob->size=GetBlobSize(image);
2604 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2605 return(MagickFalse);
2611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2621 % PingBlob() returns all the attributes of an image or image sequence except
2622 % for the pixels. It is much faster and consumes far less memory than
2623 % BlobToImage(). On failure, a NULL image is returned and exception
2624 % describes the reason for the failure.
2626 % The format of the PingBlob method is:
2628 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2629 % const size_t length,ExceptionInfo *exception)
2631 % A description of each parameter follows:
2633 % o image_info: the image info.
2635 % o blob: the address of a character stream in one of the image formats
2636 % understood by ImageMagick.
2638 % o length: This size_t integer reflects the length in bytes of the blob.
2640 % o exception: return any errors or warnings in this structure.
2644 #if defined(__cplusplus) || defined(c_plusplus)
2648 static size_t PingStream(const Image *magick_unused(image),
2649 const void *magick_unused(pixels),const size_t columns)
2654 #if defined(__cplusplus) || defined(c_plusplus)
2658 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2659 const size_t length,ExceptionInfo *exception)
2667 assert(image_info != (ImageInfo *) NULL);
2668 assert(image_info->signature == MagickSignature);
2669 if (image_info->debug != MagickFalse)
2670 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2671 image_info->filename);
2672 assert(exception != (ExceptionInfo *) NULL);
2673 if ((blob == (const void *) NULL) || (length == 0))
2675 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2676 "UnrecognizedImageFormat","`%s'",image_info->magick);
2677 return((Image *) NULL);
2679 ping_info=CloneImageInfo(image_info);
2680 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2681 if (ping_info->blob == (const void *) NULL)
2683 (void) ThrowMagickException(exception,GetMagickModule(),
2684 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2685 return((Image *) NULL);
2687 (void) memcpy(ping_info->blob,blob,length);
2688 ping_info->length=length;
2689 ping_info->ping=MagickTrue;
2690 image=ReadStream(ping_info,&PingStream,exception);
2691 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2692 ping_info=DestroyImageInfo(ping_info);
2697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2707 % ReadBlob() reads data from the blob or image file and returns it. It
2708 % returns the number of bytes read.
2710 % The format of the ReadBlob method is:
2712 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2714 % A description of each parameter follows:
2716 % o image: the image.
2718 % o length: Specifies an integer representing the number of bytes to read
2721 % o data: Specifies an area to place the information requested from the
2725 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2726 unsigned char *data)
2731 register unsigned char
2737 assert(image != (Image *) NULL);
2738 assert(image->signature == MagickSignature);
2739 assert(image->blob != (BlobInfo *) NULL);
2740 assert(image->blob->type != UndefinedStream);
2743 assert(data != (void *) NULL);
2746 switch (image->blob->type)
2748 case UndefinedStream:
2751 case StandardStream:
2758 count=(ssize_t) fread(q,1,length,image->blob->file);
2763 c=getc(image->blob->file);
2766 *q++=(unsigned char) c;
2771 c=getc(image->blob->file);
2774 *q++=(unsigned char) c;
2784 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2789 count=(ssize_t) gzread(image->blob->gzfile,q,(unsigned int) length);
2794 c=gzgetc(image->blob->gzfile);
2797 *q++=(unsigned char) c;
2802 c=gzgetc(image->blob->gzfile);
2805 *q++=(unsigned char) c;
2816 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2817 count=(ssize_t) BZ2_bzread(image->blob->bzfile,q,(int) length);
2825 register const unsigned char
2828 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2830 image->blob->eof=MagickTrue;
2833 p=image->blob->data+image->blob->offset;
2834 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2835 image->blob->offset+=count;
2836 if (count != (ssize_t) length)
2837 image->blob->eof=MagickTrue;
2838 (void) memcpy(q,p,(size_t) count);
2846 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2850 + R e a d B l o b B y t e %
2854 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2856 % ReadBlobByte() reads a single byte from the image file and returns it.
2858 % The format of the ReadBlobByte method is:
2860 % int ReadBlobByte(Image *image)
2862 % A description of each parameter follows.
2864 % o image: the image.
2867 MagickExport int ReadBlobByte(Image *image)
2869 register const unsigned char
2878 assert(image != (Image *) NULL);
2879 assert(image->signature == MagickSignature);
2880 p=ReadBlobStream(image,1,buffer,&count);
2887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2891 + R e a d B l o b D o u b l e %
2895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2897 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2898 % specified by the endian member of the image structure.
2900 % The format of the ReadBlobDouble method is:
2902 % double ReadBlobDouble(Image *image)
2904 % A description of each parameter follows.
2906 % o image: the image.
2909 MagickExport double ReadBlobDouble(Image *image)
2920 quantum.double_value=0.0;
2921 quantum.unsigned_value=ReadBlobLongLong(image);
2922 return(quantum.double_value);
2926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2930 + R e a d B l o b F l o a t %
2934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2936 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2937 % specified by the endian member of the image structure.
2939 % The format of the ReadBlobFloat method is:
2941 % float ReadBlobFloat(Image *image)
2943 % A description of each parameter follows.
2945 % o image: the image.
2948 MagickExport float ReadBlobFloat(Image *image)
2959 quantum.float_value=0.0;
2960 quantum.unsigned_value=ReadBlobLong(image);
2961 return(quantum.float_value);
2965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2969 + R e a d B l o b L o n g %
2973 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2975 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2976 % specified by the endian member of the image structure.
2978 % The format of the ReadBlobLong method is:
2980 % unsigned int ReadBlobLong(Image *image)
2982 % A description of each parameter follows.
2984 % o image: the image.
2987 MagickExport unsigned int ReadBlobLong(Image *image)
2989 register const unsigned char
3001 assert(image != (Image *) NULL);
3002 assert(image->signature == MagickSignature);
3004 p=ReadBlobStream(image,4,buffer,&count);
3007 if (image->endian == LSBEndian)
3009 value=(unsigned int) (*p++);
3010 value|=((unsigned int) (*p++)) << 8;
3011 value|=((unsigned int) (*p++)) << 16;
3012 value|=((unsigned int) (*p++)) << 24;
3015 value=((unsigned int) (*p++)) << 24;
3016 value|=((unsigned int) (*p++)) << 16;
3017 value|=((unsigned int) (*p++)) << 8;
3018 value|=((unsigned int) (*p++));
3023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3027 + R e a d B l o b L o n g L o n g %
3031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3033 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3034 % byte-order specified by the endian member of the image structure.
3036 % The format of the ReadBlobLongLong method is:
3038 % MagickSizeType ReadBlobLongLong(Image *image)
3040 % A description of each parameter follows.
3042 % o image: the image.
3045 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3050 register const unsigned char
3059 assert(image != (Image *) NULL);
3060 assert(image->signature == MagickSignature);
3062 p=ReadBlobStream(image,8,buffer,&count);
3064 return(MagickULLConstant(0));
3065 if (image->endian == LSBEndian)
3067 value=(MagickSizeType) (*p++);
3068 value|=((MagickSizeType) (*p++)) << 8;
3069 value|=((MagickSizeType) (*p++)) << 16;
3070 value|=((MagickSizeType) (*p++)) << 24;
3071 value|=((MagickSizeType) (*p++)) << 32;
3072 value|=((MagickSizeType) (*p++)) << 40;
3073 value|=((MagickSizeType) (*p++)) << 48;
3074 value|=((MagickSizeType) (*p++)) << 56;
3075 return(value & MagickULLConstant(0xffffffffffffffff));
3077 value=((MagickSizeType) (*p++)) << 56;
3078 value|=((MagickSizeType) (*p++)) << 48;
3079 value|=((MagickSizeType) (*p++)) << 40;
3080 value|=((MagickSizeType) (*p++)) << 32;
3081 value|=((MagickSizeType) (*p++)) << 24;
3082 value|=((MagickSizeType) (*p++)) << 16;
3083 value|=((MagickSizeType) (*p++)) << 8;
3084 value|=((MagickSizeType) (*p++));
3085 return(value & MagickULLConstant(0xffffffffffffffff));
3089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3093 + R e a d B l o b S h o r t %
3097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3099 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3100 % specified by the endian member of the image structure.
3102 % The format of the ReadBlobShort method is:
3104 % unsigned short ReadBlobShort(Image *image)
3106 % A description of each parameter follows.
3108 % o image: the image.
3111 MagickExport unsigned short ReadBlobShort(Image *image)
3113 register const unsigned char
3116 register unsigned int
3125 assert(image != (Image *) NULL);
3126 assert(image->signature == MagickSignature);
3128 p=ReadBlobStream(image,2,buffer,&count);
3130 return((unsigned short) 0U);
3131 if (image->endian == LSBEndian)
3133 value=(unsigned int) (*p++);
3134 value|=((unsigned int) (*p++)) << 8;
3135 return((unsigned short) (value & 0xffff));
3137 value=(unsigned int) ((*p++) << 8);
3138 value|=(unsigned int) (*p++);
3139 return((unsigned short) (value & 0xffff));
3143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3147 + R e a d B l o b L S B L o n g %
3151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3153 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3154 % least-significant byte first order.
3156 % The format of the ReadBlobLSBLong method is:
3158 % unsigned int ReadBlobLSBLong(Image *image)
3160 % A description of each parameter follows.
3162 % o image: the image.
3165 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3167 register const unsigned char
3170 register unsigned int
3179 assert(image != (Image *) NULL);
3180 assert(image->signature == MagickSignature);
3182 p=ReadBlobStream(image,4,buffer,&count);
3185 value=(unsigned int) (*p++);
3186 value|=((unsigned int) (*p++)) << 8;
3187 value|=((unsigned int) (*p++)) << 16;
3188 value|=((unsigned int) (*p++)) << 24;
3193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3197 + R e a d B l o b L S B S h o r t %
3201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3203 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3204 % least-significant byte first order.
3206 % The format of the ReadBlobLSBShort method is:
3208 % unsigned short ReadBlobLSBShort(Image *image)
3210 % A description of each parameter follows.
3212 % o image: the image.
3215 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3217 register const unsigned char
3220 register unsigned int
3229 assert(image != (Image *) NULL);
3230 assert(image->signature == MagickSignature);
3232 p=ReadBlobStream(image,2,buffer,&count);
3234 return((unsigned short) 0U);
3235 value=(unsigned int) (*p++);
3236 value|=((unsigned int) ((*p++)) << 8);
3237 return((unsigned short) (value & 0xffff));
3241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3245 + R e a d B l o b M S B L o n g %
3249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3251 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3252 % most-significant byte first order.
3254 % The format of the ReadBlobMSBLong method is:
3256 % unsigned int ReadBlobMSBLong(Image *image)
3258 % A description of each parameter follows.
3260 % o image: the image.
3263 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3265 register const unsigned char
3268 register unsigned int
3277 assert(image != (Image *) NULL);
3278 assert(image->signature == MagickSignature);
3280 p=ReadBlobStream(image,4,buffer,&count);
3283 value=((unsigned int) (*p++) << 24);
3284 value|=((unsigned int) (*p++) << 16);
3285 value|=((unsigned int) (*p++) << 8);
3286 value|=(unsigned int) (*p++);
3291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3295 + R e a d B l o b M S B L o n g L o n g %
3299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3301 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3302 % most-significant byte first order.
3304 % The format of the ReadBlobMSBLongLong method is:
3306 % unsigned int ReadBlobMSBLongLong(Image *image)
3308 % A description of each parameter follows.
3310 % o image: the image.
3313 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3315 register const unsigned char
3318 register MagickSizeType
3327 assert(image != (Image *) NULL);
3328 assert(image->signature == MagickSignature);
3330 p=ReadBlobStream(image,8,buffer,&count);
3332 return(MagickULLConstant(0));
3333 value=((MagickSizeType) (*p++)) << 56;
3334 value|=((MagickSizeType) (*p++)) << 48;
3335 value|=((MagickSizeType) (*p++)) << 40;
3336 value|=((MagickSizeType) (*p++)) << 32;
3337 value|=((MagickSizeType) (*p++)) << 24;
3338 value|=((MagickSizeType) (*p++)) << 16;
3339 value|=((MagickSizeType) (*p++)) << 8;
3340 value|=((MagickSizeType) (*p++));
3341 return(value & MagickULLConstant(0xffffffffffffffff));
3345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3349 + R e a d B l o b M S B S h o r t %
3353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3355 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3356 % most-significant byte first order.
3358 % The format of the ReadBlobMSBShort method is:
3360 % unsigned short ReadBlobMSBShort(Image *image)
3362 % A description of each parameter follows.
3364 % o image: the image.
3367 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3369 register const unsigned char
3372 register unsigned int
3381 assert(image != (Image *) NULL);
3382 assert(image->signature == MagickSignature);
3384 p=ReadBlobStream(image,2,buffer,&count);
3386 return((unsigned short) 0U);
3387 value=(unsigned int) ((*p++) << 8);
3388 value|=(unsigned int) (*p++);
3389 return((unsigned short) (value & 0xffff));
3393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3397 + R e a d B l o b S t r i n g %
3401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3403 % ReadBlobString() reads characters from a blob or file until a newline
3404 % character is read or an end-of-file condition is encountered.
3406 % The format of the ReadBlobString method is:
3408 % char *ReadBlobString(Image *image,char *string)
3410 % A description of each parameter follows:
3412 % o image: the image.
3414 % o string: the address of a character buffer.
3417 MagickExport char *ReadBlobString(Image *image,char *string)
3419 register const unsigned char
3431 assert(image != (Image *) NULL);
3432 assert(image->signature == MagickSignature);
3433 for (i=0; i < (MaxTextExtent-1L); i++)
3435 p=ReadBlobStream(image,1,buffer,&count);
3439 return((char *) NULL);
3442 string[i]=(char) (*p);
3443 if ((string[i] == '\r') || (string[i] == '\n'))
3446 if (string[i] == '\r')
3447 (void) ReadBlobStream(image,1,buffer,&count);
3453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3457 + R e f e r e n c e B l o b %
3461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3463 % ReferenceBlob() increments the reference count associated with the pixel
3464 % blob returning a pointer to the blob.
3466 % The format of the ReferenceBlob method is:
3468 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3470 % A description of each parameter follows:
3472 % o blob_info: the blob_info.
3475 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3477 assert(blob != (BlobInfo *) NULL);
3478 assert(blob->signature == MagickSignature);
3479 if (blob->debug != MagickFalse)
3480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3481 LockSemaphoreInfo(blob->semaphore);
3482 blob->reference_count++;
3483 UnlockSemaphoreInfo(blob->semaphore);
3488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3498 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3499 % and returns the resulting offset.
3501 % The format of the SeekBlob method is:
3503 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3506 % A description of each parameter follows:
3508 % o image: the image.
3510 % o offset: Specifies an integer representing the offset in bytes.
3512 % o whence: Specifies an integer representing how the offset is
3513 % treated relative to the beginning of the blob as follows:
3515 % SEEK_SET Set position equal to offset bytes.
3516 % SEEK_CUR Set position to current location plus offset.
3517 % SEEK_END Set position to EOF plus offset.
3520 MagickExport MagickOffsetType SeekBlob(Image *image,
3521 const MagickOffsetType offset,const int whence)
3523 assert(image != (Image *) NULL);
3524 assert(image->signature == MagickSignature);
3525 if (image->debug != MagickFalse)
3526 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3527 assert(image->blob != (BlobInfo *) NULL);
3528 assert(image->blob->type != UndefinedStream);
3529 switch (image->blob->type)
3531 case UndefinedStream:
3535 if (fseek(image->blob->file,offset,whence) < 0)
3537 image->blob->offset=TellBlob(image);
3540 case StandardStream:
3544 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3545 if (gzseek(image->blob->gzfile,(off_t) offset,whence) < 0)
3548 image->blob->offset=TellBlob(image);
3564 image->blob->offset=offset;
3569 if ((image->blob->offset+offset) < 0)
3571 image->blob->offset+=offset;
3576 if (((MagickOffsetType) image->blob->length+offset) < 0)
3578 image->blob->offset=image->blob->length+offset;
3582 if (image->blob->offset <= (MagickOffsetType)
3583 ((off_t) image->blob->length))
3584 image->blob->eof=MagickFalse;
3586 if (image->blob->mapped != MagickFalse)
3590 image->blob->extent=(size_t) (image->blob->offset+
3591 image->blob->quantum);
3592 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3593 image->blob->data,image->blob->extent+1,
3594 sizeof(*image->blob->data));
3595 (void) SyncBlob(image);
3596 if (image->blob->data == (unsigned char *) NULL)
3598 (void) DetachBlob(image->blob);
3605 return(image->blob->offset);
3609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3613 + S e t B l o b E x e m p t %
3617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3619 % SetBlobExempt() sets the blob exempt status.
3621 % The format of the SetBlobExempt method is:
3623 % MagickBooleanType SetBlobExempt(const Image *image,
3624 % const MagickBooleanType exempt)
3626 % A description of each parameter follows:
3628 % o image: the image.
3630 % o exempt: Set to true if this blob is exempt from being closed.
3633 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3635 assert(image != (const Image *) NULL);
3636 assert(image->signature == MagickSignature);
3637 if (image->debug != MagickFalse)
3638 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3639 image->blob->exempt=exempt;
3643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3647 + S e t B l o b E x t e n t %
3651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3653 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3654 % method is successful, subsequent writes to bytes in the specified range are
3655 % guaranteed not to fail.
3657 % The format of the SetBlobExtent method is:
3659 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3661 % A description of each parameter follows:
3663 % o image: the image.
3665 % o extent: the blob maximum extent.
3668 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3669 const MagickSizeType extent)
3671 assert(image != (Image *) NULL);
3672 assert(image->signature == MagickSignature);
3673 if (image->debug != MagickFalse)
3674 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3675 assert(image->blob != (BlobInfo *) NULL);
3676 assert(image->blob->type != UndefinedStream);
3677 switch (image->blob->type)
3679 case UndefinedStream:
3683 if (extent != (MagickSizeType) ((off_t) extent))
3684 return(MagickFalse);
3685 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3686 return(MagickFalse);
3695 offset=TellBlob(image);
3696 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3697 (off_t) (extent-offset));
3699 return(MagickFalse);
3704 case StandardStream:
3707 return(MagickFalse);
3709 return(MagickFalse);
3711 return(MagickFalse);
3714 if (image->blob->mapped != MagickFalse)
3716 if (image->blob->file == (FILE *) NULL)
3717 return(MagickFalse);
3718 (void) UnmapBlob(image->blob->data,image->blob->length);
3719 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3720 return(MagickFalse);
3729 offset=TellBlob(image);
3730 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3731 (off_t) (extent-offset));
3733 return(MagickFalse);
3735 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3736 WriteMode,0,(size_t) extent);
3737 image->blob->extent=(size_t) extent;
3738 image->blob->length=(size_t) extent;
3739 (void) SyncBlob(image);
3743 if (extent != (MagickSizeType) ((size_t) extent))
3744 return(MagickFalse);
3745 image->blob->extent=(size_t) extent;
3746 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3747 image->blob->extent+1,sizeof(*image->blob->data));
3748 (void) SyncBlob(image);
3749 if (image->blob->data == (unsigned char *) NULL)
3751 (void) DetachBlob(image->blob);
3752 return(MagickFalse);
3761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3771 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3772 % attributes if it is an blob.
3774 % The format of the SyncBlob method is:
3776 % int SyncBlob(Image *image)
3778 % A description of each parameter follows:
3780 % o image: the image.
3783 static int SyncBlob(Image *image)
3788 assert(image != (Image *) NULL);
3789 assert(image->signature == MagickSignature);
3790 if (image->debug != MagickFalse)
3791 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3792 assert(image->blob != (BlobInfo *) NULL);
3793 assert(image->blob->type != UndefinedStream);
3795 switch (image->blob->type)
3797 case UndefinedStream:
3800 case StandardStream:
3803 status=fflush(image->blob->file);
3808 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3809 status=gzflush(image->blob->gzfile,Z_SYNC_FLUSH);
3815 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3816 status=BZ2_bzflush(image->blob->bzfile);
3824 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3825 if (image->blob->mapped != MagickFalse)
3826 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3845 % TellBlob() obtains the current value of the blob or file position.
3847 % The format of the TellBlob method is:
3849 % MagickOffsetType TellBlob(const Image *image)
3851 % A description of each parameter follows:
3853 % o image: the image.
3856 MagickExport MagickOffsetType TellBlob(const Image *image)
3861 assert(image != (Image *) NULL);
3862 assert(image->signature == MagickSignature);
3863 if (image->debug != MagickFalse)
3864 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3865 assert(image->blob != (BlobInfo *) NULL);
3866 assert(image->blob->type != UndefinedStream);
3868 switch (image->blob->type)
3870 case UndefinedStream:
3874 offset=ftell(image->blob->file);
3877 case StandardStream:
3882 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3883 offset=(MagickOffsetType) gztell(image->blob->gzfile);
3893 offset=image->blob->offset;
3901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3905 + U n m a p B l o b %
3909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3911 % UnmapBlob() deallocates the binary large object previously allocated with
3912 % the MapBlob method.
3914 % The format of the UnmapBlob method is:
3916 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3918 % A description of each parameter follows:
3920 % o map: the address of the binary large object.
3922 % o length: the length of the binary large object.
3925 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3927 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3931 status=munmap(map,length);
3932 return(status == -1 ? MagickFalse : MagickTrue);
3936 return(MagickFalse);
3941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3945 + W r i t e B l o b %
3949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3951 % WriteBlob() writes data to a blob or image file. It returns the number of
3954 % The format of the WriteBlob method is:
3956 % ssize_t WriteBlob(Image *image,const size_t length,
3957 % const unsigned char *data)
3959 % A description of each parameter follows:
3961 % o image: the image.
3963 % o length: Specifies an integer representing the number of bytes to
3964 % write to the file.
3966 % o data: The address of the data to write to the blob or file.
3969 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3970 const unsigned char *data)
3975 register const unsigned char
3981 assert(image != (Image *) NULL);
3982 assert(image->signature == MagickSignature);
3983 assert(data != (const unsigned char *) NULL);
3984 assert(image->blob != (BlobInfo *) NULL);
3985 assert(image->blob->type != UndefinedStream);
3990 switch (image->blob->type)
3992 case UndefinedStream:
3995 case StandardStream:
4002 count=(ssize_t) fwrite((const char *) data,1,length,
4008 c=putc((int) *p++,image->blob->file);
4015 c=putc((int) *p++,image->blob->file);
4027 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4032 count=(ssize_t) gzwrite(image->blob->gzfile,(void *) data,
4033 (unsigned int) length);
4038 c=gzputc(image->blob->gzfile,(int) *p++);
4045 c=gzputc(image->blob->gzfile,(int) *p++);
4058 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4059 count=(ssize_t) BZ2_bzwrite(image->blob->bzfile,(void *) data,(int)
4066 count=(ssize_t) image->blob->stream(image,data,length);
4071 register unsigned char
4074 if ((image->blob->offset+(MagickOffsetType) length) >=
4075 (MagickOffsetType) image->blob->extent)
4077 if (image->blob->mapped != MagickFalse)
4079 image->blob->quantum<<=1;
4080 image->blob->extent+=length+image->blob->quantum;
4081 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4082 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4083 (void) SyncBlob(image);
4084 if (image->blob->data == (unsigned char *) NULL)
4086 (void) DetachBlob(image->blob);
4090 q=image->blob->data+image->blob->offset;
4091 (void) memcpy(q,p,length);
4092 image->blob->offset+=length;
4093 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4094 image->blob->length=(size_t) image->blob->offset;
4095 count=(ssize_t) length;
4102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4106 + W r i t e B l o b B y t e %
4110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4112 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4113 % written (either 0 or 1);
4115 % The format of the WriteBlobByte method is:
4117 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4119 % A description of each parameter follows.
4121 % o image: the image.
4123 % o value: Specifies the value to write.
4126 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4128 assert(image != (Image *) NULL);
4129 assert(image->signature == MagickSignature);
4130 return(WriteBlobStream(image,1,&value));
4134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4138 + W r i t e B l o b F l o a t %
4142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4144 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4145 % specified by the endian member of the image structure.
4147 % The format of the WriteBlobFloat method is:
4149 % ssize_t WriteBlobFloat(Image *image,const float value)
4151 % A description of each parameter follows.
4153 % o image: the image.
4155 % o value: Specifies the value to write.
4158 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4169 quantum.unsigned_value=0U;
4170 quantum.float_value=value;
4171 return(WriteBlobLong(image,quantum.unsigned_value));
4175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4179 + W r i t e B l o b L o n g %
4183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4185 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4186 % specified by the endian member of the image structure.
4188 % The format of the WriteBlobLong method is:
4190 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4192 % A description of each parameter follows.
4194 % o image: the image.
4196 % o value: Specifies the value to write.
4199 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4204 assert(image != (Image *) NULL);
4205 assert(image->signature == MagickSignature);
4206 if (image->endian == LSBEndian)
4208 buffer[0]=(unsigned char) value;
4209 buffer[1]=(unsigned char) (value >> 8);
4210 buffer[2]=(unsigned char) (value >> 16);
4211 buffer[3]=(unsigned char) (value >> 24);
4212 return(WriteBlobStream(image,4,buffer));
4214 buffer[0]=(unsigned char) (value >> 24);
4215 buffer[1]=(unsigned char) (value >> 16);
4216 buffer[2]=(unsigned char) (value >> 8);
4217 buffer[3]=(unsigned char) value;
4218 return(WriteBlobStream(image,4,buffer));
4222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4226 + W r i t e B l o b S h o r t %
4230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4232 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4233 % byte-order specified by the endian member of the image structure.
4235 % The format of the WriteBlobShort method is:
4237 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4239 % A description of each parameter follows.
4241 % o image: the image.
4243 % o value: Specifies the value to write.
4246 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4251 assert(image != (Image *) NULL);
4252 assert(image->signature == MagickSignature);
4253 if (image->endian == LSBEndian)
4255 buffer[0]=(unsigned char) value;
4256 buffer[1]=(unsigned char) (value >> 8);
4257 return(WriteBlobStream(image,2,buffer));
4259 buffer[0]=(unsigned char) (value >> 8);
4260 buffer[1]=(unsigned char) value;
4261 return(WriteBlobStream(image,2,buffer));
4265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4269 + W r i t e B l o b L S B L o n g %
4273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4275 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4276 % least-significant byte first order.
4278 % The format of the WriteBlobLSBLong method is:
4280 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4282 % A description of each parameter follows.
4284 % o image: the image.
4286 % o value: Specifies the value to write.
4289 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4294 assert(image != (Image *) NULL);
4295 assert(image->signature == MagickSignature);
4296 buffer[0]=(unsigned char) value;
4297 buffer[1]=(unsigned char) (value >> 8);
4298 buffer[2]=(unsigned char) (value >> 16);
4299 buffer[3]=(unsigned char) (value >> 24);
4300 return(WriteBlobStream(image,4,buffer));
4304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4308 + W r i t e B l o b L S B S h o r t %
4312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4314 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4315 % least-significant byte first order.
4317 % The format of the WriteBlobLSBShort method is:
4319 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4321 % A description of each parameter follows.
4323 % o image: the image.
4325 % o value: Specifies the value to write.
4328 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4333 assert(image != (Image *) NULL);
4334 assert(image->signature == MagickSignature);
4335 buffer[0]=(unsigned char) value;
4336 buffer[1]=(unsigned char) (value >> 8);
4337 return(WriteBlobStream(image,2,buffer));
4341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4345 + W r i t e B l o b M S B L o n g %
4349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4351 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4352 % most-significant byte first order.
4354 % The format of the WriteBlobMSBLong method is:
4356 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4358 % A description of each parameter follows.
4360 % o value: Specifies the value to write.
4362 % o image: the image.
4365 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4370 assert(image != (Image *) NULL);
4371 assert(image->signature == MagickSignature);
4372 buffer[0]=(unsigned char) (value >> 24);
4373 buffer[1]=(unsigned char) (value >> 16);
4374 buffer[2]=(unsigned char) (value >> 8);
4375 buffer[3]=(unsigned char) value;
4376 return(WriteBlobStream(image,4,buffer));
4380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4384 + W r i t e B l o b M S B L o n g L o n g %
4388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4390 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4391 % most-significant byte first order.
4393 % The format of the WriteBlobMSBLongLong method is:
4395 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4397 % A description of each parameter follows.
4399 % o value: Specifies the value to write.
4401 % o image: the image.
4404 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4405 const MagickSizeType value)
4410 assert(image != (Image *) NULL);
4411 assert(image->signature == MagickSignature);
4412 buffer[0]=(unsigned char) (value >> 56);
4413 buffer[1]=(unsigned char) (value >> 48);
4414 buffer[2]=(unsigned char) (value >> 40);
4415 buffer[3]=(unsigned char) (value >> 32);
4416 buffer[4]=(unsigned char) (value >> 24);
4417 buffer[5]=(unsigned char) (value >> 16);
4418 buffer[6]=(unsigned char) (value >> 8);
4419 buffer[7]=(unsigned char) value;
4420 return(WriteBlobStream(image,8,buffer));
4424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4428 + W r i t e B l o b M S B S h o r t %
4432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4434 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4435 % most-significant byte first order.
4437 % The format of the WriteBlobMSBShort method is:
4439 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4441 % A description of each parameter follows.
4443 % o value: Specifies the value to write.
4445 % o file: Specifies the file to write the data to.
4448 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4453 assert(image != (Image *) NULL);
4454 assert(image->signature == MagickSignature);
4455 buffer[0]=(unsigned char) (value >> 8);
4456 buffer[1]=(unsigned char) value;
4457 return(WriteBlobStream(image,2,buffer));
4461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4465 + W r i t e B l o b S t r i n g %
4469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4471 % WriteBlobString() write a string to a blob. It returns the number of
4472 % characters written.
4474 % The format of the WriteBlobString method is:
4476 % ssize_t WriteBlobString(Image *image,const char *string)
4478 % A description of each parameter follows.
4480 % o image: the image.
4482 % o string: Specifies the string to write.
4485 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4487 assert(image != (Image *) NULL);
4488 assert(image->signature == MagickSignature);
4489 assert(string != (const char *) NULL);
4490 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));