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;
1522 if ((image->blob->custom_stream->teller != (CustomStreamTeller) NULL) &&
1523 (image->blob->custom_stream->seeker != (CustomStreamSeeker) NULL))
1528 offset=image->blob->custom_stream->teller(
1529 image->blob->custom_stream->data);
1530 extent=(MagickSizeType) image->blob->custom_stream->seeker(0,SEEK_END,
1531 image->blob->custom_stream->data);
1532 (void) image->blob->custom_stream->seeker(offset,SEEK_SET,
1533 image->blob->custom_stream->data);
1542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1546 + G e t B l o b S t r e a m D a t a %
1550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1552 % GetBlobStreamData() returns the stream data for the image.
1554 % The format of the GetBlobStreamData method is:
1556 % void *GetBlobStreamData(const Image *image)
1558 % A description of each parameter follows:
1560 % o image: the image.
1563 MagickExport void *GetBlobStreamData(const Image *image)
1565 assert(image != (const Image *) NULL);
1566 assert(image->signature == MagickCoreSignature);
1567 return(image->blob->data);
1571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1575 + G e t B l o b S t r e a m H a n d l e r %
1579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1581 % GetBlobStreamHandler() returns the stream handler for the image.
1583 % The format of the GetBlobStreamHandler method is:
1585 % StreamHandler GetBlobStreamHandler(const Image *image)
1587 % A description of each parameter follows:
1589 % o image: the image.
1592 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1594 assert(image != (const Image *) NULL);
1595 assert(image->signature == MagickCoreSignature);
1596 if (image->debug != MagickFalse)
1597 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1598 return(image->blob->stream);
1602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1606 % I m a g e T o B l o b %
1610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1612 % ImageToBlob() implements direct to memory image formats. It returns the
1613 % image as a formatted blob and its length. The magick member of the Image
1614 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1615 % etc.). This method is the equivalent of WriteImage(), but writes the
1616 % formatted "file" to a memory buffer rather than to an actual file.
1618 % The format of the ImageToBlob method is:
1620 % void *ImageToBlob(const ImageInfo *image_info,Image *image,
1621 % size_t *length,ExceptionInfo *exception)
1623 % A description of each parameter follows:
1625 % o image_info: the image info.
1627 % o image: the image.
1629 % o length: return the actual length of the blob.
1631 % o exception: return any errors or warnings in this structure.
1634 MagickExport void *ImageToBlob(const ImageInfo *image_info,
1635 Image *image,size_t *length,ExceptionInfo *exception)
1649 assert(image_info != (const ImageInfo *) NULL);
1650 assert(image_info->signature == MagickCoreSignature);
1651 if (image_info->debug != MagickFalse)
1652 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1653 image_info->filename);
1654 assert(image != (Image *) NULL);
1655 assert(image->signature == MagickCoreSignature);
1656 assert(exception != (ExceptionInfo *) NULL);
1658 blob=(unsigned char *) NULL;
1659 blob_info=CloneImageInfo(image_info);
1660 blob_info->adjoin=MagickFalse;
1661 (void) SetImageInfo(blob_info,1,exception);
1662 if (*blob_info->magick != '\0')
1663 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1664 magick_info=GetMagickInfo(image->magick,exception);
1665 if (magick_info == (const MagickInfo *) NULL)
1667 (void) ThrowMagickException(exception,GetMagickModule(),
1668 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1670 blob_info=DestroyImageInfo(blob_info);
1673 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1674 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1677 Native blob support for this image format.
1679 blob_info->length=0;
1680 blob_info->blob=AcquireQuantumMemory(MagickMaxBlobExtent,
1681 sizeof(unsigned char));
1682 if (blob_info->blob == NULL)
1683 (void) ThrowMagickException(exception,GetMagickModule(),
1684 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1687 (void) CloseBlob(image);
1688 image->blob->exempt=MagickTrue;
1689 *image->filename='\0';
1690 status=WriteImage(blob_info,image,exception);
1691 *length=image->blob->length;
1692 blob=DetachBlob(image->blob);
1693 if (status == MagickFalse)
1694 blob=RelinquishMagickMemory(blob);
1696 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1702 unique[MagickPathExtent];
1708 Write file to disk in blob image format.
1710 file=AcquireUniqueFileResource(unique);
1713 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1714 image_info->filename);
1718 blob_info->file=fdopen(file,"wb");
1719 if (blob_info->file != (FILE *) NULL)
1721 (void) FormatLocaleString(image->filename,MagickPathExtent,
1722 "%s:%s",image->magick,unique);
1723 status=WriteImage(blob_info,image,exception);
1724 (void) CloseBlob(image);
1725 (void) fclose(blob_info->file);
1726 if (status != MagickFalse)
1727 blob=FileToBlob(unique,~0UL,length,exception);
1729 (void) RelinquishUniqueFileResource(unique);
1732 blob_info=DestroyImageInfo(blob_info);
1737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1741 + I m a g e T o C u s t o m S t r e a m %
1745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1747 % ImageToCustomStream() is the equivalent of WriteImage(), but writes the
1748 % formatted "file" to the custom stream rather than to an actual file.
1750 % The format of the ImageToCustomStream method is:
1752 % void ImageToCustomStream(const ImageInfo *image_info,Image *image,
1753 % ExceptionInfo *exception)
1755 % A description of each parameter follows:
1757 % o image_info: the image info.
1759 % o image: the image.
1761 % o exception: return any errors or warnings in this structure.
1764 MagickExport void ImageToCustomStream(const ImageInfo *image_info,Image *image,
1765 ExceptionInfo *exception)
1776 assert(image_info != (const ImageInfo *) NULL);
1777 assert(image_info->signature == MagickCoreSignature);
1778 if (image_info->debug != MagickFalse)
1779 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1780 image_info->filename);
1781 assert(image != (Image *) NULL);
1782 assert(image->signature == MagickCoreSignature);
1783 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
1784 assert(image_info->custom_stream->signature == MagickCoreSignature);
1785 assert(image_info->custom_stream->writer != (CustomStreamHandler) NULL);
1786 assert(exception != (ExceptionInfo *) NULL);
1787 blob_info=CloneImageInfo(image_info);
1788 blob_info->adjoin=MagickFalse;
1789 (void) SetImageInfo(blob_info,1,exception);
1790 if (*blob_info->magick != '\0')
1791 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1792 magick_info=GetMagickInfo(image->magick,exception);
1793 if (magick_info == (const MagickInfo *) NULL)
1795 (void) ThrowMagickException(exception,GetMagickModule(),
1796 MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'",
1798 blob_info=DestroyImageInfo(blob_info);
1801 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1802 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1805 Native blob support for this image format.
1807 (void) CloseBlob(image);
1808 *image->filename='\0';
1809 (void) WriteImage(blob_info,image,exception);
1810 (void) CloseBlob(image);
1815 unique[MagickPathExtent];
1824 Write file to disk in blob image format.
1826 blob_info->custom_stream=(CustomStreamInfo *) NULL;
1827 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
1829 if (blob == (unsigned char *) NULL)
1831 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1832 image_info->filename);
1833 blob_info=DestroyImageInfo(blob_info);
1836 file=AcquireUniqueFileResource(unique);
1839 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1840 image_info->filename);
1841 blob=(unsigned char *) RelinquishMagickMemory(blob);
1842 blob_info=DestroyImageInfo(blob_info);
1845 blob_info->file=fdopen(file,"wb+");
1846 if (blob_info->file != (FILE *) NULL)
1851 (void) FormatLocaleString(image->filename,MagickPathExtent,
1852 "%s:%s",image->magick,unique);
1853 status=WriteImage(blob_info,image,exception);
1854 (void) CloseBlob(image);
1855 if (status != MagickFalse)
1857 (void) fseek(blob_info->file,0,SEEK_SET);
1858 count=(ssize_t) MagickMaxBufferExtent;
1859 while (count == (ssize_t) MagickMaxBufferExtent)
1861 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
1863 (void) image_info->custom_stream->writer(blob,(size_t) count,
1864 image_info->custom_stream->data);
1867 (void) fclose(blob_info->file);
1869 blob=(unsigned char *) RelinquishMagickMemory(blob);
1870 (void) RelinquishUniqueFileResource(unique);
1872 blob_info=DestroyImageInfo(blob_info);
1876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1880 % I m a g e T o F i l e %
1884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1886 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1887 % occurs otherwise MagickTrue.
1889 % The format of the ImageToFile method is:
1891 % MagickBooleanType ImageToFile(Image *image,char *filename,
1892 % ExceptionInfo *exception)
1894 % A description of each parameter follows:
1896 % o image: the image.
1898 % o filename: Write the image to this file.
1900 % o exception: return any errors or warnings in this structure.
1903 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1904 ExceptionInfo *exception)
1909 register const unsigned char
1928 assert(image != (Image *) NULL);
1929 assert(image->signature == MagickCoreSignature);
1930 assert(image->blob != (BlobInfo *) NULL);
1931 assert(image->blob->type != UndefinedStream);
1932 if (image->debug != MagickFalse)
1933 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1934 assert(filename != (const char *) NULL);
1935 if (*filename == '\0')
1936 file=AcquireUniqueFileResource(filename);
1938 if (LocaleCompare(filename,"-") == 0)
1939 file=fileno(stdout);
1941 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1944 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1945 return(MagickFalse);
1947 quantum=(size_t) MagickMaxBufferExtent;
1948 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1949 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1950 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1951 if (buffer == (unsigned char *) NULL)
1954 (void) ThrowMagickException(exception,GetMagickModule(),
1955 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1956 return(MagickFalse);
1959 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1960 for (i=0; count > 0; )
1962 length=(size_t) count;
1963 for (i=0; i < length; i+=count)
1965 count=write(file,p+i,(size_t) (length-i));
1975 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1977 if (LocaleCompare(filename,"-") != 0)
1979 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1980 if ((file == -1) || (i < length))
1984 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1985 return(MagickFalse);
1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1995 % I m a g e s T o B l o b %
1999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001 % ImagesToBlob() implements direct to memory image formats. It returns the
2002 % image sequence as a blob and its length. The magick member of the ImageInfo
2003 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
2005 % Note, some image formats do not permit multiple images to the same image
2006 % stream (e.g. JPEG). in this instance, just the first image of the
2007 % sequence is returned as a blob.
2009 % The format of the ImagesToBlob method is:
2011 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
2012 % size_t *length,ExceptionInfo *exception)
2014 % A description of each parameter follows:
2016 % o image_info: the image info.
2018 % o images: the image list.
2020 % o length: return the actual length of the blob.
2022 % o exception: return any errors or warnings in this structure.
2025 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
2026 size_t *length,ExceptionInfo *exception)
2040 assert(image_info != (const ImageInfo *) NULL);
2041 assert(image_info->signature == MagickCoreSignature);
2042 if (image_info->debug != MagickFalse)
2043 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2044 image_info->filename);
2045 assert(images != (Image *) NULL);
2046 assert(images->signature == MagickCoreSignature);
2047 assert(exception != (ExceptionInfo *) NULL);
2049 blob=(unsigned char *) NULL;
2050 blob_info=CloneImageInfo(image_info);
2051 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2053 if (*blob_info->magick != '\0')
2054 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2055 magick_info=GetMagickInfo(images->magick,exception);
2056 if (magick_info == (const MagickInfo *) NULL)
2058 (void) ThrowMagickException(exception,GetMagickModule(),
2059 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
2061 blob_info=DestroyImageInfo(blob_info);
2064 if (GetMagickAdjoin(magick_info) == MagickFalse)
2066 blob_info=DestroyImageInfo(blob_info);
2067 return(ImageToBlob(image_info,images,length,exception));
2069 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2070 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2073 Native blob support for this images format.
2075 blob_info->length=0;
2076 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
2077 sizeof(unsigned char));
2078 if (blob_info->blob == (void *) NULL)
2079 (void) ThrowMagickException(exception,GetMagickModule(),
2080 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
2083 (void) CloseBlob(images);
2084 images->blob->exempt=MagickTrue;
2085 *images->filename='\0';
2086 status=WriteImages(blob_info,images,images->filename,exception);
2087 *length=images->blob->length;
2088 blob=DetachBlob(images->blob);
2089 if (status == MagickFalse)
2090 blob=RelinquishMagickMemory(blob);
2092 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
2098 filename[MagickPathExtent],
2099 unique[MagickPathExtent];
2105 Write file to disk in blob images format.
2107 file=AcquireUniqueFileResource(unique);
2110 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
2111 image_info->filename);
2115 blob_info->file=fdopen(file,"wb");
2116 if (blob_info->file != (FILE *) NULL)
2118 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2119 images->magick,unique);
2120 status=WriteImages(blob_info,images,filename,exception);
2121 (void) CloseBlob(images);
2122 (void) fclose(blob_info->file);
2123 if (status != MagickFalse)
2124 blob=FileToBlob(unique,~0UL,length,exception);
2126 (void) RelinquishUniqueFileResource(unique);
2129 blob_info=DestroyImageInfo(blob_info);
2134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2138 + I m a g e s T o C u s t o m B l o b %
2142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2144 % ImagesToCustomStream() is the equivalent of WriteImages(), but writes the
2145 % formatted "file" to the custom stream rather than to an actual file.
2147 % The format of the ImageToCustomStream method is:
2149 % void ImagesToCustomStream(const ImageInfo *image_info,Image *images,
2150 % ExceptionInfo *exception)
2152 % A description of each parameter follows:
2154 % o image_info: the image info.
2156 % o images: the image list.
2158 % o exception: return any errors or warnings in this structure.
2161 MagickExport void ImagesToCustomStream(const ImageInfo *image_info,
2162 Image *images,ExceptionInfo *exception)
2173 assert(image_info != (const ImageInfo *) NULL);
2174 assert(image_info->signature == MagickCoreSignature);
2175 if (image_info->debug != MagickFalse)
2176 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2177 image_info->filename);
2178 assert(images != (Image *) NULL);
2179 assert(images->signature == MagickCoreSignature);
2180 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
2181 assert(image_info->custom_stream->signature == MagickCoreSignature);
2182 assert(image_info->custom_stream->reader != (CustomStreamHandler) NULL);
2183 assert(image_info->custom_stream->writer != (CustomStreamHandler) NULL);
2184 assert(exception != (ExceptionInfo *) NULL);
2185 blob_info=CloneImageInfo(image_info);
2186 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2188 if (*blob_info->magick != '\0')
2189 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2190 magick_info=GetMagickInfo(images->magick,exception);
2191 if (magick_info == (const MagickInfo *) NULL)
2193 (void) ThrowMagickException(exception,GetMagickModule(),
2194 MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'",
2196 blob_info=DestroyImageInfo(blob_info);
2199 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2200 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2203 Native blob support for this image format.
2205 (void) CloseBlob(images);
2206 *images->filename='\0';
2207 (void) WriteImages(blob_info,images,images->filename,exception);
2208 (void) CloseBlob(images);
2213 filename[MagickPathExtent],
2214 unique[MagickPathExtent];
2223 Write file to disk in blob image format.
2225 blob_info->custom_stream=(CustomStreamInfo *) NULL;
2226 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
2228 if (blob == (unsigned char *) NULL)
2230 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2231 image_info->filename);
2232 blob_info=DestroyImageInfo(blob_info);
2235 file=AcquireUniqueFileResource(unique);
2238 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2239 image_info->filename);
2240 blob=(unsigned char *) RelinquishMagickMemory(blob);
2241 blob_info=DestroyImageInfo(blob_info);
2244 blob_info->file=fdopen(file,"wb+");
2245 if (blob_info->file != (FILE *) NULL)
2250 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2251 images->magick,unique);
2252 status=WriteImages(blob_info,images,filename,exception);
2253 (void) CloseBlob(images);
2254 if (status != MagickFalse)
2256 (void) fseek(blob_info->file,0,SEEK_SET);
2257 count=(ssize_t) MagickMaxBufferExtent;
2258 while (count == (ssize_t) MagickMaxBufferExtent)
2260 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
2262 (void) image_info->custom_stream->writer(blob,(size_t) count,
2263 image_info->custom_stream->data);
2266 (void) fclose(blob_info->file);
2268 blob=(unsigned char *) RelinquishMagickMemory(blob);
2269 (void) RelinquishUniqueFileResource(unique);
2271 blob_info=DestroyImageInfo(blob_info);
2276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2280 % I n j e c t I m a g e B l o b %
2284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2286 % InjectImageBlob() injects the image with a copy of itself in the specified
2287 % format (e.g. inject JPEG into a PDF image).
2289 % The format of the InjectImageBlob method is:
2291 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2292 % Image *image,Image *inject_image,const char *format,
2293 % ExceptionInfo *exception)
2295 % A description of each parameter follows:
2297 % o image_info: the image info..
2299 % o image: the image.
2301 % o inject_image: inject into the image stream.
2303 % o format: the image format.
2305 % o exception: return any errors or warnings in this structure.
2308 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2309 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
2312 filename[MagickPathExtent];
2345 Write inject image to a temporary file.
2347 assert(image_info != (ImageInfo *) NULL);
2348 assert(image_info->signature == MagickCoreSignature);
2349 assert(image != (Image *) NULL);
2350 assert(image->signature == MagickCoreSignature);
2351 if (image->debug != MagickFalse)
2352 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2353 assert(inject_image != (Image *) NULL);
2354 assert(inject_image->signature == MagickCoreSignature);
2355 assert(exception != (ExceptionInfo *) NULL);
2356 unique_file=(FILE *) NULL;
2357 file=AcquireUniqueFileResource(filename);
2359 unique_file=fdopen(file,"wb");
2360 if ((file == -1) || (unique_file == (FILE *) NULL))
2362 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2363 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
2365 return(MagickFalse);
2367 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
2368 if (byte_image == (Image *) NULL)
2370 (void) fclose(unique_file);
2371 (void) RelinquishUniqueFileResource(filename);
2372 return(MagickFalse);
2374 (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",
2376 DestroyBlob(byte_image);
2377 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
2378 write_info=CloneImageInfo(image_info);
2379 SetImageInfoFile(write_info,unique_file);
2380 status=WriteImage(write_info,byte_image,exception);
2381 write_info=DestroyImageInfo(write_info);
2382 byte_image=DestroyImage(byte_image);
2383 (void) fclose(unique_file);
2384 if (status == MagickFalse)
2386 (void) RelinquishUniqueFileResource(filename);
2387 return(MagickFalse);
2390 Inject into image stream.
2392 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
2395 (void) RelinquishUniqueFileResource(filename);
2396 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
2397 image_info->filename);
2398 return(MagickFalse);
2400 quantum=(size_t) MagickMaxBufferExtent;
2401 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
2402 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2403 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2404 if (buffer == (unsigned char *) NULL)
2406 (void) RelinquishUniqueFileResource(filename);
2408 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2411 for (i=0; ; i+=count)
2413 count=read(file,buffer,quantum);
2420 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2425 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2426 (void) RelinquishUniqueFileResource(filename);
2427 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2436 % I s B l o b E x e m p t %
2440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2442 % IsBlobExempt() returns true if the blob is exempt.
2444 % The format of the IsBlobExempt method is:
2446 % MagickBooleanType IsBlobExempt(const Image *image)
2448 % A description of each parameter follows:
2450 % o image: the image.
2453 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
2455 assert(image != (const Image *) NULL);
2456 assert(image->signature == MagickCoreSignature);
2457 if (image->debug != MagickFalse)
2458 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2459 return(image->blob->exempt);
2463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2467 % I s B l o b S e e k a b l e %
2471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2473 % IsBlobSeekable() returns true if the blob is seekable.
2475 % The format of the IsBlobSeekable method is:
2477 % MagickBooleanType IsBlobSeekable(const Image *image)
2479 % A description of each parameter follows:
2481 % o image: the image.
2484 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2489 assert(image != (const Image *) NULL);
2490 assert(image->signature == MagickCoreSignature);
2491 if (image->debug != MagickFalse)
2492 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2493 switch (image->blob->type)
2499 seekable=MagickTrue;
2502 case UndefinedStream:
2503 case StandardStream:
2509 seekable=MagickFalse;
2514 if ((image->blob->custom_stream->seeker != (CustomStreamSeeker) NULL) &&
2515 (image->blob->custom_stream->teller != (CustomStreamTeller) NULL))
2516 seekable=MagickTrue;
2518 seekable=MagickFalse;
2526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2530 % I s B l o b T e m p o r a r y %
2534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2536 % IsBlobTemporary() returns true if the blob is temporary.
2538 % The format of the IsBlobTemporary method is:
2540 % MagickBooleanType IsBlobTemporary(const Image *image)
2542 % A description of each parameter follows:
2544 % o image: the image.
2547 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2549 assert(image != (const Image *) NULL);
2550 assert(image->signature == MagickCoreSignature);
2551 if (image->debug != MagickFalse)
2552 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2553 return(image->blob->temporary);
2557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2567 % MapBlob() creates a mapping from a file to a binary large object.
2569 % The format of the MapBlob method is:
2571 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2572 % const size_t length)
2574 % A description of each parameter follows:
2576 % o file: map this file descriptor.
2578 % o mode: ReadMode, WriteMode, or IOMode.
2580 % o offset: starting at this offset within the file.
2582 % o length: the length of the mapping is returned in this pointer.
2585 MagickExport void *MapBlob(int file,const MapMode mode,
2586 const MagickOffsetType offset,const size_t length)
2588 #if defined(MAGICKCORE_HAVE_MMAP)
2601 #if defined(MAP_ANONYMOUS)
2602 flags|=MAP_ANONYMOUS;
2611 protection=PROT_READ;
2617 protection=PROT_WRITE;
2623 protection=PROT_READ | PROT_WRITE;
2628 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2629 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2631 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2633 if (map == MAP_FAILED)
2634 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2636 if (map == MAP_FAILED)
2649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2653 + M S B O r d e r L o n g %
2657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2659 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2660 % most-significant byte first.
2662 % The format of the MSBOrderLong method is:
2664 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2666 % A description of each parameter follows.
2668 % o buffer: Specifies a pointer to a buffer of integers.
2670 % o length: Specifies the length of the buffer.
2673 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2678 register unsigned char
2682 assert(buffer != (unsigned char *) NULL);
2689 *buffer++=(unsigned char) c;
2693 *buffer++=(unsigned char) c;
2699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2703 + M S B O r d e r S h o r t %
2707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2709 % MSBOrderShort() converts a least-significant byte first buffer of integers
2710 % to most-significant byte first.
2712 % The format of the MSBOrderShort method is:
2714 % void MSBOrderShort(unsigned char *p,const size_t length)
2716 % A description of each parameter follows.
2718 % o p: Specifies a pointer to a buffer of integers.
2720 % o length: Specifies the length of the buffer.
2723 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2728 register unsigned char
2731 assert(p != (unsigned char *) NULL);
2738 *p++=(unsigned char) c;
2743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2753 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2754 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2755 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2756 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2757 % from a system command.
2759 % The format of the OpenBlob method is:
2761 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2762 % const BlobMode mode,ExceptionInfo *exception)
2764 % A description of each parameter follows:
2766 % o image_info: the image info.
2768 % o image: the image.
2770 % o mode: the mode for opening the file.
2774 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2787 option=GetImageOption(image_info,"stream:buffer-size");
2788 if (option != (const char *) NULL)
2789 size=StringToUnsignedLong(option);
2790 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2791 _IONBF : _IOFBF,size);
2792 return(status == 0 ? MagickTrue : MagickFalse);
2795 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2796 Image *image,const BlobMode mode,ExceptionInfo *exception)
2799 extension[MagickPathExtent],
2800 filename[MagickPathExtent];
2811 assert(image_info != (ImageInfo *) NULL);
2812 assert(image_info->signature == MagickCoreSignature);
2813 if (image_info->debug != MagickFalse)
2814 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2815 image_info->filename);
2816 assert(image != (Image *) NULL);
2817 assert(image->signature == MagickCoreSignature);
2818 if (image_info->blob != (void *) NULL)
2820 if (image_info->stream != (StreamHandler) NULL)
2821 image->blob->stream=(StreamHandler) image_info->stream;
2822 AttachBlob(image->blob,image_info->blob,image_info->length);
2825 if ((image_info->custom_stream != (CustomStreamInfo *) NULL) &&
2826 (*image->filename == '\0'))
2828 image->blob->type=CustomStream;
2829 image->blob->custom_stream=image_info->custom_stream;
2832 (void) DetachBlob(image->blob);
2835 default: type="r"; break;
2836 case ReadBlobMode: type="r"; break;
2837 case ReadBinaryBlobMode: type="rb"; break;
2838 case WriteBlobMode: type="w"; break;
2839 case WriteBinaryBlobMode: type="w+b"; break;
2840 case AppendBlobMode: type="a"; break;
2841 case AppendBinaryBlobMode: type="a+b"; break;
2844 image->blob->synchronize=image_info->synchronize;
2845 if (image_info->stream != (StreamHandler) NULL)
2847 image->blob->stream=image_info->stream;
2850 image->blob->type=FifoStream;
2858 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2859 rights=ReadPolicyRights;
2861 rights=WritePolicyRights;
2862 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2865 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2866 "NotAuthorized","`%s'",filename);
2867 return(MagickFalse);
2869 if ((LocaleCompare(filename,"-") == 0) ||
2870 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2872 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2873 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2874 if (strchr(type,'b') != (char *) NULL)
2875 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2877 image->blob->type=StandardStream;
2878 image->blob->exempt=MagickTrue;
2879 return(SetStreamBuffering(image_info,image));
2881 if (LocaleNCompare(filename,"fd:",3) == 0)
2884 fileMode[MagickPathExtent];
2888 image->blob->file_info.file=fdopen(StringToLong(filename+3),fileMode);
2889 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2890 if (strchr(type,'b') != (char *) NULL)
2891 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2893 image->blob->type=StandardStream;
2894 image->blob->exempt=MagickTrue;
2895 return(SetStreamBuffering(image_info,image));
2897 #if defined(MAGICKCORE_HAVE_POPEN) && defined(MAGICKCORE_PIPES_SUPPORT)
2898 if (*filename == '|')
2901 fileMode[MagickPathExtent],
2905 Pipe image to or from a system command.
2907 #if defined(SIGPIPE)
2909 (void) signal(SIGPIPE,SIG_IGN);
2913 sanitize_command=SanitizeString(filename+1);
2914 image->blob->file_info.file=(FILE *) popen_utf8(sanitize_command,
2916 sanitize_command=DestroyString(sanitize_command);
2917 if (image->blob->file_info.file == (FILE *) NULL)
2919 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2920 return(MagickFalse);
2922 image->blob->type=PipeStream;
2923 image->blob->exempt=MagickTrue;
2924 return(SetStreamBuffering(image_info,image));
2927 status=GetPathAttributes(filename,&image->blob->properties);
2928 #if defined(S_ISFIFO)
2929 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2931 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2932 if (image->blob->file_info.file == (FILE *) NULL)
2934 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2935 return(MagickFalse);
2937 image->blob->type=FileStream;
2938 image->blob->exempt=MagickTrue;
2939 return(SetStreamBuffering(image_info,image));
2942 GetPathComponent(image->filename,ExtensionPath,extension);
2945 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2946 if ((image_info->adjoin == MagickFalse) ||
2947 (strchr(filename,'%') != (char *) NULL))
2950 Form filename for multi-part images.
2952 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2953 image->scene,filename,exception);
2954 if ((LocaleCompare(filename,image->filename) == 0) &&
2955 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2956 (GetNextImageInList(image) != (Image *) NULL)))
2959 path[MagickPathExtent];
2961 GetPathComponent(image->filename,RootPath,path);
2962 if (*extension == '\0')
2963 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
2964 path,(double) image->scene);
2966 (void) FormatLocaleString(filename,MagickPathExtent,
2967 "%s-%.20g.%s",path,(double) image->scene,extension);
2969 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2970 #if defined(macintosh)
2971 SetApplicationType(filename,image_info->magick,'8BIM');
2975 if (image_info->file != (FILE *) NULL)
2977 image->blob->file_info.file=image_info->file;
2978 image->blob->type=FileStream;
2979 image->blob->exempt=MagickTrue;
2984 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2985 if (image->blob->file_info.file != (FILE *) NULL)
2993 image->blob->type=FileStream;
2994 (void) SetStreamBuffering(image_info,image);
2995 (void) ResetMagickMemory(magick,0,sizeof(magick));
2996 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2997 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2998 #if defined(MAGICKCORE_POSIX_SUPPORT)
2999 (void) fflush(image->blob->file_info.file);
3001 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
3002 " read %.20g magic header bytes",(double) count);
3003 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3004 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
3005 ((int) magick[2] == 0x08))
3007 if (image->blob->file_info.file != (FILE *) NULL)
3008 (void) fclose(image->blob->file_info.file);
3009 image->blob->file_info.file=(FILE *) NULL;
3010 image->blob->file_info.gzfile=gzopen(filename,type);
3011 if (image->blob->file_info.gzfile != (gzFile) NULL)
3012 image->blob->type=ZipStream;
3015 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3016 if (strncmp((char *) magick,"BZh",3) == 0)
3018 if (image->blob->file_info.file != (FILE *) NULL)
3019 (void) fclose(image->blob->file_info.file);
3020 image->blob->file_info.file=(FILE *) NULL;
3021 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3022 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3023 image->blob->type=BZipStream;
3026 if (image->blob->type == FileStream)
3037 sans_exception=AcquireExceptionInfo();
3038 magick_info=GetMagickInfo(image_info->magick,sans_exception);
3039 sans_exception=DestroyExceptionInfo(sans_exception);
3040 length=(size_t) image->blob->properties.st_size;
3041 if ((magick_info != (const MagickInfo *) NULL) &&
3042 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
3043 (length > MagickMaxBufferExtent) &&
3044 (AcquireMagickResource(MapResource,length) != MagickFalse))
3049 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
3051 if (blob == (void *) NULL)
3052 RelinquishMagickResource(MapResource,length);
3056 Format supports blobs-- use memory-mapped I/O.
3058 if (image_info->file != (FILE *) NULL)
3059 image->blob->exempt=MagickFalse;
3062 (void) fclose(image->blob->file_info.file);
3063 image->blob->file_info.file=(FILE *) NULL;
3065 AttachBlob(image->blob,blob,length);
3066 image->blob->mapped=MagickTrue;
3073 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3074 if ((LocaleCompare(extension,"Z") == 0) ||
3075 (LocaleCompare(extension,"gz") == 0) ||
3076 (LocaleCompare(extension,"wmz") == 0) ||
3077 (LocaleCompare(extension,"svgz") == 0))
3079 if (mode == WriteBinaryBlobMode)
3081 image->blob->file_info.gzfile=gzopen(filename,type);
3082 if (image->blob->file_info.gzfile != (gzFile) NULL)
3083 image->blob->type=ZipStream;
3087 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3088 if (LocaleCompare(extension,"bz2") == 0)
3090 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
3091 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
3092 image->blob->type=BZipStream;
3097 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
3098 if (image->blob->file_info.file != (FILE *) NULL)
3100 image->blob->type=FileStream;
3101 (void) SetStreamBuffering(image_info,image);
3104 image->blob->status=MagickFalse;
3105 if (image->blob->type != UndefinedStream)
3106 image->blob->size=GetBlobSize(image);
3109 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
3110 return(MagickFalse);
3116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3126 % PingBlob() returns all the attributes of an image or image sequence except
3127 % for the pixels. It is much faster and consumes far less memory than
3128 % BlobToImage(). On failure, a NULL image is returned and exception
3129 % describes the reason for the failure.
3131 % The format of the PingBlob method is:
3133 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
3134 % const size_t length,ExceptionInfo *exception)
3136 % A description of each parameter follows:
3138 % o image_info: the image info.
3140 % o blob: the address of a character stream in one of the image formats
3141 % understood by ImageMagick.
3143 % o length: This size_t integer reflects the length in bytes of the blob.
3145 % o exception: return any errors or warnings in this structure.
3149 #if defined(__cplusplus) || defined(c_plusplus)
3153 static size_t PingStream(const Image *magick_unused(image),
3154 const void *magick_unused(pixels),const size_t columns)
3156 magick_unreferenced(image);
3157 magick_unreferenced(pixels);
3161 #if defined(__cplusplus) || defined(c_plusplus)
3165 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
3166 const size_t length,ExceptionInfo *exception)
3174 assert(image_info != (ImageInfo *) NULL);
3175 assert(image_info->signature == MagickCoreSignature);
3176 if (image_info->debug != MagickFalse)
3177 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3178 image_info->filename);
3179 assert(exception != (ExceptionInfo *) NULL);
3180 if ((blob == (const void *) NULL) || (length == 0))
3182 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
3183 "UnrecognizedImageFormat","`%s'",image_info->magick);
3184 return((Image *) NULL);
3186 ping_info=CloneImageInfo(image_info);
3187 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
3188 if (ping_info->blob == (const void *) NULL)
3190 (void) ThrowMagickException(exception,GetMagickModule(),
3191 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
3192 return((Image *) NULL);
3194 (void) memcpy(ping_info->blob,blob,length);
3195 ping_info->length=length;
3196 ping_info->ping=MagickTrue;
3197 image=ReadStream(ping_info,&PingStream,exception);
3198 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
3199 ping_info=DestroyImageInfo(ping_info);
3204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3214 % ReadBlob() reads data from the blob or image file and returns it. It
3215 % returns the number of bytes read. If length is zero, ReadBlob() returns
3216 % zero and has no other results. If length is greater than SSIZE_MAX, the
3217 % result is unspecified.
3219 % The format of the ReadBlob method is:
3221 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
3223 % A description of each parameter follows:
3225 % o image: the image.
3227 % o length: Specifies an integer representing the number of bytes to read
3230 % o data: Specifies an area to place the information requested from the
3234 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
3239 register unsigned char
3245 assert(image != (Image *) NULL);
3246 assert(image->signature == MagickCoreSignature);
3247 assert(image->blob != (BlobInfo *) NULL);
3248 assert(image->blob->type != UndefinedStream);
3251 assert(data != (void *) NULL);
3253 q=(unsigned char *) data;
3254 switch (image->blob->type)
3256 case UndefinedStream:
3258 case StandardStream:
3266 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
3271 c=getc(image->blob->file_info.file);
3274 *q++=(unsigned char) c;
3279 c=getc(image->blob->file_info.file);
3282 *q++=(unsigned char) c;
3287 c=getc(image->blob->file_info.file);
3290 *q++=(unsigned char) c;
3295 c=getc(image->blob->file_info.file);
3298 *q++=(unsigned char) c;
3308 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3313 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
3314 (unsigned int) length);
3319 c=gzgetc(image->blob->file_info.gzfile);
3322 *q++=(unsigned char) c;
3327 c=gzgetc(image->blob->file_info.gzfile);
3330 *q++=(unsigned char) c;
3335 c=gzgetc(image->blob->file_info.gzfile);
3338 *q++=(unsigned char) c;
3343 c=gzgetc(image->blob->file_info.gzfile);
3346 *q++=(unsigned char) c;
3357 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3358 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
3366 register const unsigned char
3369 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3371 image->blob->eof=MagickTrue;
3374 p=image->blob->data+image->blob->offset;
3375 count=(ssize_t) MagickMin((MagickOffsetType) length,image->blob->length-
3376 image->blob->offset);
3377 image->blob->offset+=count;
3378 if (count != (ssize_t) length)
3379 image->blob->eof=MagickTrue;
3380 (void) memcpy(q,p,(size_t) count);
3385 if (image->blob->custom_stream->reader != (CustomStreamHandler) NULL)
3386 count=image->blob->custom_stream->reader(q,length,
3387 image->blob->custom_stream->data);
3395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3399 + R e a d B l o b B y t e %
3403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3405 % ReadBlobByte() reads a single byte from the image file and returns it.
3407 % The format of the ReadBlobByte method is:
3409 % int ReadBlobByte(Image *image)
3411 % A description of each parameter follows.
3413 % o image: the image.
3416 MagickExport int ReadBlobByte(Image *image)
3418 register const unsigned char
3427 assert(image != (Image *) NULL);
3428 assert(image->signature == MagickCoreSignature);
3429 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3440 + R e a d B l o b D o u b l e %
3444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3446 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3447 % specified by the endian member of the image structure.
3449 % The format of the ReadBlobDouble method is:
3451 % double ReadBlobDouble(Image *image)
3453 % A description of each parameter follows.
3455 % o image: the image.
3458 MagickExport double ReadBlobDouble(Image *image)
3469 quantum.double_value=0.0;
3470 quantum.unsigned_value=ReadBlobLongLong(image);
3471 return(quantum.double_value);
3475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3479 + R e a d B l o b F l o a t %
3483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3485 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3486 % specified by the endian member of the image structure.
3488 % The format of the ReadBlobFloat method is:
3490 % float ReadBlobFloat(Image *image)
3492 % A description of each parameter follows.
3494 % o image: the image.
3497 MagickExport float ReadBlobFloat(Image *image)
3508 quantum.float_value=0.0;
3509 quantum.unsigned_value=ReadBlobLong(image);
3510 return(quantum.float_value);
3514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3518 + R e a d B l o b L o n g %
3522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3524 % ReadBlobLong() reads a unsigned int value as a 32-bit quantity in the
3525 % byte-order specified by the endian member of the image structure.
3527 % The format of the ReadBlobLong method is:
3529 % unsigned int ReadBlobLong(Image *image)
3531 % A description of each parameter follows.
3533 % o image: the image.
3536 MagickExport unsigned int ReadBlobLong(Image *image)
3538 register const unsigned char
3550 assert(image != (Image *) NULL);
3551 assert(image->signature == MagickCoreSignature);
3553 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3556 if (image->endian == LSBEndian)
3558 value=(unsigned int) (*p++);
3559 value|=(unsigned int) (*p++) << 8;
3560 value|=(unsigned int) (*p++) << 16;
3561 value|=(unsigned int) (*p++) << 24;
3564 value=(unsigned int) (*p++) << 24;
3565 value|=(unsigned int) (*p++) << 16;
3566 value|=(unsigned int) (*p++) << 8;
3567 value|=(unsigned int) (*p++);
3572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3576 + R e a d B l o b L o n g L o n g %
3580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3582 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3583 % byte-order specified by the endian member of the image structure.
3585 % The format of the ReadBlobLongLong method is:
3587 % MagickSizeType ReadBlobLongLong(Image *image)
3589 % A description of each parameter follows.
3591 % o image: the image.
3594 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3599 register const unsigned char
3608 assert(image != (Image *) NULL);
3609 assert(image->signature == MagickCoreSignature);
3611 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3613 return(MagickULLConstant(0));
3614 if (image->endian == LSBEndian)
3616 value=(MagickSizeType) (*p++);
3617 value|=(MagickSizeType) (*p++) << 8;
3618 value|=(MagickSizeType) (*p++) << 16;
3619 value|=(MagickSizeType) (*p++) << 24;
3620 value|=(MagickSizeType) (*p++) << 32;
3621 value|=(MagickSizeType) (*p++) << 40;
3622 value|=(MagickSizeType) (*p++) << 48;
3623 value|=(MagickSizeType) (*p++) << 56;
3626 value=(MagickSizeType) (*p++) << 56;
3627 value|=(MagickSizeType) (*p++) << 48;
3628 value|=(MagickSizeType) (*p++) << 40;
3629 value|=(MagickSizeType) (*p++) << 32;
3630 value|=(MagickSizeType) (*p++) << 24;
3631 value|=(MagickSizeType) (*p++) << 16;
3632 value|=(MagickSizeType) (*p++) << 8;
3633 value|=(MagickSizeType) (*p++);
3638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3642 + R e a d B l o b S h o r t %
3646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3648 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3649 % specified by the endian member of the image structure.
3651 % The format of the ReadBlobShort method is:
3653 % unsigned short ReadBlobShort(Image *image)
3655 % A description of each parameter follows.
3657 % o image: the image.
3660 MagickExport unsigned short ReadBlobShort(Image *image)
3662 register const unsigned char
3665 register unsigned short
3674 assert(image != (Image *) NULL);
3675 assert(image->signature == MagickCoreSignature);
3677 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3679 return((unsigned short) 0U);
3680 if (image->endian == LSBEndian)
3682 value=(unsigned short) (*p++);
3683 value|=(unsigned short) (*p++) << 8;
3686 value=(unsigned short) ((unsigned short) (*p++) << 8);
3687 value|=(unsigned short) (*p++);
3692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3696 + R e a d B l o b L S B L o n g %
3700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3702 % ReadBlobLSBLong() reads a unsigned int value as a 32-bit quantity in
3703 % least-significant byte first order.
3705 % The format of the ReadBlobLSBLong method is:
3707 % unsigned int ReadBlobLSBLong(Image *image)
3709 % A description of each parameter follows.
3711 % o image: the image.
3714 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3716 register const unsigned char
3719 register unsigned int
3728 assert(image != (Image *) NULL);
3729 assert(image->signature == MagickCoreSignature);
3731 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3734 value=(unsigned int) (*p++);
3735 value|=(unsigned int) (*p++) << 8;
3736 value|=(unsigned int) (*p++) << 16;
3737 value|=(unsigned int) (*p++) << 24;
3742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3746 + R e a d B l o b L S B S i g n e d L o n g %
3750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3752 % ReadBlobLSBSignedLong() reads a signed int value as a 32-bit quantity in
3753 % least-significant byte first order.
3755 % The format of the ReadBlobLSBSignedLong method is:
3757 % signed int ReadBlobLSBSignedLong(Image *image)
3759 % A description of each parameter follows.
3761 % o image: the image.
3764 MagickExport signed int ReadBlobLSBSignedLong(Image *image)
3775 quantum.unsigned_value=ReadBlobLSBLong(image);
3776 return(quantum.signed_value);
3780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3784 + R e a d B l o b L S B S h o r t %
3788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3790 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3791 % least-significant byte first order.
3793 % The format of the ReadBlobLSBShort method is:
3795 % unsigned short ReadBlobLSBShort(Image *image)
3797 % A description of each parameter follows.
3799 % o image: the image.
3802 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3804 register const unsigned char
3807 register unsigned short
3816 assert(image != (Image *) NULL);
3817 assert(image->signature == MagickCoreSignature);
3819 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3821 return((unsigned short) 0U);
3822 value=(unsigned short) (*p++);
3823 value|=(unsigned short) (*p++) << 8;
3828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3832 + R e a d B l o b L S B S i g n e d S h o r t %
3836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3838 % ReadBlobLSBSignedShort() reads a signed short value as a 16-bit quantity in
3839 % least-significant byte-order.
3841 % The format of the ReadBlobLSBSignedShort method is:
3843 % signed short ReadBlobLSBSignedShort(Image *image)
3845 % A description of each parameter follows.
3847 % o image: the image.
3850 MagickExport signed short ReadBlobLSBSignedShort(Image *image)
3861 quantum.unsigned_value=ReadBlobLSBShort(image);
3862 return(quantum.signed_value);
3866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3870 + R e a d B l o b M S B L o n g %
3874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3876 % ReadBlobMSBLong() reads a unsigned int value as a 32-bit quantity in
3877 % most-significant byte first order.
3879 % The format of the ReadBlobMSBLong method is:
3881 % unsigned int ReadBlobMSBLong(Image *image)
3883 % A description of each parameter follows.
3885 % o image: the image.
3888 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3890 register const unsigned char
3893 register unsigned int
3902 assert(image != (Image *) NULL);
3903 assert(image->signature == MagickCoreSignature);
3905 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3908 value=(unsigned int) (*p++) << 24;
3909 value|=(unsigned int) (*p++) << 16;
3910 value|=(unsigned int) (*p++) << 8;
3911 value|=(unsigned int) (*p++);
3916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3920 + R e a d B l o b M S B L o n g L o n g %
3924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3926 % ReadBlobMSBLongLong() reads a unsigned long long value as a 64-bit quantity
3927 % in most-significant byte first order.
3929 % The format of the ReadBlobMSBLongLong method is:
3931 % unsigned int ReadBlobMSBLongLong(Image *image)
3933 % A description of each parameter follows.
3935 % o image: the image.
3938 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3940 register const unsigned char
3943 register MagickSizeType
3952 assert(image != (Image *) NULL);
3953 assert(image->signature == MagickCoreSignature);
3955 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3957 return(MagickULLConstant(0));
3958 value=(MagickSizeType) (*p++) << 56;
3959 value|=(MagickSizeType) (*p++) << 48;
3960 value|=(MagickSizeType) (*p++) << 40;
3961 value|=(MagickSizeType) (*p++) << 32;
3962 value|=(MagickSizeType) (*p++) << 24;
3963 value|=(MagickSizeType) (*p++) << 16;
3964 value|=(MagickSizeType) (*p++) << 8;
3965 value|=(MagickSizeType) (*p++);
3970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3974 + R e a d B l o b M S B S h o r t %
3978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3980 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3981 % most-significant byte first order.
3983 % The format of the ReadBlobMSBShort method is:
3985 % unsigned short ReadBlobMSBShort(Image *image)
3987 % A description of each parameter follows.
3989 % o image: the image.
3992 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3994 register const unsigned char
3997 register unsigned short
4006 assert(image != (Image *) NULL);
4007 assert(image->signature == MagickCoreSignature);
4009 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
4011 return((unsigned short) 0U);
4012 value=(unsigned short) ((*p++) << 8);
4013 value|=(unsigned short) (*p++);
4014 return((unsigned short) (value & 0xffff));
4018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4022 + R e a d B l o b M S B S i g n e d L o n g %
4026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4028 % ReadBlobMSBSignedLong() reads a signed int value as a 32-bit quantity in
4029 % most-significant byte-order.
4031 % The format of the ReadBlobMSBSignedLong method is:
4033 % signed int ReadBlobMSBSignedLong(Image *image)
4035 % A description of each parameter follows.
4037 % o image: the image.
4040 MagickExport signed int ReadBlobMSBSignedLong(Image *image)
4051 quantum.unsigned_value=ReadBlobMSBLong(image);
4052 return(quantum.signed_value);
4056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4060 + R e a d B l o b M S B S i g n e d S h o r t %
4064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4066 % ReadBlobMSBSignedShort() reads a signed short value as a 16-bit quantity in
4067 % most-significant byte-order.
4069 % The format of the ReadBlobMSBSignedShort method is:
4071 % signed short ReadBlobMSBSignedShort(Image *image)
4073 % A description of each parameter follows.
4075 % o image: the image.
4078 MagickExport signed short ReadBlobMSBSignedShort(Image *image)
4089 quantum.unsigned_value=ReadBlobMSBShort(image);
4090 return(quantum.signed_value);
4094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4098 + R e a d B l o b S i g n e d L o n g %
4102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4104 % ReadBlobSignedLong() reads a signed int value as a 32-bit quantity in the
4105 % byte-order specified by the endian member of the image structure.
4107 % The format of the ReadBlobSignedLong method is:
4109 % signed int ReadBlobSignedLong(Image *image)
4111 % A description of each parameter follows.
4113 % o image: the image.
4116 MagickExport signed int ReadBlobSignedLong(Image *image)
4127 quantum.unsigned_value=ReadBlobLong(image);
4128 return(quantum.signed_value);
4132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4136 + R e a d B l o b S i g n e d S h o r t %
4140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4142 % ReadBlobSignedShort() reads a signed short value as a 16-bit quantity in the
4143 % byte-order specified by the endian member of the image structure.
4145 % The format of the ReadBlobSignedShort method is:
4147 % signed short ReadBlobSignedShort(Image *image)
4149 % A description of each parameter follows.
4151 % o image: the image.
4154 MagickExport signed short ReadBlobSignedShort(Image *image)
4165 quantum.unsigned_value=ReadBlobShort(image);
4166 return(quantum.signed_value);
4170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4174 + R e a d B l o b S t r e a m %
4178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4180 % ReadBlobStream() reads data from the blob or image file and returns it. It
4181 % returns a pointer to the data buffer you supply or to the image memory
4182 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
4183 % returns a count of zero and has no other results. If length is greater than
4184 % SSIZE_MAX, the result is unspecified.
4186 % The format of the ReadBlobStream method is:
4188 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
4191 % A description of each parameter follows:
4193 % o image: the image.
4195 % o length: Specifies an integer representing the number of bytes to read
4198 % o count: returns the number of bytes read.
4200 % o data: Specifies an area to place the information requested from the
4204 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
4205 void *data,ssize_t *count)
4207 assert(image != (Image *) NULL);
4208 assert(image->signature == MagickCoreSignature);
4209 assert(image->blob != (BlobInfo *) NULL);
4210 assert(image->blob->type != UndefinedStream);
4211 assert(count != (ssize_t *) NULL);
4212 if (image->blob->type != BlobStream)
4214 assert(data != NULL);
4215 *count=ReadBlob(image,length,(unsigned char *) data);
4218 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4221 image->blob->eof=MagickTrue;
4224 data=image->blob->data+image->blob->offset;
4225 *count=(ssize_t) MagickMin((MagickOffsetType) length,image->blob->length-
4226 image->blob->offset);
4227 image->blob->offset+=(*count);
4228 if (*count != (ssize_t) length)
4229 image->blob->eof=MagickTrue;
4234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4238 + R e a d B l o b S t r i n g %
4242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4244 % ReadBlobString() reads characters from a blob or file until a newline
4245 % character is read or an end-of-file condition is encountered.
4247 % The format of the ReadBlobString method is:
4249 % char *ReadBlobString(Image *image,char *string)
4251 % A description of each parameter follows:
4253 % o image: the image.
4255 % o string: the address of a character buffer.
4258 MagickExport char *ReadBlobString(Image *image,char *string)
4260 register const unsigned char
4272 assert(image != (Image *) NULL);
4273 assert(image->signature == MagickCoreSignature);
4274 for (i=0; i < (MagickPathExtent-1L); i++)
4276 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
4280 return((char *) NULL);
4284 string[i]=(char) (*p);
4285 if ((string[i] == '\r') || (string[i] == '\n'))
4288 if (string[i] == '\r')
4289 (void) ReadBlobStream(image,1,buffer,&count);
4295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4299 + R e f e r e n c e B l o b %
4303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4305 % ReferenceBlob() increments the reference count associated with the pixel
4306 % blob returning a pointer to the blob.
4308 % The format of the ReferenceBlob method is:
4310 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
4312 % A description of each parameter follows:
4314 % o blob_info: the blob_info.
4317 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
4319 assert(blob != (BlobInfo *) NULL);
4320 assert(blob->signature == MagickCoreSignature);
4321 if (blob->debug != MagickFalse)
4322 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4323 LockSemaphoreInfo(blob->semaphore);
4324 blob->reference_count++;
4325 UnlockSemaphoreInfo(blob->semaphore);
4330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4340 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
4341 % and returns the resulting offset.
4343 % The format of the SeekBlob method is:
4345 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
4348 % A description of each parameter follows:
4350 % o image: the image.
4352 % o offset: Specifies an integer representing the offset in bytes.
4354 % o whence: Specifies an integer representing how the offset is
4355 % treated relative to the beginning of the blob as follows:
4357 % SEEK_SET Set position equal to offset bytes.
4358 % SEEK_CUR Set position to current location plus offset.
4359 % SEEK_END Set position to EOF plus offset.
4362 MagickExport MagickOffsetType SeekBlob(Image *image,
4363 const MagickOffsetType offset,const int whence)
4365 assert(image != (Image *) NULL);
4366 assert(image->signature == MagickCoreSignature);
4367 if (image->debug != MagickFalse)
4368 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4369 assert(image->blob != (BlobInfo *) NULL);
4370 assert(image->blob->type != UndefinedStream);
4371 switch (image->blob->type)
4373 case UndefinedStream:
4375 case StandardStream:
4380 if ((offset < 0) && (whence == SEEK_SET))
4382 if (fseek(image->blob->file_info.file,offset,whence) < 0)
4384 image->blob->offset=TellBlob(image);
4389 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4390 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
4393 image->blob->offset=TellBlob(image);
4409 image->blob->offset=offset;
4414 if ((image->blob->offset+offset) < 0)
4416 image->blob->offset+=offset;
4421 if (((MagickOffsetType) image->blob->length+offset) < 0)
4423 image->blob->offset=image->blob->length+offset;
4427 if (image->blob->offset < (MagickOffsetType)
4428 ((off_t) image->blob->length))
4430 image->blob->eof=MagickFalse;
4433 if (image->blob->offset < (MagickOffsetType)
4434 ((off_t) image->blob->extent))
4436 if (image->blob->mapped != MagickFalse)
4438 image->blob->eof=MagickTrue;
4441 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
4442 image->blob->quantum<<=1;
4443 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4444 image->blob->extent+1,sizeof(*image->blob->data));
4445 (void) SyncBlob(image);
4446 if (image->blob->data == NULL)
4448 (void) DetachBlob(image->blob);
4455 if (image->blob->custom_stream->seeker == (CustomStreamSeeker) NULL)
4457 image->blob->offset=image->blob->custom_stream->seeker(offset,whence,
4458 image->blob->custom_stream->data);
4462 return(image->blob->offset);
4466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4470 + S e t B l o b E x e m p t %
4474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4476 % SetBlobExempt() sets the blob exempt status.
4478 % The format of the SetBlobExempt method is:
4480 % MagickBooleanType SetBlobExempt(const Image *image,
4481 % const MagickBooleanType exempt)
4483 % A description of each parameter follows:
4485 % o image: the image.
4487 % o exempt: Set to true if this blob is exempt from being closed.
4490 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
4492 assert(image != (const Image *) NULL);
4493 assert(image->signature == MagickCoreSignature);
4494 if (image->debug != MagickFalse)
4495 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4496 image->blob->exempt=exempt;
4500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4504 + S e t B l o b E x t e n t %
4508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4510 % SetBlobExtent() ensures enough space is allocated for the blob. If the
4511 % method is successful, subsequent writes to bytes in the specified range are
4512 % guaranteed not to fail.
4514 % The format of the SetBlobExtent method is:
4516 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
4518 % A description of each parameter follows:
4520 % o image: the image.
4522 % o extent: the blob maximum extent.
4525 MagickExport MagickBooleanType SetBlobExtent(Image *image,
4526 const MagickSizeType extent)
4528 assert(image != (Image *) NULL);
4529 assert(image->signature == MagickCoreSignature);
4530 if (image->debug != MagickFalse)
4531 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4532 assert(image->blob != (BlobInfo *) NULL);
4533 assert(image->blob->type != UndefinedStream);
4534 switch (image->blob->type)
4536 case UndefinedStream:
4538 case StandardStream:
4539 return(MagickFalse);
4548 if (extent != (MagickSizeType) ((off_t) extent))
4549 return(MagickFalse);
4550 offset=SeekBlob(image,0,SEEK_END);
4552 return(MagickFalse);
4553 if ((MagickSizeType) offset >= extent)
4555 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4558 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4559 image->blob->file_info.file);
4560 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4561 if (image->blob->synchronize != MagickFalse)
4566 file=fileno(image->blob->file_info.file);
4567 if ((file == -1) || (offset < 0))
4568 return(MagickFalse);
4569 (void) posix_fallocate(file,offset,extent-offset);
4572 offset=SeekBlob(image,offset,SEEK_SET);
4574 return(MagickFalse);
4579 return(MagickFalse);
4581 return(MagickFalse);
4583 return(MagickFalse);
4586 if (extent != (MagickSizeType) ((size_t) extent))
4587 return(MagickFalse);
4588 if (image->blob->mapped != MagickFalse)
4596 (void) UnmapBlob(image->blob->data,image->blob->length);
4597 RelinquishMagickResource(MapResource,image->blob->length);
4598 if (extent != (MagickSizeType) ((off_t) extent))
4599 return(MagickFalse);
4600 offset=SeekBlob(image,0,SEEK_END);
4602 return(MagickFalse);
4603 if ((MagickSizeType) offset >= extent)
4605 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4606 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4607 image->blob->file_info.file);
4608 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4609 if (image->blob->synchronize != MagickFalse)
4614 file=fileno(image->blob->file_info.file);
4615 if ((file == -1) || (offset < 0))
4616 return(MagickFalse);
4617 (void) posix_fallocate(file,offset,extent-offset);
4620 offset=SeekBlob(image,offset,SEEK_SET);
4622 return(MagickFalse);
4623 (void) AcquireMagickResource(MapResource,extent);
4624 image->blob->data=(unsigned char*) MapBlob(fileno(
4625 image->blob->file_info.file),WriteMode,0,(size_t) extent);
4626 image->blob->extent=(size_t) extent;
4627 image->blob->length=(size_t) extent;
4628 (void) SyncBlob(image);
4631 image->blob->extent=(size_t) extent;
4632 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4633 image->blob->extent+1,sizeof(*image->blob->data));
4634 (void) SyncBlob(image);
4635 if (image->blob->data == (unsigned char *) NULL)
4637 (void) DetachBlob(image->blob);
4638 return(MagickFalse);
4649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4653 + S e t C u s t o m S t r e a m D a t a %
4657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4659 % SetCustomStreamData() sets the stream info data member.
4661 % The format of the SetCustomStreamData method is:
4663 % void SetCustomStreamData(CustomStreamInfo *custom_stream,void *)
4665 % A description of each parameter follows:
4667 % o custom_stream: the custom stream info.
4669 % o data: an object containing information about the custom stream.
4672 MagickExport void SetCustomStreamData(CustomStreamInfo *custom_stream,
4675 assert(custom_stream != (CustomStreamInfo *) NULL);
4676 assert(custom_stream->signature == MagickCoreSignature);
4677 custom_stream->data=data;
4681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4685 + S e t C u s t o m S t r e a m R e a d e r %
4689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4691 % SetCustomStreamReader() sets the stream info reader member.
4693 % The format of the SetCustomStreamReader method is:
4695 % void SetCustomStreamReader(CustomStreamInfo *custom_stream,
4696 % CustomStreamHandler reader)
4698 % A description of each parameter follows:
4700 % o custom_stream: the custom stream info.
4702 % o reader: a function to read from the stream.
4705 MagickExport void SetCustomStreamReader(CustomStreamInfo *custom_stream,
4706 CustomStreamHandler reader)
4708 assert(custom_stream != (CustomStreamInfo *) NULL);
4709 assert(custom_stream->signature == MagickCoreSignature);
4710 custom_stream->reader=reader;
4714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4718 + S e t C u s t o m S t r e a m S e e k e r %
4722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4724 % SetCustomStreamSeeker() sets the stream info seeker member.
4726 % The format of the SetCustomStreamReader method is:
4728 % void SetCustomStreamSeeker(CustomStreamInfo *custom_stream,
4729 % CustomStreamSeeker seeker)
4731 % A description of each parameter follows:
4733 % o custom_stream: the custom stream info.
4735 % o seeker: a function to seek in the custom stream.
4738 MagickExport void SetCustomStreamSeeker(CustomStreamInfo *custom_stream,
4739 CustomStreamSeeker seeker)
4741 assert(custom_stream != (CustomStreamInfo *) NULL);
4742 assert(custom_stream->signature == MagickCoreSignature);
4743 custom_stream->seeker=seeker;
4747 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4751 + S e t C u s t o m S t r e a m T e l l e r %
4755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4757 % SetCustomStreamTeller() sets the stream info teller member.
4759 % The format of the SetCustomStreamTeller method is:
4761 % void SetCustomStreamTeller(CustomStreamInfo *custom_stream,
4762 % CustomStreamTeller *teller)
4764 % A description of each parameter follows:
4766 % o custom_stream: the custom stream info.
4768 % o teller: a function to set the position in the stream.
4771 MagickExport void SetCustomStreamTeller(CustomStreamInfo *custom_stream,
4772 CustomStreamTeller teller)
4774 assert(custom_stream != (CustomStreamInfo *) NULL);
4775 assert(custom_stream->signature == MagickCoreSignature);
4776 custom_stream->teller=teller;
4780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4784 + S e t C u s t o m S t r e a m W r i t e r %
4788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4790 % SetCustomStreamWriter() sets the stream info writer member.
4792 % The format of the SetCustomStreamWriter method is:
4794 % void SetCustomStreamWriter(CustomStreamInfo *custom_stream,
4795 % CustomStreamHandler *writer)
4797 % A description of each parameter follows:
4799 % o custom_stream: the custom stream info.
4801 % o writer: a function to write to the custom stream.
4804 MagickExport void SetCustomStreamWriter(CustomStreamInfo *custom_stream,
4805 CustomStreamHandler writer)
4807 assert(custom_stream != (CustomStreamInfo *) NULL);
4808 assert(custom_stream->signature == MagickCoreSignature);
4809 custom_stream->writer=writer;
4813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4823 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
4824 % attributes if it is an blob.
4826 % The format of the SyncBlob method is:
4828 % int SyncBlob(Image *image)
4830 % A description of each parameter follows:
4832 % o image: the image.
4835 static int SyncBlob(Image *image)
4840 assert(image != (Image *) NULL);
4841 assert(image->signature == MagickCoreSignature);
4842 if (image->debug != MagickFalse)
4843 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4844 assert(image->blob != (BlobInfo *) NULL);
4845 assert(image->blob->type != UndefinedStream);
4847 switch (image->blob->type)
4849 case UndefinedStream:
4850 case StandardStream:
4855 status=fflush(image->blob->file_info.file);
4860 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4861 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
4867 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4868 status=BZ2_bzflush(image->blob->file_info.bzfile);
4883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4893 % TellBlob() obtains the current value of the blob or file position.
4895 % The format of the TellBlob method is:
4897 % MagickOffsetType TellBlob(const Image *image)
4899 % A description of each parameter follows:
4901 % o image: the image.
4904 MagickExport MagickOffsetType TellBlob(const Image *image)
4909 assert(image != (Image *) NULL);
4910 assert(image->signature == MagickCoreSignature);
4911 if (image->debug != MagickFalse)
4912 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4913 assert(image->blob != (BlobInfo *) NULL);
4914 assert(image->blob->type != UndefinedStream);
4916 switch (image->blob->type)
4918 case UndefinedStream:
4919 case StandardStream:
4923 offset=ftell(image->blob->file_info.file);
4930 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4931 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
4941 offset=image->blob->offset;
4946 if (image->blob->custom_stream->teller != (CustomStreamTeller) NULL)
4947 offset=image->blob->custom_stream->teller(image->blob->custom_stream->data);
4955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4959 + U n m a p B l o b %
4963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4965 % UnmapBlob() deallocates the binary large object previously allocated with
4966 % the MapBlob method.
4968 % The format of the UnmapBlob method is:
4970 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4972 % A description of each parameter follows:
4974 % o map: the address of the binary large object.
4976 % o length: the length of the binary large object.
4979 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4981 #if defined(MAGICKCORE_HAVE_MMAP)
4985 status=munmap(map,length);
4986 return(status == -1 ? MagickFalse : MagickTrue);
4990 return(MagickFalse);
4995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4999 % C u s t o m S t r e a m T o I m a g e %
5003 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5005 % CustomStreamToImage() is the equivalent of ReadImage(), but reads the
5006 % formatted "file" from the suplied method rather than to an actual file.
5008 % The format of the CustomStreamToImage method is:
5010 % Image *CustomStreamToImage(const ImageInfo *image_info,
5011 % ExceptionInfo *exception)
5013 % A description of each parameter follows:
5015 % o image_info: the image info.
5017 % o exception: return any errors or warnings in this structure.
5020 MagickExport Image *CustomStreamToImage(const ImageInfo *image_info,
5021 ExceptionInfo *exception)
5032 assert(image_info != (ImageInfo *) NULL);
5033 assert(image_info->signature == MagickCoreSignature);
5034 if (image_info->debug != MagickFalse)
5035 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
5036 image_info->filename);
5037 assert(image_info->custom_stream != (CustomStreamInfo *) NULL);
5038 assert(image_info->custom_stream->signature == MagickCoreSignature);
5039 assert(image_info->custom_stream->reader != (CustomStreamHandler) NULL);
5040 assert(exception != (ExceptionInfo *) NULL);
5041 blob_info=CloneImageInfo(image_info);
5042 if (*blob_info->magick == '\0')
5043 (void) SetImageInfo(blob_info,0,exception);
5044 magick_info=GetMagickInfo(blob_info->magick,exception);
5045 if (magick_info == (const MagickInfo *) NULL)
5047 (void) ThrowMagickException(exception,GetMagickModule(),
5048 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
5050 blob_info=DestroyImageInfo(blob_info);
5051 return((Image *) NULL);
5053 image=(Image *) NULL;
5054 if ((GetMagickBlobSupport(magick_info) != MagickFalse) ||
5055 (blob_info->custom_stream == (CustomStreamInfo *) NULL))
5058 Native blob support for this image format or SetImageInfo changed the
5061 image=ReadImage(blob_info,exception);
5062 if (image != (Image *) NULL)
5063 (void) CloseBlob(image);
5068 unique[MagickPathExtent];
5080 Write data to file on disk.
5082 blob_info->custom_stream=(CustomStreamInfo *) NULL;
5083 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
5085 if (blob == (unsigned char *) NULL)
5087 ThrowFileException(exception,BlobError,"UnableToReadBlob",
5088 image_info->filename);
5089 blob_info=DestroyImageInfo(blob_info);
5090 return((Image *) NULL);
5092 file=AcquireUniqueFileResource(unique);
5095 ThrowFileException(exception,BlobError,"UnableToReadBlob",
5096 image_info->filename);
5097 blob=(unsigned char *) RelinquishMagickMemory(blob);
5098 blob_info=DestroyImageInfo(blob_info);
5099 return((Image *) NULL);
5101 clone_info=CloneImageInfo(blob_info);
5102 blob_info->file=fdopen(file,"wb+");
5103 if (blob_info->file != (FILE *) NULL)
5108 count=(ssize_t) MagickMaxBufferExtent;
5109 while (count == (ssize_t) MagickMaxBufferExtent)
5111 count=image_info->custom_stream->reader(blob,MagickMaxBufferExtent,
5112 image_info->custom_stream->data);
5113 count=(ssize_t) write(file,(const char *) blob,(size_t) count);
5115 (void) fclose(blob_info->file);
5116 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,
5117 "%s:%s",blob_info->magick,unique);
5118 image=ReadImage(clone_info,exception);
5119 if (image != (Image *) NULL)
5125 Restore original filenames and image format.
5127 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
5129 (void) CopyMagickString(images->filename,image_info->filename,
5131 (void) CopyMagickString(images->magick_filename,
5132 image_info->filename,MagickPathExtent);
5133 (void) CopyMagickString(images->magick,magick_info->name,
5135 (void) CloseBlob(images);
5136 images=GetNextImageInList(images);
5140 clone_info=DestroyImageInfo(clone_info);
5141 blob=(unsigned char *) RelinquishMagickMemory(blob);
5142 (void) RelinquishUniqueFileResource(unique);
5144 blob_info=DestroyImageInfo(blob_info);
5149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5153 + W r i t e B l o b %
5157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5159 % WriteBlob() writes data to a blob or image file. It returns the number of
5162 % The format of the WriteBlob method is:
5164 % ssize_t WriteBlob(Image *image,const size_t length,const void *data)
5166 % A description of each parameter follows:
5168 % o image: the image.
5170 % o length: Specifies an integer representing the number of bytes to
5171 % write to the file.
5173 % o data: The address of the data to write to the blob or file.
5176 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
5182 register const unsigned char
5188 assert(image != (Image *) NULL);
5189 assert(image->signature == MagickCoreSignature);
5190 assert(image->blob != (BlobInfo *) NULL);
5191 assert(image->blob->type != UndefinedStream);
5194 assert(data != (const void *) NULL);
5196 p=(const unsigned char *) data;
5197 switch (image->blob->type)
5199 case UndefinedStream:
5201 case StandardStream:
5209 count=(ssize_t) fwrite((const char *) data,1,length,
5210 image->blob->file_info.file);
5215 c=putc((int) *p++,image->blob->file_info.file);
5222 c=putc((int) *p++,image->blob->file_info.file);
5229 c=putc((int) *p++,image->blob->file_info.file);
5236 c=putc((int) *p++,image->blob->file_info.file);
5248 #if defined(MAGICKCORE_ZLIB_DELEGATE)
5253 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
5254 (unsigned int) length);
5259 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5266 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5273 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5280 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5293 #if defined(MAGICKCORE_BZLIB_DELEGATE)
5294 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
5301 count=(ssize_t) image->blob->stream(image,data,length);
5306 register unsigned char
5309 if ((image->blob->offset+(MagickOffsetType) length) >=
5310 (MagickOffsetType) image->blob->extent)
5312 if (image->blob->mapped != MagickFalse)
5314 image->blob->extent+=length+image->blob->quantum;
5315 image->blob->quantum<<=1;
5316 image->blob->data=(unsigned char *) ResizeQuantumMemory(
5317 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
5318 (void) SyncBlob(image);
5319 if (image->blob->data == (unsigned char *) NULL)
5321 (void) DetachBlob(image->blob);
5325 q=image->blob->data+image->blob->offset;
5326 (void) memcpy(q,p,length);
5327 image->blob->offset+=length;
5328 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
5329 image->blob->length=(size_t) image->blob->offset;
5330 count=(ssize_t) length;
5335 if (image->blob->custom_stream->writer != (CustomStreamHandler) NULL)
5336 count=image->blob->custom_stream->writer((unsigned char *) data,
5337 length,image->blob->custom_stream->data);
5345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5349 + W r i t e B l o b B y t e %
5353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5355 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
5356 % written (either 0 or 1);
5358 % The format of the WriteBlobByte method is:
5360 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
5362 % A description of each parameter follows.
5364 % o image: the image.
5366 % o value: Specifies the value to write.
5369 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
5371 assert(image != (Image *) NULL);
5372 assert(image->signature == MagickCoreSignature);
5373 return(WriteBlobStream(image,1,&value));
5377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5381 + W r i t e B l o b F l o a t %
5385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5387 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
5388 % specified by the endian member of the image structure.
5390 % The format of the WriteBlobFloat method is:
5392 % ssize_t WriteBlobFloat(Image *image,const float value)
5394 % A description of each parameter follows.
5396 % o image: the image.
5398 % o value: Specifies the value to write.
5401 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
5412 quantum.unsigned_value=0U;
5413 quantum.float_value=value;
5414 return(WriteBlobLong(image,quantum.unsigned_value));
5418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5422 + W r i t e B l o b L o n g %
5426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5428 % WriteBlobLong() writes a unsigned int value as a 32-bit quantity in the
5429 % byte-order specified by the endian member of the image structure.
5431 % The format of the WriteBlobLong method is:
5433 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
5435 % A description of each parameter follows.
5437 % o image: the image.
5439 % o value: Specifies the value to write.
5442 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
5447 assert(image != (Image *) NULL);
5448 assert(image->signature == MagickCoreSignature);
5449 if (image->endian == LSBEndian)
5451 buffer[0]=(unsigned char) value;
5452 buffer[1]=(unsigned char) (value >> 8);
5453 buffer[2]=(unsigned char) (value >> 16);
5454 buffer[3]=(unsigned char) (value >> 24);
5455 return(WriteBlobStream(image,4,buffer));
5457 buffer[0]=(unsigned char) (value >> 24);
5458 buffer[1]=(unsigned char) (value >> 16);
5459 buffer[2]=(unsigned char) (value >> 8);
5460 buffer[3]=(unsigned char) value;
5461 return(WriteBlobStream(image,4,buffer));
5465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5469 + W r i t e B l o b S h o r t %
5473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5475 % WriteBlobShort() writes a short value as a 16-bit quantity in the
5476 % byte-order specified by the endian member of the image structure.
5478 % The format of the WriteBlobShort method is:
5480 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
5482 % A description of each parameter follows.
5484 % o image: the image.
5486 % o value: Specifies the value to write.
5489 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
5494 assert(image != (Image *) NULL);
5495 assert(image->signature == MagickCoreSignature);
5496 if (image->endian == LSBEndian)
5498 buffer[0]=(unsigned char) value;
5499 buffer[1]=(unsigned char) (value >> 8);
5500 return(WriteBlobStream(image,2,buffer));
5502 buffer[0]=(unsigned char) (value >> 8);
5503 buffer[1]=(unsigned char) value;
5504 return(WriteBlobStream(image,2,buffer));
5508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5512 + W r i t e B l o b L S B L o n g %
5516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5518 % WriteBlobLSBLong() writes a unsigned int value as a 32-bit quantity in
5519 % least-significant byte first order.
5521 % The format of the WriteBlobLSBLong method is:
5523 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5525 % A description of each parameter follows.
5527 % o image: the image.
5529 % o value: Specifies the value to write.
5532 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5537 assert(image != (Image *) NULL);
5538 assert(image->signature == MagickCoreSignature);
5539 buffer[0]=(unsigned char) value;
5540 buffer[1]=(unsigned char) (value >> 8);
5541 buffer[2]=(unsigned char) (value >> 16);
5542 buffer[3]=(unsigned char) (value >> 24);
5543 return(WriteBlobStream(image,4,buffer));
5547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5551 + W r i t e B l o b L S B S h o r t %
5555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5557 % WriteBlobLSBShort() writes a unsigned short value as a 16-bit quantity in
5558 % least-significant byte first order.
5560 % The format of the WriteBlobLSBShort method is:
5562 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5564 % A description of each parameter follows.
5566 % o image: the image.
5568 % o value: Specifies the value to write.
5571 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5576 assert(image != (Image *) NULL);
5577 assert(image->signature == MagickCoreSignature);
5578 buffer[0]=(unsigned char) value;
5579 buffer[1]=(unsigned char) (value >> 8);
5580 return(WriteBlobStream(image,2,buffer));
5584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5588 + W r i t e B l o b L S B S i g n e d L o n g %
5592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5594 % WriteBlobLSBSignedLong() writes a signed value as a 32-bit quantity in
5595 % least-significant byte first order.
5597 % The format of the WriteBlobLSBSignedLong method is:
5599 % ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5601 % A description of each parameter follows.
5603 % o image: the image.
5605 % o value: Specifies the value to write.
5608 MagickExport ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5622 assert(image != (Image *) NULL);
5623 assert(image->signature == MagickCoreSignature);
5624 quantum.signed_value=value;
5625 buffer[0]=(unsigned char) quantum.unsigned_value;
5626 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5627 buffer[2]=(unsigned char) (quantum.unsigned_value >> 16);
5628 buffer[3]=(unsigned char) (quantum.unsigned_value >> 24);
5629 return(WriteBlobStream(image,4,buffer));
5633 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5637 + W r i t e B l o b L S B S i g n e d S h o r t %
5641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5643 % WriteBlobLSBSignedShort() writes a signed short value as a 16-bit quantity
5644 % in least-significant byte first order.
5646 % The format of the WriteBlobLSBSignedShort method is:
5648 % ssize_t WriteBlobLSBSignedShort(Image *image,const signed short value)
5650 % A description of each parameter follows.
5652 % o image: the image.
5654 % o value: Specifies the value to write.
5657 MagickExport ssize_t WriteBlobLSBSignedShort(Image *image,
5658 const signed short value)
5672 assert(image != (Image *) NULL);
5673 assert(image->signature == MagickCoreSignature);
5674 quantum.signed_value=value;
5675 buffer[0]=(unsigned char) quantum.unsigned_value;
5676 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5677 return(WriteBlobStream(image,2,buffer));
5681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5685 + W r i t e B l o b M S B L o n g %
5689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5691 % WriteBlobMSBLong() writes a unsigned int value as a 32-bit quantity in
5692 % most-significant byte first order.
5694 % The format of the WriteBlobMSBLong method is:
5696 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5698 % A description of each parameter follows.
5700 % o value: Specifies the value to write.
5702 % o image: the image.
5705 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5710 assert(image != (Image *) NULL);
5711 assert(image->signature == MagickCoreSignature);
5712 buffer[0]=(unsigned char) (value >> 24);
5713 buffer[1]=(unsigned char) (value >> 16);
5714 buffer[2]=(unsigned char) (value >> 8);
5715 buffer[3]=(unsigned char) value;
5716 return(WriteBlobStream(image,4,buffer));
5720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5724 + W r i t e B l o b M S B L o n g L o n g %
5728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5730 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
5731 % most-significant byte first order.
5733 % The format of the WriteBlobMSBLongLong method is:
5735 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
5737 % A description of each parameter follows.
5739 % o value: Specifies the value to write.
5741 % o image: the image.
5744 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
5745 const MagickSizeType value)
5750 assert(image != (Image *) NULL);
5751 assert(image->signature == MagickCoreSignature);
5752 buffer[0]=(unsigned char) (value >> 56);
5753 buffer[1]=(unsigned char) (value >> 48);
5754 buffer[2]=(unsigned char) (value >> 40);
5755 buffer[3]=(unsigned char) (value >> 32);
5756 buffer[4]=(unsigned char) (value >> 24);
5757 buffer[5]=(unsigned char) (value >> 16);
5758 buffer[6]=(unsigned char) (value >> 8);
5759 buffer[7]=(unsigned char) value;
5760 return(WriteBlobStream(image,8,buffer));
5764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5768 + W r i t e B l o b M S B S i g n e d L o n g %
5772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5774 % WriteBlobMSBSignedLong() writes a signed value as a 32-bit quantity in
5775 % most-significant byte first order.
5777 % The format of the WriteBlobMSBSignedLong method is:
5779 % ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5781 % A description of each parameter follows.
5783 % o image: the image.
5785 % o value: Specifies the value to write.
5788 MagickExport ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5802 assert(image != (Image *) NULL);
5803 assert(image->signature == MagickCoreSignature);
5804 quantum.signed_value=value;
5805 buffer[0]=(unsigned char) (quantum.unsigned_value >> 24);
5806 buffer[1]=(unsigned char) (quantum.unsigned_value >> 16);
5807 buffer[2]=(unsigned char) (quantum.unsigned_value >> 8);
5808 buffer[3]=(unsigned char) quantum.unsigned_value;
5809 return(WriteBlobStream(image,4,buffer));
5813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5817 + W r i t e B l o b M S B S i g n e d S h o r t %
5821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5823 % WriteBlobMSBSignedShort() writes a signed short value as a 16-bit quantity
5824 % in most-significant byte first order.
5826 % The format of the WriteBlobMSBSignedShort method is:
5828 % ssize_t WriteBlobMSBSignedShort(Image *image,const signed short value)
5830 % A description of each parameter follows.
5832 % o image: the image.
5834 % o value: Specifies the value to write.
5837 MagickExport ssize_t WriteBlobMSBSignedShort(Image *image,
5838 const signed short value)
5852 assert(image != (Image *) NULL);
5853 assert(image->signature == MagickCoreSignature);
5854 quantum.signed_value=value;
5855 buffer[0]=(unsigned char) (quantum.unsigned_value >> 8);
5856 buffer[1]=(unsigned char) quantum.unsigned_value;
5857 return(WriteBlobStream(image,2,buffer));
5861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5865 + W r i t e B l o b M S B S h o r t %
5869 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5871 % WriteBlobMSBShort() writes a unsigned short value as a 16-bit quantity in
5872 % most-significant byte first order.
5874 % The format of the WriteBlobMSBShort method is:
5876 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5878 % A description of each parameter follows.
5880 % o value: Specifies the value to write.
5882 % o file: Specifies the file to write the data to.
5885 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5890 assert(image != (Image *) NULL);
5891 assert(image->signature == MagickCoreSignature);
5892 buffer[0]=(unsigned char) (value >> 8);
5893 buffer[1]=(unsigned char) value;
5894 return(WriteBlobStream(image,2,buffer));
5898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5902 + W r i t e B l o b S t r i n g %
5906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5908 % WriteBlobString() write a string to a blob. It returns the number of
5909 % characters written.
5911 % The format of the WriteBlobString method is:
5913 % ssize_t WriteBlobString(Image *image,const char *string)
5915 % A description of each parameter follows.
5917 % o image: the image.
5919 % o string: Specifies the string to write.
5922 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
5924 assert(image != (Image *) NULL);
5925 assert(image->signature == MagickCoreSignature);
5926 assert(string != (const char *) NULL);
5927 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));