2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2017 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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 #include "MagickCore/studio.h"
48 #include "MagickCore/blob.h"
49 #include "MagickCore/blob-private.h"
50 #include "MagickCore/cache.h"
51 #include "MagickCore/client.h"
52 #include "MagickCore/constitute.h"
53 #include "MagickCore/delegate.h"
54 #include "MagickCore/exception.h"
55 #include "MagickCore/exception-private.h"
56 #include "MagickCore/image-private.h"
57 #include "MagickCore/list.h"
58 #include "MagickCore/locale_.h"
59 #include "MagickCore/log.h"
60 #include "MagickCore/magick.h"
61 #include "MagickCore/memory_.h"
62 #include "MagickCore/nt-base-private.h"
63 #include "MagickCore/option.h"
64 #include "MagickCore/policy.h"
65 #include "MagickCore/resource_.h"
66 #include "MagickCore/semaphore.h"
67 #include "MagickCore/string_.h"
68 #include "MagickCore/string-private.h"
69 #include "MagickCore/token.h"
70 #include "MagickCore/utility.h"
71 #include "MagickCore/utility-private.h"
72 #if defined(MAGICKCORE_ZLIB_DELEGATE)
75 #if defined(MAGICKCORE_BZLIB_DELEGATE)
82 #define MagickMaxBlobExtent (8*8192)
83 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
84 # define MAP_ANONYMOUS MAP_ANON
86 #if !defined(MAP_FAILED)
87 #define MAP_FAILED ((void *) -1)
91 #define _O_BINARY O_BINARY
98 (*BlobHandler)(const unsigned char *,const size_t,const void *);
101 (*BlobSeeker)(const MagickOffsetType offset,const int whence,const void *);
103 typedef MagickOffsetType
104 (*BlobTeller)(const void *);
106 struct _CustomStreamInfo
122 typedef union FileInfo
127 #if defined(MAGICKCORE_ZLIB_DELEGATE)
132 #if defined(MAGICKCORE_BZLIB_DELEGATE)
193 Forward declarations.
199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 + A t t a c h B l o b %
207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209 % AttachBlob() attaches a blob to the BlobInfo structure.
211 % The format of the AttachBlob method is:
213 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
215 % A description of each parameter follows:
217 % o blob_info: Specifies a pointer to a BlobInfo structure.
219 % o blob: the address of a character stream in one of the image formats
220 % understood by ImageMagick.
222 % o length: This size_t integer reflects the length in bytes of the blob.
225 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
228 assert(blob_info != (BlobInfo *) NULL);
229 if (blob_info->debug != MagickFalse)
230 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
231 blob_info->length=length;
232 blob_info->extent=length;
233 blob_info->quantum=(size_t) MagickMaxBlobExtent;
235 blob_info->type=BlobStream;
236 blob_info->file_info.file=(FILE *) NULL;
237 blob_info->data=(unsigned char *) blob;
238 blob_info->mapped=MagickFalse;
242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246 + B l o b T o F i l e %
250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
253 % occurs otherwise MagickTrue.
255 % The format of the BlobToFile method is:
257 % MagickBooleanType BlobToFile(char *filename,const void *blob,
258 % const size_t length,ExceptionInfo *exception)
260 % A description of each parameter follows:
262 % o filename: Write the blob to this file.
264 % o blob: the address of a blob.
266 % o length: This length in bytes of the blob.
268 % o exception: return any errors or warnings in this structure.
271 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
272 const size_t length,ExceptionInfo *exception)
283 assert(filename != (const char *) NULL);
284 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
285 assert(blob != (const void *) NULL);
286 if (*filename == '\0')
287 file=AcquireUniqueFileResource(filename);
289 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
292 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
295 for (i=0; i < length; i+=count)
297 count=write(file,(const char *) blob+i,MagickMin(length-i,SSIZE_MAX));
306 if ((file == -1) || (i < length))
308 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319 % B l o b T o I m a g e %
323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325 % BlobToImage() implements direct to memory image formats. It returns the
328 % The format of the BlobToImage method is:
330 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
331 % const size_t length,ExceptionInfo *exception)
333 % A description of each parameter follows:
335 % o image_info: the image info.
337 % o blob: the address of a character stream in one of the image formats
338 % understood by ImageMagick.
340 % o length: This size_t integer reflects the length in bytes of the blob.
342 % o exception: return any errors or warnings in this structure.
345 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
346 const size_t length,ExceptionInfo *exception)
361 assert(image_info != (ImageInfo *) NULL);
362 assert(image_info->signature == MagickCoreSignature);
363 if (image_info->debug != MagickFalse)
364 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
365 image_info->filename);
366 assert(exception != (ExceptionInfo *) NULL);
367 if ((blob == (const void *) NULL) || (length == 0))
369 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
370 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
371 return((Image *) NULL);
373 blob_info=CloneImageInfo(image_info);
374 blob_info->blob=(void *) blob;
375 blob_info->length=length;
376 if (*blob_info->magick == '\0')
377 (void) SetImageInfo(blob_info,0,exception);
378 magick_info=GetMagickInfo(blob_info->magick,exception);
379 if (magick_info == (const MagickInfo *) NULL)
381 (void) ThrowMagickException(exception,GetMagickModule(),
382 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
384 blob_info=DestroyImageInfo(blob_info);
385 return((Image *) NULL);
387 if (GetMagickBlobSupport(magick_info) != MagickFalse)
390 Native blob support for this image format.
392 (void) CopyMagickString(blob_info->filename,image_info->filename,
394 (void) CopyMagickString(blob_info->magick,image_info->magick,
396 image=ReadImage(blob_info,exception);
397 if (image != (Image *) NULL)
398 (void) DetachBlob(image->blob);
399 blob_info=DestroyImageInfo(blob_info);
403 Write blob to a temporary file on disk.
405 blob_info->blob=(void *) NULL;
407 *blob_info->filename='\0';
408 status=BlobToFile(blob_info->filename,blob,length,exception);
409 if (status == MagickFalse)
411 (void) RelinquishUniqueFileResource(blob_info->filename);
412 blob_info=DestroyImageInfo(blob_info);
413 return((Image *) NULL);
415 clone_info=CloneImageInfo(blob_info);
416 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,"%s:%s",
417 blob_info->magick,blob_info->filename);
418 image=ReadImage(clone_info,exception);
419 if (image != (Image *) NULL)
425 Restore original filenames and image format.
427 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
429 (void) CopyMagickString(images->filename,image_info->filename,
431 (void) CopyMagickString(images->magick_filename,image_info->filename,
433 (void) CopyMagickString(images->magick,magick_info->name,
435 images=GetNextImageInList(images);
438 clone_info=DestroyImageInfo(clone_info);
439 (void) RelinquishUniqueFileResource(blob_info->filename);
440 blob_info=DestroyImageInfo(blob_info);
445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449 + C l o n e B l o b I n f o %
453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
455 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
456 % blob info is NULL, a new one.
458 % The format of the CloneBlobInfo method is:
460 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
462 % A description of each parameter follows:
464 % o blob_info: the blob info.
467 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
472 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
473 if (clone_info == (BlobInfo *) NULL)
474 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
475 GetBlobInfo(clone_info);
476 if (blob_info == (BlobInfo *) NULL)
478 clone_info->length=blob_info->length;
479 clone_info->extent=blob_info->extent;
480 clone_info->synchronize=blob_info->synchronize;
481 clone_info->quantum=blob_info->quantum;
482 clone_info->mapped=blob_info->mapped;
483 clone_info->eof=blob_info->eof;
484 clone_info->offset=blob_info->offset;
485 clone_info->size=blob_info->size;
486 clone_info->exempt=blob_info->exempt;
487 clone_info->status=blob_info->status;
488 clone_info->temporary=blob_info->temporary;
489 clone_info->type=blob_info->type;
490 clone_info->file_info.file=blob_info->file_info.file;
491 clone_info->properties=blob_info->properties;
492 clone_info->stream=blob_info->stream;
493 clone_info->custom_stream=blob_info->custom_stream;
494 clone_info->data=blob_info->data;
495 clone_info->debug=IsEventLogging();
496 clone_info->reference_count=1;
501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
505 + C l o s e B l o b %
509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511 % CloseBlob() closes a stream associated with the image.
513 % The format of the CloseBlob method is:
515 % MagickBooleanType CloseBlob(Image *image)
517 % A description of each parameter follows:
519 % o image: the image.
522 MagickExport MagickBooleanType CloseBlob(Image *image)
530 assert(image != (Image *) NULL);
531 assert(image->signature == MagickCoreSignature);
532 if (image->debug != MagickFalse)
533 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
534 assert(image->blob != (BlobInfo *) NULL);
535 if (image->blob->type == UndefinedStream)
537 status=SyncBlob(image);
538 switch (image->blob->type)
540 case UndefinedStream:
546 if (image->blob->synchronize != MagickFalse)
547 status=fsync(fileno(image->blob->file_info.file));
548 status=ferror(image->blob->file_info.file);
553 #if defined(MAGICKCORE_ZLIB_DELEGATE)
554 (void) gzerror(image->blob->file_info.gzfile,&status);
560 #if defined(MAGICKCORE_BZLIB_DELEGATE)
561 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
569 if ((image->blob->file_info.file != (FILE *) NULL) &&
570 (image->blob->synchronize != MagickFalse))
572 (void) fsync(fileno(image->blob->file_info.file));
573 status=ferror(image->blob->file_info.file);
580 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
581 image->blob->size=GetBlobSize(image);
582 image->extent=image->blob->size;
583 image->blob->eof=MagickFalse;
584 if (image->blob->exempt != MagickFalse)
586 image->blob->type=UndefinedStream;
587 return(image->blob->status);
589 switch (image->blob->type)
591 case UndefinedStream:
596 status=fclose(image->blob->file_info.file);
601 #if defined(MAGICKCORE_HAVE_PCLOSE)
602 status=pclose(image->blob->file_info.file);
608 #if defined(MAGICKCORE_ZLIB_DELEGATE)
609 status=gzclose(image->blob->file_info.gzfile);
615 #if defined(MAGICKCORE_BZLIB_DELEGATE)
616 BZ2_bzclose(image->blob->file_info.bzfile);
624 if (image->blob->file_info.file != (FILE *) NULL)
625 status=fclose(image->blob->file_info.file);
631 (void) DetachBlob(image->blob);
632 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
633 return(image->blob->status);
637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641 + D e s t r o y B l o b %
645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647 % DestroyBlob() deallocates memory associated with a blob.
649 % The format of the DestroyBlob method is:
651 % void DestroyBlob(Image *image)
653 % A description of each parameter follows:
655 % o image: the image.
658 MagickExport void DestroyBlob(Image *image)
663 assert(image != (Image *) NULL);
664 assert(image->signature == MagickCoreSignature);
665 if (image->debug != MagickFalse)
666 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
667 assert(image->blob != (BlobInfo *) NULL);
668 assert(image->blob->signature == MagickCoreSignature);
670 LockSemaphoreInfo(image->blob->semaphore);
671 image->blob->reference_count--;
672 assert(image->blob->reference_count >= 0);
673 if (image->blob->reference_count == 0)
675 UnlockSemaphoreInfo(image->blob->semaphore);
676 if (destroy == MagickFalse)
678 (void) CloseBlob(image);
679 if (image->blob->mapped != MagickFalse)
681 (void) UnmapBlob(image->blob->data,image->blob->length);
682 RelinquishMagickResource(MapResource,image->blob->length);
684 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
685 RelinquishSemaphoreInfo(&image->blob->semaphore);
686 image->blob->signature=(~MagickCoreSignature);
687 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695 + D e t a c h B l o b %
699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701 % DetachBlob() detaches a blob from the BlobInfo structure.
703 % The format of the DetachBlob method is:
705 % void *DetachBlob(BlobInfo *blob_info)
707 % A description of each parameter follows:
709 % o blob_info: Specifies a pointer to a BlobInfo structure.
712 MagickExport void *DetachBlob(BlobInfo *blob_info)
717 assert(blob_info != (BlobInfo *) NULL);
718 if (blob_info->debug != MagickFalse)
719 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
720 if (blob_info->mapped != MagickFalse)
722 (void) UnmapBlob(blob_info->data,blob_info->length);
723 blob_info->data=(unsigned char *) NULL;
724 RelinquishMagickResource(MapResource,blob_info->length);
726 blob_info->mapped=MagickFalse;
729 blob_info->eof=MagickFalse;
730 blob_info->exempt=MagickFalse;
731 blob_info->type=UndefinedStream;
732 blob_info->file_info.file=(FILE *) NULL;
733 data=blob_info->data;
734 blob_info->data=(unsigned char *) NULL;
735 blob_info->stream=(StreamHandler) NULL;
736 blob_info->custom_stream=(CustomStreamInfo *) NULL;
741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
745 + D i s a s s o c i a t e B l o b %
749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
751 % DisassociateBlob() disassociates the image stream. It checks if the
752 % blob of the specified image is referenced by other images. If the reference
753 % count is higher then 1 a new blob is assigned to the specified image.
755 % The format of the DisassociateBlob method is:
757 % void DisassociateBlob(const Image *image)
759 % A description of each parameter follows:
761 % o image: the image.
764 MagickExport void DisassociateBlob(Image *image)
772 assert(image != (Image *) NULL);
773 assert(image->signature == MagickCoreSignature);
774 if (image->debug != MagickFalse)
775 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
776 assert(image->blob != (BlobInfo *) NULL);
777 assert(image->blob->signature == MagickCoreSignature);
779 LockSemaphoreInfo(image->blob->semaphore);
780 assert(image->blob->reference_count >= 0);
781 if (image->blob->reference_count > 1)
783 UnlockSemaphoreInfo(image->blob->semaphore);
784 if (clone == MagickFalse)
786 blob=CloneBlobInfo(image->blob);
792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796 + D i s c a r d B l o b B y t e s %
800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 % DiscardBlobBytes() discards bytes in a blob.
804 % The format of the DiscardBlobBytes method is:
806 % MagickBooleanType DiscardBlobBytes(Image *image,
807 % const MagickSizeType length)
809 % A description of each parameter follows.
811 % o image: the image.
813 % o length: the number of bytes to skip.
816 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
817 const MagickSizeType length)
819 register MagickOffsetType
831 assert(image != (Image *) NULL);
832 assert(image->signature == MagickCoreSignature);
833 if (length != (MagickSizeType) ((MagickOffsetType) length))
836 for (i=0; i < (MagickOffsetType) length; i+=count)
838 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
839 (void) ReadBlobStream(image,quantum,buffer,&count);
847 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
855 + D u p l i c a t e s B l o b %
859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861 % DuplicateBlob() duplicates a blob descriptor.
863 % The format of the DuplicateBlob method is:
865 % void DuplicateBlob(Image *image,const Image *duplicate)
867 % A description of each parameter follows:
869 % o image: the image.
871 % o duplicate: the duplicate image.
874 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
876 assert(image != (Image *) NULL);
877 assert(image->signature == MagickCoreSignature);
878 if (image->debug != MagickFalse)
879 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
880 assert(duplicate != (Image *) NULL);
881 assert(duplicate->signature == MagickCoreSignature);
883 image->blob=ReferenceBlob(duplicate->blob);
887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
897 % EOFBlob() returns a non-zero value when EOF has been detected reading from
900 % The format of the EOFBlob method is:
902 % int EOFBlob(const Image *image)
904 % A description of each parameter follows:
906 % o image: the image.
909 MagickExport int EOFBlob(const Image *image)
911 assert(image != (Image *) NULL);
912 assert(image->signature == MagickCoreSignature);
913 if (image->debug != MagickFalse)
914 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
915 assert(image->blob != (BlobInfo *) NULL);
916 assert(image->blob->type != UndefinedStream);
917 switch (image->blob->type)
919 case UndefinedStream:
925 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
931 image->blob->eof=MagickFalse;
936 #if defined(MAGICKCORE_BZLIB_DELEGATE)
941 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
942 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
948 image->blob->eof=MagickFalse;
956 return((int) image->blob->eof);
960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964 % F i l e T o B l o b %
968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
970 % FileToBlob() returns the contents of a file as a buffer terminated with
971 % the '\0' character. The length of the buffer (not including the extra
972 % terminating '\0' character) is returned via the 'length' parameter. Free
973 % the buffer with RelinquishMagickMemory().
975 % The format of the FileToBlob method is:
977 % void *FileToBlob(const char *filename,const size_t extent,
978 % size_t *length,ExceptionInfo *exception)
980 % A description of each parameter follows:
982 % o blob: FileToBlob() returns the contents of a file as a blob. If
983 % an error occurs NULL is returned.
985 % o filename: the filename.
987 % o extent: The maximum length of the blob.
989 % o length: On return, this reflects the actual length of the blob.
991 % o exception: return any errors or warnings in this structure.
994 MagickExport void *FileToBlob(const char *filename,const size_t extent,
995 size_t *length,ExceptionInfo *exception)
1015 assert(filename != (const char *) NULL);
1016 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1017 assert(exception != (ExceptionInfo *) NULL);
1020 if (LocaleCompare(filename,"-") != 0)
1021 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1024 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
1027 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
1029 if ((file == fileno(stdin)) || (offset < 0) ||
1030 (offset != (MagickOffsetType) ((ssize_t) offset)))
1039 Stream is not seekable.
1041 offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
1042 quantum=(size_t) MagickMaxBufferExtent;
1043 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1044 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1045 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1046 for (i=0; blob != (unsigned char *) NULL; i+=count)
1048 count=read(file,blob+i,quantum);
1055 if (~((size_t) i) < (quantum+1))
1057 blob=(unsigned char *) RelinquishMagickMemory(blob);
1060 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
1062 if ((size_t) (i+count) >= extent)
1065 if (LocaleCompare(filename,"-") != 0)
1067 if (blob == (unsigned char *) NULL)
1069 (void) ThrowMagickException(exception,GetMagickModule(),
1070 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1075 blob=(unsigned char *) RelinquishMagickMemory(blob);
1076 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1079 *length=(size_t) MagickMin(i+count,extent);
1083 *length=(size_t) MagickMin(offset,(MagickOffsetType)
1084 MagickMin(extent,SSIZE_MAX));
1085 blob=(unsigned char *) NULL;
1086 if (~(*length) >= (MagickPathExtent-1))
1087 blob=(unsigned char *) AcquireQuantumMemory(*length+MagickPathExtent,
1089 if (blob == (unsigned char *) NULL)
1092 (void) ThrowMagickException(exception,GetMagickModule(),
1093 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1096 map=MapBlob(file,ReadMode,0,*length);
1097 if (map != (unsigned char *) NULL)
1099 (void) memcpy(blob,map,*length);
1100 (void) UnmapBlob(map,*length);
1104 (void) lseek(file,0,SEEK_SET);
1105 for (i=0; i < *length; i+=count)
1107 count=read(file,blob+i,(size_t) MagickMin(*length-i,SSIZE_MAX));
1118 blob=(unsigned char *) RelinquishMagickMemory(blob);
1119 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1124 if (LocaleCompare(filename,"-") != 0)
1128 blob=(unsigned char *) RelinquishMagickMemory(blob);
1129 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1139 % F i l e T o I m a g e %
1143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1145 % FileToImage() write the contents of a file to an image.
1147 % The format of the FileToImage method is:
1149 % MagickBooleanType FileToImage(Image *,const char *filename)
1151 % A description of each parameter follows:
1153 % o image: the image.
1155 % o filename: the filename.
1159 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1165 register unsigned char
1168 assert(image->blob != (BlobInfo *) NULL);
1169 assert(image->blob->type != UndefinedStream);
1170 assert(data != NULL);
1171 if (image->blob->type != BlobStream)
1172 return(WriteBlob(image,length,(const unsigned char *) data));
1173 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1174 if (extent >= image->blob->extent)
1176 extent=image->blob->extent+image->blob->quantum+length;
1177 image->blob->quantum<<=1;
1178 if (SetBlobExtent(image,extent) == MagickFalse)
1181 q=image->blob->data+image->blob->offset;
1182 (void) memcpy(q,data,length);
1183 image->blob->offset+=length;
1184 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1185 image->blob->length=(size_t) image->blob->offset;
1186 return((ssize_t) length);
1189 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1190 ExceptionInfo *exception)
1208 assert(image != (const Image *) NULL);
1209 assert(image->signature == MagickCoreSignature);
1210 assert(filename != (const char *) NULL);
1211 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1213 if (LocaleCompare(filename,"-") != 0)
1214 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1217 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1218 return(MagickFalse);
1220 quantum=(size_t) MagickMaxBufferExtent;
1221 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1222 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1223 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1224 if (blob == (unsigned char *) NULL)
1227 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1229 return(MagickFalse);
1233 count=read(file,blob,quantum);
1240 length=(size_t) count;
1241 count=WriteBlobStream(image,length,blob);
1242 if (count != (ssize_t) length)
1244 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1250 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1251 blob=(unsigned char *) RelinquishMagickMemory(blob);
1256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1260 + G e t B l o b E r r o r %
1264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1266 % GetBlobError() returns MagickTrue if the blob associated with the specified
1267 % image encountered an error.
1269 % The format of the GetBlobError method is:
1271 % MagickBooleanType GetBlobError(const Image *image)
1273 % A description of each parameter follows:
1275 % o image: the image.
1278 MagickExport MagickBooleanType GetBlobError(const Image *image)
1280 assert(image != (const Image *) NULL);
1281 assert(image->signature == MagickCoreSignature);
1282 if (image->debug != MagickFalse)
1283 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1284 return(image->blob->status);
1288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1292 + G e t B l o b F i l e H a n d l e %
1296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1298 % GetBlobFileHandle() returns the file handle associated with the image blob.
1300 % The format of the GetBlobFile method is:
1302 % FILE *GetBlobFileHandle(const Image *image)
1304 % A description of each parameter follows:
1306 % o image: the image.
1309 MagickExport FILE *GetBlobFileHandle(const Image *image)
1311 assert(image != (const Image *) NULL);
1312 assert(image->signature == MagickCoreSignature);
1313 return(image->blob->file_info.file);
1317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1321 + G e t B l o b I n f o %
1325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1327 % GetBlobInfo() initializes the BlobInfo structure.
1329 % The format of the GetBlobInfo method is:
1331 % void GetBlobInfo(BlobInfo *blob_info)
1333 % A description of each parameter follows:
1335 % o blob_info: Specifies a pointer to a BlobInfo structure.
1338 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1340 assert(blob_info != (BlobInfo *) NULL);
1341 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1342 blob_info->type=UndefinedStream;
1343 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1344 blob_info->properties.st_mtime=time((time_t *) NULL);
1345 blob_info->properties.st_ctime=time((time_t *) NULL);
1346 blob_info->debug=IsEventLogging();
1347 blob_info->reference_count=1;
1348 blob_info->semaphore=AcquireSemaphoreInfo();
1349 blob_info->signature=MagickCoreSignature;
1353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357 % G e t B l o b P r o p e r t i e s %
1361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1363 % GetBlobProperties() returns information about an image blob.
1365 % The format of the GetBlobProperties method is:
1367 % const struct stat *GetBlobProperties(const Image *image)
1369 % A description of each parameter follows:
1371 % o image: the image.
1374 MagickExport const struct stat *GetBlobProperties(const Image *image)
1376 assert(image != (Image *) NULL);
1377 assert(image->signature == MagickCoreSignature);
1378 if (image->debug != MagickFalse)
1379 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1380 return(&image->blob->properties);
1384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1388 + G e t B l o b S i z e %
1392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1394 % GetBlobSize() returns the current length of the image file or blob; zero is
1395 % returned if the size cannot be determined.
1397 % The format of the GetBlobSize method is:
1399 % MagickSizeType GetBlobSize(const Image *image)
1401 % A description of each parameter follows:
1403 % o image: the image.
1406 MagickExport MagickSizeType GetBlobSize(const Image *image)
1411 assert(image != (Image *) NULL);
1412 assert(image->signature == MagickCoreSignature);
1413 if (image->debug != MagickFalse)
1414 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1415 assert(image->blob != (BlobInfo *) NULL);
1417 switch (image->blob->type)
1419 case UndefinedStream:
1420 case StandardStream:
1422 extent=image->blob->size;
1427 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1428 extent=(MagickSizeType) image->blob->properties.st_size;
1433 extent=image->blob->size;
1442 status=GetPathAttributes(image->filename,&image->blob->properties);
1443 if (status != MagickFalse)
1444 extent=(MagickSizeType) image->blob->properties.st_size;
1451 extent=(MagickSizeType) image->blob->length;
1461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1465 + G e t B l o b S t r e a m D a t a %
1469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1471 % GetBlobStreamData() returns the stream data for the image.
1473 % The format of the GetBlobStreamData method is:
1475 % void *GetBlobStreamData(const Image *image)
1477 % A description of each parameter follows:
1479 % o image: the image.
1482 MagickExport void *GetBlobStreamData(const Image *image)
1484 assert(image != (const Image *) NULL);
1485 assert(image->signature == MagickCoreSignature);
1486 return(image->blob->data);
1490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1494 + G e t B l o b S t r e a m H a n d l e r %
1498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1500 % GetBlobStreamHandler() returns the stream handler for the image.
1502 % The format of the GetBlobStreamHandler method is:
1504 % StreamHandler GetBlobStreamHandler(const Image *image)
1506 % A description of each parameter follows:
1508 % o image: the image.
1511 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1513 assert(image != (const Image *) NULL);
1514 assert(image->signature == MagickCoreSignature);
1515 if (image->debug != MagickFalse)
1516 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1517 return(image->blob->stream);
1521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1525 % I m a g e T o B l o b %
1529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1531 % ImageToBlob() implements direct to memory image formats. It returns the
1532 % image as a formatted blob and its length. The magick member of the Image
1533 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1534 % etc.). This method is the equivalent of WriteImage(), but writes the
1535 % formatted "file" to a memory buffer rather than to an actual file.
1537 % The format of the ImageToBlob method is:
1539 % void *ImageToBlob(const ImageInfo *image_info,Image *image,
1540 % size_t *length,ExceptionInfo *exception)
1542 % A description of each parameter follows:
1544 % o image_info: the image info.
1546 % o image: the image.
1548 % o length: return the actual length of the blob.
1550 % o exception: return any errors or warnings in this structure.
1553 MagickExport void *ImageToBlob(const ImageInfo *image_info,
1554 Image *image,size_t *length,ExceptionInfo *exception)
1568 assert(image_info != (const ImageInfo *) NULL);
1569 assert(image_info->signature == MagickCoreSignature);
1570 if (image_info->debug != MagickFalse)
1571 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1572 image_info->filename);
1573 assert(image != (Image *) NULL);
1574 assert(image->signature == MagickCoreSignature);
1575 assert(exception != (ExceptionInfo *) NULL);
1577 blob=(unsigned char *) NULL;
1578 blob_info=CloneImageInfo(image_info);
1579 blob_info->adjoin=MagickFalse;
1580 (void) SetImageInfo(blob_info,1,exception);
1581 if (*blob_info->magick != '\0')
1582 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1583 magick_info=GetMagickInfo(image->magick,exception);
1584 if (magick_info == (const MagickInfo *) NULL)
1586 (void) ThrowMagickException(exception,GetMagickModule(),
1587 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1589 blob_info=DestroyImageInfo(blob_info);
1592 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1593 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1596 Native blob support for this image format.
1598 blob_info->length=0;
1599 blob_info->blob=AcquireQuantumMemory(MagickMaxBlobExtent,
1600 sizeof(unsigned char));
1601 if (blob_info->blob == NULL)
1602 (void) ThrowMagickException(exception,GetMagickModule(),
1603 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1606 (void) CloseBlob(image);
1607 image->blob->exempt=MagickTrue;
1608 *image->filename='\0';
1609 status=WriteImage(blob_info,image,exception);
1610 *length=image->blob->length;
1611 blob=DetachBlob(image->blob);
1612 if (status == MagickFalse)
1613 blob=RelinquishMagickMemory(blob);
1615 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1621 unique[MagickPathExtent];
1627 Write file to disk in blob image format.
1629 file=AcquireUniqueFileResource(unique);
1632 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1633 image_info->filename);
1637 blob_info->file=fdopen(file,"wb");
1638 if (blob_info->file != (FILE *) NULL)
1640 (void) FormatLocaleString(image->filename,MagickPathExtent,
1641 "%s:%s",image->magick,unique);
1642 status=WriteImage(blob_info,image,exception);
1643 (void) CloseBlob(image);
1644 (void) fclose(blob_info->file);
1645 if (status != MagickFalse)
1646 blob=FileToBlob(unique,~0UL,length,exception);
1648 (void) RelinquishUniqueFileResource(unique);
1651 blob_info=DestroyImageInfo(blob_info);
1656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1660 + I m a g e T o C u s t o m S t r e a m %
1664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1666 % ImageToCustomStream() is the equivalent of WriteImage(), but writes the
1667 % formatted "file" to the custom stream rather than to an actual file.
1669 % The format of the ImageToCustomStream method is:
1671 % void ImageToCustomStream(const ImageInfo *image_info,Image *image,
1672 % CustomStreamInfo *custom_stream,ExceptionInfo *exception)
1674 % A description of each parameter follows:
1676 % o image_info: the image info.
1678 % o image: the image.
1680 % o custom_stream: the methods to use when writing and seeking.
1682 % o exception: return any errors or warnings in this structure.
1685 MagickExport void ImageToCustomStream(const ImageInfo *image_info,Image *image,
1686 CustomStreamInfo *custom_stream,ExceptionInfo *exception)
1697 assert(image_info != (const ImageInfo *) NULL);
1698 assert(image_info->signature == MagickCoreSignature);
1699 if (image_info->debug != MagickFalse)
1700 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1701 image_info->filename);
1702 assert(image != (Image *) NULL);
1703 assert(image->signature == MagickCoreSignature);
1704 assert(custom_stream != (CustomStreamInfo *) NULL);
1705 assert(custom_stream->reader != (BlobHandler) NULL);
1706 assert(custom_stream->writer != (BlobHandler) NULL);
1707 assert(exception != (ExceptionInfo *) NULL);
1708 blob_info=CloneImageInfo(image_info);
1709 blob_info->adjoin=MagickFalse;
1710 blob_info->custom_stream=custom_stream;
1711 (void) SetImageInfo(blob_info,1,exception);
1712 if (*blob_info->magick != '\0')
1713 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1714 magick_info=GetMagickInfo(image->magick,exception);
1715 if (magick_info == (const MagickInfo *) NULL)
1717 (void) ThrowMagickException(exception,GetMagickModule(),
1718 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1720 blob_info=DestroyImageInfo(blob_info);
1723 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1724 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1727 Native blob support for this image format.
1729 (void) CloseBlob(image);
1730 *image->filename='\0';
1731 (void) WriteImage(blob_info,image,exception);
1732 (void) CloseBlob(image);
1737 unique[MagickPathExtent];
1746 Write file to disk in blob image format.
1748 blob_info->custom_stream=(CustomStreamInfo *) NULL;
1749 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
1751 if (blob == (unsigned char *) NULL)
1753 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1754 image_info->filename);
1755 blob_info=DestroyImageInfo(blob_info);
1758 file=AcquireUniqueFileResource(unique);
1761 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1762 image_info->filename);
1763 blob=(unsigned char *) RelinquishMagickMemory(blob);
1764 blob_info=DestroyImageInfo(blob_info);
1767 blob_info->file=fdopen(file,"wb+");
1768 if (blob_info->file != (FILE *) NULL)
1773 (void) FormatLocaleString(image->filename,MagickPathExtent,
1774 "%s:%s",image->magick,unique);
1775 status=WriteImage(blob_info,image,exception);
1776 (void) CloseBlob(image);
1777 if (status != MagickFalse)
1779 (void) fseek(blob_info->file,0,SEEK_SET);
1780 count=(ssize_t) MagickMaxBufferExtent;
1781 while (count == (ssize_t) MagickMaxBufferExtent)
1783 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
1785 custom_stream->writer(blob,count,custom_stream->data);
1788 (void) fclose(blob_info->file);
1790 blob=(unsigned char *) RelinquishMagickMemory(blob);
1791 (void) RelinquishUniqueFileResource(unique);
1793 blob_info=DestroyImageInfo(blob_info);
1797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1801 % I m a g e T o F i l e %
1805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1807 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1808 % occurs otherwise MagickTrue.
1810 % The format of the ImageToFile method is:
1812 % MagickBooleanType ImageToFile(Image *image,char *filename,
1813 % ExceptionInfo *exception)
1815 % A description of each parameter follows:
1817 % o image: the image.
1819 % o filename: Write the image to this file.
1821 % o exception: return any errors or warnings in this structure.
1824 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1825 ExceptionInfo *exception)
1830 register const unsigned char
1849 assert(image != (Image *) NULL);
1850 assert(image->signature == MagickCoreSignature);
1851 assert(image->blob != (BlobInfo *) NULL);
1852 assert(image->blob->type != UndefinedStream);
1853 if (image->debug != MagickFalse)
1854 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1855 assert(filename != (const char *) NULL);
1856 if (*filename == '\0')
1857 file=AcquireUniqueFileResource(filename);
1859 if (LocaleCompare(filename,"-") == 0)
1860 file=fileno(stdout);
1862 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1865 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1866 return(MagickFalse);
1868 quantum=(size_t) MagickMaxBufferExtent;
1869 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1870 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1871 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1872 if (buffer == (unsigned char *) NULL)
1875 (void) ThrowMagickException(exception,GetMagickModule(),
1876 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1877 return(MagickFalse);
1880 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1881 for (i=0; count > 0; )
1883 length=(size_t) count;
1884 for (i=0; i < length; i+=count)
1886 count=write(file,p+i,(size_t) (length-i));
1896 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1898 if (LocaleCompare(filename,"-") != 0)
1900 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1901 if ((file == -1) || (i < length))
1905 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1906 return(MagickFalse);
1912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1916 % I m a g e s T o B l o b %
1920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1922 % ImagesToBlob() implements direct to memory image formats. It returns the
1923 % image sequence as a blob and its length. The magick member of the ImageInfo
1924 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1926 % Note, some image formats do not permit multiple images to the same image
1927 % stream (e.g. JPEG). in this instance, just the first image of the
1928 % sequence is returned as a blob.
1930 % The format of the ImagesToBlob method is:
1932 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1933 % size_t *length,ExceptionInfo *exception)
1935 % A description of each parameter follows:
1937 % o image_info: the image info.
1939 % o images: the image list.
1941 % o length: return the actual length of the blob.
1943 % o exception: return any errors or warnings in this structure.
1946 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1947 size_t *length,ExceptionInfo *exception)
1961 assert(image_info != (const ImageInfo *) NULL);
1962 assert(image_info->signature == MagickCoreSignature);
1963 if (image_info->debug != MagickFalse)
1964 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1965 image_info->filename);
1966 assert(images != (Image *) NULL);
1967 assert(images->signature == MagickCoreSignature);
1968 assert(exception != (ExceptionInfo *) NULL);
1970 blob=(unsigned char *) NULL;
1971 blob_info=CloneImageInfo(image_info);
1972 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1974 if (*blob_info->magick != '\0')
1975 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
1976 magick_info=GetMagickInfo(images->magick,exception);
1977 if (magick_info == (const MagickInfo *) NULL)
1979 (void) ThrowMagickException(exception,GetMagickModule(),
1980 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1982 blob_info=DestroyImageInfo(blob_info);
1985 if (GetMagickAdjoin(magick_info) == MagickFalse)
1987 blob_info=DestroyImageInfo(blob_info);
1988 return(ImageToBlob(image_info,images,length,exception));
1990 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
1991 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1994 Native blob support for this images format.
1996 blob_info->length=0;
1997 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1998 sizeof(unsigned char));
1999 if (blob_info->blob == (void *) NULL)
2000 (void) ThrowMagickException(exception,GetMagickModule(),
2001 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
2004 (void) CloseBlob(images);
2005 images->blob->exempt=MagickTrue;
2006 *images->filename='\0';
2007 status=WriteImages(blob_info,images,images->filename,exception);
2008 *length=images->blob->length;
2009 blob=DetachBlob(images->blob);
2010 if (status == MagickFalse)
2011 blob=RelinquishMagickMemory(blob);
2013 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
2019 filename[MagickPathExtent],
2020 unique[MagickPathExtent];
2026 Write file to disk in blob images format.
2028 file=AcquireUniqueFileResource(unique);
2031 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
2032 image_info->filename);
2036 blob_info->file=fdopen(file,"wb");
2037 if (blob_info->file != (FILE *) NULL)
2039 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2040 images->magick,unique);
2041 status=WriteImages(blob_info,images,filename,exception);
2042 (void) CloseBlob(images);
2043 (void) fclose(blob_info->file);
2044 if (status != MagickFalse)
2045 blob=FileToBlob(unique,~0UL,length,exception);
2047 (void) RelinquishUniqueFileResource(unique);
2050 blob_info=DestroyImageInfo(blob_info);
2055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2059 + I m a g e s T o C u s t o m B l o b %
2063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2065 % ImagesToCustomStream() is the equivalent of WriteImages(), but writes the
2066 % formatted "file" to the custom stream rather than to an actual file.
2068 % The format of the ImageToCustomStream method is:
2070 % void ImagesToCustomStream(const ImageInfo *image_info,Image *images,
2071 % CustomStreamInfo *custom_stream,ExceptionInfo *exception)
2073 % A description of each parameter follows:
2075 % o image_info: the image info.
2077 % o images: the image list.
2079 % o custom_stream: the methods to use when writing and seeking.
2081 % o exception: return any errors or warnings in this structure.
2084 MagickExport void ImagesToCustomStream(const ImageInfo *image_info,
2085 Image *images,CustomStreamInfo *custom_stream,ExceptionInfo *exception)
2096 assert(image_info != (const ImageInfo *) NULL);
2097 assert(image_info->signature == MagickCoreSignature);
2098 if (image_info->debug != MagickFalse)
2099 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2100 image_info->filename);
2101 assert(images != (Image *) NULL);
2102 assert(images->signature == MagickCoreSignature);
2103 assert(custom_stream != (CustomStreamInfo *) NULL);
2104 assert(custom_stream->reader != (BlobHandler) NULL);
2105 assert(custom_stream->writer != (BlobHandler) NULL);
2106 assert(exception != (ExceptionInfo *) NULL);
2107 blob_info=CloneImageInfo(image_info);
2108 blob_info->custom_stream=custom_stream;
2109 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2111 if (*blob_info->magick != '\0')
2112 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2113 magick_info=GetMagickInfo(images->magick,exception);
2114 if (magick_info == (const MagickInfo *) NULL)
2116 (void) ThrowMagickException(exception,GetMagickModule(),
2117 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
2119 blob_info=DestroyImageInfo(blob_info);
2122 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2123 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2126 Native blob support for this image format.
2128 (void) CloseBlob(images);
2129 *images->filename='\0';
2130 (void) WriteImages(blob_info,images,images->filename,exception);
2131 (void) CloseBlob(images);
2136 filename[MagickPathExtent],
2137 unique[MagickPathExtent];
2146 Write file to disk in blob image format.
2148 blob_info->custom_stream=(CustomStreamInfo *) NULL;
2149 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
2151 if (blob == (unsigned char *) NULL)
2153 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2154 image_info->filename);
2155 blob_info=DestroyImageInfo(blob_info);
2158 file=AcquireUniqueFileResource(unique);
2161 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2162 image_info->filename);
2163 blob=(unsigned char *) RelinquishMagickMemory(blob);
2164 blob_info=DestroyImageInfo(blob_info);
2167 blob_info->file=fdopen(file,"wb+");
2168 if (blob_info->file != (FILE *) NULL)
2173 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2174 images->magick,unique);
2175 status=WriteImages(blob_info,images,filename,exception);
2176 (void) CloseBlob(images);
2177 if (status != MagickFalse)
2179 (void) fseek(blob_info->file,0,SEEK_SET);
2180 count=(ssize_t) MagickMaxBufferExtent;
2181 while (count == (ssize_t) MagickMaxBufferExtent)
2183 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
2185 custom_stream->writer(blob,count,custom_stream->data);
2188 (void) fclose(blob_info->file);
2190 blob=(unsigned char *) RelinquishMagickMemory(blob);
2191 (void) RelinquishUniqueFileResource(unique);
2193 blob_info=DestroyImageInfo(blob_info);
2198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2202 % I n j e c t I m a g e B l o b %
2206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2208 % InjectImageBlob() injects the image with a copy of itself in the specified
2209 % format (e.g. inject JPEG into a PDF image).
2211 % The format of the InjectImageBlob method is:
2213 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2214 % Image *image,Image *inject_image,const char *format,
2215 % ExceptionInfo *exception)
2217 % A description of each parameter follows:
2219 % o image_info: the image info..
2221 % o image: the image.
2223 % o inject_image: inject into the image stream.
2225 % o format: the image format.
2227 % o exception: return any errors or warnings in this structure.
2230 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2231 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
2234 filename[MagickPathExtent];
2267 Write inject image to a temporary file.
2269 assert(image_info != (ImageInfo *) NULL);
2270 assert(image_info->signature == MagickCoreSignature);
2271 assert(image != (Image *) NULL);
2272 assert(image->signature == MagickCoreSignature);
2273 if (image->debug != MagickFalse)
2274 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2275 assert(inject_image != (Image *) NULL);
2276 assert(inject_image->signature == MagickCoreSignature);
2277 assert(exception != (ExceptionInfo *) NULL);
2278 unique_file=(FILE *) NULL;
2279 file=AcquireUniqueFileResource(filename);
2281 unique_file=fdopen(file,"wb");
2282 if ((file == -1) || (unique_file == (FILE *) NULL))
2284 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2285 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
2287 return(MagickFalse);
2289 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
2290 if (byte_image == (Image *) NULL)
2292 (void) fclose(unique_file);
2293 (void) RelinquishUniqueFileResource(filename);
2294 return(MagickFalse);
2296 (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",format,
2298 DestroyBlob(byte_image);
2299 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
2300 write_info=CloneImageInfo(image_info);
2301 SetImageInfoFile(write_info,unique_file);
2302 status=WriteImage(write_info,byte_image,exception);
2303 write_info=DestroyImageInfo(write_info);
2304 byte_image=DestroyImage(byte_image);
2305 (void) fclose(unique_file);
2306 if (status == MagickFalse)
2308 (void) RelinquishUniqueFileResource(filename);
2309 return(MagickFalse);
2312 Inject into image stream.
2314 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
2317 (void) RelinquishUniqueFileResource(filename);
2318 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
2319 image_info->filename);
2320 return(MagickFalse);
2322 quantum=(size_t) MagickMaxBufferExtent;
2323 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
2324 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2325 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2326 if (buffer == (unsigned char *) NULL)
2328 (void) RelinquishUniqueFileResource(filename);
2330 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2333 for (i=0; ; i+=count)
2335 count=read(file,buffer,quantum);
2342 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2347 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2348 (void) RelinquishUniqueFileResource(filename);
2349 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2358 % I s B l o b E x e m p t %
2362 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2364 % IsBlobExempt() returns true if the blob is exempt.
2366 % The format of the IsBlobExempt method is:
2368 % MagickBooleanType IsBlobExempt(const Image *image)
2370 % A description of each parameter follows:
2372 % o image: the image.
2375 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
2377 assert(image != (const Image *) NULL);
2378 assert(image->signature == MagickCoreSignature);
2379 if (image->debug != MagickFalse)
2380 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2381 return(image->blob->exempt);
2385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2389 % I s B l o b S e e k a b l e %
2393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2395 % IsBlobSeekable() returns true if the blob is seekable.
2397 % The format of the IsBlobSeekable method is:
2399 % MagickBooleanType IsBlobSeekable(const Image *image)
2401 % A description of each parameter follows:
2403 % o image: the image.
2406 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2411 assert(image != (const Image *) NULL);
2412 assert(image->signature == MagickCoreSignature);
2413 if (image->debug != MagickFalse)
2414 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2415 switch (image->blob->type)
2421 seekable=MagickTrue;
2424 case UndefinedStream:
2425 case StandardStream:
2431 seekable=MagickFalse;
2436 if ((image->blob->custom_stream->seeker != (BlobSeeker) NULL) &&
2437 (image->blob->custom_stream->teller != (BlobTeller) NULL))
2438 seekable=MagickTrue;
2440 seekable=MagickFalse;
2448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2452 % I s B l o b T e m p o r a r y %
2456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2458 % IsBlobTemporary() returns true if the blob is temporary.
2460 % The format of the IsBlobTemporary method is:
2462 % MagickBooleanType IsBlobTemporary(const Image *image)
2464 % A description of each parameter follows:
2466 % o image: the image.
2469 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2471 assert(image != (const Image *) NULL);
2472 assert(image->signature == MagickCoreSignature);
2473 if (image->debug != MagickFalse)
2474 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2475 return(image->blob->temporary);
2479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2489 % MapBlob() creates a mapping from a file to a binary large object.
2491 % The format of the MapBlob method is:
2493 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2494 % const size_t length)
2496 % A description of each parameter follows:
2498 % o file: map this file descriptor.
2500 % o mode: ReadMode, WriteMode, or IOMode.
2502 % o offset: starting at this offset within the file.
2504 % o length: the length of the mapping is returned in this pointer.
2507 MagickExport void *MapBlob(int file,const MapMode mode,
2508 const MagickOffsetType offset,const size_t length)
2510 #if defined(MAGICKCORE_HAVE_MMAP)
2523 #if defined(MAP_ANONYMOUS)
2524 flags|=MAP_ANONYMOUS;
2533 protection=PROT_READ;
2539 protection=PROT_WRITE;
2545 protection=PROT_READ | PROT_WRITE;
2550 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2551 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2553 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2555 if (map == MAP_FAILED)
2556 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2558 if (map == MAP_FAILED)
2571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2575 + M S B O r d e r L o n g %
2579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2581 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2582 % most-significant byte first.
2584 % The format of the MSBOrderLong method is:
2586 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2588 % A description of each parameter follows.
2590 % o buffer: Specifies a pointer to a buffer of integers.
2592 % o length: Specifies the length of the buffer.
2595 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2600 register unsigned char
2604 assert(buffer != (unsigned char *) NULL);
2611 *buffer++=(unsigned char) c;
2615 *buffer++=(unsigned char) c;
2621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2625 + M S B O r d e r S h o r t %
2629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2631 % MSBOrderShort() converts a least-significant byte first buffer of integers
2632 % to most-significant byte first.
2634 % The format of the MSBOrderShort method is:
2636 % void MSBOrderShort(unsigned char *p,const size_t length)
2638 % A description of each parameter follows.
2640 % o p: Specifies a pointer to a buffer of integers.
2642 % o length: Specifies the length of the buffer.
2645 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2650 register unsigned char
2653 assert(p != (unsigned char *) NULL);
2660 *p++=(unsigned char) c;
2665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2675 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2676 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2677 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2678 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2679 % from a system command.
2681 % The format of the OpenBlob method is:
2683 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2684 % const BlobMode mode,ExceptionInfo *exception)
2686 % A description of each parameter follows:
2688 % o image_info: the image info.
2690 % o image: the image.
2692 % o mode: the mode for opening the file.
2696 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2709 option=GetImageOption(image_info,"stream:buffer-size");
2710 if (option != (const char *) NULL)
2711 size=StringToUnsignedLong(option);
2712 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2713 _IONBF : _IOFBF,size);
2714 return(status == 0 ? MagickTrue : MagickFalse);
2717 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2718 Image *image,const BlobMode mode,ExceptionInfo *exception)
2721 extension[MagickPathExtent],
2722 filename[MagickPathExtent];
2733 assert(image_info != (ImageInfo *) NULL);
2734 assert(image_info->signature == MagickCoreSignature);
2735 if (image_info->debug != MagickFalse)
2736 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2737 image_info->filename);
2738 assert(image != (Image *) NULL);
2739 assert(image->signature == MagickCoreSignature);
2740 if (image_info->blob != (void *) NULL)
2742 if (image_info->stream != (StreamHandler) NULL)
2743 image->blob->stream=(StreamHandler) image_info->stream;
2744 AttachBlob(image->blob,image_info->blob,image_info->length);
2747 if ((image_info->custom_stream != (CustomStreamInfo *) NULL) &&
2748 (*image->filename == '\0'))
2750 image->blob->type=CustomStream;
2751 image->blob->custom_stream=image_info->custom_stream;
2754 (void) DetachBlob(image->blob);
2757 default: type="r"; break;
2758 case ReadBlobMode: type="r"; break;
2759 case ReadBinaryBlobMode: type="rb"; break;
2760 case WriteBlobMode: type="w"; break;
2761 case WriteBinaryBlobMode: type="w+b"; break;
2762 case AppendBlobMode: type="a"; break;
2763 case AppendBinaryBlobMode: type="a+b"; break;
2766 image->blob->synchronize=image_info->synchronize;
2767 if (image_info->stream != (StreamHandler) NULL)
2769 image->blob->stream=(StreamHandler) image_info->stream;
2772 image->blob->type=FifoStream;
2780 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2781 rights=ReadPolicyRights;
2783 rights=WritePolicyRights;
2784 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2787 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2788 "NotAuthorized","`%s'",filename);
2789 return(MagickFalse);
2791 if ((LocaleCompare(filename,"-") == 0) ||
2792 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2794 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2795 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2796 if (strchr(type,'b') != (char *) NULL)
2797 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2799 image->blob->type=StandardStream;
2800 image->blob->exempt=MagickTrue;
2801 return(SetStreamBuffering(image_info,image));
2803 if (LocaleNCompare(filename,"fd:",3) == 0)
2806 fileMode[MagickPathExtent];
2810 image->blob->file_info.file=fdopen(StringToLong(filename+3),fileMode);
2811 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2812 if (strchr(type,'b') != (char *) NULL)
2813 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2815 image->blob->type=StandardStream;
2816 image->blob->exempt=MagickTrue;
2817 return(SetStreamBuffering(image_info,image));
2819 #if defined(MAGICKCORE_HAVE_POPEN) && defined(MAGICKCORE_PIPES_SUPPORT)
2820 if (*filename == '|')
2823 fileMode[MagickPathExtent],
2827 Pipe image to or from a system command.
2829 #if defined(SIGPIPE)
2831 (void) signal(SIGPIPE,SIG_IGN);
2835 sanitize_command=SanitizeString(filename+1);
2836 image->blob->file_info.file=(FILE *) popen_utf8(sanitize_command,
2838 sanitize_command=DestroyString(sanitize_command);
2839 if (image->blob->file_info.file == (FILE *) NULL)
2841 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2842 return(MagickFalse);
2844 image->blob->type=PipeStream;
2845 image->blob->exempt=MagickTrue;
2846 return(SetStreamBuffering(image_info,image));
2849 status=GetPathAttributes(filename,&image->blob->properties);
2850 #if defined(S_ISFIFO)
2851 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2853 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2854 if (image->blob->file_info.file == (FILE *) NULL)
2856 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2857 return(MagickFalse);
2859 image->blob->type=FileStream;
2860 image->blob->exempt=MagickTrue;
2861 return(SetStreamBuffering(image_info,image));
2864 GetPathComponent(image->filename,ExtensionPath,extension);
2867 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2868 if ((image_info->adjoin == MagickFalse) ||
2869 (strchr(filename,'%') != (char *) NULL))
2872 Form filename for multi-part images.
2874 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2875 image->scene,filename,exception);
2876 if ((LocaleCompare(filename,image->filename) == 0) &&
2877 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2878 (GetNextImageInList(image) != (Image *) NULL)))
2881 path[MagickPathExtent];
2883 GetPathComponent(image->filename,RootPath,path);
2884 if (*extension == '\0')
2885 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
2886 path,(double) image->scene);
2888 (void) FormatLocaleString(filename,MagickPathExtent,
2889 "%s-%.20g.%s",path,(double) image->scene,extension);
2891 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2892 #if defined(macintosh)
2893 SetApplicationType(filename,image_info->magick,'8BIM');
2897 if (image_info->file != (FILE *) NULL)
2899 image->blob->file_info.file=image_info->file;
2900 image->blob->type=FileStream;
2901 image->blob->exempt=MagickTrue;
2906 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2907 if (image->blob->file_info.file != (FILE *) NULL)
2915 image->blob->type=FileStream;
2916 (void) SetStreamBuffering(image_info,image);
2917 (void) ResetMagickMemory(magick,0,sizeof(magick));
2918 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2919 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2920 #if defined(MAGICKCORE_POSIX_SUPPORT)
2921 (void) fflush(image->blob->file_info.file);
2923 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2924 " read %.20g magic header bytes",(double) count);
2925 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2926 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2927 ((int) magick[2] == 0x08))
2929 if (image->blob->file_info.file != (FILE *) NULL)
2930 (void) fclose(image->blob->file_info.file);
2931 image->blob->file_info.file=(FILE *) NULL;
2932 image->blob->file_info.gzfile=gzopen(filename,type);
2933 if (image->blob->file_info.gzfile != (gzFile) NULL)
2934 image->blob->type=ZipStream;
2937 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2938 if (strncmp((char *) magick,"BZh",3) == 0)
2940 if (image->blob->file_info.file != (FILE *) NULL)
2941 (void) fclose(image->blob->file_info.file);
2942 image->blob->file_info.file=(FILE *) NULL;
2943 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2944 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2945 image->blob->type=BZipStream;
2948 if (image->blob->type == FileStream)
2959 sans_exception=AcquireExceptionInfo();
2960 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2961 sans_exception=DestroyExceptionInfo(sans_exception);
2962 length=(size_t) image->blob->properties.st_size;
2963 if ((magick_info != (const MagickInfo *) NULL) &&
2964 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2965 (length > MagickMaxBufferExtent) &&
2966 (AcquireMagickResource(MapResource,length) != MagickFalse))
2971 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
2973 if (blob == (void *) NULL)
2974 RelinquishMagickResource(MapResource,length);
2978 Format supports blobs-- use memory-mapped I/O.
2980 if (image_info->file != (FILE *) NULL)
2981 image->blob->exempt=MagickFalse;
2984 (void) fclose(image->blob->file_info.file);
2985 image->blob->file_info.file=(FILE *) NULL;
2987 AttachBlob(image->blob,blob,length);
2988 image->blob->mapped=MagickTrue;
2995 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2996 if ((LocaleCompare(extension,"Z") == 0) ||
2997 (LocaleCompare(extension,"gz") == 0) ||
2998 (LocaleCompare(extension,"wmz") == 0) ||
2999 (LocaleCompare(extension,"svgz") == 0))
3001 if (mode == WriteBinaryBlobMode)
3003 image->blob->file_info.gzfile=gzopen(filename,type);
3004 if (image->blob->file_info.gzfile != (gzFile) NULL)
3005 image->blob->type=ZipStream;
3009 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3010 if (LocaleCompare(extension,"bz2") == 0)
3012 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3013 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3014 image->blob->type=BZipStream;
3019 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
3020 if (image->blob->file_info.file != (FILE *) NULL)
3022 image->blob->type=FileStream;
3023 (void) SetStreamBuffering(image_info,image);
3026 image->blob->status=MagickFalse;
3027 if (image->blob->type != UndefinedStream)
3028 image->blob->size=GetBlobSize(image);
3031 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
3032 return(MagickFalse);
3038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3048 % PingBlob() returns all the attributes of an image or image sequence except
3049 % for the pixels. It is much faster and consumes far less memory than
3050 % BlobToImage(). On failure, a NULL image is returned and exception
3051 % describes the reason for the failure.
3053 % The format of the PingBlob method is:
3055 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
3056 % const size_t length,ExceptionInfo *exception)
3058 % A description of each parameter follows:
3060 % o image_info: the image info.
3062 % o blob: the address of a character stream in one of the image formats
3063 % understood by ImageMagick.
3065 % o length: This size_t integer reflects the length in bytes of the blob.
3067 % o exception: return any errors or warnings in this structure.
3071 #if defined(__cplusplus) || defined(c_plusplus)
3075 static size_t PingStream(const Image *magick_unused(image),
3076 const void *magick_unused(pixels),const size_t columns)
3078 magick_unreferenced(image);
3079 magick_unreferenced(pixels);
3083 #if defined(__cplusplus) || defined(c_plusplus)
3087 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
3088 const size_t length,ExceptionInfo *exception)
3096 assert(image_info != (ImageInfo *) NULL);
3097 assert(image_info->signature == MagickCoreSignature);
3098 if (image_info->debug != MagickFalse)
3099 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3100 image_info->filename);
3101 assert(exception != (ExceptionInfo *) NULL);
3102 if ((blob == (const void *) NULL) || (length == 0))
3104 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
3105 "UnrecognizedImageFormat","`%s'",image_info->magick);
3106 return((Image *) NULL);
3108 ping_info=CloneImageInfo(image_info);
3109 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
3110 if (ping_info->blob == (const void *) NULL)
3112 (void) ThrowMagickException(exception,GetMagickModule(),
3113 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
3114 return((Image *) NULL);
3116 (void) memcpy(ping_info->blob,blob,length);
3117 ping_info->length=length;
3118 ping_info->ping=MagickTrue;
3119 image=ReadStream(ping_info,&PingStream,exception);
3120 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
3121 ping_info=DestroyImageInfo(ping_info);
3126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3136 % ReadBlob() reads data from the blob or image file and returns it. It
3137 % returns the number of bytes read. If length is zero, ReadBlob() returns
3138 % zero and has no other results. If length is greater than SSIZE_MAX, the
3139 % result is unspecified.
3141 % The format of the ReadBlob method is:
3143 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
3145 % A description of each parameter follows:
3147 % o image: the image.
3149 % o length: Specifies an integer representing the number of bytes to read
3152 % o data: Specifies an area to place the information requested from the
3156 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
3161 register unsigned char
3167 assert(image != (Image *) NULL);
3168 assert(image->signature == MagickCoreSignature);
3169 assert(image->blob != (BlobInfo *) NULL);
3170 assert(image->blob->type != UndefinedStream);
3173 assert(data != (void *) NULL);
3175 q=(unsigned char *) data;
3176 switch (image->blob->type)
3178 case UndefinedStream:
3180 case StandardStream:
3188 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
3193 c=getc(image->blob->file_info.file);
3196 *q++=(unsigned char) c;
3201 c=getc(image->blob->file_info.file);
3204 *q++=(unsigned char) c;
3209 c=getc(image->blob->file_info.file);
3212 *q++=(unsigned char) c;
3217 c=getc(image->blob->file_info.file);
3220 *q++=(unsigned char) c;
3230 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3235 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
3236 (unsigned int) length);
3241 c=gzgetc(image->blob->file_info.gzfile);
3244 *q++=(unsigned char) c;
3249 c=gzgetc(image->blob->file_info.gzfile);
3252 *q++=(unsigned char) c;
3257 c=gzgetc(image->blob->file_info.gzfile);
3260 *q++=(unsigned char) c;
3265 c=gzgetc(image->blob->file_info.gzfile);
3268 *q++=(unsigned char) c;
3279 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3280 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
3288 register const unsigned char
3291 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3293 image->blob->eof=MagickTrue;
3296 p=image->blob->data+image->blob->offset;
3297 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
3298 image->blob->offset+=count;
3299 if (count != (ssize_t) length)
3300 image->blob->eof=MagickTrue;
3301 (void) memcpy(q,p,(size_t) count);
3306 count=image->blob->custom_stream->reader(q,length,
3307 image->blob->custom_stream->data);
3315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3319 + R e a d B l o b B y t e %
3323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3325 % ReadBlobByte() reads a single byte from the image file and returns it.
3327 % The format of the ReadBlobByte method is:
3329 % int ReadBlobByte(Image *image)
3331 % A description of each parameter follows.
3333 % o image: the image.
3336 MagickExport int ReadBlobByte(Image *image)
3338 register const unsigned char
3347 assert(image != (Image *) NULL);
3348 assert(image->signature == MagickCoreSignature);
3349 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3360 + R e a d B l o b D o u b l e %
3364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3366 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3367 % specified by the endian member of the image structure.
3369 % The format of the ReadBlobDouble method is:
3371 % double ReadBlobDouble(Image *image)
3373 % A description of each parameter follows.
3375 % o image: the image.
3378 MagickExport double ReadBlobDouble(Image *image)
3389 quantum.double_value=0.0;
3390 quantum.unsigned_value=ReadBlobLongLong(image);
3391 return(quantum.double_value);
3395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3399 + R e a d B l o b F l o a t %
3403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3405 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3406 % specified by the endian member of the image structure.
3408 % The format of the ReadBlobFloat method is:
3410 % float ReadBlobFloat(Image *image)
3412 % A description of each parameter follows.
3414 % o image: the image.
3417 MagickExport float ReadBlobFloat(Image *image)
3428 quantum.float_value=0.0;
3429 quantum.unsigned_value=ReadBlobLong(image);
3430 return(quantum.float_value);
3434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3438 + R e a d B l o b L o n g %
3442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3444 % ReadBlobLong() reads a unsigned int value as a 32-bit quantity in the
3445 % byte-order specified by the endian member of the image structure.
3447 % The format of the ReadBlobLong method is:
3449 % unsigned int ReadBlobLong(Image *image)
3451 % A description of each parameter follows.
3453 % o image: the image.
3456 MagickExport unsigned int ReadBlobLong(Image *image)
3458 register const unsigned char
3470 assert(image != (Image *) NULL);
3471 assert(image->signature == MagickCoreSignature);
3473 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3476 if (image->endian == LSBEndian)
3478 value=(unsigned int) (*p++);
3479 value|=(unsigned int) (*p++) << 8;
3480 value|=(unsigned int) (*p++) << 16;
3481 value|=(unsigned int) (*p++) << 24;
3482 return(value & 0xffffffff);
3484 value=(unsigned int) (*p++) << 24;
3485 value|=(unsigned int) (*p++) << 16;
3486 value|=(unsigned int) (*p++) << 8;
3487 value|=(unsigned int) (*p++);
3488 return(value & 0xffffffff);
3492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3496 + R e a d B l o b L o n g L o n g %
3500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3502 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3503 % byte-order specified by the endian member of the image structure.
3505 % The format of the ReadBlobLongLong method is:
3507 % MagickSizeType ReadBlobLongLong(Image *image)
3509 % A description of each parameter follows.
3511 % o image: the image.
3514 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3519 register const unsigned char
3528 assert(image != (Image *) NULL);
3529 assert(image->signature == MagickCoreSignature);
3531 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3533 return(MagickULLConstant(0));
3534 if (image->endian == LSBEndian)
3536 value=(MagickSizeType) (*p++);
3537 value|=(MagickSizeType) (*p++) << 8;
3538 value|=(MagickSizeType) (*p++) << 16;
3539 value|=(MagickSizeType) (*p++) << 24;
3540 value|=(MagickSizeType) (*p++) << 32;
3541 value|=(MagickSizeType) (*p++) << 40;
3542 value|=(MagickSizeType) (*p++) << 48;
3543 value|=(MagickSizeType) (*p++) << 56;
3544 return(value & MagickULLConstant(0xffffffffffffffff));
3546 value=(MagickSizeType) (*p++) << 56;
3547 value|=(MagickSizeType) (*p++) << 48;
3548 value|=(MagickSizeType) (*p++) << 40;
3549 value|=(MagickSizeType) (*p++) << 32;
3550 value|=(MagickSizeType) (*p++) << 24;
3551 value|=(MagickSizeType) (*p++) << 16;
3552 value|=(MagickSizeType) (*p++) << 8;
3553 value|=(MagickSizeType) (*p++);
3554 return(value & MagickULLConstant(0xffffffffffffffff));
3558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3562 + R e a d B l o b S h o r t %
3566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3568 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3569 % specified by the endian member of the image structure.
3571 % The format of the ReadBlobShort method is:
3573 % unsigned short ReadBlobShort(Image *image)
3575 % A description of each parameter follows.
3577 % o image: the image.
3580 MagickExport unsigned short ReadBlobShort(Image *image)
3582 register const unsigned char
3585 register unsigned short
3594 assert(image != (Image *) NULL);
3595 assert(image->signature == MagickCoreSignature);
3597 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3599 return((unsigned short) 0U);
3600 if (image->endian == LSBEndian)
3602 value=(unsigned short) (*p++);
3603 value|=(unsigned short) (*p++) << 8;
3606 value=(unsigned short) (*p++) << 8;
3607 value|=(unsigned short) (*p++);
3612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3616 + R e a d B l o b L S B L o n g %
3620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3622 % ReadBlobLSBLong() reads a unsigned int value as a 32-bit quantity in
3623 % least-significant byte first order.
3625 % The format of the ReadBlobLSBLong method is:
3627 % unsigned int ReadBlobLSBLong(Image *image)
3629 % A description of each parameter follows.
3631 % o image: the image.
3634 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3636 register const unsigned char
3639 register unsigned int
3648 assert(image != (Image *) NULL);
3649 assert(image->signature == MagickCoreSignature);
3651 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3654 value=(unsigned int) (*p++);
3655 value|=(unsigned int) (*p++) << 8;
3656 value|=(unsigned int) (*p++) << 16;
3657 value|=(unsigned int) (*p++) << 24;
3658 return(value & 0xffffffff);
3662 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3666 + R e a d B l o b L S B S i g n e d L o n g %
3670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3672 % ReadBlobLSBSignedLong() reads a signed int value as a 32-bit quantity in
3673 % least-significant byte first order.
3675 % The format of the ReadBlobLSBSignedLong method is:
3677 % signed int ReadBlobLSBSignedLong(Image *image)
3679 % A description of each parameter follows.
3681 % o image: the image.
3684 MagickExport signed int ReadBlobLSBSignedLong(Image *image)
3695 quantum.unsigned_value=ReadBlobLSBLong(image);
3696 return(quantum.signed_value);
3700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3704 + R e a d B l o b L S B S h o r t %
3708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3710 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3711 % least-significant byte first order.
3713 % The format of the ReadBlobLSBShort method is:
3715 % unsigned short ReadBlobLSBShort(Image *image)
3717 % A description of each parameter follows.
3719 % o image: the image.
3722 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3724 register const unsigned char
3727 register unsigned short
3736 assert(image != (Image *) NULL);
3737 assert(image->signature == MagickCoreSignature);
3739 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3741 return((unsigned short) 0U);
3742 value=(unsigned int) (*p++);
3743 value|=(unsigned int) (*p++) << 8;
3744 return(value & 0xffff);
3748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3752 + R e a d B l o b L S B S i g n e d S h o r t %
3756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3758 % ReadBlobLSBSignedShort() reads a signed short value as a 16-bit quantity in
3759 % least-significant byte-order.
3761 % The format of the ReadBlobLSBSignedShort method is:
3763 % signed short ReadBlobLSBSignedShort(Image *image)
3765 % A description of each parameter follows.
3767 % o image: the image.
3770 MagickExport signed short ReadBlobLSBSignedShort(Image *image)
3781 quantum.unsigned_value=ReadBlobLSBShort(image);
3782 return(quantum.signed_value);
3786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3790 + R e a d B l o b M S B L o n g %
3794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3796 % ReadBlobMSBLong() reads a unsigned int value as a 32-bit quantity in
3797 % most-significant byte first order.
3799 % The format of the ReadBlobMSBLong method is:
3801 % unsigned int ReadBlobMSBLong(Image *image)
3803 % A description of each parameter follows.
3805 % o image: the image.
3808 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3810 register const unsigned char
3813 register unsigned int
3822 assert(image != (Image *) NULL);
3823 assert(image->signature == MagickCoreSignature);
3825 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3828 value=(unsigned int) (*p++) << 24;
3829 value|=(unsigned int) (*p++) << 16;
3830 value|=(unsigned int) (*p++) << 8;
3831 value|=(unsigned int) (*p++);
3836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3840 + R e a d B l o b M S B L o n g L o n g %
3844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3846 % ReadBlobMSBLongLong() reads a unsigned long long value as a 64-bit quantity
3847 % in most-significant byte first order.
3849 % The format of the ReadBlobMSBLongLong method is:
3851 % unsigned int ReadBlobMSBLongLong(Image *image)
3853 % A description of each parameter follows.
3855 % o image: the image.
3858 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3860 register const unsigned char
3863 register MagickSizeType
3872 assert(image != (Image *) NULL);
3873 assert(image->signature == MagickCoreSignature);
3875 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3877 return(MagickULLConstant(0));
3878 value=(MagickSizeType) (*p++) << 56;
3879 value|=(MagickSizeType) (*p++) << 48;
3880 value|=(MagickSizeType) (*p++) << 40;
3881 value|=(MagickSizeType) (*p++) << 32;
3882 value|=(MagickSizeType) (*p++) << 24;
3883 value|=(MagickSizeType) (*p++) << 16;
3884 value|=(MagickSizeType) (*p++) << 8;
3885 value|=(MagickSizeType) (*p++);
3886 return(value & MagickULLConstant(0xffffffffffffffff));
3890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3894 + R e a d B l o b M S B S h o r t %
3898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3900 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3901 % most-significant byte first order.
3903 % The format of the ReadBlobMSBShort method is:
3905 % unsigned short ReadBlobMSBShort(Image *image)
3907 % A description of each parameter follows.
3909 % o image: the image.
3912 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3914 register const unsigned char
3917 register unsigned short
3926 assert(image != (Image *) NULL);
3927 assert(image->signature == MagickCoreSignature);
3929 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3931 return((unsigned short) 0U);
3932 value=(unsigned short) (*p++) << 8;
3933 value|=(unsigned short) (*p++);
3934 return(value & 0xffff);
3938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3942 + R e a d B l o b M S B S i g n e d L o n g %
3946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3948 % ReadBlobMSBSignedLong() reads a signed int value as a 32-bit quantity in
3949 % most-significant byte-order.
3951 % The format of the ReadBlobMSBSignedLong method is:
3953 % signed int ReadBlobMSBSignedLong(Image *image)
3955 % A description of each parameter follows.
3957 % o image: the image.
3960 MagickExport signed int ReadBlobMSBSignedLong(Image *image)
3971 quantum.unsigned_value=ReadBlobMSBLong(image);
3972 return(quantum.signed_value);
3976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3980 + R e a d B l o b M S B S i g n e d S h o r t %
3984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3986 % ReadBlobMSBSignedShort() reads a signed short value as a 16-bit quantity in
3987 % most-significant byte-order.
3989 % The format of the ReadBlobMSBSignedShort method is:
3991 % signed short ReadBlobMSBSignedShort(Image *image)
3993 % A description of each parameter follows.
3995 % o image: the image.
3998 MagickExport signed short ReadBlobMSBSignedShort(Image *image)
4009 quantum.unsigned_value=ReadBlobMSBShort(image);
4010 return(quantum.signed_value);
4014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4018 + R e a d B l o b S i g n e d L o n g %
4022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4024 % ReadBlobSignedLong() reads a signed int value as a 32-bit quantity in the
4025 % byte-order specified by the endian member of the image structure.
4027 % The format of the ReadBlobSignedLong method is:
4029 % signed int ReadBlobSignedLong(Image *image)
4031 % A description of each parameter follows.
4033 % o image: the image.
4036 MagickExport signed int ReadBlobSignedLong(Image *image)
4047 quantum.unsigned_value=ReadBlobLong(image);
4048 return(quantum.signed_value);
4052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4056 + R e a d B l o b S i g n e d S h o r t %
4060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4062 % ReadBlobSignedShort() reads a signed short value as a 16-bit quantity in the
4063 % byte-order specified by the endian member of the image structure.
4065 % The format of the ReadBlobSignedShort method is:
4067 % signed short ReadBlobSignedShort(Image *image)
4069 % A description of each parameter follows.
4071 % o image: the image.
4074 MagickExport signed short ReadBlobSignedShort(Image *image)
4085 quantum.unsigned_value=ReadBlobShort(image);
4086 return(quantum.signed_value);
4090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4094 + R e a d B l o b S t r e a m %
4098 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4100 % ReadBlobStream() reads data from the blob or image file and returns it. It
4101 % returns a pointer to the data buffer you supply or to the image memory
4102 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
4103 % returns a count of zero and has no other results. If length is greater than
4104 % SSIZE_MAX, the result is unspecified.
4106 % The format of the ReadBlobStream method is:
4108 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
4111 % A description of each parameter follows:
4113 % o image: the image.
4115 % o length: Specifies an integer representing the number of bytes to read
4118 % o count: returns the number of bytes read.
4120 % o data: Specifies an area to place the information requested from the
4124 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
4125 void *data,ssize_t *count)
4127 assert(image != (Image *) NULL);
4128 assert(image->signature == MagickCoreSignature);
4129 assert(image->blob != (BlobInfo *) NULL);
4130 assert(image->blob->type != UndefinedStream);
4131 assert(count != (ssize_t *) NULL);
4132 if (image->blob->type != BlobStream)
4134 assert(data != NULL);
4135 *count=ReadBlob(image,length,(unsigned char *) data);
4138 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4141 image->blob->eof=MagickTrue;
4144 data=image->blob->data+image->blob->offset;
4145 *count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
4146 image->blob->offset+=(*count);
4147 if (*count != (ssize_t) length)
4148 image->blob->eof=MagickTrue;
4153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4157 + R e a d B l o b S t r i n g %
4161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4163 % ReadBlobString() reads characters from a blob or file until a newline
4164 % character is read or an end-of-file condition is encountered.
4166 % The format of the ReadBlobString method is:
4168 % char *ReadBlobString(Image *image,char *string)
4170 % A description of each parameter follows:
4172 % o image: the image.
4174 % o string: the address of a character buffer.
4177 MagickExport char *ReadBlobString(Image *image,char *string)
4179 register const unsigned char
4191 assert(image != (Image *) NULL);
4192 assert(image->signature == MagickCoreSignature);
4193 for (i=0; i < (MagickPathExtent-1L); i++)
4195 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
4199 return((char *) NULL);
4202 string[i]=(char) (*p);
4203 if ((string[i] == '\r') || (string[i] == '\n'))
4206 if (string[i] == '\r')
4207 (void) ReadBlobStream(image,1,buffer,&count);
4213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4217 + R e f e r e n c e B l o b %
4221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4223 % ReferenceBlob() increments the reference count associated with the pixel
4224 % blob returning a pointer to the blob.
4226 % The format of the ReferenceBlob method is:
4228 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
4230 % A description of each parameter follows:
4232 % o blob_info: the blob_info.
4235 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
4237 assert(blob != (BlobInfo *) NULL);
4238 assert(blob->signature == MagickCoreSignature);
4239 if (blob->debug != MagickFalse)
4240 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4241 LockSemaphoreInfo(blob->semaphore);
4242 blob->reference_count++;
4243 UnlockSemaphoreInfo(blob->semaphore);
4248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4258 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
4259 % and returns the resulting offset.
4261 % The format of the SeekBlob method is:
4263 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
4266 % A description of each parameter follows:
4268 % o image: the image.
4270 % o offset: Specifies an integer representing the offset in bytes.
4272 % o whence: Specifies an integer representing how the offset is
4273 % treated relative to the beginning of the blob as follows:
4275 % SEEK_SET Set position equal to offset bytes.
4276 % SEEK_CUR Set position to current location plus offset.
4277 % SEEK_END Set position to EOF plus offset.
4280 MagickExport MagickOffsetType SeekBlob(Image *image,
4281 const MagickOffsetType offset,const int whence)
4283 assert(image != (Image *) NULL);
4284 assert(image->signature == MagickCoreSignature);
4285 if (image->debug != MagickFalse)
4286 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4287 assert(image->blob != (BlobInfo *) NULL);
4288 assert(image->blob->type != UndefinedStream);
4289 switch (image->blob->type)
4291 case UndefinedStream:
4293 case StandardStream:
4298 if ((offset < 0) && (whence == SEEK_SET))
4300 if (fseek(image->blob->file_info.file,offset,whence) < 0)
4302 image->blob->offset=TellBlob(image);
4307 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4308 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
4311 image->blob->offset=TellBlob(image);
4327 image->blob->offset=offset;
4332 if ((image->blob->offset+offset) < 0)
4334 image->blob->offset+=offset;
4339 if (((MagickOffsetType) image->blob->length+offset) < 0)
4341 image->blob->offset=image->blob->length+offset;
4345 if (image->blob->offset < (MagickOffsetType)
4346 ((off_t) image->blob->length))
4348 image->blob->eof=MagickFalse;
4351 if (image->blob->offset < (MagickOffsetType)
4352 ((off_t) image->blob->extent))
4354 if (image->blob->mapped != MagickFalse)
4356 image->blob->eof=MagickTrue;
4359 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
4360 image->blob->quantum<<=1;
4361 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4362 image->blob->extent+1,sizeof(*image->blob->data));
4363 (void) SyncBlob(image);
4364 if (image->blob->data == NULL)
4366 (void) DetachBlob(image->blob);
4373 if (image->blob->custom_stream->seeker == (BlobSeeker) NULL)
4375 image->blob->offset=image->blob->custom_stream->seeker(offset,whence,
4376 image->blob->custom_stream->data);
4380 return(image->blob->offset);
4384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4388 % S e t B l o b C u s t o m S t r e a m %
4392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4394 % SetBlobCustomStream() sets the blob's custom stream handlers.
4396 % The format of the SetBlobCustomStream method is:
4398 % void SetBlobCustomStream(BlobInfo *blob_info,
4399 % ssize_t (*reader)(const unsigned char *,const size_t,const void *),
4400 % ssize_t (*writer)(const unsigned char *,const size_t,const void *),
4401 % size_t (*seeker)(const MagickOffsetType,const int,const void *),
4402 % MagickOffsetType (*teller)(const void *))
4404 % A description of each parameter follows:
4406 % o blob_info: the blob info.
4408 % o reader: your custom stream reader.
4410 % o writer: your custom stream writer.
4412 % o seeker: your custom stream seeker.
4414 % o teller: your custom stream teller.
4417 MagickExport void SetBlobCustomStream(BlobInfo *blob_info,
4418 ssize_t (*reader)(const unsigned char *,const size_t,const void *),
4419 ssize_t (*writer)(const unsigned char *,const size_t,const void *),
4420 size_t (*seeker)(const MagickOffsetType,const int,const void *),
4421 MagickOffsetType (*teller)(const void *))
4423 assert(blob_info != (BlobInfo *) NULL);
4424 assert(blob_info->signature == MagickCoreSignature);
4425 blob_info->custom_stream->reader=reader;
4426 blob_info->custom_stream->writer=writer;
4427 blob_info->custom_stream->seeker=seeker;
4428 blob_info->custom_stream->teller=teller;
4432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4436 + S e t B l o b E x e m p t %
4440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4442 % SetBlobExempt() sets the blob exempt status.
4444 % The format of the SetBlobExempt method is:
4446 % MagickBooleanType SetBlobExempt(const Image *image,
4447 % const MagickBooleanType exempt)
4449 % A description of each parameter follows:
4451 % o image: the image.
4453 % o exempt: Set to true if this blob is exempt from being closed.
4456 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
4458 assert(image != (const Image *) NULL);
4459 assert(image->signature == MagickCoreSignature);
4460 if (image->debug != MagickFalse)
4461 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4462 image->blob->exempt=exempt;
4466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4470 + S e t B l o b E x t e n t %
4474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4476 % SetBlobExtent() ensures enough space is allocated for the blob. If the
4477 % method is successful, subsequent writes to bytes in the specified range are
4478 % guaranteed not to fail.
4480 % The format of the SetBlobExtent method is:
4482 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
4484 % A description of each parameter follows:
4486 % o image: the image.
4488 % o extent: the blob maximum extent.
4491 MagickExport MagickBooleanType SetBlobExtent(Image *image,
4492 const MagickSizeType extent)
4494 assert(image != (Image *) NULL);
4495 assert(image->signature == MagickCoreSignature);
4496 if (image->debug != MagickFalse)
4497 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4498 assert(image->blob != (BlobInfo *) NULL);
4499 assert(image->blob->type != UndefinedStream);
4500 switch (image->blob->type)
4502 case UndefinedStream:
4504 case StandardStream:
4505 return(MagickFalse);
4514 if (extent != (MagickSizeType) ((off_t) extent))
4515 return(MagickFalse);
4516 offset=SeekBlob(image,0,SEEK_END);
4518 return(MagickFalse);
4519 if ((MagickSizeType) offset >= extent)
4521 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4524 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4525 image->blob->file_info.file);
4526 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4527 if (image->blob->synchronize != MagickFalse)
4532 file=fileno(image->blob->file_info.file);
4533 if ((file == -1) || (offset < 0))
4534 return(MagickFalse);
4535 (void) posix_fallocate(file,offset,extent-offset);
4538 offset=SeekBlob(image,offset,SEEK_SET);
4540 return(MagickFalse);
4545 return(MagickFalse);
4547 return(MagickFalse);
4549 return(MagickFalse);
4552 if (extent != (MagickSizeType) ((size_t) extent))
4553 return(MagickFalse);
4554 if (image->blob->mapped != MagickFalse)
4562 (void) UnmapBlob(image->blob->data,image->blob->length);
4563 RelinquishMagickResource(MapResource,image->blob->length);
4564 if (extent != (MagickSizeType) ((off_t) extent))
4565 return(MagickFalse);
4566 offset=SeekBlob(image,0,SEEK_END);
4568 return(MagickFalse);
4569 if ((MagickSizeType) offset >= extent)
4571 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4572 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4573 image->blob->file_info.file);
4574 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4575 if (image->blob->synchronize != MagickFalse)
4580 file=fileno(image->blob->file_info.file);
4581 if ((file == -1) || (offset < 0))
4582 return(MagickFalse);
4583 (void) posix_fallocate(file,offset,extent-offset);
4586 offset=SeekBlob(image,offset,SEEK_SET);
4588 return(MagickFalse);
4589 (void) AcquireMagickResource(MapResource,extent);
4590 image->blob->data=(unsigned char*) MapBlob(fileno(
4591 image->blob->file_info.file),WriteMode,0,(size_t) extent);
4592 image->blob->extent=(size_t) extent;
4593 image->blob->length=(size_t) extent;
4594 (void) SyncBlob(image);
4597 image->blob->extent=(size_t) extent;
4598 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4599 image->blob->extent+1,sizeof(*image->blob->data));
4600 (void) SyncBlob(image);
4601 if (image->blob->data == (unsigned char *) NULL)
4603 (void) DetachBlob(image->blob);
4604 return(MagickFalse);
4615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4625 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
4626 % attributes if it is an blob.
4628 % The format of the SyncBlob method is:
4630 % int SyncBlob(Image *image)
4632 % A description of each parameter follows:
4634 % o image: the image.
4637 static int SyncBlob(Image *image)
4642 assert(image != (Image *) NULL);
4643 assert(image->signature == MagickCoreSignature);
4644 if (image->debug != MagickFalse)
4645 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4646 assert(image->blob != (BlobInfo *) NULL);
4647 assert(image->blob->type != UndefinedStream);
4649 switch (image->blob->type)
4651 case UndefinedStream:
4652 case StandardStream:
4657 status=fflush(image->blob->file_info.file);
4662 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4663 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
4669 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4670 status=BZ2_bzflush(image->blob->file_info.bzfile);
4685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4695 % TellBlob() obtains the current value of the blob or file position.
4697 % The format of the TellBlob method is:
4699 % MagickOffsetType TellBlob(const Image *image)
4701 % A description of each parameter follows:
4703 % o image: the image.
4706 MagickExport MagickOffsetType TellBlob(const Image *image)
4711 assert(image != (Image *) NULL);
4712 assert(image->signature == MagickCoreSignature);
4713 if (image->debug != MagickFalse)
4714 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4715 assert(image->blob != (BlobInfo *) NULL);
4716 assert(image->blob->type != UndefinedStream);
4718 switch (image->blob->type)
4720 case UndefinedStream:
4721 case StandardStream:
4725 offset=ftell(image->blob->file_info.file);
4732 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4733 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
4743 offset=image->blob->offset;
4748 if (image->blob->custom_stream->teller != (BlobTeller) NULL)
4749 offset=image->blob->custom_stream->teller(image->blob->custom_stream->data);
4757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4761 + U n m a p B l o b %
4765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4767 % UnmapBlob() deallocates the binary large object previously allocated with
4768 % the MapBlob method.
4770 % The format of the UnmapBlob method is:
4772 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4774 % A description of each parameter follows:
4776 % o map: the address of the binary large object.
4778 % o length: the length of the binary large object.
4781 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4783 #if defined(MAGICKCORE_HAVE_MMAP)
4787 status=munmap(map,length);
4788 return(status == -1 ? MagickFalse : MagickTrue);
4792 return(MagickFalse);
4797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4801 % C u s t o m S t r e a m T o I m a g e %
4805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4807 % CustomStreamToImage() is the equivalent of ReadImage(), but reads the
4808 % formatted "file" from the suplied method rather than to an actual file.
4810 % The format of the CustomStreamToImage method is:
4812 % Image *CustomStreamToImage(const ImageInfo *image_info,
4813 % CustomStreamInfo *custom_stream,ExceptionInfo *exception)
4815 % A description of each parameter follows:
4817 % o image_info: the image info.
4819 % o custom_stream: the methods to use when writing and seeking.
4821 % o exception: return any errors or warnings in this structure.
4824 MagickExport Image *CustomStreamToImage(const ImageInfo *image_info,
4825 CustomStreamInfo *custom_stream,ExceptionInfo *exception)
4836 assert(image_info != (ImageInfo *) NULL);
4837 assert(image_info->signature == MagickCoreSignature);
4838 if (image_info->debug != MagickFalse)
4839 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
4840 image_info->filename);
4841 assert(custom_stream != (CustomStreamInfo *) NULL);
4842 assert(custom_stream->reader != (BlobHandler) NULL);
4843 assert(exception != (ExceptionInfo *) NULL);
4844 blob_info=CloneImageInfo(image_info);
4845 blob_info->custom_stream=custom_stream;
4846 if (*blob_info->magick == '\0')
4847 (void) SetImageInfo(blob_info,0,exception);
4848 magick_info=GetMagickInfo(blob_info->magick,exception);
4849 if (magick_info == (const MagickInfo *) NULL)
4851 (void) ThrowMagickException(exception,GetMagickModule(),
4852 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
4854 blob_info=DestroyImageInfo(blob_info);
4855 return((Image *) NULL);
4857 image=(Image *) NULL;
4858 if ((GetMagickBlobSupport(magick_info) != MagickFalse) ||
4859 (blob_info->custom_stream == (CustomStreamInfo *) NULL))
4862 Native blob support for this image format or SetImageInfo changed the
4865 image=ReadImage(blob_info,exception);
4866 if (image != (Image *) NULL)
4867 (void) CloseBlob(image);
4872 unique[MagickPathExtent];
4884 Write data to file on disk.
4886 blob_info->custom_stream=(CustomStreamInfo *) NULL;
4887 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
4889 if (blob == (unsigned char *) NULL)
4891 ThrowFileException(exception,BlobError,"UnableToReadBlob",
4892 image_info->filename);
4893 blob_info=DestroyImageInfo(blob_info);
4894 return((Image *) NULL);
4896 file=AcquireUniqueFileResource(unique);
4899 ThrowFileException(exception,BlobError,"UnableToReadBlob",
4900 image_info->filename);
4901 blob=(unsigned char *) RelinquishMagickMemory(blob);
4902 blob_info=DestroyImageInfo(blob_info);
4903 return((Image *) NULL);
4905 clone_info=CloneImageInfo(blob_info);
4906 blob_info->file=fdopen(file,"wb+");
4907 if (blob_info->file != (FILE *) NULL)
4912 count=(ssize_t) MagickMaxBufferExtent;
4913 while (count == (ssize_t) MagickMaxBufferExtent)
4915 count=custom_stream->reader(blob,MagickMaxBufferExtent,
4916 custom_stream->data);
4917 count=(ssize_t) write(file,(const char *) blob,count);
4919 (void) fclose(blob_info->file);
4920 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,
4921 "%s:%s",blob_info->magick,unique);
4922 image=ReadImage(clone_info,exception);
4923 if (image != (Image *) NULL)
4929 Restore original filenames and image format.
4931 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
4933 (void) CopyMagickString(images->filename,image_info->filename,
4935 (void) CopyMagickString(images->magick_filename,
4936 image_info->filename,MagickPathExtent);
4937 (void) CopyMagickString(images->magick,magick_info->name,
4939 (void) CloseBlob(images);
4940 images=GetNextImageInList(images);
4944 clone_info=DestroyImageInfo(clone_info);
4945 blob=(unsigned char *) RelinquishMagickMemory(blob);
4946 (void) RelinquishUniqueFileResource(unique);
4948 blob_info=DestroyImageInfo(blob_info);
4953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4957 + W r i t e B l o b %
4961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4963 % WriteBlob() writes data to a blob or image file. It returns the number of
4966 % The format of the WriteBlob method is:
4968 % ssize_t WriteBlob(Image *image,const size_t length,const void *data)
4970 % A description of each parameter follows:
4972 % o image: the image.
4974 % o length: Specifies an integer representing the number of bytes to
4975 % write to the file.
4977 % o data: The address of the data to write to the blob or file.
4980 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4986 register const unsigned char
4992 assert(image != (Image *) NULL);
4993 assert(image->signature == MagickCoreSignature);
4994 assert(data != (const void *) NULL);
4995 assert(image->blob != (BlobInfo *) NULL);
4996 assert(image->blob->type != UndefinedStream);
5000 p=(const unsigned char *) data;
5001 switch (image->blob->type)
5003 case UndefinedStream:
5005 case StandardStream:
5013 count=(ssize_t) fwrite((const char *) data,1,length,
5014 image->blob->file_info.file);
5019 c=putc((int) *p++,image->blob->file_info.file);
5026 c=putc((int) *p++,image->blob->file_info.file);
5033 c=putc((int) *p++,image->blob->file_info.file);
5040 c=putc((int) *p++,image->blob->file_info.file);
5052 #if defined(MAGICKCORE_ZLIB_DELEGATE)
5057 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
5058 (unsigned int) length);
5063 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5070 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5077 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5084 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5097 #if defined(MAGICKCORE_BZLIB_DELEGATE)
5098 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
5105 count=(ssize_t) image->blob->stream(image,data,length);
5110 register unsigned char
5113 if ((image->blob->offset+(MagickOffsetType) length) >=
5114 (MagickOffsetType) image->blob->extent)
5116 if (image->blob->mapped != MagickFalse)
5118 image->blob->extent+=length+image->blob->quantum;
5119 image->blob->quantum<<=1;
5120 image->blob->data=(unsigned char *) ResizeQuantumMemory(
5121 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
5122 (void) SyncBlob(image);
5123 if (image->blob->data == (unsigned char *) NULL)
5125 (void) DetachBlob(image->blob);
5129 q=image->blob->data+image->blob->offset;
5130 (void) memcpy(q,p,length);
5131 image->blob->offset+=length;
5132 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
5133 image->blob->length=(size_t) image->blob->offset;
5134 count=(ssize_t) length;
5139 count=image->blob->custom_stream->writer((const unsigned char *) data,
5140 length,image->blob->custom_stream->data);
5148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5152 + W r i t e B l o b B y t e %
5156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5158 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
5159 % written (either 0 or 1);
5161 % The format of the WriteBlobByte method is:
5163 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
5165 % A description of each parameter follows.
5167 % o image: the image.
5169 % o value: Specifies the value to write.
5172 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
5174 assert(image != (Image *) NULL);
5175 assert(image->signature == MagickCoreSignature);
5176 return(WriteBlobStream(image,1,&value));
5180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5184 + W r i t e B l o b F l o a t %
5188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5190 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
5191 % specified by the endian member of the image structure.
5193 % The format of the WriteBlobFloat method is:
5195 % ssize_t WriteBlobFloat(Image *image,const float value)
5197 % A description of each parameter follows.
5199 % o image: the image.
5201 % o value: Specifies the value to write.
5204 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
5215 quantum.unsigned_value=0U;
5216 quantum.float_value=value;
5217 return(WriteBlobLong(image,quantum.unsigned_value));
5221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5225 + W r i t e B l o b L o n g %
5229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5231 % WriteBlobLong() writes a unsigned int value as a 32-bit quantity in the
5232 % byte-order specified by the endian member of the image structure.
5234 % The format of the WriteBlobLong method is:
5236 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
5238 % A description of each parameter follows.
5240 % o image: the image.
5242 % o value: Specifies the value to write.
5245 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
5250 assert(image != (Image *) NULL);
5251 assert(image->signature == MagickCoreSignature);
5252 if (image->endian == LSBEndian)
5254 buffer[0]=(unsigned char) value;
5255 buffer[1]=(unsigned char) (value >> 8);
5256 buffer[2]=(unsigned char) (value >> 16);
5257 buffer[3]=(unsigned char) (value >> 24);
5258 return(WriteBlobStream(image,4,buffer));
5260 buffer[0]=(unsigned char) (value >> 24);
5261 buffer[1]=(unsigned char) (value >> 16);
5262 buffer[2]=(unsigned char) (value >> 8);
5263 buffer[3]=(unsigned char) value;
5264 return(WriteBlobStream(image,4,buffer));
5268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5272 + W r i t e B l o b S h o r t %
5276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5278 % WriteBlobShort() writes a short value as a 16-bit quantity in the
5279 % byte-order specified by the endian member of the image structure.
5281 % The format of the WriteBlobShort method is:
5283 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
5285 % A description of each parameter follows.
5287 % o image: the image.
5289 % o value: Specifies the value to write.
5292 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
5297 assert(image != (Image *) NULL);
5298 assert(image->signature == MagickCoreSignature);
5299 if (image->endian == LSBEndian)
5301 buffer[0]=(unsigned char) value;
5302 buffer[1]=(unsigned char) (value >> 8);
5303 return(WriteBlobStream(image,2,buffer));
5305 buffer[0]=(unsigned char) (value >> 8);
5306 buffer[1]=(unsigned char) value;
5307 return(WriteBlobStream(image,2,buffer));
5311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5315 + W r i t e B l o b L S B L o n g %
5319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5321 % WriteBlobLSBLong() writes a unsigned int value as a 32-bit quantity in
5322 % least-significant byte first order.
5324 % The format of the WriteBlobLSBLong method is:
5326 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5328 % A description of each parameter follows.
5330 % o image: the image.
5332 % o value: Specifies the value to write.
5335 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5340 assert(image != (Image *) NULL);
5341 assert(image->signature == MagickCoreSignature);
5342 buffer[0]=(unsigned char) value;
5343 buffer[1]=(unsigned char) (value >> 8);
5344 buffer[2]=(unsigned char) (value >> 16);
5345 buffer[3]=(unsigned char) (value >> 24);
5346 return(WriteBlobStream(image,4,buffer));
5350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5354 + W r i t e B l o b L S B S h o r t %
5358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5360 % WriteBlobLSBShort() writes a unsigned short value as a 16-bit quantity in
5361 % least-significant byte first order.
5363 % The format of the WriteBlobLSBShort method is:
5365 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5367 % A description of each parameter follows.
5369 % o image: the image.
5371 % o value: Specifies the value to write.
5374 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5379 assert(image != (Image *) NULL);
5380 assert(image->signature == MagickCoreSignature);
5381 buffer[0]=(unsigned char) value;
5382 buffer[1]=(unsigned char) (value >> 8);
5383 return(WriteBlobStream(image,2,buffer));
5387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5391 + W r i t e B l o b L S B S i g n e d L o n g %
5395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5397 % WriteBlobLSBSignedLong() writes a signed value as a 32-bit quantity in
5398 % least-significant byte first order.
5400 % The format of the WriteBlobLSBSignedLong method is:
5402 % ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5404 % A description of each parameter follows.
5406 % o image: the image.
5408 % o value: Specifies the value to write.
5411 MagickExport ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5425 assert(image != (Image *) NULL);
5426 assert(image->signature == MagickCoreSignature);
5427 quantum.signed_value=value;
5428 buffer[0]=(unsigned char) quantum.unsigned_value;
5429 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5430 buffer[2]=(unsigned char) (quantum.unsigned_value >> 16);
5431 buffer[3]=(unsigned char) (quantum.unsigned_value >> 24);
5432 return(WriteBlobStream(image,4,buffer));
5436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5440 + W r i t e B l o b L S B S i g n e d S h o r t %
5444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5446 % WriteBlobLSBSignedShort() writes a signed short value as a 16-bit quantity
5447 % in least-significant byte first order.
5449 % The format of the WriteBlobLSBSignedShort method is:
5451 % ssize_t WriteBlobLSBSignedShort(Image *image,const signed short value)
5453 % A description of each parameter follows.
5455 % o image: the image.
5457 % o value: Specifies the value to write.
5460 MagickExport ssize_t WriteBlobLSBSignedShort(Image *image,
5461 const signed short value)
5475 assert(image != (Image *) NULL);
5476 assert(image->signature == MagickCoreSignature);
5477 quantum.signed_value=value;
5478 buffer[0]=(unsigned char) quantum.unsigned_value;
5479 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5480 return(WriteBlobStream(image,2,buffer));
5484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5488 + W r i t e B l o b M S B L o n g %
5492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5494 % WriteBlobMSBLong() writes a unsigned int value as a 32-bit quantity in
5495 % most-significant byte first order.
5497 % The format of the WriteBlobMSBLong method is:
5499 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5501 % A description of each parameter follows.
5503 % o value: Specifies the value to write.
5505 % o image: the image.
5508 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5513 assert(image != (Image *) NULL);
5514 assert(image->signature == MagickCoreSignature);
5515 buffer[0]=(unsigned char) (value >> 24);
5516 buffer[1]=(unsigned char) (value >> 16);
5517 buffer[2]=(unsigned char) (value >> 8);
5518 buffer[3]=(unsigned char) value;
5519 return(WriteBlobStream(image,4,buffer));
5523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5527 + W r i t e B l o b M S B L o n g L o n g %
5531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5533 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
5534 % most-significant byte first order.
5536 % The format of the WriteBlobMSBLongLong method is:
5538 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
5540 % A description of each parameter follows.
5542 % o value: Specifies the value to write.
5544 % o image: the image.
5547 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
5548 const MagickSizeType value)
5553 assert(image != (Image *) NULL);
5554 assert(image->signature == MagickCoreSignature);
5555 buffer[0]=(unsigned char) (value >> 56);
5556 buffer[1]=(unsigned char) (value >> 48);
5557 buffer[2]=(unsigned char) (value >> 40);
5558 buffer[3]=(unsigned char) (value >> 32);
5559 buffer[4]=(unsigned char) (value >> 24);
5560 buffer[5]=(unsigned char) (value >> 16);
5561 buffer[6]=(unsigned char) (value >> 8);
5562 buffer[7]=(unsigned char) value;
5563 return(WriteBlobStream(image,8,buffer));
5567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5571 + W r i t e B l o b M S B S i g n e d L o n g %
5575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5577 % WriteBlobMSBSignedLong() writes a signed value as a 32-bit quantity in
5578 % most-significant byte first order.
5580 % The format of the WriteBlobMSBSignedLong method is:
5582 % ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5584 % A description of each parameter follows.
5586 % o image: the image.
5588 % o value: Specifies the value to write.
5591 MagickExport ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5605 assert(image != (Image *) NULL);
5606 assert(image->signature == MagickCoreSignature);
5607 quantum.signed_value=value;
5608 buffer[0]=(unsigned char) (quantum.unsigned_value >> 24);
5609 buffer[1]=(unsigned char) (quantum.unsigned_value >> 16);
5610 buffer[2]=(unsigned char) (quantum.unsigned_value >> 8);
5611 buffer[3]=(unsigned char) quantum.unsigned_value;
5612 return(WriteBlobStream(image,4,buffer));
5616 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5620 + W r i t e B l o b M S B S i g n e d S h o r t %
5624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5626 % WriteBlobMSBSignedShort() writes a signed short value as a 16-bit quantity
5627 % in most-significant byte first order.
5629 % The format of the WriteBlobMSBSignedShort method is:
5631 % ssize_t WriteBlobMSBSignedShort(Image *image,const signed short value)
5633 % A description of each parameter follows.
5635 % o image: the image.
5637 % o value: Specifies the value to write.
5640 MagickExport ssize_t WriteBlobMSBSignedShort(Image *image,
5641 const signed short value)
5655 assert(image != (Image *) NULL);
5656 assert(image->signature == MagickCoreSignature);
5657 quantum.signed_value=value;
5658 buffer[0]=(unsigned char) (quantum.unsigned_value >> 8);
5659 buffer[1]=(unsigned char) quantum.unsigned_value;
5660 return(WriteBlobStream(image,2,buffer));
5664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5668 + W r i t e B l o b M S B S h o r t %
5672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5674 % WriteBlobMSBShort() writes a unsigned short value as a 16-bit quantity in
5675 % most-significant byte first order.
5677 % The format of the WriteBlobMSBShort method is:
5679 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5681 % A description of each parameter follows.
5683 % o value: Specifies the value to write.
5685 % o file: Specifies the file to write the data to.
5688 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5693 assert(image != (Image *) NULL);
5694 assert(image->signature == MagickCoreSignature);
5695 buffer[0]=(unsigned char) (value >> 8);
5696 buffer[1]=(unsigned char) value;
5697 return(WriteBlobStream(image,2,buffer));
5701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5705 + W r i t e B l o b S t r i n g %
5709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5711 % WriteBlobString() write a string to a blob. It returns the number of
5712 % characters written.
5714 % The format of the WriteBlobString method is:
5716 % ssize_t WriteBlobString(Image *image,const char *string)
5718 % A description of each parameter follows.
5720 % o image: the image.
5722 % o string: Specifies the string to write.
5725 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
5727 assert(image != (Image *) NULL);
5728 assert(image->signature == MagickCoreSignature);
5729 assert(string != (const char *) NULL);
5730 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));