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/nt-base-private.h"
45 #include "MagickCore/blob.h"
46 #include "MagickCore/blob-private.h"
47 #include "MagickCore/cache.h"
48 #include "MagickCore/client.h"
49 #include "MagickCore/constitute.h"
50 #include "MagickCore/delegate.h"
51 #include "MagickCore/exception.h"
52 #include "MagickCore/exception-private.h"
53 #include "MagickCore/image-private.h"
54 #include "MagickCore/list.h"
55 #include "MagickCore/locale_.h"
56 #include "MagickCore/log.h"
57 #include "MagickCore/magick.h"
58 #include "MagickCore/memory_.h"
59 #include "MagickCore/policy.h"
60 #include "MagickCore/resource_.h"
61 #include "MagickCore/semaphore.h"
62 #include "MagickCore/string_.h"
63 #include "MagickCore/string-private.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/utility.h"
66 #include "MagickCore/utility-private.h"
67 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
68 # include <sys/mman.h>
70 #if defined(MAGICKCORE_ZLIB_DELEGATE)
73 #if defined(MAGICKCORE_BZLIB_DELEGATE)
80 #define MagickMaxBlobExtent 65541
81 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
82 # define MAP_ANONYMOUS MAP_ANON
84 #if !defined(MAP_FAILED)
85 #define MAP_FAILED ((void *) -1)
92 #define _O_BINARY O_BINARY
128 #if defined(MAGICKCORE_ZLIB_DELEGATE)
133 #if defined(MAGICKCORE_BZLIB_DELEGATE)
162 Forward declarations.
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 + A t t a c h B l o b %
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178 % AttachBlob() attaches a blob to the BlobInfo structure.
180 % The format of the AttachBlob method is:
182 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
184 % A description of each parameter follows:
186 % o blob_info: Specifies a pointer to a BlobInfo structure.
188 % o blob: the address of a character stream in one of the image formats
189 % understood by ImageMagick.
191 % o length: This size_t integer reflects the length in bytes of the blob.
194 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
197 assert(blob_info != (BlobInfo *) NULL);
198 if (blob_info->debug != MagickFalse)
199 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
200 blob_info->length=length;
201 blob_info->extent=length;
202 blob_info->quantum=(size_t) MagickMaxBlobExtent;
204 blob_info->type=BlobStream;
205 blob_info->stream_info.file=(FILE *) NULL;
206 blob_info->data=(unsigned char *) blob;
207 blob_info->mapped=MagickFalse;
211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
215 + B l o b T o F i l e %
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
222 % occurs otherwise MagickTrue.
224 % The format of the BlobToFile method is:
226 % MagickBooleanType BlobToFile(char *filename,const void *blob,
227 % const size_t length,ExceptionInfo *exception)
229 % A description of each parameter follows:
231 % o filename: Write the blob to this file.
233 % o blob: the address of a blob.
235 % o length: This length in bytes of the blob.
237 % o exception: return any errors or warnings in this structure.
241 static inline MagickSizeType MagickMin(const MagickSizeType x,
242 const MagickSizeType y)
249 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
250 const size_t length,ExceptionInfo *exception)
261 assert(filename != (const char *) NULL);
262 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
263 assert(blob != (const void *) NULL);
264 if (*filename == '\0')
265 file=AcquireUniqueFileResource(filename);
267 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
270 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
273 for (i=0; i < length; i+=count)
275 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
276 i,(MagickSizeType) SSIZE_MAX));
285 if ((file == -1) || (i < length))
287 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298 % B l o b T o I m a g e %
302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
304 % BlobToImage() implements direct to memory image formats. It returns the
307 % The format of the BlobToImage method is:
309 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
310 % const size_t length,ExceptionInfo *exception)
312 % A description of each parameter follows:
314 % o image_info: the image info.
316 % o blob: the address of a character stream in one of the image formats
317 % understood by ImageMagick.
319 % o length: This size_t integer reflects the length in bytes of the blob.
321 % o exception: return any errors or warnings in this structure.
324 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
325 const size_t length,ExceptionInfo *exception)
340 assert(image_info != (ImageInfo *) NULL);
341 assert(image_info->signature == MagickSignature);
342 if (image_info->debug != MagickFalse)
343 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
344 image_info->filename);
345 assert(exception != (ExceptionInfo *) NULL);
346 if ((blob == (const void *) NULL) || (length == 0))
348 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
349 "ZeroLengthBlobNotPermitted","'%s'",image_info->filename);
350 return((Image *) NULL);
352 blob_info=CloneImageInfo(image_info);
353 blob_info->blob=(void *) blob;
354 blob_info->length=length;
355 if (*blob_info->magick == '\0')
356 (void) SetImageInfo(blob_info,0,exception);
357 magick_info=GetMagickInfo(blob_info->magick,exception);
358 if (magick_info == (const MagickInfo *) NULL)
360 blob_info=DestroyImageInfo(blob_info);
361 (void) ThrowMagickException(exception,GetMagickModule(),
362 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
363 image_info->filename);
364 return((Image *) NULL);
366 if (GetMagickBlobSupport(magick_info) != MagickFalse)
369 Native blob support for this image format.
371 (void) CopyMagickString(blob_info->filename,image_info->filename,
373 (void) CopyMagickString(blob_info->magick,image_info->magick,
375 image=ReadImage(blob_info,exception);
376 if (image != (Image *) NULL)
377 (void) DetachBlob(image->blob);
378 blob_info=DestroyImageInfo(blob_info);
382 Write blob to a temporary file on disk.
384 blob_info->blob=(void *) NULL;
386 *blob_info->filename='\0';
387 status=BlobToFile(blob_info->filename,blob,length,exception);
388 if (status == MagickFalse)
390 (void) RelinquishUniqueFileResource(blob_info->filename);
391 blob_info=DestroyImageInfo(blob_info);
392 return((Image *) NULL);
394 clone_info=CloneImageInfo(blob_info);
395 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
396 blob_info->magick,blob_info->filename);
397 image=ReadImage(clone_info,exception);
398 clone_info=DestroyImageInfo(clone_info);
399 (void) RelinquishUniqueFileResource(blob_info->filename);
400 blob_info=DestroyImageInfo(blob_info);
405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409 + C l o n e B l o b I n f o %
413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
416 % blob info is NULL, a new one.
418 % The format of the CloneBlobInfo method is:
420 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
422 % A description of each parameter follows:
424 % o blob_info: the blob info.
427 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
432 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
433 if (clone_info == (BlobInfo *) NULL)
434 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
435 GetBlobInfo(clone_info);
436 if (blob_info == (BlobInfo *) NULL)
438 clone_info->length=blob_info->length;
439 clone_info->extent=blob_info->extent;
440 clone_info->synchronize=blob_info->synchronize;
441 clone_info->quantum=blob_info->quantum;
442 clone_info->mapped=blob_info->mapped;
443 clone_info->eof=blob_info->eof;
444 clone_info->offset=blob_info->offset;
445 clone_info->size=blob_info->size;
446 clone_info->exempt=blob_info->exempt;
447 clone_info->status=blob_info->status;
448 clone_info->temporary=blob_info->temporary;
449 clone_info->type=blob_info->type;
450 clone_info->stream_info.file=blob_info->stream_info.file;
451 clone_info->properties=blob_info->properties;
452 clone_info->stream=blob_info->stream;
453 clone_info->data=blob_info->data;
454 clone_info->debug=IsEventLogging();
455 clone_info->reference_count=1;
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464 + C l o s e B l o b %
468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470 % CloseBlob() closes a stream associated with the image.
472 % The format of the CloseBlob method is:
474 % MagickBooleanType CloseBlob(Image *image)
476 % A description of each parameter follows:
478 % o image: the image.
481 MagickExport MagickBooleanType CloseBlob(Image *image)
489 assert(image != (Image *) NULL);
490 assert(image->signature == MagickSignature);
491 if (image->debug != MagickFalse)
492 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
493 assert(image->blob != (BlobInfo *) NULL);
494 if (image->blob->type == UndefinedStream)
496 if (image->blob->synchronize != MagickFalse)
498 image->blob->size=GetBlobSize(image);
499 image->extent=image->blob->size;
500 image->blob->eof=MagickFalse;
501 if (image->blob->exempt != MagickFalse)
503 image->blob->type=UndefinedStream;
507 switch (image->blob->type)
509 case UndefinedStream:
515 status=ferror(image->blob->stream_info.file);
520 #if defined(MAGICKCORE_ZLIB_DELEGATE)
521 (void) gzerror(image->blob->stream_info.gzfile,&status);
527 #if defined(MAGICKCORE_BZLIB_DELEGATE)
528 (void) BZ2_bzerror(image->blob->stream_info.bzfile,&status);
536 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
537 switch (image->blob->type)
539 case UndefinedStream:
544 if (image->blob->synchronize != MagickFalse)
546 status=fflush(image->blob->stream_info.file);
547 status=fsync(fileno(image->blob->stream_info.file));
549 status=fclose(image->blob->stream_info.file);
554 #if defined(MAGICKCORE_HAVE_PCLOSE)
555 status=pclose(image->blob->stream_info.file);
561 #if defined(MAGICKCORE_ZLIB_DELEGATE)
562 status=gzclose(image->blob->stream_info.gzfile);
568 #if defined(MAGICKCORE_BZLIB_DELEGATE)
569 BZ2_bzclose(image->blob->stream_info.bzfile);
577 if (image->blob->stream_info.file != (FILE *) NULL)
579 if (image->blob->synchronize != MagickFalse)
580 (void) fsync(fileno(image->blob->stream_info.file));
581 status=fclose(image->blob->stream_info.file);
586 (void) DetachBlob(image->blob);
587 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
588 return(image->blob->status);
592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 + D e s t r o y B l o b %
600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602 % DestroyBlob() deallocates memory associated with a blob.
604 % The format of the DestroyBlob method is:
606 % void DestroyBlob(Image *image)
608 % A description of each parameter follows:
610 % o image: the image.
613 MagickExport void DestroyBlob(Image *image)
618 assert(image != (Image *) NULL);
619 assert(image->signature == MagickSignature);
620 if (image->debug != MagickFalse)
621 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
622 assert(image->blob != (BlobInfo *) NULL);
623 assert(image->blob->signature == MagickSignature);
625 LockSemaphoreInfo(image->blob->semaphore);
626 image->blob->reference_count--;
627 assert(image->blob->reference_count >= 0);
628 if (image->blob->reference_count == 0)
630 UnlockSemaphoreInfo(image->blob->semaphore);
631 if (destroy == MagickFalse)
633 (void) CloseBlob(image);
634 if (image->blob->mapped != MagickFalse)
635 (void) UnmapBlob(image->blob->data,image->blob->length);
636 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
637 DestroySemaphoreInfo(&image->blob->semaphore);
638 image->blob->signature=(~MagickSignature);
639 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647 + D e t a c h B l o b %
651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653 % DetachBlob() detaches a blob from the BlobInfo structure.
655 % The format of the DetachBlob method is:
657 % unsigned char *DetachBlob(BlobInfo *blob_info)
659 % A description of each parameter follows:
661 % o blob_info: Specifies a pointer to a BlobInfo structure.
664 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
669 assert(blob_info != (BlobInfo *) NULL);
670 if (blob_info->debug != MagickFalse)
671 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
672 if (blob_info->mapped != MagickFalse)
673 (void) UnmapBlob(blob_info->data,blob_info->length);
674 blob_info->mapped=MagickFalse;
677 blob_info->eof=MagickFalse;
678 blob_info->exempt=MagickFalse;
679 blob_info->type=UndefinedStream;
680 blob_info->stream_info.file=(FILE *) NULL;
681 data=blob_info->data;
682 blob_info->data=(unsigned char *) NULL;
683 blob_info->stream=(StreamHandler) NULL;
688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692 + D i s c a r d B l o b B y t e s %
696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
698 % DiscardBlobBytes() discards bytes in a blob.
700 % The format of the DiscardBlobBytes method is:
702 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
704 % A description of each parameter follows.
706 % o image: the image.
708 % o length: the number of bytes to skip.
712 static inline const unsigned char *ReadBlobStream(Image *image,
713 const size_t length,unsigned char *data,ssize_t *count)
715 assert(count != (ssize_t *) NULL);
716 assert(image->blob != (BlobInfo *) NULL);
717 if (image->blob->type != BlobStream)
719 *count=ReadBlob(image,length,data);
722 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
725 image->blob->eof=MagickTrue;
728 data=image->blob->data+image->blob->offset;
729 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
730 image->blob->offset));
731 image->blob->offset+=(*count);
732 if (*count != (ssize_t) length)
733 image->blob->eof=MagickTrue;
737 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
738 const MagickSizeType length)
740 register MagickOffsetType
752 assert(image != (Image *) NULL);
753 assert(image->signature == MagickSignature);
755 for (i=0; i < (MagickOffsetType) length; i+=count)
757 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
758 (void) ReadBlobStream(image,quantum,buffer,&count);
766 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
774 + D u p l i c a t e s B l o b %
778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
780 % DuplicateBlob() duplicates a blob descriptor.
782 % The format of the DuplicateBlob method is:
784 % void DuplicateBlob(Image *image,const Image *duplicate)
786 % A description of each parameter follows:
788 % o image: the image.
790 % o duplicate: the duplicate image.
793 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
795 assert(image != (Image *) NULL);
796 assert(image->signature == MagickSignature);
797 if (image->debug != MagickFalse)
798 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
799 assert(duplicate != (Image *) NULL);
800 assert(duplicate->signature == MagickSignature);
802 image->blob=ReferenceBlob(duplicate->blob);
806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816 % EOFBlob() returns a non-zero value when EOF has been detected reading from
819 % The format of the EOFBlob method is:
821 % int EOFBlob(const Image *image)
823 % A description of each parameter follows:
825 % o image: the image.
828 MagickExport int EOFBlob(const Image *image)
830 assert(image != (Image *) NULL);
831 assert(image->signature == MagickSignature);
832 if (image->debug != MagickFalse)
833 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
834 assert(image->blob != (BlobInfo *) NULL);
835 assert(image->blob->type != UndefinedStream);
836 switch (image->blob->type)
838 case UndefinedStream:
844 image->blob->eof=feof(image->blob->stream_info.file) != 0 ? MagickTrue :
850 image->blob->eof=MagickFalse;
855 #if defined(MAGICKCORE_BZLIB_DELEGATE)
860 (void) BZ2_bzerror(image->blob->stream_info.bzfile,&status);
861 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
867 image->blob->eof=MagickFalse;
873 return((int) image->blob->eof);
877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881 + F i l e T o B l o b %
885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
887 % FileToBlob() returns the contents of a file as a buffer terminated with
888 % the '\0' character. The length of the buffer (not including the extra
889 % terminating '\0' character) is returned via the 'length' parameter. Free
890 % the buffer with RelinquishMagickMemory().
892 % The format of the FileToBlob method is:
894 % unsigned char *FileToBlob(const char *filename,const size_t extent,
895 % size_t *length,ExceptionInfo *exception)
897 % A description of each parameter follows:
899 % o blob: FileToBlob() returns the contents of a file as a blob. If
900 % an error occurs NULL is returned.
902 % o filename: the filename.
904 % o extent: The maximum length of the blob.
906 % o length: On return, this reflects the actual length of the blob.
908 % o exception: return any errors or warnings in this structure.
911 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
912 size_t *length,ExceptionInfo *exception)
932 assert(filename != (const char *) NULL);
933 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
934 assert(exception != (ExceptionInfo *) NULL);
937 if (LocaleCompare(filename,"-") != 0)
938 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
941 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
942 return((unsigned char *) NULL);
944 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
946 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
955 Stream is not seekable.
957 quantum=(size_t) MagickMaxBufferExtent;
958 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
959 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
960 MagickMaxBufferExtent);
961 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
962 for (i=0; blob != (unsigned char *) NULL; i+=count)
964 count=(ssize_t) read(file,blob+i,quantum);
971 if (~(1UL*i) < (quantum+1))
973 blob=(unsigned char *) RelinquishMagickMemory(blob);
976 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
978 if ((size_t) (i+count) >= extent)
981 if (LocaleCompare(filename,"-") != 0)
983 if (blob == (unsigned char *) NULL)
985 (void) ThrowMagickException(exception,GetMagickModule(),
986 ResourceLimitError,"MemoryAllocationFailed","'%s'",filename);
987 return((unsigned char *) NULL);
991 blob=(unsigned char *) RelinquishMagickMemory(blob);
992 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
993 return((unsigned char *) NULL);
995 *length=(size_t) MagickMin(i+count,extent);
999 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
1000 blob=(unsigned char *) NULL;
1001 if (~(*length) >= (MaxTextExtent-1))
1002 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
1004 if (blob == (unsigned char *) NULL)
1007 (void) ThrowMagickException(exception,GetMagickModule(),
1008 ResourceLimitError,"MemoryAllocationFailed","'%s'",filename);
1009 return((unsigned char *) NULL);
1011 map=MapBlob(file,ReadMode,0,*length);
1012 if (map != (unsigned char *) NULL)
1014 (void) memcpy(blob,map,*length);
1015 (void) UnmapBlob(map,*length);
1019 (void) lseek(file,0,SEEK_SET);
1020 for (i=0; i < *length; i+=count)
1022 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1023 (MagickSizeType) SSIZE_MAX));
1034 blob=(unsigned char *) RelinquishMagickMemory(blob);
1035 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1036 return((unsigned char *) NULL);
1040 if (LocaleCompare(filename,"-") != 0)
1044 blob=(unsigned char *) RelinquishMagickMemory(blob);
1045 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1055 % F i l e T o I m a g e %
1059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1061 % FileToImage() write the contents of a file to an image.
1063 % The format of the FileToImage method is:
1065 % MagickBooleanType FileToImage(Image *,const char *filename)
1067 % A description of each parameter follows:
1069 % o image: the image.
1071 % o filename: the filename.
1075 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1076 const unsigned char *data)
1081 register unsigned char
1084 assert(image->blob != (BlobInfo *) NULL);
1085 if (image->blob->type != BlobStream)
1086 return(WriteBlob(image,length,data));
1087 assert(image->blob->type != UndefinedStream);
1088 assert(data != (void *) NULL);
1089 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1090 if (extent >= image->blob->extent)
1092 image->blob->quantum<<=1;
1093 extent=image->blob->extent+image->blob->quantum+length;
1094 if (SetBlobExtent(image,extent) == MagickFalse)
1097 q=image->blob->data+image->blob->offset;
1098 (void) memcpy(q,data,length);
1099 image->blob->offset+=length;
1100 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1101 image->blob->length=(size_t) image->blob->offset;
1102 return((ssize_t) length);
1105 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1106 ExceptionInfo *exception)
1124 assert(image != (const Image *) NULL);
1125 assert(image->signature == MagickSignature);
1126 assert(filename != (const char *) NULL);
1127 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1128 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1131 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1132 return(MagickFalse);
1134 quantum=(size_t) MagickMaxBufferExtent;
1135 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1136 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1137 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1138 if (blob == (unsigned char *) NULL)
1140 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1142 return(MagickFalse);
1146 count=(ssize_t) read(file,blob,quantum);
1153 length=(size_t) count;
1154 count=WriteBlobStream(image,length,blob);
1155 if (count != (ssize_t) length)
1157 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1163 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1164 blob=(unsigned char *) RelinquishMagickMemory(blob);
1169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1173 + G e t B l o b E r r o r %
1177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1179 % GetBlobError() returns MagickTrue if the blob associated with the specified
1180 % image encountered an error.
1182 % The format of the GetBlobError method is:
1184 % MagickBooleanType GetBlobError(const Image *image)
1186 % A description of each parameter follows:
1188 % o image: the image.
1191 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1193 assert(image != (const Image *) NULL);
1194 assert(image->signature == MagickSignature);
1195 if (image->debug != MagickFalse)
1196 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1197 return(image->blob->status);
1201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1205 + G e t B l o b F i l e H a n d l e %
1209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1211 % GetBlobFileHandle() returns the file handle associated with the image blob.
1213 % The format of the GetBlobFile method is:
1215 % FILE *GetBlobFileHandle(const Image *image)
1217 % A description of each parameter follows:
1219 % o image: the image.
1222 MagickExport FILE *GetBlobFileHandle(const Image *image)
1224 assert(image != (const Image *) NULL);
1225 assert(image->signature == MagickSignature);
1226 return(image->blob->stream_info.file);
1230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1234 + G e t B l o b I n f o %
1238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1240 % GetBlobInfo() initializes the BlobInfo structure.
1242 % The format of the GetBlobInfo method is:
1244 % void GetBlobInfo(BlobInfo *blob_info)
1246 % A description of each parameter follows:
1248 % o blob_info: Specifies a pointer to a BlobInfo structure.
1251 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1253 assert(blob_info != (BlobInfo *) NULL);
1254 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1255 blob_info->type=UndefinedStream;
1256 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1257 blob_info->properties.st_mtime=time((time_t *) NULL);
1258 blob_info->properties.st_ctime=time((time_t *) NULL);
1259 blob_info->debug=IsEventLogging();
1260 blob_info->reference_count=1;
1261 blob_info->semaphore=AllocateSemaphoreInfo();
1262 blob_info->signature=MagickSignature;
1266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1270 % G e t B l o b P r o p e r t i e s %
1274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1276 % GetBlobProperties() returns information about an image blob.
1278 % The format of the GetBlobProperties method is:
1280 % const struct stat *GetBlobProperties(const Image *image)
1282 % A description of each parameter follows:
1284 % o image: the image.
1287 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1289 assert(image != (Image *) NULL);
1290 assert(image->signature == MagickSignature);
1291 if (image->debug != MagickFalse)
1292 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1293 return(&image->blob->properties);
1297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1301 + G e t B l o b S i z e %
1305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1307 % GetBlobSize() returns the current length of the image file or blob; zero is
1308 % returned if the size cannot be determined.
1310 % The format of the GetBlobSize method is:
1312 % MagickSizeType GetBlobSize(const Image *image)
1314 % A description of each parameter follows:
1316 % o image: the image.
1319 MagickExport MagickSizeType GetBlobSize(const Image *image)
1324 assert(image != (Image *) NULL);
1325 assert(image->signature == MagickSignature);
1326 if (image->debug != MagickFalse)
1327 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1328 assert(image->blob != (BlobInfo *) NULL);
1330 switch (image->blob->type)
1332 case UndefinedStream:
1334 extent=image->blob->size;
1339 if (fstat(fileno(image->blob->stream_info.file),&image->blob->properties) == 0)
1340 extent=(MagickSizeType) image->blob->properties.st_size;
1343 case StandardStream:
1346 extent=image->blob->size;
1355 status=GetPathAttributes(image->filename,&image->blob->properties);
1356 if (status != MagickFalse)
1357 extent=(MagickSizeType) image->blob->properties.st_size;
1364 extent=(MagickSizeType) image->blob->length;
1372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1376 + G e t B l o b S t r e a m D a t a %
1380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1382 % GetBlobStreamData() returns the stream data for the image.
1384 % The format of the GetBlobStreamData method is:
1386 % unsigned char *GetBlobStreamData(const Image *image)
1388 % A description of each parameter follows:
1390 % o image: the image.
1393 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1395 assert(image != (const Image *) NULL);
1396 assert(image->signature == MagickSignature);
1397 return(image->blob->data);
1401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1405 + G e t B l o b S t r e a m H a n d l e r %
1409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1411 % GetBlobStreamHandler() returns the stream handler for the image.
1413 % The format of the GetBlobStreamHandler method is:
1415 % StreamHandler GetBlobStreamHandler(const Image *image)
1417 % A description of each parameter follows:
1419 % o image: the image.
1422 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1424 assert(image != (const Image *) NULL);
1425 assert(image->signature == MagickSignature);
1426 if (image->debug != MagickFalse)
1427 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1428 return(image->blob->stream);
1432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1436 % I m a g e T o B l o b %
1440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1442 % ImageToBlob() implements direct to memory image formats. It returns the
1443 % image as a formatted blob and its length. The magick member of the Image
1444 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1445 % etc.). This method is the equivalent of WriteImage(), but writes the
1446 % formatted "file" to a memory buffer rather than to an actual file.
1448 % The format of the ImageToBlob method is:
1450 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1451 % size_t *length,ExceptionInfo *exception)
1453 % A description of each parameter follows:
1455 % o image_info: the image info.
1457 % o image: the image.
1459 % o length: This pointer to a size_t integer sets the initial length of the
1460 % blob. On return, it reflects the actual length of the blob.
1462 % o exception: return any errors or warnings in this structure.
1465 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1466 Image *image,size_t *length,ExceptionInfo *exception)
1480 assert(image_info != (const ImageInfo *) NULL);
1481 assert(image_info->signature == MagickSignature);
1482 if (image_info->debug != MagickFalse)
1483 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1484 image_info->filename);
1485 assert(image != (Image *) NULL);
1486 assert(image->signature == MagickSignature);
1487 assert(exception != (ExceptionInfo *) NULL);
1489 blob=(unsigned char *) NULL;
1490 blob_info=CloneImageInfo(image_info);
1491 blob_info->adjoin=MagickFalse;
1492 (void) SetImageInfo(blob_info,1,exception);
1493 if (*blob_info->magick != '\0')
1494 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1495 magick_info=GetMagickInfo(image->magick,exception);
1496 if (magick_info == (const MagickInfo *) NULL)
1498 (void) ThrowMagickException(exception,GetMagickModule(),
1499 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
1503 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1504 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1507 Native blob support for this image format.
1509 blob_info->length=0;
1510 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1511 sizeof(unsigned char));
1512 if (blob_info->blob == (void *) NULL)
1513 (void) ThrowMagickException(exception,GetMagickModule(),
1514 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
1517 (void) CloseBlob(image);
1518 image->blob->exempt=MagickTrue;
1519 *image->filename='\0';
1520 status=WriteImage(blob_info,image,exception);
1521 if ((status != MagickFalse) && (image->blob->length != 0))
1523 *length=image->blob->length;
1524 blob=DetachBlob(image->blob);
1525 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1533 unique[MaxTextExtent];
1539 Write file to disk in blob image format.
1541 file=AcquireUniqueFileResource(unique);
1544 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1545 image_info->filename);
1549 blob_info->file=fdopen(file,"wb");
1550 if (blob_info->file != (FILE *) NULL)
1552 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1553 image->magick,unique);
1554 status=WriteImage(blob_info,image,exception);
1555 (void) fclose(blob_info->file);
1556 if (status != MagickFalse)
1557 blob=FileToBlob(image->filename,~0UL,length,exception);
1559 (void) RelinquishUniqueFileResource(unique);
1562 blob_info=DestroyImageInfo(blob_info);
1567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1571 % I m a g e T o F i l e %
1575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1577 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1578 % occurs otherwise MagickTrue.
1580 % The format of the ImageToFile method is:
1582 % MagickBooleanType ImageToFile(Image *image,char *filename,
1583 % ExceptionInfo *exception)
1585 % A description of each parameter follows:
1587 % o image: the image.
1589 % o filename: Write the image to this file.
1591 % o exception: return any errors or warnings in this structure.
1594 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1595 ExceptionInfo *exception)
1600 register const unsigned char
1619 assert(image != (Image *) NULL);
1620 assert(image->signature == MagickSignature);
1621 assert(image->blob != (BlobInfo *) NULL);
1622 assert(image->blob->type != UndefinedStream);
1623 if (image->debug != MagickFalse)
1624 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1625 assert(filename != (const char *) NULL);
1626 if (*filename == '\0')
1627 file=AcquireUniqueFileResource(filename);
1629 if (LocaleCompare(filename,"-") == 0)
1630 file=fileno(stdout);
1632 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1635 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1636 return(MagickFalse);
1638 quantum=(size_t) MagickMaxBufferExtent;
1639 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1640 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
1641 MagickMaxBufferExtent);
1642 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1643 if (buffer == (unsigned char *) NULL)
1646 (void) ThrowMagickException(exception,GetMagickModule(),
1647 ResourceLimitError,"MemoryAllocationError","'%s'",filename);
1648 return(MagickFalse);
1651 p=ReadBlobStream(image,quantum,buffer,&count);
1652 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1654 length=(size_t) count;
1655 for (i=0; i < length; i+=count)
1657 count=write(file,p+i,(size_t) (length-i));
1668 if (LocaleCompare(filename,"-") != 0)
1670 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1671 if ((file == -1) || (i < length))
1673 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1674 return(MagickFalse);
1680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1684 % I m a g e s T o B l o b %
1688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1690 % ImagesToBlob() implements direct to memory image formats. It returns the
1691 % image sequence as a blob and its length. The magick member of the ImageInfo
1692 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1694 % Note, some image formats do not permit multiple images to the same image
1695 % stream (e.g. JPEG). in this instance, just the first image of the
1696 % sequence is returned as a blob.
1698 % The format of the ImagesToBlob method is:
1700 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1701 % size_t *length,ExceptionInfo *exception)
1703 % A description of each parameter follows:
1705 % o image_info: the image info.
1707 % o images: the image list.
1709 % o length: This pointer to a size_t integer sets the initial length of the
1710 % blob. On return, it reflects the actual length of the blob.
1712 % o exception: return any errors or warnings in this structure.
1715 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1716 Image *images,size_t *length,ExceptionInfo *exception)
1730 assert(image_info != (const ImageInfo *) NULL);
1731 assert(image_info->signature == MagickSignature);
1732 if (image_info->debug != MagickFalse)
1733 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1734 image_info->filename);
1735 assert(images != (Image *) NULL);
1736 assert(images->signature == MagickSignature);
1737 assert(exception != (ExceptionInfo *) NULL);
1739 blob=(unsigned char *) NULL;
1740 blob_info=CloneImageInfo(image_info);
1741 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1743 if (*blob_info->magick != '\0')
1744 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1745 if (blob_info->adjoin == MagickFalse)
1747 blob_info=DestroyImageInfo(blob_info);
1748 return(ImageToBlob(image_info,images,length,exception));
1750 magick_info=GetMagickInfo(images->magick,exception);
1751 if (magick_info == (const MagickInfo *) NULL)
1753 (void) ThrowMagickException(exception,GetMagickModule(),
1754 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","'%s'",
1758 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1759 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1762 Native blob support for this images format.
1764 blob_info->length=0;
1765 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1766 sizeof(unsigned char));
1767 if (blob_info->blob == (void *) NULL)
1768 (void) ThrowMagickException(exception,GetMagickModule(),
1769 ResourceLimitError,"MemoryAllocationFailed","'%s'",images->filename);
1772 images->blob->exempt=MagickTrue;
1773 *images->filename='\0';
1774 status=WriteImages(blob_info,images,images->filename,exception);
1775 if ((status != MagickFalse) && (images->blob->length != 0))
1777 *length=images->blob->length;
1778 blob=DetachBlob(images->blob);
1779 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1787 filename[MaxTextExtent],
1788 unique[MaxTextExtent];
1794 Write file to disk in blob images format.
1796 file=AcquireUniqueFileResource(unique);
1799 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1800 image_info->filename);
1804 blob_info->file=fdopen(file,"wb");
1805 if (blob_info->file != (FILE *) NULL)
1807 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1808 images->magick,unique);
1809 status=WriteImages(blob_info,images,filename,exception);
1810 (void) fclose(blob_info->file);
1811 if (status != MagickFalse)
1812 blob=FileToBlob(images->filename,~0UL,length,exception);
1814 (void) RelinquishUniqueFileResource(unique);
1817 blob_info=DestroyImageInfo(blob_info);
1821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1825 % I n j e c t I m a g e B l o b %
1829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1831 % InjectImageBlob() injects the image with a copy of itself in the specified
1832 % format (e.g. inject JPEG into a PDF image).
1834 % The format of the InjectImageBlob method is:
1836 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1837 % Image *image,Image *inject_image,const char *format,
1838 % ExceptionInfo *exception)
1840 % A description of each parameter follows:
1842 % o image_info: the image info..
1844 % o image: the image.
1846 % o inject_image: inject into the image stream.
1848 % o format: the image format.
1850 % o exception: return any errors or warnings in this structure.
1853 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1854 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1857 filename[MaxTextExtent];
1890 Write inject image to a temporary file.
1892 assert(image_info != (ImageInfo *) NULL);
1893 assert(image_info->signature == MagickSignature);
1894 assert(image != (Image *) NULL);
1895 assert(image->signature == MagickSignature);
1896 if (image->debug != MagickFalse)
1897 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1898 assert(inject_image != (Image *) NULL);
1899 assert(inject_image->signature == MagickSignature);
1900 assert(exception != (ExceptionInfo *) NULL);
1901 unique_file=(FILE *) NULL;
1902 file=AcquireUniqueFileResource(filename);
1904 unique_file=fdopen(file,"wb");
1905 if ((file == -1) || (unique_file == (FILE *) NULL))
1907 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1908 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1910 return(MagickFalse);
1912 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1913 if (byte_image == (Image *) NULL)
1915 (void) fclose(unique_file);
1916 (void) RelinquishUniqueFileResource(filename);
1917 return(MagickFalse);
1919 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1921 DestroyBlob(byte_image);
1922 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1923 write_info=CloneImageInfo(image_info);
1924 SetImageInfoFile(write_info,unique_file);
1925 status=WriteImage(write_info,byte_image,exception);
1926 write_info=DestroyImageInfo(write_info);
1927 byte_image=DestroyImage(byte_image);
1928 (void) fclose(unique_file);
1929 if (status == MagickFalse)
1931 (void) RelinquishUniqueFileResource(filename);
1932 return(MagickFalse);
1935 Inject into image stream.
1937 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1940 (void) RelinquishUniqueFileResource(filename);
1941 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1942 image_info->filename);
1943 return(MagickFalse);
1945 quantum=(size_t) MagickMaxBufferExtent;
1946 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1947 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1948 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1949 if (buffer == (unsigned char *) NULL)
1951 (void) RelinquishUniqueFileResource(filename);
1952 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1955 for (i=0; ; i+=count)
1957 count=(ssize_t) read(file,buffer,quantum);
1964 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1969 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1970 (void) RelinquishUniqueFileResource(filename);
1971 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1980 + I s B l o b E x e m p t %
1984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1986 % IsBlobExempt() returns true if the blob is exempt.
1988 % The format of the IsBlobExempt method is:
1990 % MagickBooleanType IsBlobExempt(const Image *image)
1992 % A description of each parameter follows:
1994 % o image: the image.
1997 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
1999 assert(image != (const Image *) NULL);
2000 assert(image->signature == MagickSignature);
2001 if (image->debug != MagickFalse)
2002 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2003 return(image->blob->exempt);
2007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2011 + I s B l o b S e e k a b l e %
2015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2017 % IsBlobSeekable() returns true if the blob is seekable.
2019 % The format of the IsBlobSeekable method is:
2021 % MagickBooleanType IsBlobSeekable(const Image *image)
2023 % A description of each parameter follows:
2025 % o image: the image.
2028 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2033 assert(image != (const Image *) NULL);
2034 assert(image->signature == MagickSignature);
2035 if (image->debug != MagickFalse)
2036 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2037 switch (image->blob->type)
2043 seekable=MagickTrue;
2048 seekable=MagickFalse;
2056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2060 + I s B l o b T e m p o r a r y %
2064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2066 % IsBlobTemporary() returns true if the blob is temporary.
2068 % The format of the IsBlobTemporary method is:
2070 % MagickBooleanType IsBlobTemporary(const Image *image)
2072 % A description of each parameter follows:
2074 % o image: the image.
2077 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2079 assert(image != (const Image *) NULL);
2080 assert(image->signature == MagickSignature);
2081 if (image->debug != MagickFalse)
2082 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2083 return(image->blob->temporary);
2087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2097 % MapBlob() creates a mapping from a file to a binary large object.
2099 % The format of the MapBlob method is:
2101 % unsigned char *MapBlob(int file,const MapMode mode,
2102 % const MagickOffsetType offset,const size_t length)
2104 % A description of each parameter follows:
2106 % o file: map this file descriptor.
2108 % o mode: ReadMode, WriteMode, or IOMode.
2110 % o offset: starting at this offset within the file.
2112 % o length: the length of the mapping is returned in this pointer.
2115 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2116 const MagickOffsetType offset,const size_t length)
2118 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2131 #if defined(MAP_ANONYMOUS)
2132 flags|=MAP_ANONYMOUS;
2134 return((unsigned char *) NULL);
2141 protection=PROT_READ;
2143 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2149 protection=PROT_WRITE;
2151 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2153 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2154 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2155 POSIX_MADV_WILLNEED);
2161 protection=PROT_READ | PROT_WRITE;
2163 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2168 if (map == (unsigned char *) MAP_FAILED)
2169 return((unsigned char *) NULL);
2176 return((unsigned char *) NULL);
2181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2185 + M S B O r d e r L o n g %
2189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2191 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2192 % most-significant byte first.
2194 % The format of the MSBOrderLong method is:
2196 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2198 % A description of each parameter follows.
2200 % o buffer: Specifies a pointer to a buffer of integers.
2202 % o length: Specifies the length of the buffer.
2205 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2210 register unsigned char
2214 assert(buffer != (unsigned char *) NULL);
2221 *buffer++=(unsigned char) c;
2225 *buffer++=(unsigned char) c;
2231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2235 + M S B O r d e r S h o r t %
2239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2241 % MSBOrderShort() converts a least-significant byte first buffer of integers
2242 % to most-significant byte first.
2244 % The format of the MSBOrderShort method is:
2246 % void MSBOrderShort(unsigned char *p,const size_t length)
2248 % A description of each parameter follows.
2250 % o p: Specifies a pointer to a buffer of integers.
2252 % o length: Specifies the length of the buffer.
2255 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2260 register unsigned char
2263 assert(p != (unsigned char *) NULL);
2270 *p++=(unsigned char) c;
2275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2285 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2286 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2287 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2288 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2289 % from a system command.
2291 % The format of the OpenBlob method is:
2293 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2294 % const BlobMode mode,ExceptionInfo *exception)
2296 % A description of each parameter follows:
2298 % o image_info: the image info.
2300 % o image: the image.
2302 % o mode: the mode for opening the file.
2305 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2306 Image *image,const BlobMode mode,ExceptionInfo *exception)
2309 extension[MaxTextExtent],
2310 filename[MaxTextExtent];
2321 assert(image_info != (ImageInfo *) NULL);
2322 assert(image_info->signature == MagickSignature);
2323 if (image_info->debug != MagickFalse)
2324 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2325 image_info->filename);
2326 assert(image != (Image *) NULL);
2327 assert(image->signature == MagickSignature);
2328 if (image_info->blob != (void *) NULL)
2330 if (image_info->stream != (StreamHandler) NULL)
2331 image->blob->stream=(StreamHandler) image_info->stream;
2332 AttachBlob(image->blob,image_info->blob,image_info->length);
2335 (void) DetachBlob(image->blob);
2338 default: type="r"; break;
2339 case ReadBlobMode: type="r"; break;
2340 case ReadBinaryBlobMode: type="rb"; break;
2341 case WriteBlobMode: type="w"; break;
2342 case WriteBinaryBlobMode: type="w+b"; break;
2343 case AppendBlobMode: type="a"; break;
2344 case AppendBinaryBlobMode: type="a+b"; break;
2347 image->blob->synchronize=image_info->synchronize;
2348 if (image_info->stream != (StreamHandler) NULL)
2350 image->blob->stream=(StreamHandler) image_info->stream;
2353 image->blob->type=FifoStream;
2361 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2362 rights=ReadPolicyRights;
2364 rights=WritePolicyRights;
2365 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2368 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2369 "NotAuthorized","'%s'",filename);
2370 return(MagickFalse);
2372 if ((LocaleCompare(filename,"-") == 0) ||
2373 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2375 image->blob->stream_info.file=(*type == 'r') ? stdin : stdout;
2376 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2377 if (strchr(type,'b') != (char *) NULL)
2378 setmode(_fileno(image->blob->stream_info.file),_O_BINARY);
2380 image->blob->type=StandardStream;
2381 image->blob->exempt=MagickTrue;
2384 if (LocaleNCompare(filename,"fd:",3) == 0)
2387 mode[MaxTextExtent];
2391 image->blob->stream_info.file=fdopen(StringToLong(filename+3),mode);
2392 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2393 if (strchr(type,'b') != (char *) NULL)
2394 setmode(_fileno(image->blob->stream_info.file),_O_BINARY);
2396 image->blob->type=StandardStream;
2397 image->blob->exempt=MagickTrue;
2400 #if defined(MAGICKCORE_HAVE_POPEN)
2401 if (*filename == '|')
2404 mode[MaxTextExtent];
2407 Pipe image to or from a system command.
2409 #if defined(SIGPIPE)
2411 (void) signal(SIGPIPE,SIG_IGN);
2415 image->blob->stream_info.file=(FILE *) popen_utf8(filename+1,mode);
2416 if (image->blob->stream_info.file == (FILE *) NULL)
2418 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2419 return(MagickFalse);
2421 image->blob->type=PipeStream;
2422 image->blob->exempt=MagickTrue;
2426 status=GetPathAttributes(filename,&image->blob->properties);
2427 #if defined(S_ISFIFO)
2428 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2430 image->blob->stream_info.file=(FILE *) fopen_utf8(filename,type);
2431 if (image->blob->stream_info.file == (FILE *) NULL)
2433 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2434 return(MagickFalse);
2436 image->blob->type=FileStream;
2437 image->blob->exempt=MagickTrue;
2441 GetPathComponent(image->filename,ExtensionPath,extension);
2444 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2445 if ((image_info->adjoin == MagickFalse) ||
2446 (strchr(filename,'%') != (char *) NULL))
2449 Form filename for multi-part images.
2451 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2452 image->scene,filename,exception);
2453 if ((LocaleCompare(filename,image->filename) == 0) &&
2454 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2455 (GetNextImageInList(image) != (Image *) NULL)))
2458 path[MaxTextExtent];
2460 GetPathComponent(image->filename,RootPath,path);
2461 if (*extension == '\0')
2462 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2463 path,(double) image->scene);
2465 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2466 path,(double) image->scene,extension);
2468 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2469 #if defined(macintosh)
2470 SetApplicationType(filename,image_info->magick,'8BIM');
2474 if (image_info->file != (FILE *) NULL)
2476 image->blob->stream_info.file=image_info->file;
2477 image->blob->type=FileStream;
2478 image->blob->exempt=MagickTrue;
2483 image->blob->stream_info.file=(FILE *) fopen_utf8(filename,type);
2484 if (image->blob->stream_info.file != (FILE *) NULL)
2492 image->blob->type=FileStream;
2493 #if defined(MAGICKCORE_HAVE_SETVBUF)
2494 (void) setvbuf(image->blob->stream_info.file,(char *) NULL,
2495 (int) _IOFBF,16384);
2497 (void) ResetMagickMemory(magick,0,sizeof(magick));
2498 count=fread(magick,1,sizeof(magick),image->blob->stream_info.file);
2499 (void) rewind(image->blob->stream_info.file);
2500 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2501 " read %.20g magic header bytes",(double) count);
2502 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2503 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2504 ((int) magick[2] == 0x08))
2506 (void) fclose(image->blob->stream_info.file);
2507 image->blob->stream_info.gzfile=gzopen(filename,type);
2508 if (image->blob->stream_info.gzfile != (gzFile) NULL)
2509 image->blob->type=ZipStream;
2512 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2513 if (strncmp((char *) magick,"BZh",3) == 0)
2515 (void) fclose(image->blob->stream_info.file);
2516 image->blob->stream_info.bzfile=BZ2_bzopen(filename,type);
2517 if (image->blob->stream_info.bzfile != (BZFILE *) NULL)
2518 image->blob->type=BZipStream;
2521 if (image->blob->type == FileStream)
2532 sans_exception=AcquireExceptionInfo();
2533 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2534 sans_exception=DestroyExceptionInfo(sans_exception);
2535 properties=(&image->blob->properties);
2536 if ((magick_info != (const MagickInfo *) NULL) &&
2537 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2538 (properties->st_size <= MagickMaxBufferExtent))
2546 length=(size_t) properties->st_size;
2547 blob=MapBlob(fileno(image->blob->stream_info.file),ReadMode,
2549 if (blob != (void *) NULL)
2552 Format supports blobs-- use memory-mapped I/O.
2554 if (image_info->file != (FILE *) NULL)
2555 image->blob->exempt=MagickFalse;
2558 (void) fclose(image->blob->stream_info.file);
2559 image->blob->stream_info.file=(FILE *) NULL;
2561 AttachBlob(image->blob,blob,length);
2562 image->blob->mapped=MagickTrue;
2569 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2570 if ((LocaleCompare(extension,"Z") == 0) ||
2571 (LocaleCompare(extension,"gz") == 0) ||
2572 (LocaleCompare(extension,"wmz") == 0) ||
2573 (LocaleCompare(extension,"svgz") == 0))
2575 if (mode == WriteBinaryBlobMode)
2577 image->blob->stream_info.gzfile=gzopen(filename,type);
2578 if (image->blob->stream_info.gzfile != (gzFile) NULL)
2579 image->blob->type=ZipStream;
2583 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2584 if (LocaleCompare(extension,"bz2") == 0)
2586 image->blob->stream_info.bzfile=BZ2_bzopen(filename,type);
2587 if (image->blob->stream_info.bzfile != (BZFILE *) NULL)
2588 image->blob->type=BZipStream;
2593 image->blob->stream_info.file=(FILE *) fopen_utf8(filename,type);
2594 if (image->blob->stream_info.file != (FILE *) NULL)
2596 image->blob->type=FileStream;
2597 #if defined(MAGICKCORE_HAVE_SETVBUF)
2598 (void) setvbuf(image->blob->stream_info.file,(char *) NULL,(int) _IOFBF,
2603 image->blob->status=MagickFalse;
2604 if (image->blob->type != UndefinedStream)
2605 image->blob->size=GetBlobSize(image);
2608 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2609 return(MagickFalse);
2615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2625 % PingBlob() returns all the attributes of an image or image sequence except
2626 % for the pixels. It is much faster and consumes far less memory than
2627 % BlobToImage(). On failure, a NULL image is returned and exception
2628 % describes the reason for the failure.
2630 % The format of the PingBlob method is:
2632 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2633 % const size_t length,ExceptionInfo *exception)
2635 % A description of each parameter follows:
2637 % o image_info: the image info.
2639 % o blob: the address of a character stream in one of the image formats
2640 % understood by ImageMagick.
2642 % o length: This size_t integer reflects the length in bytes of the blob.
2644 % o exception: return any errors or warnings in this structure.
2648 #if defined(__cplusplus) || defined(c_plusplus)
2652 static size_t PingStream(const Image *magick_unused(image),
2653 const void *magick_unused(pixels),const size_t columns)
2658 #if defined(__cplusplus) || defined(c_plusplus)
2662 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2663 const size_t length,ExceptionInfo *exception)
2671 assert(image_info != (ImageInfo *) NULL);
2672 assert(image_info->signature == MagickSignature);
2673 if (image_info->debug != MagickFalse)
2674 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2675 image_info->filename);
2676 assert(exception != (ExceptionInfo *) NULL);
2677 if ((blob == (const void *) NULL) || (length == 0))
2679 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2680 "UnrecognizedImageFormat","'%s'",image_info->magick);
2681 return((Image *) NULL);
2683 ping_info=CloneImageInfo(image_info);
2684 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2685 if (ping_info->blob == (const void *) NULL)
2687 (void) ThrowMagickException(exception,GetMagickModule(),
2688 ResourceLimitFatalError,"MemoryAllocationFailed","'%s'","");
2689 return((Image *) NULL);
2691 (void) memcpy(ping_info->blob,blob,length);
2692 ping_info->length=length;
2693 ping_info->ping=MagickTrue;
2694 image=ReadStream(ping_info,&PingStream,exception);
2695 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2696 ping_info=DestroyImageInfo(ping_info);
2701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2711 % ReadBlob() reads data from the blob or image file and returns it. It
2712 % returns the number of bytes read.
2714 % The format of the ReadBlob method is:
2716 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2718 % A description of each parameter follows:
2720 % o image: the image.
2722 % o length: Specifies an integer representing the number of bytes to read
2725 % o data: Specifies an area to place the information requested from the
2729 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2730 unsigned char *data)
2735 register unsigned char
2741 assert(image != (Image *) NULL);
2742 assert(image->signature == MagickSignature);
2743 assert(image->blob != (BlobInfo *) NULL);
2744 assert(image->blob->type != UndefinedStream);
2747 assert(data != (void *) NULL);
2750 switch (image->blob->type)
2752 case UndefinedStream:
2755 case StandardStream:
2762 count=(ssize_t) fread(q,1,length,image->blob->stream_info.file);
2767 c=getc(image->blob->stream_info.file);
2770 *q++=(unsigned char) c;
2775 c=getc(image->blob->stream_info.file);
2778 *q++=(unsigned char) c;
2788 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2793 count=(ssize_t) gzread(image->blob->stream_info.gzfile,q,
2794 (unsigned int) length);
2799 c=gzgetc(image->blob->stream_info.gzfile);
2802 *q++=(unsigned char) c;
2807 c=gzgetc(image->blob->stream_info.gzfile);
2810 *q++=(unsigned char) c;
2821 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2822 count=(ssize_t) BZ2_bzread(image->blob->stream_info.bzfile,q,
2831 register const unsigned char
2834 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2836 image->blob->eof=MagickTrue;
2839 p=image->blob->data+image->blob->offset;
2840 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2841 image->blob->offset+=count;
2842 if (count != (ssize_t) length)
2843 image->blob->eof=MagickTrue;
2844 (void) memcpy(q,p,(size_t) count);
2852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2856 + R e a d B l o b B y t e %
2860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2862 % ReadBlobByte() reads a single byte from the image file and returns it.
2864 % The format of the ReadBlobByte method is:
2866 % int ReadBlobByte(Image *image)
2868 % A description of each parameter follows.
2870 % o image: the image.
2873 MagickExport int ReadBlobByte(Image *image)
2875 register const unsigned char
2884 assert(image != (Image *) NULL);
2885 assert(image->signature == MagickSignature);
2886 p=ReadBlobStream(image,1,buffer,&count);
2893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2897 + R e a d B l o b D o u b l e %
2901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2903 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2904 % specified by the endian member of the image structure.
2906 % The format of the ReadBlobDouble method is:
2908 % double ReadBlobDouble(Image *image)
2910 % A description of each parameter follows.
2912 % o image: the image.
2915 MagickExport double ReadBlobDouble(Image *image)
2926 quantum.double_value=0.0;
2927 quantum.unsigned_value=ReadBlobLongLong(image);
2928 return(quantum.double_value);
2932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2936 + R e a d B l o b F l o a t %
2940 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2942 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2943 % specified by the endian member of the image structure.
2945 % The format of the ReadBlobFloat method is:
2947 % float ReadBlobFloat(Image *image)
2949 % A description of each parameter follows.
2951 % o image: the image.
2954 MagickExport float ReadBlobFloat(Image *image)
2965 quantum.float_value=0.0;
2966 quantum.unsigned_value=ReadBlobLong(image);
2967 return(quantum.float_value);
2971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2975 + R e a d B l o b L o n g %
2979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2981 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2982 % specified by the endian member of the image structure.
2984 % The format of the ReadBlobLong method is:
2986 % unsigned int ReadBlobLong(Image *image)
2988 % A description of each parameter follows.
2990 % o image: the image.
2993 MagickExport unsigned int ReadBlobLong(Image *image)
2995 register const unsigned char
3007 assert(image != (Image *) NULL);
3008 assert(image->signature == MagickSignature);
3010 p=ReadBlobStream(image,4,buffer,&count);
3013 if (image->endian == LSBEndian)
3015 value=(unsigned int) (*p++);
3016 value|=((unsigned int) (*p++)) << 8;
3017 value|=((unsigned int) (*p++)) << 16;
3018 value|=((unsigned int) (*p++)) << 24;
3021 value=((unsigned int) (*p++)) << 24;
3022 value|=((unsigned int) (*p++)) << 16;
3023 value|=((unsigned int) (*p++)) << 8;
3024 value|=((unsigned int) (*p++));
3029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3033 + R e a d B l o b L o n g L o n g %
3037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3039 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3040 % byte-order specified by the endian member of the image structure.
3042 % The format of the ReadBlobLongLong method is:
3044 % MagickSizeType ReadBlobLongLong(Image *image)
3046 % A description of each parameter follows.
3048 % o image: the image.
3051 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3056 register const unsigned char
3065 assert(image != (Image *) NULL);
3066 assert(image->signature == MagickSignature);
3068 p=ReadBlobStream(image,8,buffer,&count);
3070 return(MagickULLConstant(0));
3071 if (image->endian == LSBEndian)
3073 value=(MagickSizeType) (*p++);
3074 value|=((MagickSizeType) (*p++)) << 8;
3075 value|=((MagickSizeType) (*p++)) << 16;
3076 value|=((MagickSizeType) (*p++)) << 24;
3077 value|=((MagickSizeType) (*p++)) << 32;
3078 value|=((MagickSizeType) (*p++)) << 40;
3079 value|=((MagickSizeType) (*p++)) << 48;
3080 value|=((MagickSizeType) (*p++)) << 56;
3081 return(value & MagickULLConstant(0xffffffffffffffff));
3083 value=((MagickSizeType) (*p++)) << 56;
3084 value|=((MagickSizeType) (*p++)) << 48;
3085 value|=((MagickSizeType) (*p++)) << 40;
3086 value|=((MagickSizeType) (*p++)) << 32;
3087 value|=((MagickSizeType) (*p++)) << 24;
3088 value|=((MagickSizeType) (*p++)) << 16;
3089 value|=((MagickSizeType) (*p++)) << 8;
3090 value|=((MagickSizeType) (*p++));
3091 return(value & MagickULLConstant(0xffffffffffffffff));
3095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3099 + R e a d B l o b S h o r t %
3103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3105 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3106 % specified by the endian member of the image structure.
3108 % The format of the ReadBlobShort method is:
3110 % unsigned short ReadBlobShort(Image *image)
3112 % A description of each parameter follows.
3114 % o image: the image.
3117 MagickExport unsigned short ReadBlobShort(Image *image)
3119 register const unsigned char
3122 register unsigned int
3131 assert(image != (Image *) NULL);
3132 assert(image->signature == MagickSignature);
3134 p=ReadBlobStream(image,2,buffer,&count);
3136 return((unsigned short) 0U);
3137 if (image->endian == LSBEndian)
3139 value=(unsigned int) (*p++);
3140 value|=((unsigned int) (*p++)) << 8;
3141 return((unsigned short) (value & 0xffff));
3143 value=(unsigned int) ((*p++) << 8);
3144 value|=(unsigned int) (*p++);
3145 return((unsigned short) (value & 0xffff));
3149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3153 + R e a d B l o b L S B L o n g %
3157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3159 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3160 % least-significant byte first order.
3162 % The format of the ReadBlobLSBLong method is:
3164 % unsigned int ReadBlobLSBLong(Image *image)
3166 % A description of each parameter follows.
3168 % o image: the image.
3171 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3173 register const unsigned char
3176 register unsigned int
3185 assert(image != (Image *) NULL);
3186 assert(image->signature == MagickSignature);
3188 p=ReadBlobStream(image,4,buffer,&count);
3191 value=(unsigned int) (*p++);
3192 value|=((unsigned int) (*p++)) << 8;
3193 value|=((unsigned int) (*p++)) << 16;
3194 value|=((unsigned int) (*p++)) << 24;
3199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3203 + R e a d B l o b L S B S h o r t %
3207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3209 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3210 % least-significant byte first order.
3212 % The format of the ReadBlobLSBShort method is:
3214 % unsigned short ReadBlobLSBShort(Image *image)
3216 % A description of each parameter follows.
3218 % o image: the image.
3221 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3223 register const unsigned char
3226 register unsigned int
3235 assert(image != (Image *) NULL);
3236 assert(image->signature == MagickSignature);
3238 p=ReadBlobStream(image,2,buffer,&count);
3240 return((unsigned short) 0U);
3241 value=(unsigned int) (*p++);
3242 value|=((unsigned int) ((*p++)) << 8);
3243 return((unsigned short) (value & 0xffff));
3247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3251 + R e a d B l o b M S B L o n g %
3255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3257 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3258 % most-significant byte first order.
3260 % The format of the ReadBlobMSBLong method is:
3262 % unsigned int ReadBlobMSBLong(Image *image)
3264 % A description of each parameter follows.
3266 % o image: the image.
3269 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3271 register const unsigned char
3274 register unsigned int
3283 assert(image != (Image *) NULL);
3284 assert(image->signature == MagickSignature);
3286 p=ReadBlobStream(image,4,buffer,&count);
3289 value=((unsigned int) (*p++) << 24);
3290 value|=((unsigned int) (*p++) << 16);
3291 value|=((unsigned int) (*p++) << 8);
3292 value|=(unsigned int) (*p++);
3297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3301 + R e a d B l o b M S B L o n g L o n g %
3305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3307 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3308 % most-significant byte first order.
3310 % The format of the ReadBlobMSBLongLong method is:
3312 % unsigned int ReadBlobMSBLongLong(Image *image)
3314 % A description of each parameter follows.
3316 % o image: the image.
3319 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3321 register const unsigned char
3324 register MagickSizeType
3333 assert(image != (Image *) NULL);
3334 assert(image->signature == MagickSignature);
3336 p=ReadBlobStream(image,8,buffer,&count);
3338 return(MagickULLConstant(0));
3339 value=((MagickSizeType) (*p++)) << 56;
3340 value|=((MagickSizeType) (*p++)) << 48;
3341 value|=((MagickSizeType) (*p++)) << 40;
3342 value|=((MagickSizeType) (*p++)) << 32;
3343 value|=((MagickSizeType) (*p++)) << 24;
3344 value|=((MagickSizeType) (*p++)) << 16;
3345 value|=((MagickSizeType) (*p++)) << 8;
3346 value|=((MagickSizeType) (*p++));
3347 return(value & MagickULLConstant(0xffffffffffffffff));
3351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3355 + R e a d B l o b M S B S h o r t %
3359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3361 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3362 % most-significant byte first order.
3364 % The format of the ReadBlobMSBShort method is:
3366 % unsigned short ReadBlobMSBShort(Image *image)
3368 % A description of each parameter follows.
3370 % o image: the image.
3373 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3375 register const unsigned char
3378 register unsigned int
3387 assert(image != (Image *) NULL);
3388 assert(image->signature == MagickSignature);
3390 p=ReadBlobStream(image,2,buffer,&count);
3392 return((unsigned short) 0U);
3393 value=(unsigned int) ((*p++) << 8);
3394 value|=(unsigned int) (*p++);
3395 return((unsigned short) (value & 0xffff));
3399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3403 + R e a d B l o b S t r i n g %
3407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3409 % ReadBlobString() reads characters from a blob or file until a newline
3410 % character is read or an end-of-file condition is encountered.
3412 % The format of the ReadBlobString method is:
3414 % char *ReadBlobString(Image *image,char *string)
3416 % A description of each parameter follows:
3418 % o image: the image.
3420 % o string: the address of a character buffer.
3423 MagickExport char *ReadBlobString(Image *image,char *string)
3425 register const unsigned char
3437 assert(image != (Image *) NULL);
3438 assert(image->signature == MagickSignature);
3439 for (i=0; i < (MaxTextExtent-1L); i++)
3441 p=ReadBlobStream(image,1,buffer,&count);
3445 return((char *) NULL);
3448 string[i]=(char) (*p);
3449 if ((string[i] == '\r') || (string[i] == '\n'))
3452 if (string[i] == '\r')
3453 (void) ReadBlobStream(image,1,buffer,&count);
3459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3463 + R e f e r e n c e B l o b %
3467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3469 % ReferenceBlob() increments the reference count associated with the pixel
3470 % blob returning a pointer to the blob.
3472 % The format of the ReferenceBlob method is:
3474 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3476 % A description of each parameter follows:
3478 % o blob_info: the blob_info.
3481 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3483 assert(blob != (BlobInfo *) NULL);
3484 assert(blob->signature == MagickSignature);
3485 if (blob->debug != MagickFalse)
3486 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3487 LockSemaphoreInfo(blob->semaphore);
3488 blob->reference_count++;
3489 UnlockSemaphoreInfo(blob->semaphore);
3494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3502 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3504 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3505 % and returns the resulting offset.
3507 % The format of the SeekBlob method is:
3509 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3512 % A description of each parameter follows:
3514 % o image: the image.
3516 % o offset: Specifies an integer representing the offset in bytes.
3518 % o whence: Specifies an integer representing how the offset is
3519 % treated relative to the beginning of the blob as follows:
3521 % SEEK_SET Set position equal to offset bytes.
3522 % SEEK_CUR Set position to current location plus offset.
3523 % SEEK_END Set position to EOF plus offset.
3526 MagickExport MagickOffsetType SeekBlob(Image *image,
3527 const MagickOffsetType offset,const int whence)
3529 assert(image != (Image *) NULL);
3530 assert(image->signature == MagickSignature);
3531 if (image->debug != MagickFalse)
3532 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3533 assert(image->blob != (BlobInfo *) NULL);
3534 assert(image->blob->type != UndefinedStream);
3535 switch (image->blob->type)
3537 case UndefinedStream:
3541 if (fseek(image->blob->stream_info.file,offset,whence) < 0)
3543 image->blob->offset=TellBlob(image);
3546 case StandardStream:
3550 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3551 if (gzseek(image->blob->stream_info.gzfile,(off_t) offset,whence) < 0)
3554 image->blob->offset=TellBlob(image);
3570 image->blob->offset=offset;
3575 if ((image->blob->offset+offset) < 0)
3577 image->blob->offset+=offset;
3582 if (((MagickOffsetType) image->blob->length+offset) < 0)
3584 image->blob->offset=image->blob->length+offset;
3588 if (image->blob->offset <= (MagickOffsetType)
3589 ((off_t) image->blob->length))
3590 image->blob->eof=MagickFalse;
3592 if (image->blob->mapped != MagickFalse)
3596 image->blob->extent=(size_t) (image->blob->offset+
3597 image->blob->quantum);
3598 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3599 image->blob->data,image->blob->extent+1,
3600 sizeof(*image->blob->data));
3601 (void) SyncBlob(image);
3602 if (image->blob->data == (unsigned char *) NULL)
3604 (void) DetachBlob(image->blob);
3611 return(image->blob->offset);
3615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3619 + S e t B l o b E x e m p t %
3623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3625 % SetBlobExempt() sets the blob exempt status.
3627 % The format of the SetBlobExempt method is:
3629 % MagickBooleanType SetBlobExempt(const Image *image,
3630 % const MagickBooleanType exempt)
3632 % A description of each parameter follows:
3634 % o image: the image.
3636 % o exempt: Set to true if this blob is exempt from being closed.
3639 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3641 assert(image != (const Image *) NULL);
3642 assert(image->signature == MagickSignature);
3643 if (image->debug != MagickFalse)
3644 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3645 image->blob->exempt=exempt;
3649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3653 + S e t B l o b E x t e n t %
3657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3659 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3660 % method is successful, subsequent writes to bytes in the specified range are
3661 % guaranteed not to fail.
3663 % The format of the SetBlobExtent method is:
3665 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3667 % A description of each parameter follows:
3669 % o image: the image.
3671 % o extent: the blob maximum extent.
3674 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3675 const MagickSizeType extent)
3677 assert(image != (Image *) NULL);
3678 assert(image->signature == MagickSignature);
3679 if (image->debug != MagickFalse)
3680 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3681 assert(image->blob != (BlobInfo *) NULL);
3682 assert(image->blob->type != UndefinedStream);
3683 switch (image->blob->type)
3685 case UndefinedStream:
3689 if (extent != (MagickSizeType) ((off_t) extent))
3690 return(MagickFalse);
3691 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3692 return(MagickFalse);
3701 offset=TellBlob(image);
3702 status=posix_fallocate(fileno(image->blob->stream_info.file),
3703 (off_t) offset,(off_t) (extent-offset));
3705 return(MagickFalse);
3710 case StandardStream:
3713 return(MagickFalse);
3715 return(MagickFalse);
3717 return(MagickFalse);
3720 if (image->blob->mapped != MagickFalse)
3722 if (image->blob->stream_info.file == (FILE *) NULL)
3723 return(MagickFalse);
3724 (void) UnmapBlob(image->blob->data,image->blob->length);
3725 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3726 return(MagickFalse);
3735 offset=TellBlob(image);
3736 status=posix_fallocate(fileno(image->blob->stream_info.file),
3737 (off_t) offset,(off_t) (extent-offset));
3739 return(MagickFalse);
3741 image->blob->data=(unsigned char*) MapBlob(fileno(
3742 image->blob->stream_info.file),WriteMode,0,(size_t) extent);
3743 image->blob->extent=(size_t) extent;
3744 image->blob->length=(size_t) extent;
3745 (void) SyncBlob(image);
3749 if (extent != (MagickSizeType) ((size_t) extent))
3750 return(MagickFalse);
3751 image->blob->extent=(size_t) extent;
3752 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3753 image->blob->extent+1,sizeof(*image->blob->data));
3754 (void) SyncBlob(image);
3755 if (image->blob->data == (unsigned char *) NULL)
3757 (void) DetachBlob(image->blob);
3758 return(MagickFalse);
3767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3777 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3778 % attributes if it is an blob.
3780 % The format of the SyncBlob method is:
3782 % int SyncBlob(Image *image)
3784 % A description of each parameter follows:
3786 % o image: the image.
3789 static int SyncBlob(Image *image)
3794 assert(image != (Image *) NULL);
3795 assert(image->signature == MagickSignature);
3796 if (image->debug != MagickFalse)
3797 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3798 assert(image->blob != (BlobInfo *) NULL);
3799 assert(image->blob->type != UndefinedStream);
3801 switch (image->blob->type)
3803 case UndefinedStream:
3806 case StandardStream:
3809 status=fflush(image->blob->stream_info.file);
3814 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3815 status=gzflush(image->blob->stream_info.gzfile,Z_SYNC_FLUSH);
3821 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3822 status=BZ2_bzflush(image->blob->stream_info.bzfile);
3830 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3831 if (image->blob->mapped != MagickFalse)
3832 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3851 % TellBlob() obtains the current value of the blob or file position.
3853 % The format of the TellBlob method is:
3855 % MagickOffsetType TellBlob(const Image *image)
3857 % A description of each parameter follows:
3859 % o image: the image.
3862 MagickExport MagickOffsetType TellBlob(const Image *image)
3867 assert(image != (Image *) NULL);
3868 assert(image->signature == MagickSignature);
3869 if (image->debug != MagickFalse)
3870 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3871 assert(image->blob != (BlobInfo *) NULL);
3872 assert(image->blob->type != UndefinedStream);
3874 switch (image->blob->type)
3876 case UndefinedStream:
3880 offset=ftell(image->blob->stream_info.file);
3883 case StandardStream:
3888 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3889 offset=(MagickOffsetType) gztell(image->blob->stream_info.gzfile);
3899 offset=image->blob->offset;
3907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3911 + U n m a p B l o b %
3915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3917 % UnmapBlob() deallocates the binary large object previously allocated with
3918 % the MapBlob method.
3920 % The format of the UnmapBlob method is:
3922 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3924 % A description of each parameter follows:
3926 % o map: the address of the binary large object.
3928 % o length: the length of the binary large object.
3931 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3933 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3937 status=munmap(map,length);
3938 return(status == -1 ? MagickFalse : MagickTrue);
3942 return(MagickFalse);
3947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3951 + W r i t e B l o b %
3955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3957 % WriteBlob() writes data to a blob or image file. It returns the number of
3960 % The format of the WriteBlob method is:
3962 % ssize_t WriteBlob(Image *image,const size_t length,
3963 % const unsigned char *data)
3965 % A description of each parameter follows:
3967 % o image: the image.
3969 % o length: Specifies an integer representing the number of bytes to
3970 % write to the file.
3972 % o data: The address of the data to write to the blob or file.
3975 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3976 const unsigned char *data)
3981 register const unsigned char
3987 assert(image != (Image *) NULL);
3988 assert(image->signature == MagickSignature);
3989 assert(data != (const unsigned char *) NULL);
3990 assert(image->blob != (BlobInfo *) NULL);
3991 assert(image->blob->type != UndefinedStream);
3996 switch (image->blob->type)
3998 case UndefinedStream:
4001 case StandardStream:
4008 count=(ssize_t) fwrite((const char *) data,1,length,
4009 image->blob->stream_info.file);
4014 c=putc((int) *p++,image->blob->stream_info.file);
4021 c=putc((int) *p++,image->blob->stream_info.file);
4033 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4038 count=(ssize_t) gzwrite(image->blob->stream_info.gzfile,(void *) data,
4039 (unsigned int) length);
4044 c=gzputc(image->blob->stream_info.gzfile,(int) *p++);
4051 c=gzputc(image->blob->stream_info.gzfile,(int) *p++);
4064 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4065 count=(ssize_t) BZ2_bzwrite(image->blob->stream_info.bzfile,(void *) data,
4072 count=(ssize_t) image->blob->stream(image,data,length);
4077 register unsigned char
4080 if ((image->blob->offset+(MagickOffsetType) length) >=
4081 (MagickOffsetType) image->blob->extent)
4083 if (image->blob->mapped != MagickFalse)
4085 image->blob->quantum<<=1;
4086 image->blob->extent+=length+image->blob->quantum;
4087 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4088 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4089 (void) SyncBlob(image);
4090 if (image->blob->data == (unsigned char *) NULL)
4092 (void) DetachBlob(image->blob);
4096 q=image->blob->data+image->blob->offset;
4097 (void) memcpy(q,p,length);
4098 image->blob->offset+=length;
4099 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4100 image->blob->length=(size_t) image->blob->offset;
4101 count=(ssize_t) length;
4108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4112 + W r i t e B l o b B y t e %
4116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4118 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4119 % written (either 0 or 1);
4121 % The format of the WriteBlobByte method is:
4123 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4125 % A description of each parameter follows.
4127 % o image: the image.
4129 % o value: Specifies the value to write.
4132 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4134 assert(image != (Image *) NULL);
4135 assert(image->signature == MagickSignature);
4136 return(WriteBlobStream(image,1,&value));
4140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4144 + W r i t e B l o b F l o a t %
4148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4150 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4151 % specified by the endian member of the image structure.
4153 % The format of the WriteBlobFloat method is:
4155 % ssize_t WriteBlobFloat(Image *image,const float value)
4157 % A description of each parameter follows.
4159 % o image: the image.
4161 % o value: Specifies the value to write.
4164 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4175 quantum.unsigned_value=0U;
4176 quantum.float_value=value;
4177 return(WriteBlobLong(image,quantum.unsigned_value));
4181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4185 + W r i t e B l o b L o n g %
4189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4191 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4192 % specified by the endian member of the image structure.
4194 % The format of the WriteBlobLong method is:
4196 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4198 % A description of each parameter follows.
4200 % o image: the image.
4202 % o value: Specifies the value to write.
4205 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4210 assert(image != (Image *) NULL);
4211 assert(image->signature == MagickSignature);
4212 if (image->endian == LSBEndian)
4214 buffer[0]=(unsigned char) value;
4215 buffer[1]=(unsigned char) (value >> 8);
4216 buffer[2]=(unsigned char) (value >> 16);
4217 buffer[3]=(unsigned char) (value >> 24);
4218 return(WriteBlobStream(image,4,buffer));
4220 buffer[0]=(unsigned char) (value >> 24);
4221 buffer[1]=(unsigned char) (value >> 16);
4222 buffer[2]=(unsigned char) (value >> 8);
4223 buffer[3]=(unsigned char) value;
4224 return(WriteBlobStream(image,4,buffer));
4228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4232 + W r i t e B l o b S h o r t %
4236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4238 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4239 % byte-order specified by the endian member of the image structure.
4241 % The format of the WriteBlobShort method is:
4243 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4245 % A description of each parameter follows.
4247 % o image: the image.
4249 % o value: Specifies the value to write.
4252 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4257 assert(image != (Image *) NULL);
4258 assert(image->signature == MagickSignature);
4259 if (image->endian == LSBEndian)
4261 buffer[0]=(unsigned char) value;
4262 buffer[1]=(unsigned char) (value >> 8);
4263 return(WriteBlobStream(image,2,buffer));
4265 buffer[0]=(unsigned char) (value >> 8);
4266 buffer[1]=(unsigned char) value;
4267 return(WriteBlobStream(image,2,buffer));
4271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4275 + W r i t e B l o b L S B L o n g %
4279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4281 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4282 % least-significant byte first order.
4284 % The format of the WriteBlobLSBLong method is:
4286 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4288 % A description of each parameter follows.
4290 % o image: the image.
4292 % o value: Specifies the value to write.
4295 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4300 assert(image != (Image *) NULL);
4301 assert(image->signature == MagickSignature);
4302 buffer[0]=(unsigned char) value;
4303 buffer[1]=(unsigned char) (value >> 8);
4304 buffer[2]=(unsigned char) (value >> 16);
4305 buffer[3]=(unsigned char) (value >> 24);
4306 return(WriteBlobStream(image,4,buffer));
4310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4314 + W r i t e B l o b L S B S h o r t %
4318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4320 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4321 % least-significant byte first order.
4323 % The format of the WriteBlobLSBShort method is:
4325 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4327 % A description of each parameter follows.
4329 % o image: the image.
4331 % o value: Specifies the value to write.
4334 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4339 assert(image != (Image *) NULL);
4340 assert(image->signature == MagickSignature);
4341 buffer[0]=(unsigned char) value;
4342 buffer[1]=(unsigned char) (value >> 8);
4343 return(WriteBlobStream(image,2,buffer));
4347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4351 + W r i t e B l o b M S B L o n g %
4355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4357 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4358 % most-significant byte first order.
4360 % The format of the WriteBlobMSBLong method is:
4362 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4364 % A description of each parameter follows.
4366 % o value: Specifies the value to write.
4368 % o image: the image.
4371 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4376 assert(image != (Image *) NULL);
4377 assert(image->signature == MagickSignature);
4378 buffer[0]=(unsigned char) (value >> 24);
4379 buffer[1]=(unsigned char) (value >> 16);
4380 buffer[2]=(unsigned char) (value >> 8);
4381 buffer[3]=(unsigned char) value;
4382 return(WriteBlobStream(image,4,buffer));
4386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4390 + W r i t e B l o b M S B L o n g L o n g %
4394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4396 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4397 % most-significant byte first order.
4399 % The format of the WriteBlobMSBLongLong method is:
4401 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4403 % A description of each parameter follows.
4405 % o value: Specifies the value to write.
4407 % o image: the image.
4410 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4411 const MagickSizeType value)
4416 assert(image != (Image *) NULL);
4417 assert(image->signature == MagickSignature);
4418 buffer[0]=(unsigned char) (value >> 56);
4419 buffer[1]=(unsigned char) (value >> 48);
4420 buffer[2]=(unsigned char) (value >> 40);
4421 buffer[3]=(unsigned char) (value >> 32);
4422 buffer[4]=(unsigned char) (value >> 24);
4423 buffer[5]=(unsigned char) (value >> 16);
4424 buffer[6]=(unsigned char) (value >> 8);
4425 buffer[7]=(unsigned char) value;
4426 return(WriteBlobStream(image,8,buffer));
4430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4434 + W r i t e B l o b M S B S h o r t %
4438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4440 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4441 % most-significant byte first order.
4443 % The format of the WriteBlobMSBShort method is:
4445 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4447 % A description of each parameter follows.
4449 % o value: Specifies the value to write.
4451 % o file: Specifies the file to write the data to.
4454 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4459 assert(image != (Image *) NULL);
4460 assert(image->signature == MagickSignature);
4461 buffer[0]=(unsigned char) (value >> 8);
4462 buffer[1]=(unsigned char) value;
4463 return(WriteBlobStream(image,2,buffer));
4467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4471 + W r i t e B l o b S t r i n g %
4475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4477 % WriteBlobString() write a string to a blob. It returns the number of
4478 % characters written.
4480 % The format of the WriteBlobString method is:
4482 % ssize_t WriteBlobString(Image *image,const char *string)
4484 % A description of each parameter follows.
4486 % o image: the image.
4488 % o string: Specifies the string to write.
4491 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4493 assert(image != (Image *) NULL);
4494 assert(image->signature == MagickSignature);
4495 assert(string != (const char *) NULL);
4496 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));