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 seekable=(image->blob->type == FileStream) ||
2036 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2045 + I s B l o b T e m p o r a r y %
2049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2051 % IsBlobTemporary() returns true if the blob is temporary.
2053 % The format of the IsBlobTemporary method is:
2055 % MagickBooleanType IsBlobTemporary(const Image *image)
2057 % A description of each parameter follows:
2059 % o image: the image.
2062 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2064 assert(image != (const Image *) NULL);
2065 assert(image->signature == MagickSignature);
2066 if (image->debug != MagickFalse)
2067 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2068 return(image->blob->temporary);
2072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2082 % MapBlob() creates a mapping from a file to a binary large object.
2084 % The format of the MapBlob method is:
2086 % unsigned char *MapBlob(int file,const MapMode mode,
2087 % const MagickOffsetType offset,const size_t length)
2089 % A description of each parameter follows:
2091 % o file: map this file descriptor.
2093 % o mode: ReadMode, WriteMode, or IOMode.
2095 % o offset: starting at this offset within the file.
2097 % o length: the length of the mapping is returned in this pointer.
2100 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2101 const MagickOffsetType offset,const size_t length)
2103 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2116 #if defined(MAP_ANONYMOUS)
2117 flags|=MAP_ANONYMOUS;
2119 return((unsigned char *) NULL);
2126 protection=PROT_READ;
2128 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2134 protection=PROT_WRITE;
2136 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2138 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2139 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2140 POSIX_MADV_WILLNEED);
2146 protection=PROT_READ | PROT_WRITE;
2148 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2153 if (map == (unsigned char *) MAP_FAILED)
2154 return((unsigned char *) NULL);
2161 return((unsigned char *) NULL);
2166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2170 + M S B O r d e r L o n g %
2174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2176 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2177 % most-significant byte first.
2179 % The format of the MSBOrderLong method is:
2181 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2183 % A description of each parameter follows.
2185 % o buffer: Specifies a pointer to a buffer of integers.
2187 % o length: Specifies the length of the buffer.
2190 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2195 register unsigned char
2199 assert(buffer != (unsigned char *) NULL);
2206 *buffer++=(unsigned char) c;
2210 *buffer++=(unsigned char) c;
2216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2220 + M S B O r d e r S h o r t %
2224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2226 % MSBOrderShort() converts a least-significant byte first buffer of integers
2227 % to most-significant byte first.
2229 % The format of the MSBOrderShort method is:
2231 % void MSBOrderShort(unsigned char *p,const size_t length)
2233 % A description of each parameter follows.
2235 % o p: Specifies a pointer to a buffer of integers.
2237 % o length: Specifies the length of the buffer.
2240 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2245 register unsigned char
2248 assert(p != (unsigned char *) NULL);
2255 *p++=(unsigned char) c;
2260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2270 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2271 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2272 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2273 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2274 % from a system command.
2276 % The format of the OpenBlob method is:
2278 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2279 % const BlobMode mode,ExceptionInfo *exception)
2281 % A description of each parameter follows:
2283 % o image_info: the image info.
2285 % o image: the image.
2287 % o mode: the mode for opening the file.
2290 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2291 Image *image,const BlobMode mode,ExceptionInfo *exception)
2294 extension[MaxTextExtent],
2295 filename[MaxTextExtent];
2306 assert(image_info != (ImageInfo *) NULL);
2307 assert(image_info->signature == MagickSignature);
2308 if (image_info->debug != MagickFalse)
2309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2310 image_info->filename);
2311 assert(image != (Image *) NULL);
2312 assert(image->signature == MagickSignature);
2313 if (image_info->blob != (void *) NULL)
2315 if (image_info->stream != (StreamHandler) NULL)
2316 image->blob->stream=(StreamHandler) image_info->stream;
2317 AttachBlob(image->blob,image_info->blob,image_info->length);
2320 (void) DetachBlob(image->blob);
2323 default: type="r"; break;
2324 case ReadBlobMode: type="r"; break;
2325 case ReadBinaryBlobMode: type="rb"; break;
2326 case WriteBlobMode: type="w"; break;
2327 case WriteBinaryBlobMode: type="w+b"; break;
2328 case AppendBlobMode: type="a"; break;
2329 case AppendBinaryBlobMode: type="a+b"; break;
2332 image->blob->synchronize=image_info->synchronize;
2333 if (image_info->stream != (StreamHandler) NULL)
2335 image->blob->stream=(StreamHandler) image_info->stream;
2338 image->blob->type=FifoStream;
2346 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2347 rights=ReadPolicyRights;
2349 rights=WritePolicyRights;
2350 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2353 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2354 "NotAuthorized","`%s'",filename);
2355 return(MagickFalse);
2357 if ((LocaleCompare(filename,"-") == 0) ||
2358 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2360 image->blob->file=(*type == 'r') ? stdin : stdout;
2361 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2362 if (strchr(type,'b') != (char *) NULL)
2363 setmode(_fileno(image->blob->file),_O_BINARY);
2365 image->blob->type=StandardStream;
2366 image->blob->exempt=MagickTrue;
2369 if (LocaleNCompare(filename,"fd:",3) == 0)
2372 mode[MaxTextExtent];
2376 image->blob->file=fdopen(StringToLong(filename+3),mode);
2377 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2378 if (strchr(type,'b') != (char *) NULL)
2379 setmode(_fileno(image->blob->file),_O_BINARY);
2381 image->blob->type=StandardStream;
2382 image->blob->exempt=MagickTrue;
2385 #if defined(MAGICKCORE_HAVE_POPEN)
2386 if (*filename == '|')
2389 mode[MaxTextExtent];
2392 Pipe image to or from a system command.
2394 #if defined(SIGPIPE)
2396 (void) signal(SIGPIPE,SIG_IGN);
2400 image->blob->file=(FILE *) popen_utf8(filename+1,mode);
2401 if (image->blob->file == (FILE *) NULL)
2403 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2404 return(MagickFalse);
2406 image->blob->type=PipeStream;
2407 image->blob->exempt=MagickTrue;
2411 status=GetPathAttributes(filename,&image->blob->properties);
2412 #if defined(S_ISFIFO)
2413 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2415 image->blob->file=(FILE *) fopen_utf8(filename,type);
2416 if (image->blob->file == (FILE *) NULL)
2418 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2419 return(MagickFalse);
2421 image->blob->type=FileStream;
2422 image->blob->exempt=MagickTrue;
2426 GetPathComponent(image->filename,ExtensionPath,extension);
2429 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2430 if ((image_info->adjoin == MagickFalse) ||
2431 (strchr(filename,'%') != (char *) NULL))
2434 Form filename for multi-part images.
2436 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2437 image->scene,filename,exception);
2438 if ((LocaleCompare(filename,image->filename) == 0) &&
2439 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2440 (GetNextImageInList(image) != (Image *) NULL)))
2443 path[MaxTextExtent];
2445 GetPathComponent(image->filename,RootPath,path);
2446 if (*extension == '\0')
2447 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2448 path,(double) image->scene);
2450 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2451 path,(double) image->scene,extension);
2453 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2454 #if defined(macintosh)
2455 SetApplicationType(filename,image_info->magick,'8BIM');
2459 if (image_info->file != (FILE *) NULL)
2461 image->blob->file=image_info->file;
2462 image->blob->type=FileStream;
2463 image->blob->exempt=MagickTrue;
2468 image->blob->file=(FILE *) fopen_utf8(filename,type);
2469 if (image->blob->file != (FILE *) NULL)
2477 image->blob->type=FileStream;
2478 #if defined(MAGICKCORE_HAVE_SETVBUF)
2479 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2481 (void) ResetMagickMemory(magick,0,sizeof(magick));
2482 count=fread(magick,1,sizeof(magick),image->blob->file);
2483 (void) rewind(image->blob->file);
2484 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2485 " read %.20g magic header bytes",(double) count);
2486 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2487 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2488 ((int) magick[2] == 0x08))
2490 (void) fclose(image->blob->file);
2491 image->blob->gzfile=gzopen(filename,type);
2492 if (image->blob->gzfile != (gzFile) NULL)
2493 image->blob->type=ZipStream;
2496 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2497 if (strncmp((char *) magick,"BZh",3) == 0)
2499 (void) fclose(image->blob->file);
2500 image->blob->bzfile=BZ2_bzopen(filename,type);
2501 if (image->blob->bzfile != (BZFILE *) NULL)
2502 image->blob->type=BZipStream;
2505 if (image->blob->type == FileStream)
2516 sans_exception=AcquireExceptionInfo();
2517 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2518 sans_exception=DestroyExceptionInfo(sans_exception);
2519 properties=(&image->blob->properties);
2520 if ((magick_info != (const MagickInfo *) NULL) &&
2521 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2522 (properties->st_size <= MagickMaxBufferExtent))
2530 length=(size_t) properties->st_size;
2531 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2532 if (blob != (void *) NULL)
2535 Format supports blobs-- use memory-mapped I/O.
2537 if (image_info->file != (FILE *) NULL)
2538 image->blob->exempt=MagickFalse;
2541 (void) fclose(image->blob->file);
2542 image->blob->file=(FILE *) NULL;
2544 AttachBlob(image->blob,blob,length);
2545 image->blob->mapped=MagickTrue;
2552 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2553 if ((LocaleCompare(extension,"Z") == 0) ||
2554 (LocaleCompare(extension,"gz") == 0) ||
2555 (LocaleCompare(extension,"wmz") == 0) ||
2556 (LocaleCompare(extension,"svgz") == 0))
2558 if (mode == WriteBinaryBlobMode)
2560 image->blob->gzfile=gzopen(filename,type);
2561 if (image->blob->gzfile != (gzFile) NULL)
2562 image->blob->type=ZipStream;
2566 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2567 if (LocaleCompare(extension,".bz2") == 0)
2569 image->blob->bzfile=BZ2_bzopen(filename,type);
2570 if (image->blob->bzfile != (BZFILE *) NULL)
2571 image->blob->type=BZipStream;
2576 image->blob->file=(FILE *) fopen_utf8(filename,type);
2577 if (image->blob->file != (FILE *) NULL)
2579 image->blob->type=FileStream;
2580 #if defined(MAGICKCORE_HAVE_SETVBUF)
2581 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2586 image->blob->status=MagickFalse;
2587 if (image->blob->type != UndefinedStream)
2588 image->blob->size=GetBlobSize(image);
2591 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2592 return(MagickFalse);
2598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2608 % PingBlob() returns all the attributes of an image or image sequence except
2609 % for the pixels. It is much faster and consumes far less memory than
2610 % BlobToImage(). On failure, a NULL image is returned and exception
2611 % describes the reason for the failure.
2613 % The format of the PingBlob method is:
2615 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2616 % const size_t length,ExceptionInfo *exception)
2618 % A description of each parameter follows:
2620 % o image_info: the image info.
2622 % o blob: the address of a character stream in one of the image formats
2623 % understood by ImageMagick.
2625 % o length: This size_t integer reflects the length in bytes of the blob.
2627 % o exception: return any errors or warnings in this structure.
2631 #if defined(__cplusplus) || defined(c_plusplus)
2635 static size_t PingStream(const Image *magick_unused(image),
2636 const void *magick_unused(pixels),const size_t columns)
2641 #if defined(__cplusplus) || defined(c_plusplus)
2645 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2646 const size_t length,ExceptionInfo *exception)
2654 assert(image_info != (ImageInfo *) NULL);
2655 assert(image_info->signature == MagickSignature);
2656 if (image_info->debug != MagickFalse)
2657 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2658 image_info->filename);
2659 assert(exception != (ExceptionInfo *) NULL);
2660 if ((blob == (const void *) NULL) || (length == 0))
2662 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2663 "UnrecognizedImageFormat","`%s'",image_info->magick);
2664 return((Image *) NULL);
2666 ping_info=CloneImageInfo(image_info);
2667 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2668 if (ping_info->blob == (const void *) NULL)
2670 (void) ThrowMagickException(exception,GetMagickModule(),
2671 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2672 return((Image *) NULL);
2674 (void) memcpy(ping_info->blob,blob,length);
2675 ping_info->length=length;
2676 ping_info->ping=MagickTrue;
2677 image=ReadStream(ping_info,&PingStream,exception);
2678 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2679 ping_info=DestroyImageInfo(ping_info);
2684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2694 % ReadBlob() reads data from the blob or image file and returns it. It
2695 % returns the number of bytes read.
2697 % The format of the ReadBlob method is:
2699 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2701 % A description of each parameter follows:
2703 % o image: the image.
2705 % o length: Specifies an integer representing the number of bytes to read
2708 % o data: Specifies an area to place the information requested from the
2712 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2713 unsigned char *data)
2718 register unsigned char
2724 assert(image != (Image *) NULL);
2725 assert(image->signature == MagickSignature);
2726 assert(image->blob != (BlobInfo *) NULL);
2727 assert(image->blob->type != UndefinedStream);
2730 assert(data != (void *) NULL);
2733 switch (image->blob->type)
2735 case UndefinedStream:
2738 case StandardStream:
2745 count=(ssize_t) fread(q,1,length,image->blob->file);
2750 c=getc(image->blob->file);
2753 *q++=(unsigned char) c;
2758 c=getc(image->blob->file);
2761 *q++=(unsigned char) c;
2771 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2776 count=(ssize_t) gzread(image->blob->gzfile,q,(unsigned int) length);
2781 c=gzgetc(image->blob->gzfile);
2784 *q++=(unsigned char) c;
2789 c=gzgetc(image->blob->gzfile);
2792 *q++=(unsigned char) c;
2803 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2804 count=(ssize_t) BZ2_bzread(image->blob->bzfile,q,(int) length);
2812 register const unsigned char
2815 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2817 image->blob->eof=MagickTrue;
2820 p=image->blob->data+image->blob->offset;
2821 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2822 image->blob->offset+=count;
2823 if (count != (ssize_t) length)
2824 image->blob->eof=MagickTrue;
2825 (void) memcpy(q,p,(size_t) count);
2833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2837 + R e a d B l o b B y t e %
2841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2843 % ReadBlobByte() reads a single byte from the image file and returns it.
2845 % The format of the ReadBlobByte method is:
2847 % int ReadBlobByte(Image *image)
2849 % A description of each parameter follows.
2851 % o image: the image.
2854 MagickExport int ReadBlobByte(Image *image)
2856 register const unsigned char
2865 assert(image != (Image *) NULL);
2866 assert(image->signature == MagickSignature);
2867 p=ReadBlobStream(image,1,buffer,&count);
2874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2878 + R e a d B l o b D o u b l e %
2882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2884 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2885 % specified by the endian member of the image structure.
2887 % The format of the ReadBlobDouble method is:
2889 % double ReadBlobDouble(Image *image)
2891 % A description of each parameter follows.
2893 % o image: the image.
2896 MagickExport double ReadBlobDouble(Image *image)
2907 quantum.double_value=0.0;
2908 quantum.unsigned_value=ReadBlobLongLong(image);
2909 return(quantum.double_value);
2913 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2917 + R e a d B l o b F l o a t %
2921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2923 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2924 % specified by the endian member of the image structure.
2926 % The format of the ReadBlobFloat method is:
2928 % float ReadBlobFloat(Image *image)
2930 % A description of each parameter follows.
2932 % o image: the image.
2935 MagickExport float ReadBlobFloat(Image *image)
2946 quantum.float_value=0.0;
2947 quantum.unsigned_value=ReadBlobLong(image);
2948 return(quantum.float_value);
2952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2956 + R e a d B l o b L o n g %
2960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2962 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2963 % specified by the endian member of the image structure.
2965 % The format of the ReadBlobLong method is:
2967 % unsigned int ReadBlobLong(Image *image)
2969 % A description of each parameter follows.
2971 % o image: the image.
2974 MagickExport unsigned int ReadBlobLong(Image *image)
2976 register const unsigned char
2988 assert(image != (Image *) NULL);
2989 assert(image->signature == MagickSignature);
2991 p=ReadBlobStream(image,4,buffer,&count);
2994 if (image->endian == LSBEndian)
2996 value=(unsigned int) (*p++);
2997 value|=((unsigned int) (*p++)) << 8;
2998 value|=((unsigned int) (*p++)) << 16;
2999 value|=((unsigned int) (*p++)) << 24;
3002 value=((unsigned int) (*p++)) << 24;
3003 value|=((unsigned int) (*p++)) << 16;
3004 value|=((unsigned int) (*p++)) << 8;
3005 value|=((unsigned int) (*p++));
3010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3014 + R e a d B l o b L o n g L o n g %
3018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3020 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3021 % byte-order specified by the endian member of the image structure.
3023 % The format of the ReadBlobLongLong method is:
3025 % MagickSizeType ReadBlobLongLong(Image *image)
3027 % A description of each parameter follows.
3029 % o image: the image.
3032 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3037 register const unsigned char
3046 assert(image != (Image *) NULL);
3047 assert(image->signature == MagickSignature);
3049 p=ReadBlobStream(image,8,buffer,&count);
3051 return(MagickULLConstant(0));
3052 if (image->endian == LSBEndian)
3054 value=(MagickSizeType) (*p++);
3055 value|=((MagickSizeType) (*p++)) << 8;
3056 value|=((MagickSizeType) (*p++)) << 16;
3057 value|=((MagickSizeType) (*p++)) << 24;
3058 value|=((MagickSizeType) (*p++)) << 32;
3059 value|=((MagickSizeType) (*p++)) << 40;
3060 value|=((MagickSizeType) (*p++)) << 48;
3061 value|=((MagickSizeType) (*p++)) << 56;
3062 return(value & MagickULLConstant(0xffffffffffffffff));
3064 value=((MagickSizeType) (*p++)) << 56;
3065 value|=((MagickSizeType) (*p++)) << 48;
3066 value|=((MagickSizeType) (*p++)) << 40;
3067 value|=((MagickSizeType) (*p++)) << 32;
3068 value|=((MagickSizeType) (*p++)) << 24;
3069 value|=((MagickSizeType) (*p++)) << 16;
3070 value|=((MagickSizeType) (*p++)) << 8;
3071 value|=((MagickSizeType) (*p++));
3072 return(value & MagickULLConstant(0xffffffffffffffff));
3076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3080 + R e a d B l o b S h o r t %
3084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3086 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3087 % specified by the endian member of the image structure.
3089 % The format of the ReadBlobShort method is:
3091 % unsigned short ReadBlobShort(Image *image)
3093 % A description of each parameter follows.
3095 % o image: the image.
3098 MagickExport unsigned short ReadBlobShort(Image *image)
3100 register const unsigned char
3103 register unsigned int
3112 assert(image != (Image *) NULL);
3113 assert(image->signature == MagickSignature);
3115 p=ReadBlobStream(image,2,buffer,&count);
3117 return((unsigned short) 0U);
3118 if (image->endian == LSBEndian)
3120 value=(unsigned int) (*p++);
3121 value|=((unsigned int) (*p++)) << 8;
3122 return((unsigned short) (value & 0xffff));
3124 value=(unsigned int) ((*p++) << 8);
3125 value|=(unsigned int) (*p++);
3126 return((unsigned short) (value & 0xffff));
3130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3134 + R e a d B l o b L S B L o n g %
3138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3140 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3141 % least-significant byte first order.
3143 % The format of the ReadBlobLSBLong method is:
3145 % unsigned int ReadBlobLSBLong(Image *image)
3147 % A description of each parameter follows.
3149 % o image: the image.
3152 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3154 register const unsigned char
3157 register unsigned int
3166 assert(image != (Image *) NULL);
3167 assert(image->signature == MagickSignature);
3169 p=ReadBlobStream(image,4,buffer,&count);
3172 value=(unsigned int) (*p++);
3173 value|=((unsigned int) (*p++)) << 8;
3174 value|=((unsigned int) (*p++)) << 16;
3175 value|=((unsigned int) (*p++)) << 24;
3180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3184 + R e a d B l o b L S B S h o r t %
3188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3190 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3191 % least-significant byte first order.
3193 % The format of the ReadBlobLSBShort method is:
3195 % unsigned short ReadBlobLSBShort(Image *image)
3197 % A description of each parameter follows.
3199 % o image: the image.
3202 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3204 register const unsigned char
3207 register unsigned int
3216 assert(image != (Image *) NULL);
3217 assert(image->signature == MagickSignature);
3219 p=ReadBlobStream(image,2,buffer,&count);
3221 return((unsigned short) 0U);
3222 value=(unsigned int) (*p++);
3223 value|=((unsigned int) ((*p++)) << 8);
3224 return((unsigned short) (value & 0xffff));
3228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3232 + R e a d B l o b M S B L o n g %
3236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3238 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3239 % most-significant byte first order.
3241 % The format of the ReadBlobMSBLong method is:
3243 % unsigned int ReadBlobMSBLong(Image *image)
3245 % A description of each parameter follows.
3247 % o image: the image.
3250 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3252 register const unsigned char
3255 register unsigned int
3264 assert(image != (Image *) NULL);
3265 assert(image->signature == MagickSignature);
3267 p=ReadBlobStream(image,4,buffer,&count);
3270 value=((unsigned int) (*p++) << 24);
3271 value|=((unsigned int) (*p++) << 16);
3272 value|=((unsigned int) (*p++) << 8);
3273 value|=(unsigned int) (*p++);
3278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3282 + R e a d B l o b M S B L o n g L o n g %
3286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3288 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3289 % most-significant byte first order.
3291 % The format of the ReadBlobMSBLongLong method is:
3293 % unsigned int ReadBlobMSBLongLong(Image *image)
3295 % A description of each parameter follows.
3297 % o image: the image.
3300 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3302 register const unsigned char
3305 register MagickSizeType
3314 assert(image != (Image *) NULL);
3315 assert(image->signature == MagickSignature);
3317 p=ReadBlobStream(image,8,buffer,&count);
3319 return(MagickULLConstant(0));
3320 value=((MagickSizeType) (*p++)) << 56;
3321 value|=((MagickSizeType) (*p++)) << 48;
3322 value|=((MagickSizeType) (*p++)) << 40;
3323 value|=((MagickSizeType) (*p++)) << 32;
3324 value|=((MagickSizeType) (*p++)) << 24;
3325 value|=((MagickSizeType) (*p++)) << 16;
3326 value|=((MagickSizeType) (*p++)) << 8;
3327 value|=((MagickSizeType) (*p++));
3328 return(value & MagickULLConstant(0xffffffffffffffff));
3332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3336 + R e a d B l o b M S B S h o r t %
3340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3342 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3343 % most-significant byte first order.
3345 % The format of the ReadBlobMSBShort method is:
3347 % unsigned short ReadBlobMSBShort(Image *image)
3349 % A description of each parameter follows.
3351 % o image: the image.
3354 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3356 register const unsigned char
3359 register unsigned int
3368 assert(image != (Image *) NULL);
3369 assert(image->signature == MagickSignature);
3371 p=ReadBlobStream(image,2,buffer,&count);
3373 return((unsigned short) 0U);
3374 value=(unsigned int) ((*p++) << 8);
3375 value|=(unsigned int) (*p++);
3376 return((unsigned short) (value & 0xffff));
3380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3384 + R e a d B l o b S t r i n g %
3388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3390 % ReadBlobString() reads characters from a blob or file until a newline
3391 % character is read or an end-of-file condition is encountered.
3393 % The format of the ReadBlobString method is:
3395 % char *ReadBlobString(Image *image,char *string)
3397 % A description of each parameter follows:
3399 % o image: the image.
3401 % o string: the address of a character buffer.
3404 MagickExport char *ReadBlobString(Image *image,char *string)
3406 register const unsigned char
3418 assert(image != (Image *) NULL);
3419 assert(image->signature == MagickSignature);
3420 for (i=0; i < (MaxTextExtent-1L); i++)
3422 p=ReadBlobStream(image,1,buffer,&count);
3426 return((char *) NULL);
3429 string[i]=(char) (*p);
3430 if ((string[i] == '\r') || (string[i] == '\n'))
3433 if (string[i] == '\r')
3434 (void) ReadBlobStream(image,1,buffer,&count);
3440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3444 + R e f e r e n c e B l o b %
3448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3450 % ReferenceBlob() increments the reference count associated with the pixel
3451 % blob returning a pointer to the blob.
3453 % The format of the ReferenceBlob method is:
3455 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3457 % A description of each parameter follows:
3459 % o blob_info: the blob_info.
3462 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3464 assert(blob != (BlobInfo *) NULL);
3465 assert(blob->signature == MagickSignature);
3466 if (blob->debug != MagickFalse)
3467 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3468 LockSemaphoreInfo(blob->semaphore);
3469 blob->reference_count++;
3470 UnlockSemaphoreInfo(blob->semaphore);
3475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3485 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3486 % and returns the resulting offset.
3488 % The format of the SeekBlob method is:
3490 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3493 % A description of each parameter follows:
3495 % o image: the image.
3497 % o offset: Specifies an integer representing the offset in bytes.
3499 % o whence: Specifies an integer representing how the offset is
3500 % treated relative to the beginning of the blob as follows:
3502 % SEEK_SET Set position equal to offset bytes.
3503 % SEEK_CUR Set position to current location plus offset.
3504 % SEEK_END Set position to EOF plus offset.
3507 MagickExport MagickOffsetType SeekBlob(Image *image,
3508 const MagickOffsetType offset,const int whence)
3510 assert(image != (Image *) NULL);
3511 assert(image->signature == MagickSignature);
3512 if (image->debug != MagickFalse)
3513 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3514 assert(image->blob != (BlobInfo *) NULL);
3515 assert(image->blob->type != UndefinedStream);
3516 switch (image->blob->type)
3518 case UndefinedStream:
3522 if (fseek(image->blob->file,offset,whence) < 0)
3524 image->blob->offset=TellBlob(image);
3527 case StandardStream:
3531 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3532 if (gzseek(image->blob->gzfile,(off_t) offset,whence) < 0)
3535 image->blob->offset=TellBlob(image);
3551 image->blob->offset=offset;
3556 if ((image->blob->offset+offset) < 0)
3558 image->blob->offset+=offset;
3563 if (((MagickOffsetType) image->blob->length+offset) < 0)
3565 image->blob->offset=image->blob->length+offset;
3569 if (image->blob->offset <= (MagickOffsetType)
3570 ((off_t) image->blob->length))
3571 image->blob->eof=MagickFalse;
3573 if (image->blob->mapped != MagickFalse)
3577 image->blob->extent=(size_t) (image->blob->offset+
3578 image->blob->quantum);
3579 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3580 image->blob->data,image->blob->extent+1,
3581 sizeof(*image->blob->data));
3582 (void) SyncBlob(image);
3583 if (image->blob->data == (unsigned char *) NULL)
3585 (void) DetachBlob(image->blob);
3592 return(image->blob->offset);
3596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3600 + S e t B l o b E x e m p t %
3604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3606 % SetBlobExempt() sets the blob exempt status.
3608 % The format of the SetBlobExempt method is:
3610 % MagickBooleanType SetBlobExempt(const Image *image,
3611 % const MagickBooleanType exempt)
3613 % A description of each parameter follows:
3615 % o image: the image.
3617 % o exempt: Set to true if this blob is exempt from being closed.
3620 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3622 assert(image != (const Image *) NULL);
3623 assert(image->signature == MagickSignature);
3624 if (image->debug != MagickFalse)
3625 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3626 image->blob->exempt=exempt;
3630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3634 + S e t B l o b E x t e n t %
3638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3640 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3641 % method is successful, subsequent writes to bytes in the specified range are
3642 % guaranteed not to fail.
3644 % The format of the SetBlobExtent method is:
3646 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3648 % A description of each parameter follows:
3650 % o image: the image.
3652 % o extent: the blob maximum extent.
3655 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3656 const MagickSizeType extent)
3658 assert(image != (Image *) NULL);
3659 assert(image->signature == MagickSignature);
3660 if (image->debug != MagickFalse)
3661 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3662 assert(image->blob != (BlobInfo *) NULL);
3663 assert(image->blob->type != UndefinedStream);
3664 switch (image->blob->type)
3666 case UndefinedStream:
3670 if (extent != (MagickSizeType) ((off_t) extent))
3671 return(MagickFalse);
3672 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3673 return(MagickFalse);
3682 offset=TellBlob(image);
3683 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3684 (off_t) (extent-offset));
3686 return(MagickFalse);
3691 case StandardStream:
3694 return(MagickFalse);
3696 return(MagickFalse);
3698 return(MagickFalse);
3701 if (image->blob->mapped != MagickFalse)
3703 if (image->blob->file == (FILE *) NULL)
3704 return(MagickFalse);
3705 (void) UnmapBlob(image->blob->data,image->blob->length);
3706 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3707 return(MagickFalse);
3716 offset=TellBlob(image);
3717 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3718 (off_t) (extent-offset));
3720 return(MagickFalse);
3722 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3723 WriteMode,0,(size_t) extent);
3724 image->blob->extent=(size_t) extent;
3725 image->blob->length=(size_t) extent;
3726 (void) SyncBlob(image);
3730 if (extent != (MagickSizeType) ((size_t) extent))
3731 return(MagickFalse);
3732 image->blob->extent=(size_t) extent;
3733 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3734 image->blob->extent+1,sizeof(*image->blob->data));
3735 (void) SyncBlob(image);
3736 if (image->blob->data == (unsigned char *) NULL)
3738 (void) DetachBlob(image->blob);
3739 return(MagickFalse);
3748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3758 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3759 % attributes if it is an blob.
3761 % The format of the SyncBlob method is:
3763 % int SyncBlob(Image *image)
3765 % A description of each parameter follows:
3767 % o image: the image.
3770 static int SyncBlob(Image *image)
3775 assert(image != (Image *) NULL);
3776 assert(image->signature == MagickSignature);
3777 if (image->debug != MagickFalse)
3778 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3779 assert(image->blob != (BlobInfo *) NULL);
3780 assert(image->blob->type != UndefinedStream);
3782 switch (image->blob->type)
3784 case UndefinedStream:
3787 case StandardStream:
3790 status=fflush(image->blob->file);
3795 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3796 status=gzflush(image->blob->gzfile,Z_SYNC_FLUSH);
3802 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3803 status=BZ2_bzflush(image->blob->bzfile);
3811 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3812 if (image->blob->mapped != MagickFalse)
3813 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3832 % TellBlob() obtains the current value of the blob or file position.
3834 % The format of the TellBlob method is:
3836 % MagickOffsetType TellBlob(const Image *image)
3838 % A description of each parameter follows:
3840 % o image: the image.
3843 MagickExport MagickOffsetType TellBlob(const Image *image)
3848 assert(image != (Image *) NULL);
3849 assert(image->signature == MagickSignature);
3850 if (image->debug != MagickFalse)
3851 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3852 assert(image->blob != (BlobInfo *) NULL);
3853 assert(image->blob->type != UndefinedStream);
3855 switch (image->blob->type)
3857 case UndefinedStream:
3861 offset=ftell(image->blob->file);
3864 case StandardStream:
3869 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3870 offset=(MagickOffsetType) gztell(image->blob->gzfile);
3880 offset=image->blob->offset;
3888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3892 + U n m a p B l o b %
3896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3898 % UnmapBlob() deallocates the binary large object previously allocated with
3899 % the MapBlob method.
3901 % The format of the UnmapBlob method is:
3903 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3905 % A description of each parameter follows:
3907 % o map: the address of the binary large object.
3909 % o length: the length of the binary large object.
3912 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3914 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3918 status=munmap(map,length);
3919 return(status == -1 ? MagickFalse : MagickTrue);
3923 return(MagickFalse);
3928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3932 + W r i t e B l o b %
3936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3938 % WriteBlob() writes data to a blob or image file. It returns the number of
3941 % The format of the WriteBlob method is:
3943 % ssize_t WriteBlob(Image *image,const size_t length,
3944 % const unsigned char *data)
3946 % A description of each parameter follows:
3948 % o image: the image.
3950 % o length: Specifies an integer representing the number of bytes to
3951 % write to the file.
3953 % o data: The address of the data to write to the blob or file.
3956 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3957 const unsigned char *data)
3962 register const unsigned char
3968 assert(image != (Image *) NULL);
3969 assert(image->signature == MagickSignature);
3970 assert(data != (const unsigned char *) NULL);
3971 assert(image->blob != (BlobInfo *) NULL);
3972 assert(image->blob->type != UndefinedStream);
3977 switch (image->blob->type)
3979 case UndefinedStream:
3982 case StandardStream:
3989 count=(ssize_t) fwrite((const char *) data,1,length,
3995 c=putc((int) *p++,image->blob->file);
4002 c=putc((int) *p++,image->blob->file);
4014 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4019 count=(ssize_t) gzwrite(image->blob->gzfile,(void *) data,
4020 (unsigned int) length);
4025 c=gzputc(image->blob->gzfile,(int) *p++);
4032 c=gzputc(image->blob->gzfile,(int) *p++);
4045 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4046 count=(ssize_t) BZ2_bzwrite(image->blob->bzfile,(void *) data,(int)
4053 count=(ssize_t) image->blob->stream(image,data,length);
4058 register unsigned char
4061 if ((image->blob->offset+(MagickOffsetType) length) >=
4062 (MagickOffsetType) image->blob->extent)
4064 if (image->blob->mapped != MagickFalse)
4066 image->blob->quantum<<=1;
4067 image->blob->extent+=length+image->blob->quantum;
4068 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4069 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4070 (void) SyncBlob(image);
4071 if (image->blob->data == (unsigned char *) NULL)
4073 (void) DetachBlob(image->blob);
4077 q=image->blob->data+image->blob->offset;
4078 (void) memcpy(q,p,length);
4079 image->blob->offset+=length;
4080 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4081 image->blob->length=(size_t) image->blob->offset;
4082 count=(ssize_t) length;
4089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4093 + W r i t e B l o b B y t e %
4097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4099 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4100 % written (either 0 or 1);
4102 % The format of the WriteBlobByte method is:
4104 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4106 % A description of each parameter follows.
4108 % o image: the image.
4110 % o value: Specifies the value to write.
4113 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4115 assert(image != (Image *) NULL);
4116 assert(image->signature == MagickSignature);
4117 return(WriteBlobStream(image,1,&value));
4121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4125 + W r i t e B l o b F l o a t %
4129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4131 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4132 % specified by the endian member of the image structure.
4134 % The format of the WriteBlobFloat method is:
4136 % ssize_t WriteBlobFloat(Image *image,const float value)
4138 % A description of each parameter follows.
4140 % o image: the image.
4142 % o value: Specifies the value to write.
4145 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4156 quantum.unsigned_value=0U;
4157 quantum.float_value=value;
4158 return(WriteBlobLong(image,quantum.unsigned_value));
4162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4166 + W r i t e B l o b L o n g %
4170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4172 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4173 % specified by the endian member of the image structure.
4175 % The format of the WriteBlobLong method is:
4177 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4179 % A description of each parameter follows.
4181 % o image: the image.
4183 % o value: Specifies the value to write.
4186 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4191 assert(image != (Image *) NULL);
4192 assert(image->signature == MagickSignature);
4193 if (image->endian == LSBEndian)
4195 buffer[0]=(unsigned char) value;
4196 buffer[1]=(unsigned char) (value >> 8);
4197 buffer[2]=(unsigned char) (value >> 16);
4198 buffer[3]=(unsigned char) (value >> 24);
4199 return(WriteBlobStream(image,4,buffer));
4201 buffer[0]=(unsigned char) (value >> 24);
4202 buffer[1]=(unsigned char) (value >> 16);
4203 buffer[2]=(unsigned char) (value >> 8);
4204 buffer[3]=(unsigned char) value;
4205 return(WriteBlobStream(image,4,buffer));
4209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4213 + W r i t e B l o b S h o r t %
4217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4219 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4220 % byte-order specified by the endian member of the image structure.
4222 % The format of the WriteBlobShort method is:
4224 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4226 % A description of each parameter follows.
4228 % o image: the image.
4230 % o value: Specifies the value to write.
4233 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4238 assert(image != (Image *) NULL);
4239 assert(image->signature == MagickSignature);
4240 if (image->endian == LSBEndian)
4242 buffer[0]=(unsigned char) value;
4243 buffer[1]=(unsigned char) (value >> 8);
4244 return(WriteBlobStream(image,2,buffer));
4246 buffer[0]=(unsigned char) (value >> 8);
4247 buffer[1]=(unsigned char) value;
4248 return(WriteBlobStream(image,2,buffer));
4252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4256 + W r i t e B l o b L S B L o n g %
4260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4262 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4263 % least-significant byte first order.
4265 % The format of the WriteBlobLSBLong method is:
4267 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4269 % A description of each parameter follows.
4271 % o image: the image.
4273 % o value: Specifies the value to write.
4276 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4281 assert(image != (Image *) NULL);
4282 assert(image->signature == MagickSignature);
4283 buffer[0]=(unsigned char) value;
4284 buffer[1]=(unsigned char) (value >> 8);
4285 buffer[2]=(unsigned char) (value >> 16);
4286 buffer[3]=(unsigned char) (value >> 24);
4287 return(WriteBlobStream(image,4,buffer));
4291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4295 + W r i t e B l o b L S B S h o r t %
4299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4301 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4302 % least-significant byte first order.
4304 % The format of the WriteBlobLSBShort method is:
4306 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4308 % A description of each parameter follows.
4310 % o image: the image.
4312 % o value: Specifies the value to write.
4315 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4320 assert(image != (Image *) NULL);
4321 assert(image->signature == MagickSignature);
4322 buffer[0]=(unsigned char) value;
4323 buffer[1]=(unsigned char) (value >> 8);
4324 return(WriteBlobStream(image,2,buffer));
4328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4332 + W r i t e B l o b M S B L o n g %
4336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4338 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4339 % most-significant byte first order.
4341 % The format of the WriteBlobMSBLong method is:
4343 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4345 % A description of each parameter follows.
4347 % o value: Specifies the value to write.
4349 % o image: the image.
4352 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4357 assert(image != (Image *) NULL);
4358 assert(image->signature == MagickSignature);
4359 buffer[0]=(unsigned char) (value >> 24);
4360 buffer[1]=(unsigned char) (value >> 16);
4361 buffer[2]=(unsigned char) (value >> 8);
4362 buffer[3]=(unsigned char) value;
4363 return(WriteBlobStream(image,4,buffer));
4367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4371 + W r i t e B l o b M S B L o n g L o n g %
4375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4377 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4378 % most-significant byte first order.
4380 % The format of the WriteBlobMSBLongLong method is:
4382 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4384 % A description of each parameter follows.
4386 % o value: Specifies the value to write.
4388 % o image: the image.
4391 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4392 const MagickSizeType value)
4397 assert(image != (Image *) NULL);
4398 assert(image->signature == MagickSignature);
4399 buffer[0]=(unsigned char) (value >> 56);
4400 buffer[1]=(unsigned char) (value >> 48);
4401 buffer[2]=(unsigned char) (value >> 40);
4402 buffer[3]=(unsigned char) (value >> 32);
4403 buffer[4]=(unsigned char) (value >> 24);
4404 buffer[5]=(unsigned char) (value >> 16);
4405 buffer[6]=(unsigned char) (value >> 8);
4406 buffer[7]=(unsigned char) value;
4407 return(WriteBlobStream(image,8,buffer));
4411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4415 + W r i t e B l o b M S B S h o r t %
4419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4421 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4422 % most-significant byte first order.
4424 % The format of the WriteBlobMSBShort method is:
4426 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4428 % A description of each parameter follows.
4430 % o value: Specifies the value to write.
4432 % o file: Specifies the file to write the data to.
4435 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4440 assert(image != (Image *) NULL);
4441 assert(image->signature == MagickSignature);
4442 buffer[0]=(unsigned char) (value >> 8);
4443 buffer[1]=(unsigned char) value;
4444 return(WriteBlobStream(image,2,buffer));
4448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4452 + W r i t e B l o b S t r i n g %
4456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4458 % WriteBlobString() write a string to a blob. It returns the number of
4459 % characters written.
4461 % The format of the WriteBlobString method is:
4463 % ssize_t WriteBlobString(Image *image,const char *string)
4465 % A description of each parameter follows.
4467 % o image: the image.
4469 % o string: Specifies the string to write.
4472 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4474 assert(image != (Image *) NULL);
4475 assert(image->signature == MagickSignature);
4476 assert(string != (const char *) NULL);
4477 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));