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.
404 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
406 (void) CopyMagickMemory(images->filename,image_info->filename,
407 sizeof(images->filename));
408 (void) CopyMagickMemory(images->magick_filename,image_info->filename,
409 sizeof(images->magick_filename));
410 images=GetNextImageInList(images);
413 clone_info=DestroyImageInfo(clone_info);
414 (void) RelinquishUniqueFileResource(blob_info->filename);
415 blob_info=DestroyImageInfo(blob_info);
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424 + C l o n e B l o b I n f o %
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
431 % blob info is NULL, a new one.
433 % The format of the CloneBlobInfo method is:
435 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
437 % A description of each parameter follows:
439 % o blob_info: the blob info.
442 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
447 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
448 if (clone_info == (BlobInfo *) NULL)
449 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
450 GetBlobInfo(clone_info);
451 if (blob_info == (BlobInfo *) NULL)
453 clone_info->length=blob_info->length;
454 clone_info->extent=blob_info->extent;
455 clone_info->synchronize=blob_info->synchronize;
456 clone_info->quantum=blob_info->quantum;
457 clone_info->mapped=blob_info->mapped;
458 clone_info->eof=blob_info->eof;
459 clone_info->offset=blob_info->offset;
460 clone_info->size=blob_info->size;
461 clone_info->exempt=blob_info->exempt;
462 clone_info->status=blob_info->status;
463 clone_info->temporary=blob_info->temporary;
464 clone_info->type=blob_info->type;
465 clone_info->file_info.file=blob_info->file_info.file;
466 clone_info->properties=blob_info->properties;
467 clone_info->stream=blob_info->stream;
468 clone_info->data=blob_info->data;
469 clone_info->debug=IsEventLogging();
470 clone_info->reference_count=1;
475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
479 + C l o s e B l o b %
483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 % CloseBlob() closes a stream associated with the image.
487 % The format of the CloseBlob method is:
489 % MagickBooleanType CloseBlob(Image *image)
491 % A description of each parameter follows:
493 % o image: the image.
496 MagickExport MagickBooleanType CloseBlob(Image *image)
504 assert(image != (Image *) NULL);
505 assert(image->signature == MagickSignature);
506 if (image->debug != MagickFalse)
507 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
508 assert(image->blob != (BlobInfo *) NULL);
509 if (image->blob->type == UndefinedStream)
511 status=SyncBlob(image);
512 switch (image->blob->type)
514 case UndefinedStream:
520 if (image->blob->synchronize != MagickFalse)
521 status=fsync(fileno(image->blob->file_info.file));
522 status=ferror(image->blob->file_info.file);
527 #if defined(MAGICKCORE_ZLIB_DELEGATE)
528 (void) gzerror(image->blob->file_info.gzfile,&status);
534 #if defined(MAGICKCORE_BZLIB_DELEGATE)
535 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
543 if ((image->blob->file_info.file != (FILE *) NULL) &&
544 (image->blob->synchronize != MagickFalse))
546 (void) fsync(fileno(image->blob->file_info.file));
547 status=ferror(image->blob->file_info.file);
552 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
553 image->blob->size=GetBlobSize(image);
554 image->extent=image->blob->size;
555 image->blob->eof=MagickFalse;
556 if (image->blob->exempt != MagickFalse)
558 image->blob->type=UndefinedStream;
559 return(image->blob->status);
561 switch (image->blob->type)
563 case UndefinedStream:
568 status=fclose(image->blob->file_info.file);
573 #if defined(MAGICKCORE_HAVE_PCLOSE)
574 status=pclose(image->blob->file_info.file);
580 #if defined(MAGICKCORE_ZLIB_DELEGATE)
581 status=gzclose(image->blob->file_info.gzfile);
587 #if defined(MAGICKCORE_BZLIB_DELEGATE)
588 BZ2_bzclose(image->blob->file_info.bzfile);
596 if (image->blob->file_info.file != (FILE *) NULL)
597 status=fclose(image->blob->file_info.file);
601 (void) DetachBlob(image->blob);
602 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
603 return(image->blob->status);
607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 + D e s t r o y B l o b %
615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 % DestroyBlob() deallocates memory associated with a blob.
619 % The format of the DestroyBlob method is:
621 % void DestroyBlob(Image *image)
623 % A description of each parameter follows:
625 % o image: the image.
628 MagickExport void DestroyBlob(Image *image)
633 assert(image != (Image *) NULL);
634 assert(image->signature == MagickSignature);
635 if (image->debug != MagickFalse)
636 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
637 assert(image->blob != (BlobInfo *) NULL);
638 assert(image->blob->signature == MagickSignature);
640 LockSemaphoreInfo(image->blob->semaphore);
641 image->blob->reference_count--;
642 assert(image->blob->reference_count >= 0);
643 if (image->blob->reference_count == 0)
645 UnlockSemaphoreInfo(image->blob->semaphore);
646 if (destroy == MagickFalse)
648 (void) CloseBlob(image);
649 if (image->blob->mapped != MagickFalse)
651 (void) UnmapBlob(image->blob->data,image->blob->length);
652 RelinquishMagickResource(MapResource,image->blob->length);
654 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
655 RelinquishSemaphoreInfo(&image->blob->semaphore);
656 image->blob->signature=(~MagickSignature);
657 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665 + D e t a c h B l o b %
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 % DetachBlob() detaches a blob from the BlobInfo structure.
673 % The format of the DetachBlob method is:
675 % unsigned char *DetachBlob(BlobInfo *blob_info)
677 % A description of each parameter follows:
679 % o blob_info: Specifies a pointer to a BlobInfo structure.
682 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
687 assert(blob_info != (BlobInfo *) NULL);
688 if (blob_info->debug != MagickFalse)
689 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
690 if (blob_info->mapped != MagickFalse)
692 (void) UnmapBlob(blob_info->data,blob_info->length);
693 RelinquishMagickResource(MapResource,blob_info->length);
695 blob_info->mapped=MagickFalse;
698 blob_info->eof=MagickFalse;
699 blob_info->exempt=MagickFalse;
700 blob_info->type=UndefinedStream;
701 blob_info->file_info.file=(FILE *) NULL;
702 data=blob_info->data;
703 blob_info->data=(unsigned char *) NULL;
704 blob_info->stream=(StreamHandler) NULL;
709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713 + D i s c a r d B l o b B y t e s %
717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719 % DiscardBlobBytes() discards bytes in a blob.
721 % The format of the DiscardBlobBytes method is:
723 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
725 % A description of each parameter follows.
727 % o image: the image.
729 % o length: the number of bytes to skip.
733 static inline const unsigned char *ReadBlobStream(Image *image,
734 const size_t length,unsigned char *data,ssize_t *count)
736 assert(count != (ssize_t *) NULL);
737 assert(image->blob != (BlobInfo *) NULL);
738 if (image->blob->type != BlobStream)
740 *count=ReadBlob(image,length,data);
743 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
746 image->blob->eof=MagickTrue;
749 data=image->blob->data+image->blob->offset;
750 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
751 image->blob->offset));
752 image->blob->offset+=(*count);
753 if (*count != (ssize_t) length)
754 image->blob->eof=MagickTrue;
758 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
759 const MagickSizeType length)
761 register MagickOffsetType
773 assert(image != (Image *) NULL);
774 assert(image->signature == MagickSignature);
776 for (i=0; i < (MagickOffsetType) length; i+=count)
778 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
779 (void) ReadBlobStream(image,quantum,buffer,&count);
787 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 + D u p l i c a t e s B l o b %
799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801 % DuplicateBlob() duplicates a blob descriptor.
803 % The format of the DuplicateBlob method is:
805 % void DuplicateBlob(Image *image,const Image *duplicate)
807 % A description of each parameter follows:
809 % o image: the image.
811 % o duplicate: the duplicate image.
814 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
816 assert(image != (Image *) NULL);
817 assert(image->signature == MagickSignature);
818 if (image->debug != MagickFalse)
819 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
820 assert(duplicate != (Image *) NULL);
821 assert(duplicate->signature == MagickSignature);
823 image->blob=ReferenceBlob(duplicate->blob);
827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
837 % EOFBlob() returns a non-zero value when EOF has been detected reading from
840 % The format of the EOFBlob method is:
842 % int EOFBlob(const Image *image)
844 % A description of each parameter follows:
846 % o image: the image.
849 MagickExport int EOFBlob(const Image *image)
851 assert(image != (Image *) NULL);
852 assert(image->signature == MagickSignature);
853 if (image->debug != MagickFalse)
854 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
855 assert(image->blob != (BlobInfo *) NULL);
856 assert(image->blob->type != UndefinedStream);
857 switch (image->blob->type)
859 case UndefinedStream:
865 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
871 image->blob->eof=MagickFalse;
876 #if defined(MAGICKCORE_BZLIB_DELEGATE)
881 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
882 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
888 image->blob->eof=MagickFalse;
894 return((int) image->blob->eof);
898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
902 + F i l e T o B l o b %
906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 % FileToBlob() returns the contents of a file as a buffer terminated with
909 % the '\0' character. The length of the buffer (not including the extra
910 % terminating '\0' character) is returned via the 'length' parameter. Free
911 % the buffer with RelinquishMagickMemory().
913 % The format of the FileToBlob method is:
915 % unsigned char *FileToBlob(const char *filename,const size_t extent,
916 % size_t *length,ExceptionInfo *exception)
918 % A description of each parameter follows:
920 % o blob: FileToBlob() returns the contents of a file as a blob. If
921 % an error occurs NULL is returned.
923 % o filename: the filename.
925 % o extent: The maximum length of the blob.
927 % o length: On return, this reflects the actual length of the blob.
929 % o exception: return any errors or warnings in this structure.
932 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
933 size_t *length,ExceptionInfo *exception)
953 assert(filename != (const char *) NULL);
954 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
955 assert(exception != (ExceptionInfo *) NULL);
958 if (LocaleCompare(filename,"-") != 0)
959 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
962 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
963 return((unsigned char *) NULL);
965 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
967 if ((file == fileno(stdin)) || (offset < 0) ||
968 (offset != (MagickOffsetType) ((ssize_t) offset)))
977 Stream is not seekable.
979 offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
980 quantum=(size_t) MagickMaxBufferExtent;
981 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
982 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
983 MagickMaxBufferExtent);
984 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
985 for (i=0; blob != (unsigned char *) NULL; i+=count)
987 count=read(file,blob+i,quantum);
994 if (~((size_t) i) < (quantum+1))
996 blob=(unsigned char *) RelinquishMagickMemory(blob);
999 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
1001 if ((size_t) (i+count) >= extent)
1004 if (LocaleCompare(filename,"-") != 0)
1006 if (blob == (unsigned char *) NULL)
1008 (void) ThrowMagickException(exception,GetMagickModule(),
1009 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1010 return((unsigned char *) NULL);
1014 blob=(unsigned char *) RelinquishMagickMemory(blob);
1015 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1016 return((unsigned char *) NULL);
1018 *length=(size_t) MagickMin(i+count,extent);
1022 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
1023 blob=(unsigned char *) NULL;
1024 if (~(*length) >= (MaxTextExtent-1))
1025 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
1027 if (blob == (unsigned char *) NULL)
1030 (void) ThrowMagickException(exception,GetMagickModule(),
1031 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1032 return((unsigned char *) NULL);
1034 map=MapBlob(file,ReadMode,0,*length);
1035 if (map != (unsigned char *) NULL)
1037 (void) memcpy(blob,map,*length);
1038 (void) UnmapBlob(map,*length);
1042 (void) lseek(file,0,SEEK_SET);
1043 for (i=0; i < *length; i+=count)
1045 count=read(file,blob+i,(size_t) MagickMin(*length-i,(MagickSizeType)
1057 blob=(unsigned char *) RelinquishMagickMemory(blob);
1058 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1059 return((unsigned char *) NULL);
1063 if (LocaleCompare(filename,"-") != 0)
1067 blob=(unsigned char *) RelinquishMagickMemory(blob);
1068 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1078 % F i l e T o I m a g e %
1082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1084 % FileToImage() write the contents of a file to an image.
1086 % The format of the FileToImage method is:
1088 % MagickBooleanType FileToImage(Image *,const char *filename)
1090 % A description of each parameter follows:
1092 % o image: the image.
1094 % o filename: the filename.
1098 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1099 const unsigned char *data)
1104 register unsigned char
1107 assert(image->blob != (BlobInfo *) NULL);
1108 if (image->blob->type != BlobStream)
1109 return(WriteBlob(image,length,data));
1110 assert(image->blob->type != UndefinedStream);
1111 assert(data != (void *) NULL);
1112 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1113 if (extent >= image->blob->extent)
1115 extent=image->blob->extent+image->blob->quantum+length;
1116 image->blob->quantum<<=1;
1117 if (SetBlobExtent(image,extent) == MagickFalse)
1120 q=image->blob->data+image->blob->offset;
1121 (void) memcpy(q,data,length);
1122 image->blob->offset+=length;
1123 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1124 image->blob->length=(size_t) image->blob->offset;
1125 return((ssize_t) length);
1128 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1129 ExceptionInfo *exception)
1147 assert(image != (const Image *) NULL);
1148 assert(image->signature == MagickSignature);
1149 assert(filename != (const char *) NULL);
1150 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1152 if (LocaleCompare(filename,"-") != 0)
1153 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1156 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1157 return(MagickFalse);
1159 quantum=(size_t) MagickMaxBufferExtent;
1160 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1161 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1162 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1163 if (blob == (unsigned char *) NULL)
1165 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1167 return(MagickFalse);
1171 count=read(file,blob,quantum);
1178 length=(size_t) count;
1179 count=WriteBlobStream(image,length,blob);
1180 if (count != (ssize_t) length)
1182 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1188 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1189 blob=(unsigned char *) RelinquishMagickMemory(blob);
1194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1198 + G e t B l o b E r r o r %
1202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1204 % GetBlobError() returns MagickTrue if the blob associated with the specified
1205 % image encountered an error.
1207 % The format of the GetBlobError method is:
1209 % MagickBooleanType GetBlobError(const Image *image)
1211 % A description of each parameter follows:
1213 % o image: the image.
1216 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1218 assert(image != (const Image *) NULL);
1219 assert(image->signature == MagickSignature);
1220 if (image->debug != MagickFalse)
1221 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1222 return(image->blob->status);
1226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1230 + G e t B l o b F i l e H a n d l e %
1234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1236 % GetBlobFileHandle() returns the file handle associated with the image blob.
1238 % The format of the GetBlobFile method is:
1240 % FILE *GetBlobFileHandle(const Image *image)
1242 % A description of each parameter follows:
1244 % o image: the image.
1247 MagickExport FILE *GetBlobFileHandle(const Image *image)
1249 assert(image != (const Image *) NULL);
1250 assert(image->signature == MagickSignature);
1251 return(image->blob->file_info.file);
1255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259 + G e t B l o b I n f o %
1263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1265 % GetBlobInfo() initializes the BlobInfo structure.
1267 % The format of the GetBlobInfo method is:
1269 % void GetBlobInfo(BlobInfo *blob_info)
1271 % A description of each parameter follows:
1273 % o blob_info: Specifies a pointer to a BlobInfo structure.
1276 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1278 assert(blob_info != (BlobInfo *) NULL);
1279 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1280 blob_info->type=UndefinedStream;
1281 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1282 blob_info->properties.st_mtime=time((time_t *) NULL);
1283 blob_info->properties.st_ctime=time((time_t *) NULL);
1284 blob_info->debug=IsEventLogging();
1285 blob_info->reference_count=1;
1286 blob_info->semaphore=AcquireSemaphoreInfo();
1287 blob_info->signature=MagickSignature;
1291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1295 % G e t B l o b P r o p e r t i e s %
1299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1301 % GetBlobProperties() returns information about an image blob.
1303 % The format of the GetBlobProperties method is:
1305 % const struct stat *GetBlobProperties(const Image *image)
1307 % A description of each parameter follows:
1309 % o image: the image.
1312 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1314 assert(image != (Image *) NULL);
1315 assert(image->signature == MagickSignature);
1316 if (image->debug != MagickFalse)
1317 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1318 return(&image->blob->properties);
1322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326 + G e t B l o b S i z e %
1330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332 % GetBlobSize() returns the current length of the image file or blob; zero is
1333 % returned if the size cannot be determined.
1335 % The format of the GetBlobSize method is:
1337 % MagickSizeType GetBlobSize(const Image *image)
1339 % A description of each parameter follows:
1341 % o image: the image.
1344 MagickExport MagickSizeType GetBlobSize(const Image *image)
1349 assert(image != (Image *) NULL);
1350 assert(image->signature == MagickSignature);
1351 if (image->debug != MagickFalse)
1352 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1353 assert(image->blob != (BlobInfo *) NULL);
1355 switch (image->blob->type)
1357 case UndefinedStream:
1359 extent=image->blob->size;
1362 case StandardStream:
1364 extent=image->blob->size;
1369 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1370 extent=(MagickSizeType) image->blob->properties.st_size;
1375 extent=image->blob->size;
1384 status=GetPathAttributes(image->filename,&image->blob->properties);
1385 if (status != MagickFalse)
1386 extent=(MagickSizeType) image->blob->properties.st_size;
1393 extent=(MagickSizeType) image->blob->length;
1401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1405 + G e t B l o b S t r e a m D a t a %
1409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1411 % GetBlobStreamData() returns the stream data for the image.
1413 % The format of the GetBlobStreamData method is:
1415 % unsigned char *GetBlobStreamData(const Image *image)
1417 % A description of each parameter follows:
1419 % o image: the image.
1422 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1424 assert(image != (const Image *) NULL);
1425 assert(image->signature == MagickSignature);
1426 return(image->blob->data);
1430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1434 + G e t B l o b S t r e a m H a n d l e r %
1438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1440 % GetBlobStreamHandler() returns the stream handler for the image.
1442 % The format of the GetBlobStreamHandler method is:
1444 % StreamHandler GetBlobStreamHandler(const Image *image)
1446 % A description of each parameter follows:
1448 % o image: the image.
1451 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1453 assert(image != (const Image *) NULL);
1454 assert(image->signature == MagickSignature);
1455 if (image->debug != MagickFalse)
1456 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1457 return(image->blob->stream);
1461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1465 % I m a g e T o B l o b %
1469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1471 % ImageToBlob() implements direct to memory image formats. It returns the
1472 % image as a formatted blob and its length. The magick member of the Image
1473 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1474 % etc.). This method is the equivalent of WriteImage(), but writes the
1475 % formatted "file" to a memory buffer rather than to an actual file.
1477 % The format of the ImageToBlob method is:
1479 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1480 % size_t *length,ExceptionInfo *exception)
1482 % A description of each parameter follows:
1484 % o image_info: the image info.
1486 % o image: the image.
1488 % o length: return the actual length of the blob.
1490 % o exception: return any errors or warnings in this structure.
1493 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1494 Image *image,size_t *length,ExceptionInfo *exception)
1508 assert(image_info != (const ImageInfo *) NULL);
1509 assert(image_info->signature == MagickSignature);
1510 if (image_info->debug != MagickFalse)
1511 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1512 image_info->filename);
1513 assert(image != (Image *) NULL);
1514 assert(image->signature == MagickSignature);
1515 assert(exception != (ExceptionInfo *) NULL);
1517 blob=(unsigned char *) NULL;
1518 blob_info=CloneImageInfo(image_info);
1519 blob_info->adjoin=MagickFalse;
1520 (void) SetImageInfo(blob_info,1,exception);
1521 if (*blob_info->magick != '\0')
1522 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1523 magick_info=GetMagickInfo(image->magick,exception);
1524 if (magick_info == (const MagickInfo *) NULL)
1526 (void) ThrowMagickException(exception,GetMagickModule(),
1527 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1529 blob_info=DestroyImageInfo(blob_info);
1532 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1533 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1536 Native blob support for this image format.
1538 blob_info->length=0;
1539 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1540 sizeof(unsigned char));
1541 if (blob_info->blob == (void *) NULL)
1542 (void) ThrowMagickException(exception,GetMagickModule(),
1543 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1546 (void) CloseBlob(image);
1547 image->blob->exempt=MagickTrue;
1548 *image->filename='\0';
1549 status=WriteImage(blob_info,image,exception);
1550 *length=image->blob->length;
1551 blob=DetachBlob(image->blob);
1552 if (status == MagickFalse)
1553 blob=(unsigned char *) RelinquishMagickMemory(blob);
1555 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1562 unique[MaxTextExtent];
1568 Write file to disk in blob image format.
1570 file=AcquireUniqueFileResource(unique);
1573 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1574 image_info->filename);
1578 blob_info->file=fdopen(file,"wb");
1579 if (blob_info->file != (FILE *) NULL)
1581 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1582 image->magick,unique);
1583 status=WriteImage(blob_info,image,exception);
1584 (void) CloseBlob(image);
1585 (void) fclose(blob_info->file);
1586 if (status != MagickFalse)
1587 blob=FileToBlob(unique,~0UL,length,exception);
1589 (void) RelinquishUniqueFileResource(unique);
1592 blob_info=DestroyImageInfo(blob_info);
1597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1601 % I m a g e T o F i l e %
1605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1607 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1608 % occurs otherwise MagickTrue.
1610 % The format of the ImageToFile method is:
1612 % MagickBooleanType ImageToFile(Image *image,char *filename,
1613 % ExceptionInfo *exception)
1615 % A description of each parameter follows:
1617 % o image: the image.
1619 % o filename: Write the image to this file.
1621 % o exception: return any errors or warnings in this structure.
1624 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1625 ExceptionInfo *exception)
1630 register const unsigned char
1649 assert(image != (Image *) NULL);
1650 assert(image->signature == MagickSignature);
1651 assert(image->blob != (BlobInfo *) NULL);
1652 assert(image->blob->type != UndefinedStream);
1653 if (image->debug != MagickFalse)
1654 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1655 assert(filename != (const char *) NULL);
1656 if (*filename == '\0')
1657 file=AcquireUniqueFileResource(filename);
1659 if (LocaleCompare(filename,"-") == 0)
1660 file=fileno(stdout);
1662 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1665 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1666 return(MagickFalse);
1668 quantum=(size_t) MagickMaxBufferExtent;
1669 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1670 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
1671 MagickMaxBufferExtent);
1672 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1673 if (buffer == (unsigned char *) NULL)
1676 (void) ThrowMagickException(exception,GetMagickModule(),
1677 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1678 return(MagickFalse);
1681 p=ReadBlobStream(image,quantum,buffer,&count);
1682 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1684 length=(size_t) count;
1685 for (i=0; i < length; i+=count)
1687 count=write(file,p+i,(size_t) (length-i));
1698 if (LocaleCompare(filename,"-") != 0)
1700 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1701 if ((file == -1) || (i < length))
1703 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1704 return(MagickFalse);
1710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1714 % I m a g e s T o B l o b %
1718 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1720 % ImagesToBlob() implements direct to memory image formats. It returns the
1721 % image sequence as a blob and its length. The magick member of the ImageInfo
1722 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1724 % Note, some image formats do not permit multiple images to the same image
1725 % stream (e.g. JPEG). in this instance, just the first image of the
1726 % sequence is returned as a blob.
1728 % The format of the ImagesToBlob method is:
1730 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1731 % size_t *length,ExceptionInfo *exception)
1733 % A description of each parameter follows:
1735 % o image_info: the image info.
1737 % o images: the image list.
1739 % o length: return the actual length of the blob.
1741 % o exception: return any errors or warnings in this structure.
1744 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1745 Image *images,size_t *length,ExceptionInfo *exception)
1759 assert(image_info != (const ImageInfo *) NULL);
1760 assert(image_info->signature == MagickSignature);
1761 if (image_info->debug != MagickFalse)
1762 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1763 image_info->filename);
1764 assert(images != (Image *) NULL);
1765 assert(images->signature == MagickSignature);
1766 assert(exception != (ExceptionInfo *) NULL);
1768 blob=(unsigned char *) NULL;
1769 blob_info=CloneImageInfo(image_info);
1770 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1772 if (*blob_info->magick != '\0')
1773 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1774 magick_info=GetMagickInfo(images->magick,exception);
1775 if (magick_info == (const MagickInfo *) NULL)
1777 (void) ThrowMagickException(exception,GetMagickModule(),
1778 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1780 blob_info=DestroyImageInfo(blob_info);
1783 if (GetMagickAdjoin(magick_info) == MagickFalse)
1785 blob_info=DestroyImageInfo(blob_info);
1786 return(ImageToBlob(image_info,images,length,exception));
1788 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1789 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1792 Native blob support for this images format.
1794 blob_info->length=0;
1795 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1796 sizeof(unsigned char));
1797 if (blob_info->blob == (void *) NULL)
1798 (void) ThrowMagickException(exception,GetMagickModule(),
1799 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1802 (void) CloseBlob(images);
1803 images->blob->exempt=MagickTrue;
1804 *images->filename='\0';
1805 status=WriteImages(blob_info,images,images->filename,exception);
1806 *length=images->blob->length;
1807 blob=DetachBlob(images->blob);
1808 if (status == MagickFalse)
1809 blob=(unsigned char *) RelinquishMagickMemory(blob);
1811 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1818 filename[MaxTextExtent],
1819 unique[MaxTextExtent];
1825 Write file to disk in blob images format.
1827 file=AcquireUniqueFileResource(unique);
1830 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1831 image_info->filename);
1835 blob_info->file=fdopen(file,"wb");
1836 if (blob_info->file != (FILE *) NULL)
1838 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1839 images->magick,unique);
1840 status=WriteImages(blob_info,images,filename,exception);
1841 (void) CloseBlob(images);
1842 (void) fclose(blob_info->file);
1843 if (status != MagickFalse)
1844 blob=FileToBlob(unique,~0UL,length,exception);
1846 (void) RelinquishUniqueFileResource(unique);
1849 blob_info=DestroyImageInfo(blob_info);
1853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1857 % I n j e c t I m a g e B l o b %
1861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1863 % InjectImageBlob() injects the image with a copy of itself in the specified
1864 % format (e.g. inject JPEG into a PDF image).
1866 % The format of the InjectImageBlob method is:
1868 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1869 % Image *image,Image *inject_image,const char *format,
1870 % ExceptionInfo *exception)
1872 % A description of each parameter follows:
1874 % o image_info: the image info..
1876 % o image: the image.
1878 % o inject_image: inject into the image stream.
1880 % o format: the image format.
1882 % o exception: return any errors or warnings in this structure.
1885 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1886 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1889 filename[MaxTextExtent];
1922 Write inject image to a temporary file.
1924 assert(image_info != (ImageInfo *) NULL);
1925 assert(image_info->signature == MagickSignature);
1926 assert(image != (Image *) NULL);
1927 assert(image->signature == MagickSignature);
1928 if (image->debug != MagickFalse)
1929 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1930 assert(inject_image != (Image *) NULL);
1931 assert(inject_image->signature == MagickSignature);
1932 assert(exception != (ExceptionInfo *) NULL);
1933 unique_file=(FILE *) NULL;
1934 file=AcquireUniqueFileResource(filename);
1936 unique_file=fdopen(file,"wb");
1937 if ((file == -1) || (unique_file == (FILE *) NULL))
1939 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1940 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1942 return(MagickFalse);
1944 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1945 if (byte_image == (Image *) NULL)
1947 (void) fclose(unique_file);
1948 (void) RelinquishUniqueFileResource(filename);
1949 return(MagickFalse);
1951 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1953 DestroyBlob(byte_image);
1954 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1955 write_info=CloneImageInfo(image_info);
1956 SetImageInfoFile(write_info,unique_file);
1957 status=WriteImage(write_info,byte_image,exception);
1958 write_info=DestroyImageInfo(write_info);
1959 byte_image=DestroyImage(byte_image);
1960 (void) fclose(unique_file);
1961 if (status == MagickFalse)
1963 (void) RelinquishUniqueFileResource(filename);
1964 return(MagickFalse);
1967 Inject into image stream.
1969 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1972 (void) RelinquishUniqueFileResource(filename);
1973 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1974 image_info->filename);
1975 return(MagickFalse);
1977 quantum=(size_t) MagickMaxBufferExtent;
1978 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1979 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1980 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1981 if (buffer == (unsigned char *) NULL)
1983 (void) RelinquishUniqueFileResource(filename);
1984 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1987 for (i=0; ; i+=count)
1989 count=read(file,buffer,quantum);
1996 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2001 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2002 (void) RelinquishUniqueFileResource(filename);
2003 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2012 + I s B l o b E x e m p t %
2016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2018 % IsBlobExempt() returns true if the blob is exempt.
2020 % The format of the IsBlobExempt method is:
2022 % MagickBooleanType IsBlobExempt(const Image *image)
2024 % A description of each parameter follows:
2026 % o image: the image.
2029 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
2031 assert(image != (const Image *) NULL);
2032 assert(image->signature == MagickSignature);
2033 if (image->debug != MagickFalse)
2034 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2035 return(image->blob->exempt);
2039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2043 + I s B l o b S e e k a b l e %
2047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2049 % IsBlobSeekable() returns true if the blob is seekable.
2051 % The format of the IsBlobSeekable method is:
2053 % MagickBooleanType IsBlobSeekable(const Image *image)
2055 % A description of each parameter follows:
2057 % o image: the image.
2060 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2065 assert(image != (const Image *) NULL);
2066 assert(image->signature == MagickSignature);
2067 if (image->debug != MagickFalse)
2068 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2069 switch (image->blob->type)
2075 seekable=MagickTrue;
2080 seekable=MagickFalse;
2088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2092 + I s B l o b T e m p o r a r y %
2096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2098 % IsBlobTemporary() returns true if the blob is temporary.
2100 % The format of the IsBlobTemporary method is:
2102 % MagickBooleanType IsBlobTemporary(const Image *image)
2104 % A description of each parameter follows:
2106 % o image: the image.
2109 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2111 assert(image != (const Image *) NULL);
2112 assert(image->signature == MagickSignature);
2113 if (image->debug != MagickFalse)
2114 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2115 return(image->blob->temporary);
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2129 % MapBlob() creates a mapping from a file to a binary large object.
2131 % The format of the MapBlob method is:
2133 % unsigned char *MapBlob(int file,const MapMode mode,
2134 % const MagickOffsetType offset,const size_t length)
2136 % A description of each parameter follows:
2138 % o file: map this file descriptor.
2140 % o mode: ReadMode, WriteMode, or IOMode.
2142 % o offset: starting at this offset within the file.
2144 % o length: the length of the mapping is returned in this pointer.
2147 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2148 const MagickOffsetType offset,const size_t length)
2150 #if defined(MAGICKCORE_HAVE_MMAP)
2163 #if defined(MAP_ANONYMOUS)
2164 flags|=MAP_ANONYMOUS;
2166 return((unsigned char *) NULL);
2173 protection=PROT_READ;
2179 protection=PROT_WRITE;
2185 protection=PROT_READ | PROT_WRITE;
2190 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2191 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2194 map=(unsigned char *) mmap((char *) NULL,length,protection,flags |
2195 MAP_HUGETLB,file,(off_t) offset);
2196 if (map == (unsigned char *) MAP_FAILED)
2197 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2200 if (map == (unsigned char *) MAP_FAILED)
2201 return((unsigned char *) NULL);
2208 return((unsigned char *) NULL);
2213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2217 + M S B O r d e r L o n g %
2221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2223 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2224 % most-significant byte first.
2226 % The format of the MSBOrderLong method is:
2228 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2230 % A description of each parameter follows.
2232 % o buffer: Specifies a pointer to a buffer of integers.
2234 % o length: Specifies the length of the buffer.
2237 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2242 register unsigned char
2246 assert(buffer != (unsigned char *) NULL);
2253 *buffer++=(unsigned char) c;
2257 *buffer++=(unsigned char) c;
2263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2267 + M S B O r d e r S h o r t %
2271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2273 % MSBOrderShort() converts a least-significant byte first buffer of integers
2274 % to most-significant byte first.
2276 % The format of the MSBOrderShort method is:
2278 % void MSBOrderShort(unsigned char *p,const size_t length)
2280 % A description of each parameter follows.
2282 % o p: Specifies a pointer to a buffer of integers.
2284 % o length: Specifies the length of the buffer.
2287 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2292 register unsigned char
2295 assert(p != (unsigned char *) NULL);
2302 *p++=(unsigned char) c;
2307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2317 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2318 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2319 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2320 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2321 % from a system command.
2323 % The format of the OpenBlob method is:
2325 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2326 % const BlobMode mode,ExceptionInfo *exception)
2328 % A description of each parameter follows:
2330 % o image_info: the image info.
2332 % o image: the image.
2334 % o mode: the mode for opening the file.
2337 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2338 Image *image,const BlobMode mode,ExceptionInfo *exception)
2341 extension[MaxTextExtent],
2342 filename[MaxTextExtent];
2353 assert(image_info != (ImageInfo *) NULL);
2354 assert(image_info->signature == MagickSignature);
2355 if (image_info->debug != MagickFalse)
2356 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2357 image_info->filename);
2358 assert(image != (Image *) NULL);
2359 assert(image->signature == MagickSignature);
2360 if (image_info->blob != (void *) NULL)
2362 if (image_info->stream != (StreamHandler) NULL)
2363 image->blob->stream=(StreamHandler) image_info->stream;
2364 AttachBlob(image->blob,image_info->blob,image_info->length);
2367 (void) DetachBlob(image->blob);
2370 default: type="r"; break;
2371 case ReadBlobMode: type="r"; break;
2372 case ReadBinaryBlobMode: type="rb"; break;
2373 case WriteBlobMode: type="w"; break;
2374 case WriteBinaryBlobMode: type="w+b"; break;
2375 case AppendBlobMode: type="a"; break;
2376 case AppendBinaryBlobMode: type="a+b"; break;
2379 image->blob->synchronize=image_info->synchronize;
2380 if (image_info->stream != (StreamHandler) NULL)
2382 image->blob->stream=(StreamHandler) image_info->stream;
2385 image->blob->type=FifoStream;
2393 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2394 rights=ReadPolicyRights;
2396 rights=WritePolicyRights;
2397 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2400 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2401 "NotAuthorized","`%s'",filename);
2402 return(MagickFalse);
2404 if ((LocaleCompare(filename,"-") == 0) ||
2405 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2407 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2408 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2409 if (strchr(type,'b') != (char *) NULL)
2410 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2412 image->blob->type=StandardStream;
2413 image->blob->exempt=MagickTrue;
2416 if (LocaleNCompare(filename,"fd:",3) == 0)
2419 mode[MaxTextExtent];
2423 image->blob->file_info.file=fdopen(StringToLong(filename+3),mode);
2424 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2425 if (strchr(type,'b') != (char *) NULL)
2426 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2428 image->blob->type=StandardStream;
2429 image->blob->exempt=MagickTrue;
2432 #if defined(MAGICKCORE_HAVE_POPEN)
2433 if (*filename == '|')
2436 mode[MaxTextExtent];
2439 Pipe image to or from a system command.
2441 #if defined(SIGPIPE)
2443 (void) signal(SIGPIPE,SIG_IGN);
2447 image->blob->file_info.file=(FILE *) popen_utf8(filename+1,mode);
2448 if (image->blob->file_info.file == (FILE *) NULL)
2450 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2451 return(MagickFalse);
2453 image->blob->type=PipeStream;
2454 image->blob->exempt=MagickTrue;
2458 status=GetPathAttributes(filename,&image->blob->properties);
2459 #if defined(S_ISFIFO)
2460 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2462 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2463 if (image->blob->file_info.file == (FILE *) NULL)
2465 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2466 return(MagickFalse);
2468 image->blob->type=FileStream;
2469 image->blob->exempt=MagickTrue;
2473 GetPathComponent(image->filename,ExtensionPath,extension);
2476 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2477 if ((image_info->adjoin == MagickFalse) ||
2478 (strchr(filename,'%') != (char *) NULL))
2481 Form filename for multi-part images.
2483 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2484 image->scene,filename,exception);
2485 if ((LocaleCompare(filename,image->filename) == 0) &&
2486 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2487 (GetNextImageInList(image) != (Image *) NULL)))
2490 path[MaxTextExtent];
2492 GetPathComponent(image->filename,RootPath,path);
2493 if (*extension == '\0')
2494 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2495 path,(double) image->scene);
2497 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2498 path,(double) image->scene,extension);
2500 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2501 #if defined(macintosh)
2502 SetApplicationType(filename,image_info->magick,'8BIM');
2506 if (image_info->file != (FILE *) NULL)
2508 image->blob->file_info.file=image_info->file;
2509 image->blob->type=FileStream;
2510 image->blob->exempt=MagickTrue;
2515 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2516 if (image->blob->file_info.file != (FILE *) NULL)
2524 image->blob->type=FileStream;
2525 #if defined(MAGICKCORE_HAVE_SETVBUF)
2526 (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
2529 (void) ResetMagickMemory(magick,0,sizeof(magick));
2530 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2531 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2532 (void) fflush(image->blob->file_info.file);
2533 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2534 " read %.20g magic header bytes",(double) count);
2535 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2536 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2537 ((int) magick[2] == 0x08))
2539 (void) fclose(image->blob->file_info.file);
2540 image->blob->file_info.gzfile=gzopen(filename,type);
2541 if (image->blob->file_info.gzfile != (gzFile) NULL)
2542 image->blob->type=ZipStream;
2545 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2546 if (strncmp((char *) magick,"BZh",3) == 0)
2548 (void) fclose(image->blob->file_info.file);
2549 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2550 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2551 image->blob->type=BZipStream;
2554 if (image->blob->type == FileStream)
2565 sans_exception=AcquireExceptionInfo();
2566 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2567 sans_exception=DestroyExceptionInfo(sans_exception);
2568 length=(size_t) image->blob->properties.st_size;
2569 if ((magick_info != (const MagickInfo *) NULL) &&
2570 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2571 (length <= MagickMaxBufferExtent) &&
2572 (AcquireMagickResource(MapResource,length) != MagickFalse))
2577 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
2579 if (blob == (void *) NULL)
2580 RelinquishMagickResource(MapResource,length);
2584 Format supports blobs-- use memory-mapped I/O.
2586 if (image_info->file != (FILE *) NULL)
2587 image->blob->exempt=MagickFalse;
2590 (void) fclose(image->blob->file_info.file);
2591 image->blob->file_info.file=(FILE *) NULL;
2593 AttachBlob(image->blob,blob,length);
2594 image->blob->mapped=MagickTrue;
2601 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2602 if ((LocaleCompare(extension,"Z") == 0) ||
2603 (LocaleCompare(extension,"gz") == 0) ||
2604 (LocaleCompare(extension,"wmz") == 0) ||
2605 (LocaleCompare(extension,"svgz") == 0))
2607 if (mode == WriteBinaryBlobMode)
2609 image->blob->file_info.gzfile=gzopen(filename,type);
2610 if (image->blob->file_info.gzfile != (gzFile) NULL)
2611 image->blob->type=ZipStream;
2615 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2616 if (LocaleCompare(extension,"bz2") == 0)
2618 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2619 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2620 image->blob->type=BZipStream;
2625 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2626 if (image->blob->file_info.file != (FILE *) NULL)
2628 image->blob->type=FileStream;
2629 #if defined(MAGICKCORE_HAVE_SETVBUF)
2630 (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
2635 image->blob->status=MagickFalse;
2636 if (image->blob->type != UndefinedStream)
2637 image->blob->size=GetBlobSize(image);
2640 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2641 return(MagickFalse);
2647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2657 % PingBlob() returns all the attributes of an image or image sequence except
2658 % for the pixels. It is much faster and consumes far less memory than
2659 % BlobToImage(). On failure, a NULL image is returned and exception
2660 % describes the reason for the failure.
2662 % The format of the PingBlob method is:
2664 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2665 % const size_t length,ExceptionInfo *exception)
2667 % A description of each parameter follows:
2669 % o image_info: the image info.
2671 % o blob: the address of a character stream in one of the image formats
2672 % understood by ImageMagick.
2674 % o length: This size_t integer reflects the length in bytes of the blob.
2676 % o exception: return any errors or warnings in this structure.
2680 #if defined(__cplusplus) || defined(c_plusplus)
2684 static size_t PingStream(const Image *magick_unused(image),
2685 const void *magick_unused(pixels),const size_t columns)
2690 #if defined(__cplusplus) || defined(c_plusplus)
2694 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2695 const size_t length,ExceptionInfo *exception)
2703 assert(image_info != (ImageInfo *) NULL);
2704 assert(image_info->signature == MagickSignature);
2705 if (image_info->debug != MagickFalse)
2706 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2707 image_info->filename);
2708 assert(exception != (ExceptionInfo *) NULL);
2709 if ((blob == (const void *) NULL) || (length == 0))
2711 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2712 "UnrecognizedImageFormat","`%s'",image_info->magick);
2713 return((Image *) NULL);
2715 ping_info=CloneImageInfo(image_info);
2716 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2717 if (ping_info->blob == (const void *) NULL)
2719 (void) ThrowMagickException(exception,GetMagickModule(),
2720 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2721 return((Image *) NULL);
2723 (void) memcpy(ping_info->blob,blob,length);
2724 ping_info->length=length;
2725 ping_info->ping=MagickTrue;
2726 image=ReadStream(ping_info,&PingStream,exception);
2727 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2728 ping_info=DestroyImageInfo(ping_info);
2733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2743 % ReadBlob() reads data from the blob or image file and returns it. It
2744 % returns the number of bytes read. If length is zero, ReadBlob() returns
2745 % zero and has no other results. If length is greater than SSIZE_MAX, the
2746 % result is unspecified.
2748 % The format of the ReadBlob method is:
2750 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2752 % A description of each parameter follows:
2754 % o image: the image.
2756 % o length: Specifies an integer representing the number of bytes to read
2759 % o data: Specifies an area to place the information requested from the
2763 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2764 unsigned char *data)
2769 register unsigned char
2775 assert(image != (Image *) NULL);
2776 assert(image->signature == MagickSignature);
2777 assert(image->blob != (BlobInfo *) NULL);
2778 assert(image->blob->type != UndefinedStream);
2781 assert(data != (void *) NULL);
2784 switch (image->blob->type)
2786 case UndefinedStream:
2788 case StandardStream:
2793 for (i=0; i < (ssize_t) length; i+=count)
2795 count=read(fileno(image->blob->file_info.file),q+i,(size_t)
2796 MagickMin(length-i,(MagickSizeType) SSIZE_MAX));
2814 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
2819 c=getc(image->blob->file_info.file);
2822 *q++=(unsigned char) c;
2827 c=getc(image->blob->file_info.file);
2830 *q++=(unsigned char) c;
2840 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2845 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
2846 (unsigned int) length);
2851 c=gzgetc(image->blob->file_info.gzfile);
2854 *q++=(unsigned char) c;
2859 c=gzgetc(image->blob->file_info.gzfile);
2862 *q++=(unsigned char) c;
2873 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2874 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
2882 register const unsigned char
2885 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2887 image->blob->eof=MagickTrue;
2890 p=image->blob->data+image->blob->offset;
2891 count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
2892 image->blob->offset));
2893 image->blob->offset+=count;
2894 if (count != (ssize_t) length)
2895 image->blob->eof=MagickTrue;
2896 (void) memcpy(q,p,(size_t) count);
2904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2908 + R e a d B l o b B y t e %
2912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2914 % ReadBlobByte() reads a single byte from the image file and returns it.
2916 % The format of the ReadBlobByte method is:
2918 % int ReadBlobByte(Image *image)
2920 % A description of each parameter follows.
2922 % o image: the image.
2925 MagickExport int ReadBlobByte(Image *image)
2927 register const unsigned char
2936 assert(image != (Image *) NULL);
2937 assert(image->signature == MagickSignature);
2938 p=ReadBlobStream(image,1,buffer,&count);
2945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2949 + R e a d B l o b D o u b l e %
2953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2955 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2956 % specified by the endian member of the image structure.
2958 % The format of the ReadBlobDouble method is:
2960 % double ReadBlobDouble(Image *image)
2962 % A description of each parameter follows.
2964 % o image: the image.
2967 MagickExport double ReadBlobDouble(Image *image)
2978 quantum.double_value=0.0;
2979 quantum.unsigned_value=ReadBlobLongLong(image);
2980 return(quantum.double_value);
2984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2988 + R e a d B l o b F l o a t %
2992 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2994 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2995 % specified by the endian member of the image structure.
2997 % The format of the ReadBlobFloat method is:
2999 % float ReadBlobFloat(Image *image)
3001 % A description of each parameter follows.
3003 % o image: the image.
3006 MagickExport float ReadBlobFloat(Image *image)
3017 quantum.float_value=0.0;
3018 quantum.unsigned_value=ReadBlobLong(image);
3019 return(quantum.float_value);
3023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3027 + R e a d B l o b L o n g %
3031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3033 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
3034 % specified by the endian member of the image structure.
3036 % The format of the ReadBlobLong method is:
3038 % unsigned int ReadBlobLong(Image *image)
3040 % A description of each parameter follows.
3042 % o image: the image.
3045 MagickExport unsigned int ReadBlobLong(Image *image)
3047 register const unsigned char
3059 assert(image != (Image *) NULL);
3060 assert(image->signature == MagickSignature);
3062 p=ReadBlobStream(image,4,buffer,&count);
3065 if (image->endian == LSBEndian)
3067 value=(unsigned int) (*p++);
3068 value|=((unsigned int) (*p++)) << 8;
3069 value|=((unsigned int) (*p++)) << 16;
3070 value|=((unsigned int) (*p++)) << 24;
3073 value=((unsigned int) (*p++)) << 24;
3074 value|=((unsigned int) (*p++)) << 16;
3075 value|=((unsigned int) (*p++)) << 8;
3076 value|=((unsigned int) (*p++));
3081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3085 + R e a d B l o b L o n g L o n g %
3089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3091 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3092 % byte-order specified by the endian member of the image structure.
3094 % The format of the ReadBlobLongLong method is:
3096 % MagickSizeType ReadBlobLongLong(Image *image)
3098 % A description of each parameter follows.
3100 % o image: the image.
3103 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3108 register const unsigned char
3117 assert(image != (Image *) NULL);
3118 assert(image->signature == MagickSignature);
3120 p=ReadBlobStream(image,8,buffer,&count);
3122 return(MagickULLConstant(0));
3123 if (image->endian == LSBEndian)
3125 value=(MagickSizeType) (*p++);
3126 value|=((MagickSizeType) (*p++)) << 8;
3127 value|=((MagickSizeType) (*p++)) << 16;
3128 value|=((MagickSizeType) (*p++)) << 24;
3129 value|=((MagickSizeType) (*p++)) << 32;
3130 value|=((MagickSizeType) (*p++)) << 40;
3131 value|=((MagickSizeType) (*p++)) << 48;
3132 value|=((MagickSizeType) (*p++)) << 56;
3133 return(value & MagickULLConstant(0xffffffffffffffff));
3135 value=((MagickSizeType) (*p++)) << 56;
3136 value|=((MagickSizeType) (*p++)) << 48;
3137 value|=((MagickSizeType) (*p++)) << 40;
3138 value|=((MagickSizeType) (*p++)) << 32;
3139 value|=((MagickSizeType) (*p++)) << 24;
3140 value|=((MagickSizeType) (*p++)) << 16;
3141 value|=((MagickSizeType) (*p++)) << 8;
3142 value|=((MagickSizeType) (*p++));
3143 return(value & MagickULLConstant(0xffffffffffffffff));
3147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3151 + R e a d B l o b S h o r t %
3155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3157 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3158 % specified by the endian member of the image structure.
3160 % The format of the ReadBlobShort method is:
3162 % unsigned short ReadBlobShort(Image *image)
3164 % A description of each parameter follows.
3166 % o image: the image.
3169 MagickExport unsigned short ReadBlobShort(Image *image)
3171 register const unsigned char
3174 register unsigned int
3183 assert(image != (Image *) NULL);
3184 assert(image->signature == MagickSignature);
3186 p=ReadBlobStream(image,2,buffer,&count);
3188 return((unsigned short) 0U);
3189 if (image->endian == LSBEndian)
3191 value=(unsigned int) (*p++);
3192 value|=((unsigned int) (*p++)) << 8;
3193 return((unsigned short) (value & 0xffff));
3195 value=(unsigned int) ((*p++) << 8);
3196 value|=(unsigned int) (*p++);
3197 return((unsigned short) (value & 0xffff));
3201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3205 + R e a d B l o b L S B L o n g %
3209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3211 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3212 % least-significant byte first order.
3214 % The format of the ReadBlobLSBLong method is:
3216 % unsigned int ReadBlobLSBLong(Image *image)
3218 % A description of each parameter follows.
3220 % o image: the image.
3223 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3225 register const unsigned char
3228 register unsigned int
3237 assert(image != (Image *) NULL);
3238 assert(image->signature == MagickSignature);
3240 p=ReadBlobStream(image,4,buffer,&count);
3243 value=(unsigned int) (*p++);
3244 value|=((unsigned int) (*p++)) << 8;
3245 value|=((unsigned int) (*p++)) << 16;
3246 value|=((unsigned int) (*p++)) << 24;
3251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3255 + R e a d B l o b L S B S h o r t %
3259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3261 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3262 % least-significant byte first order.
3264 % The format of the ReadBlobLSBShort method is:
3266 % unsigned short ReadBlobLSBShort(Image *image)
3268 % A description of each parameter follows.
3270 % o image: the image.
3273 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3275 register const unsigned char
3278 register unsigned int
3287 assert(image != (Image *) NULL);
3288 assert(image->signature == MagickSignature);
3290 p=ReadBlobStream(image,2,buffer,&count);
3292 return((unsigned short) 0U);
3293 value=(unsigned int) (*p++);
3294 value|=((unsigned int) ((*p++)) << 8);
3295 return((unsigned short) (value & 0xffff));
3299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3303 + R e a d B l o b M S B L o n g %
3307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3309 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3310 % most-significant byte first order.
3312 % The format of the ReadBlobMSBLong method is:
3314 % unsigned int ReadBlobMSBLong(Image *image)
3316 % A description of each parameter follows.
3318 % o image: the image.
3321 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3323 register const unsigned char
3326 register unsigned int
3335 assert(image != (Image *) NULL);
3336 assert(image->signature == MagickSignature);
3338 p=ReadBlobStream(image,4,buffer,&count);
3341 value=((unsigned int) (*p++) << 24);
3342 value|=((unsigned int) (*p++) << 16);
3343 value|=((unsigned int) (*p++) << 8);
3344 value|=(unsigned int) (*p++);
3349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3353 + R e a d B l o b M S B L o n g L o n g %
3357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3359 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3360 % most-significant byte first order.
3362 % The format of the ReadBlobMSBLongLong method is:
3364 % unsigned int ReadBlobMSBLongLong(Image *image)
3366 % A description of each parameter follows.
3368 % o image: the image.
3371 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3373 register const unsigned char
3376 register MagickSizeType
3385 assert(image != (Image *) NULL);
3386 assert(image->signature == MagickSignature);
3388 p=ReadBlobStream(image,8,buffer,&count);
3390 return(MagickULLConstant(0));
3391 value=((MagickSizeType) (*p++)) << 56;
3392 value|=((MagickSizeType) (*p++)) << 48;
3393 value|=((MagickSizeType) (*p++)) << 40;
3394 value|=((MagickSizeType) (*p++)) << 32;
3395 value|=((MagickSizeType) (*p++)) << 24;
3396 value|=((MagickSizeType) (*p++)) << 16;
3397 value|=((MagickSizeType) (*p++)) << 8;
3398 value|=((MagickSizeType) (*p++));
3399 return(value & MagickULLConstant(0xffffffffffffffff));
3403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3407 + R e a d B l o b M S B S h o r t %
3411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3413 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3414 % most-significant byte first order.
3416 % The format of the ReadBlobMSBShort method is:
3418 % unsigned short ReadBlobMSBShort(Image *image)
3420 % A description of each parameter follows.
3422 % o image: the image.
3425 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3427 register const unsigned char
3430 register unsigned int
3439 assert(image != (Image *) NULL);
3440 assert(image->signature == MagickSignature);
3442 p=ReadBlobStream(image,2,buffer,&count);
3444 return((unsigned short) 0U);
3445 value=(unsigned int) ((*p++) << 8);
3446 value|=(unsigned int) (*p++);
3447 return((unsigned short) (value & 0xffff));
3451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3455 + R e a d B l o b S t r i n g %
3459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3461 % ReadBlobString() reads characters from a blob or file until a newline
3462 % character is read or an end-of-file condition is encountered.
3464 % The format of the ReadBlobString method is:
3466 % char *ReadBlobString(Image *image,char *string)
3468 % A description of each parameter follows:
3470 % o image: the image.
3472 % o string: the address of a character buffer.
3475 MagickExport char *ReadBlobString(Image *image,char *string)
3477 register const unsigned char
3489 assert(image != (Image *) NULL);
3490 assert(image->signature == MagickSignature);
3491 for (i=0; i < (MaxTextExtent-1L); i++)
3493 p=ReadBlobStream(image,1,buffer,&count);
3497 return((char *) NULL);
3500 string[i]=(char) (*p);
3501 if ((string[i] == '\r') || (string[i] == '\n'))
3504 if (string[i] == '\r')
3505 (void) ReadBlobStream(image,1,buffer,&count);
3511 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3515 + R e f e r e n c e B l o b %
3519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3521 % ReferenceBlob() increments the reference count associated with the pixel
3522 % blob returning a pointer to the blob.
3524 % The format of the ReferenceBlob method is:
3526 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3528 % A description of each parameter follows:
3530 % o blob_info: the blob_info.
3533 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3535 assert(blob != (BlobInfo *) NULL);
3536 assert(blob->signature == MagickSignature);
3537 if (blob->debug != MagickFalse)
3538 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3539 LockSemaphoreInfo(blob->semaphore);
3540 blob->reference_count++;
3541 UnlockSemaphoreInfo(blob->semaphore);
3546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3556 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3557 % and returns the resulting offset.
3559 % The format of the SeekBlob method is:
3561 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3564 % A description of each parameter follows:
3566 % o image: the image.
3568 % o offset: Specifies an integer representing the offset in bytes.
3570 % o whence: Specifies an integer representing how the offset is
3571 % treated relative to the beginning of the blob as follows:
3573 % SEEK_SET Set position equal to offset bytes.
3574 % SEEK_CUR Set position to current location plus offset.
3575 % SEEK_END Set position to EOF plus offset.
3578 MagickExport MagickOffsetType SeekBlob(Image *image,
3579 const MagickOffsetType offset,const int whence)
3581 assert(image != (Image *) NULL);
3582 assert(image->signature == MagickSignature);
3583 if (image->debug != MagickFalse)
3584 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3585 assert(image->blob != (BlobInfo *) NULL);
3586 assert(image->blob->type != UndefinedStream);
3587 switch (image->blob->type)
3589 case UndefinedStream:
3591 case StandardStream:
3595 if (fseek(image->blob->file_info.file,offset,whence) < 0)
3597 image->blob->offset=TellBlob(image);
3603 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3604 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
3607 image->blob->offset=TellBlob(image);
3623 image->blob->offset=offset;
3628 if ((image->blob->offset+offset) < 0)
3630 image->blob->offset+=offset;
3635 if (((MagickOffsetType) image->blob->length+offset) < 0)
3637 image->blob->offset=image->blob->length+offset;
3641 if (image->blob->offset <= (MagickOffsetType)
3642 ((off_t) image->blob->length))
3643 image->blob->eof=MagickFalse;
3645 if (image->blob->mapped != MagickFalse)
3649 image->blob->extent=(size_t) (image->blob->offset+
3650 image->blob->quantum);
3651 image->blob->quantum<<=1;
3652 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3653 image->blob->data,image->blob->extent+1,
3654 sizeof(*image->blob->data));
3655 (void) SyncBlob(image);
3656 if (image->blob->data == (unsigned char *) NULL)
3658 (void) DetachBlob(image->blob);
3665 return(image->blob->offset);
3669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3673 + S e t B l o b E x e m p t %
3677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3679 % SetBlobExempt() sets the blob exempt status.
3681 % The format of the SetBlobExempt method is:
3683 % MagickBooleanType SetBlobExempt(const Image *image,
3684 % const MagickBooleanType exempt)
3686 % A description of each parameter follows:
3688 % o image: the image.
3690 % o exempt: Set to true if this blob is exempt from being closed.
3693 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3695 assert(image != (const Image *) NULL);
3696 assert(image->signature == MagickSignature);
3697 if (image->debug != MagickFalse)
3698 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3699 image->blob->exempt=exempt;
3703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3707 + S e t B l o b E x t e n t %
3711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3713 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3714 % method is successful, subsequent writes to bytes in the specified range are
3715 % guaranteed not to fail.
3717 % The format of the SetBlobExtent method is:
3719 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3721 % A description of each parameter follows:
3723 % o image: the image.
3725 % o extent: the blob maximum extent.
3728 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3729 const MagickSizeType extent)
3731 assert(image != (Image *) NULL);
3732 assert(image->signature == MagickSignature);
3733 if (image->debug != MagickFalse)
3734 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3735 assert(image->blob != (BlobInfo *) NULL);
3736 assert(image->blob->type != UndefinedStream);
3737 switch (image->blob->type)
3739 case UndefinedStream:
3741 case StandardStream:
3742 return(MagickFalse);
3751 if (extent != (MagickSizeType) ((off_t) extent))
3752 return(MagickFalse);
3753 offset=SeekBlob(image,0,SEEK_END);
3755 return(MagickFalse);
3756 if ((MagickSizeType) offset >= extent)
3758 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3759 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3760 image->blob->file_info.file);
3761 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3762 if (image->blob->synchronize != MagickFalse)
3767 status=posix_fallocate(fileno(image->blob->file_info.file),offset,
3770 return(MagickFalse);
3773 offset=SeekBlob(image,offset,SEEK_SET);
3775 return(MagickFalse);
3780 return(MagickFalse);
3782 return(MagickFalse);
3784 return(MagickFalse);
3787 if (extent != (MagickSizeType) ((size_t) extent))
3788 return(MagickFalse);
3789 if (image->blob->mapped != MagickFalse)
3797 (void) UnmapBlob(image->blob->data,image->blob->length);
3798 RelinquishMagickResource(MapResource,image->blob->length);
3799 if (extent != (MagickSizeType) ((off_t) extent))
3800 return(MagickFalse);
3801 offset=SeekBlob(image,0,SEEK_END);
3803 return(MagickFalse);
3804 if ((MagickSizeType) offset >= extent)
3806 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3807 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3808 image->blob->file_info.file);
3809 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3810 if (image->blob->synchronize != MagickFalse)
3815 status=posix_fallocate(fileno(image->blob->file_info.file),offset,
3818 return(MagickFalse);
3821 offset=SeekBlob(image,offset,SEEK_SET);
3823 return(MagickFalse);
3824 (void) AcquireMagickResource(MapResource,extent);
3825 image->blob->data=(unsigned char*) MapBlob(fileno(
3826 image->blob->file_info.file),WriteMode,0,(size_t) extent);
3827 image->blob->extent=(size_t) extent;
3828 image->blob->length=(size_t) extent;
3829 (void) SyncBlob(image);
3832 image->blob->extent=(size_t) extent;
3833 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3834 image->blob->extent+1,sizeof(*image->blob->data));
3835 (void) SyncBlob(image);
3836 if (image->blob->data == (unsigned char *) NULL)
3838 (void) DetachBlob(image->blob);
3839 return(MagickFalse);
3848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3858 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3859 % attributes if it is an blob.
3861 % The format of the SyncBlob method is:
3863 % int SyncBlob(Image *image)
3865 % A description of each parameter follows:
3867 % o image: the image.
3870 static int SyncBlob(Image *image)
3875 assert(image != (Image *) NULL);
3876 assert(image->signature == MagickSignature);
3877 if (image->debug != MagickFalse)
3878 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3879 assert(image->blob != (BlobInfo *) NULL);
3880 assert(image->blob->type != UndefinedStream);
3882 switch (image->blob->type)
3884 case UndefinedStream:
3885 case StandardStream:
3890 status=fflush(image->blob->file_info.file);
3895 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3896 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
3902 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3903 status=BZ2_bzflush(image->blob->file_info.bzfile);
3916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3926 % TellBlob() obtains the current value of the blob or file position.
3928 % The format of the TellBlob method is:
3930 % MagickOffsetType TellBlob(const Image *image)
3932 % A description of each parameter follows:
3934 % o image: the image.
3937 MagickExport MagickOffsetType TellBlob(const Image *image)
3942 assert(image != (Image *) NULL);
3943 assert(image->signature == MagickSignature);
3944 if (image->debug != MagickFalse)
3945 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3946 assert(image->blob != (BlobInfo *) NULL);
3947 assert(image->blob->type != UndefinedStream);
3949 switch (image->blob->type)
3951 case UndefinedStream:
3952 case StandardStream:
3956 offset=ftell(image->blob->file_info.file);
3963 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3964 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
3974 offset=image->blob->offset;
3982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3986 + U n m a p B l o b %
3990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3992 % UnmapBlob() deallocates the binary large object previously allocated with
3993 % the MapBlob method.
3995 % The format of the UnmapBlob method is:
3997 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3999 % A description of each parameter follows:
4001 % o map: the address of the binary large object.
4003 % o length: the length of the binary large object.
4006 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4008 #if defined(MAGICKCORE_HAVE_MMAP)
4012 status=munmap(map,length);
4013 return(status == -1 ? MagickFalse : MagickTrue);
4017 return(MagickFalse);
4022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4026 + W r i t e B l o b %
4030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4032 % WriteBlob() writes data to a blob or image file. It returns the number of
4035 % The format of the WriteBlob method is:
4037 % ssize_t WriteBlob(Image *image,const size_t length,
4038 % const unsigned char *data)
4040 % A description of each parameter follows:
4042 % o image: the image.
4044 % o length: Specifies an integer representing the number of bytes to
4045 % write to the file.
4047 % o data: The address of the data to write to the blob or file.
4050 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4051 const unsigned char *data)
4056 register const unsigned char
4062 assert(image != (Image *) NULL);
4063 assert(image->signature == MagickSignature);
4064 assert(data != (const unsigned char *) NULL);
4065 assert(image->blob != (BlobInfo *) NULL);
4066 assert(image->blob->type != UndefinedStream);
4071 switch (image->blob->type)
4073 case UndefinedStream:
4075 case StandardStream:
4077 count=write(fileno(image->blob->file_info.file),data,length);
4087 count=(ssize_t) fwrite((const char *) data,1,length,
4088 image->blob->file_info.file);
4093 c=putc((int) *p++,image->blob->file_info.file);
4100 c=putc((int) *p++,image->blob->file_info.file);
4112 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4117 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4118 (unsigned int) length);
4123 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4130 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4143 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4144 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
4151 count=(ssize_t) image->blob->stream(image,data,length);
4156 register unsigned char
4159 if ((image->blob->offset+(MagickOffsetType) length) >=
4160 (MagickOffsetType) image->blob->extent)
4162 if (image->blob->mapped != MagickFalse)
4164 image->blob->extent+=length+image->blob->quantum;
4165 image->blob->quantum<<=1;
4166 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4167 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4168 (void) SyncBlob(image);
4169 if (image->blob->data == (unsigned char *) NULL)
4171 (void) DetachBlob(image->blob);
4175 q=image->blob->data+image->blob->offset;
4176 (void) memcpy(q,p,length);
4177 image->blob->offset+=length;
4178 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4179 image->blob->length=(size_t) image->blob->offset;
4180 count=(ssize_t) length;
4187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4191 + W r i t e B l o b B y t e %
4195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4197 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4198 % written (either 0 or 1);
4200 % The format of the WriteBlobByte method is:
4202 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4204 % A description of each parameter follows.
4206 % o image: the image.
4208 % o value: Specifies the value to write.
4211 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4213 assert(image != (Image *) NULL);
4214 assert(image->signature == MagickSignature);
4215 return(WriteBlobStream(image,1,&value));
4219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4223 + W r i t e B l o b F l o a t %
4227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4229 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4230 % specified by the endian member of the image structure.
4232 % The format of the WriteBlobFloat method is:
4234 % ssize_t WriteBlobFloat(Image *image,const float value)
4236 % A description of each parameter follows.
4238 % o image: the image.
4240 % o value: Specifies the value to write.
4243 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4254 quantum.unsigned_value=0U;
4255 quantum.float_value=value;
4256 return(WriteBlobLong(image,quantum.unsigned_value));
4260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4264 + W r i t e B l o b L o n g %
4268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4270 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4271 % specified by the endian member of the image structure.
4273 % The format of the WriteBlobLong method is:
4275 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4277 % A description of each parameter follows.
4279 % o image: the image.
4281 % o value: Specifies the value to write.
4284 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4289 assert(image != (Image *) NULL);
4290 assert(image->signature == MagickSignature);
4291 if (image->endian == LSBEndian)
4293 buffer[0]=(unsigned char) value;
4294 buffer[1]=(unsigned char) (value >> 8);
4295 buffer[2]=(unsigned char) (value >> 16);
4296 buffer[3]=(unsigned char) (value >> 24);
4297 return(WriteBlobStream(image,4,buffer));
4299 buffer[0]=(unsigned char) (value >> 24);
4300 buffer[1]=(unsigned char) (value >> 16);
4301 buffer[2]=(unsigned char) (value >> 8);
4302 buffer[3]=(unsigned char) value;
4303 return(WriteBlobStream(image,4,buffer));
4307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4311 + W r i t e B l o b S h o r t %
4315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4317 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4318 % byte-order specified by the endian member of the image structure.
4320 % The format of the WriteBlobShort method is:
4322 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4324 % A description of each parameter follows.
4326 % o image: the image.
4328 % o value: Specifies the value to write.
4331 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4336 assert(image != (Image *) NULL);
4337 assert(image->signature == MagickSignature);
4338 if (image->endian == LSBEndian)
4340 buffer[0]=(unsigned char) value;
4341 buffer[1]=(unsigned char) (value >> 8);
4342 return(WriteBlobStream(image,2,buffer));
4344 buffer[0]=(unsigned char) (value >> 8);
4345 buffer[1]=(unsigned char) value;
4346 return(WriteBlobStream(image,2,buffer));
4350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4354 + W r i t e B l o b L S B L o n g %
4358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4360 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4361 % least-significant byte first order.
4363 % The format of the WriteBlobLSBLong method is:
4365 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4367 % A description of each parameter follows.
4369 % o image: the image.
4371 % o value: Specifies the value to write.
4374 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4379 assert(image != (Image *) NULL);
4380 assert(image->signature == MagickSignature);
4381 buffer[0]=(unsigned char) value;
4382 buffer[1]=(unsigned char) (value >> 8);
4383 buffer[2]=(unsigned char) (value >> 16);
4384 buffer[3]=(unsigned char) (value >> 24);
4385 return(WriteBlobStream(image,4,buffer));
4389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4393 + W r i t e B l o b L S B S h o r t %
4397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4399 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4400 % least-significant byte first order.
4402 % The format of the WriteBlobLSBShort method is:
4404 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4406 % A description of each parameter follows.
4408 % o image: the image.
4410 % o value: Specifies the value to write.
4413 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4418 assert(image != (Image *) NULL);
4419 assert(image->signature == MagickSignature);
4420 buffer[0]=(unsigned char) value;
4421 buffer[1]=(unsigned char) (value >> 8);
4422 return(WriteBlobStream(image,2,buffer));
4426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4430 + W r i t e B l o b M S B L o n g %
4434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4436 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4437 % most-significant byte first order.
4439 % The format of the WriteBlobMSBLong method is:
4441 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4443 % A description of each parameter follows.
4445 % o value: Specifies the value to write.
4447 % o image: the image.
4450 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4455 assert(image != (Image *) NULL);
4456 assert(image->signature == MagickSignature);
4457 buffer[0]=(unsigned char) (value >> 24);
4458 buffer[1]=(unsigned char) (value >> 16);
4459 buffer[2]=(unsigned char) (value >> 8);
4460 buffer[3]=(unsigned char) value;
4461 return(WriteBlobStream(image,4,buffer));
4465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4469 + W r i t e B l o b M S B L o n g L o n g %
4473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4475 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4476 % most-significant byte first order.
4478 % The format of the WriteBlobMSBLongLong method is:
4480 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4482 % A description of each parameter follows.
4484 % o value: Specifies the value to write.
4486 % o image: the image.
4489 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4490 const MagickSizeType value)
4495 assert(image != (Image *) NULL);
4496 assert(image->signature == MagickSignature);
4497 buffer[0]=(unsigned char) (value >> 56);
4498 buffer[1]=(unsigned char) (value >> 48);
4499 buffer[2]=(unsigned char) (value >> 40);
4500 buffer[3]=(unsigned char) (value >> 32);
4501 buffer[4]=(unsigned char) (value >> 24);
4502 buffer[5]=(unsigned char) (value >> 16);
4503 buffer[6]=(unsigned char) (value >> 8);
4504 buffer[7]=(unsigned char) value;
4505 return(WriteBlobStream(image,8,buffer));
4509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4513 + W r i t e B l o b M S B S h o r t %
4517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4519 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4520 % most-significant byte first order.
4522 % The format of the WriteBlobMSBShort method is:
4524 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4526 % A description of each parameter follows.
4528 % o value: Specifies the value to write.
4530 % o file: Specifies the file to write the data to.
4533 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4538 assert(image != (Image *) NULL);
4539 assert(image->signature == MagickSignature);
4540 buffer[0]=(unsigned char) (value >> 8);
4541 buffer[1]=(unsigned char) value;
4542 return(WriteBlobStream(image,2,buffer));
4546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4550 + W r i t e B l o b S t r i n g %
4554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4556 % WriteBlobString() write a string to a blob. It returns the number of
4557 % characters written.
4559 % The format of the WriteBlobString method is:
4561 % ssize_t WriteBlobString(Image *image,const char *string)
4563 % A description of each parameter follows.
4565 % o image: the image.
4567 % o string: Specifies the string to write.
4570 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4572 assert(image != (Image *) NULL);
4573 assert(image->signature == MagickSignature);
4574 assert(string != (const char *) NULL);
4575 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));