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 % https://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
97 typedef union FileInfo
102 #if defined(MAGICKCORE_ZLIB_DELEGATE)
107 #if defined(MAGICKCORE_BZLIB_DELEGATE)
167 struct _CustomStreamInfo
187 Forward declarations.
193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 + A c q u i r e C u s t o m S t r e a m I n f o %
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 % AcquireCustomStreamInfo() allocates the CustomStreamInfo structure.
205 % The format of the AcquireCustomStreamInfo method is:
207 % CustomStreamInfo *AcquireCustomStreamInfo(ExceptionInfo *exception)
209 % A description of each parameter follows:
211 % o exception: return any errors or warnings in this structure.
214 MagickExport CustomStreamInfo *AcquireCustomStreamInfo(
215 ExceptionInfo *exception)
220 custom_stream=(CustomStreamInfo *) AcquireMagickMemory(
221 sizeof(*custom_stream));
222 if (custom_stream == (CustomStreamInfo *) NULL)
223 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
224 (void) ResetMagickMemory(custom_stream,0,sizeof(*custom_stream));
225 custom_stream->signature=MagickCoreSignature;
226 return(custom_stream);
230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234 + A t t a c h B l o b %
238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240 % AttachBlob() attaches a blob to the BlobInfo structure.
242 % The format of the AttachBlob method is:
244 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
246 % A description of each parameter follows:
248 % o blob_info: Specifies a pointer to a BlobInfo structure.
250 % o blob: the address of a character stream in one of the image formats
251 % understood by ImageMagick.
253 % o length: This size_t integer reflects the length in bytes of the blob.
256 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
259 assert(blob_info != (BlobInfo *) NULL);
260 if (blob_info->debug != MagickFalse)
261 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
262 blob_info->length=length;
263 blob_info->extent=length;
264 blob_info->quantum=(size_t) MagickMaxBlobExtent;
266 blob_info->type=BlobStream;
267 blob_info->file_info.file=(FILE *) NULL;
268 blob_info->data=(unsigned char *) blob;
269 blob_info->mapped=MagickFalse;
273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277 + B l o b T o F i l e %
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
284 % occurs otherwise MagickTrue.
286 % The format of the BlobToFile method is:
288 % MagickBooleanType BlobToFile(char *filename,const void *blob,
289 % const size_t length,ExceptionInfo *exception)
291 % A description of each parameter follows:
293 % o filename: Write the blob to this file.
295 % o blob: the address of a blob.
297 % o length: This length in bytes of the blob.
299 % o exception: return any errors or warnings in this structure.
302 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
303 const size_t length,ExceptionInfo *exception)
314 assert(filename != (const char *) NULL);
315 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
316 assert(blob != (const void *) NULL);
317 if (*filename == '\0')
318 file=AcquireUniqueFileResource(filename);
320 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
323 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
326 for (i=0; i < length; i+=count)
328 count=write(file,(const char *) blob+i,MagickMin(length-i,SSIZE_MAX));
337 if ((file == -1) || (i < length))
339 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350 % B l o b T o I m a g e %
354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
356 % BlobToImage() implements direct to memory image formats. It returns the
359 % The format of the BlobToImage method is:
361 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
362 % const size_t length,ExceptionInfo *exception)
364 % A description of each parameter follows:
366 % o image_info: the image info.
368 % o blob: the address of a character stream in one of the image formats
369 % understood by ImageMagick.
371 % o length: This size_t integer reflects the length in bytes of the blob.
373 % o exception: return any errors or warnings in this structure.
376 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
377 const size_t length,ExceptionInfo *exception)
392 assert(image_info != (ImageInfo *) NULL);
393 assert(image_info->signature == MagickCoreSignature);
394 if (image_info->debug != MagickFalse)
395 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
396 image_info->filename);
397 assert(exception != (ExceptionInfo *) NULL);
398 if ((blob == (const void *) NULL) || (length == 0))
400 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
401 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
402 return((Image *) NULL);
404 blob_info=CloneImageInfo(image_info);
405 blob_info->blob=(void *) blob;
406 blob_info->length=length;
407 if (*blob_info->magick == '\0')
408 (void) SetImageInfo(blob_info,0,exception);
409 magick_info=GetMagickInfo(blob_info->magick,exception);
410 if (magick_info == (const MagickInfo *) NULL)
412 (void) ThrowMagickException(exception,GetMagickModule(),
413 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
415 blob_info=DestroyImageInfo(blob_info);
416 return((Image *) NULL);
418 if (GetMagickBlobSupport(magick_info) != MagickFalse)
421 Native blob support for this image format.
423 (void) CopyMagickString(blob_info->filename,image_info->filename,
425 (void) CopyMagickString(blob_info->magick,image_info->magick,
427 image=ReadImage(blob_info,exception);
428 if (image != (Image *) NULL)
429 (void) DetachBlob(image->blob);
430 blob_info=DestroyImageInfo(blob_info);
434 Write blob to a temporary file on disk.
436 blob_info->blob=(void *) NULL;
438 *blob_info->filename='\0';
439 status=BlobToFile(blob_info->filename,blob,length,exception);
440 if (status == MagickFalse)
442 (void) RelinquishUniqueFileResource(blob_info->filename);
443 blob_info=DestroyImageInfo(blob_info);
444 return((Image *) NULL);
446 clone_info=CloneImageInfo(blob_info);
447 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,"%s:%s",
448 blob_info->magick,blob_info->filename);
449 image=ReadImage(clone_info,exception);
450 if (image != (Image *) NULL)
456 Restore original filenames and image format.
458 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
460 (void) CopyMagickString(images->filename,image_info->filename,
462 (void) CopyMagickString(images->magick_filename,image_info->filename,
464 (void) CopyMagickString(images->magick,magick_info->name,
466 images=GetNextImageInList(images);
469 clone_info=DestroyImageInfo(clone_info);
470 (void) RelinquishUniqueFileResource(blob_info->filename);
471 blob_info=DestroyImageInfo(blob_info);
476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480 + C l o n e B l o b I n f o %
484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
486 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
487 % blob info is NULL, a new one.
489 % The format of the CloneBlobInfo method is:
491 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
493 % A description of each parameter follows:
495 % o blob_info: the blob info.
498 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
503 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
504 if (clone_info == (BlobInfo *) NULL)
505 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
506 GetBlobInfo(clone_info);
507 if (blob_info == (BlobInfo *) NULL)
509 clone_info->length=blob_info->length;
510 clone_info->extent=blob_info->extent;
511 clone_info->synchronize=blob_info->synchronize;
512 clone_info->quantum=blob_info->quantum;
513 clone_info->mapped=blob_info->mapped;
514 clone_info->eof=blob_info->eof;
515 clone_info->offset=blob_info->offset;
516 clone_info->size=blob_info->size;
517 clone_info->exempt=blob_info->exempt;
518 clone_info->status=blob_info->status;
519 clone_info->temporary=blob_info->temporary;
520 clone_info->type=blob_info->type;
521 clone_info->file_info.file=blob_info->file_info.file;
522 clone_info->properties=blob_info->properties;
523 clone_info->stream=blob_info->stream;
524 clone_info->custom_stream=blob_info->custom_stream;
525 clone_info->data=blob_info->data;
526 clone_info->debug=IsEventLogging();
527 clone_info->reference_count=1;
532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
536 + C l o s e B l o b %
540 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
542 % CloseBlob() closes a stream associated with the image.
544 % The format of the CloseBlob method is:
546 % MagickBooleanType CloseBlob(Image *image)
548 % A description of each parameter follows:
550 % o image: the image.
553 MagickExport MagickBooleanType CloseBlob(Image *image)
561 assert(image != (Image *) NULL);
562 assert(image->signature == MagickCoreSignature);
563 if (image->debug != MagickFalse)
564 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
565 assert(image->blob != (BlobInfo *) NULL);
566 if (image->blob->type == UndefinedStream)
568 status=SyncBlob(image);
569 switch (image->blob->type)
571 case UndefinedStream:
577 if (image->blob->synchronize != MagickFalse)
578 status=fsync(fileno(image->blob->file_info.file));
579 status=ferror(image->blob->file_info.file);
584 #if defined(MAGICKCORE_ZLIB_DELEGATE)
585 (void) gzerror(image->blob->file_info.gzfile,&status);
591 #if defined(MAGICKCORE_BZLIB_DELEGATE)
592 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
600 if ((image->blob->file_info.file != (FILE *) NULL) &&
601 (image->blob->synchronize != MagickFalse))
603 (void) fsync(fileno(image->blob->file_info.file));
604 status=ferror(image->blob->file_info.file);
611 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
612 image->blob->size=GetBlobSize(image);
613 image->extent=image->blob->size;
614 image->blob->eof=MagickFalse;
615 if (image->blob->exempt != MagickFalse)
617 image->blob->type=UndefinedStream;
618 return(image->blob->status);
620 switch (image->blob->type)
622 case UndefinedStream:
627 status=fclose(image->blob->file_info.file);
632 #if defined(MAGICKCORE_HAVE_PCLOSE)
633 status=pclose(image->blob->file_info.file);
639 #if defined(MAGICKCORE_ZLIB_DELEGATE)
640 status=gzclose(image->blob->file_info.gzfile);
646 #if defined(MAGICKCORE_BZLIB_DELEGATE)
647 BZ2_bzclose(image->blob->file_info.bzfile);
655 if (image->blob->file_info.file != (FILE *) NULL)
656 status=fclose(image->blob->file_info.file);
662 (void) DetachBlob(image->blob);
663 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
664 return(image->blob->status);
668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 + D e s t r o y B l o b %
676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
678 % DestroyBlob() deallocates memory associated with a blob.
680 % The format of the DestroyBlob method is:
682 % void DestroyBlob(Image *image)
684 % A description of each parameter follows:
686 % o image: the image.
689 MagickExport void DestroyBlob(Image *image)
694 assert(image != (Image *) NULL);
695 assert(image->signature == MagickCoreSignature);
696 if (image->debug != MagickFalse)
697 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
698 assert(image->blob != (BlobInfo *) NULL);
699 assert(image->blob->signature == MagickCoreSignature);
701 LockSemaphoreInfo(image->blob->semaphore);
702 image->blob->reference_count--;
703 assert(image->blob->reference_count >= 0);
704 if (image->blob->reference_count == 0)
706 UnlockSemaphoreInfo(image->blob->semaphore);
707 if (destroy == MagickFalse)
709 (void) CloseBlob(image);
710 if (image->blob->mapped != MagickFalse)
712 (void) UnmapBlob(image->blob->data,image->blob->length);
713 RelinquishMagickResource(MapResource,image->blob->length);
715 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
716 RelinquishSemaphoreInfo(&image->blob->semaphore);
717 image->blob->signature=(~MagickCoreSignature);
718 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
726 + D e s t r o y C u s t o m S t r e a m I n f o %
730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
732 % DestroyCustomStreamInfo() destroys memory associated with the
733 % CustomStreamInfo structure.
735 % The format of the DestroyCustomStreamInfo method is:
737 % CustomStreamInfo *DestroyCustomStreamInfo(CustomStreamInfo *stream_info)
739 % A description of each parameter follows:
741 % o custom_stream: the custom stream info.
744 MagickExport CustomStreamInfo *DestroyCustomStreamInfo(
745 CustomStreamInfo *custom_stream)
747 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
748 assert(custom_stream != (CustomStreamInfo *) NULL);
749 assert(custom_stream->signature == MagickCoreSignature);
750 custom_stream->signature=(~MagickCoreSignature);
751 custom_stream=(CustomStreamInfo *) RelinquishMagickMemory(custom_stream);
752 return(custom_stream);
756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
760 + D e t a c h B l o b %
764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 % DetachBlob() detaches a blob from the BlobInfo structure.
768 % The format of the DetachBlob method is:
770 % void *DetachBlob(BlobInfo *blob_info)
772 % A description of each parameter follows:
774 % o blob_info: Specifies a pointer to a BlobInfo structure.
777 MagickExport void *DetachBlob(BlobInfo *blob_info)
782 assert(blob_info != (BlobInfo *) NULL);
783 if (blob_info->debug != MagickFalse)
784 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
785 if (blob_info->mapped != MagickFalse)
787 (void) UnmapBlob(blob_info->data,blob_info->length);
788 blob_info->data=(unsigned char *) NULL;
789 RelinquishMagickResource(MapResource,blob_info->length);
791 blob_info->mapped=MagickFalse;
794 blob_info->eof=MagickFalse;
795 blob_info->exempt=MagickFalse;
796 blob_info->type=UndefinedStream;
797 blob_info->file_info.file=(FILE *) NULL;
798 data=blob_info->data;
799 blob_info->data=(unsigned char *) NULL;
800 blob_info->stream=(StreamHandler) NULL;
801 blob_info->custom_stream=(CustomStreamInfo *) NULL;
806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
810 + D i s a s s o c i a t e B l o b %
814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816 % DisassociateBlob() disassociates the image stream. It checks if the
817 % blob of the specified image is referenced by other images. If the reference
818 % count is higher then 1 a new blob is assigned to the specified image.
820 % The format of the DisassociateBlob method is:
822 % void DisassociateBlob(const Image *image)
824 % A description of each parameter follows:
826 % o image: the image.
829 MagickExport void DisassociateBlob(Image *image)
837 assert(image != (Image *) NULL);
838 assert(image->signature == MagickCoreSignature);
839 if (image->debug != MagickFalse)
840 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
841 assert(image->blob != (BlobInfo *) NULL);
842 assert(image->blob->signature == MagickCoreSignature);
844 LockSemaphoreInfo(image->blob->semaphore);
845 assert(image->blob->reference_count >= 0);
846 if (image->blob->reference_count > 1)
848 UnlockSemaphoreInfo(image->blob->semaphore);
849 if (clone == MagickFalse)
851 blob=CloneBlobInfo(image->blob);
857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861 + D i s c a r d B l o b B y t e s %
865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
867 % DiscardBlobBytes() discards bytes in a blob.
869 % The format of the DiscardBlobBytes method is:
871 % MagickBooleanType DiscardBlobBytes(Image *image,
872 % const MagickSizeType length)
874 % A description of each parameter follows.
876 % o image: the image.
878 % o length: the number of bytes to skip.
881 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
882 const MagickSizeType length)
884 register MagickOffsetType
896 assert(image != (Image *) NULL);
897 assert(image->signature == MagickCoreSignature);
898 if (length != (MagickSizeType) ((MagickOffsetType) length))
901 for (i=0; i < (MagickOffsetType) length; i+=count)
903 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
904 (void) ReadBlobStream(image,quantum,buffer,&count);
912 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
920 + D u p l i c a t e s B l o b %
924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926 % DuplicateBlob() duplicates a blob descriptor.
928 % The format of the DuplicateBlob method is:
930 % void DuplicateBlob(Image *image,const Image *duplicate)
932 % A description of each parameter follows:
934 % o image: the image.
936 % o duplicate: the duplicate image.
939 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
941 assert(image != (Image *) NULL);
942 assert(image->signature == MagickCoreSignature);
943 if (image->debug != MagickFalse)
944 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
945 assert(duplicate != (Image *) NULL);
946 assert(duplicate->signature == MagickCoreSignature);
948 image->blob=ReferenceBlob(duplicate->blob);
952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 % EOFBlob() returns a non-zero value when EOF has been detected reading from
965 % The format of the EOFBlob method is:
967 % int EOFBlob(const Image *image)
969 % A description of each parameter follows:
971 % o image: the image.
974 MagickExport int EOFBlob(const Image *image)
976 assert(image != (Image *) NULL);
977 assert(image->signature == MagickCoreSignature);
978 if (image->debug != MagickFalse)
979 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
980 assert(image->blob != (BlobInfo *) NULL);
981 assert(image->blob->type != UndefinedStream);
982 switch (image->blob->type)
984 case UndefinedStream:
990 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
996 image->blob->eof=MagickFalse;
1001 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1006 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
1007 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
1013 image->blob->eof=MagickFalse;
1021 return((int) image->blob->eof);
1025 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1029 % F i l e T o B l o b %
1033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035 % FileToBlob() returns the contents of a file as a buffer terminated with
1036 % the '\0' character. The length of the buffer (not including the extra
1037 % terminating '\0' character) is returned via the 'length' parameter. Free
1038 % the buffer with RelinquishMagickMemory().
1040 % The format of the FileToBlob method is:
1042 % void *FileToBlob(const char *filename,const size_t extent,
1043 % size_t *length,ExceptionInfo *exception)
1045 % A description of each parameter follows:
1047 % o blob: FileToBlob() returns the contents of a file as a blob. If
1048 % an error occurs NULL is returned.
1050 % o filename: the filename.
1052 % o extent: The maximum length of the blob.
1054 % o length: On return, this reflects the actual length of the blob.
1056 % o exception: return any errors or warnings in this structure.
1059 MagickExport void *FileToBlob(const char *filename,const size_t extent,
1060 size_t *length,ExceptionInfo *exception)
1080 assert(filename != (const char *) NULL);
1081 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1082 assert(exception != (ExceptionInfo *) NULL);
1085 if (LocaleCompare(filename,"-") != 0)
1086 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1089 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
1092 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
1094 if ((file == fileno(stdin)) || (offset < 0) ||
1095 (offset != (MagickOffsetType) ((ssize_t) offset)))
1104 Stream is not seekable.
1106 offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
1107 quantum=(size_t) MagickMaxBufferExtent;
1108 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1109 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1110 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1111 for (i=0; blob != (unsigned char *) NULL; i+=count)
1113 count=read(file,blob+i,quantum);
1120 if (~((size_t) i) < (quantum+1))
1122 blob=(unsigned char *) RelinquishMagickMemory(blob);
1125 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
1127 if ((size_t) (i+count) >= extent)
1130 if (LocaleCompare(filename,"-") != 0)
1132 if (blob == (unsigned char *) NULL)
1134 (void) ThrowMagickException(exception,GetMagickModule(),
1135 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1140 blob=(unsigned char *) RelinquishMagickMemory(blob);
1141 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1144 *length=(size_t) MagickMin(i+count,extent);
1148 *length=(size_t) MagickMin(offset,(MagickOffsetType)
1149 MagickMin(extent,SSIZE_MAX));
1150 blob=(unsigned char *) NULL;
1151 if (~(*length) >= (MagickPathExtent-1))
1152 blob=(unsigned char *) AcquireQuantumMemory(*length+MagickPathExtent,
1154 if (blob == (unsigned char *) NULL)
1157 (void) ThrowMagickException(exception,GetMagickModule(),
1158 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1161 map=MapBlob(file,ReadMode,0,*length);
1162 if (map != (unsigned char *) NULL)
1164 (void) memcpy(blob,map,*length);
1165 (void) UnmapBlob(map,*length);
1169 (void) lseek(file,0,SEEK_SET);
1170 for (i=0; i < *length; i+=count)
1172 count=read(file,blob+i,(size_t) MagickMin(*length-i,SSIZE_MAX));
1183 blob=(unsigned char *) RelinquishMagickMemory(blob);
1184 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1189 if (LocaleCompare(filename,"-") != 0)
1193 blob=(unsigned char *) RelinquishMagickMemory(blob);
1194 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1204 % F i l e T o I m a g e %
1208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1210 % FileToImage() write the contents of a file to an image.
1212 % The format of the FileToImage method is:
1214 % MagickBooleanType FileToImage(Image *,const char *filename)
1216 % A description of each parameter follows:
1218 % o image: the image.
1220 % o filename: the filename.
1224 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1230 register unsigned char
1233 assert(image->blob != (BlobInfo *) NULL);
1234 assert(image->blob->type != UndefinedStream);
1235 assert(data != NULL);
1236 if (image->blob->type != BlobStream)
1237 return(WriteBlob(image,length,(const unsigned char *) data));
1238 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1239 if (extent >= image->blob->extent)
1241 extent=image->blob->extent+image->blob->quantum+length;
1242 image->blob->quantum<<=1;
1243 if (SetBlobExtent(image,extent) == MagickFalse)
1246 q=image->blob->data+image->blob->offset;
1247 (void) memcpy(q,data,length);
1248 image->blob->offset+=length;
1249 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1250 image->blob->length=(size_t) image->blob->offset;
1251 return((ssize_t) length);
1254 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1255 ExceptionInfo *exception)
1273 assert(image != (const Image *) NULL);
1274 assert(image->signature == MagickCoreSignature);
1275 assert(filename != (const char *) NULL);
1276 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1278 if (LocaleCompare(filename,"-") != 0)
1279 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1282 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1283 return(MagickFalse);
1285 quantum=(size_t) MagickMaxBufferExtent;
1286 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1287 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1288 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1289 if (blob == (unsigned char *) NULL)
1292 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1294 return(MagickFalse);
1298 count=read(file,blob,quantum);
1305 length=(size_t) count;
1306 count=WriteBlobStream(image,length,blob);
1307 if (count != (ssize_t) length)
1309 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1315 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1316 blob=(unsigned char *) RelinquishMagickMemory(blob);
1321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1325 + G e t B l o b E r r o r %
1329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1331 % GetBlobError() returns MagickTrue if the blob associated with the specified
1332 % image encountered an error.
1334 % The format of the GetBlobError method is:
1336 % MagickBooleanType GetBlobError(const Image *image)
1338 % A description of each parameter follows:
1340 % o image: the image.
1343 MagickExport MagickBooleanType GetBlobError(const Image *image)
1345 assert(image != (const Image *) NULL);
1346 assert(image->signature == MagickCoreSignature);
1347 if (image->debug != MagickFalse)
1348 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1349 return(image->blob->status);
1353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357 + G e t B l o b F i l e H a n d l e %
1361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1363 % GetBlobFileHandle() returns the file handle associated with the image blob.
1365 % The format of the GetBlobFile method is:
1367 % FILE *GetBlobFileHandle(const Image *image)
1369 % A description of each parameter follows:
1371 % o image: the image.
1374 MagickExport FILE *GetBlobFileHandle(const Image *image)
1376 assert(image != (const Image *) NULL);
1377 assert(image->signature == MagickCoreSignature);
1378 return(image->blob->file_info.file);
1382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1386 + G e t B l o b I n f o %
1390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1392 % GetBlobInfo() initializes the BlobInfo structure.
1394 % The format of the GetBlobInfo method is:
1396 % void GetBlobInfo(BlobInfo *blob_info)
1398 % A description of each parameter follows:
1400 % o blob_info: Specifies a pointer to a BlobInfo structure.
1403 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1405 assert(blob_info != (BlobInfo *) NULL);
1406 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1407 blob_info->type=UndefinedStream;
1408 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1409 blob_info->properties.st_mtime=time((time_t *) NULL);
1410 blob_info->properties.st_ctime=time((time_t *) NULL);
1411 blob_info->debug=IsEventLogging();
1412 blob_info->reference_count=1;
1413 blob_info->semaphore=AcquireSemaphoreInfo();
1414 blob_info->signature=MagickCoreSignature;
1418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1422 % G e t B l o b P r o p e r t i e s %
1426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 % GetBlobProperties() returns information about an image blob.
1430 % The format of the GetBlobProperties method is:
1432 % const struct stat *GetBlobProperties(const Image *image)
1434 % A description of each parameter follows:
1436 % o image: the image.
1439 MagickExport const struct stat *GetBlobProperties(const Image *image)
1441 assert(image != (Image *) NULL);
1442 assert(image->signature == MagickCoreSignature);
1443 if (image->debug != MagickFalse)
1444 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1445 return(&image->blob->properties);
1449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1453 + G e t B l o b S i z e %
1457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1459 % GetBlobSize() returns the current length of the image file or blob; zero is
1460 % returned if the size cannot be determined.
1462 % The format of the GetBlobSize method is:
1464 % MagickSizeType GetBlobSize(const Image *image)
1466 % A description of each parameter follows:
1468 % o image: the image.
1471 MagickExport MagickSizeType GetBlobSize(const Image *image)
1476 assert(image != (Image *) NULL);
1477 assert(image->signature == MagickCoreSignature);
1478 if (image->debug != MagickFalse)
1479 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1480 assert(image->blob != (BlobInfo *) NULL);
1482 switch (image->blob->type)
1484 case UndefinedStream:
1485 case StandardStream:
1487 extent=image->blob->size;
1492 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1493 extent=(MagickSizeType) image->blob->properties.st_size;
1498 extent=image->blob->size;
1507 status=GetPathAttributes(image->filename,&image->blob->properties);
1508 if (status != MagickFalse)
1509 extent=(MagickSizeType) image->blob->properties.st_size;
1516 extent=(MagickSizeType) image->blob->length;
1526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1530 + G e t B l o b S t r e a m D a t a %
1534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1536 % GetBlobStreamData() returns the stream data for the image.
1538 % The format of the GetBlobStreamData method is:
1540 % void *GetBlobStreamData(const Image *image)
1542 % A description of each parameter follows:
1544 % o image: the image.
1547 MagickExport void *GetBlobStreamData(const Image *image)
1549 assert(image != (const Image *) NULL);
1550 assert(image->signature == MagickCoreSignature);
1551 return(image->blob->data);
1555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1559 + G e t B l o b S t r e a m H a n d l e r %
1563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565 % GetBlobStreamHandler() returns the stream handler for the image.
1567 % The format of the GetBlobStreamHandler method is:
1569 % StreamHandler GetBlobStreamHandler(const Image *image)
1571 % A description of each parameter follows:
1573 % o image: the image.
1576 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1578 assert(image != (const Image *) NULL);
1579 assert(image->signature == MagickCoreSignature);
1580 if (image->debug != MagickFalse)
1581 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1582 return(image->blob->stream);
1586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1590 % I m a g e T o B l o b %
1594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596 % ImageToBlob() implements direct to memory image formats. It returns the
1597 % image as a formatted blob and its length. The magick member of the Image
1598 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1599 % etc.). This method is the equivalent of WriteImage(), but writes the
1600 % formatted "file" to a memory buffer rather than to an actual file.
1602 % The format of the ImageToBlob method is:
1604 % void *ImageToBlob(const ImageInfo *image_info,Image *image,
1605 % size_t *length,ExceptionInfo *exception)
1607 % A description of each parameter follows:
1609 % o image_info: the image info.
1611 % o image: the image.
1613 % o length: return the actual length of the blob.
1615 % o exception: return any errors or warnings in this structure.
1618 MagickExport void *ImageToBlob(const ImageInfo *image_info,
1619 Image *image,size_t *length,ExceptionInfo *exception)
1633 assert(image_info != (const ImageInfo *) NULL);
1634 assert(image_info->signature == MagickCoreSignature);
1635 if (image_info->debug != MagickFalse)
1636 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1637 image_info->filename);
1638 assert(image != (Image *) NULL);
1639 assert(image->signature == MagickCoreSignature);
1640 assert(exception != (ExceptionInfo *) NULL);
1642 blob=(unsigned char *) NULL;
1643 blob_info=CloneImageInfo(image_info);
1644 blob_info->adjoin=MagickFalse;
1645 (void) SetImageInfo(blob_info,1,exception);
1646 if (*blob_info->magick != '\0')
1647 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1648 magick_info=GetMagickInfo(image->magick,exception);
1649 if (magick_info == (const MagickInfo *) NULL)
1651 (void) ThrowMagickException(exception,GetMagickModule(),
1652 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1654 blob_info=DestroyImageInfo(blob_info);
1657 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1658 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1661 Native blob support for this image format.
1663 blob_info->length=0;
1664 blob_info->blob=AcquireQuantumMemory(MagickMaxBlobExtent,
1665 sizeof(unsigned char));
1666 if (blob_info->blob == NULL)
1667 (void) ThrowMagickException(exception,GetMagickModule(),
1668 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1671 (void) CloseBlob(image);
1672 image->blob->exempt=MagickTrue;
1673 *image->filename='\0';
1674 status=WriteImage(blob_info,image,exception);
1675 *length=image->blob->length;
1676 blob=DetachBlob(image->blob);
1677 if (status == MagickFalse)
1678 blob=RelinquishMagickMemory(blob);
1680 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1686 unique[MagickPathExtent];
1692 Write file to disk in blob image format.
1694 file=AcquireUniqueFileResource(unique);
1697 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1698 image_info->filename);
1702 blob_info->file=fdopen(file,"wb");
1703 if (blob_info->file != (FILE *) NULL)
1705 (void) FormatLocaleString(image->filename,MagickPathExtent,
1706 "%s:%s",image->magick,unique);
1707 status=WriteImage(blob_info,image,exception);
1708 (void) CloseBlob(image);
1709 (void) fclose(blob_info->file);
1710 if (status != MagickFalse)
1711 blob=FileToBlob(unique,~0UL,length,exception);
1713 (void) RelinquishUniqueFileResource(unique);
1716 blob_info=DestroyImageInfo(blob_info);
1721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1725 + I m a g e T o C u s t o m S t r e a m %
1729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1731 % ImageToCustomStream() is the equivalent of WriteImage(), but writes the
1732 % formatted "file" to the custom stream rather than to an actual file.
1734 % The format of the ImageToCustomStream method is:
1736 % void ImageToCustomStream(const ImageInfo *image_info,Image *image,
1737 % ExceptionInfo *exception)
1739 % A description of each parameter follows:
1741 % o image_info: the image info.
1743 % o image: the image.
1745 % o exception: return any errors or warnings in this structure.
1748 MagickExport void ImageToCustomStream(const ImageInfo *image_info,Image *image,
1749 ExceptionInfo *exception)
1760 assert(image_info != (const ImageInfo *) NULL);
1761 assert(image_info->signature == MagickCoreSignature);
1762 if (image_info->debug != MagickFalse)
1763 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1764 image_info->filename);
1765 assert(image != (Image *) NULL);
1766 assert(image->signature == MagickCoreSignature);
1767 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
1768 assert(image_info->custom_stream->signature == MagickCoreSignature);
1769 assert(image_info->custom_stream->writer != (CustomStreamHandler) NULL);
1770 assert(exception != (ExceptionInfo *) NULL);
1771 blob_info=CloneImageInfo(image_info);
1772 blob_info->adjoin=MagickFalse;
1773 (void) SetImageInfo(blob_info,1,exception);
1774 if (*blob_info->magick != '\0')
1775 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1776 magick_info=GetMagickInfo(image->magick,exception);
1777 if (magick_info == (const MagickInfo *) NULL)
1779 (void) ThrowMagickException(exception,GetMagickModule(),
1780 MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'",
1782 blob_info=DestroyImageInfo(blob_info);
1785 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1786 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1789 Native blob support for this image format.
1791 (void) CloseBlob(image);
1792 *image->filename='\0';
1793 (void) WriteImage(blob_info,image,exception);
1794 (void) CloseBlob(image);
1799 unique[MagickPathExtent];
1808 Write file to disk in blob image format.
1810 blob_info->custom_stream=(CustomStreamInfo *) NULL;
1811 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
1813 if (blob == (unsigned char *) NULL)
1815 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1816 image_info->filename);
1817 blob_info=DestroyImageInfo(blob_info);
1820 file=AcquireUniqueFileResource(unique);
1823 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1824 image_info->filename);
1825 blob=(unsigned char *) RelinquishMagickMemory(blob);
1826 blob_info=DestroyImageInfo(blob_info);
1829 blob_info->file=fdopen(file,"wb+");
1830 if (blob_info->file != (FILE *) NULL)
1835 (void) FormatLocaleString(image->filename,MagickPathExtent,
1836 "%s:%s",image->magick,unique);
1837 status=WriteImage(blob_info,image,exception);
1838 (void) CloseBlob(image);
1839 if (status != MagickFalse)
1841 (void) fseek(blob_info->file,0,SEEK_SET);
1842 count=(ssize_t) MagickMaxBufferExtent;
1843 while (count == (ssize_t) MagickMaxBufferExtent)
1845 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
1847 image_info->custom_stream->writer(blob,count,
1848 image_info->custom_stream->data);
1851 (void) fclose(blob_info->file);
1853 blob=(unsigned char *) RelinquishMagickMemory(blob);
1854 (void) RelinquishUniqueFileResource(unique);
1856 blob_info=DestroyImageInfo(blob_info);
1860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1864 % I m a g e T o F i l e %
1868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1870 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1871 % occurs otherwise MagickTrue.
1873 % The format of the ImageToFile method is:
1875 % MagickBooleanType ImageToFile(Image *image,char *filename,
1876 % ExceptionInfo *exception)
1878 % A description of each parameter follows:
1880 % o image: the image.
1882 % o filename: Write the image to this file.
1884 % o exception: return any errors or warnings in this structure.
1887 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1888 ExceptionInfo *exception)
1893 register const unsigned char
1912 assert(image != (Image *) NULL);
1913 assert(image->signature == MagickCoreSignature);
1914 assert(image->blob != (BlobInfo *) NULL);
1915 assert(image->blob->type != UndefinedStream);
1916 if (image->debug != MagickFalse)
1917 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1918 assert(filename != (const char *) NULL);
1919 if (*filename == '\0')
1920 file=AcquireUniqueFileResource(filename);
1922 if (LocaleCompare(filename,"-") == 0)
1923 file=fileno(stdout);
1925 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1928 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1929 return(MagickFalse);
1931 quantum=(size_t) MagickMaxBufferExtent;
1932 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1933 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1934 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1935 if (buffer == (unsigned char *) NULL)
1938 (void) ThrowMagickException(exception,GetMagickModule(),
1939 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1940 return(MagickFalse);
1943 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1944 for (i=0; count > 0; )
1946 length=(size_t) count;
1947 for (i=0; i < length; i+=count)
1949 count=write(file,p+i,(size_t) (length-i));
1959 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1961 if (LocaleCompare(filename,"-") != 0)
1963 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1964 if ((file == -1) || (i < length))
1968 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1969 return(MagickFalse);
1975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1979 % I m a g e s T o B l o b %
1983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1985 % ImagesToBlob() implements direct to memory image formats. It returns the
1986 % image sequence as a blob and its length. The magick member of the ImageInfo
1987 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1989 % Note, some image formats do not permit multiple images to the same image
1990 % stream (e.g. JPEG). in this instance, just the first image of the
1991 % sequence is returned as a blob.
1993 % The format of the ImagesToBlob method is:
1995 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1996 % size_t *length,ExceptionInfo *exception)
1998 % A description of each parameter follows:
2000 % o image_info: the image info.
2002 % o images: the image list.
2004 % o length: return the actual length of the blob.
2006 % o exception: return any errors or warnings in this structure.
2009 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
2010 size_t *length,ExceptionInfo *exception)
2024 assert(image_info != (const ImageInfo *) NULL);
2025 assert(image_info->signature == MagickCoreSignature);
2026 if (image_info->debug != MagickFalse)
2027 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2028 image_info->filename);
2029 assert(images != (Image *) NULL);
2030 assert(images->signature == MagickCoreSignature);
2031 assert(exception != (ExceptionInfo *) NULL);
2033 blob=(unsigned char *) NULL;
2034 blob_info=CloneImageInfo(image_info);
2035 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2037 if (*blob_info->magick != '\0')
2038 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2039 magick_info=GetMagickInfo(images->magick,exception);
2040 if (magick_info == (const MagickInfo *) NULL)
2042 (void) ThrowMagickException(exception,GetMagickModule(),
2043 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
2045 blob_info=DestroyImageInfo(blob_info);
2048 if (GetMagickAdjoin(magick_info) == MagickFalse)
2050 blob_info=DestroyImageInfo(blob_info);
2051 return(ImageToBlob(image_info,images,length,exception));
2053 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2054 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2057 Native blob support for this images format.
2059 blob_info->length=0;
2060 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
2061 sizeof(unsigned char));
2062 if (blob_info->blob == (void *) NULL)
2063 (void) ThrowMagickException(exception,GetMagickModule(),
2064 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
2067 (void) CloseBlob(images);
2068 images->blob->exempt=MagickTrue;
2069 *images->filename='\0';
2070 status=WriteImages(blob_info,images,images->filename,exception);
2071 *length=images->blob->length;
2072 blob=DetachBlob(images->blob);
2073 if (status == MagickFalse)
2074 blob=RelinquishMagickMemory(blob);
2076 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
2082 filename[MagickPathExtent],
2083 unique[MagickPathExtent];
2089 Write file to disk in blob images format.
2091 file=AcquireUniqueFileResource(unique);
2094 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
2095 image_info->filename);
2099 blob_info->file=fdopen(file,"wb");
2100 if (blob_info->file != (FILE *) NULL)
2102 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2103 images->magick,unique);
2104 status=WriteImages(blob_info,images,filename,exception);
2105 (void) CloseBlob(images);
2106 (void) fclose(blob_info->file);
2107 if (status != MagickFalse)
2108 blob=FileToBlob(unique,~0UL,length,exception);
2110 (void) RelinquishUniqueFileResource(unique);
2113 blob_info=DestroyImageInfo(blob_info);
2118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2122 + I m a g e s T o C u s t o m B l o b %
2126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2128 % ImagesToCustomStream() is the equivalent of WriteImages(), but writes the
2129 % formatted "file" to the custom stream rather than to an actual file.
2131 % The format of the ImageToCustomStream method is:
2133 % void ImagesToCustomStream(const ImageInfo *image_info,Image *images,
2134 % ExceptionInfo *exception)
2136 % A description of each parameter follows:
2138 % o image_info: the image info.
2140 % o images: the image list.
2142 % o exception: return any errors or warnings in this structure.
2145 MagickExport void ImagesToCustomStream(const ImageInfo *image_info,
2146 Image *images,ExceptionInfo *exception)
2157 assert(image_info != (const ImageInfo *) NULL);
2158 assert(image_info->signature == MagickCoreSignature);
2159 if (image_info->debug != MagickFalse)
2160 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2161 image_info->filename);
2162 assert(images != (Image *) NULL);
2163 assert(images->signature == MagickCoreSignature);
2164 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
2165 assert(image_info->custom_stream->signature == MagickCoreSignature);
2166 assert(image_info->custom_stream->reader != (CustomStreamHandler) NULL);
2167 assert(image_info->custom_stream->writer != (CustomStreamHandler) NULL);
2168 assert(exception != (ExceptionInfo *) NULL);
2169 blob_info=CloneImageInfo(image_info);
2170 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2172 if (*blob_info->magick != '\0')
2173 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2174 magick_info=GetMagickInfo(images->magick,exception);
2175 if (magick_info == (const MagickInfo *) NULL)
2177 (void) ThrowMagickException(exception,GetMagickModule(),
2178 MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'",
2180 blob_info=DestroyImageInfo(blob_info);
2183 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2184 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2187 Native blob support for this image format.
2189 (void) CloseBlob(images);
2190 *images->filename='\0';
2191 (void) WriteImages(blob_info,images,images->filename,exception);
2192 (void) CloseBlob(images);
2197 filename[MagickPathExtent],
2198 unique[MagickPathExtent];
2207 Write file to disk in blob image format.
2209 blob_info->custom_stream=(CustomStreamInfo *) NULL;
2210 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
2212 if (blob == (unsigned char *) NULL)
2214 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2215 image_info->filename);
2216 blob_info=DestroyImageInfo(blob_info);
2219 file=AcquireUniqueFileResource(unique);
2222 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2223 image_info->filename);
2224 blob=(unsigned char *) RelinquishMagickMemory(blob);
2225 blob_info=DestroyImageInfo(blob_info);
2228 blob_info->file=fdopen(file,"wb+");
2229 if (blob_info->file != (FILE *) NULL)
2234 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2235 images->magick,unique);
2236 status=WriteImages(blob_info,images,filename,exception);
2237 (void) CloseBlob(images);
2238 if (status != MagickFalse)
2240 (void) fseek(blob_info->file,0,SEEK_SET);
2241 count=(ssize_t) MagickMaxBufferExtent;
2242 while (count == (ssize_t) MagickMaxBufferExtent)
2244 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
2246 image_info->custom_stream->writer(blob,count,
2247 image_info->custom_stream->data);
2250 (void) fclose(blob_info->file);
2252 blob=(unsigned char *) RelinquishMagickMemory(blob);
2253 (void) RelinquishUniqueFileResource(unique);
2255 blob_info=DestroyImageInfo(blob_info);
2260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2264 % I n j e c t I m a g e B l o b %
2268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2270 % InjectImageBlob() injects the image with a copy of itself in the specified
2271 % format (e.g. inject JPEG into a PDF image).
2273 % The format of the InjectImageBlob method is:
2275 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2276 % Image *image,Image *inject_image,const char *format,
2277 % ExceptionInfo *exception)
2279 % A description of each parameter follows:
2281 % o image_info: the image info..
2283 % o image: the image.
2285 % o inject_image: inject into the image stream.
2287 % o format: the image format.
2289 % o exception: return any errors or warnings in this structure.
2292 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2293 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
2296 filename[MagickPathExtent];
2329 Write inject image to a temporary file.
2331 assert(image_info != (ImageInfo *) NULL);
2332 assert(image_info->signature == MagickCoreSignature);
2333 assert(image != (Image *) NULL);
2334 assert(image->signature == MagickCoreSignature);
2335 if (image->debug != MagickFalse)
2336 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2337 assert(inject_image != (Image *) NULL);
2338 assert(inject_image->signature == MagickCoreSignature);
2339 assert(exception != (ExceptionInfo *) NULL);
2340 unique_file=(FILE *) NULL;
2341 file=AcquireUniqueFileResource(filename);
2343 unique_file=fdopen(file,"wb");
2344 if ((file == -1) || (unique_file == (FILE *) NULL))
2346 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2347 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
2349 return(MagickFalse);
2351 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
2352 if (byte_image == (Image *) NULL)
2354 (void) fclose(unique_file);
2355 (void) RelinquishUniqueFileResource(filename);
2356 return(MagickFalse);
2358 (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",
2360 DestroyBlob(byte_image);
2361 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
2362 write_info=CloneImageInfo(image_info);
2363 SetImageInfoFile(write_info,unique_file);
2364 status=WriteImage(write_info,byte_image,exception);
2365 write_info=DestroyImageInfo(write_info);
2366 byte_image=DestroyImage(byte_image);
2367 (void) fclose(unique_file);
2368 if (status == MagickFalse)
2370 (void) RelinquishUniqueFileResource(filename);
2371 return(MagickFalse);
2374 Inject into image stream.
2376 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
2379 (void) RelinquishUniqueFileResource(filename);
2380 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
2381 image_info->filename);
2382 return(MagickFalse);
2384 quantum=(size_t) MagickMaxBufferExtent;
2385 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
2386 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2387 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2388 if (buffer == (unsigned char *) NULL)
2390 (void) RelinquishUniqueFileResource(filename);
2392 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2395 for (i=0; ; i+=count)
2397 count=read(file,buffer,quantum);
2404 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2409 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2410 (void) RelinquishUniqueFileResource(filename);
2411 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2420 % I s B l o b E x e m p t %
2424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2426 % IsBlobExempt() returns true if the blob is exempt.
2428 % The format of the IsBlobExempt method is:
2430 % MagickBooleanType IsBlobExempt(const Image *image)
2432 % A description of each parameter follows:
2434 % o image: the image.
2437 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
2439 assert(image != (const Image *) NULL);
2440 assert(image->signature == MagickCoreSignature);
2441 if (image->debug != MagickFalse)
2442 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2443 return(image->blob->exempt);
2447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2451 % I s B l o b S e e k a b l e %
2455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2457 % IsBlobSeekable() returns true if the blob is seekable.
2459 % The format of the IsBlobSeekable method is:
2461 % MagickBooleanType IsBlobSeekable(const Image *image)
2463 % A description of each parameter follows:
2465 % o image: the image.
2468 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2473 assert(image != (const Image *) NULL);
2474 assert(image->signature == MagickCoreSignature);
2475 if (image->debug != MagickFalse)
2476 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2477 switch (image->blob->type)
2483 seekable=MagickTrue;
2486 case UndefinedStream:
2487 case StandardStream:
2493 seekable=MagickFalse;
2498 if ((image->blob->custom_stream->seeker != (CustomStreamSeeker) NULL) &&
2499 (image->blob->custom_stream->teller != (CustomStreamTeller) NULL))
2500 seekable=MagickTrue;
2502 seekable=MagickFalse;
2510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2514 % I s B l o b T e m p o r a r y %
2518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2520 % IsBlobTemporary() returns true if the blob is temporary.
2522 % The format of the IsBlobTemporary method is:
2524 % MagickBooleanType IsBlobTemporary(const Image *image)
2526 % A description of each parameter follows:
2528 % o image: the image.
2531 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2533 assert(image != (const Image *) NULL);
2534 assert(image->signature == MagickCoreSignature);
2535 if (image->debug != MagickFalse)
2536 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2537 return(image->blob->temporary);
2541 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2551 % MapBlob() creates a mapping from a file to a binary large object.
2553 % The format of the MapBlob method is:
2555 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2556 % const size_t length)
2558 % A description of each parameter follows:
2560 % o file: map this file descriptor.
2562 % o mode: ReadMode, WriteMode, or IOMode.
2564 % o offset: starting at this offset within the file.
2566 % o length: the length of the mapping is returned in this pointer.
2569 MagickExport void *MapBlob(int file,const MapMode mode,
2570 const MagickOffsetType offset,const size_t length)
2572 #if defined(MAGICKCORE_HAVE_MMAP)
2585 #if defined(MAP_ANONYMOUS)
2586 flags|=MAP_ANONYMOUS;
2595 protection=PROT_READ;
2601 protection=PROT_WRITE;
2607 protection=PROT_READ | PROT_WRITE;
2612 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2613 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2615 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2617 if (map == MAP_FAILED)
2618 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2620 if (map == MAP_FAILED)
2633 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2637 + M S B O r d e r L o n g %
2641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2643 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2644 % most-significant byte first.
2646 % The format of the MSBOrderLong method is:
2648 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2650 % A description of each parameter follows.
2652 % o buffer: Specifies a pointer to a buffer of integers.
2654 % o length: Specifies the length of the buffer.
2657 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2662 register unsigned char
2666 assert(buffer != (unsigned char *) NULL);
2673 *buffer++=(unsigned char) c;
2677 *buffer++=(unsigned char) c;
2683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2687 + M S B O r d e r S h o r t %
2691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2693 % MSBOrderShort() converts a least-significant byte first buffer of integers
2694 % to most-significant byte first.
2696 % The format of the MSBOrderShort method is:
2698 % void MSBOrderShort(unsigned char *p,const size_t length)
2700 % A description of each parameter follows.
2702 % o p: Specifies a pointer to a buffer of integers.
2704 % o length: Specifies the length of the buffer.
2707 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2712 register unsigned char
2715 assert(p != (unsigned char *) NULL);
2722 *p++=(unsigned char) c;
2727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2737 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2738 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2739 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2740 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2741 % from a system command.
2743 % The format of the OpenBlob method is:
2745 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2746 % const BlobMode mode,ExceptionInfo *exception)
2748 % A description of each parameter follows:
2750 % o image_info: the image info.
2752 % o image: the image.
2754 % o mode: the mode for opening the file.
2758 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2771 option=GetImageOption(image_info,"stream:buffer-size");
2772 if (option != (const char *) NULL)
2773 size=StringToUnsignedLong(option);
2774 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2775 _IONBF : _IOFBF,size);
2776 return(status == 0 ? MagickTrue : MagickFalse);
2779 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2780 Image *image,const BlobMode mode,ExceptionInfo *exception)
2783 extension[MagickPathExtent],
2784 filename[MagickPathExtent];
2795 assert(image_info != (ImageInfo *) NULL);
2796 assert(image_info->signature == MagickCoreSignature);
2797 if (image_info->debug != MagickFalse)
2798 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2799 image_info->filename);
2800 assert(image != (Image *) NULL);
2801 assert(image->signature == MagickCoreSignature);
2802 if (image_info->blob != (void *) NULL)
2804 if (image_info->stream != (StreamHandler) NULL)
2805 image->blob->stream=(StreamHandler) image_info->stream;
2806 AttachBlob(image->blob,image_info->blob,image_info->length);
2809 if ((image_info->custom_stream != (CustomStreamInfo *) NULL) &&
2810 (*image->filename == '\0'))
2812 image->blob->type=CustomStream;
2813 image->blob->custom_stream=image_info->custom_stream;
2816 (void) DetachBlob(image->blob);
2819 default: type="r"; break;
2820 case ReadBlobMode: type="r"; break;
2821 case ReadBinaryBlobMode: type="rb"; break;
2822 case WriteBlobMode: type="w"; break;
2823 case WriteBinaryBlobMode: type="w+b"; break;
2824 case AppendBlobMode: type="a"; break;
2825 case AppendBinaryBlobMode: type="a+b"; break;
2828 image->blob->synchronize=image_info->synchronize;
2829 if (image_info->stream != (StreamHandler) NULL)
2831 image->blob->stream=image_info->stream;
2834 image->blob->type=FifoStream;
2842 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2843 rights=ReadPolicyRights;
2845 rights=WritePolicyRights;
2846 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2849 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2850 "NotAuthorized","`%s'",filename);
2851 return(MagickFalse);
2853 if ((LocaleCompare(filename,"-") == 0) ||
2854 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2856 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2857 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2858 if (strchr(type,'b') != (char *) NULL)
2859 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2861 image->blob->type=StandardStream;
2862 image->blob->exempt=MagickTrue;
2863 return(SetStreamBuffering(image_info,image));
2865 if (LocaleNCompare(filename,"fd:",3) == 0)
2868 fileMode[MagickPathExtent];
2872 image->blob->file_info.file=fdopen(StringToLong(filename+3),fileMode);
2873 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2874 if (strchr(type,'b') != (char *) NULL)
2875 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2877 image->blob->type=StandardStream;
2878 image->blob->exempt=MagickTrue;
2879 return(SetStreamBuffering(image_info,image));
2881 #if defined(MAGICKCORE_HAVE_POPEN) && defined(MAGICKCORE_PIPES_SUPPORT)
2882 if (*filename == '|')
2885 fileMode[MagickPathExtent],
2889 Pipe image to or from a system command.
2891 #if defined(SIGPIPE)
2893 (void) signal(SIGPIPE,SIG_IGN);
2897 sanitize_command=SanitizeString(filename+1);
2898 image->blob->file_info.file=(FILE *) popen_utf8(sanitize_command,
2900 sanitize_command=DestroyString(sanitize_command);
2901 if (image->blob->file_info.file == (FILE *) NULL)
2903 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2904 return(MagickFalse);
2906 image->blob->type=PipeStream;
2907 image->blob->exempt=MagickTrue;
2908 return(SetStreamBuffering(image_info,image));
2911 status=GetPathAttributes(filename,&image->blob->properties);
2912 #if defined(S_ISFIFO)
2913 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2915 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2916 if (image->blob->file_info.file == (FILE *) NULL)
2918 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2919 return(MagickFalse);
2921 image->blob->type=FileStream;
2922 image->blob->exempt=MagickTrue;
2923 return(SetStreamBuffering(image_info,image));
2926 GetPathComponent(image->filename,ExtensionPath,extension);
2929 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2930 if ((image_info->adjoin == MagickFalse) ||
2931 (strchr(filename,'%') != (char *) NULL))
2934 Form filename for multi-part images.
2936 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2937 image->scene,filename,exception);
2938 if ((LocaleCompare(filename,image->filename) == 0) &&
2939 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2940 (GetNextImageInList(image) != (Image *) NULL)))
2943 path[MagickPathExtent];
2945 GetPathComponent(image->filename,RootPath,path);
2946 if (*extension == '\0')
2947 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
2948 path,(double) image->scene);
2950 (void) FormatLocaleString(filename,MagickPathExtent,
2951 "%s-%.20g.%s",path,(double) image->scene,extension);
2953 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2954 #if defined(macintosh)
2955 SetApplicationType(filename,image_info->magick,'8BIM');
2959 if (image_info->file != (FILE *) NULL)
2961 image->blob->file_info.file=image_info->file;
2962 image->blob->type=FileStream;
2963 image->blob->exempt=MagickTrue;
2968 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2969 if (image->blob->file_info.file != (FILE *) NULL)
2977 image->blob->type=FileStream;
2978 (void) SetStreamBuffering(image_info,image);
2979 (void) ResetMagickMemory(magick,0,sizeof(magick));
2980 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2981 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2982 #if defined(MAGICKCORE_POSIX_SUPPORT)
2983 (void) fflush(image->blob->file_info.file);
2985 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2986 " read %.20g magic header bytes",(double) count);
2987 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2988 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2989 ((int) magick[2] == 0x08))
2991 if (image->blob->file_info.file != (FILE *) NULL)
2992 (void) fclose(image->blob->file_info.file);
2993 image->blob->file_info.file=(FILE *) NULL;
2994 image->blob->file_info.gzfile=gzopen(filename,type);
2995 if (image->blob->file_info.gzfile != (gzFile) NULL)
2996 image->blob->type=ZipStream;
2999 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3000 if (strncmp((char *) magick,"BZh",3) == 0)
3002 if (image->blob->file_info.file != (FILE *) NULL)
3003 (void) fclose(image->blob->file_info.file);
3004 image->blob->file_info.file=(FILE *) NULL;
3005 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3006 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3007 image->blob->type=BZipStream;
3010 if (image->blob->type == FileStream)
3021 sans_exception=AcquireExceptionInfo();
3022 magick_info=GetMagickInfo(image_info->magick,sans_exception);
3023 sans_exception=DestroyExceptionInfo(sans_exception);
3024 length=(size_t) image->blob->properties.st_size;
3025 if ((magick_info != (const MagickInfo *) NULL) &&
3026 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
3027 (length > MagickMaxBufferExtent) &&
3028 (AcquireMagickResource(MapResource,length) != MagickFalse))
3033 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
3035 if (blob == (void *) NULL)
3036 RelinquishMagickResource(MapResource,length);
3040 Format supports blobs-- use memory-mapped I/O.
3042 if (image_info->file != (FILE *) NULL)
3043 image->blob->exempt=MagickFalse;
3046 (void) fclose(image->blob->file_info.file);
3047 image->blob->file_info.file=(FILE *) NULL;
3049 AttachBlob(image->blob,blob,length);
3050 image->blob->mapped=MagickTrue;
3057 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3058 if ((LocaleCompare(extension,"Z") == 0) ||
3059 (LocaleCompare(extension,"gz") == 0) ||
3060 (LocaleCompare(extension,"wmz") == 0) ||
3061 (LocaleCompare(extension,"svgz") == 0))
3063 if (mode == WriteBinaryBlobMode)
3065 image->blob->file_info.gzfile=gzopen(filename,type);
3066 if (image->blob->file_info.gzfile != (gzFile) NULL)
3067 image->blob->type=ZipStream;
3071 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3072 if (LocaleCompare(extension,"bz2") == 0)
3074 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3075 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3076 image->blob->type=BZipStream;
3081 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
3082 if (image->blob->file_info.file != (FILE *) NULL)
3084 image->blob->type=FileStream;
3085 (void) SetStreamBuffering(image_info,image);
3088 image->blob->status=MagickFalse;
3089 if (image->blob->type != UndefinedStream)
3090 image->blob->size=GetBlobSize(image);
3093 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
3094 return(MagickFalse);
3100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3110 % PingBlob() returns all the attributes of an image or image sequence except
3111 % for the pixels. It is much faster and consumes far less memory than
3112 % BlobToImage(). On failure, a NULL image is returned and exception
3113 % describes the reason for the failure.
3115 % The format of the PingBlob method is:
3117 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
3118 % const size_t length,ExceptionInfo *exception)
3120 % A description of each parameter follows:
3122 % o image_info: the image info.
3124 % o blob: the address of a character stream in one of the image formats
3125 % understood by ImageMagick.
3127 % o length: This size_t integer reflects the length in bytes of the blob.
3129 % o exception: return any errors or warnings in this structure.
3133 #if defined(__cplusplus) || defined(c_plusplus)
3137 static size_t PingStream(const Image *magick_unused(image),
3138 const void *magick_unused(pixels),const size_t columns)
3140 magick_unreferenced(image);
3141 magick_unreferenced(pixels);
3145 #if defined(__cplusplus) || defined(c_plusplus)
3149 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
3150 const size_t length,ExceptionInfo *exception)
3158 assert(image_info != (ImageInfo *) NULL);
3159 assert(image_info->signature == MagickCoreSignature);
3160 if (image_info->debug != MagickFalse)
3161 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3162 image_info->filename);
3163 assert(exception != (ExceptionInfo *) NULL);
3164 if ((blob == (const void *) NULL) || (length == 0))
3166 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
3167 "UnrecognizedImageFormat","`%s'",image_info->magick);
3168 return((Image *) NULL);
3170 ping_info=CloneImageInfo(image_info);
3171 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
3172 if (ping_info->blob == (const void *) NULL)
3174 (void) ThrowMagickException(exception,GetMagickModule(),
3175 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
3176 return((Image *) NULL);
3178 (void) memcpy(ping_info->blob,blob,length);
3179 ping_info->length=length;
3180 ping_info->ping=MagickTrue;
3181 image=ReadStream(ping_info,&PingStream,exception);
3182 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
3183 ping_info=DestroyImageInfo(ping_info);
3188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3198 % ReadBlob() reads data from the blob or image file and returns it. It
3199 % returns the number of bytes read. If length is zero, ReadBlob() returns
3200 % zero and has no other results. If length is greater than SSIZE_MAX, the
3201 % result is unspecified.
3203 % The format of the ReadBlob method is:
3205 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
3207 % A description of each parameter follows:
3209 % o image: the image.
3211 % o length: Specifies an integer representing the number of bytes to read
3214 % o data: Specifies an area to place the information requested from the
3218 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
3223 register unsigned char
3229 assert(image != (Image *) NULL);
3230 assert(image->signature == MagickCoreSignature);
3231 assert(image->blob != (BlobInfo *) NULL);
3232 assert(image->blob->type != UndefinedStream);
3235 assert(data != (void *) NULL);
3237 q=(unsigned char *) data;
3238 switch (image->blob->type)
3240 case UndefinedStream:
3242 case StandardStream:
3250 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
3255 c=getc(image->blob->file_info.file);
3258 *q++=(unsigned char) c;
3263 c=getc(image->blob->file_info.file);
3266 *q++=(unsigned char) c;
3271 c=getc(image->blob->file_info.file);
3274 *q++=(unsigned char) c;
3279 c=getc(image->blob->file_info.file);
3282 *q++=(unsigned char) c;
3292 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3297 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
3298 (unsigned int) length);
3303 c=gzgetc(image->blob->file_info.gzfile);
3306 *q++=(unsigned char) c;
3311 c=gzgetc(image->blob->file_info.gzfile);
3314 *q++=(unsigned char) c;
3319 c=gzgetc(image->blob->file_info.gzfile);
3322 *q++=(unsigned char) c;
3327 c=gzgetc(image->blob->file_info.gzfile);
3330 *q++=(unsigned char) c;
3341 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3342 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
3350 register const unsigned char
3353 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3355 image->blob->eof=MagickTrue;
3358 p=image->blob->data+image->blob->offset;
3359 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
3360 image->blob->offset+=count;
3361 if (count != (ssize_t) length)
3362 image->blob->eof=MagickTrue;
3363 (void) memcpy(q,p,(size_t) count);
3368 count=image->blob->custom_stream->reader(q,length,
3369 image->blob->custom_stream->data);
3377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3381 + R e a d B l o b B y t e %
3385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3387 % ReadBlobByte() reads a single byte from the image file and returns it.
3389 % The format of the ReadBlobByte method is:
3391 % int ReadBlobByte(Image *image)
3393 % A description of each parameter follows.
3395 % o image: the image.
3398 MagickExport int ReadBlobByte(Image *image)
3400 register const unsigned char
3409 assert(image != (Image *) NULL);
3410 assert(image->signature == MagickCoreSignature);
3411 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3422 + R e a d B l o b D o u b l e %
3426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3428 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3429 % specified by the endian member of the image structure.
3431 % The format of the ReadBlobDouble method is:
3433 % double ReadBlobDouble(Image *image)
3435 % A description of each parameter follows.
3437 % o image: the image.
3440 MagickExport double ReadBlobDouble(Image *image)
3451 quantum.double_value=0.0;
3452 quantum.unsigned_value=ReadBlobLongLong(image);
3453 return(quantum.double_value);
3457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3461 + R e a d B l o b F l o a t %
3465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3467 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3468 % specified by the endian member of the image structure.
3470 % The format of the ReadBlobFloat method is:
3472 % float ReadBlobFloat(Image *image)
3474 % A description of each parameter follows.
3476 % o image: the image.
3479 MagickExport float ReadBlobFloat(Image *image)
3490 quantum.float_value=0.0;
3491 quantum.unsigned_value=ReadBlobLong(image);
3492 return(quantum.float_value);
3496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3500 + R e a d B l o b L o n g %
3504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3506 % ReadBlobLong() reads a unsigned int value as a 32-bit quantity in the
3507 % byte-order specified by the endian member of the image structure.
3509 % The format of the ReadBlobLong method is:
3511 % unsigned int ReadBlobLong(Image *image)
3513 % A description of each parameter follows.
3515 % o image: the image.
3518 MagickExport unsigned int ReadBlobLong(Image *image)
3520 register const unsigned char
3532 assert(image != (Image *) NULL);
3533 assert(image->signature == MagickCoreSignature);
3535 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3538 if (image->endian == LSBEndian)
3540 value=(unsigned int) (*p++);
3541 value|=(unsigned int) (*p++) << 8;
3542 value|=(unsigned int) (*p++) << 16;
3543 value|=(unsigned int) (*p++) << 24;
3544 return(value & 0xffffffff);
3546 value=(unsigned int) (*p++) << 24;
3547 value|=(unsigned int) (*p++) << 16;
3548 value|=(unsigned int) (*p++) << 8;
3549 value|=(unsigned int) (*p++);
3550 return(value & 0xffffffff);
3554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3558 + R e a d B l o b L o n g L o n g %
3562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3564 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3565 % byte-order specified by the endian member of the image structure.
3567 % The format of the ReadBlobLongLong method is:
3569 % MagickSizeType ReadBlobLongLong(Image *image)
3571 % A description of each parameter follows.
3573 % o image: the image.
3576 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3581 register const unsigned char
3590 assert(image != (Image *) NULL);
3591 assert(image->signature == MagickCoreSignature);
3593 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3595 return(MagickULLConstant(0));
3596 if (image->endian == LSBEndian)
3598 value=(MagickSizeType) (*p++);
3599 value|=(MagickSizeType) (*p++) << 8;
3600 value|=(MagickSizeType) (*p++) << 16;
3601 value|=(MagickSizeType) (*p++) << 24;
3602 value|=(MagickSizeType) (*p++) << 32;
3603 value|=(MagickSizeType) (*p++) << 40;
3604 value|=(MagickSizeType) (*p++) << 48;
3605 value|=(MagickSizeType) (*p++) << 56;
3606 return(value & MagickULLConstant(0xffffffffffffffff));
3608 value=(MagickSizeType) (*p++) << 56;
3609 value|=(MagickSizeType) (*p++) << 48;
3610 value|=(MagickSizeType) (*p++) << 40;
3611 value|=(MagickSizeType) (*p++) << 32;
3612 value|=(MagickSizeType) (*p++) << 24;
3613 value|=(MagickSizeType) (*p++) << 16;
3614 value|=(MagickSizeType) (*p++) << 8;
3615 value|=(MagickSizeType) (*p++);
3616 return(value & MagickULLConstant(0xffffffffffffffff));
3620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3624 + R e a d B l o b S h o r t %
3628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3630 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3631 % specified by the endian member of the image structure.
3633 % The format of the ReadBlobShort method is:
3635 % unsigned short ReadBlobShort(Image *image)
3637 % A description of each parameter follows.
3639 % o image: the image.
3642 MagickExport unsigned short ReadBlobShort(Image *image)
3644 register const unsigned char
3647 register unsigned short
3656 assert(image != (Image *) NULL);
3657 assert(image->signature == MagickCoreSignature);
3659 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3661 return((unsigned short) 0U);
3662 if (image->endian == LSBEndian)
3664 value=(unsigned short) (*p++);
3665 value|=(unsigned short) (*p++) << 8;
3668 value=(unsigned short) (*p++) << 8;
3669 value|=(unsigned short) (*p++);
3674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3678 + R e a d B l o b L S B L o n g %
3682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3684 % ReadBlobLSBLong() reads a unsigned int value as a 32-bit quantity in
3685 % least-significant byte first order.
3687 % The format of the ReadBlobLSBLong method is:
3689 % unsigned int ReadBlobLSBLong(Image *image)
3691 % A description of each parameter follows.
3693 % o image: the image.
3696 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3698 register const unsigned char
3701 register unsigned int
3710 assert(image != (Image *) NULL);
3711 assert(image->signature == MagickCoreSignature);
3713 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3716 value=(unsigned int) (*p++);
3717 value|=(unsigned int) (*p++) << 8;
3718 value|=(unsigned int) (*p++) << 16;
3719 value|=(unsigned int) (*p++) << 24;
3720 return(value & 0xffffffff);
3724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3728 + R e a d B l o b L S B S i g n e d L o n g %
3732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3734 % ReadBlobLSBSignedLong() reads a signed int value as a 32-bit quantity in
3735 % least-significant byte first order.
3737 % The format of the ReadBlobLSBSignedLong method is:
3739 % signed int ReadBlobLSBSignedLong(Image *image)
3741 % A description of each parameter follows.
3743 % o image: the image.
3746 MagickExport signed int ReadBlobLSBSignedLong(Image *image)
3757 quantum.unsigned_value=ReadBlobLSBLong(image);
3758 return(quantum.signed_value);
3762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3766 + R e a d B l o b L S B S h o r t %
3770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3772 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3773 % least-significant byte first order.
3775 % The format of the ReadBlobLSBShort method is:
3777 % unsigned short ReadBlobLSBShort(Image *image)
3779 % A description of each parameter follows.
3781 % o image: the image.
3784 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3786 register const unsigned char
3789 register unsigned short
3798 assert(image != (Image *) NULL);
3799 assert(image->signature == MagickCoreSignature);
3801 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3803 return((unsigned short) 0U);
3804 value=(unsigned int) (*p++);
3805 value|=(unsigned int) (*p++) << 8;
3806 return(value & 0xffff);
3810 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3814 + R e a d B l o b L S B S i g n e d S h o r t %
3818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3820 % ReadBlobLSBSignedShort() reads a signed short value as a 16-bit quantity in
3821 % least-significant byte-order.
3823 % The format of the ReadBlobLSBSignedShort method is:
3825 % signed short ReadBlobLSBSignedShort(Image *image)
3827 % A description of each parameter follows.
3829 % o image: the image.
3832 MagickExport signed short ReadBlobLSBSignedShort(Image *image)
3843 quantum.unsigned_value=ReadBlobLSBShort(image);
3844 return(quantum.signed_value);
3848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3852 + R e a d B l o b M S B L o n g %
3856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3858 % ReadBlobMSBLong() reads a unsigned int value as a 32-bit quantity in
3859 % most-significant byte first order.
3861 % The format of the ReadBlobMSBLong method is:
3863 % unsigned int ReadBlobMSBLong(Image *image)
3865 % A description of each parameter follows.
3867 % o image: the image.
3870 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3872 register const unsigned char
3875 register unsigned int
3884 assert(image != (Image *) NULL);
3885 assert(image->signature == MagickCoreSignature);
3887 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3890 value=(unsigned int) (*p++) << 24;
3891 value|=(unsigned int) (*p++) << 16;
3892 value|=(unsigned int) (*p++) << 8;
3893 value|=(unsigned int) (*p++);
3898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3902 + R e a d B l o b M S B L o n g L o n g %
3906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3908 % ReadBlobMSBLongLong() reads a unsigned long long value as a 64-bit quantity
3909 % in most-significant byte first order.
3911 % The format of the ReadBlobMSBLongLong method is:
3913 % unsigned int ReadBlobMSBLongLong(Image *image)
3915 % A description of each parameter follows.
3917 % o image: the image.
3920 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3922 register const unsigned char
3925 register MagickSizeType
3934 assert(image != (Image *) NULL);
3935 assert(image->signature == MagickCoreSignature);
3937 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3939 return(MagickULLConstant(0));
3940 value=(MagickSizeType) (*p++) << 56;
3941 value|=(MagickSizeType) (*p++) << 48;
3942 value|=(MagickSizeType) (*p++) << 40;
3943 value|=(MagickSizeType) (*p++) << 32;
3944 value|=(MagickSizeType) (*p++) << 24;
3945 value|=(MagickSizeType) (*p++) << 16;
3946 value|=(MagickSizeType) (*p++) << 8;
3947 value|=(MagickSizeType) (*p++);
3948 return(value & MagickULLConstant(0xffffffffffffffff));
3952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3956 + R e a d B l o b M S B S h o r t %
3960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3962 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3963 % most-significant byte first order.
3965 % The format of the ReadBlobMSBShort method is:
3967 % unsigned short ReadBlobMSBShort(Image *image)
3969 % A description of each parameter follows.
3971 % o image: the image.
3974 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3976 register const unsigned char
3979 register unsigned short
3988 assert(image != (Image *) NULL);
3989 assert(image->signature == MagickCoreSignature);
3991 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3993 return((unsigned short) 0U);
3994 value=(unsigned short) (*p++) << 8;
3995 value|=(unsigned short) (*p++);
3996 return(value & 0xffff);
4000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4004 + R e a d B l o b M S B S i g n e d L o n g %
4008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4010 % ReadBlobMSBSignedLong() reads a signed int value as a 32-bit quantity in
4011 % most-significant byte-order.
4013 % The format of the ReadBlobMSBSignedLong method is:
4015 % signed int ReadBlobMSBSignedLong(Image *image)
4017 % A description of each parameter follows.
4019 % o image: the image.
4022 MagickExport signed int ReadBlobMSBSignedLong(Image *image)
4033 quantum.unsigned_value=ReadBlobMSBLong(image);
4034 return(quantum.signed_value);
4038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4042 + R e a d B l o b M S B S i g n e d S h o r t %
4046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4048 % ReadBlobMSBSignedShort() reads a signed short value as a 16-bit quantity in
4049 % most-significant byte-order.
4051 % The format of the ReadBlobMSBSignedShort method is:
4053 % signed short ReadBlobMSBSignedShort(Image *image)
4055 % A description of each parameter follows.
4057 % o image: the image.
4060 MagickExport signed short ReadBlobMSBSignedShort(Image *image)
4071 quantum.unsigned_value=ReadBlobMSBShort(image);
4072 return(quantum.signed_value);
4076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4080 + R e a d B l o b S i g n e d L o n g %
4084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4086 % ReadBlobSignedLong() reads a signed int value as a 32-bit quantity in the
4087 % byte-order specified by the endian member of the image structure.
4089 % The format of the ReadBlobSignedLong method is:
4091 % signed int ReadBlobSignedLong(Image *image)
4093 % A description of each parameter follows.
4095 % o image: the image.
4098 MagickExport signed int ReadBlobSignedLong(Image *image)
4109 quantum.unsigned_value=ReadBlobLong(image);
4110 return(quantum.signed_value);
4114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4118 + R e a d B l o b S i g n e d S h o r t %
4122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4124 % ReadBlobSignedShort() reads a signed short value as a 16-bit quantity in the
4125 % byte-order specified by the endian member of the image structure.
4127 % The format of the ReadBlobSignedShort method is:
4129 % signed short ReadBlobSignedShort(Image *image)
4131 % A description of each parameter follows.
4133 % o image: the image.
4136 MagickExport signed short ReadBlobSignedShort(Image *image)
4147 quantum.unsigned_value=ReadBlobShort(image);
4148 return(quantum.signed_value);
4152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4156 + R e a d B l o b S t r e a m %
4160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4162 % ReadBlobStream() reads data from the blob or image file and returns it. It
4163 % returns a pointer to the data buffer you supply or to the image memory
4164 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
4165 % returns a count of zero and has no other results. If length is greater than
4166 % SSIZE_MAX, the result is unspecified.
4168 % The format of the ReadBlobStream method is:
4170 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
4173 % A description of each parameter follows:
4175 % o image: the image.
4177 % o length: Specifies an integer representing the number of bytes to read
4180 % o count: returns the number of bytes read.
4182 % o data: Specifies an area to place the information requested from the
4186 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
4187 void *data,ssize_t *count)
4189 assert(image != (Image *) NULL);
4190 assert(image->signature == MagickCoreSignature);
4191 assert(image->blob != (BlobInfo *) NULL);
4192 assert(image->blob->type != UndefinedStream);
4193 assert(count != (ssize_t *) NULL);
4194 if (image->blob->type != BlobStream)
4196 assert(data != NULL);
4197 *count=ReadBlob(image,length,(unsigned char *) data);
4200 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4203 image->blob->eof=MagickTrue;
4206 data=image->blob->data+image->blob->offset;
4207 *count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
4208 image->blob->offset+=(*count);
4209 if (*count != (ssize_t) length)
4210 image->blob->eof=MagickTrue;
4215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4219 + R e a d B l o b S t r i n g %
4223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4225 % ReadBlobString() reads characters from a blob or file until a newline
4226 % character is read or an end-of-file condition is encountered.
4228 % The format of the ReadBlobString method is:
4230 % char *ReadBlobString(Image *image,char *string)
4232 % A description of each parameter follows:
4234 % o image: the image.
4236 % o string: the address of a character buffer.
4239 MagickExport char *ReadBlobString(Image *image,char *string)
4241 register const unsigned char
4253 assert(image != (Image *) NULL);
4254 assert(image->signature == MagickCoreSignature);
4255 for (i=0; i < (MagickPathExtent-1L); i++)
4257 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
4261 return((char *) NULL);
4264 string[i]=(char) (*p);
4265 if ((string[i] == '\r') || (string[i] == '\n'))
4268 if (string[i] == '\r')
4269 (void) ReadBlobStream(image,1,buffer,&count);
4275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4279 + R e f e r e n c e B l o b %
4283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4285 % ReferenceBlob() increments the reference count associated with the pixel
4286 % blob returning a pointer to the blob.
4288 % The format of the ReferenceBlob method is:
4290 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
4292 % A description of each parameter follows:
4294 % o blob_info: the blob_info.
4297 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
4299 assert(blob != (BlobInfo *) NULL);
4300 assert(blob->signature == MagickCoreSignature);
4301 if (blob->debug != MagickFalse)
4302 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4303 LockSemaphoreInfo(blob->semaphore);
4304 blob->reference_count++;
4305 UnlockSemaphoreInfo(blob->semaphore);
4310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4320 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
4321 % and returns the resulting offset.
4323 % The format of the SeekBlob method is:
4325 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
4328 % A description of each parameter follows:
4330 % o image: the image.
4332 % o offset: Specifies an integer representing the offset in bytes.
4334 % o whence: Specifies an integer representing how the offset is
4335 % treated relative to the beginning of the blob as follows:
4337 % SEEK_SET Set position equal to offset bytes.
4338 % SEEK_CUR Set position to current location plus offset.
4339 % SEEK_END Set position to EOF plus offset.
4342 MagickExport MagickOffsetType SeekBlob(Image *image,
4343 const MagickOffsetType offset,const int whence)
4345 assert(image != (Image *) NULL);
4346 assert(image->signature == MagickCoreSignature);
4347 if (image->debug != MagickFalse)
4348 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4349 assert(image->blob != (BlobInfo *) NULL);
4350 assert(image->blob->type != UndefinedStream);
4351 switch (image->blob->type)
4353 case UndefinedStream:
4355 case StandardStream:
4360 if ((offset < 0) && (whence == SEEK_SET))
4362 if (fseek(image->blob->file_info.file,offset,whence) < 0)
4364 image->blob->offset=TellBlob(image);
4369 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4370 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
4373 image->blob->offset=TellBlob(image);
4389 image->blob->offset=offset;
4394 if ((image->blob->offset+offset) < 0)
4396 image->blob->offset+=offset;
4401 if (((MagickOffsetType) image->blob->length+offset) < 0)
4403 image->blob->offset=image->blob->length+offset;
4407 if (image->blob->offset < (MagickOffsetType)
4408 ((off_t) image->blob->length))
4410 image->blob->eof=MagickFalse;
4413 if (image->blob->offset < (MagickOffsetType)
4414 ((off_t) image->blob->extent))
4416 if (image->blob->mapped != MagickFalse)
4418 image->blob->eof=MagickTrue;
4421 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
4422 image->blob->quantum<<=1;
4423 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4424 image->blob->extent+1,sizeof(*image->blob->data));
4425 (void) SyncBlob(image);
4426 if (image->blob->data == NULL)
4428 (void) DetachBlob(image->blob);
4435 if (image->blob->custom_stream->seeker == (CustomStreamSeeker) NULL)
4437 image->blob->offset=image->blob->custom_stream->seeker(offset,whence,
4438 image->blob->custom_stream->data);
4442 return(image->blob->offset);
4446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4450 + S e t B l o b E x e m p t %
4454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4456 % SetBlobExempt() sets the blob exempt status.
4458 % The format of the SetBlobExempt method is:
4460 % MagickBooleanType SetBlobExempt(const Image *image,
4461 % const MagickBooleanType exempt)
4463 % A description of each parameter follows:
4465 % o image: the image.
4467 % o exempt: Set to true if this blob is exempt from being closed.
4470 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
4472 assert(image != (const Image *) NULL);
4473 assert(image->signature == MagickCoreSignature);
4474 if (image->debug != MagickFalse)
4475 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4476 image->blob->exempt=exempt;
4480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4484 + S e t B l o b E x t e n t %
4488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4490 % SetBlobExtent() ensures enough space is allocated for the blob. If the
4491 % method is successful, subsequent writes to bytes in the specified range are
4492 % guaranteed not to fail.
4494 % The format of the SetBlobExtent method is:
4496 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
4498 % A description of each parameter follows:
4500 % o image: the image.
4502 % o extent: the blob maximum extent.
4505 MagickExport MagickBooleanType SetBlobExtent(Image *image,
4506 const MagickSizeType extent)
4508 assert(image != (Image *) NULL);
4509 assert(image->signature == MagickCoreSignature);
4510 if (image->debug != MagickFalse)
4511 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4512 assert(image->blob != (BlobInfo *) NULL);
4513 assert(image->blob->type != UndefinedStream);
4514 switch (image->blob->type)
4516 case UndefinedStream:
4518 case StandardStream:
4519 return(MagickFalse);
4528 if (extent != (MagickSizeType) ((off_t) extent))
4529 return(MagickFalse);
4530 offset=SeekBlob(image,0,SEEK_END);
4532 return(MagickFalse);
4533 if ((MagickSizeType) offset >= extent)
4535 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4538 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4539 image->blob->file_info.file);
4540 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4541 if (image->blob->synchronize != MagickFalse)
4546 file=fileno(image->blob->file_info.file);
4547 if ((file == -1) || (offset < 0))
4548 return(MagickFalse);
4549 (void) posix_fallocate(file,offset,extent-offset);
4552 offset=SeekBlob(image,offset,SEEK_SET);
4554 return(MagickFalse);
4559 return(MagickFalse);
4561 return(MagickFalse);
4563 return(MagickFalse);
4566 if (extent != (MagickSizeType) ((size_t) extent))
4567 return(MagickFalse);
4568 if (image->blob->mapped != MagickFalse)
4576 (void) UnmapBlob(image->blob->data,image->blob->length);
4577 RelinquishMagickResource(MapResource,image->blob->length);
4578 if (extent != (MagickSizeType) ((off_t) extent))
4579 return(MagickFalse);
4580 offset=SeekBlob(image,0,SEEK_END);
4582 return(MagickFalse);
4583 if ((MagickSizeType) offset >= extent)
4585 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4586 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4587 image->blob->file_info.file);
4588 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4589 if (image->blob->synchronize != MagickFalse)
4594 file=fileno(image->blob->file_info.file);
4595 if ((file == -1) || (offset < 0))
4596 return(MagickFalse);
4597 (void) posix_fallocate(file,offset,extent-offset);
4600 offset=SeekBlob(image,offset,SEEK_SET);
4602 return(MagickFalse);
4603 (void) AcquireMagickResource(MapResource,extent);
4604 image->blob->data=(unsigned char*) MapBlob(fileno(
4605 image->blob->file_info.file),WriteMode,0,(size_t) extent);
4606 image->blob->extent=(size_t) extent;
4607 image->blob->length=(size_t) extent;
4608 (void) SyncBlob(image);
4611 image->blob->extent=(size_t) extent;
4612 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4613 image->blob->extent+1,sizeof(*image->blob->data));
4614 (void) SyncBlob(image);
4615 if (image->blob->data == (unsigned char *) NULL)
4617 (void) DetachBlob(image->blob);
4618 return(MagickFalse);
4629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4633 + S e t C u s t o m S t r e a m D a t a %
4637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4639 % SetCustomStreamData() sets the stream info data member.
4641 % The format of the SetCustomStreamData method is:
4643 % void SetCustomStreamData(CustomStreamInfo *custom_stream,void *)
4645 % A description of each parameter follows:
4647 % o custom_stream: your custom stream.
4649 % o void: your data.
4652 MagickExport void SetCustomStreamData(CustomStreamInfo *custom_stream,
4655 assert(custom_stream != (CustomStreamInfo *) NULL);
4656 assert(custom_stream->signature == MagickCoreSignature);
4657 custom_stream->data=data;
4661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4665 + S e t C u s t o m S t r e a m R e a d e r %
4669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4671 % SetCustomStreamReader() sets the stream info reader member.
4673 % The format of the SetCustomStreamReader method is:
4675 % void SetCustomStreamReader(CustomStreamInfo *custom_stream,
4676 % CustomStreamHandler reader)
4678 % A description of each parameter follows:
4680 % o custom_stream: your custom stream.
4682 % o reader: your custom stream reader.
4685 MagickExport void SetCustomStreamReader(CustomStreamInfo *custom_stream,
4686 CustomStreamHandler reader)
4688 assert(custom_stream != (CustomStreamInfo *) NULL);
4689 assert(custom_stream->signature == MagickCoreSignature);
4690 custom_stream->reader=reader;
4694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4698 + S e t C u s t o m S t r e a m S e e k e r %
4702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4704 % SetCustomStreamSeeker() sets the stream info seeker member.
4706 % The format of the SetCustomStreamReader method is:
4708 % void SetCustomStreamSeeker(CustomStreamInfo *custom_stream,
4709 % CustomStreamSeeker seeker)
4711 % A description of each parameter follows:
4713 % o custom_stream: your custom stream.
4715 % o seeker: your custom stream seeker.
4718 MagickExport void SetCustomStreamSeeker(CustomStreamInfo *custom_stream,
4719 CustomStreamSeeker seeker)
4721 assert(custom_stream != (CustomStreamInfo *) NULL);
4722 assert(custom_stream->signature == MagickCoreSignature);
4723 custom_stream->seeker=seeker;
4727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4731 + S e t C u s t o m S t r e a m T e l l e r %
4735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4737 % SetCustomStreamTeller() sets the stream info teller member.
4739 % The format of the SetCustomStreamTeller method is:
4741 % void SetCustomStreamTeller(CustomStreamInfo *custom_stream,
4742 % CustomStreamTeller *teller)
4744 % A description of each parameter follows:
4746 % o custom_stream: your custom stream.
4748 % o teller: your custom stream teller.
4751 MagickExport void SetCustomStreamTeller(CustomStreamInfo *custom_stream,
4752 CustomStreamTeller teller)
4754 assert(custom_stream != (CustomStreamInfo *) NULL);
4755 assert(custom_stream->signature == MagickCoreSignature);
4756 custom_stream->teller=teller;
4760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4764 + S e t C u s t o m S t r e a m W r i t e r %
4768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4770 % SetCustomStreamWriter() sets the stream info writer member.
4772 % The format of the SetCustomStreamWriter method is:
4774 % void SetCustomStreamWriter(CustomStreamInfo *custom_stream,
4775 % CustomStreamHandler *writer)
4777 % A description of each parameter follows:
4779 % o custom_stream: your custom stream.
4781 % o writer: your custom stream writer.
4784 MagickExport void SetCustomStreamWriter(CustomStreamInfo *custom_stream,
4785 CustomStreamHandler writer)
4787 assert(custom_stream != (CustomStreamInfo *) NULL);
4788 assert(custom_stream->signature == MagickCoreSignature);
4789 custom_stream->writer=writer;
4793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4803 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
4804 % attributes if it is an blob.
4806 % The format of the SyncBlob method is:
4808 % int SyncBlob(Image *image)
4810 % A description of each parameter follows:
4812 % o image: the image.
4815 static int SyncBlob(Image *image)
4820 assert(image != (Image *) NULL);
4821 assert(image->signature == MagickCoreSignature);
4822 if (image->debug != MagickFalse)
4823 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4824 assert(image->blob != (BlobInfo *) NULL);
4825 assert(image->blob->type != UndefinedStream);
4827 switch (image->blob->type)
4829 case UndefinedStream:
4830 case StandardStream:
4835 status=fflush(image->blob->file_info.file);
4840 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4841 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
4847 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4848 status=BZ2_bzflush(image->blob->file_info.bzfile);
4863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4873 % TellBlob() obtains the current value of the blob or file position.
4875 % The format of the TellBlob method is:
4877 % MagickOffsetType TellBlob(const Image *image)
4879 % A description of each parameter follows:
4881 % o image: the image.
4884 MagickExport MagickOffsetType TellBlob(const Image *image)
4889 assert(image != (Image *) NULL);
4890 assert(image->signature == MagickCoreSignature);
4891 if (image->debug != MagickFalse)
4892 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4893 assert(image->blob != (BlobInfo *) NULL);
4894 assert(image->blob->type != UndefinedStream);
4896 switch (image->blob->type)
4898 case UndefinedStream:
4899 case StandardStream:
4903 offset=ftell(image->blob->file_info.file);
4910 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4911 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
4921 offset=image->blob->offset;
4926 if (image->blob->custom_stream->teller != (CustomStreamTeller) NULL)
4927 offset=image->blob->custom_stream->teller(image->blob->custom_stream->data);
4935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4939 + U n m a p B l o b %
4943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4945 % UnmapBlob() deallocates the binary large object previously allocated with
4946 % the MapBlob method.
4948 % The format of the UnmapBlob method is:
4950 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4952 % A description of each parameter follows:
4954 % o map: the address of the binary large object.
4956 % o length: the length of the binary large object.
4959 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4961 #if defined(MAGICKCORE_HAVE_MMAP)
4965 status=munmap(map,length);
4966 return(status == -1 ? MagickFalse : MagickTrue);
4970 return(MagickFalse);
4975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4979 % C u s t o m S t r e a m T o I m a g e %
4983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4985 % CustomStreamToImage() is the equivalent of ReadImage(), but reads the
4986 % formatted "file" from the suplied method rather than to an actual file.
4988 % The format of the CustomStreamToImage method is:
4990 % Image *CustomStreamToImage(const ImageInfo *image_info,
4991 % ExceptionInfo *exception)
4993 % A description of each parameter follows:
4995 % o image_info: the image info.
4997 % o exception: return any errors or warnings in this structure.
5000 MagickExport Image *CustomStreamToImage(const ImageInfo *image_info,
5001 ExceptionInfo *exception)
5012 assert(image_info != (ImageInfo *) NULL);
5013 assert(image_info->signature == MagickCoreSignature);
5014 if (image_info->debug != MagickFalse)
5015 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
5016 image_info->filename);
5017 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
5018 assert(image_info->custom_stream->signature == MagickCoreSignature);
5019 assert(image_info->custom_stream->reader != (CustomStreamHandler) NULL);
5020 assert(exception != (ExceptionInfo *) NULL);
5021 blob_info=CloneImageInfo(image_info);
5022 if (*blob_info->magick == '\0')
5023 (void) SetImageInfo(blob_info,0,exception);
5024 magick_info=GetMagickInfo(blob_info->magick,exception);
5025 if (magick_info == (const MagickInfo *) NULL)
5027 (void) ThrowMagickException(exception,GetMagickModule(),
5028 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
5030 blob_info=DestroyImageInfo(blob_info);
5031 return((Image *) NULL);
5033 image=(Image *) NULL;
5034 if ((GetMagickBlobSupport(magick_info) != MagickFalse) ||
5035 (blob_info->custom_stream == (CustomStreamInfo *) NULL))
5038 Native blob support for this image format or SetImageInfo changed the
5041 image=ReadImage(blob_info,exception);
5042 if (image != (Image *) NULL)
5043 (void) CloseBlob(image);
5048 unique[MagickPathExtent];
5060 Write data to file on disk.
5062 blob_info->custom_stream=(CustomStreamInfo *) NULL;
5063 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
5065 if (blob == (unsigned char *) NULL)
5067 ThrowFileException(exception,BlobError,"UnableToReadBlob",
5068 image_info->filename);
5069 blob_info=DestroyImageInfo(blob_info);
5070 return((Image *) NULL);
5072 file=AcquireUniqueFileResource(unique);
5075 ThrowFileException(exception,BlobError,"UnableToReadBlob",
5076 image_info->filename);
5077 blob=(unsigned char *) RelinquishMagickMemory(blob);
5078 blob_info=DestroyImageInfo(blob_info);
5079 return((Image *) NULL);
5081 clone_info=CloneImageInfo(blob_info);
5082 blob_info->file=fdopen(file,"wb+");
5083 if (blob_info->file != (FILE *) NULL)
5088 count=(ssize_t) MagickMaxBufferExtent;
5089 while (count == (ssize_t) MagickMaxBufferExtent)
5091 count=image_info->custom_stream->reader(blob,MagickMaxBufferExtent,
5092 image_info->custom_stream->data);
5093 count=(ssize_t) write(file,(const char *) blob,count);
5095 (void) fclose(blob_info->file);
5096 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,
5097 "%s:%s",blob_info->magick,unique);
5098 image=ReadImage(clone_info,exception);
5099 if (image != (Image *) NULL)
5105 Restore original filenames and image format.
5107 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
5109 (void) CopyMagickString(images->filename,image_info->filename,
5111 (void) CopyMagickString(images->magick_filename,
5112 image_info->filename,MagickPathExtent);
5113 (void) CopyMagickString(images->magick,magick_info->name,
5115 (void) CloseBlob(images);
5116 images=GetNextImageInList(images);
5120 clone_info=DestroyImageInfo(clone_info);
5121 blob=(unsigned char *) RelinquishMagickMemory(blob);
5122 (void) RelinquishUniqueFileResource(unique);
5124 blob_info=DestroyImageInfo(blob_info);
5129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5133 + W r i t e B l o b %
5137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5139 % WriteBlob() writes data to a blob or image file. It returns the number of
5142 % The format of the WriteBlob method is:
5144 % ssize_t WriteBlob(Image *image,const size_t length,const void *data)
5146 % A description of each parameter follows:
5148 % o image: the image.
5150 % o length: Specifies an integer representing the number of bytes to
5151 % write to the file.
5153 % o data: The address of the data to write to the blob or file.
5156 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
5162 register const unsigned char
5168 assert(image != (Image *) NULL);
5169 assert(image->signature == MagickCoreSignature);
5170 assert(data != (const void *) NULL);
5171 assert(image->blob != (BlobInfo *) NULL);
5172 assert(image->blob->type != UndefinedStream);
5176 p=(const unsigned char *) data;
5177 switch (image->blob->type)
5179 case UndefinedStream:
5181 case StandardStream:
5189 count=(ssize_t) fwrite((const char *) data,1,length,
5190 image->blob->file_info.file);
5195 c=putc((int) *p++,image->blob->file_info.file);
5202 c=putc((int) *p++,image->blob->file_info.file);
5209 c=putc((int) *p++,image->blob->file_info.file);
5216 c=putc((int) *p++,image->blob->file_info.file);
5228 #if defined(MAGICKCORE_ZLIB_DELEGATE)
5233 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
5234 (unsigned int) length);
5239 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5246 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5253 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5260 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5273 #if defined(MAGICKCORE_BZLIB_DELEGATE)
5274 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
5281 count=(ssize_t) image->blob->stream(image,data,length);
5286 register unsigned char
5289 if ((image->blob->offset+(MagickOffsetType) length) >=
5290 (MagickOffsetType) image->blob->extent)
5292 if (image->blob->mapped != MagickFalse)
5294 image->blob->extent+=length+image->blob->quantum;
5295 image->blob->quantum<<=1;
5296 image->blob->data=(unsigned char *) ResizeQuantumMemory(
5297 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
5298 (void) SyncBlob(image);
5299 if (image->blob->data == (unsigned char *) NULL)
5301 (void) DetachBlob(image->blob);
5305 q=image->blob->data+image->blob->offset;
5306 (void) memcpy(q,p,length);
5307 image->blob->offset+=length;
5308 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
5309 image->blob->length=(size_t) image->blob->offset;
5310 count=(ssize_t) length;
5315 count=image->blob->custom_stream->writer((const unsigned char *) data,
5316 length,image->blob->custom_stream->data);
5324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5328 + W r i t e B l o b B y t e %
5332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5334 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
5335 % written (either 0 or 1);
5337 % The format of the WriteBlobByte method is:
5339 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
5341 % A description of each parameter follows.
5343 % o image: the image.
5345 % o value: Specifies the value to write.
5348 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
5350 assert(image != (Image *) NULL);
5351 assert(image->signature == MagickCoreSignature);
5352 return(WriteBlobStream(image,1,&value));
5356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5360 + W r i t e B l o b F l o a t %
5364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5366 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
5367 % specified by the endian member of the image structure.
5369 % The format of the WriteBlobFloat method is:
5371 % ssize_t WriteBlobFloat(Image *image,const float value)
5373 % A description of each parameter follows.
5375 % o image: the image.
5377 % o value: Specifies the value to write.
5380 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
5391 quantum.unsigned_value=0U;
5392 quantum.float_value=value;
5393 return(WriteBlobLong(image,quantum.unsigned_value));
5397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5401 + W r i t e B l o b L o n g %
5405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5407 % WriteBlobLong() writes a unsigned int value as a 32-bit quantity in the
5408 % byte-order specified by the endian member of the image structure.
5410 % The format of the WriteBlobLong method is:
5412 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
5414 % A description of each parameter follows.
5416 % o image: the image.
5418 % o value: Specifies the value to write.
5421 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
5426 assert(image != (Image *) NULL);
5427 assert(image->signature == MagickCoreSignature);
5428 if (image->endian == LSBEndian)
5430 buffer[0]=(unsigned char) value;
5431 buffer[1]=(unsigned char) (value >> 8);
5432 buffer[2]=(unsigned char) (value >> 16);
5433 buffer[3]=(unsigned char) (value >> 24);
5434 return(WriteBlobStream(image,4,buffer));
5436 buffer[0]=(unsigned char) (value >> 24);
5437 buffer[1]=(unsigned char) (value >> 16);
5438 buffer[2]=(unsigned char) (value >> 8);
5439 buffer[3]=(unsigned char) value;
5440 return(WriteBlobStream(image,4,buffer));
5444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5448 + W r i t e B l o b S h o r t %
5452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5454 % WriteBlobShort() writes a short value as a 16-bit quantity in the
5455 % byte-order specified by the endian member of the image structure.
5457 % The format of the WriteBlobShort method is:
5459 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
5461 % A description of each parameter follows.
5463 % o image: the image.
5465 % o value: Specifies the value to write.
5468 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
5473 assert(image != (Image *) NULL);
5474 assert(image->signature == MagickCoreSignature);
5475 if (image->endian == LSBEndian)
5477 buffer[0]=(unsigned char) value;
5478 buffer[1]=(unsigned char) (value >> 8);
5479 return(WriteBlobStream(image,2,buffer));
5481 buffer[0]=(unsigned char) (value >> 8);
5482 buffer[1]=(unsigned char) value;
5483 return(WriteBlobStream(image,2,buffer));
5487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5491 + W r i t e B l o b L S B L o n g %
5495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5497 % WriteBlobLSBLong() writes a unsigned int value as a 32-bit quantity in
5498 % least-significant byte first order.
5500 % The format of the WriteBlobLSBLong method is:
5502 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5504 % A description of each parameter follows.
5506 % o image: the image.
5508 % o value: Specifies the value to write.
5511 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5516 assert(image != (Image *) NULL);
5517 assert(image->signature == MagickCoreSignature);
5518 buffer[0]=(unsigned char) value;
5519 buffer[1]=(unsigned char) (value >> 8);
5520 buffer[2]=(unsigned char) (value >> 16);
5521 buffer[3]=(unsigned char) (value >> 24);
5522 return(WriteBlobStream(image,4,buffer));
5526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5530 + W r i t e B l o b L S B S h o r t %
5534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5536 % WriteBlobLSBShort() writes a unsigned short value as a 16-bit quantity in
5537 % least-significant byte first order.
5539 % The format of the WriteBlobLSBShort method is:
5541 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5543 % A description of each parameter follows.
5545 % o image: the image.
5547 % o value: Specifies the value to write.
5550 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5555 assert(image != (Image *) NULL);
5556 assert(image->signature == MagickCoreSignature);
5557 buffer[0]=(unsigned char) value;
5558 buffer[1]=(unsigned char) (value >> 8);
5559 return(WriteBlobStream(image,2,buffer));
5563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5567 + W r i t e B l o b L S B S i g n e d L o n g %
5571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5573 % WriteBlobLSBSignedLong() writes a signed value as a 32-bit quantity in
5574 % least-significant byte first order.
5576 % The format of the WriteBlobLSBSignedLong method is:
5578 % ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5580 % A description of each parameter follows.
5582 % o image: the image.
5584 % o value: Specifies the value to write.
5587 MagickExport ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5601 assert(image != (Image *) NULL);
5602 assert(image->signature == MagickCoreSignature);
5603 quantum.signed_value=value;
5604 buffer[0]=(unsigned char) quantum.unsigned_value;
5605 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5606 buffer[2]=(unsigned char) (quantum.unsigned_value >> 16);
5607 buffer[3]=(unsigned char) (quantum.unsigned_value >> 24);
5608 return(WriteBlobStream(image,4,buffer));
5612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5616 + W r i t e B l o b L S B S i g n e d S h o r t %
5620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5622 % WriteBlobLSBSignedShort() writes a signed short value as a 16-bit quantity
5623 % in least-significant byte first order.
5625 % The format of the WriteBlobLSBSignedShort method is:
5627 % ssize_t WriteBlobLSBSignedShort(Image *image,const signed short value)
5629 % A description of each parameter follows.
5631 % o image: the image.
5633 % o value: Specifies the value to write.
5636 MagickExport ssize_t WriteBlobLSBSignedShort(Image *image,
5637 const signed short value)
5651 assert(image != (Image *) NULL);
5652 assert(image->signature == MagickCoreSignature);
5653 quantum.signed_value=value;
5654 buffer[0]=(unsigned char) quantum.unsigned_value;
5655 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5656 return(WriteBlobStream(image,2,buffer));
5660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5664 + W r i t e B l o b M S B L o n g %
5668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5670 % WriteBlobMSBLong() writes a unsigned int value as a 32-bit quantity in
5671 % most-significant byte first order.
5673 % The format of the WriteBlobMSBLong method is:
5675 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5677 % A description of each parameter follows.
5679 % o value: Specifies the value to write.
5681 % o image: the image.
5684 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5689 assert(image != (Image *) NULL);
5690 assert(image->signature == MagickCoreSignature);
5691 buffer[0]=(unsigned char) (value >> 24);
5692 buffer[1]=(unsigned char) (value >> 16);
5693 buffer[2]=(unsigned char) (value >> 8);
5694 buffer[3]=(unsigned char) value;
5695 return(WriteBlobStream(image,4,buffer));
5699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5703 + W r i t e B l o b M S B L o n g L o n g %
5707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5709 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
5710 % most-significant byte first order.
5712 % The format of the WriteBlobMSBLongLong method is:
5714 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
5716 % A description of each parameter follows.
5718 % o value: Specifies the value to write.
5720 % o image: the image.
5723 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
5724 const MagickSizeType value)
5729 assert(image != (Image *) NULL);
5730 assert(image->signature == MagickCoreSignature);
5731 buffer[0]=(unsigned char) (value >> 56);
5732 buffer[1]=(unsigned char) (value >> 48);
5733 buffer[2]=(unsigned char) (value >> 40);
5734 buffer[3]=(unsigned char) (value >> 32);
5735 buffer[4]=(unsigned char) (value >> 24);
5736 buffer[5]=(unsigned char) (value >> 16);
5737 buffer[6]=(unsigned char) (value >> 8);
5738 buffer[7]=(unsigned char) value;
5739 return(WriteBlobStream(image,8,buffer));
5743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5747 + W r i t e B l o b M S B S i g n e d L o n g %
5751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5753 % WriteBlobMSBSignedLong() writes a signed value as a 32-bit quantity in
5754 % most-significant byte first order.
5756 % The format of the WriteBlobMSBSignedLong method is:
5758 % ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5760 % A description of each parameter follows.
5762 % o image: the image.
5764 % o value: Specifies the value to write.
5767 MagickExport ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5781 assert(image != (Image *) NULL);
5782 assert(image->signature == MagickCoreSignature);
5783 quantum.signed_value=value;
5784 buffer[0]=(unsigned char) (quantum.unsigned_value >> 24);
5785 buffer[1]=(unsigned char) (quantum.unsigned_value >> 16);
5786 buffer[2]=(unsigned char) (quantum.unsigned_value >> 8);
5787 buffer[3]=(unsigned char) quantum.unsigned_value;
5788 return(WriteBlobStream(image,4,buffer));
5792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5796 + W r i t e B l o b M S B S i g n e d S h o r t %
5800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5802 % WriteBlobMSBSignedShort() writes a signed short value as a 16-bit quantity
5803 % in most-significant byte first order.
5805 % The format of the WriteBlobMSBSignedShort method is:
5807 % ssize_t WriteBlobMSBSignedShort(Image *image,const signed short value)
5809 % A description of each parameter follows.
5811 % o image: the image.
5813 % o value: Specifies the value to write.
5816 MagickExport ssize_t WriteBlobMSBSignedShort(Image *image,
5817 const signed short value)
5831 assert(image != (Image *) NULL);
5832 assert(image->signature == MagickCoreSignature);
5833 quantum.signed_value=value;
5834 buffer[0]=(unsigned char) (quantum.unsigned_value >> 8);
5835 buffer[1]=(unsigned char) quantum.unsigned_value;
5836 return(WriteBlobStream(image,2,buffer));
5840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5844 + W r i t e B l o b M S B S h o r t %
5848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5850 % WriteBlobMSBShort() writes a unsigned short value as a 16-bit quantity in
5851 % most-significant byte first order.
5853 % The format of the WriteBlobMSBShort method is:
5855 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5857 % A description of each parameter follows.
5859 % o value: Specifies the value to write.
5861 % o file: Specifies the file to write the data to.
5864 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5869 assert(image != (Image *) NULL);
5870 assert(image->signature == MagickCoreSignature);
5871 buffer[0]=(unsigned char) (value >> 8);
5872 buffer[1]=(unsigned char) value;
5873 return(WriteBlobStream(image,2,buffer));
5877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5881 + W r i t e B l o b S t r i n g %
5885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5887 % WriteBlobString() write a string to a blob. It returns the number of
5888 % characters written.
5890 % The format of the WriteBlobString method is:
5892 % ssize_t WriteBlobString(Image *image,const char *string)
5894 % A description of each parameter follows.
5896 % o image: the image.
5898 % o string: Specifies the string to write.
5901 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
5903 assert(image != (Image *) NULL);
5904 assert(image->signature == MagickCoreSignature);
5905 assert(string != (const char *) NULL);
5906 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));