2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/client.h"
48 #include "MagickCore/constitute.h"
49 #include "MagickCore/delegate.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image-private.h"
53 #include "MagickCore/list.h"
54 #include "MagickCore/locale_.h"
55 #include "MagickCore/log.h"
56 #include "MagickCore/magick.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/nt-base-private.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_ZLIB_DELEGATE)
70 #if defined(MAGICKCORE_BZLIB_DELEGATE)
77 #define MagickMaxBlobExtent 65541
78 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
79 # define MAP_ANONYMOUS MAP_ANON
81 #if !defined(MAP_FAILED)
82 #define MAP_FAILED ((void *) -1)
86 #define _O_BINARY O_BINARY
92 typedef union FileInfo
97 #if defined(MAGICKCORE_ZLIB_DELEGATE)
102 #if defined(MAGICKCORE_BZLIB_DELEGATE)
160 Forward declarations.
166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 + A t t a c h B l o b %
174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176 % AttachBlob() attaches a blob to the BlobInfo structure.
178 % The format of the AttachBlob method is:
180 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
182 % A description of each parameter follows:
184 % o blob_info: Specifies a pointer to a BlobInfo structure.
186 % o blob: the address of a character stream in one of the image formats
187 % understood by ImageMagick.
189 % o length: This size_t integer reflects the length in bytes of the blob.
192 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
195 assert(blob_info != (BlobInfo *) NULL);
196 if (blob_info->debug != MagickFalse)
197 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
198 blob_info->length=length;
199 blob_info->extent=length;
200 blob_info->quantum=(size_t) MagickMaxBlobExtent;
202 blob_info->type=BlobStream;
203 blob_info->file_info.file=(FILE *) NULL;
204 blob_info->data=(unsigned char *) blob;
205 blob_info->mapped=MagickFalse;
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213 + B l o b T o F i l e %
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
220 % occurs otherwise MagickTrue.
222 % The format of the BlobToFile method is:
224 % MagickBooleanType BlobToFile(char *filename,const void *blob,
225 % const size_t length,ExceptionInfo *exception)
227 % A description of each parameter follows:
229 % o filename: Write the blob to this file.
231 % o blob: the address of a blob.
233 % o length: This length in bytes of the blob.
235 % o exception: return any errors or warnings in this structure.
239 static inline MagickSizeType MagickMin(const MagickSizeType x,
240 const MagickSizeType y)
247 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
248 const size_t length,ExceptionInfo *exception)
259 assert(filename != (const char *) NULL);
260 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
261 assert(blob != (const void *) NULL);
262 if (*filename == '\0')
263 file=AcquireUniqueFileResource(filename);
265 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
268 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
271 for (i=0; i < length; i+=count)
273 count=write(file,(const char *) blob+i,(size_t) MagickMin(length-i,
274 (MagickSizeType) SSIZE_MAX));
283 if ((file == -1) || (i < length))
285 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296 % B l o b T o I m a g e %
300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302 % BlobToImage() implements direct to memory image formats. It returns the
305 % The format of the BlobToImage method is:
307 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
308 % const size_t length,ExceptionInfo *exception)
310 % A description of each parameter follows:
312 % o image_info: the image info.
314 % o blob: the address of a character stream in one of the image formats
315 % understood by ImageMagick.
317 % o length: This size_t integer reflects the length in bytes of the blob.
319 % o exception: return any errors or warnings in this structure.
322 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
323 const size_t length,ExceptionInfo *exception)
338 assert(image_info != (ImageInfo *) NULL);
339 assert(image_info->signature == MagickSignature);
340 if (image_info->debug != MagickFalse)
341 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
342 image_info->filename);
343 assert(exception != (ExceptionInfo *) NULL);
344 if ((blob == (const void *) NULL) || (length == 0))
346 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
347 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
348 return((Image *) NULL);
350 blob_info=CloneImageInfo(image_info);
351 blob_info->blob=(void *) blob;
352 blob_info->length=length;
353 if (*blob_info->magick == '\0')
354 (void) SetImageInfo(blob_info,0,exception);
355 magick_info=GetMagickInfo(blob_info->magick,exception);
356 if (magick_info == (const MagickInfo *) NULL)
358 (void) ThrowMagickException(exception,GetMagickModule(),
359 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
361 blob_info=DestroyImageInfo(blob_info);
362 return((Image *) NULL);
364 if (GetMagickBlobSupport(magick_info) != MagickFalse)
367 Native blob support for this image format.
369 (void) CopyMagickString(blob_info->filename,image_info->filename,
371 (void) CopyMagickString(blob_info->magick,image_info->magick,
373 image=ReadImage(blob_info,exception);
374 if (image != (Image *) NULL)
375 (void) DetachBlob(image->blob);
376 blob_info=DestroyImageInfo(blob_info);
380 Write blob to a temporary file on disk.
382 blob_info->blob=(void *) NULL;
384 *blob_info->filename='\0';
385 status=BlobToFile(blob_info->filename,blob,length,exception);
386 if (status == MagickFalse)
388 (void) RelinquishUniqueFileResource(blob_info->filename);
389 blob_info=DestroyImageInfo(blob_info);
390 return((Image *) NULL);
392 clone_info=CloneImageInfo(blob_info);
393 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
394 blob_info->magick,blob_info->filename);
395 image=ReadImage(clone_info,exception);
396 if (image != (Image *) NULL)
402 Restore original filenames and image format.
404 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
406 (void) CopyMagickString(images->filename,image_info->filename,
408 (void) CopyMagickString(images->magick_filename,image_info->filename,
410 (void) CopyMagickString(images->magick,magick_info->name,
412 images=GetNextImageInList(images);
415 clone_info=DestroyImageInfo(clone_info);
416 (void) RelinquishUniqueFileResource(blob_info->filename);
417 blob_info=DestroyImageInfo(blob_info);
422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426 + C l o n e B l o b I n f o %
430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
433 % blob info is NULL, a new one.
435 % The format of the CloneBlobInfo method is:
437 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
439 % A description of each parameter follows:
441 % o blob_info: the blob info.
444 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
449 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
450 if (clone_info == (BlobInfo *) NULL)
451 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
452 GetBlobInfo(clone_info);
453 if (blob_info == (BlobInfo *) NULL)
455 clone_info->length=blob_info->length;
456 clone_info->extent=blob_info->extent;
457 clone_info->synchronize=blob_info->synchronize;
458 clone_info->quantum=blob_info->quantum;
459 clone_info->mapped=blob_info->mapped;
460 clone_info->eof=blob_info->eof;
461 clone_info->offset=blob_info->offset;
462 clone_info->size=blob_info->size;
463 clone_info->exempt=blob_info->exempt;
464 clone_info->status=blob_info->status;
465 clone_info->temporary=blob_info->temporary;
466 clone_info->type=blob_info->type;
467 clone_info->file_info.file=blob_info->file_info.file;
468 clone_info->properties=blob_info->properties;
469 clone_info->stream=blob_info->stream;
470 clone_info->data=blob_info->data;
471 clone_info->debug=IsEventLogging();
472 clone_info->reference_count=1;
477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 + C l o s e B l o b %
485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
487 % CloseBlob() closes a stream associated with the image.
489 % The format of the CloseBlob method is:
491 % MagickBooleanType CloseBlob(Image *image)
493 % A description of each parameter follows:
495 % o image: the image.
498 MagickExport MagickBooleanType CloseBlob(Image *image)
506 assert(image != (Image *) NULL);
507 assert(image->signature == MagickSignature);
508 if (image->debug != MagickFalse)
509 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
510 assert(image->blob != (BlobInfo *) NULL);
511 if (image->blob->type == UndefinedStream)
513 status=SyncBlob(image);
514 switch (image->blob->type)
516 case UndefinedStream:
522 if (image->blob->synchronize != MagickFalse)
523 status=fsync(fileno(image->blob->file_info.file));
524 status=ferror(image->blob->file_info.file);
529 #if defined(MAGICKCORE_ZLIB_DELEGATE)
530 (void) gzerror(image->blob->file_info.gzfile,&status);
536 #if defined(MAGICKCORE_BZLIB_DELEGATE)
537 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
545 if ((image->blob->file_info.file != (FILE *) NULL) &&
546 (image->blob->synchronize != MagickFalse))
548 (void) fsync(fileno(image->blob->file_info.file));
549 status=ferror(image->blob->file_info.file);
554 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
555 image->blob->size=GetBlobSize(image);
556 image->extent=image->blob->size;
557 image->blob->eof=MagickFalse;
558 if (image->blob->exempt != MagickFalse)
560 image->blob->type=UndefinedStream;
561 return(image->blob->status);
563 switch (image->blob->type)
565 case UndefinedStream:
570 status=fclose(image->blob->file_info.file);
575 #if defined(MAGICKCORE_HAVE_PCLOSE)
576 status=pclose(image->blob->file_info.file);
582 #if defined(MAGICKCORE_ZLIB_DELEGATE)
583 status=gzclose(image->blob->file_info.gzfile);
589 #if defined(MAGICKCORE_BZLIB_DELEGATE)
590 BZ2_bzclose(image->blob->file_info.bzfile);
598 if (image->blob->file_info.file != (FILE *) NULL)
599 status=fclose(image->blob->file_info.file);
603 (void) DetachBlob(image->blob);
604 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
605 return(image->blob->status);
609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
613 + D e s t r o y B l o b %
617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619 % DestroyBlob() deallocates memory associated with a blob.
621 % The format of the DestroyBlob method is:
623 % void DestroyBlob(Image *image)
625 % A description of each parameter follows:
627 % o image: the image.
630 MagickExport void DestroyBlob(Image *image)
635 assert(image != (Image *) NULL);
636 assert(image->signature == MagickSignature);
637 if (image->debug != MagickFalse)
638 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
639 assert(image->blob != (BlobInfo *) NULL);
640 assert(image->blob->signature == MagickSignature);
642 LockSemaphoreInfo(image->blob->semaphore);
643 image->blob->reference_count--;
644 assert(image->blob->reference_count >= 0);
645 if (image->blob->reference_count == 0)
647 UnlockSemaphoreInfo(image->blob->semaphore);
648 if (destroy == MagickFalse)
650 (void) CloseBlob(image);
651 if (image->blob->mapped != MagickFalse)
653 (void) UnmapBlob(image->blob->data,image->blob->length);
654 RelinquishMagickResource(MapResource,image->blob->length);
656 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
657 RelinquishSemaphoreInfo(&image->blob->semaphore);
658 image->blob->signature=(~MagickSignature);
659 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
667 + D e t a c h B l o b %
671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673 % DetachBlob() detaches a blob from the BlobInfo structure.
675 % The format of the DetachBlob method is:
677 % unsigned char *DetachBlob(BlobInfo *blob_info)
679 % A description of each parameter follows:
681 % o blob_info: Specifies a pointer to a BlobInfo structure.
684 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
689 assert(blob_info != (BlobInfo *) NULL);
690 if (blob_info->debug != MagickFalse)
691 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
692 if (blob_info->mapped != MagickFalse)
694 (void) UnmapBlob(blob_info->data,blob_info->length);
695 blob_info->data=(unsigned char *) NULL;
696 RelinquishMagickResource(MapResource,blob_info->length);
698 blob_info->mapped=MagickFalse;
701 blob_info->eof=MagickFalse;
702 blob_info->exempt=MagickFalse;
703 blob_info->type=UndefinedStream;
704 blob_info->file_info.file=(FILE *) NULL;
705 data=blob_info->data;
706 blob_info->data=(unsigned char *) NULL;
707 blob_info->stream=(StreamHandler) NULL;
712 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716 + D i s c a r d B l o b B y t e s %
720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722 % DiscardBlobBytes() discards bytes in a blob.
724 % The format of the DiscardBlobBytes method is:
726 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
728 % A description of each parameter follows.
730 % o image: the image.
732 % o length: the number of bytes to skip.
736 static inline const unsigned char *ReadBlobStream(Image *image,
737 const size_t length,unsigned char *data,ssize_t *count)
739 assert(count != (ssize_t *) NULL);
740 assert(image->blob != (BlobInfo *) NULL);
741 if (image->blob->type != BlobStream)
743 *count=ReadBlob(image,length,data);
746 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
749 image->blob->eof=MagickTrue;
752 data=image->blob->data+image->blob->offset;
753 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
754 image->blob->offset));
755 image->blob->offset+=(*count);
756 if (*count != (ssize_t) length)
757 image->blob->eof=MagickTrue;
761 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
762 const MagickSizeType length)
764 register MagickOffsetType
776 assert(image != (Image *) NULL);
777 assert(image->signature == MagickSignature);
779 for (i=0; i < (MagickOffsetType) length; i+=count)
781 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
782 (void) ReadBlobStream(image,quantum,buffer,&count);
790 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798 + D u p l i c a t e s B l o b %
802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804 % DuplicateBlob() duplicates a blob descriptor.
806 % The format of the DuplicateBlob method is:
808 % void DuplicateBlob(Image *image,const Image *duplicate)
810 % A description of each parameter follows:
812 % o image: the image.
814 % o duplicate: the duplicate image.
817 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
819 assert(image != (Image *) NULL);
820 assert(image->signature == MagickSignature);
821 if (image->debug != MagickFalse)
822 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
823 assert(duplicate != (Image *) NULL);
824 assert(duplicate->signature == MagickSignature);
826 image->blob=ReferenceBlob(duplicate->blob);
830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
840 % EOFBlob() returns a non-zero value when EOF has been detected reading from
843 % The format of the EOFBlob method is:
845 % int EOFBlob(const Image *image)
847 % A description of each parameter follows:
849 % o image: the image.
852 MagickExport int EOFBlob(const Image *image)
854 assert(image != (Image *) NULL);
855 assert(image->signature == MagickSignature);
856 if (image->debug != MagickFalse)
857 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
858 assert(image->blob != (BlobInfo *) NULL);
859 assert(image->blob->type != UndefinedStream);
860 switch (image->blob->type)
862 case UndefinedStream:
868 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
874 image->blob->eof=MagickFalse;
879 #if defined(MAGICKCORE_BZLIB_DELEGATE)
884 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
885 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
891 image->blob->eof=MagickFalse;
897 return((int) image->blob->eof);
901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
905 + F i l e T o B l o b %
909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
911 % FileToBlob() returns the contents of a file as a buffer terminated with
912 % the '\0' character. The length of the buffer (not including the extra
913 % terminating '\0' character) is returned via the 'length' parameter. Free
914 % the buffer with RelinquishMagickMemory().
916 % The format of the FileToBlob method is:
918 % unsigned char *FileToBlob(const char *filename,const size_t extent,
919 % size_t *length,ExceptionInfo *exception)
921 % A description of each parameter follows:
923 % o blob: FileToBlob() returns the contents of a file as a blob. If
924 % an error occurs NULL is returned.
926 % o filename: the filename.
928 % o extent: The maximum length of the blob.
930 % o length: On return, this reflects the actual length of the blob.
932 % o exception: return any errors or warnings in this structure.
935 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
936 size_t *length,ExceptionInfo *exception)
956 assert(filename != (const char *) NULL);
957 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
958 assert(exception != (ExceptionInfo *) NULL);
961 if (LocaleCompare(filename,"-") != 0)
962 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
965 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
966 return((unsigned char *) NULL);
968 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
970 if ((file == fileno(stdin)) || (offset < 0) ||
971 (offset != (MagickOffsetType) ((ssize_t) offset)))
980 Stream is not seekable.
982 offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
983 quantum=(size_t) MagickMaxBufferExtent;
984 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
985 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
986 MagickMaxBufferExtent);
987 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
988 for (i=0; blob != (unsigned char *) NULL; i+=count)
990 count=read(file,blob+i,quantum);
997 if (~((size_t) i) < (quantum+1))
999 blob=(unsigned char *) RelinquishMagickMemory(blob);
1002 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
1004 if ((size_t) (i+count) >= extent)
1007 if (LocaleCompare(filename,"-") != 0)
1009 if (blob == (unsigned char *) NULL)
1011 (void) ThrowMagickException(exception,GetMagickModule(),
1012 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1013 return((unsigned char *) NULL);
1017 blob=(unsigned char *) RelinquishMagickMemory(blob);
1018 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1019 return((unsigned char *) NULL);
1021 *length=(size_t) MagickMin(i+count,extent);
1025 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
1026 blob=(unsigned char *) NULL;
1027 if (~(*length) >= (MaxTextExtent-1))
1028 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
1030 if (blob == (unsigned char *) NULL)
1033 (void) ThrowMagickException(exception,GetMagickModule(),
1034 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1035 return((unsigned char *) NULL);
1037 map=MapBlob(file,ReadMode,0,*length);
1038 if (map != (unsigned char *) NULL)
1040 (void) memcpy(blob,map,*length);
1041 (void) UnmapBlob(map,*length);
1045 (void) lseek(file,0,SEEK_SET);
1046 for (i=0; i < *length; i+=count)
1048 count=read(file,blob+i,(size_t) MagickMin(*length-i,(MagickSizeType)
1060 blob=(unsigned char *) RelinquishMagickMemory(blob);
1061 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1062 return((unsigned char *) NULL);
1066 if (LocaleCompare(filename,"-") != 0)
1070 blob=(unsigned char *) RelinquishMagickMemory(blob);
1071 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081 % F i l e T o I m a g e %
1085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087 % FileToImage() write the contents of a file to an image.
1089 % The format of the FileToImage method is:
1091 % MagickBooleanType FileToImage(Image *,const char *filename)
1093 % A description of each parameter follows:
1095 % o image: the image.
1097 % o filename: the filename.
1101 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1102 const unsigned char *data)
1107 register unsigned char
1110 assert(image->blob != (BlobInfo *) NULL);
1111 if (image->blob->type != BlobStream)
1112 return(WriteBlob(image,length,data));
1113 assert(image->blob->type != UndefinedStream);
1114 assert(data != (void *) NULL);
1115 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1116 if (extent >= image->blob->extent)
1118 extent=image->blob->extent+image->blob->quantum+length;
1119 image->blob->quantum<<=1;
1120 if (SetBlobExtent(image,extent) == MagickFalse)
1123 q=image->blob->data+image->blob->offset;
1124 (void) memcpy(q,data,length);
1125 image->blob->offset+=length;
1126 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1127 image->blob->length=(size_t) image->blob->offset;
1128 return((ssize_t) length);
1131 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1132 ExceptionInfo *exception)
1150 assert(image != (const Image *) NULL);
1151 assert(image->signature == MagickSignature);
1152 assert(filename != (const char *) NULL);
1153 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1155 if (LocaleCompare(filename,"-") != 0)
1156 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1159 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1160 return(MagickFalse);
1162 quantum=(size_t) MagickMaxBufferExtent;
1163 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1164 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1165 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1166 if (blob == (unsigned char *) NULL)
1169 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1171 return(MagickFalse);
1175 count=read(file,blob,quantum);
1182 length=(size_t) count;
1183 count=WriteBlobStream(image,length,blob);
1184 if (count != (ssize_t) length)
1186 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1192 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1193 blob=(unsigned char *) RelinquishMagickMemory(blob);
1198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1202 + G e t B l o b E r r o r %
1206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1208 % GetBlobError() returns MagickTrue if the blob associated with the specified
1209 % image encountered an error.
1211 % The format of the GetBlobError method is:
1213 % MagickBooleanType GetBlobError(const Image *image)
1215 % A description of each parameter follows:
1217 % o image: the image.
1220 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1222 assert(image != (const Image *) NULL);
1223 assert(image->signature == MagickSignature);
1224 if (image->debug != MagickFalse)
1225 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1226 return(image->blob->status);
1230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1234 + G e t B l o b F i l e H a n d l e %
1238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1240 % GetBlobFileHandle() returns the file handle associated with the image blob.
1242 % The format of the GetBlobFile method is:
1244 % FILE *GetBlobFileHandle(const Image *image)
1246 % A description of each parameter follows:
1248 % o image: the image.
1251 MagickExport FILE *GetBlobFileHandle(const Image *image)
1253 assert(image != (const Image *) NULL);
1254 assert(image->signature == MagickSignature);
1255 return(image->blob->file_info.file);
1259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1263 + G e t B l o b I n f o %
1267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1269 % GetBlobInfo() initializes the BlobInfo structure.
1271 % The format of the GetBlobInfo method is:
1273 % void GetBlobInfo(BlobInfo *blob_info)
1275 % A description of each parameter follows:
1277 % o blob_info: Specifies a pointer to a BlobInfo structure.
1280 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1282 assert(blob_info != (BlobInfo *) NULL);
1283 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1284 blob_info->type=UndefinedStream;
1285 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1286 blob_info->properties.st_mtime=time((time_t *) NULL);
1287 blob_info->properties.st_ctime=time((time_t *) NULL);
1288 blob_info->debug=IsEventLogging();
1289 blob_info->reference_count=1;
1290 blob_info->semaphore=AcquireSemaphoreInfo();
1291 blob_info->signature=MagickSignature;
1295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1299 % G e t B l o b P r o p e r t i e s %
1303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1305 % GetBlobProperties() returns information about an image blob.
1307 % The format of the GetBlobProperties method is:
1309 % const struct stat *GetBlobProperties(const Image *image)
1311 % A description of each parameter follows:
1313 % o image: the image.
1316 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1318 assert(image != (Image *) NULL);
1319 assert(image->signature == MagickSignature);
1320 if (image->debug != MagickFalse)
1321 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1322 return(&image->blob->properties);
1326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1330 + G e t B l o b S i z e %
1334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1336 % GetBlobSize() returns the current length of the image file or blob; zero is
1337 % returned if the size cannot be determined.
1339 % The format of the GetBlobSize method is:
1341 % MagickSizeType GetBlobSize(const Image *image)
1343 % A description of each parameter follows:
1345 % o image: the image.
1348 MagickExport MagickSizeType GetBlobSize(const Image *image)
1353 assert(image != (Image *) NULL);
1354 assert(image->signature == MagickSignature);
1355 if (image->debug != MagickFalse)
1356 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1357 assert(image->blob != (BlobInfo *) NULL);
1359 switch (image->blob->type)
1361 case UndefinedStream:
1363 extent=image->blob->size;
1366 case StandardStream:
1368 extent=image->blob->size;
1373 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1374 extent=(MagickSizeType) image->blob->properties.st_size;
1379 extent=image->blob->size;
1388 status=GetPathAttributes(image->filename,&image->blob->properties);
1389 if (status != MagickFalse)
1390 extent=(MagickSizeType) image->blob->properties.st_size;
1397 extent=(MagickSizeType) image->blob->length;
1405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409 + G e t B l o b S t r e a m D a t a %
1413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415 % GetBlobStreamData() returns the stream data for the image.
1417 % The format of the GetBlobStreamData method is:
1419 % unsigned char *GetBlobStreamData(const Image *image)
1421 % A description of each parameter follows:
1423 % o image: the image.
1426 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1428 assert(image != (const Image *) NULL);
1429 assert(image->signature == MagickSignature);
1430 return(image->blob->data);
1434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1438 + G e t B l o b S t r e a m H a n d l e r %
1442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1444 % GetBlobStreamHandler() returns the stream handler for the image.
1446 % The format of the GetBlobStreamHandler method is:
1448 % StreamHandler GetBlobStreamHandler(const Image *image)
1450 % A description of each parameter follows:
1452 % o image: the image.
1455 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1457 assert(image != (const Image *) NULL);
1458 assert(image->signature == MagickSignature);
1459 if (image->debug != MagickFalse)
1460 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1461 return(image->blob->stream);
1465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1469 % I m a g e T o B l o b %
1473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1475 % ImageToBlob() implements direct to memory image formats. It returns the
1476 % image as a formatted blob and its length. The magick member of the Image
1477 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1478 % etc.). This method is the equivalent of WriteImage(), but writes the
1479 % formatted "file" to a memory buffer rather than to an actual file.
1481 % The format of the ImageToBlob method is:
1483 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1484 % size_t *length,ExceptionInfo *exception)
1486 % A description of each parameter follows:
1488 % o image_info: the image info.
1490 % o image: the image.
1492 % o length: return the actual length of the blob.
1494 % o exception: return any errors or warnings in this structure.
1497 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1498 Image *image,size_t *length,ExceptionInfo *exception)
1512 assert(image_info != (const ImageInfo *) NULL);
1513 assert(image_info->signature == MagickSignature);
1514 if (image_info->debug != MagickFalse)
1515 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1516 image_info->filename);
1517 assert(image != (Image *) NULL);
1518 assert(image->signature == MagickSignature);
1519 assert(exception != (ExceptionInfo *) NULL);
1521 blob=(unsigned char *) NULL;
1522 blob_info=CloneImageInfo(image_info);
1523 blob_info->adjoin=MagickFalse;
1524 (void) SetImageInfo(blob_info,1,exception);
1525 if (*blob_info->magick != '\0')
1526 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1527 magick_info=GetMagickInfo(image->magick,exception);
1528 if (magick_info == (const MagickInfo *) NULL)
1530 (void) ThrowMagickException(exception,GetMagickModule(),
1531 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1533 blob_info=DestroyImageInfo(blob_info);
1536 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1537 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1540 Native blob support for this image format.
1542 blob_info->length=0;
1543 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1544 sizeof(unsigned char));
1545 if (blob_info->blob == (void *) NULL)
1546 (void) ThrowMagickException(exception,GetMagickModule(),
1547 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1550 (void) CloseBlob(image);
1551 image->blob->exempt=MagickTrue;
1552 *image->filename='\0';
1553 status=WriteImage(blob_info,image,exception);
1554 *length=image->blob->length;
1555 blob=DetachBlob(image->blob);
1556 if (status == MagickFalse)
1557 blob=(unsigned char *) RelinquishMagickMemory(blob);
1559 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1566 unique[MaxTextExtent];
1572 Write file to disk in blob image format.
1574 file=AcquireUniqueFileResource(unique);
1577 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1578 image_info->filename);
1582 blob_info->file=fdopen(file,"wb");
1583 if (blob_info->file != (FILE *) NULL)
1585 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1586 image->magick,unique);
1587 status=WriteImage(blob_info,image,exception);
1588 (void) CloseBlob(image);
1589 (void) fclose(blob_info->file);
1590 if (status != MagickFalse)
1591 blob=FileToBlob(unique,~0UL,length,exception);
1593 (void) RelinquishUniqueFileResource(unique);
1596 blob_info=DestroyImageInfo(blob_info);
1601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1605 % I m a g e T o F i l e %
1609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1611 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1612 % occurs otherwise MagickTrue.
1614 % The format of the ImageToFile method is:
1616 % MagickBooleanType ImageToFile(Image *image,char *filename,
1617 % ExceptionInfo *exception)
1619 % A description of each parameter follows:
1621 % o image: the image.
1623 % o filename: Write the image to this file.
1625 % o exception: return any errors or warnings in this structure.
1628 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1629 ExceptionInfo *exception)
1634 register const unsigned char
1653 assert(image != (Image *) NULL);
1654 assert(image->signature == MagickSignature);
1655 assert(image->blob != (BlobInfo *) NULL);
1656 assert(image->blob->type != UndefinedStream);
1657 if (image->debug != MagickFalse)
1658 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1659 assert(filename != (const char *) NULL);
1660 if (*filename == '\0')
1661 file=AcquireUniqueFileResource(filename);
1663 if (LocaleCompare(filename,"-") == 0)
1664 file=fileno(stdout);
1666 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1669 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1670 return(MagickFalse);
1672 quantum=(size_t) MagickMaxBufferExtent;
1673 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1674 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
1675 MagickMaxBufferExtent);
1676 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1677 if (buffer == (unsigned char *) NULL)
1680 (void) ThrowMagickException(exception,GetMagickModule(),
1681 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1682 return(MagickFalse);
1685 p=ReadBlobStream(image,quantum,buffer,&count);
1686 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1688 length=(size_t) count;
1689 for (i=0; i < length; i+=count)
1691 count=write(file,p+i,(size_t) (length-i));
1702 if (LocaleCompare(filename,"-") != 0)
1704 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1705 if ((file == -1) || (i < length))
1709 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1710 return(MagickFalse);
1716 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1720 % I m a g e s T o B l o b %
1724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1726 % ImagesToBlob() implements direct to memory image formats. It returns the
1727 % image sequence as a blob and its length. The magick member of the ImageInfo
1728 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1730 % Note, some image formats do not permit multiple images to the same image
1731 % stream (e.g. JPEG). in this instance, just the first image of the
1732 % sequence is returned as a blob.
1734 % The format of the ImagesToBlob method is:
1736 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1737 % size_t *length,ExceptionInfo *exception)
1739 % A description of each parameter follows:
1741 % o image_info: the image info.
1743 % o images: the image list.
1745 % o length: return the actual length of the blob.
1747 % o exception: return any errors or warnings in this structure.
1750 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1751 Image *images,size_t *length,ExceptionInfo *exception)
1765 assert(image_info != (const ImageInfo *) NULL);
1766 assert(image_info->signature == MagickSignature);
1767 if (image_info->debug != MagickFalse)
1768 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1769 image_info->filename);
1770 assert(images != (Image *) NULL);
1771 assert(images->signature == MagickSignature);
1772 assert(exception != (ExceptionInfo *) NULL);
1774 blob=(unsigned char *) NULL;
1775 blob_info=CloneImageInfo(image_info);
1776 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1778 if (*blob_info->magick != '\0')
1779 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1780 magick_info=GetMagickInfo(images->magick,exception);
1781 if (magick_info == (const MagickInfo *) NULL)
1783 (void) ThrowMagickException(exception,GetMagickModule(),
1784 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1786 blob_info=DestroyImageInfo(blob_info);
1789 if (GetMagickAdjoin(magick_info) == MagickFalse)
1791 blob_info=DestroyImageInfo(blob_info);
1792 return(ImageToBlob(image_info,images,length,exception));
1794 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1795 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1798 Native blob support for this images format.
1800 blob_info->length=0;
1801 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1802 sizeof(unsigned char));
1803 if (blob_info->blob == (void *) NULL)
1804 (void) ThrowMagickException(exception,GetMagickModule(),
1805 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1808 (void) CloseBlob(images);
1809 images->blob->exempt=MagickTrue;
1810 *images->filename='\0';
1811 status=WriteImages(blob_info,images,images->filename,exception);
1812 *length=images->blob->length;
1813 blob=DetachBlob(images->blob);
1814 if (status == MagickFalse)
1815 blob=(unsigned char *) RelinquishMagickMemory(blob);
1817 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1824 filename[MaxTextExtent],
1825 unique[MaxTextExtent];
1831 Write file to disk in blob images format.
1833 file=AcquireUniqueFileResource(unique);
1836 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1837 image_info->filename);
1841 blob_info->file=fdopen(file,"wb");
1842 if (blob_info->file != (FILE *) NULL)
1844 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1845 images->magick,unique);
1846 status=WriteImages(blob_info,images,filename,exception);
1847 (void) CloseBlob(images);
1848 (void) fclose(blob_info->file);
1849 if (status != MagickFalse)
1850 blob=FileToBlob(unique,~0UL,length,exception);
1852 (void) RelinquishUniqueFileResource(unique);
1855 blob_info=DestroyImageInfo(blob_info);
1859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1863 % I n j e c t I m a g e B l o b %
1867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1869 % InjectImageBlob() injects the image with a copy of itself in the specified
1870 % format (e.g. inject JPEG into a PDF image).
1872 % The format of the InjectImageBlob method is:
1874 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1875 % Image *image,Image *inject_image,const char *format,
1876 % ExceptionInfo *exception)
1878 % A description of each parameter follows:
1880 % o image_info: the image info..
1882 % o image: the image.
1884 % o inject_image: inject into the image stream.
1886 % o format: the image format.
1888 % o exception: return any errors or warnings in this structure.
1891 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1892 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1895 filename[MaxTextExtent];
1928 Write inject image to a temporary file.
1930 assert(image_info != (ImageInfo *) NULL);
1931 assert(image_info->signature == MagickSignature);
1932 assert(image != (Image *) NULL);
1933 assert(image->signature == MagickSignature);
1934 if (image->debug != MagickFalse)
1935 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1936 assert(inject_image != (Image *) NULL);
1937 assert(inject_image->signature == MagickSignature);
1938 assert(exception != (ExceptionInfo *) NULL);
1939 unique_file=(FILE *) NULL;
1940 file=AcquireUniqueFileResource(filename);
1942 unique_file=fdopen(file,"wb");
1943 if ((file == -1) || (unique_file == (FILE *) NULL))
1945 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1946 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1948 return(MagickFalse);
1950 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1951 if (byte_image == (Image *) NULL)
1953 (void) fclose(unique_file);
1954 (void) RelinquishUniqueFileResource(filename);
1955 return(MagickFalse);
1957 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1959 DestroyBlob(byte_image);
1960 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1961 write_info=CloneImageInfo(image_info);
1962 SetImageInfoFile(write_info,unique_file);
1963 status=WriteImage(write_info,byte_image,exception);
1964 write_info=DestroyImageInfo(write_info);
1965 byte_image=DestroyImage(byte_image);
1966 (void) fclose(unique_file);
1967 if (status == MagickFalse)
1969 (void) RelinquishUniqueFileResource(filename);
1970 return(MagickFalse);
1973 Inject into image stream.
1975 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1978 (void) RelinquishUniqueFileResource(filename);
1979 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1980 image_info->filename);
1981 return(MagickFalse);
1983 quantum=(size_t) MagickMaxBufferExtent;
1984 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1985 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1986 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1987 if (buffer == (unsigned char *) NULL)
1989 (void) RelinquishUniqueFileResource(filename);
1990 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1993 for (i=0; ; i+=count)
1995 count=read(file,buffer,quantum);
2002 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2007 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2008 (void) RelinquishUniqueFileResource(filename);
2009 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2018 + I s B l o b E x e m p t %
2022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2024 % IsBlobExempt() returns true if the blob is exempt.
2026 % The format of the IsBlobExempt method is:
2028 % MagickBooleanType IsBlobExempt(const Image *image)
2030 % A description of each parameter follows:
2032 % o image: the image.
2035 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
2037 assert(image != (const Image *) NULL);
2038 assert(image->signature == MagickSignature);
2039 if (image->debug != MagickFalse)
2040 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2041 return(image->blob->exempt);
2045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2049 + I s B l o b S e e k a b l e %
2053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2055 % IsBlobSeekable() returns true if the blob is seekable.
2057 % The format of the IsBlobSeekable method is:
2059 % MagickBooleanType IsBlobSeekable(const Image *image)
2061 % A description of each parameter follows:
2063 % o image: the image.
2066 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2071 assert(image != (const Image *) NULL);
2072 assert(image->signature == MagickSignature);
2073 if (image->debug != MagickFalse)
2074 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2075 switch (image->blob->type)
2081 seekable=MagickTrue;
2086 seekable=MagickFalse;
2094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2098 + I s B l o b T e m p o r a r y %
2102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2104 % IsBlobTemporary() returns true if the blob is temporary.
2106 % The format of the IsBlobTemporary method is:
2108 % MagickBooleanType IsBlobTemporary(const Image *image)
2110 % A description of each parameter follows:
2112 % o image: the image.
2115 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2117 assert(image != (const Image *) NULL);
2118 assert(image->signature == MagickSignature);
2119 if (image->debug != MagickFalse)
2120 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2121 return(image->blob->temporary);
2125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2135 % MapBlob() creates a mapping from a file to a binary large object.
2137 % The format of the MapBlob method is:
2139 % unsigned char *MapBlob(int file,const MapMode mode,
2140 % const MagickOffsetType offset,const size_t length)
2142 % A description of each parameter follows:
2144 % o file: map this file descriptor.
2146 % o mode: ReadMode, WriteMode, or IOMode.
2148 % o offset: starting at this offset within the file.
2150 % o length: the length of the mapping is returned in this pointer.
2153 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2154 const MagickOffsetType offset,const size_t length)
2156 #if defined(MAGICKCORE_HAVE_MMAP)
2169 #if defined(MAP_ANONYMOUS)
2170 flags|=MAP_ANONYMOUS;
2172 return((unsigned char *) NULL);
2179 protection=PROT_READ;
2185 protection=PROT_WRITE;
2191 protection=PROT_READ | PROT_WRITE;
2196 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2197 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2200 map=(unsigned char *) mmap((char *) NULL,length,protection,flags |
2201 MAP_HUGETLB,file,(off_t) offset);
2202 if (map == (unsigned char *) MAP_FAILED)
2203 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2206 if (map == (unsigned char *) MAP_FAILED)
2207 return((unsigned char *) NULL);
2214 return((unsigned char *) NULL);
2219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2223 + M S B O r d e r L o n g %
2227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2229 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2230 % most-significant byte first.
2232 % The format of the MSBOrderLong method is:
2234 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2236 % A description of each parameter follows.
2238 % o buffer: Specifies a pointer to a buffer of integers.
2240 % o length: Specifies the length of the buffer.
2243 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2248 register unsigned char
2252 assert(buffer != (unsigned char *) NULL);
2259 *buffer++=(unsigned char) c;
2263 *buffer++=(unsigned char) c;
2269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2273 + M S B O r d e r S h o r t %
2277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2279 % MSBOrderShort() converts a least-significant byte first buffer of integers
2280 % to most-significant byte first.
2282 % The format of the MSBOrderShort method is:
2284 % void MSBOrderShort(unsigned char *p,const size_t length)
2286 % A description of each parameter follows.
2288 % o p: Specifies a pointer to a buffer of integers.
2290 % o length: Specifies the length of the buffer.
2293 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2298 register unsigned char
2301 assert(p != (unsigned char *) NULL);
2308 *p++=(unsigned char) c;
2313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2323 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2324 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2325 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2326 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2327 % from a system command.
2329 % The format of the OpenBlob method is:
2331 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2332 % const BlobMode mode,ExceptionInfo *exception)
2334 % A description of each parameter follows:
2336 % o image_info: the image info.
2338 % o image: the image.
2340 % o mode: the mode for opening the file.
2343 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2344 Image *image,const BlobMode mode,ExceptionInfo *exception)
2347 extension[MaxTextExtent],
2348 filename[MaxTextExtent];
2359 assert(image_info != (ImageInfo *) NULL);
2360 assert(image_info->signature == MagickSignature);
2361 if (image_info->debug != MagickFalse)
2362 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2363 image_info->filename);
2364 assert(image != (Image *) NULL);
2365 assert(image->signature == MagickSignature);
2366 if (image_info->blob != (void *) NULL)
2368 if (image_info->stream != (StreamHandler) NULL)
2369 image->blob->stream=(StreamHandler) image_info->stream;
2370 AttachBlob(image->blob,image_info->blob,image_info->length);
2373 (void) DetachBlob(image->blob);
2376 default: type="r"; break;
2377 case ReadBlobMode: type="r"; break;
2378 case ReadBinaryBlobMode: type="rb"; break;
2379 case WriteBlobMode: type="w"; break;
2380 case WriteBinaryBlobMode: type="w+b"; break;
2381 case AppendBlobMode: type="a"; break;
2382 case AppendBinaryBlobMode: type="a+b"; break;
2385 image->blob->synchronize=image_info->synchronize;
2386 if (image_info->stream != (StreamHandler) NULL)
2388 image->blob->stream=(StreamHandler) image_info->stream;
2391 image->blob->type=FifoStream;
2399 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2400 rights=ReadPolicyRights;
2402 rights=WritePolicyRights;
2403 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2406 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2407 "NotAuthorized","`%s'",filename);
2408 return(MagickFalse);
2410 if ((LocaleCompare(filename,"-") == 0) ||
2411 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2413 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2414 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2415 if (strchr(type,'b') != (char *) NULL)
2416 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2418 image->blob->type=StandardStream;
2419 image->blob->exempt=MagickTrue;
2422 if (LocaleNCompare(filename,"fd:",3) == 0)
2425 mode[MaxTextExtent];
2429 image->blob->file_info.file=fdopen(StringToLong(filename+3),mode);
2430 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2431 if (strchr(type,'b') != (char *) NULL)
2432 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2434 image->blob->type=StandardStream;
2435 image->blob->exempt=MagickTrue;
2438 #if defined(MAGICKCORE_HAVE_POPEN)
2439 if (*filename == '|')
2442 mode[MaxTextExtent];
2445 Pipe image to or from a system command.
2447 #if defined(SIGPIPE)
2449 (void) signal(SIGPIPE,SIG_IGN);
2453 image->blob->file_info.file=(FILE *) popen_utf8(filename+1,mode);
2454 if (image->blob->file_info.file == (FILE *) NULL)
2456 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2457 return(MagickFalse);
2459 image->blob->type=PipeStream;
2460 image->blob->exempt=MagickTrue;
2464 status=GetPathAttributes(filename,&image->blob->properties);
2465 #if defined(S_ISFIFO)
2466 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2468 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2469 if (image->blob->file_info.file == (FILE *) NULL)
2471 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2472 return(MagickFalse);
2474 image->blob->type=FileStream;
2475 image->blob->exempt=MagickTrue;
2479 GetPathComponent(image->filename,ExtensionPath,extension);
2482 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2483 if ((image_info->adjoin == MagickFalse) ||
2484 (strchr(filename,'%') != (char *) NULL))
2487 Form filename for multi-part images.
2489 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2490 image->scene,filename,exception);
2491 if ((LocaleCompare(filename,image->filename) == 0) &&
2492 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2493 (GetNextImageInList(image) != (Image *) NULL)))
2496 path[MaxTextExtent];
2498 GetPathComponent(image->filename,RootPath,path);
2499 if (*extension == '\0')
2500 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2501 path,(double) image->scene);
2503 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2504 path,(double) image->scene,extension);
2506 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2507 #if defined(macintosh)
2508 SetApplicationType(filename,image_info->magick,'8BIM');
2512 if (image_info->file != (FILE *) NULL)
2514 image->blob->file_info.file=image_info->file;
2515 image->blob->type=FileStream;
2516 image->blob->exempt=MagickTrue;
2521 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2522 if (image->blob->file_info.file != (FILE *) NULL)
2530 image->blob->type=FileStream;
2531 #if defined(MAGICKCORE_HAVE_SETVBUF)
2532 (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
2535 (void) ResetMagickMemory(magick,0,sizeof(magick));
2536 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2537 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2538 (void) fflush(image->blob->file_info.file);
2539 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2540 " read %.20g magic header bytes",(double) count);
2541 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2542 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2543 ((int) magick[2] == 0x08))
2545 (void) fclose(image->blob->file_info.file);
2546 image->blob->file_info.gzfile=gzopen(filename,type);
2547 if (image->blob->file_info.gzfile != (gzFile) NULL)
2548 image->blob->type=ZipStream;
2551 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2552 if (strncmp((char *) magick,"BZh",3) == 0)
2554 (void) fclose(image->blob->file_info.file);
2555 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2556 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2557 image->blob->type=BZipStream;
2560 if (image->blob->type == FileStream)
2571 sans_exception=AcquireExceptionInfo();
2572 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2573 sans_exception=DestroyExceptionInfo(sans_exception);
2574 length=(size_t) image->blob->properties.st_size;
2575 if ((magick_info != (const MagickInfo *) NULL) &&
2576 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2577 (length <= MagickMaxBufferExtent) &&
2578 (AcquireMagickResource(MapResource,length) != MagickFalse))
2583 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
2585 if (blob == (void *) NULL)
2586 RelinquishMagickResource(MapResource,length);
2590 Format supports blobs-- use memory-mapped I/O.
2592 if (image_info->file != (FILE *) NULL)
2593 image->blob->exempt=MagickFalse;
2596 (void) fclose(image->blob->file_info.file);
2597 image->blob->file_info.file=(FILE *) NULL;
2599 AttachBlob(image->blob,blob,length);
2600 image->blob->mapped=MagickTrue;
2607 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2608 if ((LocaleCompare(extension,"Z") == 0) ||
2609 (LocaleCompare(extension,"gz") == 0) ||
2610 (LocaleCompare(extension,"wmz") == 0) ||
2611 (LocaleCompare(extension,"svgz") == 0))
2613 if (mode == WriteBinaryBlobMode)
2615 image->blob->file_info.gzfile=gzopen(filename,type);
2616 if (image->blob->file_info.gzfile != (gzFile) NULL)
2617 image->blob->type=ZipStream;
2621 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2622 if (LocaleCompare(extension,"bz2") == 0)
2624 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2625 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2626 image->blob->type=BZipStream;
2631 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2632 if (image->blob->file_info.file != (FILE *) NULL)
2634 image->blob->type=FileStream;
2635 #if defined(MAGICKCORE_HAVE_SETVBUF)
2636 (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
2641 image->blob->status=MagickFalse;
2642 if (image->blob->type != UndefinedStream)
2643 image->blob->size=GetBlobSize(image);
2646 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2647 return(MagickFalse);
2653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2663 % PingBlob() returns all the attributes of an image or image sequence except
2664 % for the pixels. It is much faster and consumes far less memory than
2665 % BlobToImage(). On failure, a NULL image is returned and exception
2666 % describes the reason for the failure.
2668 % The format of the PingBlob method is:
2670 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2671 % const size_t length,ExceptionInfo *exception)
2673 % A description of each parameter follows:
2675 % o image_info: the image info.
2677 % o blob: the address of a character stream in one of the image formats
2678 % understood by ImageMagick.
2680 % o length: This size_t integer reflects the length in bytes of the blob.
2682 % o exception: return any errors or warnings in this structure.
2686 #if defined(__cplusplus) || defined(c_plusplus)
2690 static size_t PingStream(const Image *magick_unused(image),
2691 const void *magick_unused(pixels),const size_t columns)
2696 #if defined(__cplusplus) || defined(c_plusplus)
2700 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2701 const size_t length,ExceptionInfo *exception)
2709 assert(image_info != (ImageInfo *) NULL);
2710 assert(image_info->signature == MagickSignature);
2711 if (image_info->debug != MagickFalse)
2712 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2713 image_info->filename);
2714 assert(exception != (ExceptionInfo *) NULL);
2715 if ((blob == (const void *) NULL) || (length == 0))
2717 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2718 "UnrecognizedImageFormat","`%s'",image_info->magick);
2719 return((Image *) NULL);
2721 ping_info=CloneImageInfo(image_info);
2722 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2723 if (ping_info->blob == (const void *) NULL)
2725 (void) ThrowMagickException(exception,GetMagickModule(),
2726 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2727 return((Image *) NULL);
2729 (void) memcpy(ping_info->blob,blob,length);
2730 ping_info->length=length;
2731 ping_info->ping=MagickTrue;
2732 image=ReadStream(ping_info,&PingStream,exception);
2733 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2734 ping_info=DestroyImageInfo(ping_info);
2739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2747 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2749 % ReadBlob() reads data from the blob or image file and returns it. It
2750 % returns the number of bytes read. If length is zero, ReadBlob() returns
2751 % zero and has no other results. If length is greater than SSIZE_MAX, the
2752 % result is unspecified.
2754 % The format of the ReadBlob method is:
2756 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2758 % A description of each parameter follows:
2760 % o image: the image.
2762 % o length: Specifies an integer representing the number of bytes to read
2765 % o data: Specifies an area to place the information requested from the
2769 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2770 unsigned char *data)
2775 register unsigned char
2781 assert(image != (Image *) NULL);
2782 assert(image->signature == MagickSignature);
2783 assert(image->blob != (BlobInfo *) NULL);
2784 assert(image->blob->type != UndefinedStream);
2787 assert(data != (void *) NULL);
2790 switch (image->blob->type)
2792 case UndefinedStream:
2794 case StandardStream:
2799 for (i=0; i < (ssize_t) length; i+=count)
2801 count=read(fileno(image->blob->file_info.file),q+i,(size_t)
2802 MagickMin(length-i,(MagickSizeType) SSIZE_MAX));
2820 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
2825 c=getc(image->blob->file_info.file);
2828 *q++=(unsigned char) c;
2833 c=getc(image->blob->file_info.file);
2836 *q++=(unsigned char) c;
2846 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2851 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
2852 (unsigned int) length);
2857 c=gzgetc(image->blob->file_info.gzfile);
2860 *q++=(unsigned char) c;
2865 c=gzgetc(image->blob->file_info.gzfile);
2868 *q++=(unsigned char) c;
2879 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2880 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
2888 register const unsigned char
2891 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2893 image->blob->eof=MagickTrue;
2896 p=image->blob->data+image->blob->offset;
2897 count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
2898 image->blob->offset));
2899 image->blob->offset+=count;
2900 if (count != (ssize_t) length)
2901 image->blob->eof=MagickTrue;
2902 (void) memcpy(q,p,(size_t) count);
2910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2914 + R e a d B l o b B y t e %
2918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2920 % ReadBlobByte() reads a single byte from the image file and returns it.
2922 % The format of the ReadBlobByte method is:
2924 % int ReadBlobByte(Image *image)
2926 % A description of each parameter follows.
2928 % o image: the image.
2931 MagickExport int ReadBlobByte(Image *image)
2933 register const unsigned char
2942 assert(image != (Image *) NULL);
2943 assert(image->signature == MagickSignature);
2944 p=ReadBlobStream(image,1,buffer,&count);
2951 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2955 + R e a d B l o b D o u b l e %
2959 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2961 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2962 % specified by the endian member of the image structure.
2964 % The format of the ReadBlobDouble method is:
2966 % double ReadBlobDouble(Image *image)
2968 % A description of each parameter follows.
2970 % o image: the image.
2973 MagickExport double ReadBlobDouble(Image *image)
2984 quantum.double_value=0.0;
2985 quantum.unsigned_value=ReadBlobLongLong(image);
2986 return(quantum.double_value);
2990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2994 + R e a d B l o b F l o a t %
2998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3000 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3001 % specified by the endian member of the image structure.
3003 % The format of the ReadBlobFloat method is:
3005 % float ReadBlobFloat(Image *image)
3007 % A description of each parameter follows.
3009 % o image: the image.
3012 MagickExport float ReadBlobFloat(Image *image)
3023 quantum.float_value=0.0;
3024 quantum.unsigned_value=ReadBlobLong(image);
3025 return(quantum.float_value);
3029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3033 + R e a d B l o b L o n g %
3037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3039 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
3040 % specified by the endian member of the image structure.
3042 % The format of the ReadBlobLong method is:
3044 % unsigned int ReadBlobLong(Image *image)
3046 % A description of each parameter follows.
3048 % o image: the image.
3051 MagickExport unsigned int ReadBlobLong(Image *image)
3053 register const unsigned char
3065 assert(image != (Image *) NULL);
3066 assert(image->signature == MagickSignature);
3068 p=ReadBlobStream(image,4,buffer,&count);
3071 if (image->endian == LSBEndian)
3073 value=(unsigned int) (*p++);
3074 value|=((unsigned int) (*p++)) << 8;
3075 value|=((unsigned int) (*p++)) << 16;
3076 value|=((unsigned int) (*p++)) << 24;
3079 value=((unsigned int) (*p++)) << 24;
3080 value|=((unsigned int) (*p++)) << 16;
3081 value|=((unsigned int) (*p++)) << 8;
3082 value|=((unsigned int) (*p++));
3087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3091 + R e a d B l o b L o n g L o n g %
3095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3097 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3098 % byte-order specified by the endian member of the image structure.
3100 % The format of the ReadBlobLongLong method is:
3102 % MagickSizeType ReadBlobLongLong(Image *image)
3104 % A description of each parameter follows.
3106 % o image: the image.
3109 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3114 register const unsigned char
3123 assert(image != (Image *) NULL);
3124 assert(image->signature == MagickSignature);
3126 p=ReadBlobStream(image,8,buffer,&count);
3128 return(MagickULLConstant(0));
3129 if (image->endian == LSBEndian)
3131 value=(MagickSizeType) (*p++);
3132 value|=((MagickSizeType) (*p++)) << 8;
3133 value|=((MagickSizeType) (*p++)) << 16;
3134 value|=((MagickSizeType) (*p++)) << 24;
3135 value|=((MagickSizeType) (*p++)) << 32;
3136 value|=((MagickSizeType) (*p++)) << 40;
3137 value|=((MagickSizeType) (*p++)) << 48;
3138 value|=((MagickSizeType) (*p++)) << 56;
3139 return(value & MagickULLConstant(0xffffffffffffffff));
3141 value=((MagickSizeType) (*p++)) << 56;
3142 value|=((MagickSizeType) (*p++)) << 48;
3143 value|=((MagickSizeType) (*p++)) << 40;
3144 value|=((MagickSizeType) (*p++)) << 32;
3145 value|=((MagickSizeType) (*p++)) << 24;
3146 value|=((MagickSizeType) (*p++)) << 16;
3147 value|=((MagickSizeType) (*p++)) << 8;
3148 value|=((MagickSizeType) (*p++));
3149 return(value & MagickULLConstant(0xffffffffffffffff));
3153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3157 + R e a d B l o b S h o r t %
3161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3163 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3164 % specified by the endian member of the image structure.
3166 % The format of the ReadBlobShort method is:
3168 % unsigned short ReadBlobShort(Image *image)
3170 % A description of each parameter follows.
3172 % o image: the image.
3175 MagickExport unsigned short ReadBlobShort(Image *image)
3177 register const unsigned char
3180 register unsigned int
3189 assert(image != (Image *) NULL);
3190 assert(image->signature == MagickSignature);
3192 p=ReadBlobStream(image,2,buffer,&count);
3194 return((unsigned short) 0U);
3195 if (image->endian == LSBEndian)
3197 value=(unsigned int) (*p++);
3198 value|=((unsigned int) (*p++)) << 8;
3199 return((unsigned short) (value & 0xffff));
3201 value=(unsigned int) ((*p++) << 8);
3202 value|=(unsigned int) (*p++);
3203 return((unsigned short) (value & 0xffff));
3207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3211 + R e a d B l o b L S B L o n g %
3215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3217 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3218 % least-significant byte first order.
3220 % The format of the ReadBlobLSBLong method is:
3222 % unsigned int ReadBlobLSBLong(Image *image)
3224 % A description of each parameter follows.
3226 % o image: the image.
3229 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3231 register const unsigned char
3234 register unsigned int
3243 assert(image != (Image *) NULL);
3244 assert(image->signature == MagickSignature);
3246 p=ReadBlobStream(image,4,buffer,&count);
3249 value=(unsigned int) (*p++);
3250 value|=((unsigned int) (*p++)) << 8;
3251 value|=((unsigned int) (*p++)) << 16;
3252 value|=((unsigned int) (*p++)) << 24;
3257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3261 + R e a d B l o b L S B S h o r t %
3265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3267 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3268 % least-significant byte first order.
3270 % The format of the ReadBlobLSBShort method is:
3272 % unsigned short ReadBlobLSBShort(Image *image)
3274 % A description of each parameter follows.
3276 % o image: the image.
3279 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3281 register const unsigned char
3284 register unsigned int
3293 assert(image != (Image *) NULL);
3294 assert(image->signature == MagickSignature);
3296 p=ReadBlobStream(image,2,buffer,&count);
3298 return((unsigned short) 0U);
3299 value=(unsigned int) (*p++);
3300 value|=((unsigned int) ((*p++)) << 8);
3301 return((unsigned short) (value & 0xffff));
3305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3309 + R e a d B l o b M S B L o n g %
3313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3315 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3316 % most-significant byte first order.
3318 % The format of the ReadBlobMSBLong method is:
3320 % unsigned int ReadBlobMSBLong(Image *image)
3322 % A description of each parameter follows.
3324 % o image: the image.
3327 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3329 register const unsigned char
3332 register unsigned int
3341 assert(image != (Image *) NULL);
3342 assert(image->signature == MagickSignature);
3344 p=ReadBlobStream(image,4,buffer,&count);
3347 value=((unsigned int) (*p++) << 24);
3348 value|=((unsigned int) (*p++) << 16);
3349 value|=((unsigned int) (*p++) << 8);
3350 value|=(unsigned int) (*p++);
3355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3359 + R e a d B l o b M S B L o n g L o n g %
3363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3365 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3366 % most-significant byte first order.
3368 % The format of the ReadBlobMSBLongLong method is:
3370 % unsigned int ReadBlobMSBLongLong(Image *image)
3372 % A description of each parameter follows.
3374 % o image: the image.
3377 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3379 register const unsigned char
3382 register MagickSizeType
3391 assert(image != (Image *) NULL);
3392 assert(image->signature == MagickSignature);
3394 p=ReadBlobStream(image,8,buffer,&count);
3396 return(MagickULLConstant(0));
3397 value=((MagickSizeType) (*p++)) << 56;
3398 value|=((MagickSizeType) (*p++)) << 48;
3399 value|=((MagickSizeType) (*p++)) << 40;
3400 value|=((MagickSizeType) (*p++)) << 32;
3401 value|=((MagickSizeType) (*p++)) << 24;
3402 value|=((MagickSizeType) (*p++)) << 16;
3403 value|=((MagickSizeType) (*p++)) << 8;
3404 value|=((MagickSizeType) (*p++));
3405 return(value & MagickULLConstant(0xffffffffffffffff));
3409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3413 + R e a d B l o b M S B S h o r t %
3417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3419 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3420 % most-significant byte first order.
3422 % The format of the ReadBlobMSBShort method is:
3424 % unsigned short ReadBlobMSBShort(Image *image)
3426 % A description of each parameter follows.
3428 % o image: the image.
3431 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3433 register const unsigned char
3436 register unsigned int
3445 assert(image != (Image *) NULL);
3446 assert(image->signature == MagickSignature);
3448 p=ReadBlobStream(image,2,buffer,&count);
3450 return((unsigned short) 0U);
3451 value=(unsigned int) ((*p++) << 8);
3452 value|=(unsigned int) (*p++);
3453 return((unsigned short) (value & 0xffff));
3457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3461 + R e a d B l o b S t r i n g %
3465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3467 % ReadBlobString() reads characters from a blob or file until a newline
3468 % character is read or an end-of-file condition is encountered.
3470 % The format of the ReadBlobString method is:
3472 % char *ReadBlobString(Image *image,char *string)
3474 % A description of each parameter follows:
3476 % o image: the image.
3478 % o string: the address of a character buffer.
3481 MagickExport char *ReadBlobString(Image *image,char *string)
3483 register const unsigned char
3495 assert(image != (Image *) NULL);
3496 assert(image->signature == MagickSignature);
3497 for (i=0; i < (MaxTextExtent-1L); i++)
3499 p=ReadBlobStream(image,1,buffer,&count);
3503 return((char *) NULL);
3506 string[i]=(char) (*p);
3507 if ((string[i] == '\r') || (string[i] == '\n'))
3510 if (string[i] == '\r')
3511 (void) ReadBlobStream(image,1,buffer,&count);
3517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3521 + R e f e r e n c e B l o b %
3525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3527 % ReferenceBlob() increments the reference count associated with the pixel
3528 % blob returning a pointer to the blob.
3530 % The format of the ReferenceBlob method is:
3532 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3534 % A description of each parameter follows:
3536 % o blob_info: the blob_info.
3539 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3541 assert(blob != (BlobInfo *) NULL);
3542 assert(blob->signature == MagickSignature);
3543 if (blob->debug != MagickFalse)
3544 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3545 LockSemaphoreInfo(blob->semaphore);
3546 blob->reference_count++;
3547 UnlockSemaphoreInfo(blob->semaphore);
3552 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3560 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3562 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3563 % and returns the resulting offset.
3565 % The format of the SeekBlob method is:
3567 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3570 % A description of each parameter follows:
3572 % o image: the image.
3574 % o offset: Specifies an integer representing the offset in bytes.
3576 % o whence: Specifies an integer representing how the offset is
3577 % treated relative to the beginning of the blob as follows:
3579 % SEEK_SET Set position equal to offset bytes.
3580 % SEEK_CUR Set position to current location plus offset.
3581 % SEEK_END Set position to EOF plus offset.
3584 MagickExport MagickOffsetType SeekBlob(Image *image,
3585 const MagickOffsetType offset,const int whence)
3587 assert(image != (Image *) NULL);
3588 assert(image->signature == MagickSignature);
3589 if (image->debug != MagickFalse)
3590 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3591 assert(image->blob != (BlobInfo *) NULL);
3592 assert(image->blob->type != UndefinedStream);
3593 switch (image->blob->type)
3595 case UndefinedStream:
3597 case StandardStream:
3601 if (fseek(image->blob->file_info.file,offset,whence) < 0)
3603 image->blob->offset=TellBlob(image);
3609 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3610 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
3613 image->blob->offset=TellBlob(image);
3629 image->blob->offset=offset;
3634 if ((image->blob->offset+offset) < 0)
3636 image->blob->offset+=offset;
3641 if (((MagickOffsetType) image->blob->length+offset) < 0)
3643 image->blob->offset=image->blob->length+offset;
3647 if (image->blob->offset <= (MagickOffsetType)
3648 ((off_t) image->blob->length))
3649 image->blob->eof=MagickFalse;
3651 if (image->blob->mapped != MagickFalse)
3655 image->blob->extent=(size_t) (image->blob->offset+
3656 image->blob->quantum);
3657 image->blob->quantum<<=1;
3658 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3659 image->blob->data,image->blob->extent+1,
3660 sizeof(*image->blob->data));
3661 (void) SyncBlob(image);
3662 if (image->blob->data == (unsigned char *) NULL)
3664 (void) DetachBlob(image->blob);
3671 return(image->blob->offset);
3675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3679 + S e t B l o b E x e m p t %
3683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3685 % SetBlobExempt() sets the blob exempt status.
3687 % The format of the SetBlobExempt method is:
3689 % MagickBooleanType SetBlobExempt(const Image *image,
3690 % const MagickBooleanType exempt)
3692 % A description of each parameter follows:
3694 % o image: the image.
3696 % o exempt: Set to true if this blob is exempt from being closed.
3699 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3701 assert(image != (const Image *) NULL);
3702 assert(image->signature == MagickSignature);
3703 if (image->debug != MagickFalse)
3704 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3705 image->blob->exempt=exempt;
3709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3713 + S e t B l o b E x t e n t %
3717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3719 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3720 % method is successful, subsequent writes to bytes in the specified range are
3721 % guaranteed not to fail.
3723 % The format of the SetBlobExtent method is:
3725 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3727 % A description of each parameter follows:
3729 % o image: the image.
3731 % o extent: the blob maximum extent.
3734 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3735 const MagickSizeType extent)
3737 assert(image != (Image *) NULL);
3738 assert(image->signature == MagickSignature);
3739 if (image->debug != MagickFalse)
3740 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3741 assert(image->blob != (BlobInfo *) NULL);
3742 assert(image->blob->type != UndefinedStream);
3743 switch (image->blob->type)
3745 case UndefinedStream:
3747 case StandardStream:
3748 return(MagickFalse);
3757 if (extent != (MagickSizeType) ((off_t) extent))
3758 return(MagickFalse);
3759 offset=SeekBlob(image,0,SEEK_END);
3761 return(MagickFalse);
3762 if ((MagickSizeType) offset >= extent)
3764 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3765 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3766 image->blob->file_info.file);
3767 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3768 if (image->blob->synchronize != MagickFalse)
3773 status=posix_fallocate(fileno(image->blob->file_info.file),offset,
3776 return(MagickFalse);
3779 offset=SeekBlob(image,offset,SEEK_SET);
3781 return(MagickFalse);
3786 return(MagickFalse);
3788 return(MagickFalse);
3790 return(MagickFalse);
3793 if (extent != (MagickSizeType) ((size_t) extent))
3794 return(MagickFalse);
3795 if (image->blob->mapped != MagickFalse)
3803 (void) UnmapBlob(image->blob->data,image->blob->length);
3804 RelinquishMagickResource(MapResource,image->blob->length);
3805 if (extent != (MagickSizeType) ((off_t) extent))
3806 return(MagickFalse);
3807 offset=SeekBlob(image,0,SEEK_END);
3809 return(MagickFalse);
3810 if ((MagickSizeType) offset >= extent)
3812 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3813 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3814 image->blob->file_info.file);
3815 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3816 if (image->blob->synchronize != MagickFalse)
3821 status=posix_fallocate(fileno(image->blob->file_info.file),offset,
3824 return(MagickFalse);
3827 offset=SeekBlob(image,offset,SEEK_SET);
3829 return(MagickFalse);
3830 (void) AcquireMagickResource(MapResource,extent);
3831 image->blob->data=(unsigned char*) MapBlob(fileno(
3832 image->blob->file_info.file),WriteMode,0,(size_t) extent);
3833 image->blob->extent=(size_t) extent;
3834 image->blob->length=(size_t) extent;
3835 (void) SyncBlob(image);
3838 image->blob->extent=(size_t) extent;
3839 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3840 image->blob->extent+1,sizeof(*image->blob->data));
3841 (void) SyncBlob(image);
3842 if (image->blob->data == (unsigned char *) NULL)
3844 (void) DetachBlob(image->blob);
3845 return(MagickFalse);
3854 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3864 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3865 % attributes if it is an blob.
3867 % The format of the SyncBlob method is:
3869 % int SyncBlob(Image *image)
3871 % A description of each parameter follows:
3873 % o image: the image.
3876 static int SyncBlob(Image *image)
3881 assert(image != (Image *) NULL);
3882 assert(image->signature == MagickSignature);
3883 if (image->debug != MagickFalse)
3884 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3885 assert(image->blob != (BlobInfo *) NULL);
3886 assert(image->blob->type != UndefinedStream);
3888 switch (image->blob->type)
3890 case UndefinedStream:
3891 case StandardStream:
3896 status=fflush(image->blob->file_info.file);
3901 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3902 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
3908 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3909 status=BZ2_bzflush(image->blob->file_info.bzfile);
3922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3932 % TellBlob() obtains the current value of the blob or file position.
3934 % The format of the TellBlob method is:
3936 % MagickOffsetType TellBlob(const Image *image)
3938 % A description of each parameter follows:
3940 % o image: the image.
3943 MagickExport MagickOffsetType TellBlob(const Image *image)
3948 assert(image != (Image *) NULL);
3949 assert(image->signature == MagickSignature);
3950 if (image->debug != MagickFalse)
3951 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3952 assert(image->blob != (BlobInfo *) NULL);
3953 assert(image->blob->type != UndefinedStream);
3955 switch (image->blob->type)
3957 case UndefinedStream:
3958 case StandardStream:
3962 offset=ftell(image->blob->file_info.file);
3969 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3970 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
3980 offset=image->blob->offset;
3988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3992 + U n m a p B l o b %
3996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3998 % UnmapBlob() deallocates the binary large object previously allocated with
3999 % the MapBlob method.
4001 % The format of the UnmapBlob method is:
4003 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4005 % A description of each parameter follows:
4007 % o map: the address of the binary large object.
4009 % o length: the length of the binary large object.
4012 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4014 #if defined(MAGICKCORE_HAVE_MMAP)
4018 status=munmap(map,length);
4019 return(status == -1 ? MagickFalse : MagickTrue);
4023 return(MagickFalse);
4028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4032 + W r i t e B l o b %
4036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4038 % WriteBlob() writes data to a blob or image file. It returns the number of
4041 % The format of the WriteBlob method is:
4043 % ssize_t WriteBlob(Image *image,const size_t length,
4044 % const unsigned char *data)
4046 % A description of each parameter follows:
4048 % o image: the image.
4050 % o length: Specifies an integer representing the number of bytes to
4051 % write to the file.
4053 % o data: The address of the data to write to the blob or file.
4056 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4057 const unsigned char *data)
4062 register const unsigned char
4068 assert(image != (Image *) NULL);
4069 assert(image->signature == MagickSignature);
4070 assert(data != (const unsigned char *) NULL);
4071 assert(image->blob != (BlobInfo *) NULL);
4072 assert(image->blob->type != UndefinedStream);
4077 switch (image->blob->type)
4079 case UndefinedStream:
4081 case StandardStream:
4083 count=write(fileno(image->blob->file_info.file),data,length);
4093 count=(ssize_t) fwrite((const char *) data,1,length,
4094 image->blob->file_info.file);
4099 c=putc((int) *p++,image->blob->file_info.file);
4106 c=putc((int) *p++,image->blob->file_info.file);
4118 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4123 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4124 (unsigned int) length);
4129 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4136 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4149 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4150 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
4157 count=(ssize_t) image->blob->stream(image,data,length);
4162 register unsigned char
4165 if ((image->blob->offset+(MagickOffsetType) length) >=
4166 (MagickOffsetType) image->blob->extent)
4168 if (image->blob->mapped != MagickFalse)
4170 image->blob->extent+=length+image->blob->quantum;
4171 image->blob->quantum<<=1;
4172 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4173 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4174 (void) SyncBlob(image);
4175 if (image->blob->data == (unsigned char *) NULL)
4177 (void) DetachBlob(image->blob);
4181 q=image->blob->data+image->blob->offset;
4182 (void) memcpy(q,p,length);
4183 image->blob->offset+=length;
4184 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4185 image->blob->length=(size_t) image->blob->offset;
4186 count=(ssize_t) length;
4193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4197 + W r i t e B l o b B y t e %
4201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4203 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4204 % written (either 0 or 1);
4206 % The format of the WriteBlobByte method is:
4208 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4210 % A description of each parameter follows.
4212 % o image: the image.
4214 % o value: Specifies the value to write.
4217 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4219 assert(image != (Image *) NULL);
4220 assert(image->signature == MagickSignature);
4221 return(WriteBlobStream(image,1,&value));
4225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4229 + W r i t e B l o b F l o a t %
4233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4235 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4236 % specified by the endian member of the image structure.
4238 % The format of the WriteBlobFloat method is:
4240 % ssize_t WriteBlobFloat(Image *image,const float value)
4242 % A description of each parameter follows.
4244 % o image: the image.
4246 % o value: Specifies the value to write.
4249 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4260 quantum.unsigned_value=0U;
4261 quantum.float_value=value;
4262 return(WriteBlobLong(image,quantum.unsigned_value));
4266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4270 + W r i t e B l o b L o n g %
4274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4276 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4277 % specified by the endian member of the image structure.
4279 % The format of the WriteBlobLong method is:
4281 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4283 % A description of each parameter follows.
4285 % o image: the image.
4287 % o value: Specifies the value to write.
4290 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4295 assert(image != (Image *) NULL);
4296 assert(image->signature == MagickSignature);
4297 if (image->endian == LSBEndian)
4299 buffer[0]=(unsigned char) value;
4300 buffer[1]=(unsigned char) (value >> 8);
4301 buffer[2]=(unsigned char) (value >> 16);
4302 buffer[3]=(unsigned char) (value >> 24);
4303 return(WriteBlobStream(image,4,buffer));
4305 buffer[0]=(unsigned char) (value >> 24);
4306 buffer[1]=(unsigned char) (value >> 16);
4307 buffer[2]=(unsigned char) (value >> 8);
4308 buffer[3]=(unsigned char) value;
4309 return(WriteBlobStream(image,4,buffer));
4313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4317 + W r i t e B l o b S h o r t %
4321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4323 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4324 % byte-order specified by the endian member of the image structure.
4326 % The format of the WriteBlobShort method is:
4328 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4330 % A description of each parameter follows.
4332 % o image: the image.
4334 % o value: Specifies the value to write.
4337 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4342 assert(image != (Image *) NULL);
4343 assert(image->signature == MagickSignature);
4344 if (image->endian == LSBEndian)
4346 buffer[0]=(unsigned char) value;
4347 buffer[1]=(unsigned char) (value >> 8);
4348 return(WriteBlobStream(image,2,buffer));
4350 buffer[0]=(unsigned char) (value >> 8);
4351 buffer[1]=(unsigned char) value;
4352 return(WriteBlobStream(image,2,buffer));
4356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4360 + W r i t e B l o b L S B L o n g %
4364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4366 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4367 % least-significant byte first order.
4369 % The format of the WriteBlobLSBLong method is:
4371 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4373 % A description of each parameter follows.
4375 % o image: the image.
4377 % o value: Specifies the value to write.
4380 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4385 assert(image != (Image *) NULL);
4386 assert(image->signature == MagickSignature);
4387 buffer[0]=(unsigned char) value;
4388 buffer[1]=(unsigned char) (value >> 8);
4389 buffer[2]=(unsigned char) (value >> 16);
4390 buffer[3]=(unsigned char) (value >> 24);
4391 return(WriteBlobStream(image,4,buffer));
4395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4399 + W r i t e B l o b L S B S h o r t %
4403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4405 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4406 % least-significant byte first order.
4408 % The format of the WriteBlobLSBShort method is:
4410 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4412 % A description of each parameter follows.
4414 % o image: the image.
4416 % o value: Specifies the value to write.
4419 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4424 assert(image != (Image *) NULL);
4425 assert(image->signature == MagickSignature);
4426 buffer[0]=(unsigned char) value;
4427 buffer[1]=(unsigned char) (value >> 8);
4428 return(WriteBlobStream(image,2,buffer));
4432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4436 + W r i t e B l o b M S B L o n g %
4440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4442 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4443 % most-significant byte first order.
4445 % The format of the WriteBlobMSBLong method is:
4447 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4449 % A description of each parameter follows.
4451 % o value: Specifies the value to write.
4453 % o image: the image.
4456 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4461 assert(image != (Image *) NULL);
4462 assert(image->signature == MagickSignature);
4463 buffer[0]=(unsigned char) (value >> 24);
4464 buffer[1]=(unsigned char) (value >> 16);
4465 buffer[2]=(unsigned char) (value >> 8);
4466 buffer[3]=(unsigned char) value;
4467 return(WriteBlobStream(image,4,buffer));
4471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4475 + W r i t e B l o b M S B L o n g L o n g %
4479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4481 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4482 % most-significant byte first order.
4484 % The format of the WriteBlobMSBLongLong method is:
4486 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4488 % A description of each parameter follows.
4490 % o value: Specifies the value to write.
4492 % o image: the image.
4495 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4496 const MagickSizeType value)
4501 assert(image != (Image *) NULL);
4502 assert(image->signature == MagickSignature);
4503 buffer[0]=(unsigned char) (value >> 56);
4504 buffer[1]=(unsigned char) (value >> 48);
4505 buffer[2]=(unsigned char) (value >> 40);
4506 buffer[3]=(unsigned char) (value >> 32);
4507 buffer[4]=(unsigned char) (value >> 24);
4508 buffer[5]=(unsigned char) (value >> 16);
4509 buffer[6]=(unsigned char) (value >> 8);
4510 buffer[7]=(unsigned char) value;
4511 return(WriteBlobStream(image,8,buffer));
4515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4519 + W r i t e B l o b M S B S h o r t %
4523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4525 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4526 % most-significant byte first order.
4528 % The format of the WriteBlobMSBShort method is:
4530 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4532 % A description of each parameter follows.
4534 % o value: Specifies the value to write.
4536 % o file: Specifies the file to write the data to.
4539 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4544 assert(image != (Image *) NULL);
4545 assert(image->signature == MagickSignature);
4546 buffer[0]=(unsigned char) (value >> 8);
4547 buffer[1]=(unsigned char) value;
4548 return(WriteBlobStream(image,2,buffer));
4552 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4556 + W r i t e B l o b S t r i n g %
4560 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4562 % WriteBlobString() write a string to a blob. It returns the number of
4563 % characters written.
4565 % The format of the WriteBlobString method is:
4567 % ssize_t WriteBlobString(Image *image,const char *string)
4569 % A description of each parameter follows.
4571 % o image: the image.
4573 % o string: Specifies the string to write.
4576 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4578 assert(image != (Image *) NULL);
4579 assert(image->signature == MagickSignature);
4580 assert(string != (const char *) NULL);
4581 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));