2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 #include "MagickCore/studio.h"
48 #include "MagickCore/blob.h"
49 #include "MagickCore/blob-private.h"
50 #include "MagickCore/cache.h"
51 #include "MagickCore/client.h"
52 #include "MagickCore/constitute.h"
53 #include "MagickCore/delegate.h"
54 #include "MagickCore/exception.h"
55 #include "MagickCore/exception-private.h"
56 #include "MagickCore/image-private.h"
57 #include "MagickCore/list.h"
58 #include "MagickCore/locale_.h"
59 #include "MagickCore/log.h"
60 #include "MagickCore/magick.h"
61 #include "MagickCore/memory_.h"
62 #include "MagickCore/nt-base-private.h"
63 #include "MagickCore/option.h"
64 #include "MagickCore/policy.h"
65 #include "MagickCore/resource_.h"
66 #include "MagickCore/semaphore.h"
67 #include "MagickCore/string_.h"
68 #include "MagickCore/string-private.h"
69 #include "MagickCore/token.h"
70 #include "MagickCore/utility.h"
71 #include "MagickCore/utility-private.h"
72 #if defined(MAGICKCORE_ZLIB_DELEGATE)
75 #if defined(MAGICKCORE_BZLIB_DELEGATE)
82 #define MagickMaxBlobExtent (8*8192)
83 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
84 # define MAP_ANONYMOUS MAP_ANON
86 #if !defined(MAP_FAILED)
87 #define MAP_FAILED ((void *) -1)
91 #define _O_BINARY O_BINARY
97 typedef union FileInfo
102 #if defined(MAGICKCORE_ZLIB_DELEGATE)
107 #if defined(MAGICKCORE_BZLIB_DELEGATE)
166 Forward declarations.
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176 + A t t a c h B l o b %
180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 % AttachBlob() attaches a blob to the BlobInfo structure.
184 % The format of the AttachBlob method is:
186 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
188 % A description of each parameter follows:
190 % o blob_info: Specifies a pointer to a BlobInfo structure.
192 % o blob: the address of a character stream in one of the image formats
193 % understood by ImageMagick.
195 % o length: This size_t integer reflects the length in bytes of the blob.
198 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
201 assert(blob_info != (BlobInfo *) NULL);
202 if (blob_info->debug != MagickFalse)
203 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
204 blob_info->length=length;
205 blob_info->extent=length;
206 blob_info->quantum=(size_t) MagickMaxBlobExtent;
208 blob_info->type=BlobStream;
209 blob_info->file_info.file=(FILE *) NULL;
210 blob_info->data=(unsigned char *) blob;
211 blob_info->mapped=MagickFalse;
212 blob_info->immutable=MagickTrue;
216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 + B l o b T o F i l e %
224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
227 % occurs otherwise MagickTrue.
229 % The format of the BlobToFile method is:
231 % MagickBooleanType BlobToFile(char *filename,const void *blob,
232 % const size_t length,ExceptionInfo *exception)
234 % A description of each parameter follows:
236 % o filename: Write the blob to this file.
238 % o blob: the address of a blob.
240 % o length: This length in bytes of the blob.
242 % o exception: return any errors or warnings in this structure.
245 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
246 const size_t length,ExceptionInfo *exception)
257 assert(filename != (const char *) NULL);
258 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
259 assert(blob != (const void *) NULL);
260 if (*filename == '\0')
261 file=AcquireUniqueFileResource(filename);
263 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
266 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
269 for (i=0; i < length; i+=count)
271 count=write(file,(const char *) blob+i,MagickMin(length-i,SSIZE_MAX));
280 if ((file == -1) || (i < length))
282 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293 % B l o b T o I m a g e %
297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299 % BlobToImage() implements direct to memory image formats. It returns the
302 % The format of the BlobToImage method is:
304 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
305 % const size_t length,ExceptionInfo *exception)
307 % A description of each parameter follows:
309 % o image_info: the image info.
311 % o blob: the address of a character stream in one of the image formats
312 % understood by ImageMagick.
314 % o length: This size_t integer reflects the length in bytes of the blob.
316 % o exception: return any errors or warnings in this structure.
319 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
320 const size_t length,ExceptionInfo *exception)
335 assert(image_info != (ImageInfo *) NULL);
336 assert(image_info->signature == MagickCoreSignature);
337 if (image_info->debug != MagickFalse)
338 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
339 image_info->filename);
340 assert(exception != (ExceptionInfo *) NULL);
341 if ((blob == (const void *) NULL) || (length == 0))
343 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
344 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
345 return((Image *) NULL);
347 blob_info=CloneImageInfo(image_info);
348 blob_info->blob=(void *) blob;
349 blob_info->length=length;
350 if (*blob_info->magick == '\0')
351 (void) SetImageInfo(blob_info,0,exception);
352 magick_info=GetMagickInfo(blob_info->magick,exception);
353 if (magick_info == (const MagickInfo *) NULL)
355 (void) ThrowMagickException(exception,GetMagickModule(),
356 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
358 blob_info=DestroyImageInfo(blob_info);
359 return((Image *) NULL);
361 if (GetMagickBlobSupport(magick_info) != MagickFalse)
364 Native blob support for this image format.
366 (void) CopyMagickString(blob_info->filename,image_info->filename,
368 (void) CopyMagickString(blob_info->magick,image_info->magick,
370 image=ReadImage(blob_info,exception);
371 if (image != (Image *) NULL)
372 (void) DetachBlob(image->blob);
373 blob_info=DestroyImageInfo(blob_info);
377 Write blob to a temporary file on disk.
379 blob_info->blob=(void *) NULL;
381 *blob_info->filename='\0';
382 status=BlobToFile(blob_info->filename,blob,length,exception);
383 if (status == MagickFalse)
385 (void) RelinquishUniqueFileResource(blob_info->filename);
386 blob_info=DestroyImageInfo(blob_info);
387 return((Image *) NULL);
389 clone_info=CloneImageInfo(blob_info);
390 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,"%s:%s",
391 blob_info->magick,blob_info->filename);
392 image=ReadImage(clone_info,exception);
393 if (image != (Image *) NULL)
399 Restore original filenames and image format.
401 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
403 (void) CopyMagickString(images->filename,image_info->filename,
405 (void) CopyMagickString(images->magick_filename,image_info->filename,
407 (void) CopyMagickString(images->magick,magick_info->name,
409 images=GetNextImageInList(images);
412 clone_info=DestroyImageInfo(clone_info);
413 (void) RelinquishUniqueFileResource(blob_info->filename);
414 blob_info=DestroyImageInfo(blob_info);
419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423 + C l o n e B l o b I n f o %
427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
429 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
430 % blob info is NULL, a new one.
432 % The format of the CloneBlobInfo method is:
434 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
436 % A description of each parameter follows:
438 % o blob_info: the blob info.
441 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
446 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
447 if (clone_info == (BlobInfo *) NULL)
448 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
449 GetBlobInfo(clone_info);
450 if (blob_info == (BlobInfo *) NULL)
452 clone_info->length=blob_info->length;
453 clone_info->extent=blob_info->extent;
454 clone_info->synchronize=blob_info->synchronize;
455 clone_info->quantum=blob_info->quantum;
456 clone_info->mapped=blob_info->mapped;
457 clone_info->eof=blob_info->eof;
458 clone_info->offset=blob_info->offset;
459 clone_info->size=blob_info->size;
460 clone_info->exempt=blob_info->exempt;
461 clone_info->immutable=blob_info->immutable;
462 clone_info->status=blob_info->status;
463 clone_info->temporary=blob_info->temporary;
464 clone_info->type=blob_info->type;
465 clone_info->file_info.file=blob_info->file_info.file;
466 clone_info->properties=blob_info->properties;
467 clone_info->stream=blob_info->stream;
468 clone_info->data=blob_info->data;
469 clone_info->debug=IsEventLogging();
470 clone_info->reference_count=1;
475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
479 + C l o s e B l o b %
483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 % CloseBlob() closes a stream associated with the image.
487 % The format of the CloseBlob method is:
489 % MagickBooleanType CloseBlob(Image *image)
491 % A description of each parameter follows:
493 % o image: the image.
496 MagickExport MagickBooleanType CloseBlob(Image *image)
504 assert(image != (Image *) NULL);
505 assert(image->signature == MagickCoreSignature);
506 if (image->debug != MagickFalse)
507 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
508 assert(image->blob != (BlobInfo *) NULL);
509 if (image->blob->type == UndefinedStream)
511 status=SyncBlob(image);
512 switch (image->blob->type)
514 case UndefinedStream:
520 if (image->blob->synchronize != MagickFalse)
521 status=fsync(fileno(image->blob->file_info.file));
522 status=ferror(image->blob->file_info.file);
527 #if defined(MAGICKCORE_ZLIB_DELEGATE)
528 (void) gzerror(image->blob->file_info.gzfile,&status);
534 #if defined(MAGICKCORE_BZLIB_DELEGATE)
535 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
543 if ((image->blob->file_info.file != (FILE *) NULL) &&
544 (image->blob->synchronize != MagickFalse))
546 (void) fsync(fileno(image->blob->file_info.file));
547 status=ferror(image->blob->file_info.file);
552 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
553 image->blob->size=GetBlobSize(image);
554 image->extent=image->blob->size;
555 image->blob->eof=MagickFalse;
556 if (image->blob->exempt != MagickFalse)
558 image->blob->type=UndefinedStream;
559 return(image->blob->status);
561 switch (image->blob->type)
563 case UndefinedStream:
568 status=fclose(image->blob->file_info.file);
573 #if defined(MAGICKCORE_HAVE_PCLOSE)
574 status=pclose(image->blob->file_info.file);
580 #if defined(MAGICKCORE_ZLIB_DELEGATE)
581 status=gzclose(image->blob->file_info.gzfile);
587 #if defined(MAGICKCORE_BZLIB_DELEGATE)
588 BZ2_bzclose(image->blob->file_info.bzfile);
596 if (image->blob->file_info.file != (FILE *) NULL)
597 status=fclose(image->blob->file_info.file);
601 (void) DetachBlob(image->blob);
602 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
603 return(image->blob->status);
607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 + D e s t r o y B l o b %
615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 % DestroyBlob() deallocates memory associated with a blob.
619 % The format of the DestroyBlob method is:
621 % void DestroyBlob(Image *image)
623 % A description of each parameter follows:
625 % o image: the image.
628 MagickExport void DestroyBlob(Image *image)
633 assert(image != (Image *) NULL);
634 assert(image->signature == MagickCoreSignature);
635 if (image->debug != MagickFalse)
636 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
637 assert(image->blob != (BlobInfo *) NULL);
638 assert(image->blob->signature == MagickCoreSignature);
640 LockSemaphoreInfo(image->blob->semaphore);
641 image->blob->reference_count--;
642 assert(image->blob->reference_count >= 0);
643 if (image->blob->reference_count == 0)
645 UnlockSemaphoreInfo(image->blob->semaphore);
646 if (destroy == MagickFalse)
648 (void) CloseBlob(image);
649 if (image->blob->mapped != MagickFalse)
651 (void) UnmapBlob(image->blob->data,image->blob->length);
652 RelinquishMagickResource(MapResource,image->blob->length);
654 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
655 RelinquishSemaphoreInfo(&image->blob->semaphore);
656 image->blob->signature=(~MagickCoreSignature);
657 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665 + D e t a c h B l o b %
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 % DetachBlob() detaches a blob from the BlobInfo structure.
673 % The format of the DetachBlob method is:
675 % void *DetachBlob(BlobInfo *blob_info)
677 % A description of each parameter follows:
679 % o blob_info: Specifies a pointer to a BlobInfo structure.
682 MagickExport void *DetachBlob(BlobInfo *blob_info)
687 assert(blob_info != (BlobInfo *) NULL);
688 if (blob_info->debug != MagickFalse)
689 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
690 if (blob_info->mapped != MagickFalse)
692 (void) UnmapBlob(blob_info->data,blob_info->length);
693 blob_info->data=(unsigned char *) NULL;
694 RelinquishMagickResource(MapResource,blob_info->length);
696 blob_info->mapped=MagickFalse;
699 blob_info->eof=MagickFalse;
700 blob_info->exempt=MagickFalse;
701 blob_info->immutable=MagickFalse;
702 blob_info->type=UndefinedStream;
703 blob_info->file_info.file=(FILE *) NULL;
704 data=blob_info->data;
705 blob_info->data=(unsigned char *) NULL;
706 blob_info->stream=(StreamHandler) NULL;
711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715 + D i s a s s o c i a t e B l o b %
719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
721 % DisassociateBlob() disassociates the image stream. It checks if the
722 % blob of the specified image is referenced by other images. If the reference
723 % count is higher then 1 a new blob is assigned to the specified image.
725 % The format of the DisassociateBlob method is:
727 % void DisassociateBlob(const Image *image)
729 % A description of each parameter follows:
731 % o image: the image.
734 MagickPrivate void DisassociateBlob(Image *image)
742 assert(image != (Image *) NULL);
743 assert(image->signature == MagickCoreSignature);
744 if (image->debug != MagickFalse)
745 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
746 assert(image->blob != (BlobInfo *) NULL);
747 assert(image->blob->signature == MagickCoreSignature);
749 LockSemaphoreInfo(image->blob->semaphore);
750 assert(image->blob->reference_count >= 0);
751 if (image->blob->reference_count > 1)
753 UnlockSemaphoreInfo(image->blob->semaphore);
754 if (clone == MagickFalse)
756 blob=CloneBlobInfo(image->blob);
762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 + D i s c a r d B l o b B y t e s %
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
772 % DiscardBlobBytes() discards bytes in a blob.
774 % The format of the DiscardBlobBytes method is:
776 % MagickBooleanType DiscardBlobBytes(Image *image,
777 % const MagickSizeType length)
779 % A description of each parameter follows.
781 % o image: the image.
783 % o length: the number of bytes to skip.
786 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
787 const MagickSizeType length)
789 register MagickOffsetType
801 assert(image != (Image *) NULL);
802 assert(image->signature == MagickCoreSignature);
803 if (length != (MagickSizeType) ((MagickOffsetType) length))
806 for (i=0; i < (MagickOffsetType) length; i+=count)
808 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
809 (void) ReadBlobStream(image,quantum,buffer,&count);
817 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825 + D u p l i c a t e s B l o b %
829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831 % DuplicateBlob() duplicates a blob descriptor.
833 % The format of the DuplicateBlob method is:
835 % void DuplicateBlob(Image *image,const Image *duplicate)
837 % A description of each parameter follows:
839 % o image: the image.
841 % o duplicate: the duplicate image.
844 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
846 assert(image != (Image *) NULL);
847 assert(image->signature == MagickCoreSignature);
848 if (image->debug != MagickFalse)
849 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
850 assert(duplicate != (Image *) NULL);
851 assert(duplicate->signature == MagickCoreSignature);
853 image->blob=ReferenceBlob(duplicate->blob);
857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
867 % EOFBlob() returns a non-zero value when EOF has been detected reading from
870 % The format of the EOFBlob method is:
872 % int EOFBlob(const Image *image)
874 % A description of each parameter follows:
876 % o image: the image.
879 MagickExport int EOFBlob(const Image *image)
881 assert(image != (Image *) NULL);
882 assert(image->signature == MagickCoreSignature);
883 if (image->debug != MagickFalse)
884 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
885 assert(image->blob != (BlobInfo *) NULL);
886 assert(image->blob->type != UndefinedStream);
887 switch (image->blob->type)
889 case UndefinedStream:
895 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
901 image->blob->eof=MagickFalse;
906 #if defined(MAGICKCORE_BZLIB_DELEGATE)
911 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
912 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
918 image->blob->eof=MagickFalse;
924 return((int) image->blob->eof);
928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932 + F i l e T o B l o b %
936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
938 % FileToBlob() returns the contents of a file as a buffer terminated with
939 % the '\0' character. The length of the buffer (not including the extra
940 % terminating '\0' character) is returned via the 'length' parameter. Free
941 % the buffer with RelinquishMagickMemory().
943 % The format of the FileToBlob method is:
945 % void *FileToBlob(const char *filename,const size_t extent,
946 % size_t *length,ExceptionInfo *exception)
948 % A description of each parameter follows:
950 % o blob: FileToBlob() returns the contents of a file as a blob. If
951 % an error occurs NULL is returned.
953 % o filename: the filename.
955 % o extent: The maximum length of the blob.
957 % o length: On return, this reflects the actual length of the blob.
959 % o exception: return any errors or warnings in this structure.
962 MagickExport void *FileToBlob(const char *filename,const size_t extent,
963 size_t *length,ExceptionInfo *exception)
983 assert(filename != (const char *) NULL);
984 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
985 assert(exception != (ExceptionInfo *) NULL);
988 if (LocaleCompare(filename,"-") != 0)
989 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
992 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
995 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
997 if ((file == fileno(stdin)) || (offset < 0) ||
998 (offset != (MagickOffsetType) ((ssize_t) offset)))
1007 Stream is not seekable.
1009 offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
1010 quantum=(size_t) MagickMaxBufferExtent;
1011 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1012 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1013 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1014 for (i=0; blob != (unsigned char *) NULL; i+=count)
1016 count=read(file,blob+i,quantum);
1023 if (~((size_t) i) < (quantum+1))
1025 blob=(unsigned char *) RelinquishMagickMemory(blob);
1028 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
1030 if ((size_t) (i+count) >= extent)
1033 if (LocaleCompare(filename,"-") != 0)
1035 if (blob == (unsigned char *) NULL)
1037 (void) ThrowMagickException(exception,GetMagickModule(),
1038 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1043 blob=(unsigned char *) RelinquishMagickMemory(blob);
1044 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1047 *length=(size_t) MagickMin(i+count,extent);
1051 *length=(size_t) MagickMin(offset,extent);
1052 blob=(unsigned char *) NULL;
1053 if (~(*length) >= (MagickPathExtent-1))
1054 blob=(unsigned char *) AcquireQuantumMemory(*length+MagickPathExtent,
1056 if (blob == (unsigned char *) NULL)
1059 (void) ThrowMagickException(exception,GetMagickModule(),
1060 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1063 map=MapBlob(file,ReadMode,0,*length);
1064 if (map != (unsigned char *) NULL)
1066 (void) memcpy(blob,map,*length);
1067 (void) UnmapBlob(map,*length);
1071 (void) lseek(file,0,SEEK_SET);
1072 for (i=0; i < *length; i+=count)
1074 count=read(file,blob+i,(size_t) MagickMin(*length-i,SSIZE_MAX));
1085 blob=(unsigned char *) RelinquishMagickMemory(blob);
1086 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1091 if (LocaleCompare(filename,"-") != 0)
1095 blob=(unsigned char *) RelinquishMagickMemory(blob);
1096 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1106 % F i l e T o I m a g e %
1110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1112 % FileToImage() write the contents of a file to an image.
1114 % The format of the FileToImage method is:
1116 % MagickBooleanType FileToImage(Image *,const char *filename)
1118 % A description of each parameter follows:
1120 % o image: the image.
1122 % o filename: the filename.
1126 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1132 register unsigned char
1135 assert(image->blob != (BlobInfo *) NULL);
1136 assert(image->blob->type != UndefinedStream);
1137 assert(data != NULL);
1138 if (image->blob->type != BlobStream)
1139 return(WriteBlob(image,length,(const unsigned char *) data));
1140 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1141 if (extent >= image->blob->extent)
1143 extent=image->blob->extent+image->blob->quantum+length;
1144 image->blob->quantum<<=1;
1145 if (SetBlobExtent(image,extent) == MagickFalse)
1148 q=image->blob->data+image->blob->offset;
1149 (void) memcpy(q,data,length);
1150 image->blob->offset+=length;
1151 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1152 image->blob->length=(size_t) image->blob->offset;
1153 return((ssize_t) length);
1156 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1157 ExceptionInfo *exception)
1175 assert(image != (const Image *) NULL);
1176 assert(image->signature == MagickCoreSignature);
1177 assert(filename != (const char *) NULL);
1178 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1180 if (LocaleCompare(filename,"-") != 0)
1181 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1184 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1185 return(MagickFalse);
1187 quantum=(size_t) MagickMaxBufferExtent;
1188 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1189 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1190 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1191 if (blob == (unsigned char *) NULL)
1194 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1196 return(MagickFalse);
1200 count=read(file,blob,quantum);
1207 length=(size_t) count;
1208 count=WriteBlobStream(image,length,blob);
1209 if (count != (ssize_t) length)
1211 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1217 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1218 blob=(unsigned char *) RelinquishMagickMemory(blob);
1224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228 + G e t B l o b E r r o r %
1232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1234 % GetBlobError() returns MagickTrue if the blob associated with the specified
1235 % image encountered an error.
1237 % The format of the GetBlobError method is:
1239 % MagickBooleanType GetBlobError(const Image *image)
1241 % A description of each parameter follows:
1243 % o image: the image.
1246 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1248 assert(image != (const Image *) NULL);
1249 assert(image->signature == MagickCoreSignature);
1250 if (image->debug != MagickFalse)
1251 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1252 return(image->blob->status);
1256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1260 + G e t B l o b F i l e H a n d l e %
1264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1266 % GetBlobFileHandle() returns the file handle associated with the image blob.
1268 % The format of the GetBlobFile method is:
1270 % FILE *GetBlobFileHandle(const Image *image)
1272 % A description of each parameter follows:
1274 % o image: the image.
1277 MagickExport FILE *GetBlobFileHandle(const Image *image)
1279 assert(image != (const Image *) NULL);
1280 assert(image->signature == MagickCoreSignature);
1281 return(image->blob->file_info.file);
1285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1289 + G e t B l o b I n f o %
1293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1295 % GetBlobInfo() initializes the BlobInfo structure.
1297 % The format of the GetBlobInfo method is:
1299 % void GetBlobInfo(BlobInfo *blob_info)
1301 % A description of each parameter follows:
1303 % o blob_info: Specifies a pointer to a BlobInfo structure.
1306 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1308 assert(blob_info != (BlobInfo *) NULL);
1309 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1310 blob_info->type=UndefinedStream;
1311 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1312 blob_info->properties.st_mtime=time((time_t *) NULL);
1313 blob_info->properties.st_ctime=time((time_t *) NULL);
1314 blob_info->debug=IsEventLogging();
1315 blob_info->reference_count=1;
1316 blob_info->semaphore=AcquireSemaphoreInfo();
1317 blob_info->signature=MagickCoreSignature;
1321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1325 % G e t B l o b P r o p e r t i e s %
1329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1331 % GetBlobProperties() returns information about an image blob.
1333 % The format of the GetBlobProperties method is:
1335 % const struct stat *GetBlobProperties(const Image *image)
1337 % A description of each parameter follows:
1339 % o image: the image.
1342 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1344 assert(image != (Image *) NULL);
1345 assert(image->signature == MagickCoreSignature);
1346 if (image->debug != MagickFalse)
1347 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1348 return(&image->blob->properties);
1352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1356 + G e t B l o b S i z e %
1360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1362 % GetBlobSize() returns the current length of the image file or blob; zero is
1363 % returned if the size cannot be determined.
1365 % The format of the GetBlobSize method is:
1367 % MagickSizeType GetBlobSize(const Image *image)
1369 % A description of each parameter follows:
1371 % o image: the image.
1374 MagickExport MagickSizeType GetBlobSize(const Image *image)
1379 assert(image != (Image *) NULL);
1380 assert(image->signature == MagickCoreSignature);
1381 if (image->debug != MagickFalse)
1382 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1383 assert(image->blob != (BlobInfo *) NULL);
1385 switch (image->blob->type)
1387 case UndefinedStream:
1389 extent=image->blob->size;
1392 case StandardStream:
1394 extent=image->blob->size;
1399 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1400 extent=(MagickSizeType) image->blob->properties.st_size;
1405 extent=image->blob->size;
1414 status=GetPathAttributes(image->filename,&image->blob->properties);
1415 if (status != MagickFalse)
1416 extent=(MagickSizeType) image->blob->properties.st_size;
1423 extent=(MagickSizeType) image->blob->length;
1431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1435 + G e t B l o b S t r e a m D a t a %
1439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1441 % GetBlobStreamData() returns the stream data for the image.
1443 % The format of the GetBlobStreamData method is:
1445 % void *GetBlobStreamData(const Image *image)
1447 % A description of each parameter follows:
1449 % o image: the image.
1452 MagickExport void *GetBlobStreamData(const Image *image)
1454 assert(image != (const Image *) NULL);
1455 assert(image->signature == MagickCoreSignature);
1456 return(image->blob->data);
1460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1464 + G e t B l o b S t r e a m H a n d l e r %
1468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1470 % GetBlobStreamHandler() returns the stream handler for the image.
1472 % The format of the GetBlobStreamHandler method is:
1474 % StreamHandler GetBlobStreamHandler(const Image *image)
1476 % A description of each parameter follows:
1478 % o image: the image.
1481 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1483 assert(image != (const Image *) NULL);
1484 assert(image->signature == MagickCoreSignature);
1485 if (image->debug != MagickFalse)
1486 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1487 return(image->blob->stream);
1491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1495 % I m a g e T o B l o b %
1499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1501 % ImageToBlob() implements direct to memory image formats. It returns the
1502 % image as a formatted blob and its length. The magick member of the Image
1503 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1504 % etc.). This method is the equivalent of WriteImage(), but writes the
1505 % formatted "file" to a memory buffer rather than to an actual file.
1507 % The format of the ImageToBlob method is:
1509 % void *ImageToBlob(const ImageInfo *image_info,Image *image,
1510 % size_t *length,ExceptionInfo *exception)
1512 % A description of each parameter follows:
1514 % o image_info: the image info.
1516 % o image: the image.
1518 % o length: return the actual length of the blob.
1520 % o exception: return any errors or warnings in this structure.
1523 MagickExport void *ImageToBlob(const ImageInfo *image_info,
1524 Image *image,size_t *length,ExceptionInfo *exception)
1538 assert(image_info != (const ImageInfo *) NULL);
1539 assert(image_info->signature == MagickCoreSignature);
1540 if (image_info->debug != MagickFalse)
1541 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1542 image_info->filename);
1543 assert(image != (Image *) NULL);
1544 assert(image->signature == MagickCoreSignature);
1545 assert(exception != (ExceptionInfo *) NULL);
1547 blob=(unsigned char *) NULL;
1548 blob_info=CloneImageInfo(image_info);
1549 blob_info->adjoin=MagickFalse;
1550 (void) SetImageInfo(blob_info,1,exception);
1551 if (*blob_info->magick != '\0')
1552 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1553 magick_info=GetMagickInfo(image->magick,exception);
1554 if (magick_info == (const MagickInfo *) NULL)
1556 (void) ThrowMagickException(exception,GetMagickModule(),
1557 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1559 blob_info=DestroyImageInfo(blob_info);
1562 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1563 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1566 Native blob support for this image format.
1568 blob_info->length=0;
1569 blob_info->blob=AcquireQuantumMemory(MagickMaxBlobExtent,
1570 sizeof(unsigned char));
1571 if (blob_info->blob == NULL)
1572 (void) ThrowMagickException(exception,GetMagickModule(),
1573 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1576 (void) CloseBlob(image);
1577 image->blob->exempt=MagickTrue;
1578 *image->filename='\0';
1579 status=WriteImage(blob_info,image,exception);
1580 *length=image->blob->length;
1581 blob=DetachBlob(image->blob);
1582 if (status == MagickFalse)
1583 blob=RelinquishMagickMemory(blob);
1585 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1591 unique[MagickPathExtent];
1597 Write file to disk in blob image format.
1599 file=AcquireUniqueFileResource(unique);
1602 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1603 image_info->filename);
1607 blob_info->file=fdopen(file,"wb");
1608 if (blob_info->file != (FILE *) NULL)
1610 (void) FormatLocaleString(image->filename,MagickPathExtent,
1611 "%s:%s",image->magick,unique);
1612 status=WriteImage(blob_info,image,exception);
1613 (void) CloseBlob(image);
1614 (void) fclose(blob_info->file);
1615 if (status != MagickFalse)
1616 blob=FileToBlob(unique,~0UL,length,exception);
1618 (void) RelinquishUniqueFileResource(unique);
1621 blob_info=DestroyImageInfo(blob_info);
1626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1630 % I m a g e T o F i l e %
1634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1636 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1637 % occurs otherwise MagickTrue.
1639 % The format of the ImageToFile method is:
1641 % MagickBooleanType ImageToFile(Image *image,char *filename,
1642 % ExceptionInfo *exception)
1644 % A description of each parameter follows:
1646 % o image: the image.
1648 % o filename: Write the image to this file.
1650 % o exception: return any errors or warnings in this structure.
1653 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1654 ExceptionInfo *exception)
1659 register const unsigned char
1678 assert(image != (Image *) NULL);
1679 assert(image->signature == MagickCoreSignature);
1680 assert(image->blob != (BlobInfo *) NULL);
1681 assert(image->blob->type != UndefinedStream);
1682 if (image->debug != MagickFalse)
1683 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1684 assert(filename != (const char *) NULL);
1685 if (*filename == '\0')
1686 file=AcquireUniqueFileResource(filename);
1688 if (LocaleCompare(filename,"-") == 0)
1689 file=fileno(stdout);
1691 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1694 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1695 return(MagickFalse);
1697 quantum=(size_t) MagickMaxBufferExtent;
1698 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1699 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1700 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1701 if (buffer == (unsigned char *) NULL)
1704 (void) ThrowMagickException(exception,GetMagickModule(),
1705 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1706 return(MagickFalse);
1709 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1710 for (i=0; count > 0; )
1712 length=(size_t) count;
1713 for (i=0; i < length; i+=count)
1715 count=write(file,p+i,(size_t) (length-i));
1725 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1727 if (LocaleCompare(filename,"-") != 0)
1729 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1730 if ((file == -1) || (i < length))
1734 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1735 return(MagickFalse);
1741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1745 % I m a g e s T o B l o b %
1749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1751 % ImagesToBlob() implements direct to memory image formats. It returns the
1752 % image sequence as a blob and its length. The magick member of the ImageInfo
1753 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1755 % Note, some image formats do not permit multiple images to the same image
1756 % stream (e.g. JPEG). in this instance, just the first image of the
1757 % sequence is returned as a blob.
1759 % The format of the ImagesToBlob method is:
1761 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1762 % size_t *length,ExceptionInfo *exception)
1764 % A description of each parameter follows:
1766 % o image_info: the image info.
1768 % o images: the image list.
1770 % o length: return the actual length of the blob.
1772 % o exception: return any errors or warnings in this structure.
1775 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1776 size_t *length,ExceptionInfo *exception)
1790 assert(image_info != (const ImageInfo *) NULL);
1791 assert(image_info->signature == MagickCoreSignature);
1792 if (image_info->debug != MagickFalse)
1793 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1794 image_info->filename);
1795 assert(images != (Image *) NULL);
1796 assert(images->signature == MagickCoreSignature);
1797 assert(exception != (ExceptionInfo *) NULL);
1799 blob=(unsigned char *) NULL;
1800 blob_info=CloneImageInfo(image_info);
1801 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1803 if (*blob_info->magick != '\0')
1804 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
1805 magick_info=GetMagickInfo(images->magick,exception);
1806 if (magick_info == (const MagickInfo *) NULL)
1808 (void) ThrowMagickException(exception,GetMagickModule(),
1809 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1811 blob_info=DestroyImageInfo(blob_info);
1814 if (GetMagickAdjoin(magick_info) == MagickFalse)
1816 blob_info=DestroyImageInfo(blob_info);
1817 return(ImageToBlob(image_info,images,length,exception));
1819 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
1820 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1823 Native blob support for this images format.
1825 blob_info->length=0;
1826 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1827 sizeof(unsigned char));
1828 if (blob_info->blob == (void *) NULL)
1829 (void) ThrowMagickException(exception,GetMagickModule(),
1830 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1833 (void) CloseBlob(images);
1834 images->blob->exempt=MagickTrue;
1835 *images->filename='\0';
1836 status=WriteImages(blob_info,images,images->filename,exception);
1837 *length=images->blob->length;
1838 blob=DetachBlob(images->blob);
1839 if (status == MagickFalse)
1840 blob=RelinquishMagickMemory(blob);
1842 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1848 filename[MagickPathExtent],
1849 unique[MagickPathExtent];
1855 Write file to disk in blob images format.
1857 file=AcquireUniqueFileResource(unique);
1860 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1861 image_info->filename);
1865 blob_info->file=fdopen(file,"wb");
1866 if (blob_info->file != (FILE *) NULL)
1868 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
1869 images->magick,unique);
1870 status=WriteImages(blob_info,images,filename,exception);
1871 (void) CloseBlob(images);
1872 (void) fclose(blob_info->file);
1873 if (status != MagickFalse)
1874 blob=FileToBlob(unique,~0UL,length,exception);
1876 (void) RelinquishUniqueFileResource(unique);
1879 blob_info=DestroyImageInfo(blob_info);
1883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1887 % I n j e c t I m a g e B l o b %
1891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1893 % InjectImageBlob() injects the image with a copy of itself in the specified
1894 % format (e.g. inject JPEG into a PDF image).
1896 % The format of the InjectImageBlob method is:
1898 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1899 % Image *image,Image *inject_image,const char *format,
1900 % ExceptionInfo *exception)
1902 % A description of each parameter follows:
1904 % o image_info: the image info..
1906 % o image: the image.
1908 % o inject_image: inject into the image stream.
1910 % o format: the image format.
1912 % o exception: return any errors or warnings in this structure.
1915 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1916 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1919 filename[MagickPathExtent];
1952 Write inject image to a temporary file.
1954 assert(image_info != (ImageInfo *) NULL);
1955 assert(image_info->signature == MagickCoreSignature);
1956 assert(image != (Image *) NULL);
1957 assert(image->signature == MagickCoreSignature);
1958 if (image->debug != MagickFalse)
1959 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1960 assert(inject_image != (Image *) NULL);
1961 assert(inject_image->signature == MagickCoreSignature);
1962 assert(exception != (ExceptionInfo *) NULL);
1963 unique_file=(FILE *) NULL;
1964 file=AcquireUniqueFileResource(filename);
1966 unique_file=fdopen(file,"wb");
1967 if ((file == -1) || (unique_file == (FILE *) NULL))
1969 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
1970 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1972 return(MagickFalse);
1974 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1975 if (byte_image == (Image *) NULL)
1977 (void) fclose(unique_file);
1978 (void) RelinquishUniqueFileResource(filename);
1979 return(MagickFalse);
1981 (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",format,
1983 DestroyBlob(byte_image);
1984 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1985 write_info=CloneImageInfo(image_info);
1986 SetImageInfoFile(write_info,unique_file);
1987 status=WriteImage(write_info,byte_image,exception);
1988 write_info=DestroyImageInfo(write_info);
1989 byte_image=DestroyImage(byte_image);
1990 (void) fclose(unique_file);
1991 if (status == MagickFalse)
1993 (void) RelinquishUniqueFileResource(filename);
1994 return(MagickFalse);
1997 Inject into image stream.
1999 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
2002 (void) RelinquishUniqueFileResource(filename);
2003 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
2004 image_info->filename);
2005 return(MagickFalse);
2007 quantum=(size_t) MagickMaxBufferExtent;
2008 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
2009 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2010 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2011 if (buffer == (unsigned char *) NULL)
2013 (void) RelinquishUniqueFileResource(filename);
2015 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2018 for (i=0; ; i+=count)
2020 count=read(file,buffer,quantum);
2027 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2032 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2033 (void) RelinquishUniqueFileResource(filename);
2034 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2043 + I s B l o b E x e m p t %
2047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2049 % IsBlobExempt() returns true if the blob is exempt.
2051 % The format of the IsBlobExempt method is:
2053 % MagickBooleanType IsBlobExempt(const Image *image)
2055 % A description of each parameter follows:
2057 % o image: the image.
2060 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
2062 assert(image != (const Image *) NULL);
2063 assert(image->signature == MagickCoreSignature);
2064 if (image->debug != MagickFalse)
2065 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2066 return(image->blob->exempt);
2070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2074 + I s B l o b S e e k a b l e %
2078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2080 % IsBlobSeekable() returns true if the blob is seekable.
2082 % The format of the IsBlobSeekable method is:
2084 % MagickBooleanType IsBlobSeekable(const Image *image)
2086 % A description of each parameter follows:
2088 % o image: the image.
2091 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2096 assert(image != (const Image *) NULL);
2097 assert(image->signature == MagickCoreSignature);
2098 if (image->debug != MagickFalse)
2099 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2100 switch (image->blob->type)
2106 seekable=MagickTrue;
2111 seekable=MagickFalse;
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2123 + I s B l o b T e m p o r a r y %
2127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2129 % IsBlobTemporary() returns true if the blob is temporary.
2131 % The format of the IsBlobTemporary method is:
2133 % MagickBooleanType IsBlobTemporary(const Image *image)
2135 % A description of each parameter follows:
2137 % o image: the image.
2140 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2142 assert(image != (const Image *) NULL);
2143 assert(image->signature == MagickCoreSignature);
2144 if (image->debug != MagickFalse)
2145 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2146 return(image->blob->temporary);
2150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2160 % MapBlob() creates a mapping from a file to a binary large object.
2162 % The format of the MapBlob method is:
2164 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2165 % const size_t length)
2167 % A description of each parameter follows:
2169 % o file: map this file descriptor.
2171 % o mode: ReadMode, WriteMode, or IOMode.
2173 % o offset: starting at this offset within the file.
2175 % o length: the length of the mapping is returned in this pointer.
2178 MagickExport void *MapBlob(int file,const MapMode mode,
2179 const MagickOffsetType offset,const size_t length)
2181 #if defined(MAGICKCORE_HAVE_MMAP)
2194 #if defined(MAP_ANONYMOUS)
2195 flags|=MAP_ANONYMOUS;
2204 protection=PROT_READ;
2210 protection=PROT_WRITE;
2216 protection=PROT_READ | PROT_WRITE;
2221 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2222 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2224 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2226 if (map == MAP_FAILED)
2227 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2229 if (map == MAP_FAILED)
2242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2246 + M S B O r d e r L o n g %
2250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2252 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2253 % most-significant byte first.
2255 % The format of the MSBOrderLong method is:
2257 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2259 % A description of each parameter follows.
2261 % o buffer: Specifies a pointer to a buffer of integers.
2263 % o length: Specifies the length of the buffer.
2266 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2271 register unsigned char
2275 assert(buffer != (unsigned char *) NULL);
2282 *buffer++=(unsigned char) c;
2286 *buffer++=(unsigned char) c;
2292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2296 + M S B O r d e r S h o r t %
2300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2302 % MSBOrderShort() converts a least-significant byte first buffer of integers
2303 % to most-significant byte first.
2305 % The format of the MSBOrderShort method is:
2307 % void MSBOrderShort(unsigned char *p,const size_t length)
2309 % A description of each parameter follows.
2311 % o p: Specifies a pointer to a buffer of integers.
2313 % o length: Specifies the length of the buffer.
2316 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2321 register unsigned char
2324 assert(p != (unsigned char *) NULL);
2331 *p++=(unsigned char) c;
2336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2346 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2347 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2348 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2349 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2350 % from a system command.
2352 % The format of the OpenBlob method is:
2354 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2355 % const BlobMode mode,ExceptionInfo *exception)
2357 % A description of each parameter follows:
2359 % o image_info: the image info.
2361 % o image: the image.
2363 % o mode: the mode for opening the file.
2367 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2380 option=GetImageOption(image_info,"stream:buffer-size");
2381 if (option != (const char *) NULL)
2382 size=StringToUnsignedLong(option);
2383 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2384 _IONBF : _IOFBF,size);
2385 return(status == 0 ? MagickTrue : MagickFalse);
2388 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2389 Image *image,const BlobMode mode,ExceptionInfo *exception)
2392 extension[MagickPathExtent],
2393 filename[MagickPathExtent];
2404 assert(image_info != (ImageInfo *) NULL);
2405 assert(image_info->signature == MagickCoreSignature);
2406 if (image_info->debug != MagickFalse)
2407 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2408 image_info->filename);
2409 assert(image != (Image *) NULL);
2410 assert(image->signature == MagickCoreSignature);
2411 if (image_info->blob != (void *) NULL)
2413 if (image_info->stream != (StreamHandler) NULL)
2414 image->blob->stream=(StreamHandler) image_info->stream;
2415 AttachBlob(image->blob,image_info->blob,image_info->length);
2418 (void) DetachBlob(image->blob);
2421 default: type="r"; break;
2422 case ReadBlobMode: type="r"; break;
2423 case ReadBinaryBlobMode: type="rb"; break;
2424 case WriteBlobMode: type="w"; break;
2425 case WriteBinaryBlobMode: type="w+b"; break;
2426 case AppendBlobMode: type="a"; break;
2427 case AppendBinaryBlobMode: type="a+b"; break;
2430 image->blob->synchronize=image_info->synchronize;
2431 if (image_info->stream != (StreamHandler) NULL)
2433 image->blob->stream=(StreamHandler) image_info->stream;
2436 image->blob->type=FifoStream;
2444 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2445 rights=ReadPolicyRights;
2447 rights=WritePolicyRights;
2448 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2451 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2452 "NotAuthorized","`%s'",filename);
2453 return(MagickFalse);
2455 if ((LocaleCompare(filename,"-") == 0) ||
2456 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2458 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2459 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2460 if (strchr(type,'b') != (char *) NULL)
2461 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2463 image->blob->type=StandardStream;
2464 image->blob->exempt=MagickTrue;
2465 return(SetStreamBuffering(image_info,image));
2467 if (LocaleNCompare(filename,"fd:",3) == 0)
2470 fileMode[MagickPathExtent];
2474 image->blob->file_info.file=fdopen(StringToLong(filename+3),fileMode);
2475 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2476 if (strchr(type,'b') != (char *) NULL)
2477 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2479 image->blob->type=StandardStream;
2480 image->blob->exempt=MagickTrue;
2481 return(SetStreamBuffering(image_info,image));
2483 #if defined(MAGICKCORE_HAVE_POPEN)
2484 if (*filename == '|')
2487 fileMode[MagickPathExtent];
2490 Pipe image to or from a system command.
2492 #if defined(SIGPIPE)
2494 (void) signal(SIGPIPE,SIG_IGN);
2498 image->blob->file_info.file=(FILE *) popen_utf8(filename+1, fileMode);
2499 if (image->blob->file_info.file == (FILE *) NULL)
2501 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2502 return(MagickFalse);
2504 image->blob->type=PipeStream;
2505 image->blob->exempt=MagickTrue;
2506 return(SetStreamBuffering(image_info,image));
2509 status=GetPathAttributes(filename,&image->blob->properties);
2510 #if defined(S_ISFIFO)
2511 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2513 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2514 if (image->blob->file_info.file == (FILE *) NULL)
2516 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2517 return(MagickFalse);
2519 image->blob->type=FileStream;
2520 image->blob->exempt=MagickTrue;
2521 return(SetStreamBuffering(image_info,image));
2524 GetPathComponent(image->filename,ExtensionPath,extension);
2527 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2528 if ((image_info->adjoin == MagickFalse) ||
2529 (strchr(filename,'%') != (char *) NULL))
2532 Form filename for multi-part images.
2534 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2535 image->scene,filename,exception);
2536 if ((LocaleCompare(filename,image->filename) == 0) &&
2537 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2538 (GetNextImageInList(image) != (Image *) NULL)))
2541 path[MagickPathExtent];
2543 GetPathComponent(image->filename,RootPath,path);
2544 if (*extension == '\0')
2545 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
2546 path,(double) image->scene);
2548 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g.%s",
2549 path,(double) image->scene,extension);
2551 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2552 #if defined(macintosh)
2553 SetApplicationType(filename,image_info->magick,'8BIM');
2557 if (image_info->file != (FILE *) NULL)
2559 image->blob->file_info.file=image_info->file;
2560 image->blob->type=FileStream;
2561 image->blob->exempt=MagickTrue;
2566 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2567 if (image->blob->file_info.file != (FILE *) NULL)
2575 image->blob->type=FileStream;
2576 (void) SetStreamBuffering(image_info,image);
2577 (void) ResetMagickMemory(magick,0,sizeof(magick));
2578 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2579 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2580 #if defined(MAGICKCORE_POSIX_SUPPORT)
2581 (void) fflush(image->blob->file_info.file);
2583 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2584 " read %.20g magic header bytes",(double) count);
2585 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2586 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2587 ((int) magick[2] == 0x08))
2589 if (image->blob->file_info.file != (FILE *) NULL)
2590 (void) fclose(image->blob->file_info.file);
2591 image->blob->file_info.file=(FILE *) NULL;
2592 image->blob->file_info.gzfile=gzopen(filename,type);
2593 if (image->blob->file_info.gzfile != (gzFile) NULL)
2594 image->blob->type=ZipStream;
2597 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2598 if (strncmp((char *) magick,"BZh",3) == 0)
2600 if (image->blob->file_info.file != (FILE *) NULL)
2601 (void) fclose(image->blob->file_info.file);
2602 image->blob->file_info.file=(FILE *) NULL;
2603 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2604 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2605 image->blob->type=BZipStream;
2608 if (image->blob->type == FileStream)
2619 sans_exception=AcquireExceptionInfo();
2620 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2621 sans_exception=DestroyExceptionInfo(sans_exception);
2622 length=(size_t) image->blob->properties.st_size;
2623 if ((magick_info != (const MagickInfo *) NULL) &&
2624 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2625 (length > MagickMaxBufferExtent) &&
2626 (AcquireMagickResource(MapResource,length) != MagickFalse))
2631 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
2633 if (blob == (void *) NULL)
2634 RelinquishMagickResource(MapResource,length);
2638 Format supports blobs-- use memory-mapped I/O.
2640 if (image_info->file != (FILE *) NULL)
2641 image->blob->exempt=MagickFalse;
2644 (void) fclose(image->blob->file_info.file);
2645 image->blob->file_info.file=(FILE *) NULL;
2647 AttachBlob(image->blob,blob,length);
2648 image->blob->mapped=MagickTrue;
2655 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2656 if ((LocaleCompare(extension,"Z") == 0) ||
2657 (LocaleCompare(extension,"gz") == 0) ||
2658 (LocaleCompare(extension,"wmz") == 0) ||
2659 (LocaleCompare(extension,"svgz") == 0))
2661 if (mode == WriteBinaryBlobMode)
2663 image->blob->file_info.gzfile=gzopen(filename,type);
2664 if (image->blob->file_info.gzfile != (gzFile) NULL)
2665 image->blob->type=ZipStream;
2669 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2670 if (LocaleCompare(extension,"bz2") == 0)
2672 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2673 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2674 image->blob->type=BZipStream;
2679 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2680 if (image->blob->file_info.file != (FILE *) NULL)
2682 image->blob->type=FileStream;
2683 (void) SetStreamBuffering(image_info,image);
2686 image->blob->status=MagickFalse;
2687 if (image->blob->type != UndefinedStream)
2688 image->blob->size=GetBlobSize(image);
2691 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2692 return(MagickFalse);
2698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2708 % PingBlob() returns all the attributes of an image or image sequence except
2709 % for the pixels. It is much faster and consumes far less memory than
2710 % BlobToImage(). On failure, a NULL image is returned and exception
2711 % describes the reason for the failure.
2713 % The format of the PingBlob method is:
2715 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2716 % const size_t length,ExceptionInfo *exception)
2718 % A description of each parameter follows:
2720 % o image_info: the image info.
2722 % o blob: the address of a character stream in one of the image formats
2723 % understood by ImageMagick.
2725 % o length: This size_t integer reflects the length in bytes of the blob.
2727 % o exception: return any errors or warnings in this structure.
2731 #if defined(__cplusplus) || defined(c_plusplus)
2735 static size_t PingStream(const Image *magick_unused(image),
2736 const void *magick_unused(pixels),const size_t columns)
2741 #if defined(__cplusplus) || defined(c_plusplus)
2745 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2746 const size_t length,ExceptionInfo *exception)
2754 assert(image_info != (ImageInfo *) NULL);
2755 assert(image_info->signature == MagickCoreSignature);
2756 if (image_info->debug != MagickFalse)
2757 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2758 image_info->filename);
2759 assert(exception != (ExceptionInfo *) NULL);
2760 if ((blob == (const void *) NULL) || (length == 0))
2762 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2763 "UnrecognizedImageFormat","`%s'",image_info->magick);
2764 return((Image *) NULL);
2766 ping_info=CloneImageInfo(image_info);
2767 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2768 if (ping_info->blob == (const void *) NULL)
2770 (void) ThrowMagickException(exception,GetMagickModule(),
2771 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2772 return((Image *) NULL);
2774 (void) memcpy(ping_info->blob,blob,length);
2775 ping_info->length=length;
2776 ping_info->ping=MagickTrue;
2777 image=ReadStream(ping_info,&PingStream,exception);
2778 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2779 ping_info=DestroyImageInfo(ping_info);
2784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2794 % ReadBlob() reads data from the blob or image file and returns it. It
2795 % returns the number of bytes read. If length is zero, ReadBlob() returns
2796 % zero and has no other results. If length is greater than SSIZE_MAX, the
2797 % result is unspecified.
2799 % The format of the ReadBlob method is:
2801 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
2803 % A description of each parameter follows:
2805 % o image: the image.
2807 % o length: Specifies an integer representing the number of bytes to read
2810 % o data: Specifies an area to place the information requested from the
2814 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
2819 register unsigned char
2825 assert(image != (Image *) NULL);
2826 assert(image->signature == MagickCoreSignature);
2827 assert(image->blob != (BlobInfo *) NULL);
2828 assert(image->blob->type != UndefinedStream);
2831 assert(data != (void *) NULL);
2833 q=(unsigned char *) data;
2834 switch (image->blob->type)
2836 case UndefinedStream:
2838 case StandardStream:
2846 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
2851 c=getc(image->blob->file_info.file);
2854 *q++=(unsigned char) c;
2859 c=getc(image->blob->file_info.file);
2862 *q++=(unsigned char) c;
2867 c=getc(image->blob->file_info.file);
2870 *q++=(unsigned char) c;
2875 c=getc(image->blob->file_info.file);
2878 *q++=(unsigned char) c;
2888 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2893 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
2894 (unsigned int) length);
2899 c=gzgetc(image->blob->file_info.gzfile);
2902 *q++=(unsigned char) c;
2907 c=gzgetc(image->blob->file_info.gzfile);
2910 *q++=(unsigned char) c;
2915 c=gzgetc(image->blob->file_info.gzfile);
2918 *q++=(unsigned char) c;
2923 c=gzgetc(image->blob->file_info.gzfile);
2926 *q++=(unsigned char) c;
2937 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2938 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
2946 register const unsigned char
2949 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2951 image->blob->eof=MagickTrue;
2954 p=image->blob->data+image->blob->offset;
2955 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2956 image->blob->offset+=count;
2957 if (count != (ssize_t) length)
2958 image->blob->eof=MagickTrue;
2959 (void) memcpy(q,p,(size_t) count);
2967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2971 + R e a d B l o b B y t e %
2975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2977 % ReadBlobByte() reads a single byte from the image file and returns it.
2979 % The format of the ReadBlobByte method is:
2981 % int ReadBlobByte(Image *image)
2983 % A description of each parameter follows.
2985 % o image: the image.
2988 MagickExport int ReadBlobByte(Image *image)
2990 register const unsigned char
2999 assert(image != (Image *) NULL);
3000 assert(image->signature == MagickCoreSignature);
3001 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3012 + R e a d B l o b D o u b l e %
3016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3018 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3019 % specified by the endian member of the image structure.
3021 % The format of the ReadBlobDouble method is:
3023 % double ReadBlobDouble(Image *image)
3025 % A description of each parameter follows.
3027 % o image: the image.
3030 MagickExport double ReadBlobDouble(Image *image)
3041 quantum.double_value=0.0;
3042 quantum.unsigned_value=ReadBlobLongLong(image);
3043 return(quantum.double_value);
3047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3051 + R e a d B l o b F l o a t %
3055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3057 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3058 % specified by the endian member of the image structure.
3060 % The format of the ReadBlobFloat method is:
3062 % float ReadBlobFloat(Image *image)
3064 % A description of each parameter follows.
3066 % o image: the image.
3069 MagickExport float ReadBlobFloat(Image *image)
3080 quantum.float_value=0.0;
3081 quantum.unsigned_value=ReadBlobLong(image);
3082 return(quantum.float_value);
3086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3090 + R e a d B l o b L o n g %
3094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3096 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
3097 % specified by the endian member of the image structure.
3099 % The format of the ReadBlobLong method is:
3101 % unsigned int ReadBlobLong(Image *image)
3103 % A description of each parameter follows.
3105 % o image: the image.
3108 MagickExport unsigned int ReadBlobLong(Image *image)
3110 register const unsigned char
3122 assert(image != (Image *) NULL);
3123 assert(image->signature == MagickCoreSignature);
3125 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3128 if (image->endian == LSBEndian)
3130 value=(unsigned int) (*p++);
3131 value|=((unsigned int) (*p++)) << 8;
3132 value|=((unsigned int) (*p++)) << 16;
3133 value|=((unsigned int) (*p++)) << 24;
3136 value=((unsigned int) (*p++)) << 24;
3137 value|=((unsigned int) (*p++)) << 16;
3138 value|=((unsigned int) (*p++)) << 8;
3139 value|=((unsigned int) (*p++));
3144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3148 + R e a d B l o b L o n g L o n g %
3152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3154 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3155 % byte-order specified by the endian member of the image structure.
3157 % The format of the ReadBlobLongLong method is:
3159 % MagickSizeType ReadBlobLongLong(Image *image)
3161 % A description of each parameter follows.
3163 % o image: the image.
3166 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3171 register const unsigned char
3180 assert(image != (Image *) NULL);
3181 assert(image->signature == MagickCoreSignature);
3183 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3185 return(MagickULLConstant(0));
3186 if (image->endian == LSBEndian)
3188 value=(MagickSizeType) (*p++);
3189 value|=((MagickSizeType) (*p++)) << 8;
3190 value|=((MagickSizeType) (*p++)) << 16;
3191 value|=((MagickSizeType) (*p++)) << 24;
3192 value|=((MagickSizeType) (*p++)) << 32;
3193 value|=((MagickSizeType) (*p++)) << 40;
3194 value|=((MagickSizeType) (*p++)) << 48;
3195 value|=((MagickSizeType) (*p++)) << 56;
3196 return(value & MagickULLConstant(0xffffffffffffffff));
3198 value=((MagickSizeType) (*p++)) << 56;
3199 value|=((MagickSizeType) (*p++)) << 48;
3200 value|=((MagickSizeType) (*p++)) << 40;
3201 value|=((MagickSizeType) (*p++)) << 32;
3202 value|=((MagickSizeType) (*p++)) << 24;
3203 value|=((MagickSizeType) (*p++)) << 16;
3204 value|=((MagickSizeType) (*p++)) << 8;
3205 value|=((MagickSizeType) (*p++));
3206 return(value & MagickULLConstant(0xffffffffffffffff));
3210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3214 + R e a d B l o b S h o r t %
3218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3220 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3221 % specified by the endian member of the image structure.
3223 % The format of the ReadBlobShort method is:
3225 % unsigned short ReadBlobShort(Image *image)
3227 % A description of each parameter follows.
3229 % o image: the image.
3232 MagickExport unsigned short ReadBlobShort(Image *image)
3234 register const unsigned char
3237 register unsigned int
3246 assert(image != (Image *) NULL);
3247 assert(image->signature == MagickCoreSignature);
3249 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3251 return((unsigned short) 0U);
3252 if (image->endian == LSBEndian)
3254 value=(unsigned int) (*p++);
3255 value|=((unsigned int) (*p++)) << 8;
3256 return((unsigned short) (value & 0xffff));
3258 value=(unsigned int) ((*p++) << 8);
3259 value|=(unsigned int) (*p++);
3260 return((unsigned short) (value & 0xffff));
3264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3268 + R e a d B l o b L S B L o n g %
3272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3274 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3275 % least-significant byte first order.
3277 % The format of the ReadBlobLSBLong method is:
3279 % unsigned int ReadBlobLSBLong(Image *image)
3281 % A description of each parameter follows.
3283 % o image: the image.
3286 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3288 register const unsigned char
3291 register unsigned int
3300 assert(image != (Image *) NULL);
3301 assert(image->signature == MagickCoreSignature);
3303 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3306 value=(unsigned int) (*p++);
3307 value|=((unsigned int) (*p++)) << 8;
3308 value|=((unsigned int) (*p++)) << 16;
3309 value|=((unsigned int) (*p++)) << 24;
3314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3318 + R e a d B l o b L S B S h o r t %
3322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3324 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3325 % least-significant byte first order.
3327 % The format of the ReadBlobLSBShort method is:
3329 % unsigned short ReadBlobLSBShort(Image *image)
3331 % A description of each parameter follows.
3333 % o image: the image.
3336 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3338 register const unsigned char
3341 register unsigned int
3350 assert(image != (Image *) NULL);
3351 assert(image->signature == MagickCoreSignature);
3353 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3355 return((unsigned short) 0U);
3356 value=(unsigned int) (*p++);
3357 value|=((unsigned int) ((*p++)) << 8);
3358 return((unsigned short) (value & 0xffff));
3362 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3366 + R e a d B l o b M S B L o n g %
3370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3372 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3373 % most-significant byte first order.
3375 % The format of the ReadBlobMSBLong method is:
3377 % unsigned int ReadBlobMSBLong(Image *image)
3379 % A description of each parameter follows.
3381 % o image: the image.
3384 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3386 register const unsigned char
3389 register unsigned int
3398 assert(image != (Image *) NULL);
3399 assert(image->signature == MagickCoreSignature);
3401 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3404 value=((unsigned int) (*p++) << 24);
3405 value|=((unsigned int) (*p++) << 16);
3406 value|=((unsigned int) (*p++) << 8);
3407 value|=(unsigned int) (*p++);
3412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3416 + R e a d B l o b M S B L o n g L o n g %
3420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3422 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3423 % most-significant byte first order.
3425 % The format of the ReadBlobMSBLongLong method is:
3427 % unsigned int ReadBlobMSBLongLong(Image *image)
3429 % A description of each parameter follows.
3431 % o image: the image.
3434 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3436 register const unsigned char
3439 register MagickSizeType
3448 assert(image != (Image *) NULL);
3449 assert(image->signature == MagickCoreSignature);
3451 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3453 return(MagickULLConstant(0));
3454 value=((MagickSizeType) (*p++)) << 56;
3455 value|=((MagickSizeType) (*p++)) << 48;
3456 value|=((MagickSizeType) (*p++)) << 40;
3457 value|=((MagickSizeType) (*p++)) << 32;
3458 value|=((MagickSizeType) (*p++)) << 24;
3459 value|=((MagickSizeType) (*p++)) << 16;
3460 value|=((MagickSizeType) (*p++)) << 8;
3461 value|=((MagickSizeType) (*p++));
3462 return(value & MagickULLConstant(0xffffffffffffffff));
3466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3470 + R e a d B l o b M S B S h o r t %
3474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3476 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3477 % most-significant byte first order.
3479 % The format of the ReadBlobMSBShort method is:
3481 % unsigned short ReadBlobMSBShort(Image *image)
3483 % A description of each parameter follows.
3485 % o image: the image.
3488 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3490 register const unsigned char
3493 register unsigned int
3502 assert(image != (Image *) NULL);
3503 assert(image->signature == MagickCoreSignature);
3505 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3507 return((unsigned short) 0U);
3508 value=(unsigned int) ((*p++) << 8);
3509 value|=(unsigned int) (*p++);
3510 return((unsigned short) (value & 0xffff));
3514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3518 + R e a d B l o b S t r e a m %
3522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3524 % ReadBlobStream() reads data from the blob or image file and returns it. It
3525 % returns a pointer to the data buffer you supply or to the image memory
3526 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
3527 % returns a count of zero and has no other results. If length is greater than
3528 % SSIZE_MAX, the result is unspecified.
3530 % The format of the ReadBlobStream method is:
3532 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
3535 % A description of each parameter follows:
3537 % o image: the image.
3539 % o length: Specifies an integer representing the number of bytes to read
3542 % o count: returns the number of bytes read.
3544 % o data: Specifies an area to place the information requested from the
3548 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
3549 void *data,ssize_t *count)
3551 assert(image != (Image *) NULL);
3552 assert(image->signature == MagickCoreSignature);
3553 assert(image->blob != (BlobInfo *) NULL);
3554 assert(image->blob->type != UndefinedStream);
3555 assert(count != (ssize_t *) NULL);
3556 if (image->blob->type != BlobStream)
3558 assert(data != NULL);
3559 *count=ReadBlob(image,length,(unsigned char *) data);
3562 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3565 image->blob->eof=MagickTrue;
3568 data=image->blob->data+image->blob->offset;
3569 *count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
3570 image->blob->offset+=(*count);
3571 if (*count != (ssize_t) length)
3572 image->blob->eof=MagickTrue;
3577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3581 + R e a d B l o b S t r i n g %
3585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3587 % ReadBlobString() reads characters from a blob or file until a newline
3588 % character is read or an end-of-file condition is encountered.
3590 % The format of the ReadBlobString method is:
3592 % char *ReadBlobString(Image *image,char *string)
3594 % A description of each parameter follows:
3596 % o image: the image.
3598 % o string: the address of a character buffer.
3601 MagickExport char *ReadBlobString(Image *image,char *string)
3603 register const unsigned char
3615 assert(image != (Image *) NULL);
3616 assert(image->signature == MagickCoreSignature);
3617 for (i=0; i < (MagickPathExtent-1L); i++)
3619 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3623 return((char *) NULL);
3626 string[i]=(char) (*p);
3627 if ((string[i] == '\r') || (string[i] == '\n'))
3630 if (string[i] == '\r')
3631 (void) ReadBlobStream(image,1,buffer,&count);
3637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3641 + R e f e r e n c e B l o b %
3645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3647 % ReferenceBlob() increments the reference count associated with the pixel
3648 % blob returning a pointer to the blob.
3650 % The format of the ReferenceBlob method is:
3652 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3654 % A description of each parameter follows:
3656 % o blob_info: the blob_info.
3659 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3661 assert(blob != (BlobInfo *) NULL);
3662 assert(blob->signature == MagickCoreSignature);
3663 if (blob->debug != MagickFalse)
3664 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3665 LockSemaphoreInfo(blob->semaphore);
3666 blob->reference_count++;
3667 UnlockSemaphoreInfo(blob->semaphore);
3672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3682 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3683 % and returns the resulting offset.
3685 % The format of the SeekBlob method is:
3687 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3690 % A description of each parameter follows:
3692 % o image: the image.
3694 % o offset: Specifies an integer representing the offset in bytes.
3696 % o whence: Specifies an integer representing how the offset is
3697 % treated relative to the beginning of the blob as follows:
3699 % SEEK_SET Set position equal to offset bytes.
3700 % SEEK_CUR Set position to current location plus offset.
3701 % SEEK_END Set position to EOF plus offset.
3704 MagickExport MagickOffsetType SeekBlob(Image *image,
3705 const MagickOffsetType offset,const int whence)
3707 assert(image != (Image *) NULL);
3708 assert(image->signature == MagickCoreSignature);
3709 if (image->debug != MagickFalse)
3710 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3711 assert(image->blob != (BlobInfo *) NULL);
3712 assert(image->blob->type != UndefinedStream);
3713 switch (image->blob->type)
3715 case UndefinedStream:
3717 case StandardStream:
3721 if ((offset < 0) && (whence == SEEK_SET))
3723 if (fseek(image->blob->file_info.file,offset,whence) < 0)
3725 image->blob->offset=TellBlob(image);
3731 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3732 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
3735 image->blob->offset=TellBlob(image);
3751 image->blob->offset=offset;
3756 if ((image->blob->offset+offset) < 0)
3758 image->blob->offset+=offset;
3763 if (((MagickOffsetType) image->blob->length+offset) < 0)
3765 image->blob->offset=image->blob->length+offset;
3769 if (image->blob->offset < (MagickOffsetType)
3770 ((off_t) image->blob->length))
3772 image->blob->eof=MagickFalse;
3775 if (image->blob->offset < (MagickOffsetType)
3776 ((off_t) image->blob->extent))
3778 if (image->blob->immutable != MagickFalse)
3780 image->blob->eof=MagickTrue;
3783 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
3784 image->blob->quantum<<=1;
3785 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3786 image->blob->extent+1,sizeof(*image->blob->data));
3787 (void) SyncBlob(image);
3788 if (image->blob->data == NULL)
3790 (void) DetachBlob(image->blob);
3796 return(image->blob->offset);
3800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3804 + S e t B l o b E x e m p t %
3808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3810 % SetBlobExempt() sets the blob exempt status.
3812 % The format of the SetBlobExempt method is:
3814 % MagickBooleanType SetBlobExempt(const Image *image,
3815 % const MagickBooleanType exempt)
3817 % A description of each parameter follows:
3819 % o image: the image.
3821 % o exempt: Set to true if this blob is exempt from being closed.
3824 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3826 assert(image != (const Image *) NULL);
3827 assert(image->signature == MagickCoreSignature);
3828 if (image->debug != MagickFalse)
3829 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3830 image->blob->exempt=exempt;
3834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3838 + S e t B l o b E x t e n t %
3842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3844 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3845 % method is successful, subsequent writes to bytes in the specified range are
3846 % guaranteed not to fail.
3848 % The format of the SetBlobExtent method is:
3850 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3852 % A description of each parameter follows:
3854 % o image: the image.
3856 % o extent: the blob maximum extent.
3859 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3860 const MagickSizeType extent)
3862 assert(image != (Image *) NULL);
3863 assert(image->signature == MagickCoreSignature);
3864 if (image->debug != MagickFalse)
3865 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3866 assert(image->blob != (BlobInfo *) NULL);
3867 assert(image->blob->type != UndefinedStream);
3868 switch (image->blob->type)
3870 case UndefinedStream:
3872 case StandardStream:
3873 return(MagickFalse);
3882 if (extent != (MagickSizeType) ((off_t) extent))
3883 return(MagickFalse);
3884 offset=SeekBlob(image,0,SEEK_END);
3886 return(MagickFalse);
3887 if ((MagickSizeType) offset >= extent)
3889 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3892 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3893 image->blob->file_info.file);
3894 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3895 if (image->blob->synchronize != MagickFalse)
3900 file=fileno(image->blob->file_info.file);
3901 if ((file == -1) || (offset < 0))
3902 return(MagickFalse);
3903 (void) posix_fallocate(file,offset,extent-offset);
3906 offset=SeekBlob(image,offset,SEEK_SET);
3908 return(MagickFalse);
3913 return(MagickFalse);
3915 return(MagickFalse);
3917 return(MagickFalse);
3920 if (extent != (MagickSizeType) ((size_t) extent))
3921 return(MagickFalse);
3922 if (image->blob->mapped != MagickFalse)
3930 (void) UnmapBlob(image->blob->data,image->blob->length);
3931 RelinquishMagickResource(MapResource,image->blob->length);
3932 if (extent != (MagickSizeType) ((off_t) extent))
3933 return(MagickFalse);
3934 offset=SeekBlob(image,0,SEEK_END);
3936 return(MagickFalse);
3937 if ((MagickSizeType) offset >= extent)
3939 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3940 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3941 image->blob->file_info.file);
3942 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3943 if (image->blob->synchronize != MagickFalse)
3948 file=fileno(image->blob->file_info.file);
3949 if ((file == -1) || (offset < 0))
3950 return(MagickFalse);
3951 (void) posix_fallocate(file,offset,extent-offset);
3954 offset=SeekBlob(image,offset,SEEK_SET);
3956 return(MagickFalse);
3957 (void) AcquireMagickResource(MapResource,extent);
3958 image->blob->data=(unsigned char*) MapBlob(fileno(
3959 image->blob->file_info.file),WriteMode,0,(size_t) extent);
3960 image->blob->extent=(size_t) extent;
3961 image->blob->length=(size_t) extent;
3962 (void) SyncBlob(image);
3965 image->blob->extent=(size_t) extent;
3966 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3967 image->blob->extent+1,sizeof(*image->blob->data));
3968 (void) SyncBlob(image);
3969 if (image->blob->data == (unsigned char *) NULL)
3971 (void) DetachBlob(image->blob);
3972 return(MagickFalse);
3981 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3991 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3992 % attributes if it is an blob.
3994 % The format of the SyncBlob method is:
3996 % int SyncBlob(Image *image)
3998 % A description of each parameter follows:
4000 % o image: the image.
4003 static int SyncBlob(Image *image)
4008 assert(image != (Image *) NULL);
4009 assert(image->signature == MagickCoreSignature);
4010 if (image->debug != MagickFalse)
4011 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4012 assert(image->blob != (BlobInfo *) NULL);
4013 assert(image->blob->type != UndefinedStream);
4015 switch (image->blob->type)
4017 case UndefinedStream:
4018 case StandardStream:
4023 status=fflush(image->blob->file_info.file);
4028 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4029 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
4035 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4036 status=BZ2_bzflush(image->blob->file_info.bzfile);
4049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4059 % TellBlob() obtains the current value of the blob or file position.
4061 % The format of the TellBlob method is:
4063 % MagickOffsetType TellBlob(const Image *image)
4065 % A description of each parameter follows:
4067 % o image: the image.
4070 MagickExport MagickOffsetType TellBlob(const Image *image)
4075 assert(image != (Image *) NULL);
4076 assert(image->signature == MagickCoreSignature);
4077 if (image->debug != MagickFalse)
4078 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4079 assert(image->blob != (BlobInfo *) NULL);
4080 assert(image->blob->type != UndefinedStream);
4082 switch (image->blob->type)
4084 case UndefinedStream:
4085 case StandardStream:
4089 offset=ftell(image->blob->file_info.file);
4096 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4097 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
4107 offset=image->blob->offset;
4115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4119 + U n m a p B l o b %
4123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4125 % UnmapBlob() deallocates the binary large object previously allocated with
4126 % the MapBlob method.
4128 % The format of the UnmapBlob method is:
4130 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4132 % A description of each parameter follows:
4134 % o map: the address of the binary large object.
4136 % o length: the length of the binary large object.
4139 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4141 #if defined(MAGICKCORE_HAVE_MMAP)
4145 status=munmap(map,length);
4146 return(status == -1 ? MagickFalse : MagickTrue);
4150 return(MagickFalse);
4155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4159 + W r i t e B l o b %
4163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4165 % WriteBlob() writes data to a blob or image file. It returns the number of
4168 % The format of the WriteBlob method is:
4170 % ssize_t WriteBlob(Image *image,const size_t length,const void *data)
4172 % A description of each parameter follows:
4174 % o image: the image.
4176 % o length: Specifies an integer representing the number of bytes to
4177 % write to the file.
4179 % o data: The address of the data to write to the blob or file.
4182 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4188 register const unsigned char
4194 assert(image != (Image *) NULL);
4195 assert(image->signature == MagickCoreSignature);
4196 assert(data != (const void *) NULL);
4197 assert(image->blob != (BlobInfo *) NULL);
4198 assert(image->blob->type != UndefinedStream);
4202 p=(const unsigned char *) data;
4203 switch (image->blob->type)
4205 case UndefinedStream:
4207 case StandardStream:
4215 count=(ssize_t) fwrite((const char *) data,1,length,
4216 image->blob->file_info.file);
4221 c=putc((int) *p++,image->blob->file_info.file);
4228 c=putc((int) *p++,image->blob->file_info.file);
4235 c=putc((int) *p++,image->blob->file_info.file);
4242 c=putc((int) *p++,image->blob->file_info.file);
4254 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4259 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4260 (unsigned int) length);
4265 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4272 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4279 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4286 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4299 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4300 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
4307 count=(ssize_t) image->blob->stream(image,data,length);
4312 register unsigned char
4315 if ((image->blob->offset+(MagickOffsetType) length) >=
4316 (MagickOffsetType) image->blob->extent)
4318 if (image->blob->mapped != MagickFalse)
4320 image->blob->extent+=length+image->blob->quantum;
4321 image->blob->quantum<<=1;
4322 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4323 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4324 (void) SyncBlob(image);
4325 if (image->blob->data == (unsigned char *) NULL)
4327 (void) DetachBlob(image->blob);
4331 q=image->blob->data+image->blob->offset;
4332 (void) memcpy(q,p,length);
4333 image->blob->offset+=length;
4334 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4335 image->blob->length=(size_t) image->blob->offset;
4336 count=(ssize_t) length;
4343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4347 + W r i t e B l o b B y t e %
4351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4353 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4354 % written (either 0 or 1);
4356 % The format of the WriteBlobByte method is:
4358 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4360 % A description of each parameter follows.
4362 % o image: the image.
4364 % o value: Specifies the value to write.
4367 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4369 assert(image != (Image *) NULL);
4370 assert(image->signature == MagickCoreSignature);
4371 return(WriteBlobStream(image,1,&value));
4375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4379 + W r i t e B l o b F l o a t %
4383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4385 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4386 % specified by the endian member of the image structure.
4388 % The format of the WriteBlobFloat method is:
4390 % ssize_t WriteBlobFloat(Image *image,const float value)
4392 % A description of each parameter follows.
4394 % o image: the image.
4396 % o value: Specifies the value to write.
4399 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4410 quantum.unsigned_value=0U;
4411 quantum.float_value=value;
4412 return(WriteBlobLong(image,quantum.unsigned_value));
4416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4420 + W r i t e B l o b L o n g %
4424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4426 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4427 % specified by the endian member of the image structure.
4429 % The format of the WriteBlobLong method is:
4431 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4433 % A description of each parameter follows.
4435 % o image: the image.
4437 % o value: Specifies the value to write.
4440 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4445 assert(image != (Image *) NULL);
4446 assert(image->signature == MagickCoreSignature);
4447 if (image->endian == LSBEndian)
4449 buffer[0]=(unsigned char) value;
4450 buffer[1]=(unsigned char) (value >> 8);
4451 buffer[2]=(unsigned char) (value >> 16);
4452 buffer[3]=(unsigned char) (value >> 24);
4453 return(WriteBlobStream(image,4,buffer));
4455 buffer[0]=(unsigned char) (value >> 24);
4456 buffer[1]=(unsigned char) (value >> 16);
4457 buffer[2]=(unsigned char) (value >> 8);
4458 buffer[3]=(unsigned char) value;
4459 return(WriteBlobStream(image,4,buffer));
4463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4467 + W r i t e B l o b S h o r t %
4471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4473 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4474 % byte-order specified by the endian member of the image structure.
4476 % The format of the WriteBlobShort method is:
4478 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4480 % A description of each parameter follows.
4482 % o image: the image.
4484 % o value: Specifies the value to write.
4487 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4492 assert(image != (Image *) NULL);
4493 assert(image->signature == MagickCoreSignature);
4494 if (image->endian == LSBEndian)
4496 buffer[0]=(unsigned char) value;
4497 buffer[1]=(unsigned char) (value >> 8);
4498 return(WriteBlobStream(image,2,buffer));
4500 buffer[0]=(unsigned char) (value >> 8);
4501 buffer[1]=(unsigned char) value;
4502 return(WriteBlobStream(image,2,buffer));
4506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4510 + W r i t e B l o b L S B L o n g %
4514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4516 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4517 % least-significant byte first order.
4519 % The format of the WriteBlobLSBLong method is:
4521 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4523 % A description of each parameter follows.
4525 % o image: the image.
4527 % o value: Specifies the value to write.
4530 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4535 assert(image != (Image *) NULL);
4536 assert(image->signature == MagickCoreSignature);
4537 buffer[0]=(unsigned char) value;
4538 buffer[1]=(unsigned char) (value >> 8);
4539 buffer[2]=(unsigned char) (value >> 16);
4540 buffer[3]=(unsigned char) (value >> 24);
4541 return(WriteBlobStream(image,4,buffer));
4545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4549 + W r i t e B l o b L S B S h o r t %
4553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4555 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4556 % least-significant byte first order.
4558 % The format of the WriteBlobLSBShort method is:
4560 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4562 % A description of each parameter follows.
4564 % o image: the image.
4566 % o value: Specifies the value to write.
4569 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4574 assert(image != (Image *) NULL);
4575 assert(image->signature == MagickCoreSignature);
4576 buffer[0]=(unsigned char) value;
4577 buffer[1]=(unsigned char) (value >> 8);
4578 return(WriteBlobStream(image,2,buffer));
4582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4586 + W r i t e B l o b M S B L o n g %
4590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4592 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4593 % most-significant byte first order.
4595 % The format of the WriteBlobMSBLong method is:
4597 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4599 % A description of each parameter follows.
4601 % o value: Specifies the value to write.
4603 % o image: the image.
4606 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4611 assert(image != (Image *) NULL);
4612 assert(image->signature == MagickCoreSignature);
4613 buffer[0]=(unsigned char) (value >> 24);
4614 buffer[1]=(unsigned char) (value >> 16);
4615 buffer[2]=(unsigned char) (value >> 8);
4616 buffer[3]=(unsigned char) value;
4617 return(WriteBlobStream(image,4,buffer));
4621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4625 + W r i t e B l o b M S B L o n g L o n g %
4629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4631 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4632 % most-significant byte first order.
4634 % The format of the WriteBlobMSBLongLong method is:
4636 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4638 % A description of each parameter follows.
4640 % o value: Specifies the value to write.
4642 % o image: the image.
4645 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4646 const MagickSizeType value)
4651 assert(image != (Image *) NULL);
4652 assert(image->signature == MagickCoreSignature);
4653 buffer[0]=(unsigned char) (value >> 56);
4654 buffer[1]=(unsigned char) (value >> 48);
4655 buffer[2]=(unsigned char) (value >> 40);
4656 buffer[3]=(unsigned char) (value >> 32);
4657 buffer[4]=(unsigned char) (value >> 24);
4658 buffer[5]=(unsigned char) (value >> 16);
4659 buffer[6]=(unsigned char) (value >> 8);
4660 buffer[7]=(unsigned char) value;
4661 return(WriteBlobStream(image,8,buffer));
4665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4669 + W r i t e B l o b M S B S h o r t %
4673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4675 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4676 % most-significant byte first order.
4678 % The format of the WriteBlobMSBShort method is:
4680 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4682 % A description of each parameter follows.
4684 % o value: Specifies the value to write.
4686 % o file: Specifies the file to write the data to.
4689 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4694 assert(image != (Image *) NULL);
4695 assert(image->signature == MagickCoreSignature);
4696 buffer[0]=(unsigned char) (value >> 8);
4697 buffer[1]=(unsigned char) value;
4698 return(WriteBlobStream(image,2,buffer));
4702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4706 + W r i t e B l o b S t r i n g %
4710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4712 % WriteBlobString() write a string to a blob. It returns the number of
4713 % characters written.
4715 % The format of the WriteBlobString method is:
4717 % ssize_t WriteBlobString(Image *image,const char *string)
4719 % A description of each parameter follows.
4721 % o image: the image.
4723 % o string: Specifies the string to write.
4726 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4728 assert(image != (Image *) NULL);
4729 assert(image->signature == MagickCoreSignature);
4730 assert(string != (const char *) NULL);
4731 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));