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->reader != (CustomStreamHandler) NULL);
1770 assert(image_info->custom_stream->writer != (CustomStreamHandler) NULL);
1771 assert(exception != (ExceptionInfo *) NULL);
1772 blob_info=CloneImageInfo(image_info);
1773 blob_info->adjoin=MagickFalse;
1774 (void) SetImageInfo(blob_info,1,exception);
1775 if (*blob_info->magick != '\0')
1776 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1777 magick_info=GetMagickInfo(image->magick,exception);
1778 if (magick_info == (const MagickInfo *) NULL)
1780 (void) ThrowMagickException(exception,GetMagickModule(),
1781 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1783 blob_info=DestroyImageInfo(blob_info);
1786 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1787 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1790 Native blob support for this image format.
1792 (void) CloseBlob(image);
1793 *image->filename='\0';
1794 (void) WriteImage(blob_info,image,exception);
1795 (void) CloseBlob(image);
1800 unique[MagickPathExtent];
1809 Write file to disk in blob image format.
1811 blob_info->custom_stream=(CustomStreamInfo *) NULL;
1812 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
1814 if (blob == (unsigned char *) NULL)
1816 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1817 image_info->filename);
1818 blob_info=DestroyImageInfo(blob_info);
1821 file=AcquireUniqueFileResource(unique);
1824 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1825 image_info->filename);
1826 blob=(unsigned char *) RelinquishMagickMemory(blob);
1827 blob_info=DestroyImageInfo(blob_info);
1830 blob_info->file=fdopen(file,"wb+");
1831 if (blob_info->file != (FILE *) NULL)
1836 (void) FormatLocaleString(image->filename,MagickPathExtent,
1837 "%s:%s",image->magick,unique);
1838 status=WriteImage(blob_info,image,exception);
1839 (void) CloseBlob(image);
1840 if (status != MagickFalse)
1842 (void) fseek(blob_info->file,0,SEEK_SET);
1843 count=(ssize_t) MagickMaxBufferExtent;
1844 while (count == (ssize_t) MagickMaxBufferExtent)
1846 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
1848 image_info->custom_stream->writer(blob,count,
1849 image_info->custom_stream->data);
1852 (void) fclose(blob_info->file);
1854 blob=(unsigned char *) RelinquishMagickMemory(blob);
1855 (void) RelinquishUniqueFileResource(unique);
1857 blob_info=DestroyImageInfo(blob_info);
1861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1865 % I m a g e T o F i l e %
1869 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1871 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1872 % occurs otherwise MagickTrue.
1874 % The format of the ImageToFile method is:
1876 % MagickBooleanType ImageToFile(Image *image,char *filename,
1877 % ExceptionInfo *exception)
1879 % A description of each parameter follows:
1881 % o image: the image.
1883 % o filename: Write the image to this file.
1885 % o exception: return any errors or warnings in this structure.
1888 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1889 ExceptionInfo *exception)
1894 register const unsigned char
1913 assert(image != (Image *) NULL);
1914 assert(image->signature == MagickCoreSignature);
1915 assert(image->blob != (BlobInfo *) NULL);
1916 assert(image->blob->type != UndefinedStream);
1917 if (image->debug != MagickFalse)
1918 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1919 assert(filename != (const char *) NULL);
1920 if (*filename == '\0')
1921 file=AcquireUniqueFileResource(filename);
1923 if (LocaleCompare(filename,"-") == 0)
1924 file=fileno(stdout);
1926 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1929 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1930 return(MagickFalse);
1932 quantum=(size_t) MagickMaxBufferExtent;
1933 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1934 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1935 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1936 if (buffer == (unsigned char *) NULL)
1939 (void) ThrowMagickException(exception,GetMagickModule(),
1940 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1941 return(MagickFalse);
1944 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1945 for (i=0; count > 0; )
1947 length=(size_t) count;
1948 for (i=0; i < length; i+=count)
1950 count=write(file,p+i,(size_t) (length-i));
1960 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1962 if (LocaleCompare(filename,"-") != 0)
1964 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1965 if ((file == -1) || (i < length))
1969 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1970 return(MagickFalse);
1976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1980 % I m a g e s T o B l o b %
1984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1986 % ImagesToBlob() implements direct to memory image formats. It returns the
1987 % image sequence as a blob and its length. The magick member of the ImageInfo
1988 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1990 % Note, some image formats do not permit multiple images to the same image
1991 % stream (e.g. JPEG). in this instance, just the first image of the
1992 % sequence is returned as a blob.
1994 % The format of the ImagesToBlob method is:
1996 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1997 % size_t *length,ExceptionInfo *exception)
1999 % A description of each parameter follows:
2001 % o image_info: the image info.
2003 % o images: the image list.
2005 % o length: return the actual length of the blob.
2007 % o exception: return any errors or warnings in this structure.
2010 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
2011 size_t *length,ExceptionInfo *exception)
2025 assert(image_info != (const ImageInfo *) NULL);
2026 assert(image_info->signature == MagickCoreSignature);
2027 if (image_info->debug != MagickFalse)
2028 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2029 image_info->filename);
2030 assert(images != (Image *) NULL);
2031 assert(images->signature == MagickCoreSignature);
2032 assert(exception != (ExceptionInfo *) NULL);
2034 blob=(unsigned char *) NULL;
2035 blob_info=CloneImageInfo(image_info);
2036 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2038 if (*blob_info->magick != '\0')
2039 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2040 magick_info=GetMagickInfo(images->magick,exception);
2041 if (magick_info == (const MagickInfo *) NULL)
2043 (void) ThrowMagickException(exception,GetMagickModule(),
2044 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
2046 blob_info=DestroyImageInfo(blob_info);
2049 if (GetMagickAdjoin(magick_info) == MagickFalse)
2051 blob_info=DestroyImageInfo(blob_info);
2052 return(ImageToBlob(image_info,images,length,exception));
2054 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2055 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2058 Native blob support for this images format.
2060 blob_info->length=0;
2061 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
2062 sizeof(unsigned char));
2063 if (blob_info->blob == (void *) NULL)
2064 (void) ThrowMagickException(exception,GetMagickModule(),
2065 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
2068 (void) CloseBlob(images);
2069 images->blob->exempt=MagickTrue;
2070 *images->filename='\0';
2071 status=WriteImages(blob_info,images,images->filename,exception);
2072 *length=images->blob->length;
2073 blob=DetachBlob(images->blob);
2074 if (status == MagickFalse)
2075 blob=RelinquishMagickMemory(blob);
2077 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
2083 filename[MagickPathExtent],
2084 unique[MagickPathExtent];
2090 Write file to disk in blob images format.
2092 file=AcquireUniqueFileResource(unique);
2095 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
2096 image_info->filename);
2100 blob_info->file=fdopen(file,"wb");
2101 if (blob_info->file != (FILE *) NULL)
2103 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2104 images->magick,unique);
2105 status=WriteImages(blob_info,images,filename,exception);
2106 (void) CloseBlob(images);
2107 (void) fclose(blob_info->file);
2108 if (status != MagickFalse)
2109 blob=FileToBlob(unique,~0UL,length,exception);
2111 (void) RelinquishUniqueFileResource(unique);
2114 blob_info=DestroyImageInfo(blob_info);
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2123 + I m a g e s T o C u s t o m B l o b %
2127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2129 % ImagesToCustomStream() is the equivalent of WriteImages(), but writes the
2130 % formatted "file" to the custom stream rather than to an actual file.
2132 % The format of the ImageToCustomStream method is:
2134 % void ImagesToCustomStream(const ImageInfo *image_info,Image *images,
2135 % ExceptionInfo *exception)
2137 % A description of each parameter follows:
2139 % o image_info: the image info.
2141 % o images: the image list.
2143 % o exception: return any errors or warnings in this structure.
2146 MagickExport void ImagesToCustomStream(const ImageInfo *image_info,
2147 Image *images,ExceptionInfo *exception)
2158 assert(image_info != (const ImageInfo *) NULL);
2159 assert(image_info->signature == MagickCoreSignature);
2160 if (image_info->debug != MagickFalse)
2161 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2162 image_info->filename);
2163 assert(images != (Image *) NULL);
2164 assert(images->signature == MagickCoreSignature);
2165 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
2166 assert(image_info->custom_stream->signature == MagickCoreSignature);
2167 assert(image_info->custom_stream->reader != (CustomStreamHandler) NULL);
2168 assert(image_info->custom_stream->writer != (CustomStreamHandler) NULL);
2169 assert(exception != (ExceptionInfo *) NULL);
2170 blob_info=CloneImageInfo(image_info);
2171 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2173 if (*blob_info->magick != '\0')
2174 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2175 magick_info=GetMagickInfo(images->magick,exception);
2176 if (magick_info == (const MagickInfo *) NULL)
2178 (void) ThrowMagickException(exception,GetMagickModule(),
2179 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
2181 blob_info=DestroyImageInfo(blob_info);
2184 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2185 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2188 Native blob support for this image format.
2190 (void) CloseBlob(images);
2191 *images->filename='\0';
2192 (void) WriteImages(blob_info,images,images->filename,exception);
2193 (void) CloseBlob(images);
2198 filename[MagickPathExtent],
2199 unique[MagickPathExtent];
2208 Write file to disk in blob image format.
2210 blob_info->custom_stream=(CustomStreamInfo *) NULL;
2211 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
2213 if (blob == (unsigned char *) NULL)
2215 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2216 image_info->filename);
2217 blob_info=DestroyImageInfo(blob_info);
2220 file=AcquireUniqueFileResource(unique);
2223 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2224 image_info->filename);
2225 blob=(unsigned char *) RelinquishMagickMemory(blob);
2226 blob_info=DestroyImageInfo(blob_info);
2229 blob_info->file=fdopen(file,"wb+");
2230 if (blob_info->file != (FILE *) NULL)
2235 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2236 images->magick,unique);
2237 status=WriteImages(blob_info,images,filename,exception);
2238 (void) CloseBlob(images);
2239 if (status != MagickFalse)
2241 (void) fseek(blob_info->file,0,SEEK_SET);
2242 count=(ssize_t) MagickMaxBufferExtent;
2243 while (count == (ssize_t) MagickMaxBufferExtent)
2245 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
2247 image_info->custom_stream->writer(blob,count,
2248 image_info->custom_stream->data);
2251 (void) fclose(blob_info->file);
2253 blob=(unsigned char *) RelinquishMagickMemory(blob);
2254 (void) RelinquishUniqueFileResource(unique);
2256 blob_info=DestroyImageInfo(blob_info);
2261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2265 % I n j e c t I m a g e B l o b %
2269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2271 % InjectImageBlob() injects the image with a copy of itself in the specified
2272 % format (e.g. inject JPEG into a PDF image).
2274 % The format of the InjectImageBlob method is:
2276 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2277 % Image *image,Image *inject_image,const char *format,
2278 % ExceptionInfo *exception)
2280 % A description of each parameter follows:
2282 % o image_info: the image info..
2284 % o image: the image.
2286 % o inject_image: inject into the image stream.
2288 % o format: the image format.
2290 % o exception: return any errors or warnings in this structure.
2293 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2294 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
2297 filename[MagickPathExtent];
2330 Write inject image to a temporary file.
2332 assert(image_info != (ImageInfo *) NULL);
2333 assert(image_info->signature == MagickCoreSignature);
2334 assert(image != (Image *) NULL);
2335 assert(image->signature == MagickCoreSignature);
2336 if (image->debug != MagickFalse)
2337 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2338 assert(inject_image != (Image *) NULL);
2339 assert(inject_image->signature == MagickCoreSignature);
2340 assert(exception != (ExceptionInfo *) NULL);
2341 unique_file=(FILE *) NULL;
2342 file=AcquireUniqueFileResource(filename);
2344 unique_file=fdopen(file,"wb");
2345 if ((file == -1) || (unique_file == (FILE *) NULL))
2347 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2348 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
2350 return(MagickFalse);
2352 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
2353 if (byte_image == (Image *) NULL)
2355 (void) fclose(unique_file);
2356 (void) RelinquishUniqueFileResource(filename);
2357 return(MagickFalse);
2359 (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",
2361 DestroyBlob(byte_image);
2362 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
2363 write_info=CloneImageInfo(image_info);
2364 SetImageInfoFile(write_info,unique_file);
2365 status=WriteImage(write_info,byte_image,exception);
2366 write_info=DestroyImageInfo(write_info);
2367 byte_image=DestroyImage(byte_image);
2368 (void) fclose(unique_file);
2369 if (status == MagickFalse)
2371 (void) RelinquishUniqueFileResource(filename);
2372 return(MagickFalse);
2375 Inject into image stream.
2377 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
2380 (void) RelinquishUniqueFileResource(filename);
2381 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
2382 image_info->filename);
2383 return(MagickFalse);
2385 quantum=(size_t) MagickMaxBufferExtent;
2386 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
2387 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2388 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2389 if (buffer == (unsigned char *) NULL)
2391 (void) RelinquishUniqueFileResource(filename);
2393 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2396 for (i=0; ; i+=count)
2398 count=read(file,buffer,quantum);
2405 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2410 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2411 (void) RelinquishUniqueFileResource(filename);
2412 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2421 % I s B l o b E x e m p t %
2425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2427 % IsBlobExempt() returns true if the blob is exempt.
2429 % The format of the IsBlobExempt method is:
2431 % MagickBooleanType IsBlobExempt(const Image *image)
2433 % A description of each parameter follows:
2435 % o image: the image.
2438 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
2440 assert(image != (const Image *) NULL);
2441 assert(image->signature == MagickCoreSignature);
2442 if (image->debug != MagickFalse)
2443 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2444 return(image->blob->exempt);
2448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2452 % I s B l o b S e e k a b l e %
2456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2458 % IsBlobSeekable() returns true if the blob is seekable.
2460 % The format of the IsBlobSeekable method is:
2462 % MagickBooleanType IsBlobSeekable(const Image *image)
2464 % A description of each parameter follows:
2466 % o image: the image.
2469 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2474 assert(image != (const Image *) NULL);
2475 assert(image->signature == MagickCoreSignature);
2476 if (image->debug != MagickFalse)
2477 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2478 switch (image->blob->type)
2484 seekable=MagickTrue;
2487 case UndefinedStream:
2488 case StandardStream:
2494 seekable=MagickFalse;
2499 if ((image->blob->custom_stream->seeker != (CustomStreamSeeker) NULL) &&
2500 (image->blob->custom_stream->teller != (CustomStreamTeller) NULL))
2501 seekable=MagickTrue;
2503 seekable=MagickFalse;
2511 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2515 % I s B l o b T e m p o r a r y %
2519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2521 % IsBlobTemporary() returns true if the blob is temporary.
2523 % The format of the IsBlobTemporary method is:
2525 % MagickBooleanType IsBlobTemporary(const Image *image)
2527 % A description of each parameter follows:
2529 % o image: the image.
2532 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2534 assert(image != (const Image *) NULL);
2535 assert(image->signature == MagickCoreSignature);
2536 if (image->debug != MagickFalse)
2537 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2538 return(image->blob->temporary);
2542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2552 % MapBlob() creates a mapping from a file to a binary large object.
2554 % The format of the MapBlob method is:
2556 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2557 % const size_t length)
2559 % A description of each parameter follows:
2561 % o file: map this file descriptor.
2563 % o mode: ReadMode, WriteMode, or IOMode.
2565 % o offset: starting at this offset within the file.
2567 % o length: the length of the mapping is returned in this pointer.
2570 MagickExport void *MapBlob(int file,const MapMode mode,
2571 const MagickOffsetType offset,const size_t length)
2573 #if defined(MAGICKCORE_HAVE_MMAP)
2586 #if defined(MAP_ANONYMOUS)
2587 flags|=MAP_ANONYMOUS;
2596 protection=PROT_READ;
2602 protection=PROT_WRITE;
2608 protection=PROT_READ | PROT_WRITE;
2613 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2614 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2616 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2618 if (map == MAP_FAILED)
2619 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2621 if (map == MAP_FAILED)
2634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2638 + M S B O r d e r L o n g %
2642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2644 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2645 % most-significant byte first.
2647 % The format of the MSBOrderLong method is:
2649 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2651 % A description of each parameter follows.
2653 % o buffer: Specifies a pointer to a buffer of integers.
2655 % o length: Specifies the length of the buffer.
2658 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2663 register unsigned char
2667 assert(buffer != (unsigned char *) NULL);
2674 *buffer++=(unsigned char) c;
2678 *buffer++=(unsigned char) c;
2684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2688 + M S B O r d e r S h o r t %
2692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2694 % MSBOrderShort() converts a least-significant byte first buffer of integers
2695 % to most-significant byte first.
2697 % The format of the MSBOrderShort method is:
2699 % void MSBOrderShort(unsigned char *p,const size_t length)
2701 % A description of each parameter follows.
2703 % o p: Specifies a pointer to a buffer of integers.
2705 % o length: Specifies the length of the buffer.
2708 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2713 register unsigned char
2716 assert(p != (unsigned char *) NULL);
2723 *p++=(unsigned char) c;
2728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2738 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2739 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2740 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2741 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2742 % from a system command.
2744 % The format of the OpenBlob method is:
2746 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2747 % const BlobMode mode,ExceptionInfo *exception)
2749 % A description of each parameter follows:
2751 % o image_info: the image info.
2753 % o image: the image.
2755 % o mode: the mode for opening the file.
2759 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2772 option=GetImageOption(image_info,"stream:buffer-size");
2773 if (option != (const char *) NULL)
2774 size=StringToUnsignedLong(option);
2775 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2776 _IONBF : _IOFBF,size);
2777 return(status == 0 ? MagickTrue : MagickFalse);
2780 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2781 Image *image,const BlobMode mode,ExceptionInfo *exception)
2784 extension[MagickPathExtent],
2785 filename[MagickPathExtent];
2796 assert(image_info != (ImageInfo *) NULL);
2797 assert(image_info->signature == MagickCoreSignature);
2798 if (image_info->debug != MagickFalse)
2799 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2800 image_info->filename);
2801 assert(image != (Image *) NULL);
2802 assert(image->signature == MagickCoreSignature);
2803 if (image_info->blob != (void *) NULL)
2805 if (image_info->stream != (StreamHandler) NULL)
2806 image->blob->stream=(StreamHandler) image_info->stream;
2807 AttachBlob(image->blob,image_info->blob,image_info->length);
2810 if ((image_info->custom_stream != (CustomStreamInfo *) NULL) &&
2811 (*image->filename == '\0'))
2813 image->blob->type=CustomStream;
2814 image->blob->custom_stream=image_info->custom_stream;
2817 (void) DetachBlob(image->blob);
2820 default: type="r"; break;
2821 case ReadBlobMode: type="r"; break;
2822 case ReadBinaryBlobMode: type="rb"; break;
2823 case WriteBlobMode: type="w"; break;
2824 case WriteBinaryBlobMode: type="w+b"; break;
2825 case AppendBlobMode: type="a"; break;
2826 case AppendBinaryBlobMode: type="a+b"; break;
2829 image->blob->synchronize=image_info->synchronize;
2830 if (image_info->stream != (StreamHandler) NULL)
2832 image->blob->stream=image_info->stream;
2835 image->blob->type=FifoStream;
2843 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2844 rights=ReadPolicyRights;
2846 rights=WritePolicyRights;
2847 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2850 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2851 "NotAuthorized","`%s'",filename);
2852 return(MagickFalse);
2854 if ((LocaleCompare(filename,"-") == 0) ||
2855 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2857 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2858 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2859 if (strchr(type,'b') != (char *) NULL)
2860 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2862 image->blob->type=StandardStream;
2863 image->blob->exempt=MagickTrue;
2864 return(SetStreamBuffering(image_info,image));
2866 if (LocaleNCompare(filename,"fd:",3) == 0)
2869 fileMode[MagickPathExtent];
2873 image->blob->file_info.file=fdopen(StringToLong(filename+3),fileMode);
2874 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2875 if (strchr(type,'b') != (char *) NULL)
2876 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2878 image->blob->type=StandardStream;
2879 image->blob->exempt=MagickTrue;
2880 return(SetStreamBuffering(image_info,image));
2882 #if defined(MAGICKCORE_HAVE_POPEN) && defined(MAGICKCORE_PIPES_SUPPORT)
2883 if (*filename == '|')
2886 fileMode[MagickPathExtent],
2890 Pipe image to or from a system command.
2892 #if defined(SIGPIPE)
2894 (void) signal(SIGPIPE,SIG_IGN);
2898 sanitize_command=SanitizeString(filename+1);
2899 image->blob->file_info.file=(FILE *) popen_utf8(sanitize_command,
2901 sanitize_command=DestroyString(sanitize_command);
2902 if (image->blob->file_info.file == (FILE *) NULL)
2904 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2905 return(MagickFalse);
2907 image->blob->type=PipeStream;
2908 image->blob->exempt=MagickTrue;
2909 return(SetStreamBuffering(image_info,image));
2912 status=GetPathAttributes(filename,&image->blob->properties);
2913 #if defined(S_ISFIFO)
2914 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2916 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2917 if (image->blob->file_info.file == (FILE *) NULL)
2919 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2920 return(MagickFalse);
2922 image->blob->type=FileStream;
2923 image->blob->exempt=MagickTrue;
2924 return(SetStreamBuffering(image_info,image));
2927 GetPathComponent(image->filename,ExtensionPath,extension);
2930 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2931 if ((image_info->adjoin == MagickFalse) ||
2932 (strchr(filename,'%') != (char *) NULL))
2935 Form filename for multi-part images.
2937 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2938 image->scene,filename,exception);
2939 if ((LocaleCompare(filename,image->filename) == 0) &&
2940 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2941 (GetNextImageInList(image) != (Image *) NULL)))
2944 path[MagickPathExtent];
2946 GetPathComponent(image->filename,RootPath,path);
2947 if (*extension == '\0')
2948 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
2949 path,(double) image->scene);
2951 (void) FormatLocaleString(filename,MagickPathExtent,
2952 "%s-%.20g.%s",path,(double) image->scene,extension);
2954 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2955 #if defined(macintosh)
2956 SetApplicationType(filename,image_info->magick,'8BIM');
2960 if (image_info->file != (FILE *) NULL)
2962 image->blob->file_info.file=image_info->file;
2963 image->blob->type=FileStream;
2964 image->blob->exempt=MagickTrue;
2969 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2970 if (image->blob->file_info.file != (FILE *) NULL)
2978 image->blob->type=FileStream;
2979 (void) SetStreamBuffering(image_info,image);
2980 (void) ResetMagickMemory(magick,0,sizeof(magick));
2981 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2982 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2983 #if defined(MAGICKCORE_POSIX_SUPPORT)
2984 (void) fflush(image->blob->file_info.file);
2986 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2987 " read %.20g magic header bytes",(double) count);
2988 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2989 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2990 ((int) magick[2] == 0x08))
2992 if (image->blob->file_info.file != (FILE *) NULL)
2993 (void) fclose(image->blob->file_info.file);
2994 image->blob->file_info.file=(FILE *) NULL;
2995 image->blob->file_info.gzfile=gzopen(filename,type);
2996 if (image->blob->file_info.gzfile != (gzFile) NULL)
2997 image->blob->type=ZipStream;
3000 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3001 if (strncmp((char *) magick,"BZh",3) == 0)
3003 if (image->blob->file_info.file != (FILE *) NULL)
3004 (void) fclose(image->blob->file_info.file);
3005 image->blob->file_info.file=(FILE *) NULL;
3006 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3007 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3008 image->blob->type=BZipStream;
3011 if (image->blob->type == FileStream)
3022 sans_exception=AcquireExceptionInfo();
3023 magick_info=GetMagickInfo(image_info->magick,sans_exception);
3024 sans_exception=DestroyExceptionInfo(sans_exception);
3025 length=(size_t) image->blob->properties.st_size;
3026 if ((magick_info != (const MagickInfo *) NULL) &&
3027 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
3028 (length > MagickMaxBufferExtent) &&
3029 (AcquireMagickResource(MapResource,length) != MagickFalse))
3034 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
3036 if (blob == (void *) NULL)
3037 RelinquishMagickResource(MapResource,length);
3041 Format supports blobs-- use memory-mapped I/O.
3043 if (image_info->file != (FILE *) NULL)
3044 image->blob->exempt=MagickFalse;
3047 (void) fclose(image->blob->file_info.file);
3048 image->blob->file_info.file=(FILE *) NULL;
3050 AttachBlob(image->blob,blob,length);
3051 image->blob->mapped=MagickTrue;
3058 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3059 if ((LocaleCompare(extension,"Z") == 0) ||
3060 (LocaleCompare(extension,"gz") == 0) ||
3061 (LocaleCompare(extension,"wmz") == 0) ||
3062 (LocaleCompare(extension,"svgz") == 0))
3064 if (mode == WriteBinaryBlobMode)
3066 image->blob->file_info.gzfile=gzopen(filename,type);
3067 if (image->blob->file_info.gzfile != (gzFile) NULL)
3068 image->blob->type=ZipStream;
3072 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3073 if (LocaleCompare(extension,"bz2") == 0)
3075 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3076 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3077 image->blob->type=BZipStream;
3082 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
3083 if (image->blob->file_info.file != (FILE *) NULL)
3085 image->blob->type=FileStream;
3086 (void) SetStreamBuffering(image_info,image);
3089 image->blob->status=MagickFalse;
3090 if (image->blob->type != UndefinedStream)
3091 image->blob->size=GetBlobSize(image);
3094 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
3095 return(MagickFalse);
3101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3111 % PingBlob() returns all the attributes of an image or image sequence except
3112 % for the pixels. It is much faster and consumes far less memory than
3113 % BlobToImage(). On failure, a NULL image is returned and exception
3114 % describes the reason for the failure.
3116 % The format of the PingBlob method is:
3118 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
3119 % const size_t length,ExceptionInfo *exception)
3121 % A description of each parameter follows:
3123 % o image_info: the image info.
3125 % o blob: the address of a character stream in one of the image formats
3126 % understood by ImageMagick.
3128 % o length: This size_t integer reflects the length in bytes of the blob.
3130 % o exception: return any errors or warnings in this structure.
3134 #if defined(__cplusplus) || defined(c_plusplus)
3138 static size_t PingStream(const Image *magick_unused(image),
3139 const void *magick_unused(pixels),const size_t columns)
3141 magick_unreferenced(image);
3142 magick_unreferenced(pixels);
3146 #if defined(__cplusplus) || defined(c_plusplus)
3150 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
3151 const size_t length,ExceptionInfo *exception)
3159 assert(image_info != (ImageInfo *) NULL);
3160 assert(image_info->signature == MagickCoreSignature);
3161 if (image_info->debug != MagickFalse)
3162 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3163 image_info->filename);
3164 assert(exception != (ExceptionInfo *) NULL);
3165 if ((blob == (const void *) NULL) || (length == 0))
3167 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
3168 "UnrecognizedImageFormat","`%s'",image_info->magick);
3169 return((Image *) NULL);
3171 ping_info=CloneImageInfo(image_info);
3172 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
3173 if (ping_info->blob == (const void *) NULL)
3175 (void) ThrowMagickException(exception,GetMagickModule(),
3176 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
3177 return((Image *) NULL);
3179 (void) memcpy(ping_info->blob,blob,length);
3180 ping_info->length=length;
3181 ping_info->ping=MagickTrue;
3182 image=ReadStream(ping_info,&PingStream,exception);
3183 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
3184 ping_info=DestroyImageInfo(ping_info);
3189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3199 % ReadBlob() reads data from the blob or image file and returns it. It
3200 % returns the number of bytes read. If length is zero, ReadBlob() returns
3201 % zero and has no other results. If length is greater than SSIZE_MAX, the
3202 % result is unspecified.
3204 % The format of the ReadBlob method is:
3206 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
3208 % A description of each parameter follows:
3210 % o image: the image.
3212 % o length: Specifies an integer representing the number of bytes to read
3215 % o data: Specifies an area to place the information requested from the
3219 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
3224 register unsigned char
3230 assert(image != (Image *) NULL);
3231 assert(image->signature == MagickCoreSignature);
3232 assert(image->blob != (BlobInfo *) NULL);
3233 assert(image->blob->type != UndefinedStream);
3236 assert(data != (void *) NULL);
3238 q=(unsigned char *) data;
3239 switch (image->blob->type)
3241 case UndefinedStream:
3243 case StandardStream:
3251 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
3256 c=getc(image->blob->file_info.file);
3259 *q++=(unsigned char) c;
3264 c=getc(image->blob->file_info.file);
3267 *q++=(unsigned char) c;
3272 c=getc(image->blob->file_info.file);
3275 *q++=(unsigned char) c;
3280 c=getc(image->blob->file_info.file);
3283 *q++=(unsigned char) c;
3293 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3298 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
3299 (unsigned int) length);
3304 c=gzgetc(image->blob->file_info.gzfile);
3307 *q++=(unsigned char) c;
3312 c=gzgetc(image->blob->file_info.gzfile);
3315 *q++=(unsigned char) c;
3320 c=gzgetc(image->blob->file_info.gzfile);
3323 *q++=(unsigned char) c;
3328 c=gzgetc(image->blob->file_info.gzfile);
3331 *q++=(unsigned char) c;
3342 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3343 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
3351 register const unsigned char
3354 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3356 image->blob->eof=MagickTrue;
3359 p=image->blob->data+image->blob->offset;
3360 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
3361 image->blob->offset+=count;
3362 if (count != (ssize_t) length)
3363 image->blob->eof=MagickTrue;
3364 (void) memcpy(q,p,(size_t) count);
3369 count=image->blob->custom_stream->reader(q,length,
3370 image->blob->custom_stream->data);
3378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3382 + R e a d B l o b B y t e %
3386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3388 % ReadBlobByte() reads a single byte from the image file and returns it.
3390 % The format of the ReadBlobByte method is:
3392 % int ReadBlobByte(Image *image)
3394 % A description of each parameter follows.
3396 % o image: the image.
3399 MagickExport int ReadBlobByte(Image *image)
3401 register const unsigned char
3410 assert(image != (Image *) NULL);
3411 assert(image->signature == MagickCoreSignature);
3412 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3423 + R e a d B l o b D o u b l e %
3427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3429 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3430 % specified by the endian member of the image structure.
3432 % The format of the ReadBlobDouble method is:
3434 % double ReadBlobDouble(Image *image)
3436 % A description of each parameter follows.
3438 % o image: the image.
3441 MagickExport double ReadBlobDouble(Image *image)
3452 quantum.double_value=0.0;
3453 quantum.unsigned_value=ReadBlobLongLong(image);
3454 return(quantum.double_value);
3458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3462 + R e a d B l o b F l o a t %
3466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3468 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3469 % specified by the endian member of the image structure.
3471 % The format of the ReadBlobFloat method is:
3473 % float ReadBlobFloat(Image *image)
3475 % A description of each parameter follows.
3477 % o image: the image.
3480 MagickExport float ReadBlobFloat(Image *image)
3491 quantum.float_value=0.0;
3492 quantum.unsigned_value=ReadBlobLong(image);
3493 return(quantum.float_value);
3497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3501 + R e a d B l o b L o n g %
3505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3507 % ReadBlobLong() reads a unsigned int value as a 32-bit quantity in the
3508 % byte-order specified by the endian member of the image structure.
3510 % The format of the ReadBlobLong method is:
3512 % unsigned int ReadBlobLong(Image *image)
3514 % A description of each parameter follows.
3516 % o image: the image.
3519 MagickExport unsigned int ReadBlobLong(Image *image)
3521 register const unsigned char
3533 assert(image != (Image *) NULL);
3534 assert(image->signature == MagickCoreSignature);
3536 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3539 if (image->endian == LSBEndian)
3541 value=(unsigned int) (*p++);
3542 value|=(unsigned int) (*p++) << 8;
3543 value|=(unsigned int) (*p++) << 16;
3544 value|=(unsigned int) (*p++) << 24;
3545 return(value & 0xffffffff);
3547 value=(unsigned int) (*p++) << 24;
3548 value|=(unsigned int) (*p++) << 16;
3549 value|=(unsigned int) (*p++) << 8;
3550 value|=(unsigned int) (*p++);
3551 return(value & 0xffffffff);
3555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3559 + R e a d B l o b L o n g L o n g %
3563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3565 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3566 % byte-order specified by the endian member of the image structure.
3568 % The format of the ReadBlobLongLong method is:
3570 % MagickSizeType ReadBlobLongLong(Image *image)
3572 % A description of each parameter follows.
3574 % o image: the image.
3577 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3582 register const unsigned char
3591 assert(image != (Image *) NULL);
3592 assert(image->signature == MagickCoreSignature);
3594 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3596 return(MagickULLConstant(0));
3597 if (image->endian == LSBEndian)
3599 value=(MagickSizeType) (*p++);
3600 value|=(MagickSizeType) (*p++) << 8;
3601 value|=(MagickSizeType) (*p++) << 16;
3602 value|=(MagickSizeType) (*p++) << 24;
3603 value|=(MagickSizeType) (*p++) << 32;
3604 value|=(MagickSizeType) (*p++) << 40;
3605 value|=(MagickSizeType) (*p++) << 48;
3606 value|=(MagickSizeType) (*p++) << 56;
3607 return(value & MagickULLConstant(0xffffffffffffffff));
3609 value=(MagickSizeType) (*p++) << 56;
3610 value|=(MagickSizeType) (*p++) << 48;
3611 value|=(MagickSizeType) (*p++) << 40;
3612 value|=(MagickSizeType) (*p++) << 32;
3613 value|=(MagickSizeType) (*p++) << 24;
3614 value|=(MagickSizeType) (*p++) << 16;
3615 value|=(MagickSizeType) (*p++) << 8;
3616 value|=(MagickSizeType) (*p++);
3617 return(value & MagickULLConstant(0xffffffffffffffff));
3621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3625 + R e a d B l o b S h o r t %
3629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3631 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3632 % specified by the endian member of the image structure.
3634 % The format of the ReadBlobShort method is:
3636 % unsigned short ReadBlobShort(Image *image)
3638 % A description of each parameter follows.
3640 % o image: the image.
3643 MagickExport unsigned short ReadBlobShort(Image *image)
3645 register const unsigned char
3648 register unsigned short
3657 assert(image != (Image *) NULL);
3658 assert(image->signature == MagickCoreSignature);
3660 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3662 return((unsigned short) 0U);
3663 if (image->endian == LSBEndian)
3665 value=(unsigned short) (*p++);
3666 value|=(unsigned short) (*p++) << 8;
3669 value=(unsigned short) (*p++) << 8;
3670 value|=(unsigned short) (*p++);
3675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3679 + R e a d B l o b L S B L o n g %
3683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3685 % ReadBlobLSBLong() reads a unsigned int value as a 32-bit quantity in
3686 % least-significant byte first order.
3688 % The format of the ReadBlobLSBLong method is:
3690 % unsigned int ReadBlobLSBLong(Image *image)
3692 % A description of each parameter follows.
3694 % o image: the image.
3697 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3699 register const unsigned char
3702 register unsigned int
3711 assert(image != (Image *) NULL);
3712 assert(image->signature == MagickCoreSignature);
3714 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3717 value=(unsigned int) (*p++);
3718 value|=(unsigned int) (*p++) << 8;
3719 value|=(unsigned int) (*p++) << 16;
3720 value|=(unsigned int) (*p++) << 24;
3721 return(value & 0xffffffff);
3725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3729 + R e a d B l o b L S B S i g n e d L o n g %
3733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3735 % ReadBlobLSBSignedLong() reads a signed int value as a 32-bit quantity in
3736 % least-significant byte first order.
3738 % The format of the ReadBlobLSBSignedLong method is:
3740 % signed int ReadBlobLSBSignedLong(Image *image)
3742 % A description of each parameter follows.
3744 % o image: the image.
3747 MagickExport signed int ReadBlobLSBSignedLong(Image *image)
3758 quantum.unsigned_value=ReadBlobLSBLong(image);
3759 return(quantum.signed_value);
3763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3767 + R e a d B l o b L S B S h o r t %
3771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3773 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3774 % least-significant byte first order.
3776 % The format of the ReadBlobLSBShort method is:
3778 % unsigned short ReadBlobLSBShort(Image *image)
3780 % A description of each parameter follows.
3782 % o image: the image.
3785 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3787 register const unsigned char
3790 register unsigned short
3799 assert(image != (Image *) NULL);
3800 assert(image->signature == MagickCoreSignature);
3802 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3804 return((unsigned short) 0U);
3805 value=(unsigned int) (*p++);
3806 value|=(unsigned int) (*p++) << 8;
3807 return(value & 0xffff);
3811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3815 + R e a d B l o b L S B S i g n e d S h o r t %
3819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3821 % ReadBlobLSBSignedShort() reads a signed short value as a 16-bit quantity in
3822 % least-significant byte-order.
3824 % The format of the ReadBlobLSBSignedShort method is:
3826 % signed short ReadBlobLSBSignedShort(Image *image)
3828 % A description of each parameter follows.
3830 % o image: the image.
3833 MagickExport signed short ReadBlobLSBSignedShort(Image *image)
3844 quantum.unsigned_value=ReadBlobLSBShort(image);
3845 return(quantum.signed_value);
3849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3853 + R e a d B l o b M S B L o n g %
3857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3859 % ReadBlobMSBLong() reads a unsigned int value as a 32-bit quantity in
3860 % most-significant byte first order.
3862 % The format of the ReadBlobMSBLong method is:
3864 % unsigned int ReadBlobMSBLong(Image *image)
3866 % A description of each parameter follows.
3868 % o image: the image.
3871 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3873 register const unsigned char
3876 register unsigned int
3885 assert(image != (Image *) NULL);
3886 assert(image->signature == MagickCoreSignature);
3888 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3891 value=(unsigned int) (*p++) << 24;
3892 value|=(unsigned int) (*p++) << 16;
3893 value|=(unsigned int) (*p++) << 8;
3894 value|=(unsigned int) (*p++);
3899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3903 + R e a d B l o b M S B L o n g L o n g %
3907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3909 % ReadBlobMSBLongLong() reads a unsigned long long value as a 64-bit quantity
3910 % in most-significant byte first order.
3912 % The format of the ReadBlobMSBLongLong method is:
3914 % unsigned int ReadBlobMSBLongLong(Image *image)
3916 % A description of each parameter follows.
3918 % o image: the image.
3921 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3923 register const unsigned char
3926 register MagickSizeType
3935 assert(image != (Image *) NULL);
3936 assert(image->signature == MagickCoreSignature);
3938 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3940 return(MagickULLConstant(0));
3941 value=(MagickSizeType) (*p++) << 56;
3942 value|=(MagickSizeType) (*p++) << 48;
3943 value|=(MagickSizeType) (*p++) << 40;
3944 value|=(MagickSizeType) (*p++) << 32;
3945 value|=(MagickSizeType) (*p++) << 24;
3946 value|=(MagickSizeType) (*p++) << 16;
3947 value|=(MagickSizeType) (*p++) << 8;
3948 value|=(MagickSizeType) (*p++);
3949 return(value & MagickULLConstant(0xffffffffffffffff));
3953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3957 + R e a d B l o b M S B S h o r t %
3961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3963 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3964 % most-significant byte first order.
3966 % The format of the ReadBlobMSBShort method is:
3968 % unsigned short ReadBlobMSBShort(Image *image)
3970 % A description of each parameter follows.
3972 % o image: the image.
3975 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3977 register const unsigned char
3980 register unsigned short
3989 assert(image != (Image *) NULL);
3990 assert(image->signature == MagickCoreSignature);
3992 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3994 return((unsigned short) 0U);
3995 value=(unsigned short) (*p++) << 8;
3996 value|=(unsigned short) (*p++);
3997 return(value & 0xffff);
4001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4005 + R e a d B l o b M S B S i g n e d L o n g %
4009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4011 % ReadBlobMSBSignedLong() reads a signed int value as a 32-bit quantity in
4012 % most-significant byte-order.
4014 % The format of the ReadBlobMSBSignedLong method is:
4016 % signed int ReadBlobMSBSignedLong(Image *image)
4018 % A description of each parameter follows.
4020 % o image: the image.
4023 MagickExport signed int ReadBlobMSBSignedLong(Image *image)
4034 quantum.unsigned_value=ReadBlobMSBLong(image);
4035 return(quantum.signed_value);
4039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4043 + R e a d B l o b M S B S i g n e d S h o r t %
4047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4049 % ReadBlobMSBSignedShort() reads a signed short value as a 16-bit quantity in
4050 % most-significant byte-order.
4052 % The format of the ReadBlobMSBSignedShort method is:
4054 % signed short ReadBlobMSBSignedShort(Image *image)
4056 % A description of each parameter follows.
4058 % o image: the image.
4061 MagickExport signed short ReadBlobMSBSignedShort(Image *image)
4072 quantum.unsigned_value=ReadBlobMSBShort(image);
4073 return(quantum.signed_value);
4077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4081 + R e a d B l o b S i g n e d L o n g %
4085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4087 % ReadBlobSignedLong() reads a signed int value as a 32-bit quantity in the
4088 % byte-order specified by the endian member of the image structure.
4090 % The format of the ReadBlobSignedLong method is:
4092 % signed int ReadBlobSignedLong(Image *image)
4094 % A description of each parameter follows.
4096 % o image: the image.
4099 MagickExport signed int ReadBlobSignedLong(Image *image)
4110 quantum.unsigned_value=ReadBlobLong(image);
4111 return(quantum.signed_value);
4115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4119 + R e a d B l o b S i g n e d S h o r t %
4123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4125 % ReadBlobSignedShort() reads a signed short value as a 16-bit quantity in the
4126 % byte-order specified by the endian member of the image structure.
4128 % The format of the ReadBlobSignedShort method is:
4130 % signed short ReadBlobSignedShort(Image *image)
4132 % A description of each parameter follows.
4134 % o image: the image.
4137 MagickExport signed short ReadBlobSignedShort(Image *image)
4148 quantum.unsigned_value=ReadBlobShort(image);
4149 return(quantum.signed_value);
4153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4157 + R e a d B l o b S t r e a m %
4161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4163 % ReadBlobStream() reads data from the blob or image file and returns it. It
4164 % returns a pointer to the data buffer you supply or to the image memory
4165 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
4166 % returns a count of zero and has no other results. If length is greater than
4167 % SSIZE_MAX, the result is unspecified.
4169 % The format of the ReadBlobStream method is:
4171 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
4174 % A description of each parameter follows:
4176 % o image: the image.
4178 % o length: Specifies an integer representing the number of bytes to read
4181 % o count: returns the number of bytes read.
4183 % o data: Specifies an area to place the information requested from the
4187 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
4188 void *data,ssize_t *count)
4190 assert(image != (Image *) NULL);
4191 assert(image->signature == MagickCoreSignature);
4192 assert(image->blob != (BlobInfo *) NULL);
4193 assert(image->blob->type != UndefinedStream);
4194 assert(count != (ssize_t *) NULL);
4195 if (image->blob->type != BlobStream)
4197 assert(data != NULL);
4198 *count=ReadBlob(image,length,(unsigned char *) data);
4201 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4204 image->blob->eof=MagickTrue;
4207 data=image->blob->data+image->blob->offset;
4208 *count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
4209 image->blob->offset+=(*count);
4210 if (*count != (ssize_t) length)
4211 image->blob->eof=MagickTrue;
4216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4220 + R e a d B l o b S t r i n g %
4224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4226 % ReadBlobString() reads characters from a blob or file until a newline
4227 % character is read or an end-of-file condition is encountered.
4229 % The format of the ReadBlobString method is:
4231 % char *ReadBlobString(Image *image,char *string)
4233 % A description of each parameter follows:
4235 % o image: the image.
4237 % o string: the address of a character buffer.
4240 MagickExport char *ReadBlobString(Image *image,char *string)
4242 register const unsigned char
4254 assert(image != (Image *) NULL);
4255 assert(image->signature == MagickCoreSignature);
4256 for (i=0; i < (MagickPathExtent-1L); i++)
4258 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
4262 return((char *) NULL);
4265 string[i]=(char) (*p);
4266 if ((string[i] == '\r') || (string[i] == '\n'))
4269 if (string[i] == '\r')
4270 (void) ReadBlobStream(image,1,buffer,&count);
4276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4280 + R e f e r e n c e B l o b %
4284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4286 % ReferenceBlob() increments the reference count associated with the pixel
4287 % blob returning a pointer to the blob.
4289 % The format of the ReferenceBlob method is:
4291 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
4293 % A description of each parameter follows:
4295 % o blob_info: the blob_info.
4298 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
4300 assert(blob != (BlobInfo *) NULL);
4301 assert(blob->signature == MagickCoreSignature);
4302 if (blob->debug != MagickFalse)
4303 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4304 LockSemaphoreInfo(blob->semaphore);
4305 blob->reference_count++;
4306 UnlockSemaphoreInfo(blob->semaphore);
4311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4321 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
4322 % and returns the resulting offset.
4324 % The format of the SeekBlob method is:
4326 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
4329 % A description of each parameter follows:
4331 % o image: the image.
4333 % o offset: Specifies an integer representing the offset in bytes.
4335 % o whence: Specifies an integer representing how the offset is
4336 % treated relative to the beginning of the blob as follows:
4338 % SEEK_SET Set position equal to offset bytes.
4339 % SEEK_CUR Set position to current location plus offset.
4340 % SEEK_END Set position to EOF plus offset.
4343 MagickExport MagickOffsetType SeekBlob(Image *image,
4344 const MagickOffsetType offset,const int whence)
4346 assert(image != (Image *) NULL);
4347 assert(image->signature == MagickCoreSignature);
4348 if (image->debug != MagickFalse)
4349 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4350 assert(image->blob != (BlobInfo *) NULL);
4351 assert(image->blob->type != UndefinedStream);
4352 switch (image->blob->type)
4354 case UndefinedStream:
4356 case StandardStream:
4361 if ((offset < 0) && (whence == SEEK_SET))
4363 if (fseek(image->blob->file_info.file,offset,whence) < 0)
4365 image->blob->offset=TellBlob(image);
4370 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4371 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
4374 image->blob->offset=TellBlob(image);
4390 image->blob->offset=offset;
4395 if ((image->blob->offset+offset) < 0)
4397 image->blob->offset+=offset;
4402 if (((MagickOffsetType) image->blob->length+offset) < 0)
4404 image->blob->offset=image->blob->length+offset;
4408 if (image->blob->offset < (MagickOffsetType)
4409 ((off_t) image->blob->length))
4411 image->blob->eof=MagickFalse;
4414 if (image->blob->offset < (MagickOffsetType)
4415 ((off_t) image->blob->extent))
4417 if (image->blob->mapped != MagickFalse)
4419 image->blob->eof=MagickTrue;
4422 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
4423 image->blob->quantum<<=1;
4424 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4425 image->blob->extent+1,sizeof(*image->blob->data));
4426 (void) SyncBlob(image);
4427 if (image->blob->data == NULL)
4429 (void) DetachBlob(image->blob);
4436 if (image->blob->custom_stream->seeker == (CustomStreamSeeker) NULL)
4438 image->blob->offset=image->blob->custom_stream->seeker(offset,whence,
4439 image->blob->custom_stream->data);
4443 return(image->blob->offset);
4447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4451 + S e t B l o b E x e m p t %
4455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4457 % SetBlobExempt() sets the blob exempt status.
4459 % The format of the SetBlobExempt method is:
4461 % MagickBooleanType SetBlobExempt(const Image *image,
4462 % const MagickBooleanType exempt)
4464 % A description of each parameter follows:
4466 % o image: the image.
4468 % o exempt: Set to true if this blob is exempt from being closed.
4471 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
4473 assert(image != (const Image *) NULL);
4474 assert(image->signature == MagickCoreSignature);
4475 if (image->debug != MagickFalse)
4476 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4477 image->blob->exempt=exempt;
4481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4485 + S e t B l o b E x t e n t %
4489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4491 % SetBlobExtent() ensures enough space is allocated for the blob. If the
4492 % method is successful, subsequent writes to bytes in the specified range are
4493 % guaranteed not to fail.
4495 % The format of the SetBlobExtent method is:
4497 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
4499 % A description of each parameter follows:
4501 % o image: the image.
4503 % o extent: the blob maximum extent.
4506 MagickExport MagickBooleanType SetBlobExtent(Image *image,
4507 const MagickSizeType extent)
4509 assert(image != (Image *) NULL);
4510 assert(image->signature == MagickCoreSignature);
4511 if (image->debug != MagickFalse)
4512 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4513 assert(image->blob != (BlobInfo *) NULL);
4514 assert(image->blob->type != UndefinedStream);
4515 switch (image->blob->type)
4517 case UndefinedStream:
4519 case StandardStream:
4520 return(MagickFalse);
4529 if (extent != (MagickSizeType) ((off_t) extent))
4530 return(MagickFalse);
4531 offset=SeekBlob(image,0,SEEK_END);
4533 return(MagickFalse);
4534 if ((MagickSizeType) offset >= extent)
4536 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4539 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4540 image->blob->file_info.file);
4541 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4542 if (image->blob->synchronize != MagickFalse)
4547 file=fileno(image->blob->file_info.file);
4548 if ((file == -1) || (offset < 0))
4549 return(MagickFalse);
4550 (void) posix_fallocate(file,offset,extent-offset);
4553 offset=SeekBlob(image,offset,SEEK_SET);
4555 return(MagickFalse);
4560 return(MagickFalse);
4562 return(MagickFalse);
4564 return(MagickFalse);
4567 if (extent != (MagickSizeType) ((size_t) extent))
4568 return(MagickFalse);
4569 if (image->blob->mapped != MagickFalse)
4577 (void) UnmapBlob(image->blob->data,image->blob->length);
4578 RelinquishMagickResource(MapResource,image->blob->length);
4579 if (extent != (MagickSizeType) ((off_t) extent))
4580 return(MagickFalse);
4581 offset=SeekBlob(image,0,SEEK_END);
4583 return(MagickFalse);
4584 if ((MagickSizeType) offset >= extent)
4586 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4587 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4588 image->blob->file_info.file);
4589 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4590 if (image->blob->synchronize != MagickFalse)
4595 file=fileno(image->blob->file_info.file);
4596 if ((file == -1) || (offset < 0))
4597 return(MagickFalse);
4598 (void) posix_fallocate(file,offset,extent-offset);
4601 offset=SeekBlob(image,offset,SEEK_SET);
4603 return(MagickFalse);
4604 (void) AcquireMagickResource(MapResource,extent);
4605 image->blob->data=(unsigned char*) MapBlob(fileno(
4606 image->blob->file_info.file),WriteMode,0,(size_t) extent);
4607 image->blob->extent=(size_t) extent;
4608 image->blob->length=(size_t) extent;
4609 (void) SyncBlob(image);
4612 image->blob->extent=(size_t) extent;
4613 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4614 image->blob->extent+1,sizeof(*image->blob->data));
4615 (void) SyncBlob(image);
4616 if (image->blob->data == (unsigned char *) NULL)
4618 (void) DetachBlob(image->blob);
4619 return(MagickFalse);
4630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4634 + S e t C u s t o m S t r e a m D a t a %
4638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4640 % SetCustomStreamData() sets the stream info data member.
4642 % The format of the SetCustomStreamData method is:
4644 % void SetCustomStreamData(CustomStreamInfo *custom_stream,void *)
4646 % A description of each parameter follows:
4648 % o custom_stream: your custom stream.
4650 % o void: your data.
4653 MagickExport void SetCustomStreamData(CustomStreamInfo *custom_stream,
4656 assert(custom_stream != (CustomStreamInfo *) NULL);
4657 assert(custom_stream->signature == MagickCoreSignature);
4658 custom_stream->data=data;
4662 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4666 + S e t C u s t o m S t r e a m R e a d e r %
4670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4672 % SetCustomStreamReader() sets the stream info reader member.
4674 % The format of the SetCustomStreamReader method is:
4676 % void SetCustomStreamReader(CustomStreamInfo *custom_stream,
4677 % CustomStreamHandler reader)
4679 % A description of each parameter follows:
4681 % o custom_stream: your custom stream.
4683 % o reader: your custom stream reader.
4686 MagickExport void SetCustomStreamReader(CustomStreamInfo *custom_stream,
4687 CustomStreamHandler reader)
4689 assert(custom_stream != (CustomStreamInfo *) NULL);
4690 assert(custom_stream->signature == MagickCoreSignature);
4691 custom_stream->reader=reader;
4695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4699 + S e t C u s t o m S t r e a m S e e k e r %
4703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4705 % SetCustomStreamSeeker() sets the stream info seeker member.
4707 % The format of the SetCustomStreamReader method is:
4709 % void SetCustomStreamSeeker(CustomStreamInfo *custom_stream,
4710 % CustomStreamSeeker seeker)
4712 % A description of each parameter follows:
4714 % o custom_stream: your custom stream.
4716 % o seeker: your custom stream seeker.
4719 MagickExport void SetCustomStreamSeeker(CustomStreamInfo *custom_stream,
4720 CustomStreamSeeker seeker)
4722 assert(custom_stream != (CustomStreamInfo *) NULL);
4723 assert(custom_stream->signature == MagickCoreSignature);
4724 custom_stream->seeker=seeker;
4728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4732 + S e t C u s t o m S t r e a m T e l l e r %
4736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4738 % SetCustomStreamTeller() sets the stream info teller member.
4740 % The format of the SetCustomStreamTeller method is:
4742 % void SetCustomStreamTeller(CustomStreamInfo *custom_stream,
4743 % CustomStreamTeller *teller)
4745 % A description of each parameter follows:
4747 % o custom_stream: your custom stream.
4749 % o teller: your custom stream teller.
4752 MagickExport void SetCustomStreamTeller(CustomStreamInfo *custom_stream,
4753 CustomStreamTeller teller)
4755 assert(custom_stream != (CustomStreamInfo *) NULL);
4756 assert(custom_stream->signature == MagickCoreSignature);
4757 custom_stream->teller=teller;
4761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4765 + S e t C u s t o m S t r e a m W r i t e r %
4769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4771 % SetCustomStreamWriter() sets the stream info writer member.
4773 % The format of the SetCustomStreamWriter method is:
4775 % void SetCustomStreamWriter(CustomStreamInfo *custom_stream,
4776 % CustomStreamHandler *writer)
4778 % A description of each parameter follows:
4780 % o custom_stream: your custom stream.
4782 % o writer: your custom stream writer.
4785 MagickExport void SetCustomStreamWriter(CustomStreamInfo *custom_stream,
4786 CustomStreamHandler writer)
4788 assert(custom_stream != (CustomStreamInfo *) NULL);
4789 assert(custom_stream->signature == MagickCoreSignature);
4790 custom_stream->writer=writer;
4794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4804 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
4805 % attributes if it is an blob.
4807 % The format of the SyncBlob method is:
4809 % int SyncBlob(Image *image)
4811 % A description of each parameter follows:
4813 % o image: the image.
4816 static int SyncBlob(Image *image)
4821 assert(image != (Image *) NULL);
4822 assert(image->signature == MagickCoreSignature);
4823 if (image->debug != MagickFalse)
4824 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4825 assert(image->blob != (BlobInfo *) NULL);
4826 assert(image->blob->type != UndefinedStream);
4828 switch (image->blob->type)
4830 case UndefinedStream:
4831 case StandardStream:
4836 status=fflush(image->blob->file_info.file);
4841 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4842 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
4848 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4849 status=BZ2_bzflush(image->blob->file_info.bzfile);
4864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4874 % TellBlob() obtains the current value of the blob or file position.
4876 % The format of the TellBlob method is:
4878 % MagickOffsetType TellBlob(const Image *image)
4880 % A description of each parameter follows:
4882 % o image: the image.
4885 MagickExport MagickOffsetType TellBlob(const Image *image)
4890 assert(image != (Image *) NULL);
4891 assert(image->signature == MagickCoreSignature);
4892 if (image->debug != MagickFalse)
4893 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4894 assert(image->blob != (BlobInfo *) NULL);
4895 assert(image->blob->type != UndefinedStream);
4897 switch (image->blob->type)
4899 case UndefinedStream:
4900 case StandardStream:
4904 offset=ftell(image->blob->file_info.file);
4911 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4912 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
4922 offset=image->blob->offset;
4927 if (image->blob->custom_stream->teller != (CustomStreamTeller) NULL)
4928 offset=image->blob->custom_stream->teller(image->blob->custom_stream->data);
4936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4940 + U n m a p B l o b %
4944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4946 % UnmapBlob() deallocates the binary large object previously allocated with
4947 % the MapBlob method.
4949 % The format of the UnmapBlob method is:
4951 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4953 % A description of each parameter follows:
4955 % o map: the address of the binary large object.
4957 % o length: the length of the binary large object.
4960 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4962 #if defined(MAGICKCORE_HAVE_MMAP)
4966 status=munmap(map,length);
4967 return(status == -1 ? MagickFalse : MagickTrue);
4971 return(MagickFalse);
4976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4980 % C u s t o m S t r e a m T o I m a g e %
4984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4986 % CustomStreamToImage() is the equivalent of ReadImage(), but reads the
4987 % formatted "file" from the suplied method rather than to an actual file.
4989 % The format of the CustomStreamToImage method is:
4991 % Image *CustomStreamToImage(const ImageInfo *image_info,
4992 % ExceptionInfo *exception)
4994 % A description of each parameter follows:
4996 % o image_info: the image info.
4998 % o exception: return any errors or warnings in this structure.
5001 MagickExport Image *CustomStreamToImage(const ImageInfo *image_info,
5002 ExceptionInfo *exception)
5013 assert(image_info != (ImageInfo *) NULL);
5014 assert(image_info->signature == MagickCoreSignature);
5015 if (image_info->debug != MagickFalse)
5016 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
5017 image_info->filename);
5018 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
5019 assert(image_info->custom_stream->signature == MagickCoreSignature);
5020 assert(image_info->custom_stream->reader != (CustomStreamHandler) NULL);
5021 assert(exception != (ExceptionInfo *) NULL);
5022 blob_info=CloneImageInfo(image_info);
5023 if (*blob_info->magick == '\0')
5024 (void) SetImageInfo(blob_info,0,exception);
5025 magick_info=GetMagickInfo(blob_info->magick,exception);
5026 if (magick_info == (const MagickInfo *) NULL)
5028 (void) ThrowMagickException(exception,GetMagickModule(),
5029 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
5031 blob_info=DestroyImageInfo(blob_info);
5032 return((Image *) NULL);
5034 image=(Image *) NULL;
5035 if ((GetMagickBlobSupport(magick_info) != MagickFalse) ||
5036 (blob_info->custom_stream == (CustomStreamInfo *) NULL))
5039 Native blob support for this image format or SetImageInfo changed the
5042 image=ReadImage(blob_info,exception);
5043 if (image != (Image *) NULL)
5044 (void) CloseBlob(image);
5049 unique[MagickPathExtent];
5061 Write data to file on disk.
5063 blob_info->custom_stream=(CustomStreamInfo *) NULL;
5064 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
5066 if (blob == (unsigned char *) NULL)
5068 ThrowFileException(exception,BlobError,"UnableToReadBlob",
5069 image_info->filename);
5070 blob_info=DestroyImageInfo(blob_info);
5071 return((Image *) NULL);
5073 file=AcquireUniqueFileResource(unique);
5076 ThrowFileException(exception,BlobError,"UnableToReadBlob",
5077 image_info->filename);
5078 blob=(unsigned char *) RelinquishMagickMemory(blob);
5079 blob_info=DestroyImageInfo(blob_info);
5080 return((Image *) NULL);
5082 clone_info=CloneImageInfo(blob_info);
5083 blob_info->file=fdopen(file,"wb+");
5084 if (blob_info->file != (FILE *) NULL)
5089 count=(ssize_t) MagickMaxBufferExtent;
5090 while (count == (ssize_t) MagickMaxBufferExtent)
5092 count=image_info->custom_stream->reader(blob,MagickMaxBufferExtent,
5093 image_info->custom_stream->data);
5094 count=(ssize_t) write(file,(const char *) blob,count);
5096 (void) fclose(blob_info->file);
5097 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,
5098 "%s:%s",blob_info->magick,unique);
5099 image=ReadImage(clone_info,exception);
5100 if (image != (Image *) NULL)
5106 Restore original filenames and image format.
5108 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
5110 (void) CopyMagickString(images->filename,image_info->filename,
5112 (void) CopyMagickString(images->magick_filename,
5113 image_info->filename,MagickPathExtent);
5114 (void) CopyMagickString(images->magick,magick_info->name,
5116 (void) CloseBlob(images);
5117 images=GetNextImageInList(images);
5121 clone_info=DestroyImageInfo(clone_info);
5122 blob=(unsigned char *) RelinquishMagickMemory(blob);
5123 (void) RelinquishUniqueFileResource(unique);
5125 blob_info=DestroyImageInfo(blob_info);
5130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5134 + W r i t e B l o b %
5138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5140 % WriteBlob() writes data to a blob or image file. It returns the number of
5143 % The format of the WriteBlob method is:
5145 % ssize_t WriteBlob(Image *image,const size_t length,const void *data)
5147 % A description of each parameter follows:
5149 % o image: the image.
5151 % o length: Specifies an integer representing the number of bytes to
5152 % write to the file.
5154 % o data: The address of the data to write to the blob or file.
5157 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
5163 register const unsigned char
5169 assert(image != (Image *) NULL);
5170 assert(image->signature == MagickCoreSignature);
5171 assert(data != (const void *) NULL);
5172 assert(image->blob != (BlobInfo *) NULL);
5173 assert(image->blob->type != UndefinedStream);
5177 p=(const unsigned char *) data;
5178 switch (image->blob->type)
5180 case UndefinedStream:
5182 case StandardStream:
5190 count=(ssize_t) fwrite((const char *) data,1,length,
5191 image->blob->file_info.file);
5196 c=putc((int) *p++,image->blob->file_info.file);
5203 c=putc((int) *p++,image->blob->file_info.file);
5210 c=putc((int) *p++,image->blob->file_info.file);
5217 c=putc((int) *p++,image->blob->file_info.file);
5229 #if defined(MAGICKCORE_ZLIB_DELEGATE)
5234 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
5235 (unsigned int) length);
5240 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5247 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5254 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5261 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5274 #if defined(MAGICKCORE_BZLIB_DELEGATE)
5275 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
5282 count=(ssize_t) image->blob->stream(image,data,length);
5287 register unsigned char
5290 if ((image->blob->offset+(MagickOffsetType) length) >=
5291 (MagickOffsetType) image->blob->extent)
5293 if (image->blob->mapped != MagickFalse)
5295 image->blob->extent+=length+image->blob->quantum;
5296 image->blob->quantum<<=1;
5297 image->blob->data=(unsigned char *) ResizeQuantumMemory(
5298 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
5299 (void) SyncBlob(image);
5300 if (image->blob->data == (unsigned char *) NULL)
5302 (void) DetachBlob(image->blob);
5306 q=image->blob->data+image->blob->offset;
5307 (void) memcpy(q,p,length);
5308 image->blob->offset+=length;
5309 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
5310 image->blob->length=(size_t) image->blob->offset;
5311 count=(ssize_t) length;
5316 count=image->blob->custom_stream->writer((const unsigned char *) data,
5317 length,image->blob->custom_stream->data);
5325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5329 + W r i t e B l o b B y t e %
5333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5335 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
5336 % written (either 0 or 1);
5338 % The format of the WriteBlobByte method is:
5340 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
5342 % A description of each parameter follows.
5344 % o image: the image.
5346 % o value: Specifies the value to write.
5349 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
5351 assert(image != (Image *) NULL);
5352 assert(image->signature == MagickCoreSignature);
5353 return(WriteBlobStream(image,1,&value));
5357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5361 + W r i t e B l o b F l o a t %
5365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5367 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
5368 % specified by the endian member of the image structure.
5370 % The format of the WriteBlobFloat method is:
5372 % ssize_t WriteBlobFloat(Image *image,const float value)
5374 % A description of each parameter follows.
5376 % o image: the image.
5378 % o value: Specifies the value to write.
5381 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
5392 quantum.unsigned_value=0U;
5393 quantum.float_value=value;
5394 return(WriteBlobLong(image,quantum.unsigned_value));
5398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5402 + W r i t e B l o b L o n g %
5406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5408 % WriteBlobLong() writes a unsigned int value as a 32-bit quantity in the
5409 % byte-order specified by the endian member of the image structure.
5411 % The format of the WriteBlobLong method is:
5413 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
5415 % A description of each parameter follows.
5417 % o image: the image.
5419 % o value: Specifies the value to write.
5422 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
5427 assert(image != (Image *) NULL);
5428 assert(image->signature == MagickCoreSignature);
5429 if (image->endian == LSBEndian)
5431 buffer[0]=(unsigned char) value;
5432 buffer[1]=(unsigned char) (value >> 8);
5433 buffer[2]=(unsigned char) (value >> 16);
5434 buffer[3]=(unsigned char) (value >> 24);
5435 return(WriteBlobStream(image,4,buffer));
5437 buffer[0]=(unsigned char) (value >> 24);
5438 buffer[1]=(unsigned char) (value >> 16);
5439 buffer[2]=(unsigned char) (value >> 8);
5440 buffer[3]=(unsigned char) value;
5441 return(WriteBlobStream(image,4,buffer));
5445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5449 + W r i t e B l o b S h o r t %
5453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5455 % WriteBlobShort() writes a short value as a 16-bit quantity in the
5456 % byte-order specified by the endian member of the image structure.
5458 % The format of the WriteBlobShort method is:
5460 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
5462 % A description of each parameter follows.
5464 % o image: the image.
5466 % o value: Specifies the value to write.
5469 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
5474 assert(image != (Image *) NULL);
5475 assert(image->signature == MagickCoreSignature);
5476 if (image->endian == LSBEndian)
5478 buffer[0]=(unsigned char) value;
5479 buffer[1]=(unsigned char) (value >> 8);
5480 return(WriteBlobStream(image,2,buffer));
5482 buffer[0]=(unsigned char) (value >> 8);
5483 buffer[1]=(unsigned char) value;
5484 return(WriteBlobStream(image,2,buffer));
5488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5492 + W r i t e B l o b L S B L o n g %
5496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5498 % WriteBlobLSBLong() writes a unsigned int value as a 32-bit quantity in
5499 % least-significant byte first order.
5501 % The format of the WriteBlobLSBLong method is:
5503 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5505 % A description of each parameter follows.
5507 % o image: the image.
5509 % o value: Specifies the value to write.
5512 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5517 assert(image != (Image *) NULL);
5518 assert(image->signature == MagickCoreSignature);
5519 buffer[0]=(unsigned char) value;
5520 buffer[1]=(unsigned char) (value >> 8);
5521 buffer[2]=(unsigned char) (value >> 16);
5522 buffer[3]=(unsigned char) (value >> 24);
5523 return(WriteBlobStream(image,4,buffer));
5527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5531 + W r i t e B l o b L S B S h o r t %
5535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5537 % WriteBlobLSBShort() writes a unsigned short value as a 16-bit quantity in
5538 % least-significant byte first order.
5540 % The format of the WriteBlobLSBShort method is:
5542 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5544 % A description of each parameter follows.
5546 % o image: the image.
5548 % o value: Specifies the value to write.
5551 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5556 assert(image != (Image *) NULL);
5557 assert(image->signature == MagickCoreSignature);
5558 buffer[0]=(unsigned char) value;
5559 buffer[1]=(unsigned char) (value >> 8);
5560 return(WriteBlobStream(image,2,buffer));
5564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5568 + W r i t e B l o b L S B S i g n e d L o n g %
5572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5574 % WriteBlobLSBSignedLong() writes a signed value as a 32-bit quantity in
5575 % least-significant byte first order.
5577 % The format of the WriteBlobLSBSignedLong method is:
5579 % ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5581 % A description of each parameter follows.
5583 % o image: the image.
5585 % o value: Specifies the value to write.
5588 MagickExport ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5602 assert(image != (Image *) NULL);
5603 assert(image->signature == MagickCoreSignature);
5604 quantum.signed_value=value;
5605 buffer[0]=(unsigned char) quantum.unsigned_value;
5606 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5607 buffer[2]=(unsigned char) (quantum.unsigned_value >> 16);
5608 buffer[3]=(unsigned char) (quantum.unsigned_value >> 24);
5609 return(WriteBlobStream(image,4,buffer));
5613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5617 + W r i t e B l o b L S B S i g n e d S h o r t %
5621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5623 % WriteBlobLSBSignedShort() writes a signed short value as a 16-bit quantity
5624 % in least-significant byte first order.
5626 % The format of the WriteBlobLSBSignedShort method is:
5628 % ssize_t WriteBlobLSBSignedShort(Image *image,const signed short value)
5630 % A description of each parameter follows.
5632 % o image: the image.
5634 % o value: Specifies the value to write.
5637 MagickExport ssize_t WriteBlobLSBSignedShort(Image *image,
5638 const signed short value)
5652 assert(image != (Image *) NULL);
5653 assert(image->signature == MagickCoreSignature);
5654 quantum.signed_value=value;
5655 buffer[0]=(unsigned char) quantum.unsigned_value;
5656 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5657 return(WriteBlobStream(image,2,buffer));
5661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5665 + W r i t e B l o b M S B L o n g %
5669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5671 % WriteBlobMSBLong() writes a unsigned int value as a 32-bit quantity in
5672 % most-significant byte first order.
5674 % The format of the WriteBlobMSBLong method is:
5676 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5678 % A description of each parameter follows.
5680 % o value: Specifies the value to write.
5682 % o image: the image.
5685 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5690 assert(image != (Image *) NULL);
5691 assert(image->signature == MagickCoreSignature);
5692 buffer[0]=(unsigned char) (value >> 24);
5693 buffer[1]=(unsigned char) (value >> 16);
5694 buffer[2]=(unsigned char) (value >> 8);
5695 buffer[3]=(unsigned char) value;
5696 return(WriteBlobStream(image,4,buffer));
5700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5704 + W r i t e B l o b M S B L o n g L o n g %
5708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5710 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
5711 % most-significant byte first order.
5713 % The format of the WriteBlobMSBLongLong method is:
5715 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
5717 % A description of each parameter follows.
5719 % o value: Specifies the value to write.
5721 % o image: the image.
5724 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
5725 const MagickSizeType value)
5730 assert(image != (Image *) NULL);
5731 assert(image->signature == MagickCoreSignature);
5732 buffer[0]=(unsigned char) (value >> 56);
5733 buffer[1]=(unsigned char) (value >> 48);
5734 buffer[2]=(unsigned char) (value >> 40);
5735 buffer[3]=(unsigned char) (value >> 32);
5736 buffer[4]=(unsigned char) (value >> 24);
5737 buffer[5]=(unsigned char) (value >> 16);
5738 buffer[6]=(unsigned char) (value >> 8);
5739 buffer[7]=(unsigned char) value;
5740 return(WriteBlobStream(image,8,buffer));
5744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5748 + W r i t e B l o b M S B S i g n e d L o n g %
5752 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5754 % WriteBlobMSBSignedLong() writes a signed value as a 32-bit quantity in
5755 % most-significant byte first order.
5757 % The format of the WriteBlobMSBSignedLong method is:
5759 % ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5761 % A description of each parameter follows.
5763 % o image: the image.
5765 % o value: Specifies the value to write.
5768 MagickExport ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5782 assert(image != (Image *) NULL);
5783 assert(image->signature == MagickCoreSignature);
5784 quantum.signed_value=value;
5785 buffer[0]=(unsigned char) (quantum.unsigned_value >> 24);
5786 buffer[1]=(unsigned char) (quantum.unsigned_value >> 16);
5787 buffer[2]=(unsigned char) (quantum.unsigned_value >> 8);
5788 buffer[3]=(unsigned char) quantum.unsigned_value;
5789 return(WriteBlobStream(image,4,buffer));
5793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5797 + W r i t e B l o b M S B S i g n e d S h o r t %
5801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5803 % WriteBlobMSBSignedShort() writes a signed short value as a 16-bit quantity
5804 % in most-significant byte first order.
5806 % The format of the WriteBlobMSBSignedShort method is:
5808 % ssize_t WriteBlobMSBSignedShort(Image *image,const signed short value)
5810 % A description of each parameter follows.
5812 % o image: the image.
5814 % o value: Specifies the value to write.
5817 MagickExport ssize_t WriteBlobMSBSignedShort(Image *image,
5818 const signed short value)
5832 assert(image != (Image *) NULL);
5833 assert(image->signature == MagickCoreSignature);
5834 quantum.signed_value=value;
5835 buffer[0]=(unsigned char) (quantum.unsigned_value >> 8);
5836 buffer[1]=(unsigned char) quantum.unsigned_value;
5837 return(WriteBlobStream(image,2,buffer));
5841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5845 + W r i t e B l o b M S B S h o r t %
5849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5851 % WriteBlobMSBShort() writes a unsigned short value as a 16-bit quantity in
5852 % most-significant byte first order.
5854 % The format of the WriteBlobMSBShort method is:
5856 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5858 % A description of each parameter follows.
5860 % o value: Specifies the value to write.
5862 % o file: Specifies the file to write the data to.
5865 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5870 assert(image != (Image *) NULL);
5871 assert(image->signature == MagickCoreSignature);
5872 buffer[0]=(unsigned char) (value >> 8);
5873 buffer[1]=(unsigned char) value;
5874 return(WriteBlobStream(image,2,buffer));
5878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5882 + W r i t e B l o b S t r i n g %
5886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5888 % WriteBlobString() write a string to a blob. It returns the number of
5889 % characters written.
5891 % The format of the WriteBlobString method is:
5893 % ssize_t WriteBlobString(Image *image,const char *string)
5895 % A description of each parameter follows.
5897 % o image: the image.
5899 % o string: Specifies the string to write.
5902 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
5904 assert(image != (Image *) NULL);
5905 assert(image->signature == MagickCoreSignature);
5906 assert(string != (const char *) NULL);
5907 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));