2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % https://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 #include "MagickCore/studio.h"
48 #include "MagickCore/blob.h"
49 #include "MagickCore/blob-private.h"
50 #include "MagickCore/cache.h"
51 #include "MagickCore/client.h"
52 #include "MagickCore/constitute.h"
53 #include "MagickCore/delegate.h"
54 #include "MagickCore/exception.h"
55 #include "MagickCore/exception-private.h"
56 #include "MagickCore/image-private.h"
57 #include "MagickCore/list.h"
58 #include "MagickCore/locale_.h"
59 #include "MagickCore/log.h"
60 #include "MagickCore/magick.h"
61 #include "MagickCore/memory_.h"
62 #include "MagickCore/nt-base-private.h"
63 #include "MagickCore/option.h"
64 #include "MagickCore/policy.h"
65 #include "MagickCore/resource_.h"
66 #include "MagickCore/semaphore.h"
67 #include "MagickCore/string_.h"
68 #include "MagickCore/string-private.h"
69 #include "MagickCore/token.h"
70 #include "MagickCore/utility.h"
71 #include "MagickCore/utility-private.h"
72 #if defined(MAGICKCORE_ZLIB_DELEGATE)
75 #if defined(MAGICKCORE_BZLIB_DELEGATE)
82 #define MagickMaxBlobExtent (8*8192)
83 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
84 # define MAP_ANONYMOUS MAP_ANON
86 #if !defined(MAP_FAILED)
87 #define MAP_FAILED ((void *) -1)
91 #define _O_BINARY O_BINARY
97 typedef union FileInfo
102 #if defined(MAGICKCORE_ZLIB_DELEGATE)
107 #if defined(MAGICKCORE_BZLIB_DELEGATE)
167 struct _CustomStreamInfo
187 Forward declarations.
193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 + A c q u i r e C u s t o m S t r e a m I n f o %
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 % AcquireCustomStreamInfo() allocates the CustomStreamInfo structure.
205 % The format of the AcquireCustomStreamInfo method is:
207 % CustomStreamInfo *AcquireCustomStreamInfo(ExceptionInfo *exception)
209 % A description of each parameter follows:
211 % o exception: return any errors or warnings in this structure.
214 MagickExport CustomStreamInfo *AcquireCustomStreamInfo(
215 ExceptionInfo *magick_unused(exception))
220 magick_unreferenced(exception);
221 custom_stream=(CustomStreamInfo *) AcquireMagickMemory(
222 sizeof(*custom_stream));
223 if (custom_stream == (CustomStreamInfo *) NULL)
224 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
225 (void) ResetMagickMemory(custom_stream,0,sizeof(*custom_stream));
226 custom_stream->signature=MagickCoreSignature;
227 return(custom_stream);
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235 + A t t a c h B l o b %
239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241 % AttachBlob() attaches a blob to the BlobInfo structure.
243 % The format of the AttachBlob method is:
245 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
247 % A description of each parameter follows:
249 % o blob_info: Specifies a pointer to a BlobInfo structure.
251 % o blob: the address of a character stream in one of the image formats
252 % understood by ImageMagick.
254 % o length: This size_t integer reflects the length in bytes of the blob.
257 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
260 assert(blob_info != (BlobInfo *) NULL);
261 if (blob_info->debug != MagickFalse)
262 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
263 blob_info->length=length;
264 blob_info->extent=length;
265 blob_info->quantum=(size_t) MagickMaxBlobExtent;
267 blob_info->type=BlobStream;
268 blob_info->file_info.file=(FILE *) NULL;
269 blob_info->data=(unsigned char *) blob;
270 blob_info->mapped=MagickFalse;
274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278 + B l o b T o F i l e %
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
285 % occurs otherwise MagickTrue.
287 % The format of the BlobToFile method is:
289 % MagickBooleanType BlobToFile(char *filename,const void *blob,
290 % const size_t length,ExceptionInfo *exception)
292 % A description of each parameter follows:
294 % o filename: Write the blob to this file.
296 % o blob: the address of a blob.
298 % o length: This length in bytes of the blob.
300 % o exception: return any errors or warnings in this structure.
303 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
304 const size_t length,ExceptionInfo *exception)
315 assert(filename != (const char *) NULL);
316 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
317 assert(blob != (const void *) NULL);
318 if (*filename == '\0')
319 file=AcquireUniqueFileResource(filename);
321 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
324 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
327 for (i=0; i < length; i+=count)
329 count=write(file,(const char *) blob+i,MagickMin(length-i,SSIZE_MAX));
338 if ((file == -1) || (i < length))
340 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 % B l o b T o I m a g e %
355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
357 % BlobToImage() implements direct to memory image formats. It returns the
360 % The format of the BlobToImage method is:
362 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
363 % const size_t length,ExceptionInfo *exception)
365 % A description of each parameter follows:
367 % o image_info: the image info.
369 % o blob: the address of a character stream in one of the image formats
370 % understood by ImageMagick.
372 % o length: This size_t integer reflects the length in bytes of the blob.
374 % o exception: return any errors or warnings in this structure.
377 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
378 const size_t length,ExceptionInfo *exception)
393 assert(image_info != (ImageInfo *) NULL);
394 assert(image_info->signature == MagickCoreSignature);
395 if (image_info->debug != MagickFalse)
396 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
397 image_info->filename);
398 assert(exception != (ExceptionInfo *) NULL);
399 if ((blob == (const void *) NULL) || (length == 0))
401 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
402 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
403 return((Image *) NULL);
405 blob_info=CloneImageInfo(image_info);
406 blob_info->blob=(void *) blob;
407 blob_info->length=length;
408 if (*blob_info->magick == '\0')
409 (void) SetImageInfo(blob_info,0,exception);
410 magick_info=GetMagickInfo(blob_info->magick,exception);
411 if (magick_info == (const MagickInfo *) NULL)
413 (void) ThrowMagickException(exception,GetMagickModule(),
414 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
416 blob_info=DestroyImageInfo(blob_info);
417 return((Image *) NULL);
419 if (GetMagickBlobSupport(magick_info) != MagickFalse)
422 Native blob support for this image format.
424 (void) CopyMagickString(blob_info->filename,image_info->filename,
426 (void) CopyMagickString(blob_info->magick,image_info->magick,
428 image=ReadImage(blob_info,exception);
429 if (image != (Image *) NULL)
430 (void) DetachBlob(image->blob);
431 blob_info=DestroyImageInfo(blob_info);
435 Write blob to a temporary file on disk.
437 blob_info->blob=(void *) NULL;
439 *blob_info->filename='\0';
440 status=BlobToFile(blob_info->filename,blob,length,exception);
441 if (status == MagickFalse)
443 (void) RelinquishUniqueFileResource(blob_info->filename);
444 blob_info=DestroyImageInfo(blob_info);
445 return((Image *) NULL);
447 clone_info=CloneImageInfo(blob_info);
448 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,"%s:%s",
449 blob_info->magick,blob_info->filename);
450 image=ReadImage(clone_info,exception);
451 if (image != (Image *) NULL)
457 Restore original filenames and image format.
459 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
461 (void) CopyMagickString(images->filename,image_info->filename,
463 (void) CopyMagickString(images->magick_filename,image_info->filename,
465 (void) CopyMagickString(images->magick,magick_info->name,
467 images=GetNextImageInList(images);
470 clone_info=DestroyImageInfo(clone_info);
471 (void) RelinquishUniqueFileResource(blob_info->filename);
472 blob_info=DestroyImageInfo(blob_info);
477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 + C l o n e B l o b I n f o %
485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
487 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
488 % blob info is NULL, a new one.
490 % The format of the CloneBlobInfo method is:
492 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
494 % A description of each parameter follows:
496 % o blob_info: the blob info.
499 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
504 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
505 if (clone_info == (BlobInfo *) NULL)
506 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
507 GetBlobInfo(clone_info);
508 if (blob_info == (BlobInfo *) NULL)
510 clone_info->length=blob_info->length;
511 clone_info->extent=blob_info->extent;
512 clone_info->synchronize=blob_info->synchronize;
513 clone_info->quantum=blob_info->quantum;
514 clone_info->mapped=blob_info->mapped;
515 clone_info->eof=blob_info->eof;
516 clone_info->offset=blob_info->offset;
517 clone_info->size=blob_info->size;
518 clone_info->exempt=blob_info->exempt;
519 clone_info->status=blob_info->status;
520 clone_info->temporary=blob_info->temporary;
521 clone_info->type=blob_info->type;
522 clone_info->file_info.file=blob_info->file_info.file;
523 clone_info->properties=blob_info->properties;
524 clone_info->stream=blob_info->stream;
525 clone_info->custom_stream=blob_info->custom_stream;
526 clone_info->data=blob_info->data;
527 clone_info->debug=IsEventLogging();
528 clone_info->reference_count=1;
533 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
537 + C l o s e B l o b %
541 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
543 % CloseBlob() closes a stream associated with the image.
545 % The format of the CloseBlob method is:
547 % MagickBooleanType CloseBlob(Image *image)
549 % A description of each parameter follows:
551 % o image: the image.
554 MagickExport MagickBooleanType CloseBlob(Image *image)
562 assert(image != (Image *) NULL);
563 assert(image->signature == MagickCoreSignature);
564 if (image->debug != MagickFalse)
565 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
566 assert(image->blob != (BlobInfo *) NULL);
567 if (image->blob->type == UndefinedStream)
569 status=SyncBlob(image);
570 switch (image->blob->type)
572 case UndefinedStream:
578 if (image->blob->synchronize != MagickFalse)
579 status=fsync(fileno(image->blob->file_info.file));
580 status=ferror(image->blob->file_info.file);
585 #if defined(MAGICKCORE_ZLIB_DELEGATE)
586 (void) gzerror(image->blob->file_info.gzfile,&status);
592 #if defined(MAGICKCORE_BZLIB_DELEGATE)
593 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
601 if ((image->blob->file_info.file != (FILE *) NULL) &&
602 (image->blob->synchronize != MagickFalse))
604 (void) fsync(fileno(image->blob->file_info.file));
605 status=ferror(image->blob->file_info.file);
612 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
613 image->blob->size=GetBlobSize(image);
614 image->extent=image->blob->size;
615 image->blob->eof=MagickFalse;
616 if (image->blob->exempt != MagickFalse)
618 image->blob->type=UndefinedStream;
619 return(image->blob->status);
621 switch (image->blob->type)
623 case UndefinedStream:
628 status=fclose(image->blob->file_info.file);
633 #if defined(MAGICKCORE_HAVE_PCLOSE)
634 status=pclose(image->blob->file_info.file);
640 #if defined(MAGICKCORE_ZLIB_DELEGATE)
641 status=gzclose(image->blob->file_info.gzfile);
647 #if defined(MAGICKCORE_BZLIB_DELEGATE)
648 BZ2_bzclose(image->blob->file_info.bzfile);
656 if (image->blob->file_info.file != (FILE *) NULL)
657 status=fclose(image->blob->file_info.file);
663 (void) DetachBlob(image->blob);
664 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
665 return(image->blob->status);
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673 + D e s t r o y B l o b %
677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 % DestroyBlob() deallocates memory associated with a blob.
681 % The format of the DestroyBlob method is:
683 % void DestroyBlob(Image *image)
685 % A description of each parameter follows:
687 % o image: the image.
690 MagickExport void DestroyBlob(Image *image)
695 assert(image != (Image *) NULL);
696 assert(image->signature == MagickCoreSignature);
697 if (image->debug != MagickFalse)
698 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
699 assert(image->blob != (BlobInfo *) NULL);
700 assert(image->blob->signature == MagickCoreSignature);
702 LockSemaphoreInfo(image->blob->semaphore);
703 image->blob->reference_count--;
704 assert(image->blob->reference_count >= 0);
705 if (image->blob->reference_count == 0)
707 UnlockSemaphoreInfo(image->blob->semaphore);
708 if (destroy == MagickFalse)
710 (void) CloseBlob(image);
711 if (image->blob->mapped != MagickFalse)
713 (void) UnmapBlob(image->blob->data,image->blob->length);
714 RelinquishMagickResource(MapResource,image->blob->length);
716 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
717 RelinquishSemaphoreInfo(&image->blob->semaphore);
718 image->blob->signature=(~MagickCoreSignature);
719 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
727 + D e s t r o y C u s t o m S t r e a m I n f o %
731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
733 % DestroyCustomStreamInfo() destroys memory associated with the
734 % CustomStreamInfo structure.
736 % The format of the DestroyCustomStreamInfo method is:
738 % CustomStreamInfo *DestroyCustomStreamInfo(CustomStreamInfo *stream_info)
740 % A description of each parameter follows:
742 % o custom_stream: the custom stream info.
745 MagickExport CustomStreamInfo *DestroyCustomStreamInfo(
746 CustomStreamInfo *custom_stream)
748 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
749 assert(custom_stream != (CustomStreamInfo *) NULL);
750 assert(custom_stream->signature == MagickCoreSignature);
751 custom_stream->signature=(~MagickCoreSignature);
752 custom_stream=(CustomStreamInfo *) RelinquishMagickMemory(custom_stream);
753 return(custom_stream);
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
761 + D e t a c h B l o b %
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767 % DetachBlob() detaches a blob from the BlobInfo structure.
769 % The format of the DetachBlob method is:
771 % void *DetachBlob(BlobInfo *blob_info)
773 % A description of each parameter follows:
775 % o blob_info: Specifies a pointer to a BlobInfo structure.
778 MagickExport void *DetachBlob(BlobInfo *blob_info)
783 assert(blob_info != (BlobInfo *) NULL);
784 if (blob_info->debug != MagickFalse)
785 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
786 if (blob_info->mapped != MagickFalse)
788 (void) UnmapBlob(blob_info->data,blob_info->length);
789 blob_info->data=(unsigned char *) NULL;
790 RelinquishMagickResource(MapResource,blob_info->length);
792 blob_info->mapped=MagickFalse;
795 blob_info->eof=MagickFalse;
796 blob_info->exempt=MagickFalse;
797 blob_info->type=UndefinedStream;
798 blob_info->file_info.file=(FILE *) NULL;
799 data=blob_info->data;
800 blob_info->data=(unsigned char *) NULL;
801 blob_info->stream=(StreamHandler) NULL;
802 blob_info->custom_stream=(CustomStreamInfo *) NULL;
807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
811 + D i s a s s o c i a t e B l o b %
815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817 % DisassociateBlob() disassociates the image stream. It checks if the
818 % blob of the specified image is referenced by other images. If the reference
819 % count is higher then 1 a new blob is assigned to the specified image.
821 % The format of the DisassociateBlob method is:
823 % void DisassociateBlob(const Image *image)
825 % A description of each parameter follows:
827 % o image: the image.
830 MagickExport void DisassociateBlob(Image *image)
838 assert(image != (Image *) NULL);
839 assert(image->signature == MagickCoreSignature);
840 if (image->debug != MagickFalse)
841 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
842 assert(image->blob != (BlobInfo *) NULL);
843 assert(image->blob->signature == MagickCoreSignature);
845 LockSemaphoreInfo(image->blob->semaphore);
846 assert(image->blob->reference_count >= 0);
847 if (image->blob->reference_count > 1)
849 UnlockSemaphoreInfo(image->blob->semaphore);
850 if (clone == MagickFalse)
852 blob=CloneBlobInfo(image->blob);
858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
862 + D i s c a r d B l o b B y t e s %
866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868 % DiscardBlobBytes() discards bytes in a blob.
870 % The format of the DiscardBlobBytes method is:
872 % MagickBooleanType DiscardBlobBytes(Image *image,
873 % const MagickSizeType length)
875 % A description of each parameter follows.
877 % o image: the image.
879 % o length: the number of bytes to skip.
882 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
883 const MagickSizeType length)
885 register MagickOffsetType
897 assert(image != (Image *) NULL);
898 assert(image->signature == MagickCoreSignature);
899 if (length != (MagickSizeType) ((MagickOffsetType) length))
902 for (i=0; i < (MagickOffsetType) length; i+=count)
904 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
905 (void) ReadBlobStream(image,quantum,buffer,&count);
913 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
917 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
921 + D u p l i c a t e s B l o b %
925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
927 % DuplicateBlob() duplicates a blob descriptor.
929 % The format of the DuplicateBlob method is:
931 % void DuplicateBlob(Image *image,const Image *duplicate)
933 % A description of each parameter follows:
935 % o image: the image.
937 % o duplicate: the duplicate image.
940 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
942 assert(image != (Image *) NULL);
943 assert(image->signature == MagickCoreSignature);
944 if (image->debug != MagickFalse)
945 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
946 assert(duplicate != (Image *) NULL);
947 assert(duplicate->signature == MagickCoreSignature);
949 image->blob=ReferenceBlob(duplicate->blob);
953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
963 % EOFBlob() returns a non-zero value when EOF has been detected reading from
966 % The format of the EOFBlob method is:
968 % int EOFBlob(const Image *image)
970 % A description of each parameter follows:
972 % o image: the image.
975 MagickExport int EOFBlob(const Image *image)
977 assert(image != (Image *) NULL);
978 assert(image->signature == MagickCoreSignature);
979 if (image->debug != MagickFalse)
980 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
981 assert(image->blob != (BlobInfo *) NULL);
982 assert(image->blob->type != UndefinedStream);
983 switch (image->blob->type)
985 case UndefinedStream:
991 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
997 image->blob->eof=MagickFalse;
1002 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1007 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
1008 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
1014 image->blob->eof=MagickFalse;
1022 return((int) image->blob->eof);
1026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030 % F i l e T o B l o b %
1034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1036 % FileToBlob() returns the contents of a file as a buffer terminated with
1037 % the '\0' character. The length of the buffer (not including the extra
1038 % terminating '\0' character) is returned via the 'length' parameter. Free
1039 % the buffer with RelinquishMagickMemory().
1041 % The format of the FileToBlob method is:
1043 % void *FileToBlob(const char *filename,const size_t extent,
1044 % size_t *length,ExceptionInfo *exception)
1046 % A description of each parameter follows:
1048 % o blob: FileToBlob() returns the contents of a file as a blob. If
1049 % an error occurs NULL is returned.
1051 % o filename: the filename.
1053 % o extent: The maximum length of the blob.
1055 % o length: On return, this reflects the actual length of the blob.
1057 % o exception: return any errors or warnings in this structure.
1060 MagickExport void *FileToBlob(const char *filename,const size_t extent,
1061 size_t *length,ExceptionInfo *exception)
1081 assert(filename != (const char *) NULL);
1082 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1083 assert(exception != (ExceptionInfo *) NULL);
1086 if (LocaleCompare(filename,"-") != 0)
1087 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1090 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
1093 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
1095 if ((file == fileno(stdin)) || (offset < 0) ||
1096 (offset != (MagickOffsetType) ((ssize_t) offset)))
1105 Stream is not seekable.
1107 offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
1108 quantum=(size_t) MagickMaxBufferExtent;
1109 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1110 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1111 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1112 for (i=0; blob != (unsigned char *) NULL; i+=count)
1114 count=read(file,blob+i,quantum);
1121 if (~((size_t) i) < (quantum+1))
1123 blob=(unsigned char *) RelinquishMagickMemory(blob);
1126 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
1128 if ((size_t) (i+count) >= extent)
1131 if (LocaleCompare(filename,"-") != 0)
1133 if (blob == (unsigned char *) NULL)
1135 (void) ThrowMagickException(exception,GetMagickModule(),
1136 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1141 blob=(unsigned char *) RelinquishMagickMemory(blob);
1142 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1145 *length=(size_t) MagickMin(i+count,extent);
1149 *length=(size_t) MagickMin(offset,(MagickOffsetType)
1150 MagickMin(extent,SSIZE_MAX));
1151 blob=(unsigned char *) NULL;
1152 if (~(*length) >= (MagickPathExtent-1))
1153 blob=(unsigned char *) AcquireQuantumMemory(*length+MagickPathExtent,
1155 if (blob == (unsigned char *) NULL)
1158 (void) ThrowMagickException(exception,GetMagickModule(),
1159 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1162 map=MapBlob(file,ReadMode,0,*length);
1163 if (map != (unsigned char *) NULL)
1165 (void) memcpy(blob,map,*length);
1166 (void) UnmapBlob(map,*length);
1170 (void) lseek(file,0,SEEK_SET);
1171 for (i=0; i < *length; i+=count)
1173 count=read(file,blob+i,(size_t) MagickMin(*length-i,SSIZE_MAX));
1184 blob=(unsigned char *) RelinquishMagickMemory(blob);
1185 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1190 if (LocaleCompare(filename,"-") != 0)
1194 blob=(unsigned char *) RelinquishMagickMemory(blob);
1195 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1205 % F i l e T o I m a g e %
1209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1211 % FileToImage() write the contents of a file to an image.
1213 % The format of the FileToImage method is:
1215 % MagickBooleanType FileToImage(Image *,const char *filename)
1217 % A description of each parameter follows:
1219 % o image: the image.
1221 % o filename: the filename.
1225 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1231 register unsigned char
1234 assert(image->blob != (BlobInfo *) NULL);
1235 assert(image->blob->type != UndefinedStream);
1236 assert(data != NULL);
1237 if (image->blob->type != BlobStream)
1238 return(WriteBlob(image,length,(const unsigned char *) data));
1239 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1240 if (extent >= image->blob->extent)
1242 extent=image->blob->extent+image->blob->quantum+length;
1243 image->blob->quantum<<=1;
1244 if (SetBlobExtent(image,extent) == MagickFalse)
1247 q=image->blob->data+image->blob->offset;
1248 (void) memcpy(q,data,length);
1249 image->blob->offset+=length;
1250 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1251 image->blob->length=(size_t) image->blob->offset;
1252 return((ssize_t) length);
1255 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1256 ExceptionInfo *exception)
1274 assert(image != (const Image *) NULL);
1275 assert(image->signature == MagickCoreSignature);
1276 assert(filename != (const char *) NULL);
1277 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1279 if (LocaleCompare(filename,"-") != 0)
1280 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1283 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1284 return(MagickFalse);
1286 quantum=(size_t) MagickMaxBufferExtent;
1287 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1288 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1289 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1290 if (blob == (unsigned char *) NULL)
1293 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1295 return(MagickFalse);
1299 count=read(file,blob,quantum);
1306 length=(size_t) count;
1307 count=WriteBlobStream(image,length,blob);
1308 if (count != (ssize_t) length)
1310 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1316 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1317 blob=(unsigned char *) RelinquishMagickMemory(blob);
1322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326 + G e t B l o b E r r o r %
1330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332 % GetBlobError() returns MagickTrue if the blob associated with the specified
1333 % image encountered an error.
1335 % The format of the GetBlobError method is:
1337 % MagickBooleanType GetBlobError(const Image *image)
1339 % A description of each parameter follows:
1341 % o image: the image.
1344 MagickExport MagickBooleanType GetBlobError(const Image *image)
1346 assert(image != (const Image *) NULL);
1347 assert(image->signature == MagickCoreSignature);
1348 if (image->debug != MagickFalse)
1349 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1350 return(image->blob->status);
1354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1358 + G e t B l o b F i l e H a n d l e %
1362 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1364 % GetBlobFileHandle() returns the file handle associated with the image blob.
1366 % The format of the GetBlobFile method is:
1368 % FILE *GetBlobFileHandle(const Image *image)
1370 % A description of each parameter follows:
1372 % o image: the image.
1375 MagickExport FILE *GetBlobFileHandle(const Image *image)
1377 assert(image != (const Image *) NULL);
1378 assert(image->signature == MagickCoreSignature);
1379 return(image->blob->file_info.file);
1383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1387 + G e t B l o b I n f o %
1391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1393 % GetBlobInfo() initializes the BlobInfo structure.
1395 % The format of the GetBlobInfo method is:
1397 % void GetBlobInfo(BlobInfo *blob_info)
1399 % A description of each parameter follows:
1401 % o blob_info: Specifies a pointer to a BlobInfo structure.
1404 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1406 assert(blob_info != (BlobInfo *) NULL);
1407 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1408 blob_info->type=UndefinedStream;
1409 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1410 blob_info->properties.st_mtime=time((time_t *) NULL);
1411 blob_info->properties.st_ctime=time((time_t *) NULL);
1412 blob_info->debug=IsEventLogging();
1413 blob_info->reference_count=1;
1414 blob_info->semaphore=AcquireSemaphoreInfo();
1415 blob_info->signature=MagickCoreSignature;
1419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1423 % G e t B l o b P r o p e r t i e s %
1427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1429 % GetBlobProperties() returns information about an image blob.
1431 % The format of the GetBlobProperties method is:
1433 % const struct stat *GetBlobProperties(const Image *image)
1435 % A description of each parameter follows:
1437 % o image: the image.
1440 MagickExport const struct stat *GetBlobProperties(const Image *image)
1442 assert(image != (Image *) NULL);
1443 assert(image->signature == MagickCoreSignature);
1444 if (image->debug != MagickFalse)
1445 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1446 return(&image->blob->properties);
1450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1454 + G e t B l o b S i z e %
1458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1460 % GetBlobSize() returns the current length of the image file or blob; zero is
1461 % returned if the size cannot be determined.
1463 % The format of the GetBlobSize method is:
1465 % MagickSizeType GetBlobSize(const Image *image)
1467 % A description of each parameter follows:
1469 % o image: the image.
1472 MagickExport MagickSizeType GetBlobSize(const Image *image)
1477 assert(image != (Image *) NULL);
1478 assert(image->signature == MagickCoreSignature);
1479 if (image->debug != MagickFalse)
1480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1481 assert(image->blob != (BlobInfo *) NULL);
1483 switch (image->blob->type)
1485 case UndefinedStream:
1486 case StandardStream:
1488 extent=image->blob->size;
1493 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1494 extent=(MagickSizeType) image->blob->properties.st_size;
1499 extent=image->blob->size;
1508 status=GetPathAttributes(image->filename,&image->blob->properties);
1509 if (status != MagickFalse)
1510 extent=(MagickSizeType) image->blob->properties.st_size;
1517 extent=(MagickSizeType) image->blob->length;
1527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1531 + G e t B l o b S t r e a m D a t a %
1535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1537 % GetBlobStreamData() returns the stream data for the image.
1539 % The format of the GetBlobStreamData method is:
1541 % void *GetBlobStreamData(const Image *image)
1543 % A description of each parameter follows:
1545 % o image: the image.
1548 MagickExport void *GetBlobStreamData(const Image *image)
1550 assert(image != (const Image *) NULL);
1551 assert(image->signature == MagickCoreSignature);
1552 return(image->blob->data);
1556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1560 + G e t B l o b S t r e a m H a n d l e r %
1564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1566 % GetBlobStreamHandler() returns the stream handler for the image.
1568 % The format of the GetBlobStreamHandler method is:
1570 % StreamHandler GetBlobStreamHandler(const Image *image)
1572 % A description of each parameter follows:
1574 % o image: the image.
1577 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1579 assert(image != (const Image *) NULL);
1580 assert(image->signature == MagickCoreSignature);
1581 if (image->debug != MagickFalse)
1582 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1583 return(image->blob->stream);
1587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1591 % I m a g e T o B l o b %
1595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1597 % ImageToBlob() implements direct to memory image formats. It returns the
1598 % image as a formatted blob and its length. The magick member of the Image
1599 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1600 % etc.). This method is the equivalent of WriteImage(), but writes the
1601 % formatted "file" to a memory buffer rather than to an actual file.
1603 % The format of the ImageToBlob method is:
1605 % void *ImageToBlob(const ImageInfo *image_info,Image *image,
1606 % size_t *length,ExceptionInfo *exception)
1608 % A description of each parameter follows:
1610 % o image_info: the image info.
1612 % o image: the image.
1614 % o length: return the actual length of the blob.
1616 % o exception: return any errors or warnings in this structure.
1619 MagickExport void *ImageToBlob(const ImageInfo *image_info,
1620 Image *image,size_t *length,ExceptionInfo *exception)
1634 assert(image_info != (const ImageInfo *) NULL);
1635 assert(image_info->signature == MagickCoreSignature);
1636 if (image_info->debug != MagickFalse)
1637 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1638 image_info->filename);
1639 assert(image != (Image *) NULL);
1640 assert(image->signature == MagickCoreSignature);
1641 assert(exception != (ExceptionInfo *) NULL);
1643 blob=(unsigned char *) NULL;
1644 blob_info=CloneImageInfo(image_info);
1645 blob_info->adjoin=MagickFalse;
1646 (void) SetImageInfo(blob_info,1,exception);
1647 if (*blob_info->magick != '\0')
1648 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1649 magick_info=GetMagickInfo(image->magick,exception);
1650 if (magick_info == (const MagickInfo *) NULL)
1652 (void) ThrowMagickException(exception,GetMagickModule(),
1653 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1655 blob_info=DestroyImageInfo(blob_info);
1658 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1659 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1662 Native blob support for this image format.
1664 blob_info->length=0;
1665 blob_info->blob=AcquireQuantumMemory(MagickMaxBlobExtent,
1666 sizeof(unsigned char));
1667 if (blob_info->blob == NULL)
1668 (void) ThrowMagickException(exception,GetMagickModule(),
1669 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1672 (void) CloseBlob(image);
1673 image->blob->exempt=MagickTrue;
1674 *image->filename='\0';
1675 status=WriteImage(blob_info,image,exception);
1676 *length=image->blob->length;
1677 blob=DetachBlob(image->blob);
1678 if (status == MagickFalse)
1679 blob=RelinquishMagickMemory(blob);
1681 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1687 unique[MagickPathExtent];
1693 Write file to disk in blob image format.
1695 file=AcquireUniqueFileResource(unique);
1698 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1699 image_info->filename);
1703 blob_info->file=fdopen(file,"wb");
1704 if (blob_info->file != (FILE *) NULL)
1706 (void) FormatLocaleString(image->filename,MagickPathExtent,
1707 "%s:%s",image->magick,unique);
1708 status=WriteImage(blob_info,image,exception);
1709 (void) CloseBlob(image);
1710 (void) fclose(blob_info->file);
1711 if (status != MagickFalse)
1712 blob=FileToBlob(unique,~0UL,length,exception);
1714 (void) RelinquishUniqueFileResource(unique);
1717 blob_info=DestroyImageInfo(blob_info);
1722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1726 + I m a g e T o C u s t o m S t r e a m %
1730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1732 % ImageToCustomStream() is the equivalent of WriteImage(), but writes the
1733 % formatted "file" to the custom stream rather than to an actual file.
1735 % The format of the ImageToCustomStream method is:
1737 % void ImageToCustomStream(const ImageInfo *image_info,Image *image,
1738 % ExceptionInfo *exception)
1740 % A description of each parameter follows:
1742 % o image_info: the image info.
1744 % o image: the image.
1746 % o exception: return any errors or warnings in this structure.
1749 MagickExport void ImageToCustomStream(const ImageInfo *image_info,Image *image,
1750 ExceptionInfo *exception)
1761 assert(image_info != (const ImageInfo *) NULL);
1762 assert(image_info->signature == MagickCoreSignature);
1763 if (image_info->debug != MagickFalse)
1764 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1765 image_info->filename);
1766 assert(image != (Image *) NULL);
1767 assert(image->signature == MagickCoreSignature);
1768 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
1769 assert(image_info->custom_stream->signature == MagickCoreSignature);
1770 assert(image_info->custom_stream->writer != (CustomStreamHandler) NULL);
1771 assert(exception != (ExceptionInfo *) NULL);
1772 blob_info=CloneImageInfo(image_info);
1773 blob_info->adjoin=MagickFalse;
1774 (void) SetImageInfo(blob_info,1,exception);
1775 if (*blob_info->magick != '\0')
1776 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1777 magick_info=GetMagickInfo(image->magick,exception);
1778 if (magick_info == (const MagickInfo *) NULL)
1780 (void) ThrowMagickException(exception,GetMagickModule(),
1781 MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'",
1783 blob_info=DestroyImageInfo(blob_info);
1786 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1787 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1790 Native blob support for this image format.
1792 (void) CloseBlob(image);
1793 *image->filename='\0';
1794 (void) WriteImage(blob_info,image,exception);
1795 (void) CloseBlob(image);
1800 unique[MagickPathExtent];
1809 Write file to disk in blob image format.
1811 blob_info->custom_stream=(CustomStreamInfo *) NULL;
1812 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
1814 if (blob == (unsigned char *) NULL)
1816 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1817 image_info->filename);
1818 blob_info=DestroyImageInfo(blob_info);
1821 file=AcquireUniqueFileResource(unique);
1824 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1825 image_info->filename);
1826 blob=(unsigned char *) RelinquishMagickMemory(blob);
1827 blob_info=DestroyImageInfo(blob_info);
1830 blob_info->file=fdopen(file,"wb+");
1831 if (blob_info->file != (FILE *) NULL)
1836 (void) FormatLocaleString(image->filename,MagickPathExtent,
1837 "%s:%s",image->magick,unique);
1838 status=WriteImage(blob_info,image,exception);
1839 (void) CloseBlob(image);
1840 if (status != MagickFalse)
1842 (void) fseek(blob_info->file,0,SEEK_SET);
1843 count=(ssize_t) MagickMaxBufferExtent;
1844 while (count == (ssize_t) MagickMaxBufferExtent)
1846 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
1848 image_info->custom_stream->writer(blob,count,
1849 image_info->custom_stream->data);
1852 (void) fclose(blob_info->file);
1854 blob=(unsigned char *) RelinquishMagickMemory(blob);
1855 (void) RelinquishUniqueFileResource(unique);
1857 blob_info=DestroyImageInfo(blob_info);
1861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1865 % I m a g e T o F i l e %
1869 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1871 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1872 % occurs otherwise MagickTrue.
1874 % The format of the ImageToFile method is:
1876 % MagickBooleanType ImageToFile(Image *image,char *filename,
1877 % ExceptionInfo *exception)
1879 % A description of each parameter follows:
1881 % o image: the image.
1883 % o filename: Write the image to this file.
1885 % o exception: return any errors or warnings in this structure.
1888 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1889 ExceptionInfo *exception)
1894 register const unsigned char
1913 assert(image != (Image *) NULL);
1914 assert(image->signature == MagickCoreSignature);
1915 assert(image->blob != (BlobInfo *) NULL);
1916 assert(image->blob->type != UndefinedStream);
1917 if (image->debug != MagickFalse)
1918 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1919 assert(filename != (const char *) NULL);
1920 if (*filename == '\0')
1921 file=AcquireUniqueFileResource(filename);
1923 if (LocaleCompare(filename,"-") == 0)
1924 file=fileno(stdout);
1926 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1929 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1930 return(MagickFalse);
1932 quantum=(size_t) MagickMaxBufferExtent;
1933 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1934 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1935 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1936 if (buffer == (unsigned char *) NULL)
1939 (void) ThrowMagickException(exception,GetMagickModule(),
1940 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1941 return(MagickFalse);
1944 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1945 for (i=0; count > 0; )
1947 length=(size_t) count;
1948 for (i=0; i < length; i+=count)
1950 count=write(file,p+i,(size_t) (length-i));
1960 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1962 if (LocaleCompare(filename,"-") != 0)
1964 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1965 if ((file == -1) || (i < length))
1969 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1970 return(MagickFalse);
1976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1980 % I m a g e s T o B l o b %
1984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1986 % ImagesToBlob() implements direct to memory image formats. It returns the
1987 % image sequence as a blob and its length. The magick member of the ImageInfo
1988 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1990 % Note, some image formats do not permit multiple images to the same image
1991 % stream (e.g. JPEG). in this instance, just the first image of the
1992 % sequence is returned as a blob.
1994 % The format of the ImagesToBlob method is:
1996 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1997 % size_t *length,ExceptionInfo *exception)
1999 % A description of each parameter follows:
2001 % o image_info: the image info.
2003 % o images: the image list.
2005 % o length: return the actual length of the blob.
2007 % o exception: return any errors or warnings in this structure.
2010 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
2011 size_t *length,ExceptionInfo *exception)
2025 assert(image_info != (const ImageInfo *) NULL);
2026 assert(image_info->signature == MagickCoreSignature);
2027 if (image_info->debug != MagickFalse)
2028 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2029 image_info->filename);
2030 assert(images != (Image *) NULL);
2031 assert(images->signature == MagickCoreSignature);
2032 assert(exception != (ExceptionInfo *) NULL);
2034 blob=(unsigned char *) NULL;
2035 blob_info=CloneImageInfo(image_info);
2036 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2038 if (*blob_info->magick != '\0')
2039 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2040 magick_info=GetMagickInfo(images->magick,exception);
2041 if (magick_info == (const MagickInfo *) NULL)
2043 (void) ThrowMagickException(exception,GetMagickModule(),
2044 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
2046 blob_info=DestroyImageInfo(blob_info);
2049 if (GetMagickAdjoin(magick_info) == MagickFalse)
2051 blob_info=DestroyImageInfo(blob_info);
2052 return(ImageToBlob(image_info,images,length,exception));
2054 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2055 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2058 Native blob support for this images format.
2060 blob_info->length=0;
2061 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
2062 sizeof(unsigned char));
2063 if (blob_info->blob == (void *) NULL)
2064 (void) ThrowMagickException(exception,GetMagickModule(),
2065 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
2068 (void) CloseBlob(images);
2069 images->blob->exempt=MagickTrue;
2070 *images->filename='\0';
2071 status=WriteImages(blob_info,images,images->filename,exception);
2072 *length=images->blob->length;
2073 blob=DetachBlob(images->blob);
2074 if (status == MagickFalse)
2075 blob=RelinquishMagickMemory(blob);
2077 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
2083 filename[MagickPathExtent],
2084 unique[MagickPathExtent];
2090 Write file to disk in blob images format.
2092 file=AcquireUniqueFileResource(unique);
2095 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
2096 image_info->filename);
2100 blob_info->file=fdopen(file,"wb");
2101 if (blob_info->file != (FILE *) NULL)
2103 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2104 images->magick,unique);
2105 status=WriteImages(blob_info,images,filename,exception);
2106 (void) CloseBlob(images);
2107 (void) fclose(blob_info->file);
2108 if (status != MagickFalse)
2109 blob=FileToBlob(unique,~0UL,length,exception);
2111 (void) RelinquishUniqueFileResource(unique);
2114 blob_info=DestroyImageInfo(blob_info);
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2123 + I m a g e s T o C u s t o m B l o b %
2127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2129 % ImagesToCustomStream() is the equivalent of WriteImages(), but writes the
2130 % formatted "file" to the custom stream rather than to an actual file.
2132 % The format of the ImageToCustomStream method is:
2134 % void ImagesToCustomStream(const ImageInfo *image_info,Image *images,
2135 % ExceptionInfo *exception)
2137 % A description of each parameter follows:
2139 % o image_info: the image info.
2141 % o images: the image list.
2143 % o exception: return any errors or warnings in this structure.
2146 MagickExport void ImagesToCustomStream(const ImageInfo *image_info,
2147 Image *images,ExceptionInfo *exception)
2158 assert(image_info != (const ImageInfo *) NULL);
2159 assert(image_info->signature == MagickCoreSignature);
2160 if (image_info->debug != MagickFalse)
2161 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2162 image_info->filename);
2163 assert(images != (Image *) NULL);
2164 assert(images->signature == MagickCoreSignature);
2165 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
2166 assert(image_info->custom_stream->signature == MagickCoreSignature);
2167 assert(image_info->custom_stream->reader != (CustomStreamHandler) NULL);
2168 assert(image_info->custom_stream->writer != (CustomStreamHandler) NULL);
2169 assert(exception != (ExceptionInfo *) NULL);
2170 blob_info=CloneImageInfo(image_info);
2171 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2173 if (*blob_info->magick != '\0')
2174 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2175 magick_info=GetMagickInfo(images->magick,exception);
2176 if (magick_info == (const MagickInfo *) NULL)
2178 (void) ThrowMagickException(exception,GetMagickModule(),
2179 MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'",
2181 blob_info=DestroyImageInfo(blob_info);
2184 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2185 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2188 Native blob support for this image format.
2190 (void) CloseBlob(images);
2191 *images->filename='\0';
2192 (void) WriteImages(blob_info,images,images->filename,exception);
2193 (void) CloseBlob(images);
2198 filename[MagickPathExtent],
2199 unique[MagickPathExtent];
2208 Write file to disk in blob image format.
2210 blob_info->custom_stream=(CustomStreamInfo *) NULL;
2211 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
2213 if (blob == (unsigned char *) NULL)
2215 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2216 image_info->filename);
2217 blob_info=DestroyImageInfo(blob_info);
2220 file=AcquireUniqueFileResource(unique);
2223 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2224 image_info->filename);
2225 blob=(unsigned char *) RelinquishMagickMemory(blob);
2226 blob_info=DestroyImageInfo(blob_info);
2229 blob_info->file=fdopen(file,"wb+");
2230 if (blob_info->file != (FILE *) NULL)
2235 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2236 images->magick,unique);
2237 status=WriteImages(blob_info,images,filename,exception);
2238 (void) CloseBlob(images);
2239 if (status != MagickFalse)
2241 (void) fseek(blob_info->file,0,SEEK_SET);
2242 count=(ssize_t) MagickMaxBufferExtent;
2243 while (count == (ssize_t) MagickMaxBufferExtent)
2245 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
2247 image_info->custom_stream->writer(blob,count,
2248 image_info->custom_stream->data);
2251 (void) fclose(blob_info->file);
2253 blob=(unsigned char *) RelinquishMagickMemory(blob);
2254 (void) RelinquishUniqueFileResource(unique);
2256 blob_info=DestroyImageInfo(blob_info);
2261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2265 % I n j e c t I m a g e B l o b %
2269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2271 % InjectImageBlob() injects the image with a copy of itself in the specified
2272 % format (e.g. inject JPEG into a PDF image).
2274 % The format of the InjectImageBlob method is:
2276 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2277 % Image *image,Image *inject_image,const char *format,
2278 % ExceptionInfo *exception)
2280 % A description of each parameter follows:
2282 % o image_info: the image info..
2284 % o image: the image.
2286 % o inject_image: inject into the image stream.
2288 % o format: the image format.
2290 % o exception: return any errors or warnings in this structure.
2293 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2294 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
2297 filename[MagickPathExtent];
2330 Write inject image to a temporary file.
2332 assert(image_info != (ImageInfo *) NULL);
2333 assert(image_info->signature == MagickCoreSignature);
2334 assert(image != (Image *) NULL);
2335 assert(image->signature == MagickCoreSignature);
2336 if (image->debug != MagickFalse)
2337 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2338 assert(inject_image != (Image *) NULL);
2339 assert(inject_image->signature == MagickCoreSignature);
2340 assert(exception != (ExceptionInfo *) NULL);
2341 unique_file=(FILE *) NULL;
2342 file=AcquireUniqueFileResource(filename);
2344 unique_file=fdopen(file,"wb");
2345 if ((file == -1) || (unique_file == (FILE *) NULL))
2347 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2348 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
2350 return(MagickFalse);
2352 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
2353 if (byte_image == (Image *) NULL)
2355 (void) fclose(unique_file);
2356 (void) RelinquishUniqueFileResource(filename);
2357 return(MagickFalse);
2359 (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",
2361 DestroyBlob(byte_image);
2362 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
2363 write_info=CloneImageInfo(image_info);
2364 SetImageInfoFile(write_info,unique_file);
2365 status=WriteImage(write_info,byte_image,exception);
2366 write_info=DestroyImageInfo(write_info);
2367 byte_image=DestroyImage(byte_image);
2368 (void) fclose(unique_file);
2369 if (status == MagickFalse)
2371 (void) RelinquishUniqueFileResource(filename);
2372 return(MagickFalse);
2375 Inject into image stream.
2377 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
2380 (void) RelinquishUniqueFileResource(filename);
2381 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
2382 image_info->filename);
2383 return(MagickFalse);
2385 quantum=(size_t) MagickMaxBufferExtent;
2386 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
2387 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2388 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2389 if (buffer == (unsigned char *) NULL)
2391 (void) RelinquishUniqueFileResource(filename);
2393 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2396 for (i=0; ; i+=count)
2398 count=read(file,buffer,quantum);
2405 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2410 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2411 (void) RelinquishUniqueFileResource(filename);
2412 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2421 % I s B l o b E x e m p t %
2425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2427 % IsBlobExempt() returns true if the blob is exempt.
2429 % The format of the IsBlobExempt method is:
2431 % MagickBooleanType IsBlobExempt(const Image *image)
2433 % A description of each parameter follows:
2435 % o image: the image.
2438 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
2440 assert(image != (const Image *) NULL);
2441 assert(image->signature == MagickCoreSignature);
2442 if (image->debug != MagickFalse)
2443 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2444 return(image->blob->exempt);
2448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2452 % I s B l o b S e e k a b l e %
2456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2458 % IsBlobSeekable() returns true if the blob is seekable.
2460 % The format of the IsBlobSeekable method is:
2462 % MagickBooleanType IsBlobSeekable(const Image *image)
2464 % A description of each parameter follows:
2466 % o image: the image.
2469 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2474 assert(image != (const Image *) NULL);
2475 assert(image->signature == MagickCoreSignature);
2476 if (image->debug != MagickFalse)
2477 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2478 switch (image->blob->type)
2484 seekable=MagickTrue;
2487 case UndefinedStream:
2488 case StandardStream:
2494 seekable=MagickFalse;
2499 if ((image->blob->custom_stream->seeker != (CustomStreamSeeker) NULL) &&
2500 (image->blob->custom_stream->teller != (CustomStreamTeller) NULL))
2501 seekable=MagickTrue;
2503 seekable=MagickFalse;
2511 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2515 % I s B l o b T e m p o r a r y %
2519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2521 % IsBlobTemporary() returns true if the blob is temporary.
2523 % The format of the IsBlobTemporary method is:
2525 % MagickBooleanType IsBlobTemporary(const Image *image)
2527 % A description of each parameter follows:
2529 % o image: the image.
2532 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2534 assert(image != (const Image *) NULL);
2535 assert(image->signature == MagickCoreSignature);
2536 if (image->debug != MagickFalse)
2537 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2538 return(image->blob->temporary);
2542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2552 % MapBlob() creates a mapping from a file to a binary large object.
2554 % The format of the MapBlob method is:
2556 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2557 % const size_t length)
2559 % A description of each parameter follows:
2561 % o file: map this file descriptor.
2563 % o mode: ReadMode, WriteMode, or IOMode.
2565 % o offset: starting at this offset within the file.
2567 % o length: the length of the mapping is returned in this pointer.
2570 MagickExport void *MapBlob(int file,const MapMode mode,
2571 const MagickOffsetType offset,const size_t length)
2573 #if defined(MAGICKCORE_HAVE_MMAP)
2586 #if defined(MAP_ANONYMOUS)
2587 flags|=MAP_ANONYMOUS;
2596 protection=PROT_READ;
2602 protection=PROT_WRITE;
2608 protection=PROT_READ | PROT_WRITE;
2613 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2614 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2616 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2618 if (map == MAP_FAILED)
2619 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2621 if (map == MAP_FAILED)
2634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2638 + M S B O r d e r L o n g %
2642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2644 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2645 % most-significant byte first.
2647 % The format of the MSBOrderLong method is:
2649 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2651 % A description of each parameter follows.
2653 % o buffer: Specifies a pointer to a buffer of integers.
2655 % o length: Specifies the length of the buffer.
2658 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2663 register unsigned char
2667 assert(buffer != (unsigned char *) NULL);
2674 *buffer++=(unsigned char) c;
2678 *buffer++=(unsigned char) c;
2684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2688 + M S B O r d e r S h o r t %
2692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2694 % MSBOrderShort() converts a least-significant byte first buffer of integers
2695 % to most-significant byte first.
2697 % The format of the MSBOrderShort method is:
2699 % void MSBOrderShort(unsigned char *p,const size_t length)
2701 % A description of each parameter follows.
2703 % o p: Specifies a pointer to a buffer of integers.
2705 % o length: Specifies the length of the buffer.
2708 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2713 register unsigned char
2716 assert(p != (unsigned char *) NULL);
2723 *p++=(unsigned char) c;
2728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2738 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2739 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2740 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2741 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2742 % from a system command.
2744 % The format of the OpenBlob method is:
2746 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2747 % const BlobMode mode,ExceptionInfo *exception)
2749 % A description of each parameter follows:
2751 % o image_info: the image info.
2753 % o image: the image.
2755 % o mode: the mode for opening the file.
2759 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2772 option=GetImageOption(image_info,"stream:buffer-size");
2773 if (option != (const char *) NULL)
2774 size=StringToUnsignedLong(option);
2775 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2776 _IONBF : _IOFBF,size);
2777 return(status == 0 ? MagickTrue : MagickFalse);
2780 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2781 Image *image,const BlobMode mode,ExceptionInfo *exception)
2784 extension[MagickPathExtent],
2785 filename[MagickPathExtent];
2796 assert(image_info != (ImageInfo *) NULL);
2797 assert(image_info->signature == MagickCoreSignature);
2798 if (image_info->debug != MagickFalse)
2799 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2800 image_info->filename);
2801 assert(image != (Image *) NULL);
2802 assert(image->signature == MagickCoreSignature);
2803 if (image_info->blob != (void *) NULL)
2805 if (image_info->stream != (StreamHandler) NULL)
2806 image->blob->stream=(StreamHandler) image_info->stream;
2807 AttachBlob(image->blob,image_info->blob,image_info->length);
2810 if ((image_info->custom_stream != (CustomStreamInfo *) NULL) &&
2811 (*image->filename == '\0'))
2813 image->blob->type=CustomStream;
2814 image->blob->custom_stream=image_info->custom_stream;
2817 (void) DetachBlob(image->blob);
2820 default: type="r"; break;
2821 case ReadBlobMode: type="r"; break;
2822 case ReadBinaryBlobMode: type="rb"; break;
2823 case WriteBlobMode: type="w"; break;
2824 case WriteBinaryBlobMode: type="w+b"; break;
2825 case AppendBlobMode: type="a"; break;
2826 case AppendBinaryBlobMode: type="a+b"; break;
2829 image->blob->synchronize=image_info->synchronize;
2830 if (image_info->stream != (StreamHandler) NULL)
2832 image->blob->stream=image_info->stream;
2835 image->blob->type=FifoStream;
2843 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2844 rights=ReadPolicyRights;
2846 rights=WritePolicyRights;
2847 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2850 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2851 "NotAuthorized","`%s'",filename);
2852 return(MagickFalse);
2854 if ((LocaleCompare(filename,"-") == 0) ||
2855 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2857 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2858 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2859 if (strchr(type,'b') != (char *) NULL)
2860 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2862 image->blob->type=StandardStream;
2863 image->blob->exempt=MagickTrue;
2864 return(SetStreamBuffering(image_info,image));
2866 if (LocaleNCompare(filename,"fd:",3) == 0)
2869 fileMode[MagickPathExtent];
2873 image->blob->file_info.file=fdopen(StringToLong(filename+3),fileMode);
2874 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2875 if (strchr(type,'b') != (char *) NULL)
2876 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2878 image->blob->type=StandardStream;
2879 image->blob->exempt=MagickTrue;
2880 return(SetStreamBuffering(image_info,image));
2882 #if defined(MAGICKCORE_HAVE_POPEN) && defined(MAGICKCORE_PIPES_SUPPORT)
2883 if (*filename == '|')
2886 fileMode[MagickPathExtent],
2890 Pipe image to or from a system command.
2892 #if defined(SIGPIPE)
2894 (void) signal(SIGPIPE,SIG_IGN);
2898 sanitize_command=SanitizeString(filename+1);
2899 image->blob->file_info.file=(FILE *) popen_utf8(sanitize_command,
2901 sanitize_command=DestroyString(sanitize_command);
2902 if (image->blob->file_info.file == (FILE *) NULL)
2904 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2905 return(MagickFalse);
2907 image->blob->type=PipeStream;
2908 image->blob->exempt=MagickTrue;
2909 return(SetStreamBuffering(image_info,image));
2912 status=GetPathAttributes(filename,&image->blob->properties);
2913 #if defined(S_ISFIFO)
2914 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2916 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2917 if (image->blob->file_info.file == (FILE *) NULL)
2919 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2920 return(MagickFalse);
2922 image->blob->type=FileStream;
2923 image->blob->exempt=MagickTrue;
2924 return(SetStreamBuffering(image_info,image));
2927 GetPathComponent(image->filename,ExtensionPath,extension);
2930 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2931 if ((image_info->adjoin == MagickFalse) ||
2932 (strchr(filename,'%') != (char *) NULL))
2935 Form filename for multi-part images.
2937 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2938 image->scene,filename,exception);
2939 if ((LocaleCompare(filename,image->filename) == 0) &&
2940 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2941 (GetNextImageInList(image) != (Image *) NULL)))
2944 path[MagickPathExtent];
2946 GetPathComponent(image->filename,RootPath,path);
2947 if (*extension == '\0')
2948 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
2949 path,(double) image->scene);
2951 (void) FormatLocaleString(filename,MagickPathExtent,
2952 "%s-%.20g.%s",path,(double) image->scene,extension);
2954 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2955 #if defined(macintosh)
2956 SetApplicationType(filename,image_info->magick,'8BIM');
2960 if (image_info->file != (FILE *) NULL)
2962 image->blob->file_info.file=image_info->file;
2963 image->blob->type=FileStream;
2964 image->blob->exempt=MagickTrue;
2969 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2970 if (image->blob->file_info.file != (FILE *) NULL)
2978 image->blob->type=FileStream;
2979 (void) SetStreamBuffering(image_info,image);
2980 (void) ResetMagickMemory(magick,0,sizeof(magick));
2981 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2982 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2983 #if defined(MAGICKCORE_POSIX_SUPPORT)
2984 (void) fflush(image->blob->file_info.file);
2986 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2987 " read %.20g magic header bytes",(double) count);
2988 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2989 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2990 ((int) magick[2] == 0x08))
2992 if (image->blob->file_info.file != (FILE *) NULL)
2993 (void) fclose(image->blob->file_info.file);
2994 image->blob->file_info.file=(FILE *) NULL;
2995 image->blob->file_info.gzfile=gzopen(filename,type);
2996 if (image->blob->file_info.gzfile != (gzFile) NULL)
2997 image->blob->type=ZipStream;
3000 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3001 if (strncmp((char *) magick,"BZh",3) == 0)
3003 if (image->blob->file_info.file != (FILE *) NULL)
3004 (void) fclose(image->blob->file_info.file);
3005 image->blob->file_info.file=(FILE *) NULL;
3006 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3007 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3008 image->blob->type=BZipStream;
3011 if (image->blob->type == FileStream)
3022 sans_exception=AcquireExceptionInfo();
3023 magick_info=GetMagickInfo(image_info->magick,sans_exception);
3024 sans_exception=DestroyExceptionInfo(sans_exception);
3025 length=(size_t) image->blob->properties.st_size;
3026 if ((magick_info != (const MagickInfo *) NULL) &&
3027 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
3028 (length > MagickMaxBufferExtent) &&
3029 (AcquireMagickResource(MapResource,length) != MagickFalse))
3034 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
3036 if (blob == (void *) NULL)
3037 RelinquishMagickResource(MapResource,length);
3041 Format supports blobs-- use memory-mapped I/O.
3043 if (image_info->file != (FILE *) NULL)
3044 image->blob->exempt=MagickFalse;
3047 (void) fclose(image->blob->file_info.file);
3048 image->blob->file_info.file=(FILE *) NULL;
3050 AttachBlob(image->blob,blob,length);
3051 image->blob->mapped=MagickTrue;
3058 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3059 if ((LocaleCompare(extension,"Z") == 0) ||
3060 (LocaleCompare(extension,"gz") == 0) ||
3061 (LocaleCompare(extension,"wmz") == 0) ||
3062 (LocaleCompare(extension,"svgz") == 0))
3064 if (mode == WriteBinaryBlobMode)
3066 image->blob->file_info.gzfile=gzopen(filename,type);
3067 if (image->blob->file_info.gzfile != (gzFile) NULL)
3068 image->blob->type=ZipStream;
3072 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3073 if (LocaleCompare(extension,"bz2") == 0)
3075 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3076 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3077 image->blob->type=BZipStream;
3082 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
3083 if (image->blob->file_info.file != (FILE *) NULL)
3085 image->blob->type=FileStream;
3086 (void) SetStreamBuffering(image_info,image);
3089 image->blob->status=MagickFalse;
3090 if (image->blob->type != UndefinedStream)
3091 image->blob->size=GetBlobSize(image);
3094 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
3095 return(MagickFalse);
3101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3111 % PingBlob() returns all the attributes of an image or image sequence except
3112 % for the pixels. It is much faster and consumes far less memory than
3113 % BlobToImage(). On failure, a NULL image is returned and exception
3114 % describes the reason for the failure.
3116 % The format of the PingBlob method is:
3118 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
3119 % const size_t length,ExceptionInfo *exception)
3121 % A description of each parameter follows:
3123 % o image_info: the image info.
3125 % o blob: the address of a character stream in one of the image formats
3126 % understood by ImageMagick.
3128 % o length: This size_t integer reflects the length in bytes of the blob.
3130 % o exception: return any errors or warnings in this structure.
3134 #if defined(__cplusplus) || defined(c_plusplus)
3138 static size_t PingStream(const Image *magick_unused(image),
3139 const void *magick_unused(pixels),const size_t columns)
3141 magick_unreferenced(image);
3142 magick_unreferenced(pixels);
3146 #if defined(__cplusplus) || defined(c_plusplus)
3150 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
3151 const size_t length,ExceptionInfo *exception)
3159 assert(image_info != (ImageInfo *) NULL);
3160 assert(image_info->signature == MagickCoreSignature);
3161 if (image_info->debug != MagickFalse)
3162 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3163 image_info->filename);
3164 assert(exception != (ExceptionInfo *) NULL);
3165 if ((blob == (const void *) NULL) || (length == 0))
3167 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
3168 "UnrecognizedImageFormat","`%s'",image_info->magick);
3169 return((Image *) NULL);
3171 ping_info=CloneImageInfo(image_info);
3172 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
3173 if (ping_info->blob == (const void *) NULL)
3175 (void) ThrowMagickException(exception,GetMagickModule(),
3176 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
3177 return((Image *) NULL);
3179 (void) memcpy(ping_info->blob,blob,length);
3180 ping_info->length=length;
3181 ping_info->ping=MagickTrue;
3182 image=ReadStream(ping_info,&PingStream,exception);
3183 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
3184 ping_info=DestroyImageInfo(ping_info);
3189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3199 % ReadBlob() reads data from the blob or image file and returns it. It
3200 % returns the number of bytes read. If length is zero, ReadBlob() returns
3201 % zero and has no other results. If length is greater than SSIZE_MAX, the
3202 % result is unspecified.
3204 % The format of the ReadBlob method is:
3206 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
3208 % A description of each parameter follows:
3210 % o image: the image.
3212 % o length: Specifies an integer representing the number of bytes to read
3215 % o data: Specifies an area to place the information requested from the
3219 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
3224 register unsigned char
3230 assert(image != (Image *) NULL);
3231 assert(image->signature == MagickCoreSignature);
3232 assert(image->blob != (BlobInfo *) NULL);
3233 assert(image->blob->type != UndefinedStream);
3236 assert(data != (void *) NULL);
3238 q=(unsigned char *) data;
3239 switch (image->blob->type)
3241 case UndefinedStream:
3243 case StandardStream:
3251 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
3256 c=getc(image->blob->file_info.file);
3259 *q++=(unsigned char) c;
3264 c=getc(image->blob->file_info.file);
3267 *q++=(unsigned char) c;
3272 c=getc(image->blob->file_info.file);
3275 *q++=(unsigned char) c;
3280 c=getc(image->blob->file_info.file);
3283 *q++=(unsigned char) c;
3293 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3298 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
3299 (unsigned int) length);
3304 c=gzgetc(image->blob->file_info.gzfile);
3307 *q++=(unsigned char) c;
3312 c=gzgetc(image->blob->file_info.gzfile);
3315 *q++=(unsigned char) c;
3320 c=gzgetc(image->blob->file_info.gzfile);
3323 *q++=(unsigned char) c;
3328 c=gzgetc(image->blob->file_info.gzfile);
3331 *q++=(unsigned char) c;
3342 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3343 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
3351 register const unsigned char
3354 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3356 image->blob->eof=MagickTrue;
3359 p=image->blob->data+image->blob->offset;
3360 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
3361 image->blob->offset+=count;
3362 if (count != (ssize_t) length)
3363 image->blob->eof=MagickTrue;
3364 (void) memcpy(q,p,(size_t) count);
3369 if (image->blob->custom_stream->reader != (CustomStreamHandler) NULL)
3370 count=image->blob->custom_stream->reader(q,length,
3371 image->blob->custom_stream->data);
3379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3383 + R e a d B l o b B y t e %
3387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3389 % ReadBlobByte() reads a single byte from the image file and returns it.
3391 % The format of the ReadBlobByte method is:
3393 % int ReadBlobByte(Image *image)
3395 % A description of each parameter follows.
3397 % o image: the image.
3400 MagickExport int ReadBlobByte(Image *image)
3402 register const unsigned char
3411 assert(image != (Image *) NULL);
3412 assert(image->signature == MagickCoreSignature);
3413 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3424 + R e a d B l o b D o u b l e %
3428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3430 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3431 % specified by the endian member of the image structure.
3433 % The format of the ReadBlobDouble method is:
3435 % double ReadBlobDouble(Image *image)
3437 % A description of each parameter follows.
3439 % o image: the image.
3442 MagickExport double ReadBlobDouble(Image *image)
3453 quantum.double_value=0.0;
3454 quantum.unsigned_value=ReadBlobLongLong(image);
3455 return(quantum.double_value);
3459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3463 + R e a d B l o b F l o a t %
3467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3469 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3470 % specified by the endian member of the image structure.
3472 % The format of the ReadBlobFloat method is:
3474 % float ReadBlobFloat(Image *image)
3476 % A description of each parameter follows.
3478 % o image: the image.
3481 MagickExport float ReadBlobFloat(Image *image)
3492 quantum.float_value=0.0;
3493 quantum.unsigned_value=ReadBlobLong(image);
3494 return(quantum.float_value);
3498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3502 + R e a d B l o b L o n g %
3506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3508 % ReadBlobLong() reads a unsigned int value as a 32-bit quantity in the
3509 % byte-order specified by the endian member of the image structure.
3511 % The format of the ReadBlobLong method is:
3513 % unsigned int ReadBlobLong(Image *image)
3515 % A description of each parameter follows.
3517 % o image: the image.
3520 MagickExport unsigned int ReadBlobLong(Image *image)
3522 register const unsigned char
3534 assert(image != (Image *) NULL);
3535 assert(image->signature == MagickCoreSignature);
3537 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3540 if (image->endian == LSBEndian)
3542 value=(unsigned int) (*p++);
3543 value|=(unsigned int) (*p++) << 8;
3544 value|=(unsigned int) (*p++) << 16;
3545 value|=(unsigned int) (*p++) << 24;
3546 return(value & 0xffffffff);
3548 value=(unsigned int) (*p++) << 24;
3549 value|=(unsigned int) (*p++) << 16;
3550 value|=(unsigned int) (*p++) << 8;
3551 value|=(unsigned int) (*p++);
3552 return(value & 0xffffffff);
3556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3560 + R e a d B l o b L o n g L o n g %
3564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3566 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3567 % byte-order specified by the endian member of the image structure.
3569 % The format of the ReadBlobLongLong method is:
3571 % MagickSizeType ReadBlobLongLong(Image *image)
3573 % A description of each parameter follows.
3575 % o image: the image.
3578 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3583 register const unsigned char
3592 assert(image != (Image *) NULL);
3593 assert(image->signature == MagickCoreSignature);
3595 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3597 return(MagickULLConstant(0));
3598 if (image->endian == LSBEndian)
3600 value=(MagickSizeType) (*p++);
3601 value|=(MagickSizeType) (*p++) << 8;
3602 value|=(MagickSizeType) (*p++) << 16;
3603 value|=(MagickSizeType) (*p++) << 24;
3604 value|=(MagickSizeType) (*p++) << 32;
3605 value|=(MagickSizeType) (*p++) << 40;
3606 value|=(MagickSizeType) (*p++) << 48;
3607 value|=(MagickSizeType) (*p++) << 56;
3608 return(value & MagickULLConstant(0xffffffffffffffff));
3610 value=(MagickSizeType) (*p++) << 56;
3611 value|=(MagickSizeType) (*p++) << 48;
3612 value|=(MagickSizeType) (*p++) << 40;
3613 value|=(MagickSizeType) (*p++) << 32;
3614 value|=(MagickSizeType) (*p++) << 24;
3615 value|=(MagickSizeType) (*p++) << 16;
3616 value|=(MagickSizeType) (*p++) << 8;
3617 value|=(MagickSizeType) (*p++);
3618 return(value & MagickULLConstant(0xffffffffffffffff));
3622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3626 + R e a d B l o b S h o r t %
3630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3632 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3633 % specified by the endian member of the image structure.
3635 % The format of the ReadBlobShort method is:
3637 % unsigned short ReadBlobShort(Image *image)
3639 % A description of each parameter follows.
3641 % o image: the image.
3644 MagickExport unsigned short ReadBlobShort(Image *image)
3646 register const unsigned char
3649 register unsigned short
3658 assert(image != (Image *) NULL);
3659 assert(image->signature == MagickCoreSignature);
3661 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3663 return((unsigned short) 0U);
3664 if (image->endian == LSBEndian)
3666 value=(unsigned short) (*p++);
3667 value|=(unsigned short) (*p++) << 8;
3670 value=(unsigned short) (*p++) << 8;
3671 value|=(unsigned short) (*p++);
3676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3680 + R e a d B l o b L S B L o n g %
3684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3686 % ReadBlobLSBLong() reads a unsigned int value as a 32-bit quantity in
3687 % least-significant byte first order.
3689 % The format of the ReadBlobLSBLong method is:
3691 % unsigned int ReadBlobLSBLong(Image *image)
3693 % A description of each parameter follows.
3695 % o image: the image.
3698 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3700 register const unsigned char
3703 register unsigned int
3712 assert(image != (Image *) NULL);
3713 assert(image->signature == MagickCoreSignature);
3715 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3718 value=(unsigned int) (*p++);
3719 value|=(unsigned int) (*p++) << 8;
3720 value|=(unsigned int) (*p++) << 16;
3721 value|=(unsigned int) (*p++) << 24;
3722 return(value & 0xffffffff);
3726 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3730 + R e a d B l o b L S B S i g n e d L o n g %
3734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3736 % ReadBlobLSBSignedLong() reads a signed int value as a 32-bit quantity in
3737 % least-significant byte first order.
3739 % The format of the ReadBlobLSBSignedLong method is:
3741 % signed int ReadBlobLSBSignedLong(Image *image)
3743 % A description of each parameter follows.
3745 % o image: the image.
3748 MagickExport signed int ReadBlobLSBSignedLong(Image *image)
3759 quantum.unsigned_value=ReadBlobLSBLong(image);
3760 return(quantum.signed_value);
3764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3768 + R e a d B l o b L S B S h o r t %
3772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3774 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3775 % least-significant byte first order.
3777 % The format of the ReadBlobLSBShort method is:
3779 % unsigned short ReadBlobLSBShort(Image *image)
3781 % A description of each parameter follows.
3783 % o image: the image.
3786 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3788 register const unsigned char
3791 register unsigned short
3800 assert(image != (Image *) NULL);
3801 assert(image->signature == MagickCoreSignature);
3803 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3805 return((unsigned short) 0U);
3806 value=(unsigned int) (*p++);
3807 value|=(unsigned int) (*p++) << 8;
3808 return(value & 0xffff);
3812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3816 + R e a d B l o b L S B S i g n e d S h o r t %
3820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3822 % ReadBlobLSBSignedShort() reads a signed short value as a 16-bit quantity in
3823 % least-significant byte-order.
3825 % The format of the ReadBlobLSBSignedShort method is:
3827 % signed short ReadBlobLSBSignedShort(Image *image)
3829 % A description of each parameter follows.
3831 % o image: the image.
3834 MagickExport signed short ReadBlobLSBSignedShort(Image *image)
3845 quantum.unsigned_value=ReadBlobLSBShort(image);
3846 return(quantum.signed_value);
3850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3854 + R e a d B l o b M S B L o n g %
3858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3860 % ReadBlobMSBLong() reads a unsigned int value as a 32-bit quantity in
3861 % most-significant byte first order.
3863 % The format of the ReadBlobMSBLong method is:
3865 % unsigned int ReadBlobMSBLong(Image *image)
3867 % A description of each parameter follows.
3869 % o image: the image.
3872 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3874 register const unsigned char
3877 register unsigned int
3886 assert(image != (Image *) NULL);
3887 assert(image->signature == MagickCoreSignature);
3889 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3892 value=(unsigned int) (*p++) << 24;
3893 value|=(unsigned int) (*p++) << 16;
3894 value|=(unsigned int) (*p++) << 8;
3895 value|=(unsigned int) (*p++);
3900 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3904 + R e a d B l o b M S B L o n g L o n g %
3908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3910 % ReadBlobMSBLongLong() reads a unsigned long long value as a 64-bit quantity
3911 % in most-significant byte first order.
3913 % The format of the ReadBlobMSBLongLong method is:
3915 % unsigned int ReadBlobMSBLongLong(Image *image)
3917 % A description of each parameter follows.
3919 % o image: the image.
3922 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3924 register const unsigned char
3927 register MagickSizeType
3936 assert(image != (Image *) NULL);
3937 assert(image->signature == MagickCoreSignature);
3939 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3941 return(MagickULLConstant(0));
3942 value=(MagickSizeType) (*p++) << 56;
3943 value|=(MagickSizeType) (*p++) << 48;
3944 value|=(MagickSizeType) (*p++) << 40;
3945 value|=(MagickSizeType) (*p++) << 32;
3946 value|=(MagickSizeType) (*p++) << 24;
3947 value|=(MagickSizeType) (*p++) << 16;
3948 value|=(MagickSizeType) (*p++) << 8;
3949 value|=(MagickSizeType) (*p++);
3950 return(value & MagickULLConstant(0xffffffffffffffff));
3954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3958 + R e a d B l o b M S B S h o r t %
3962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3964 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3965 % most-significant byte first order.
3967 % The format of the ReadBlobMSBShort method is:
3969 % unsigned short ReadBlobMSBShort(Image *image)
3971 % A description of each parameter follows.
3973 % o image: the image.
3976 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3978 register const unsigned char
3981 register unsigned short
3990 assert(image != (Image *) NULL);
3991 assert(image->signature == MagickCoreSignature);
3993 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3995 return((unsigned short) 0U);
3996 value=(unsigned short) (*p++) << 8;
3997 value|=(unsigned short) (*p++);
3998 return(value & 0xffff);
4002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4006 + R e a d B l o b M S B S i g n e d L o n g %
4010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4012 % ReadBlobMSBSignedLong() reads a signed int value as a 32-bit quantity in
4013 % most-significant byte-order.
4015 % The format of the ReadBlobMSBSignedLong method is:
4017 % signed int ReadBlobMSBSignedLong(Image *image)
4019 % A description of each parameter follows.
4021 % o image: the image.
4024 MagickExport signed int ReadBlobMSBSignedLong(Image *image)
4035 quantum.unsigned_value=ReadBlobMSBLong(image);
4036 return(quantum.signed_value);
4040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4044 + R e a d B l o b M S B S i g n e d S h o r t %
4048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4050 % ReadBlobMSBSignedShort() reads a signed short value as a 16-bit quantity in
4051 % most-significant byte-order.
4053 % The format of the ReadBlobMSBSignedShort method is:
4055 % signed short ReadBlobMSBSignedShort(Image *image)
4057 % A description of each parameter follows.
4059 % o image: the image.
4062 MagickExport signed short ReadBlobMSBSignedShort(Image *image)
4073 quantum.unsigned_value=ReadBlobMSBShort(image);
4074 return(quantum.signed_value);
4078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4082 + R e a d B l o b S i g n e d L o n g %
4086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4088 % ReadBlobSignedLong() reads a signed int value as a 32-bit quantity in the
4089 % byte-order specified by the endian member of the image structure.
4091 % The format of the ReadBlobSignedLong method is:
4093 % signed int ReadBlobSignedLong(Image *image)
4095 % A description of each parameter follows.
4097 % o image: the image.
4100 MagickExport signed int ReadBlobSignedLong(Image *image)
4111 quantum.unsigned_value=ReadBlobLong(image);
4112 return(quantum.signed_value);
4116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4120 + R e a d B l o b S i g n e d S h o r t %
4124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4126 % ReadBlobSignedShort() reads a signed short value as a 16-bit quantity in the
4127 % byte-order specified by the endian member of the image structure.
4129 % The format of the ReadBlobSignedShort method is:
4131 % signed short ReadBlobSignedShort(Image *image)
4133 % A description of each parameter follows.
4135 % o image: the image.
4138 MagickExport signed short ReadBlobSignedShort(Image *image)
4149 quantum.unsigned_value=ReadBlobShort(image);
4150 return(quantum.signed_value);
4154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4158 + R e a d B l o b S t r e a m %
4162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4164 % ReadBlobStream() reads data from the blob or image file and returns it. It
4165 % returns a pointer to the data buffer you supply or to the image memory
4166 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
4167 % returns a count of zero and has no other results. If length is greater than
4168 % SSIZE_MAX, the result is unspecified.
4170 % The format of the ReadBlobStream method is:
4172 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
4175 % A description of each parameter follows:
4177 % o image: the image.
4179 % o length: Specifies an integer representing the number of bytes to read
4182 % o count: returns the number of bytes read.
4184 % o data: Specifies an area to place the information requested from the
4188 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
4189 void *data,ssize_t *count)
4191 assert(image != (Image *) NULL);
4192 assert(image->signature == MagickCoreSignature);
4193 assert(image->blob != (BlobInfo *) NULL);
4194 assert(image->blob->type != UndefinedStream);
4195 assert(count != (ssize_t *) NULL);
4196 if (image->blob->type != BlobStream)
4198 assert(data != NULL);
4199 *count=ReadBlob(image,length,(unsigned char *) data);
4202 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4205 image->blob->eof=MagickTrue;
4208 data=image->blob->data+image->blob->offset;
4209 *count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
4210 image->blob->offset+=(*count);
4211 if (*count != (ssize_t) length)
4212 image->blob->eof=MagickTrue;
4217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4221 + R e a d B l o b S t r i n g %
4225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4227 % ReadBlobString() reads characters from a blob or file until a newline
4228 % character is read or an end-of-file condition is encountered.
4230 % The format of the ReadBlobString method is:
4232 % char *ReadBlobString(Image *image,char *string)
4234 % A description of each parameter follows:
4236 % o image: the image.
4238 % o string: the address of a character buffer.
4241 MagickExport char *ReadBlobString(Image *image,char *string)
4243 register const unsigned char
4255 assert(image != (Image *) NULL);
4256 assert(image->signature == MagickCoreSignature);
4257 for (i=0; i < (MagickPathExtent-1L); i++)
4259 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
4263 return((char *) NULL);
4266 string[i]=(char) (*p);
4267 if ((string[i] == '\r') || (string[i] == '\n'))
4270 if (string[i] == '\r')
4271 (void) ReadBlobStream(image,1,buffer,&count);
4277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4281 + R e f e r e n c e B l o b %
4285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4287 % ReferenceBlob() increments the reference count associated with the pixel
4288 % blob returning a pointer to the blob.
4290 % The format of the ReferenceBlob method is:
4292 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
4294 % A description of each parameter follows:
4296 % o blob_info: the blob_info.
4299 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
4301 assert(blob != (BlobInfo *) NULL);
4302 assert(blob->signature == MagickCoreSignature);
4303 if (blob->debug != MagickFalse)
4304 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4305 LockSemaphoreInfo(blob->semaphore);
4306 blob->reference_count++;
4307 UnlockSemaphoreInfo(blob->semaphore);
4312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4322 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
4323 % and returns the resulting offset.
4325 % The format of the SeekBlob method is:
4327 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
4330 % A description of each parameter follows:
4332 % o image: the image.
4334 % o offset: Specifies an integer representing the offset in bytes.
4336 % o whence: Specifies an integer representing how the offset is
4337 % treated relative to the beginning of the blob as follows:
4339 % SEEK_SET Set position equal to offset bytes.
4340 % SEEK_CUR Set position to current location plus offset.
4341 % SEEK_END Set position to EOF plus offset.
4344 MagickExport MagickOffsetType SeekBlob(Image *image,
4345 const MagickOffsetType offset,const int whence)
4347 assert(image != (Image *) NULL);
4348 assert(image->signature == MagickCoreSignature);
4349 if (image->debug != MagickFalse)
4350 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4351 assert(image->blob != (BlobInfo *) NULL);
4352 assert(image->blob->type != UndefinedStream);
4353 switch (image->blob->type)
4355 case UndefinedStream:
4357 case StandardStream:
4362 if ((offset < 0) && (whence == SEEK_SET))
4364 if (fseek(image->blob->file_info.file,offset,whence) < 0)
4366 image->blob->offset=TellBlob(image);
4371 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4372 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
4375 image->blob->offset=TellBlob(image);
4391 image->blob->offset=offset;
4396 if ((image->blob->offset+offset) < 0)
4398 image->blob->offset+=offset;
4403 if (((MagickOffsetType) image->blob->length+offset) < 0)
4405 image->blob->offset=image->blob->length+offset;
4409 if (image->blob->offset < (MagickOffsetType)
4410 ((off_t) image->blob->length))
4412 image->blob->eof=MagickFalse;
4415 if (image->blob->offset < (MagickOffsetType)
4416 ((off_t) image->blob->extent))
4418 if (image->blob->mapped != MagickFalse)
4420 image->blob->eof=MagickTrue;
4423 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
4424 image->blob->quantum<<=1;
4425 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4426 image->blob->extent+1,sizeof(*image->blob->data));
4427 (void) SyncBlob(image);
4428 if (image->blob->data == NULL)
4430 (void) DetachBlob(image->blob);
4437 if (image->blob->custom_stream->seeker == (CustomStreamSeeker) NULL)
4439 image->blob->offset=image->blob->custom_stream->seeker(offset,whence,
4440 image->blob->custom_stream->data);
4444 return(image->blob->offset);
4448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4452 + S e t B l o b E x e m p t %
4456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4458 % SetBlobExempt() sets the blob exempt status.
4460 % The format of the SetBlobExempt method is:
4462 % MagickBooleanType SetBlobExempt(const Image *image,
4463 % const MagickBooleanType exempt)
4465 % A description of each parameter follows:
4467 % o image: the image.
4469 % o exempt: Set to true if this blob is exempt from being closed.
4472 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
4474 assert(image != (const Image *) NULL);
4475 assert(image->signature == MagickCoreSignature);
4476 if (image->debug != MagickFalse)
4477 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4478 image->blob->exempt=exempt;
4482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4486 + S e t B l o b E x t e n t %
4490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4492 % SetBlobExtent() ensures enough space is allocated for the blob. If the
4493 % method is successful, subsequent writes to bytes in the specified range are
4494 % guaranteed not to fail.
4496 % The format of the SetBlobExtent method is:
4498 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
4500 % A description of each parameter follows:
4502 % o image: the image.
4504 % o extent: the blob maximum extent.
4507 MagickExport MagickBooleanType SetBlobExtent(Image *image,
4508 const MagickSizeType extent)
4510 assert(image != (Image *) NULL);
4511 assert(image->signature == MagickCoreSignature);
4512 if (image->debug != MagickFalse)
4513 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4514 assert(image->blob != (BlobInfo *) NULL);
4515 assert(image->blob->type != UndefinedStream);
4516 switch (image->blob->type)
4518 case UndefinedStream:
4520 case StandardStream:
4521 return(MagickFalse);
4530 if (extent != (MagickSizeType) ((off_t) extent))
4531 return(MagickFalse);
4532 offset=SeekBlob(image,0,SEEK_END);
4534 return(MagickFalse);
4535 if ((MagickSizeType) offset >= extent)
4537 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4540 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4541 image->blob->file_info.file);
4542 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4543 if (image->blob->synchronize != MagickFalse)
4548 file=fileno(image->blob->file_info.file);
4549 if ((file == -1) || (offset < 0))
4550 return(MagickFalse);
4551 (void) posix_fallocate(file,offset,extent-offset);
4554 offset=SeekBlob(image,offset,SEEK_SET);
4556 return(MagickFalse);
4561 return(MagickFalse);
4563 return(MagickFalse);
4565 return(MagickFalse);
4568 if (extent != (MagickSizeType) ((size_t) extent))
4569 return(MagickFalse);
4570 if (image->blob->mapped != MagickFalse)
4578 (void) UnmapBlob(image->blob->data,image->blob->length);
4579 RelinquishMagickResource(MapResource,image->blob->length);
4580 if (extent != (MagickSizeType) ((off_t) extent))
4581 return(MagickFalse);
4582 offset=SeekBlob(image,0,SEEK_END);
4584 return(MagickFalse);
4585 if ((MagickSizeType) offset >= extent)
4587 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4588 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4589 image->blob->file_info.file);
4590 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4591 if (image->blob->synchronize != MagickFalse)
4596 file=fileno(image->blob->file_info.file);
4597 if ((file == -1) || (offset < 0))
4598 return(MagickFalse);
4599 (void) posix_fallocate(file,offset,extent-offset);
4602 offset=SeekBlob(image,offset,SEEK_SET);
4604 return(MagickFalse);
4605 (void) AcquireMagickResource(MapResource,extent);
4606 image->blob->data=(unsigned char*) MapBlob(fileno(
4607 image->blob->file_info.file),WriteMode,0,(size_t) extent);
4608 image->blob->extent=(size_t) extent;
4609 image->blob->length=(size_t) extent;
4610 (void) SyncBlob(image);
4613 image->blob->extent=(size_t) extent;
4614 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4615 image->blob->extent+1,sizeof(*image->blob->data));
4616 (void) SyncBlob(image);
4617 if (image->blob->data == (unsigned char *) NULL)
4619 (void) DetachBlob(image->blob);
4620 return(MagickFalse);
4631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4635 + S e t C u s t o m S t r e a m D a t a %
4639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4641 % SetCustomStreamData() sets the stream info data member.
4643 % The format of the SetCustomStreamData method is:
4645 % void SetCustomStreamData(CustomStreamInfo *custom_stream,void *)
4647 % A description of each parameter follows:
4649 % o custom_stream: your custom stream.
4651 % o void: your data.
4654 MagickExport void SetCustomStreamData(CustomStreamInfo *custom_stream,
4657 assert(custom_stream != (CustomStreamInfo *) NULL);
4658 assert(custom_stream->signature == MagickCoreSignature);
4659 custom_stream->data=data;
4663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4667 + S e t C u s t o m S t r e a m R e a d e r %
4671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4673 % SetCustomStreamReader() sets the stream info reader member.
4675 % The format of the SetCustomStreamReader method is:
4677 % void SetCustomStreamReader(CustomStreamInfo *custom_stream,
4678 % CustomStreamHandler reader)
4680 % A description of each parameter follows:
4682 % o custom_stream: your custom stream.
4684 % o reader: your custom stream reader.
4687 MagickExport void SetCustomStreamReader(CustomStreamInfo *custom_stream,
4688 CustomStreamHandler reader)
4690 assert(custom_stream != (CustomStreamInfo *) NULL);
4691 assert(custom_stream->signature == MagickCoreSignature);
4692 custom_stream->reader=reader;
4696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4700 + S e t C u s t o m S t r e a m S e e k e r %
4704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4706 % SetCustomStreamSeeker() sets the stream info seeker member.
4708 % The format of the SetCustomStreamReader method is:
4710 % void SetCustomStreamSeeker(CustomStreamInfo *custom_stream,
4711 % CustomStreamSeeker seeker)
4713 % A description of each parameter follows:
4715 % o custom_stream: your custom stream.
4717 % o seeker: your custom stream seeker.
4720 MagickExport void SetCustomStreamSeeker(CustomStreamInfo *custom_stream,
4721 CustomStreamSeeker seeker)
4723 assert(custom_stream != (CustomStreamInfo *) NULL);
4724 assert(custom_stream->signature == MagickCoreSignature);
4725 custom_stream->seeker=seeker;
4729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4733 + S e t C u s t o m S t r e a m T e l l e r %
4737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4739 % SetCustomStreamTeller() sets the stream info teller member.
4741 % The format of the SetCustomStreamTeller method is:
4743 % void SetCustomStreamTeller(CustomStreamInfo *custom_stream,
4744 % CustomStreamTeller *teller)
4746 % A description of each parameter follows:
4748 % o custom_stream: your custom stream.
4750 % o teller: your custom stream teller.
4753 MagickExport void SetCustomStreamTeller(CustomStreamInfo *custom_stream,
4754 CustomStreamTeller teller)
4756 assert(custom_stream != (CustomStreamInfo *) NULL);
4757 assert(custom_stream->signature == MagickCoreSignature);
4758 custom_stream->teller=teller;
4762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4766 + S e t C u s t o m S t r e a m W r i t e r %
4770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4772 % SetCustomStreamWriter() sets the stream info writer member.
4774 % The format of the SetCustomStreamWriter method is:
4776 % void SetCustomStreamWriter(CustomStreamInfo *custom_stream,
4777 % CustomStreamHandler *writer)
4779 % A description of each parameter follows:
4781 % o custom_stream: your custom stream.
4783 % o writer: your custom stream writer.
4786 MagickExport void SetCustomStreamWriter(CustomStreamInfo *custom_stream,
4787 CustomStreamHandler writer)
4789 assert(custom_stream != (CustomStreamInfo *) NULL);
4790 assert(custom_stream->signature == MagickCoreSignature);
4791 custom_stream->writer=writer;
4795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4805 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
4806 % attributes if it is an blob.
4808 % The format of the SyncBlob method is:
4810 % int SyncBlob(Image *image)
4812 % A description of each parameter follows:
4814 % o image: the image.
4817 static int SyncBlob(Image *image)
4822 assert(image != (Image *) NULL);
4823 assert(image->signature == MagickCoreSignature);
4824 if (image->debug != MagickFalse)
4825 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4826 assert(image->blob != (BlobInfo *) NULL);
4827 assert(image->blob->type != UndefinedStream);
4829 switch (image->blob->type)
4831 case UndefinedStream:
4832 case StandardStream:
4837 status=fflush(image->blob->file_info.file);
4842 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4843 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
4849 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4850 status=BZ2_bzflush(image->blob->file_info.bzfile);
4865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4875 % TellBlob() obtains the current value of the blob or file position.
4877 % The format of the TellBlob method is:
4879 % MagickOffsetType TellBlob(const Image *image)
4881 % A description of each parameter follows:
4883 % o image: the image.
4886 MagickExport MagickOffsetType TellBlob(const Image *image)
4891 assert(image != (Image *) NULL);
4892 assert(image->signature == MagickCoreSignature);
4893 if (image->debug != MagickFalse)
4894 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4895 assert(image->blob != (BlobInfo *) NULL);
4896 assert(image->blob->type != UndefinedStream);
4898 switch (image->blob->type)
4900 case UndefinedStream:
4901 case StandardStream:
4905 offset=ftell(image->blob->file_info.file);
4912 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4913 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
4923 offset=image->blob->offset;
4928 if (image->blob->custom_stream->teller != (CustomStreamTeller) NULL)
4929 offset=image->blob->custom_stream->teller(image->blob->custom_stream->data);
4937 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4941 + U n m a p B l o b %
4945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4947 % UnmapBlob() deallocates the binary large object previously allocated with
4948 % the MapBlob method.
4950 % The format of the UnmapBlob method is:
4952 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4954 % A description of each parameter follows:
4956 % o map: the address of the binary large object.
4958 % o length: the length of the binary large object.
4961 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4963 #if defined(MAGICKCORE_HAVE_MMAP)
4967 status=munmap(map,length);
4968 return(status == -1 ? MagickFalse : MagickTrue);
4972 return(MagickFalse);
4977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4981 % C u s t o m S t r e a m T o I m a g e %
4985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4987 % CustomStreamToImage() is the equivalent of ReadImage(), but reads the
4988 % formatted "file" from the suplied method rather than to an actual file.
4990 % The format of the CustomStreamToImage method is:
4992 % Image *CustomStreamToImage(const ImageInfo *image_info,
4993 % ExceptionInfo *exception)
4995 % A description of each parameter follows:
4997 % o image_info: the image info.
4999 % o exception: return any errors or warnings in this structure.
5002 MagickExport Image *CustomStreamToImage(const ImageInfo *image_info,
5003 ExceptionInfo *exception)
5014 assert(image_info != (ImageInfo *) NULL);
5015 assert(image_info->signature == MagickCoreSignature);
5016 if (image_info->debug != MagickFalse)
5017 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
5018 image_info->filename);
5019 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
5020 assert(image_info->custom_stream->signature == MagickCoreSignature);
5021 assert(image_info->custom_stream->reader != (CustomStreamHandler) NULL);
5022 assert(exception != (ExceptionInfo *) NULL);
5023 blob_info=CloneImageInfo(image_info);
5024 if (*blob_info->magick == '\0')
5025 (void) SetImageInfo(blob_info,0,exception);
5026 magick_info=GetMagickInfo(blob_info->magick,exception);
5027 if (magick_info == (const MagickInfo *) NULL)
5029 (void) ThrowMagickException(exception,GetMagickModule(),
5030 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
5032 blob_info=DestroyImageInfo(blob_info);
5033 return((Image *) NULL);
5035 image=(Image *) NULL;
5036 if ((GetMagickBlobSupport(magick_info) != MagickFalse) ||
5037 (blob_info->custom_stream == (CustomStreamInfo *) NULL))
5040 Native blob support for this image format or SetImageInfo changed the
5043 image=ReadImage(blob_info,exception);
5044 if (image != (Image *) NULL)
5045 (void) CloseBlob(image);
5050 unique[MagickPathExtent];
5062 Write data to file on disk.
5064 blob_info->custom_stream=(CustomStreamInfo *) NULL;
5065 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
5067 if (blob == (unsigned char *) NULL)
5069 ThrowFileException(exception,BlobError,"UnableToReadBlob",
5070 image_info->filename);
5071 blob_info=DestroyImageInfo(blob_info);
5072 return((Image *) NULL);
5074 file=AcquireUniqueFileResource(unique);
5077 ThrowFileException(exception,BlobError,"UnableToReadBlob",
5078 image_info->filename);
5079 blob=(unsigned char *) RelinquishMagickMemory(blob);
5080 blob_info=DestroyImageInfo(blob_info);
5081 return((Image *) NULL);
5083 clone_info=CloneImageInfo(blob_info);
5084 blob_info->file=fdopen(file,"wb+");
5085 if (blob_info->file != (FILE *) NULL)
5090 count=(ssize_t) MagickMaxBufferExtent;
5091 while (count == (ssize_t) MagickMaxBufferExtent)
5093 count=image_info->custom_stream->reader(blob,MagickMaxBufferExtent,
5094 image_info->custom_stream->data);
5095 count=(ssize_t) write(file,(const char *) blob,count);
5097 (void) fclose(blob_info->file);
5098 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,
5099 "%s:%s",blob_info->magick,unique);
5100 image=ReadImage(clone_info,exception);
5101 if (image != (Image *) NULL)
5107 Restore original filenames and image format.
5109 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
5111 (void) CopyMagickString(images->filename,image_info->filename,
5113 (void) CopyMagickString(images->magick_filename,
5114 image_info->filename,MagickPathExtent);
5115 (void) CopyMagickString(images->magick,magick_info->name,
5117 (void) CloseBlob(images);
5118 images=GetNextImageInList(images);
5122 clone_info=DestroyImageInfo(clone_info);
5123 blob=(unsigned char *) RelinquishMagickMemory(blob);
5124 (void) RelinquishUniqueFileResource(unique);
5126 blob_info=DestroyImageInfo(blob_info);
5131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5135 + W r i t e B l o b %
5139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5141 % WriteBlob() writes data to a blob or image file. It returns the number of
5144 % The format of the WriteBlob method is:
5146 % ssize_t WriteBlob(Image *image,const size_t length,const void *data)
5148 % A description of each parameter follows:
5150 % o image: the image.
5152 % o length: Specifies an integer representing the number of bytes to
5153 % write to the file.
5155 % o data: The address of the data to write to the blob or file.
5158 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
5164 register const unsigned char
5170 assert(image != (Image *) NULL);
5171 assert(image->signature == MagickCoreSignature);
5172 assert(image->blob != (BlobInfo *) NULL);
5173 assert(image->blob->type != UndefinedStream);
5176 assert(data != (const void *) NULL);
5178 p=(const unsigned char *) data;
5179 switch (image->blob->type)
5181 case UndefinedStream:
5183 case StandardStream:
5191 count=(ssize_t) fwrite((const char *) data,1,length,
5192 image->blob->file_info.file);
5197 c=putc((int) *p++,image->blob->file_info.file);
5204 c=putc((int) *p++,image->blob->file_info.file);
5211 c=putc((int) *p++,image->blob->file_info.file);
5218 c=putc((int) *p++,image->blob->file_info.file);
5230 #if defined(MAGICKCORE_ZLIB_DELEGATE)
5235 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
5236 (unsigned int) length);
5241 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5248 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5255 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5262 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5275 #if defined(MAGICKCORE_BZLIB_DELEGATE)
5276 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
5283 count=(ssize_t) image->blob->stream(image,data,length);
5288 register unsigned char
5291 if ((image->blob->offset+(MagickOffsetType) length) >=
5292 (MagickOffsetType) image->blob->extent)
5294 if (image->blob->mapped != MagickFalse)
5296 image->blob->extent+=length+image->blob->quantum;
5297 image->blob->quantum<<=1;
5298 image->blob->data=(unsigned char *) ResizeQuantumMemory(
5299 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
5300 (void) SyncBlob(image);
5301 if (image->blob->data == (unsigned char *) NULL)
5303 (void) DetachBlob(image->blob);
5307 q=image->blob->data+image->blob->offset;
5308 (void) memcpy(q,p,length);
5309 image->blob->offset+=length;
5310 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
5311 image->blob->length=(size_t) image->blob->offset;
5312 count=(ssize_t) length;
5317 if (image->blob->custom_stream->writer != (CustomStreamHandler) NULL)
5318 count=image->blob->custom_stream->writer((const unsigned char *) data,
5319 length,image->blob->custom_stream->data);
5327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5331 + W r i t e B l o b B y t e %
5335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5337 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
5338 % written (either 0 or 1);
5340 % The format of the WriteBlobByte method is:
5342 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
5344 % A description of each parameter follows.
5346 % o image: the image.
5348 % o value: Specifies the value to write.
5351 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
5353 assert(image != (Image *) NULL);
5354 assert(image->signature == MagickCoreSignature);
5355 return(WriteBlobStream(image,1,&value));
5359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5363 + W r i t e B l o b F l o a t %
5367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5369 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
5370 % specified by the endian member of the image structure.
5372 % The format of the WriteBlobFloat method is:
5374 % ssize_t WriteBlobFloat(Image *image,const float value)
5376 % A description of each parameter follows.
5378 % o image: the image.
5380 % o value: Specifies the value to write.
5383 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
5394 quantum.unsigned_value=0U;
5395 quantum.float_value=value;
5396 return(WriteBlobLong(image,quantum.unsigned_value));
5400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5404 + W r i t e B l o b L o n g %
5408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5410 % WriteBlobLong() writes a unsigned int value as a 32-bit quantity in the
5411 % byte-order specified by the endian member of the image structure.
5413 % The format of the WriteBlobLong method is:
5415 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
5417 % A description of each parameter follows.
5419 % o image: the image.
5421 % o value: Specifies the value to write.
5424 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
5429 assert(image != (Image *) NULL);
5430 assert(image->signature == MagickCoreSignature);
5431 if (image->endian == LSBEndian)
5433 buffer[0]=(unsigned char) value;
5434 buffer[1]=(unsigned char) (value >> 8);
5435 buffer[2]=(unsigned char) (value >> 16);
5436 buffer[3]=(unsigned char) (value >> 24);
5437 return(WriteBlobStream(image,4,buffer));
5439 buffer[0]=(unsigned char) (value >> 24);
5440 buffer[1]=(unsigned char) (value >> 16);
5441 buffer[2]=(unsigned char) (value >> 8);
5442 buffer[3]=(unsigned char) value;
5443 return(WriteBlobStream(image,4,buffer));
5447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5451 + W r i t e B l o b S h o r t %
5455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5457 % WriteBlobShort() writes a short value as a 16-bit quantity in the
5458 % byte-order specified by the endian member of the image structure.
5460 % The format of the WriteBlobShort method is:
5462 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
5464 % A description of each parameter follows.
5466 % o image: the image.
5468 % o value: Specifies the value to write.
5471 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
5476 assert(image != (Image *) NULL);
5477 assert(image->signature == MagickCoreSignature);
5478 if (image->endian == LSBEndian)
5480 buffer[0]=(unsigned char) value;
5481 buffer[1]=(unsigned char) (value >> 8);
5482 return(WriteBlobStream(image,2,buffer));
5484 buffer[0]=(unsigned char) (value >> 8);
5485 buffer[1]=(unsigned char) value;
5486 return(WriteBlobStream(image,2,buffer));
5490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5494 + W r i t e B l o b L S B L o n g %
5498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5500 % WriteBlobLSBLong() writes a unsigned int value as a 32-bit quantity in
5501 % least-significant byte first order.
5503 % The format of the WriteBlobLSBLong method is:
5505 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5507 % A description of each parameter follows.
5509 % o image: the image.
5511 % o value: Specifies the value to write.
5514 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5519 assert(image != (Image *) NULL);
5520 assert(image->signature == MagickCoreSignature);
5521 buffer[0]=(unsigned char) value;
5522 buffer[1]=(unsigned char) (value >> 8);
5523 buffer[2]=(unsigned char) (value >> 16);
5524 buffer[3]=(unsigned char) (value >> 24);
5525 return(WriteBlobStream(image,4,buffer));
5529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5533 + W r i t e B l o b L S B S h o r t %
5537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5539 % WriteBlobLSBShort() writes a unsigned short value as a 16-bit quantity in
5540 % least-significant byte first order.
5542 % The format of the WriteBlobLSBShort method is:
5544 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5546 % A description of each parameter follows.
5548 % o image: the image.
5550 % o value: Specifies the value to write.
5553 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5558 assert(image != (Image *) NULL);
5559 assert(image->signature == MagickCoreSignature);
5560 buffer[0]=(unsigned char) value;
5561 buffer[1]=(unsigned char) (value >> 8);
5562 return(WriteBlobStream(image,2,buffer));
5566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5570 + W r i t e B l o b L S B S i g n e d L o n g %
5574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5576 % WriteBlobLSBSignedLong() writes a signed value as a 32-bit quantity in
5577 % least-significant byte first order.
5579 % The format of the WriteBlobLSBSignedLong method is:
5581 % ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5583 % A description of each parameter follows.
5585 % o image: the image.
5587 % o value: Specifies the value to write.
5590 MagickExport ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5604 assert(image != (Image *) NULL);
5605 assert(image->signature == MagickCoreSignature);
5606 quantum.signed_value=value;
5607 buffer[0]=(unsigned char) quantum.unsigned_value;
5608 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5609 buffer[2]=(unsigned char) (quantum.unsigned_value >> 16);
5610 buffer[3]=(unsigned char) (quantum.unsigned_value >> 24);
5611 return(WriteBlobStream(image,4,buffer));
5615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5619 + W r i t e B l o b L S B S i g n e d S h o r t %
5623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5625 % WriteBlobLSBSignedShort() writes a signed short value as a 16-bit quantity
5626 % in least-significant byte first order.
5628 % The format of the WriteBlobLSBSignedShort method is:
5630 % ssize_t WriteBlobLSBSignedShort(Image *image,const signed short value)
5632 % A description of each parameter follows.
5634 % o image: the image.
5636 % o value: Specifies the value to write.
5639 MagickExport ssize_t WriteBlobLSBSignedShort(Image *image,
5640 const signed short value)
5654 assert(image != (Image *) NULL);
5655 assert(image->signature == MagickCoreSignature);
5656 quantum.signed_value=value;
5657 buffer[0]=(unsigned char) quantum.unsigned_value;
5658 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5659 return(WriteBlobStream(image,2,buffer));
5663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5667 + W r i t e B l o b M S B L o n g %
5671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5673 % WriteBlobMSBLong() writes a unsigned int value as a 32-bit quantity in
5674 % most-significant byte first order.
5676 % The format of the WriteBlobMSBLong method is:
5678 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5680 % A description of each parameter follows.
5682 % o value: Specifies the value to write.
5684 % o image: the image.
5687 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5692 assert(image != (Image *) NULL);
5693 assert(image->signature == MagickCoreSignature);
5694 buffer[0]=(unsigned char) (value >> 24);
5695 buffer[1]=(unsigned char) (value >> 16);
5696 buffer[2]=(unsigned char) (value >> 8);
5697 buffer[3]=(unsigned char) value;
5698 return(WriteBlobStream(image,4,buffer));
5702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5706 + W r i t e B l o b M S B L o n g L o n g %
5710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5712 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
5713 % most-significant byte first order.
5715 % The format of the WriteBlobMSBLongLong method is:
5717 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
5719 % A description of each parameter follows.
5721 % o value: Specifies the value to write.
5723 % o image: the image.
5726 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
5727 const MagickSizeType value)
5732 assert(image != (Image *) NULL);
5733 assert(image->signature == MagickCoreSignature);
5734 buffer[0]=(unsigned char) (value >> 56);
5735 buffer[1]=(unsigned char) (value >> 48);
5736 buffer[2]=(unsigned char) (value >> 40);
5737 buffer[3]=(unsigned char) (value >> 32);
5738 buffer[4]=(unsigned char) (value >> 24);
5739 buffer[5]=(unsigned char) (value >> 16);
5740 buffer[6]=(unsigned char) (value >> 8);
5741 buffer[7]=(unsigned char) value;
5742 return(WriteBlobStream(image,8,buffer));
5746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5750 + W r i t e B l o b M S B S i g n e d L o n g %
5754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5756 % WriteBlobMSBSignedLong() writes a signed value as a 32-bit quantity in
5757 % most-significant byte first order.
5759 % The format of the WriteBlobMSBSignedLong method is:
5761 % ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5763 % A description of each parameter follows.
5765 % o image: the image.
5767 % o value: Specifies the value to write.
5770 MagickExport ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5784 assert(image != (Image *) NULL);
5785 assert(image->signature == MagickCoreSignature);
5786 quantum.signed_value=value;
5787 buffer[0]=(unsigned char) (quantum.unsigned_value >> 24);
5788 buffer[1]=(unsigned char) (quantum.unsigned_value >> 16);
5789 buffer[2]=(unsigned char) (quantum.unsigned_value >> 8);
5790 buffer[3]=(unsigned char) quantum.unsigned_value;
5791 return(WriteBlobStream(image,4,buffer));
5795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5799 + W r i t e B l o b M S B S i g n e d S h o r t %
5803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5805 % WriteBlobMSBSignedShort() writes a signed short value as a 16-bit quantity
5806 % in most-significant byte first order.
5808 % The format of the WriteBlobMSBSignedShort method is:
5810 % ssize_t WriteBlobMSBSignedShort(Image *image,const signed short value)
5812 % A description of each parameter follows.
5814 % o image: the image.
5816 % o value: Specifies the value to write.
5819 MagickExport ssize_t WriteBlobMSBSignedShort(Image *image,
5820 const signed short value)
5834 assert(image != (Image *) NULL);
5835 assert(image->signature == MagickCoreSignature);
5836 quantum.signed_value=value;
5837 buffer[0]=(unsigned char) (quantum.unsigned_value >> 8);
5838 buffer[1]=(unsigned char) quantum.unsigned_value;
5839 return(WriteBlobStream(image,2,buffer));
5843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5847 + W r i t e B l o b M S B S h o r t %
5851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5853 % WriteBlobMSBShort() writes a unsigned short value as a 16-bit quantity in
5854 % most-significant byte first order.
5856 % The format of the WriteBlobMSBShort method is:
5858 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5860 % A description of each parameter follows.
5862 % o value: Specifies the value to write.
5864 % o file: Specifies the file to write the data to.
5867 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5872 assert(image != (Image *) NULL);
5873 assert(image->signature == MagickCoreSignature);
5874 buffer[0]=(unsigned char) (value >> 8);
5875 buffer[1]=(unsigned char) value;
5876 return(WriteBlobStream(image,2,buffer));
5880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5884 + W r i t e B l o b S t r i n g %
5888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5890 % WriteBlobString() write a string to a blob. It returns the number of
5891 % characters written.
5893 % The format of the WriteBlobString method is:
5895 % ssize_t WriteBlobString(Image *image,const char *string)
5897 % A description of each parameter follows.
5899 % o image: the image.
5901 % o string: Specifies the string to write.
5904 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
5906 assert(image != (Image *) NULL);
5907 assert(image->signature == MagickCoreSignature);
5908 assert(string != (const char *) NULL);
5909 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));