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 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 #include "MagickCore/studio.h"
48 #include "MagickCore/blob.h"
49 #include "MagickCore/blob-private.h"
50 #include "MagickCore/cache.h"
51 #include "MagickCore/client.h"
52 #include "MagickCore/constitute.h"
53 #include "MagickCore/delegate.h"
54 #include "MagickCore/exception.h"
55 #include "MagickCore/exception-private.h"
56 #include "MagickCore/image-private.h"
57 #include "MagickCore/list.h"
58 #include "MagickCore/locale_.h"
59 #include "MagickCore/log.h"
60 #include "MagickCore/magick.h"
61 #include "MagickCore/memory_.h"
62 #include "MagickCore/nt-base-private.h"
63 #include "MagickCore/option.h"
64 #include "MagickCore/policy.h"
65 #include "MagickCore/resource_.h"
66 #include "MagickCore/semaphore.h"
67 #include "MagickCore/string_.h"
68 #include "MagickCore/string-private.h"
69 #include "MagickCore/token.h"
70 #include "MagickCore/utility.h"
71 #include "MagickCore/utility-private.h"
72 #if defined(MAGICKCORE_ZLIB_DELEGATE)
75 #if defined(MAGICKCORE_BZLIB_DELEGATE)
82 #define MagickMaxBlobExtent (8*8192)
83 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
84 # define MAP_ANONYMOUS MAP_ANON
86 #if !defined(MAP_FAILED)
87 #define MAP_FAILED ((void *) -1)
91 #define _O_BINARY O_BINARY
97 typedef union FileInfo
102 #if defined(MAGICKCORE_ZLIB_DELEGATE)
107 #if defined(MAGICKCORE_BZLIB_DELEGATE)
168 Forward declarations.
174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178 + A t t a c h B l o b %
182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184 % AttachBlob() attaches a blob to the BlobInfo structure.
186 % The format of the AttachBlob method is:
188 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
190 % A description of each parameter follows:
192 % o blob_info: Specifies a pointer to a BlobInfo structure.
194 % o blob: the address of a character stream in one of the image formats
195 % understood by ImageMagick.
197 % o length: This size_t integer reflects the length in bytes of the blob.
200 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
203 assert(blob_info != (BlobInfo *) NULL);
204 if (blob_info->debug != MagickFalse)
205 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
206 blob_info->length=length;
207 blob_info->extent=length;
208 blob_info->quantum=(size_t) MagickMaxBlobExtent;
210 blob_info->type=BlobStream;
211 blob_info->file_info.file=(FILE *) NULL;
212 blob_info->data=(unsigned char *) blob;
213 blob_info->mapped=MagickFalse;
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 + B l o b T o F i l e %
225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
228 % occurs otherwise MagickTrue.
230 % The format of the BlobToFile method is:
232 % MagickBooleanType BlobToFile(char *filename,const void *blob,
233 % const size_t length,ExceptionInfo *exception)
235 % A description of each parameter follows:
237 % o filename: Write the blob to this file.
239 % o blob: the address of a blob.
241 % o length: This length in bytes of the blob.
243 % o exception: return any errors or warnings in this structure.
246 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
247 const size_t length,ExceptionInfo *exception)
258 assert(filename != (const char *) NULL);
259 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
260 assert(blob != (const void *) NULL);
261 if (*filename == '\0')
262 file=AcquireUniqueFileResource(filename);
264 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
267 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
270 for (i=0; i < length; i+=count)
272 count=write(file,(const char *) blob+i,MagickMin(length-i,SSIZE_MAX));
281 if ((file == -1) || (i < length))
283 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294 % B l o b T o I m a g e %
298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
300 % BlobToImage() implements direct to memory image formats. It returns the
303 % The format of the BlobToImage method is:
305 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
306 % const size_t length,ExceptionInfo *exception)
308 % A description of each parameter follows:
310 % o image_info: the image info.
312 % o blob: the address of a character stream in one of the image formats
313 % understood by ImageMagick.
315 % o length: This size_t integer reflects the length in bytes of the blob.
317 % o exception: return any errors or warnings in this structure.
320 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
321 const size_t length,ExceptionInfo *exception)
336 assert(image_info != (ImageInfo *) NULL);
337 assert(image_info->signature == MagickCoreSignature);
338 if (image_info->debug != MagickFalse)
339 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
340 image_info->filename);
341 assert(exception != (ExceptionInfo *) NULL);
342 if ((blob == (const void *) NULL) || (length == 0))
344 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
345 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
346 return((Image *) NULL);
348 blob_info=CloneImageInfo(image_info);
349 blob_info->blob=(void *) blob;
350 blob_info->length=length;
351 if (*blob_info->magick == '\0')
352 (void) SetImageInfo(blob_info,0,exception);
353 magick_info=GetMagickInfo(blob_info->magick,exception);
354 if (magick_info == (const MagickInfo *) NULL)
356 (void) ThrowMagickException(exception,GetMagickModule(),
357 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
359 blob_info=DestroyImageInfo(blob_info);
360 return((Image *) NULL);
362 if (GetMagickBlobSupport(magick_info) != MagickFalse)
365 Native blob support for this image format.
367 (void) CopyMagickString(blob_info->filename,image_info->filename,
369 (void) CopyMagickString(blob_info->magick,image_info->magick,
371 image=ReadImage(blob_info,exception);
372 if (image != (Image *) NULL)
373 (void) DetachBlob(image->blob);
374 blob_info=DestroyImageInfo(blob_info);
378 Write blob to a temporary file on disk.
380 blob_info->blob=(void *) NULL;
382 *blob_info->filename='\0';
383 status=BlobToFile(blob_info->filename,blob,length,exception);
384 if (status == MagickFalse)
386 (void) RelinquishUniqueFileResource(blob_info->filename);
387 blob_info=DestroyImageInfo(blob_info);
388 return((Image *) NULL);
390 clone_info=CloneImageInfo(blob_info);
391 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,"%s:%s",
392 blob_info->magick,blob_info->filename);
393 image=ReadImage(clone_info,exception);
394 if (image != (Image *) NULL)
400 Restore original filenames and image format.
402 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
404 (void) CopyMagickString(images->filename,image_info->filename,
406 (void) CopyMagickString(images->magick_filename,image_info->filename,
408 (void) CopyMagickString(images->magick,magick_info->name,
410 images=GetNextImageInList(images);
413 clone_info=DestroyImageInfo(clone_info);
414 (void) RelinquishUniqueFileResource(blob_info->filename);
415 blob_info=DestroyImageInfo(blob_info);
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424 + C l o n e B l o b I n f o %
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
431 % blob info is NULL, a new one.
433 % The format of the CloneBlobInfo method is:
435 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
437 % A description of each parameter follows:
439 % o blob_info: the blob info.
442 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
447 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
448 if (clone_info == (BlobInfo *) NULL)
449 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
450 GetBlobInfo(clone_info);
451 if (blob_info == (BlobInfo *) NULL)
453 clone_info->length=blob_info->length;
454 clone_info->extent=blob_info->extent;
455 clone_info->synchronize=blob_info->synchronize;
456 clone_info->quantum=blob_info->quantum;
457 clone_info->mapped=blob_info->mapped;
458 clone_info->eof=blob_info->eof;
459 clone_info->offset=blob_info->offset;
460 clone_info->size=blob_info->size;
461 clone_info->exempt=blob_info->exempt;
462 clone_info->status=blob_info->status;
463 clone_info->temporary=blob_info->temporary;
464 clone_info->type=blob_info->type;
465 clone_info->file_info.file=blob_info->file_info.file;
466 clone_info->properties=blob_info->properties;
467 clone_info->stream=blob_info->stream;
468 clone_info->user_info=blob_info->user_info;
469 clone_info->data=blob_info->data;
470 clone_info->debug=IsEventLogging();
471 clone_info->reference_count=1;
476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480 + C l o s e B l o b %
484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
486 % CloseBlob() closes a stream associated with the image.
488 % The format of the CloseBlob method is:
490 % MagickBooleanType CloseBlob(Image *image)
492 % A description of each parameter follows:
494 % o image: the image.
497 MagickExport MagickBooleanType CloseBlob(Image *image)
505 assert(image != (Image *) NULL);
506 assert(image->signature == MagickCoreSignature);
507 if (image->debug != MagickFalse)
508 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
509 assert(image->blob != (BlobInfo *) NULL);
510 if (image->blob->type == UndefinedStream)
512 status=SyncBlob(image);
513 switch (image->blob->type)
515 case UndefinedStream:
521 if (image->blob->synchronize != MagickFalse)
522 status=fsync(fileno(image->blob->file_info.file));
523 status=ferror(image->blob->file_info.file);
528 #if defined(MAGICKCORE_ZLIB_DELEGATE)
529 (void) gzerror(image->blob->file_info.gzfile,&status);
535 #if defined(MAGICKCORE_BZLIB_DELEGATE)
536 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
544 if ((image->blob->file_info.file != (FILE *) NULL) &&
545 (image->blob->synchronize != MagickFalse))
547 (void) fsync(fileno(image->blob->file_info.file));
548 status=ferror(image->blob->file_info.file);
555 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
556 image->blob->size=GetBlobSize(image);
557 image->extent=image->blob->size;
558 image->blob->eof=MagickFalse;
559 if (image->blob->exempt != MagickFalse)
561 image->blob->type=UndefinedStream;
562 return(image->blob->status);
564 switch (image->blob->type)
566 case UndefinedStream:
571 status=fclose(image->blob->file_info.file);
576 #if defined(MAGICKCORE_HAVE_PCLOSE)
577 status=pclose(image->blob->file_info.file);
583 #if defined(MAGICKCORE_ZLIB_DELEGATE)
584 status=gzclose(image->blob->file_info.gzfile);
590 #if defined(MAGICKCORE_BZLIB_DELEGATE)
591 BZ2_bzclose(image->blob->file_info.bzfile);
599 if (image->blob->file_info.file != (FILE *) NULL)
600 status=fclose(image->blob->file_info.file);
606 (void) DetachBlob(image->blob);
607 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
608 return(image->blob->status);
612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616 + D e s t r o y B l o b %
620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622 % DestroyBlob() deallocates memory associated with a blob.
624 % The format of the DestroyBlob method is:
626 % void DestroyBlob(Image *image)
628 % A description of each parameter follows:
630 % o image: the image.
633 MagickExport void DestroyBlob(Image *image)
638 assert(image != (Image *) NULL);
639 assert(image->signature == MagickCoreSignature);
640 if (image->debug != MagickFalse)
641 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
642 assert(image->blob != (BlobInfo *) NULL);
643 assert(image->blob->signature == MagickCoreSignature);
645 LockSemaphoreInfo(image->blob->semaphore);
646 image->blob->reference_count--;
647 assert(image->blob->reference_count >= 0);
648 if (image->blob->reference_count == 0)
650 UnlockSemaphoreInfo(image->blob->semaphore);
651 if (destroy == MagickFalse)
653 (void) CloseBlob(image);
654 if (image->blob->mapped != MagickFalse)
656 (void) UnmapBlob(image->blob->data,image->blob->length);
657 RelinquishMagickResource(MapResource,image->blob->length);
659 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
660 RelinquishSemaphoreInfo(&image->blob->semaphore);
661 image->blob->signature=(~MagickCoreSignature);
662 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
670 + D e t a c h B l o b %
674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
676 % DetachBlob() detaches a blob from the BlobInfo structure.
678 % The format of the DetachBlob method is:
680 % void *DetachBlob(BlobInfo *blob_info)
682 % A description of each parameter follows:
684 % o blob_info: Specifies a pointer to a BlobInfo structure.
687 MagickExport void *DetachBlob(BlobInfo *blob_info)
692 assert(blob_info != (BlobInfo *) NULL);
693 if (blob_info->debug != MagickFalse)
694 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
695 if (blob_info->mapped != MagickFalse)
697 (void) UnmapBlob(blob_info->data,blob_info->length);
698 blob_info->data=(unsigned char *) NULL;
699 RelinquishMagickResource(MapResource,blob_info->length);
701 blob_info->mapped=MagickFalse;
704 blob_info->eof=MagickFalse;
705 blob_info->exempt=MagickFalse;
706 blob_info->type=UndefinedStream;
707 blob_info->file_info.file=(FILE *) NULL;
708 data=blob_info->data;
709 blob_info->data=(unsigned char *) NULL;
710 blob_info->stream=(StreamHandler) NULL;
711 blob_info->user_info=(UserBlobInfo*) NULL;
716 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
720 + D i s a s s o c i a t e B l o b %
724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
726 % DisassociateBlob() disassociates the image stream. It checks if the
727 % blob of the specified image is referenced by other images. If the reference
728 % count is higher then 1 a new blob is assigned to the specified image.
730 % The format of the DisassociateBlob method is:
732 % void DisassociateBlob(const Image *image)
734 % A description of each parameter follows:
736 % o image: the image.
739 MagickExport void DisassociateBlob(Image *image)
747 assert(image != (Image *) NULL);
748 assert(image->signature == MagickCoreSignature);
749 if (image->debug != MagickFalse)
750 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
751 assert(image->blob != (BlobInfo *) NULL);
752 assert(image->blob->signature == MagickCoreSignature);
754 LockSemaphoreInfo(image->blob->semaphore);
755 assert(image->blob->reference_count >= 0);
756 if (image->blob->reference_count > 1)
758 UnlockSemaphoreInfo(image->blob->semaphore);
759 if (clone == MagickFalse)
761 blob=CloneBlobInfo(image->blob);
767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
771 + D i s c a r d B l o b B y t e s %
775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777 % DiscardBlobBytes() discards bytes in a blob.
779 % The format of the DiscardBlobBytes method is:
781 % MagickBooleanType DiscardBlobBytes(Image *image,
782 % const MagickSizeType length)
784 % A description of each parameter follows.
786 % o image: the image.
788 % o length: the number of bytes to skip.
791 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
792 const MagickSizeType length)
794 register MagickOffsetType
806 assert(image != (Image *) NULL);
807 assert(image->signature == MagickCoreSignature);
808 if (length != (MagickSizeType) ((MagickOffsetType) length))
811 for (i=0; i < (MagickOffsetType) length; i+=count)
813 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
814 (void) ReadBlobStream(image,quantum,buffer,&count);
822 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 + D u p l i c a t e s B l o b %
834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
836 % DuplicateBlob() duplicates a blob descriptor.
838 % The format of the DuplicateBlob method is:
840 % void DuplicateBlob(Image *image,const Image *duplicate)
842 % A description of each parameter follows:
844 % o image: the image.
846 % o duplicate: the duplicate image.
849 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
851 assert(image != (Image *) NULL);
852 assert(image->signature == MagickCoreSignature);
853 if (image->debug != MagickFalse)
854 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
855 assert(duplicate != (Image *) NULL);
856 assert(duplicate->signature == MagickCoreSignature);
858 image->blob=ReferenceBlob(duplicate->blob);
862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872 % EOFBlob() returns a non-zero value when EOF has been detected reading from
875 % The format of the EOFBlob method is:
877 % int EOFBlob(const Image *image)
879 % A description of each parameter follows:
881 % o image: the image.
884 MagickExport int EOFBlob(const Image *image)
886 assert(image != (Image *) NULL);
887 assert(image->signature == MagickCoreSignature);
888 if (image->debug != MagickFalse)
889 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
890 assert(image->blob != (BlobInfo *) NULL);
891 assert(image->blob->type != UndefinedStream);
892 switch (image->blob->type)
894 case UndefinedStream:
900 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
906 image->blob->eof=MagickFalse;
911 #if defined(MAGICKCORE_BZLIB_DELEGATE)
916 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
917 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
923 image->blob->eof=MagickFalse;
931 return((int) image->blob->eof);
935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
939 % F i l e T o B l o b %
943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 % FileToBlob() returns the contents of a file as a buffer terminated with
946 % the '\0' character. The length of the buffer (not including the extra
947 % terminating '\0' character) is returned via the 'length' parameter. Free
948 % the buffer with RelinquishMagickMemory().
950 % The format of the FileToBlob method is:
952 % void *FileToBlob(const char *filename,const size_t extent,
953 % size_t *length,ExceptionInfo *exception)
955 % A description of each parameter follows:
957 % o blob: FileToBlob() returns the contents of a file as a blob. If
958 % an error occurs NULL is returned.
960 % o filename: the filename.
962 % o extent: The maximum length of the blob.
964 % o length: On return, this reflects the actual length of the blob.
966 % o exception: return any errors or warnings in this structure.
969 MagickExport void *FileToBlob(const char *filename,const size_t extent,
970 size_t *length,ExceptionInfo *exception)
990 assert(filename != (const char *) NULL);
991 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
992 assert(exception != (ExceptionInfo *) NULL);
995 if (LocaleCompare(filename,"-") != 0)
996 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
999 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
1002 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
1004 if ((file == fileno(stdin)) || (offset < 0) ||
1005 (offset != (MagickOffsetType) ((ssize_t) offset)))
1014 Stream is not seekable.
1016 offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
1017 quantum=(size_t) MagickMaxBufferExtent;
1018 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1019 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1020 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1021 for (i=0; blob != (unsigned char *) NULL; i+=count)
1023 count=read(file,blob+i,quantum);
1030 if (~((size_t) i) < (quantum+1))
1032 blob=(unsigned char *) RelinquishMagickMemory(blob);
1035 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
1037 if ((size_t) (i+count) >= extent)
1040 if (LocaleCompare(filename,"-") != 0)
1042 if (blob == (unsigned char *) NULL)
1044 (void) ThrowMagickException(exception,GetMagickModule(),
1045 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1050 blob=(unsigned char *) RelinquishMagickMemory(blob);
1051 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1054 *length=(size_t) MagickMin(i+count,extent);
1058 *length=(size_t) MagickMin(offset,(MagickOffsetType)
1059 MagickMin(extent,SSIZE_MAX));
1060 blob=(unsigned char *) NULL;
1061 if (~(*length) >= (MagickPathExtent-1))
1062 blob=(unsigned char *) AcquireQuantumMemory(*length+MagickPathExtent,
1064 if (blob == (unsigned char *) NULL)
1067 (void) ThrowMagickException(exception,GetMagickModule(),
1068 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1071 map=MapBlob(file,ReadMode,0,*length);
1072 if (map != (unsigned char *) NULL)
1074 (void) memcpy(blob,map,*length);
1075 (void) UnmapBlob(map,*length);
1079 (void) lseek(file,0,SEEK_SET);
1080 for (i=0; i < *length; i+=count)
1082 count=read(file,blob+i,(size_t) MagickMin(*length-i,SSIZE_MAX));
1093 blob=(unsigned char *) RelinquishMagickMemory(blob);
1094 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1099 if (LocaleCompare(filename,"-") != 0)
1103 blob=(unsigned char *) RelinquishMagickMemory(blob);
1104 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1114 % F i l e T o I m a g e %
1118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1120 % FileToImage() write the contents of a file to an image.
1122 % The format of the FileToImage method is:
1124 % MagickBooleanType FileToImage(Image *,const char *filename)
1126 % A description of each parameter follows:
1128 % o image: the image.
1130 % o filename: the filename.
1134 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1140 register unsigned char
1143 assert(image->blob != (BlobInfo *) NULL);
1144 assert(image->blob->type != UndefinedStream);
1145 assert(data != NULL);
1146 if (image->blob->type != BlobStream)
1147 return(WriteBlob(image,length,(const unsigned char *) data));
1148 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1149 if (extent >= image->blob->extent)
1151 extent=image->blob->extent+image->blob->quantum+length;
1152 image->blob->quantum<<=1;
1153 if (SetBlobExtent(image,extent) == MagickFalse)
1156 q=image->blob->data+image->blob->offset;
1157 (void) memcpy(q,data,length);
1158 image->blob->offset+=length;
1159 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1160 image->blob->length=(size_t) image->blob->offset;
1161 return((ssize_t) length);
1164 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1165 ExceptionInfo *exception)
1183 assert(image != (const Image *) NULL);
1184 assert(image->signature == MagickCoreSignature);
1185 assert(filename != (const char *) NULL);
1186 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1188 if (LocaleCompare(filename,"-") != 0)
1189 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1192 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1193 return(MagickFalse);
1195 quantum=(size_t) MagickMaxBufferExtent;
1196 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1197 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1198 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1199 if (blob == (unsigned char *) NULL)
1202 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1204 return(MagickFalse);
1208 count=read(file,blob,quantum);
1215 length=(size_t) count;
1216 count=WriteBlobStream(image,length,blob);
1217 if (count != (ssize_t) length)
1219 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1225 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1226 blob=(unsigned char *) RelinquishMagickMemory(blob);
1231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1235 + G e t B l o b E r r o r %
1239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1241 % GetBlobError() returns MagickTrue if the blob associated with the specified
1242 % image encountered an error.
1244 % The format of the GetBlobError method is:
1246 % MagickBooleanType GetBlobError(const Image *image)
1248 % A description of each parameter follows:
1250 % o image: the image.
1253 MagickExport MagickBooleanType GetBlobError(const Image *image)
1255 assert(image != (const Image *) NULL);
1256 assert(image->signature == MagickCoreSignature);
1257 if (image->debug != MagickFalse)
1258 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1259 return(image->blob->status);
1263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267 + G e t B l o b F i l e H a n d l e %
1271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1273 % GetBlobFileHandle() returns the file handle associated with the image blob.
1275 % The format of the GetBlobFile method is:
1277 % FILE *GetBlobFileHandle(const Image *image)
1279 % A description of each parameter follows:
1281 % o image: the image.
1284 MagickExport FILE *GetBlobFileHandle(const Image *image)
1286 assert(image != (const Image *) NULL);
1287 assert(image->signature == MagickCoreSignature);
1288 return(image->blob->file_info.file);
1292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296 + G e t B l o b I n f o %
1300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1302 % GetBlobInfo() initializes the BlobInfo structure.
1304 % The format of the GetBlobInfo method is:
1306 % void GetBlobInfo(BlobInfo *blob_info)
1308 % A description of each parameter follows:
1310 % o blob_info: Specifies a pointer to a BlobInfo structure.
1313 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1315 assert(blob_info != (BlobInfo *) NULL);
1316 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1317 blob_info->type=UndefinedStream;
1318 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1319 blob_info->properties.st_mtime=time((time_t *) NULL);
1320 blob_info->properties.st_ctime=time((time_t *) NULL);
1321 blob_info->debug=IsEventLogging();
1322 blob_info->reference_count=1;
1323 blob_info->semaphore=AcquireSemaphoreInfo();
1324 blob_info->signature=MagickCoreSignature;
1328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332 % G e t B l o b P r o p e r t i e s %
1336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1338 % GetBlobProperties() returns information about an image blob.
1340 % The format of the GetBlobProperties method is:
1342 % const struct stat *GetBlobProperties(const Image *image)
1344 % A description of each parameter follows:
1346 % o image: the image.
1349 MagickExport const struct stat *GetBlobProperties(const Image *image)
1351 assert(image != (Image *) NULL);
1352 assert(image->signature == MagickCoreSignature);
1353 if (image->debug != MagickFalse)
1354 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1355 return(&image->blob->properties);
1359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1363 + G e t B l o b S i z e %
1367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1369 % GetBlobSize() returns the current length of the image file or blob; zero is
1370 % returned if the size cannot be determined.
1372 % The format of the GetBlobSize method is:
1374 % MagickSizeType GetBlobSize(const Image *image)
1376 % A description of each parameter follows:
1378 % o image: the image.
1381 MagickExport MagickSizeType GetBlobSize(const Image *image)
1386 assert(image != (Image *) NULL);
1387 assert(image->signature == MagickCoreSignature);
1388 if (image->debug != MagickFalse)
1389 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1390 assert(image->blob != (BlobInfo *) NULL);
1392 switch (image->blob->type)
1394 case UndefinedStream:
1395 case StandardStream:
1397 extent=image->blob->size;
1402 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1403 extent=(MagickSizeType) image->blob->properties.st_size;
1408 extent=image->blob->size;
1417 status=GetPathAttributes(image->filename,&image->blob->properties);
1418 if (status != MagickFalse)
1419 extent=(MagickSizeType) image->blob->properties.st_size;
1426 extent=(MagickSizeType) image->blob->length;
1436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1440 + G e t B l o b S t r e a m D a t a %
1444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1446 % GetBlobStreamData() returns the stream data for the image.
1448 % The format of the GetBlobStreamData method is:
1450 % void *GetBlobStreamData(const Image *image)
1452 % A description of each parameter follows:
1454 % o image: the image.
1457 MagickExport void *GetBlobStreamData(const Image *image)
1459 assert(image != (const Image *) NULL);
1460 assert(image->signature == MagickCoreSignature);
1461 return(image->blob->data);
1465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1469 + G e t B l o b S t r e a m H a n d l e r %
1473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1475 % GetBlobStreamHandler() returns the stream handler for the image.
1477 % The format of the GetBlobStreamHandler method is:
1479 % StreamHandler GetBlobStreamHandler(const Image *image)
1481 % A description of each parameter follows:
1483 % o image: the image.
1486 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1488 assert(image != (const Image *) NULL);
1489 assert(image->signature == MagickCoreSignature);
1490 if (image->debug != MagickFalse)
1491 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1492 return(image->blob->stream);
1496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1500 % I m a g e T o B l o b %
1504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1506 % ImageToBlob() implements direct to memory image formats. It returns the
1507 % image as a formatted blob and its length. The magick member of the Image
1508 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1509 % etc.). This method is the equivalent of WriteImage(), but writes the
1510 % formatted "file" to a memory buffer rather than to an actual file.
1512 % The format of the ImageToBlob method is:
1514 % void *ImageToBlob(const ImageInfo *image_info,Image *image,
1515 % size_t *length,ExceptionInfo *exception)
1517 % A description of each parameter follows:
1519 % o image_info: the image info.
1521 % o image: the image.
1523 % o length: return the actual length of the blob.
1525 % o exception: return any errors or warnings in this structure.
1528 MagickExport void *ImageToBlob(const ImageInfo *image_info,
1529 Image *image,size_t *length,ExceptionInfo *exception)
1543 assert(image_info != (const ImageInfo *) NULL);
1544 assert(image_info->signature == MagickCoreSignature);
1545 if (image_info->debug != MagickFalse)
1546 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1547 image_info->filename);
1548 assert(image != (Image *) NULL);
1549 assert(image->signature == MagickCoreSignature);
1550 assert(exception != (ExceptionInfo *) NULL);
1552 blob=(unsigned char *) NULL;
1553 blob_info=CloneImageInfo(image_info);
1554 blob_info->adjoin=MagickFalse;
1555 (void) SetImageInfo(blob_info,1,exception);
1556 if (*blob_info->magick != '\0')
1557 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1558 magick_info=GetMagickInfo(image->magick,exception);
1559 if (magick_info == (const MagickInfo *) NULL)
1561 (void) ThrowMagickException(exception,GetMagickModule(),
1562 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1564 blob_info=DestroyImageInfo(blob_info);
1567 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1568 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1571 Native blob support for this image format.
1573 blob_info->length=0;
1574 blob_info->blob=AcquireQuantumMemory(MagickMaxBlobExtent,
1575 sizeof(unsigned char));
1576 if (blob_info->blob == NULL)
1577 (void) ThrowMagickException(exception,GetMagickModule(),
1578 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1581 (void) CloseBlob(image);
1582 image->blob->exempt=MagickTrue;
1583 *image->filename='\0';
1584 status=WriteImage(blob_info,image,exception);
1585 *length=image->blob->length;
1586 blob=DetachBlob(image->blob);
1587 if (status == MagickFalse)
1588 blob=RelinquishMagickMemory(blob);
1590 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1596 unique[MagickPathExtent];
1602 Write file to disk in blob image format.
1604 file=AcquireUniqueFileResource(unique);
1607 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1608 image_info->filename);
1612 blob_info->file=fdopen(file,"wb");
1613 if (blob_info->file != (FILE *) NULL)
1615 (void) FormatLocaleString(image->filename,MagickPathExtent,
1616 "%s:%s",image->magick,unique);
1617 status=WriteImage(blob_info,image,exception);
1618 (void) CloseBlob(image);
1619 (void) fclose(blob_info->file);
1620 if (status != MagickFalse)
1621 blob=FileToBlob(unique,~0UL,length,exception);
1623 (void) RelinquishUniqueFileResource(unique);
1626 blob_info=DestroyImageInfo(blob_info);
1631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1635 + I m a g e T o U s e r B l o b %
1639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1641 % ImageToUserBlob() is the equivalent of WriteImage(), but writes the
1642 % formatted "file" to the suplied method rather than to an actual file.
1644 % The format of the ImageToUserBlob method is:
1646 % void ImageToUserBlob(const ImageInfo *image_info,Image *image,
1647 % UserBlobInfo *user_info,ExceptionInfo *exception)
1649 % A description of each parameter follows:
1651 % o image_info: the image info.
1653 % o image: the image.
1655 % o user_info: the methods to use when writing and seeking.
1657 % o exception: return any errors or warnings in this structure.
1660 MagickExport void ImageToUserBlob(const ImageInfo *image_info,Image *image,
1661 UserBlobInfo *user_info,ExceptionInfo *exception)
1672 assert(image_info != (const ImageInfo *) NULL);
1673 assert(image_info->signature == MagickCoreSignature);
1674 if (image_info->debug != MagickFalse)
1675 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1676 image_info->filename);
1677 assert(image != (Image *) NULL);
1678 assert(image->signature == MagickCoreSignature);
1679 assert(user_info != (UserBlobInfo *) NULL);
1680 assert(user_info->handler != (BlobHandler) NULL);
1681 assert(exception != (ExceptionInfo *) NULL);
1682 blob_info=CloneImageInfo(image_info);
1683 blob_info->adjoin=MagickFalse;
1684 blob_info->user_info=user_info;
1685 (void) SetImageInfo(blob_info,1,exception);
1686 if (*blob_info->magick != '\0')
1687 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1688 magick_info=GetMagickInfo(image->magick,exception);
1689 if (magick_info == (const MagickInfo *) NULL)
1691 (void) ThrowMagickException(exception,GetMagickModule(),
1692 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1694 blob_info=DestroyImageInfo(blob_info);
1697 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1698 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1701 Native blob support for this image format.
1703 (void) CloseBlob(image);
1704 *image->filename='\0';
1705 (void) WriteImage(blob_info,image,exception);
1706 (void) CloseBlob(image);
1711 unique[MagickPathExtent];
1720 Write file to disk in blob image format.
1722 blob_info->user_info=(UserBlobInfo *) NULL;
1723 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
1725 if (blob == (unsigned char *) NULL)
1727 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1728 image_info->filename);
1729 blob_info=DestroyImageInfo(blob_info);
1732 file=AcquireUniqueFileResource(unique);
1735 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1736 image_info->filename);
1737 blob=(unsigned char *) RelinquishMagickMemory(blob);
1738 blob_info=DestroyImageInfo(blob_info);
1741 blob_info->file=fdopen(file,"wb+");
1742 if (blob_info->file != (FILE *) NULL)
1747 (void) FormatLocaleString(image->filename,MagickPathExtent,
1748 "%s:%s",image->magick,unique);
1749 status=WriteImage(blob_info,image,exception);
1750 (void) CloseBlob(image);
1751 if (status != MagickFalse)
1753 (void) fseek(blob_info->file,0,SEEK_SET);
1754 count=(ssize_t) MagickMaxBufferExtent;
1755 while (count == (ssize_t) MagickMaxBufferExtent)
1757 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
1759 user_info->handler(blob,count,user_info->data);
1762 (void) fclose(blob_info->file);
1764 blob=(unsigned char *) RelinquishMagickMemory(blob);
1765 (void) RelinquishUniqueFileResource(unique);
1767 blob_info=DestroyImageInfo(blob_info);
1771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1775 % I m a g e T o F i l e %
1779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1781 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1782 % occurs otherwise MagickTrue.
1784 % The format of the ImageToFile method is:
1786 % MagickBooleanType ImageToFile(Image *image,char *filename,
1787 % ExceptionInfo *exception)
1789 % A description of each parameter follows:
1791 % o image: the image.
1793 % o filename: Write the image to this file.
1795 % o exception: return any errors or warnings in this structure.
1798 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1799 ExceptionInfo *exception)
1804 register const unsigned char
1823 assert(image != (Image *) NULL);
1824 assert(image->signature == MagickCoreSignature);
1825 assert(image->blob != (BlobInfo *) NULL);
1826 assert(image->blob->type != UndefinedStream);
1827 if (image->debug != MagickFalse)
1828 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1829 assert(filename != (const char *) NULL);
1830 if (*filename == '\0')
1831 file=AcquireUniqueFileResource(filename);
1833 if (LocaleCompare(filename,"-") == 0)
1834 file=fileno(stdout);
1836 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1839 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1840 return(MagickFalse);
1842 quantum=(size_t) MagickMaxBufferExtent;
1843 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1844 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1845 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1846 if (buffer == (unsigned char *) NULL)
1849 (void) ThrowMagickException(exception,GetMagickModule(),
1850 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1851 return(MagickFalse);
1854 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1855 for (i=0; count > 0; )
1857 length=(size_t) count;
1858 for (i=0; i < length; i+=count)
1860 count=write(file,p+i,(size_t) (length-i));
1870 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1872 if (LocaleCompare(filename,"-") != 0)
1874 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1875 if ((file == -1) || (i < length))
1879 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1880 return(MagickFalse);
1886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1890 % I m a g e s T o B l o b %
1894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1896 % ImagesToBlob() implements direct to memory image formats. It returns the
1897 % image sequence as a blob and its length. The magick member of the ImageInfo
1898 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1900 % Note, some image formats do not permit multiple images to the same image
1901 % stream (e.g. JPEG). in this instance, just the first image of the
1902 % sequence is returned as a blob.
1904 % The format of the ImagesToBlob method is:
1906 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1907 % size_t *length,ExceptionInfo *exception)
1909 % A description of each parameter follows:
1911 % o image_info: the image info.
1913 % o images: the image list.
1915 % o length: return the actual length of the blob.
1917 % o exception: return any errors or warnings in this structure.
1920 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1921 size_t *length,ExceptionInfo *exception)
1935 assert(image_info != (const ImageInfo *) NULL);
1936 assert(image_info->signature == MagickCoreSignature);
1937 if (image_info->debug != MagickFalse)
1938 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1939 image_info->filename);
1940 assert(images != (Image *) NULL);
1941 assert(images->signature == MagickCoreSignature);
1942 assert(exception != (ExceptionInfo *) NULL);
1944 blob=(unsigned char *) NULL;
1945 blob_info=CloneImageInfo(image_info);
1946 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1948 if (*blob_info->magick != '\0')
1949 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
1950 magick_info=GetMagickInfo(images->magick,exception);
1951 if (magick_info == (const MagickInfo *) NULL)
1953 (void) ThrowMagickException(exception,GetMagickModule(),
1954 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1956 blob_info=DestroyImageInfo(blob_info);
1959 if (GetMagickAdjoin(magick_info) == MagickFalse)
1961 blob_info=DestroyImageInfo(blob_info);
1962 return(ImageToBlob(image_info,images,length,exception));
1964 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
1965 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1968 Native blob support for this images format.
1970 blob_info->length=0;
1971 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1972 sizeof(unsigned char));
1973 if (blob_info->blob == (void *) NULL)
1974 (void) ThrowMagickException(exception,GetMagickModule(),
1975 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1978 (void) CloseBlob(images);
1979 images->blob->exempt=MagickTrue;
1980 *images->filename='\0';
1981 status=WriteImages(blob_info,images,images->filename,exception);
1982 *length=images->blob->length;
1983 blob=DetachBlob(images->blob);
1984 if (status == MagickFalse)
1985 blob=RelinquishMagickMemory(blob);
1987 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1993 filename[MagickPathExtent],
1994 unique[MagickPathExtent];
2000 Write file to disk in blob images format.
2002 file=AcquireUniqueFileResource(unique);
2005 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
2006 image_info->filename);
2010 blob_info->file=fdopen(file,"wb");
2011 if (blob_info->file != (FILE *) NULL)
2013 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2014 images->magick,unique);
2015 status=WriteImages(blob_info,images,filename,exception);
2016 (void) CloseBlob(images);
2017 (void) fclose(blob_info->file);
2018 if (status != MagickFalse)
2019 blob=FileToBlob(unique,~0UL,length,exception);
2021 (void) RelinquishUniqueFileResource(unique);
2024 blob_info=DestroyImageInfo(blob_info);
2029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2033 + I m a g e s T o U s e r B l o b %
2037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2039 % ImagesToUserBlob() is the equivalent of WriteImages(), but writes the
2040 % formatted "file" to the suplied method rather than to an actual file.
2042 % The format of the ImageToUserBlob method is:
2044 % void ImagesToUserBlob(const ImageInfo *image_info,Image *images,
2045 % UserBlobInfo *user_info,ExceptionInfo *exception)
2047 % A description of each parameter follows:
2049 % o image_info: the image info.
2051 % o images: the image list.
2053 % o user_info: the methods to use when writing and seeking.
2055 % o exception: return any errors or warnings in this structure.
2058 MagickExport void ImagesToUserBlob(const ImageInfo *image_info,Image *images,
2059 UserBlobInfo *user_info,ExceptionInfo *exception)
2070 assert(image_info != (const ImageInfo *) NULL);
2071 assert(image_info->signature == MagickCoreSignature);
2072 if (image_info->debug != MagickFalse)
2073 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2074 image_info->filename);
2075 assert(images != (Image *) NULL);
2076 assert(images->signature == MagickCoreSignature);
2077 assert(user_info != (UserBlobInfo *) NULL);
2078 assert(user_info->handler != (BlobHandler) NULL);
2079 assert(exception != (ExceptionInfo *) NULL);
2080 blob_info=CloneImageInfo(image_info);
2081 blob_info->adjoin=MagickFalse;
2082 blob_info->user_info=user_info;
2083 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2085 if (*blob_info->magick != '\0')
2086 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2087 magick_info=GetMagickInfo(images->magick,exception);
2088 if (magick_info == (const MagickInfo *) NULL)
2090 (void) ThrowMagickException(exception,GetMagickModule(),
2091 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
2093 blob_info=DestroyImageInfo(blob_info);
2096 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2097 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2100 Native blob support for this image format.
2102 (void) CloseBlob(images);
2103 *images->filename='\0';
2104 (void) WriteImages(blob_info,images,images->filename,exception);
2105 (void) CloseBlob(images);
2110 filename[MagickPathExtent],
2111 unique[MagickPathExtent];
2120 Write file to disk in blob image format.
2122 blob_info->user_info=(UserBlobInfo *) NULL;
2123 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
2125 if (blob == (unsigned char *) NULL)
2127 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2128 image_info->filename);
2129 blob_info=DestroyImageInfo(blob_info);
2132 file=AcquireUniqueFileResource(unique);
2135 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2136 image_info->filename);
2137 blob=(unsigned char *) RelinquishMagickMemory(blob);
2138 blob_info=DestroyImageInfo(blob_info);
2141 blob_info->file=fdopen(file,"wb+");
2142 if (blob_info->file != (FILE *) NULL)
2147 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2148 images->magick,unique);
2149 status=WriteImages(blob_info,images,filename,exception);
2150 (void) CloseBlob(images);
2151 if (status != MagickFalse)
2153 (void) fseek(blob_info->file,0,SEEK_SET);
2154 count=(ssize_t) MagickMaxBufferExtent;
2155 while (count == (ssize_t) MagickMaxBufferExtent)
2157 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
2159 user_info->handler(blob,count,user_info->data);
2162 (void) fclose(blob_info->file);
2164 blob=(unsigned char *) RelinquishMagickMemory(blob);
2165 (void) RelinquishUniqueFileResource(unique);
2167 blob_info=DestroyImageInfo(blob_info);
2172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2176 % I n j e c t I m a g e B l o b %
2180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2182 % InjectImageBlob() injects the image with a copy of itself in the specified
2183 % format (e.g. inject JPEG into a PDF image).
2185 % The format of the InjectImageBlob method is:
2187 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2188 % Image *image,Image *inject_image,const char *format,
2189 % ExceptionInfo *exception)
2191 % A description of each parameter follows:
2193 % o image_info: the image info..
2195 % o image: the image.
2197 % o inject_image: inject into the image stream.
2199 % o format: the image format.
2201 % o exception: return any errors or warnings in this structure.
2204 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2205 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
2208 filename[MagickPathExtent];
2241 Write inject image to a temporary file.
2243 assert(image_info != (ImageInfo *) NULL);
2244 assert(image_info->signature == MagickCoreSignature);
2245 assert(image != (Image *) NULL);
2246 assert(image->signature == MagickCoreSignature);
2247 if (image->debug != MagickFalse)
2248 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2249 assert(inject_image != (Image *) NULL);
2250 assert(inject_image->signature == MagickCoreSignature);
2251 assert(exception != (ExceptionInfo *) NULL);
2252 unique_file=(FILE *) NULL;
2253 file=AcquireUniqueFileResource(filename);
2255 unique_file=fdopen(file,"wb");
2256 if ((file == -1) || (unique_file == (FILE *) NULL))
2258 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2259 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
2261 return(MagickFalse);
2263 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
2264 if (byte_image == (Image *) NULL)
2266 (void) fclose(unique_file);
2267 (void) RelinquishUniqueFileResource(filename);
2268 return(MagickFalse);
2270 (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",format,
2272 DestroyBlob(byte_image);
2273 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
2274 write_info=CloneImageInfo(image_info);
2275 SetImageInfoFile(write_info,unique_file);
2276 status=WriteImage(write_info,byte_image,exception);
2277 write_info=DestroyImageInfo(write_info);
2278 byte_image=DestroyImage(byte_image);
2279 (void) fclose(unique_file);
2280 if (status == MagickFalse)
2282 (void) RelinquishUniqueFileResource(filename);
2283 return(MagickFalse);
2286 Inject into image stream.
2288 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
2291 (void) RelinquishUniqueFileResource(filename);
2292 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
2293 image_info->filename);
2294 return(MagickFalse);
2296 quantum=(size_t) MagickMaxBufferExtent;
2297 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
2298 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2299 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2300 if (buffer == (unsigned char *) NULL)
2302 (void) RelinquishUniqueFileResource(filename);
2304 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2307 for (i=0; ; i+=count)
2309 count=read(file,buffer,quantum);
2316 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2321 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2322 (void) RelinquishUniqueFileResource(filename);
2323 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2332 % I s B l o b E x e m p t %
2336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2338 % IsBlobExempt() returns true if the blob is exempt.
2340 % The format of the IsBlobExempt method is:
2342 % MagickBooleanType IsBlobExempt(const Image *image)
2344 % A description of each parameter follows:
2346 % o image: the image.
2349 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
2351 assert(image != (const Image *) NULL);
2352 assert(image->signature == MagickCoreSignature);
2353 if (image->debug != MagickFalse)
2354 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2355 return(image->blob->exempt);
2359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2363 % I s B l o b S e e k a b l e %
2367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2369 % IsBlobSeekable() returns true if the blob is seekable.
2371 % The format of the IsBlobSeekable method is:
2373 % MagickBooleanType IsBlobSeekable(const Image *image)
2375 % A description of each parameter follows:
2377 % o image: the image.
2380 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2385 assert(image != (const Image *) NULL);
2386 assert(image->signature == MagickCoreSignature);
2387 if (image->debug != MagickFalse)
2388 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2389 switch (image->blob->type)
2395 seekable=MagickTrue;
2398 case UndefinedStream:
2399 case StandardStream:
2405 seekable=MagickFalse;
2410 if ((image->blob->user_info->seeker != (BlobSeeker) NULL) &&
2411 (image->blob->user_info->teller != (BlobTeller) NULL))
2412 seekable=MagickTrue;
2414 seekable=MagickFalse;
2422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2426 % I s B l o b T e m p o r a r y %
2430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2432 % IsBlobTemporary() returns true if the blob is temporary.
2434 % The format of the IsBlobTemporary method is:
2436 % MagickBooleanType IsBlobTemporary(const Image *image)
2438 % A description of each parameter follows:
2440 % o image: the image.
2443 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2445 assert(image != (const Image *) NULL);
2446 assert(image->signature == MagickCoreSignature);
2447 if (image->debug != MagickFalse)
2448 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2449 return(image->blob->temporary);
2453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2463 % MapBlob() creates a mapping from a file to a binary large object.
2465 % The format of the MapBlob method is:
2467 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2468 % const size_t length)
2470 % A description of each parameter follows:
2472 % o file: map this file descriptor.
2474 % o mode: ReadMode, WriteMode, or IOMode.
2476 % o offset: starting at this offset within the file.
2478 % o length: the length of the mapping is returned in this pointer.
2481 MagickExport void *MapBlob(int file,const MapMode mode,
2482 const MagickOffsetType offset,const size_t length)
2484 #if defined(MAGICKCORE_HAVE_MMAP)
2497 #if defined(MAP_ANONYMOUS)
2498 flags|=MAP_ANONYMOUS;
2507 protection=PROT_READ;
2513 protection=PROT_WRITE;
2519 protection=PROT_READ | PROT_WRITE;
2524 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2525 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2527 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2529 if (map == MAP_FAILED)
2530 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2532 if (map == MAP_FAILED)
2545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2549 + M S B O r d e r L o n g %
2553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2555 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2556 % most-significant byte first.
2558 % The format of the MSBOrderLong method is:
2560 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2562 % A description of each parameter follows.
2564 % o buffer: Specifies a pointer to a buffer of integers.
2566 % o length: Specifies the length of the buffer.
2569 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2574 register unsigned char
2578 assert(buffer != (unsigned char *) NULL);
2585 *buffer++=(unsigned char) c;
2589 *buffer++=(unsigned char) c;
2595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2599 + M S B O r d e r S h o r t %
2603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2605 % MSBOrderShort() converts a least-significant byte first buffer of integers
2606 % to most-significant byte first.
2608 % The format of the MSBOrderShort method is:
2610 % void MSBOrderShort(unsigned char *p,const size_t length)
2612 % A description of each parameter follows.
2614 % o p: Specifies a pointer to a buffer of integers.
2616 % o length: Specifies the length of the buffer.
2619 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2624 register unsigned char
2627 assert(p != (unsigned char *) NULL);
2634 *p++=(unsigned char) c;
2639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2649 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2650 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2651 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2652 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2653 % from a system command.
2655 % The format of the OpenBlob method is:
2657 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2658 % const BlobMode mode,ExceptionInfo *exception)
2660 % A description of each parameter follows:
2662 % o image_info: the image info.
2664 % o image: the image.
2666 % o mode: the mode for opening the file.
2670 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2683 option=GetImageOption(image_info,"stream:buffer-size");
2684 if (option != (const char *) NULL)
2685 size=StringToUnsignedLong(option);
2686 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2687 _IONBF : _IOFBF,size);
2688 return(status == 0 ? MagickTrue : MagickFalse);
2691 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2692 Image *image,const BlobMode mode,ExceptionInfo *exception)
2695 extension[MagickPathExtent],
2696 filename[MagickPathExtent];
2707 assert(image_info != (ImageInfo *) NULL);
2708 assert(image_info->signature == MagickCoreSignature);
2709 if (image_info->debug != MagickFalse)
2710 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2711 image_info->filename);
2712 assert(image != (Image *) NULL);
2713 assert(image->signature == MagickCoreSignature);
2714 if (image_info->blob != (void *) NULL)
2716 if (image_info->stream != (StreamHandler) NULL)
2717 image->blob->stream=(StreamHandler) image_info->stream;
2718 AttachBlob(image->blob,image_info->blob,image_info->length);
2721 if (image_info->user_info != (UserBlobInfo *) NULL)
2723 image->blob->type=UserStream;
2724 image->blob->user_info=image_info->user_info;
2727 (void) DetachBlob(image->blob);
2730 default: type="r"; break;
2731 case ReadBlobMode: type="r"; break;
2732 case ReadBinaryBlobMode: type="rb"; break;
2733 case WriteBlobMode: type="w"; break;
2734 case WriteBinaryBlobMode: type="w+b"; break;
2735 case AppendBlobMode: type="a"; break;
2736 case AppendBinaryBlobMode: type="a+b"; break;
2739 image->blob->synchronize=image_info->synchronize;
2740 if (image_info->stream != (StreamHandler) NULL)
2742 image->blob->stream=(StreamHandler) image_info->stream;
2745 image->blob->type=FifoStream;
2753 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2754 rights=ReadPolicyRights;
2756 rights=WritePolicyRights;
2757 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2760 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2761 "NotAuthorized","`%s'",filename);
2762 return(MagickFalse);
2764 if ((LocaleCompare(filename,"-") == 0) ||
2765 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2767 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2768 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2769 if (strchr(type,'b') != (char *) NULL)
2770 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2772 image->blob->type=StandardStream;
2773 image->blob->exempt=MagickTrue;
2774 return(SetStreamBuffering(image_info,image));
2776 if (LocaleNCompare(filename,"fd:",3) == 0)
2779 fileMode[MagickPathExtent];
2783 image->blob->file_info.file=fdopen(StringToLong(filename+3),fileMode);
2784 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2785 if (strchr(type,'b') != (char *) NULL)
2786 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2788 image->blob->type=StandardStream;
2789 image->blob->exempt=MagickTrue;
2790 return(SetStreamBuffering(image_info,image));
2792 #if defined(MAGICKCORE_HAVE_POPEN) && defined(MAGICKCORE_PIPES_SUPPORT)
2793 if (*filename == '|')
2796 fileMode[MagickPathExtent],
2800 Pipe image to or from a system command.
2802 #if defined(SIGPIPE)
2804 (void) signal(SIGPIPE,SIG_IGN);
2808 sanitize_command=SanitizeString(filename+1);
2809 image->blob->file_info.file=(FILE *) popen_utf8(sanitize_command,
2811 sanitize_command=DestroyString(sanitize_command);
2812 if (image->blob->file_info.file == (FILE *) NULL)
2814 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2815 return(MagickFalse);
2817 image->blob->type=PipeStream;
2818 image->blob->exempt=MagickTrue;
2819 return(SetStreamBuffering(image_info,image));
2822 status=GetPathAttributes(filename,&image->blob->properties);
2823 #if defined(S_ISFIFO)
2824 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2826 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2827 if (image->blob->file_info.file == (FILE *) NULL)
2829 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2830 return(MagickFalse);
2832 image->blob->type=FileStream;
2833 image->blob->exempt=MagickTrue;
2834 return(SetStreamBuffering(image_info,image));
2837 GetPathComponent(image->filename,ExtensionPath,extension);
2840 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2841 if ((image_info->adjoin == MagickFalse) ||
2842 (strchr(filename,'%') != (char *) NULL))
2845 Form filename for multi-part images.
2847 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2848 image->scene,filename,exception);
2849 if ((LocaleCompare(filename,image->filename) == 0) &&
2850 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2851 (GetNextImageInList(image) != (Image *) NULL)))
2854 path[MagickPathExtent];
2856 GetPathComponent(image->filename,RootPath,path);
2857 if (*extension == '\0')
2858 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
2859 path,(double) image->scene);
2861 (void) FormatLocaleString(filename,MagickPathExtent,
2862 "%s-%.20g.%s",path,(double) image->scene,extension);
2864 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2865 #if defined(macintosh)
2866 SetApplicationType(filename,image_info->magick,'8BIM');
2870 if (image_info->file != (FILE *) NULL)
2872 image->blob->file_info.file=image_info->file;
2873 image->blob->type=FileStream;
2874 image->blob->exempt=MagickTrue;
2879 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2880 if (image->blob->file_info.file != (FILE *) NULL)
2888 image->blob->type=FileStream;
2889 (void) SetStreamBuffering(image_info,image);
2890 (void) ResetMagickMemory(magick,0,sizeof(magick));
2891 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2892 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2893 #if defined(MAGICKCORE_POSIX_SUPPORT)
2894 (void) fflush(image->blob->file_info.file);
2896 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2897 " read %.20g magic header bytes",(double) count);
2898 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2899 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2900 ((int) magick[2] == 0x08))
2902 if (image->blob->file_info.file != (FILE *) NULL)
2903 (void) fclose(image->blob->file_info.file);
2904 image->blob->file_info.file=(FILE *) NULL;
2905 image->blob->file_info.gzfile=gzopen(filename,type);
2906 if (image->blob->file_info.gzfile != (gzFile) NULL)
2907 image->blob->type=ZipStream;
2910 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2911 if (strncmp((char *) magick,"BZh",3) == 0)
2913 if (image->blob->file_info.file != (FILE *) NULL)
2914 (void) fclose(image->blob->file_info.file);
2915 image->blob->file_info.file=(FILE *) NULL;
2916 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2917 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2918 image->blob->type=BZipStream;
2921 if (image->blob->type == FileStream)
2932 sans_exception=AcquireExceptionInfo();
2933 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2934 sans_exception=DestroyExceptionInfo(sans_exception);
2935 length=(size_t) image->blob->properties.st_size;
2936 if ((magick_info != (const MagickInfo *) NULL) &&
2937 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2938 (length > MagickMaxBufferExtent) &&
2939 (AcquireMagickResource(MapResource,length) != MagickFalse))
2944 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
2946 if (blob == (void *) NULL)
2947 RelinquishMagickResource(MapResource,length);
2951 Format supports blobs-- use memory-mapped I/O.
2953 if (image_info->file != (FILE *) NULL)
2954 image->blob->exempt=MagickFalse;
2957 (void) fclose(image->blob->file_info.file);
2958 image->blob->file_info.file=(FILE *) NULL;
2960 AttachBlob(image->blob,blob,length);
2961 image->blob->mapped=MagickTrue;
2968 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2969 if ((LocaleCompare(extension,"Z") == 0) ||
2970 (LocaleCompare(extension,"gz") == 0) ||
2971 (LocaleCompare(extension,"wmz") == 0) ||
2972 (LocaleCompare(extension,"svgz") == 0))
2974 if (mode == WriteBinaryBlobMode)
2976 image->blob->file_info.gzfile=gzopen(filename,type);
2977 if (image->blob->file_info.gzfile != (gzFile) NULL)
2978 image->blob->type=ZipStream;
2982 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2983 if (LocaleCompare(extension,"bz2") == 0)
2985 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2986 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2987 image->blob->type=BZipStream;
2992 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2993 if (image->blob->file_info.file != (FILE *) NULL)
2995 image->blob->type=FileStream;
2996 (void) SetStreamBuffering(image_info,image);
2999 image->blob->status=MagickFalse;
3000 if (image->blob->type != UndefinedStream)
3001 image->blob->size=GetBlobSize(image);
3004 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
3005 return(MagickFalse);
3011 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3019 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3021 % PingBlob() returns all the attributes of an image or image sequence except
3022 % for the pixels. It is much faster and consumes far less memory than
3023 % BlobToImage(). On failure, a NULL image is returned and exception
3024 % describes the reason for the failure.
3026 % The format of the PingBlob method is:
3028 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
3029 % const size_t length,ExceptionInfo *exception)
3031 % A description of each parameter follows:
3033 % o image_info: the image info.
3035 % o blob: the address of a character stream in one of the image formats
3036 % understood by ImageMagick.
3038 % o length: This size_t integer reflects the length in bytes of the blob.
3040 % o exception: return any errors or warnings in this structure.
3044 #if defined(__cplusplus) || defined(c_plusplus)
3048 static size_t PingStream(const Image *magick_unused(image),
3049 const void *magick_unused(pixels),const size_t columns)
3051 magick_unreferenced(image);
3052 magick_unreferenced(pixels);
3056 #if defined(__cplusplus) || defined(c_plusplus)
3060 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
3061 const size_t length,ExceptionInfo *exception)
3069 assert(image_info != (ImageInfo *) NULL);
3070 assert(image_info->signature == MagickCoreSignature);
3071 if (image_info->debug != MagickFalse)
3072 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3073 image_info->filename);
3074 assert(exception != (ExceptionInfo *) NULL);
3075 if ((blob == (const void *) NULL) || (length == 0))
3077 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
3078 "UnrecognizedImageFormat","`%s'",image_info->magick);
3079 return((Image *) NULL);
3081 ping_info=CloneImageInfo(image_info);
3082 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
3083 if (ping_info->blob == (const void *) NULL)
3085 (void) ThrowMagickException(exception,GetMagickModule(),
3086 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
3087 return((Image *) NULL);
3089 (void) memcpy(ping_info->blob,blob,length);
3090 ping_info->length=length;
3091 ping_info->ping=MagickTrue;
3092 image=ReadStream(ping_info,&PingStream,exception);
3093 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
3094 ping_info=DestroyImageInfo(ping_info);
3099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3109 % ReadBlob() reads data from the blob or image file and returns it. It
3110 % returns the number of bytes read. If length is zero, ReadBlob() returns
3111 % zero and has no other results. If length is greater than SSIZE_MAX, the
3112 % result is unspecified.
3114 % The format of the ReadBlob method is:
3116 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
3118 % A description of each parameter follows:
3120 % o image: the image.
3122 % o length: Specifies an integer representing the number of bytes to read
3125 % o data: Specifies an area to place the information requested from the
3129 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
3134 register unsigned char
3140 assert(image != (Image *) NULL);
3141 assert(image->signature == MagickCoreSignature);
3142 assert(image->blob != (BlobInfo *) NULL);
3143 assert(image->blob->type != UndefinedStream);
3146 assert(data != (void *) NULL);
3148 q=(unsigned char *) data;
3149 switch (image->blob->type)
3151 case UndefinedStream:
3153 case StandardStream:
3161 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
3166 c=getc(image->blob->file_info.file);
3169 *q++=(unsigned char) c;
3174 c=getc(image->blob->file_info.file);
3177 *q++=(unsigned char) c;
3182 c=getc(image->blob->file_info.file);
3185 *q++=(unsigned char) c;
3190 c=getc(image->blob->file_info.file);
3193 *q++=(unsigned char) c;
3203 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3208 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
3209 (unsigned int) length);
3214 c=gzgetc(image->blob->file_info.gzfile);
3217 *q++=(unsigned char) c;
3222 c=gzgetc(image->blob->file_info.gzfile);
3225 *q++=(unsigned char) c;
3230 c=gzgetc(image->blob->file_info.gzfile);
3233 *q++=(unsigned char) c;
3238 c=gzgetc(image->blob->file_info.gzfile);
3241 *q++=(unsigned char) c;
3252 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3253 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
3261 register const unsigned char
3264 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3266 image->blob->eof=MagickTrue;
3269 p=image->blob->data+image->blob->offset;
3270 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
3271 image->blob->offset+=count;
3272 if (count != (ssize_t) length)
3273 image->blob->eof=MagickTrue;
3274 (void) memcpy(q,p,(size_t) count);
3279 count=image->blob->user_info->handler(q,length,
3280 image->blob->user_info->data);
3288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3292 + R e a d B l o b B y t e %
3296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3298 % ReadBlobByte() reads a single byte from the image file and returns it.
3300 % The format of the ReadBlobByte method is:
3302 % int ReadBlobByte(Image *image)
3304 % A description of each parameter follows.
3306 % o image: the image.
3309 MagickExport int ReadBlobByte(Image *image)
3311 register const unsigned char
3320 assert(image != (Image *) NULL);
3321 assert(image->signature == MagickCoreSignature);
3322 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3333 + R e a d B l o b D o u b l e %
3337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3339 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3340 % specified by the endian member of the image structure.
3342 % The format of the ReadBlobDouble method is:
3344 % double ReadBlobDouble(Image *image)
3346 % A description of each parameter follows.
3348 % o image: the image.
3351 MagickExport double ReadBlobDouble(Image *image)
3362 quantum.double_value=0.0;
3363 quantum.unsigned_value=ReadBlobLongLong(image);
3364 return(quantum.double_value);
3368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3372 + R e a d B l o b F l o a t %
3376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3378 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3379 % specified by the endian member of the image structure.
3381 % The format of the ReadBlobFloat method is:
3383 % float ReadBlobFloat(Image *image)
3385 % A description of each parameter follows.
3387 % o image: the image.
3390 MagickExport float ReadBlobFloat(Image *image)
3401 quantum.float_value=0.0;
3402 quantum.unsigned_value=ReadBlobLong(image);
3403 return(quantum.float_value);
3407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3411 + R e a d B l o b L o n g %
3415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3417 % ReadBlobLong() reads a unsigned int value as a 32-bit quantity in the
3418 % byte-order specified by the endian member of the image structure.
3420 % The format of the ReadBlobLong method is:
3422 % unsigned int ReadBlobLong(Image *image)
3424 % A description of each parameter follows.
3426 % o image: the image.
3429 MagickExport unsigned int ReadBlobLong(Image *image)
3431 register const unsigned char
3443 assert(image != (Image *) NULL);
3444 assert(image->signature == MagickCoreSignature);
3446 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3449 if (image->endian == LSBEndian)
3451 value=(unsigned int) (*p++);
3452 value|=(unsigned int) (*p++) << 8;
3453 value|=(unsigned int) (*p++) << 16;
3454 value|=(unsigned int) (*p++) << 24;
3455 return(value & 0xffffffff);
3457 value=(unsigned int) (*p++) << 24;
3458 value|=(unsigned int) (*p++) << 16;
3459 value|=(unsigned int) (*p++) << 8;
3460 value|=(unsigned int) (*p++);
3461 return(value & 0xffffffff);
3465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3469 + R e a d B l o b L o n g L o n g %
3473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3475 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3476 % byte-order specified by the endian member of the image structure.
3478 % The format of the ReadBlobLongLong method is:
3480 % MagickSizeType ReadBlobLongLong(Image *image)
3482 % A description of each parameter follows.
3484 % o image: the image.
3487 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3492 register const unsigned char
3501 assert(image != (Image *) NULL);
3502 assert(image->signature == MagickCoreSignature);
3504 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3506 return(MagickULLConstant(0));
3507 if (image->endian == LSBEndian)
3509 value=(MagickSizeType) (*p++);
3510 value|=(MagickSizeType) (*p++) << 8;
3511 value|=(MagickSizeType) (*p++) << 16;
3512 value|=(MagickSizeType) (*p++) << 24;
3513 value|=(MagickSizeType) (*p++) << 32;
3514 value|=(MagickSizeType) (*p++) << 40;
3515 value|=(MagickSizeType) (*p++) << 48;
3516 value|=(MagickSizeType) (*p++) << 56;
3517 return(value & MagickULLConstant(0xffffffffffffffff));
3519 value=(MagickSizeType) (*p++) << 56;
3520 value|=(MagickSizeType) (*p++) << 48;
3521 value|=(MagickSizeType) (*p++) << 40;
3522 value|=(MagickSizeType) (*p++) << 32;
3523 value|=(MagickSizeType) (*p++) << 24;
3524 value|=(MagickSizeType) (*p++) << 16;
3525 value|=(MagickSizeType) (*p++) << 8;
3526 value|=(MagickSizeType) (*p++);
3527 return(value & MagickULLConstant(0xffffffffffffffff));
3531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3535 + R e a d B l o b S h o r t %
3539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3541 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3542 % specified by the endian member of the image structure.
3544 % The format of the ReadBlobShort method is:
3546 % unsigned short ReadBlobShort(Image *image)
3548 % A description of each parameter follows.
3550 % o image: the image.
3553 MagickExport unsigned short ReadBlobShort(Image *image)
3555 register const unsigned char
3558 register unsigned short
3567 assert(image != (Image *) NULL);
3568 assert(image->signature == MagickCoreSignature);
3570 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3572 return((unsigned short) 0U);
3573 if (image->endian == LSBEndian)
3575 value=(unsigned short) (*p++);
3576 value|=(unsigned short) (*p++) << 8;
3579 value=(unsigned short) (*p++) << 8;
3580 value|=(unsigned short) (*p++);
3585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3589 + R e a d B l o b L S B L o n g %
3593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3595 % ReadBlobLSBLong() reads a unsigned int value as a 32-bit quantity in
3596 % least-significant byte first order.
3598 % The format of the ReadBlobLSBLong method is:
3600 % unsigned int ReadBlobLSBLong(Image *image)
3602 % A description of each parameter follows.
3604 % o image: the image.
3607 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3609 register const unsigned char
3612 register unsigned int
3621 assert(image != (Image *) NULL);
3622 assert(image->signature == MagickCoreSignature);
3624 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3627 value=(unsigned int) (*p++);
3628 value|=(unsigned int) (*p++) << 8;
3629 value|=(unsigned int) (*p++) << 16;
3630 value|=(unsigned int) (*p++) << 24;
3631 return(value & 0xffffffff);
3635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3639 + R e a d B l o b L S B S i g n e d L o n g %
3643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3645 % ReadBlobLSBSignedLong() reads a signed int value as a 32-bit quantity in
3646 % least-significant byte first order.
3648 % The format of the ReadBlobLSBSignedLong method is:
3650 % signed int ReadBlobLSBSignedLong(Image *image)
3652 % A description of each parameter follows.
3654 % o image: the image.
3657 MagickExport signed int ReadBlobLSBSignedLong(Image *image)
3668 quantum.unsigned_value=ReadBlobLSBLong(image);
3669 return(quantum.signed_value);
3673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3677 + R e a d B l o b L S B S h o r t %
3681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3683 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3684 % least-significant byte first order.
3686 % The format of the ReadBlobLSBShort method is:
3688 % unsigned short ReadBlobLSBShort(Image *image)
3690 % A description of each parameter follows.
3692 % o image: the image.
3695 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3697 register const unsigned char
3700 register unsigned short
3709 assert(image != (Image *) NULL);
3710 assert(image->signature == MagickCoreSignature);
3712 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3714 return((unsigned short) 0U);
3715 value=(unsigned int) (*p++);
3716 value|=(unsigned int) (*p++) << 8;
3717 return(value & 0xffff);
3721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3725 + R e a d B l o b L S B S i g n e d S h o r t %
3729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3731 % ReadBlobLSBSignedShort() reads a signed short value as a 16-bit quantity in
3732 % least-significant byte-order.
3734 % The format of the ReadBlobLSBSignedShort method is:
3736 % signed short ReadBlobLSBSignedShort(Image *image)
3738 % A description of each parameter follows.
3740 % o image: the image.
3743 MagickExport signed short ReadBlobLSBSignedShort(Image *image)
3754 quantum.unsigned_value=ReadBlobLSBShort(image);
3755 return(quantum.signed_value);
3759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3763 + R e a d B l o b M S B L o n g %
3767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3769 % ReadBlobMSBLong() reads a unsigned int value as a 32-bit quantity in
3770 % most-significant byte first order.
3772 % The format of the ReadBlobMSBLong method is:
3774 % unsigned int ReadBlobMSBLong(Image *image)
3776 % A description of each parameter follows.
3778 % o image: the image.
3781 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3783 register const unsigned char
3786 register unsigned int
3795 assert(image != (Image *) NULL);
3796 assert(image->signature == MagickCoreSignature);
3798 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3801 value=(unsigned int) (*p++) << 24;
3802 value|=(unsigned int) (*p++) << 16;
3803 value|=(unsigned int) (*p++) << 8;
3804 value|=(unsigned int) (*p++);
3809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3813 + R e a d B l o b M S B L o n g L o n g %
3817 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3819 % ReadBlobMSBLongLong() reads a unsigned long long value as a 64-bit quantity
3820 % in most-significant byte first order.
3822 % The format of the ReadBlobMSBLongLong method is:
3824 % unsigned int ReadBlobMSBLongLong(Image *image)
3826 % A description of each parameter follows.
3828 % o image: the image.
3831 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3833 register const unsigned char
3836 register MagickSizeType
3845 assert(image != (Image *) NULL);
3846 assert(image->signature == MagickCoreSignature);
3848 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3850 return(MagickULLConstant(0));
3851 value=(MagickSizeType) (*p++) << 56;
3852 value|=(MagickSizeType) (*p++) << 48;
3853 value|=(MagickSizeType) (*p++) << 40;
3854 value|=(MagickSizeType) (*p++) << 32;
3855 value|=(MagickSizeType) (*p++) << 24;
3856 value|=(MagickSizeType) (*p++) << 16;
3857 value|=(MagickSizeType) (*p++) << 8;
3858 value|=(MagickSizeType) (*p++);
3859 return(value & MagickULLConstant(0xffffffffffffffff));
3863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3867 + R e a d B l o b M S B S h o r t %
3871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3873 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3874 % most-significant byte first order.
3876 % The format of the ReadBlobMSBShort method is:
3878 % unsigned short ReadBlobMSBShort(Image *image)
3880 % A description of each parameter follows.
3882 % o image: the image.
3885 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3887 register const unsigned char
3890 register unsigned short
3899 assert(image != (Image *) NULL);
3900 assert(image->signature == MagickCoreSignature);
3902 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3904 return((unsigned short) 0U);
3905 value=(unsigned short) (*p++) << 8;
3906 value|=(unsigned short) (*p++);
3907 return(value & 0xffff);
3911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3915 + R e a d B l o b M S B S i g n e d L o n g %
3919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3921 % ReadBlobMSBSignedLong() reads a signed int value as a 32-bit quantity in
3922 % most-significant byte-order.
3924 % The format of the ReadBlobMSBSignedLong method is:
3926 % signed int ReadBlobMSBSignedLong(Image *image)
3928 % A description of each parameter follows.
3930 % o image: the image.
3933 MagickExport signed int ReadBlobMSBSignedLong(Image *image)
3944 quantum.unsigned_value=ReadBlobMSBLong(image);
3945 return(quantum.signed_value);
3949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3953 + R e a d B l o b M S B S i g n e d S h o r t %
3957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3959 % ReadBlobMSBSignedShort() reads a signed short value as a 16-bit quantity in
3960 % most-significant byte-order.
3962 % The format of the ReadBlobMSBSignedShort method is:
3964 % signed short ReadBlobMSBSignedShort(Image *image)
3966 % A description of each parameter follows.
3968 % o image: the image.
3971 MagickExport signed short ReadBlobMSBSignedShort(Image *image)
3982 quantum.unsigned_value=ReadBlobMSBShort(image);
3983 return(quantum.signed_value);
3987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3991 + R e a d B l o b S i g n e d L o n g %
3995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3997 % ReadBlobSignedLong() reads a signed int value as a 32-bit quantity in the
3998 % byte-order specified by the endian member of the image structure.
4000 % The format of the ReadBlobSignedLong method is:
4002 % signed int ReadBlobSignedLong(Image *image)
4004 % A description of each parameter follows.
4006 % o image: the image.
4009 MagickExport signed int ReadBlobSignedLong(Image *image)
4020 quantum.unsigned_value=ReadBlobLong(image);
4021 return(quantum.signed_value);
4025 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4029 + R e a d B l o b S i g n e d S h o r t %
4033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4035 % ReadBlobSignedShort() reads a signed short value as a 16-bit quantity in the
4036 % byte-order specified by the endian member of the image structure.
4038 % The format of the ReadBlobSignedShort method is:
4040 % signed short ReadBlobSignedShort(Image *image)
4042 % A description of each parameter follows.
4044 % o image: the image.
4047 MagickExport signed short ReadBlobSignedShort(Image *image)
4058 quantum.unsigned_value=ReadBlobShort(image);
4059 return(quantum.signed_value);
4063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4067 + R e a d B l o b S t r e a m %
4071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4073 % ReadBlobStream() reads data from the blob or image file and returns it. It
4074 % returns a pointer to the data buffer you supply or to the image memory
4075 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
4076 % returns a count of zero and has no other results. If length is greater than
4077 % SSIZE_MAX, the result is unspecified.
4079 % The format of the ReadBlobStream method is:
4081 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
4084 % A description of each parameter follows:
4086 % o image: the image.
4088 % o length: Specifies an integer representing the number of bytes to read
4091 % o count: returns the number of bytes read.
4093 % o data: Specifies an area to place the information requested from the
4097 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
4098 void *data,ssize_t *count)
4100 assert(image != (Image *) NULL);
4101 assert(image->signature == MagickCoreSignature);
4102 assert(image->blob != (BlobInfo *) NULL);
4103 assert(image->blob->type != UndefinedStream);
4104 assert(count != (ssize_t *) NULL);
4105 if (image->blob->type != BlobStream)
4107 assert(data != NULL);
4108 *count=ReadBlob(image,length,(unsigned char *) data);
4111 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4114 image->blob->eof=MagickTrue;
4117 data=image->blob->data+image->blob->offset;
4118 *count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
4119 image->blob->offset+=(*count);
4120 if (*count != (ssize_t) length)
4121 image->blob->eof=MagickTrue;
4126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4130 + R e a d B l o b S t r i n g %
4134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4136 % ReadBlobString() reads characters from a blob or file until a newline
4137 % character is read or an end-of-file condition is encountered.
4139 % The format of the ReadBlobString method is:
4141 % char *ReadBlobString(Image *image,char *string)
4143 % A description of each parameter follows:
4145 % o image: the image.
4147 % o string: the address of a character buffer.
4150 MagickExport char *ReadBlobString(Image *image,char *string)
4152 register const unsigned char
4164 assert(image != (Image *) NULL);
4165 assert(image->signature == MagickCoreSignature);
4166 for (i=0; i < (MagickPathExtent-1L); i++)
4168 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
4172 return((char *) NULL);
4175 string[i]=(char) (*p);
4176 if ((string[i] == '\r') || (string[i] == '\n'))
4179 if (string[i] == '\r')
4180 (void) ReadBlobStream(image,1,buffer,&count);
4186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4190 + R e f e r e n c e B l o b %
4194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4196 % ReferenceBlob() increments the reference count associated with the pixel
4197 % blob returning a pointer to the blob.
4199 % The format of the ReferenceBlob method is:
4201 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
4203 % A description of each parameter follows:
4205 % o blob_info: the blob_info.
4208 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
4210 assert(blob != (BlobInfo *) NULL);
4211 assert(blob->signature == MagickCoreSignature);
4212 if (blob->debug != MagickFalse)
4213 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4214 LockSemaphoreInfo(blob->semaphore);
4215 blob->reference_count++;
4216 UnlockSemaphoreInfo(blob->semaphore);
4221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4231 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
4232 % and returns the resulting offset.
4234 % The format of the SeekBlob method is:
4236 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
4239 % A description of each parameter follows:
4241 % o image: the image.
4243 % o offset: Specifies an integer representing the offset in bytes.
4245 % o whence: Specifies an integer representing how the offset is
4246 % treated relative to the beginning of the blob as follows:
4248 % SEEK_SET Set position equal to offset bytes.
4249 % SEEK_CUR Set position to current location plus offset.
4250 % SEEK_END Set position to EOF plus offset.
4253 MagickExport MagickOffsetType SeekBlob(Image *image,
4254 const MagickOffsetType offset,const int whence)
4256 assert(image != (Image *) NULL);
4257 assert(image->signature == MagickCoreSignature);
4258 if (image->debug != MagickFalse)
4259 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4260 assert(image->blob != (BlobInfo *) NULL);
4261 assert(image->blob->type != UndefinedStream);
4262 switch (image->blob->type)
4264 case UndefinedStream:
4266 case StandardStream:
4271 if ((offset < 0) && (whence == SEEK_SET))
4273 if (fseek(image->blob->file_info.file,offset,whence) < 0)
4275 image->blob->offset=TellBlob(image);
4280 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4281 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
4284 image->blob->offset=TellBlob(image);
4300 image->blob->offset=offset;
4305 if ((image->blob->offset+offset) < 0)
4307 image->blob->offset+=offset;
4312 if (((MagickOffsetType) image->blob->length+offset) < 0)
4314 image->blob->offset=image->blob->length+offset;
4318 if (image->blob->offset < (MagickOffsetType)
4319 ((off_t) image->blob->length))
4321 image->blob->eof=MagickFalse;
4324 if (image->blob->offset < (MagickOffsetType)
4325 ((off_t) image->blob->extent))
4327 if (image->blob->mapped != MagickFalse)
4329 image->blob->eof=MagickTrue;
4332 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
4333 image->blob->quantum<<=1;
4334 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4335 image->blob->extent+1,sizeof(*image->blob->data));
4336 (void) SyncBlob(image);
4337 if (image->blob->data == NULL)
4339 (void) DetachBlob(image->blob);
4346 if (image->blob->user_info->seeker == (BlobSeeker) NULL)
4348 image->blob->user_info->seeker(offset,whence,
4349 image->blob->user_info->data);
4350 image->blob->offset=TellBlob(image);
4354 return(image->blob->offset);
4358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4362 + S e t B l o b E x e m p t %
4366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4368 % SetBlobExempt() sets the blob exempt status.
4370 % The format of the SetBlobExempt method is:
4372 % MagickBooleanType SetBlobExempt(const Image *image,
4373 % const MagickBooleanType exempt)
4375 % A description of each parameter follows:
4377 % o image: the image.
4379 % o exempt: Set to true if this blob is exempt from being closed.
4382 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
4384 assert(image != (const Image *) NULL);
4385 assert(image->signature == MagickCoreSignature);
4386 if (image->debug != MagickFalse)
4387 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4388 image->blob->exempt=exempt;
4392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4396 + S e t B l o b E x t e n t %
4400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4402 % SetBlobExtent() ensures enough space is allocated for the blob. If the
4403 % method is successful, subsequent writes to bytes in the specified range are
4404 % guaranteed not to fail.
4406 % The format of the SetBlobExtent method is:
4408 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
4410 % A description of each parameter follows:
4412 % o image: the image.
4414 % o extent: the blob maximum extent.
4417 MagickExport MagickBooleanType SetBlobExtent(Image *image,
4418 const MagickSizeType extent)
4420 assert(image != (Image *) NULL);
4421 assert(image->signature == MagickCoreSignature);
4422 if (image->debug != MagickFalse)
4423 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4424 assert(image->blob != (BlobInfo *) NULL);
4425 assert(image->blob->type != UndefinedStream);
4426 switch (image->blob->type)
4428 case UndefinedStream:
4430 case StandardStream:
4431 return(MagickFalse);
4440 if (extent != (MagickSizeType) ((off_t) extent))
4441 return(MagickFalse);
4442 offset=SeekBlob(image,0,SEEK_END);
4444 return(MagickFalse);
4445 if ((MagickSizeType) offset >= extent)
4447 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4450 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4451 image->blob->file_info.file);
4452 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4453 if (image->blob->synchronize != MagickFalse)
4458 file=fileno(image->blob->file_info.file);
4459 if ((file == -1) || (offset < 0))
4460 return(MagickFalse);
4461 (void) posix_fallocate(file,offset,extent-offset);
4464 offset=SeekBlob(image,offset,SEEK_SET);
4466 return(MagickFalse);
4471 return(MagickFalse);
4473 return(MagickFalse);
4475 return(MagickFalse);
4478 if (extent != (MagickSizeType) ((size_t) extent))
4479 return(MagickFalse);
4480 if (image->blob->mapped != MagickFalse)
4488 (void) UnmapBlob(image->blob->data,image->blob->length);
4489 RelinquishMagickResource(MapResource,image->blob->length);
4490 if (extent != (MagickSizeType) ((off_t) extent))
4491 return(MagickFalse);
4492 offset=SeekBlob(image,0,SEEK_END);
4494 return(MagickFalse);
4495 if ((MagickSizeType) offset >= extent)
4497 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
4498 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
4499 image->blob->file_info.file);
4500 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
4501 if (image->blob->synchronize != MagickFalse)
4506 file=fileno(image->blob->file_info.file);
4507 if ((file == -1) || (offset < 0))
4508 return(MagickFalse);
4509 (void) posix_fallocate(file,offset,extent-offset);
4512 offset=SeekBlob(image,offset,SEEK_SET);
4514 return(MagickFalse);
4515 (void) AcquireMagickResource(MapResource,extent);
4516 image->blob->data=(unsigned char*) MapBlob(fileno(
4517 image->blob->file_info.file),WriteMode,0,(size_t) extent);
4518 image->blob->extent=(size_t) extent;
4519 image->blob->length=(size_t) extent;
4520 (void) SyncBlob(image);
4523 image->blob->extent=(size_t) extent;
4524 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4525 image->blob->extent+1,sizeof(*image->blob->data));
4526 (void) SyncBlob(image);
4527 if (image->blob->data == (unsigned char *) NULL)
4529 (void) DetachBlob(image->blob);
4530 return(MagickFalse);
4541 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4551 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
4552 % attributes if it is an blob.
4554 % The format of the SyncBlob method is:
4556 % int SyncBlob(Image *image)
4558 % A description of each parameter follows:
4560 % o image: the image.
4563 static int SyncBlob(Image *image)
4568 assert(image != (Image *) NULL);
4569 assert(image->signature == MagickCoreSignature);
4570 if (image->debug != MagickFalse)
4571 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4572 assert(image->blob != (BlobInfo *) NULL);
4573 assert(image->blob->type != UndefinedStream);
4575 switch (image->blob->type)
4577 case UndefinedStream:
4578 case StandardStream:
4583 status=fflush(image->blob->file_info.file);
4588 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4589 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
4595 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4596 status=BZ2_bzflush(image->blob->file_info.bzfile);
4611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4621 % TellBlob() obtains the current value of the blob or file position.
4623 % The format of the TellBlob method is:
4625 % MagickOffsetType TellBlob(const Image *image)
4627 % A description of each parameter follows:
4629 % o image: the image.
4632 MagickExport MagickOffsetType TellBlob(const Image *image)
4637 assert(image != (Image *) NULL);
4638 assert(image->signature == MagickCoreSignature);
4639 if (image->debug != MagickFalse)
4640 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4641 assert(image->blob != (BlobInfo *) NULL);
4642 assert(image->blob->type != UndefinedStream);
4644 switch (image->blob->type)
4646 case UndefinedStream:
4647 case StandardStream:
4651 offset=ftell(image->blob->file_info.file);
4658 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4659 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
4669 offset=image->blob->offset;
4674 if (image->blob->user_info->teller != (BlobTeller) NULL)
4675 offset=image->blob->user_info->teller(image->blob->user_info->data);
4683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4687 + U n m a p B l o b %
4691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4693 % UnmapBlob() deallocates the binary large object previously allocated with
4694 % the MapBlob method.
4696 % The format of the UnmapBlob method is:
4698 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4700 % A description of each parameter follows:
4702 % o map: the address of the binary large object.
4704 % o length: the length of the binary large object.
4707 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4709 #if defined(MAGICKCORE_HAVE_MMAP)
4713 status=munmap(map,length);
4714 return(status == -1 ? MagickFalse : MagickTrue);
4718 return(MagickFalse);
4723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4727 % U s e r B l o b T o I m a g e %
4731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4733 % UserBlobToImage() is the equivalent of ReadImage(), but reads the
4734 % formatted "file" from the suplied method rather than to an actual file.
4736 % The format of the BlobToImage method is:
4738 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
4739 % const size_t length,ExceptionInfo *exception)
4741 % A description of each parameter follows:
4743 % o image_info: the image info.
4745 % o blob: the address of a character stream in one of the image formats
4746 % understood by ImageMagick.
4748 % o length: This size_t integer reflects the length in bytes of the blob.
4750 % o exception: return any errors or warnings in this structure.
4753 MagickExport Image *UserBlobToImage(const ImageInfo *image_info,
4754 UserBlobInfo *user_info,ExceptionInfo *exception)
4765 assert(image_info != (ImageInfo *) NULL);
4766 assert(image_info->signature == MagickCoreSignature);
4767 if (image_info->debug != MagickFalse)
4768 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
4769 image_info->filename);
4770 assert(user_info != (UserBlobInfo *) NULL);
4771 assert(user_info->handler != (BlobHandler) NULL);
4772 assert(exception != (ExceptionInfo *) NULL);
4773 blob_info=CloneImageInfo(image_info);
4774 blob_info->user_info=user_info;
4775 if (*blob_info->magick == '\0')
4776 (void) SetImageInfo(blob_info,0,exception);
4777 magick_info=GetMagickInfo(blob_info->magick,exception);
4778 if (magick_info == (const MagickInfo *) NULL)
4780 (void) ThrowMagickException(exception,GetMagickModule(),
4781 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
4783 blob_info=DestroyImageInfo(blob_info);
4784 return((Image *) NULL);
4786 image=(Image *) NULL;
4787 if (GetMagickBlobSupport(magick_info) != MagickFalse)
4790 Native blob support for this image format.
4792 (void) CopyMagickString(blob_info->filename,image_info->filename,
4794 (void) CopyMagickString(blob_info->magick,image_info->magick,
4796 image=ReadImage(blob_info,exception);
4797 if (image != (Image *) NULL)
4798 (void) CloseBlob(image);
4803 unique[MagickPathExtent];
4815 Write data to file on disk.
4817 blob_info->user_info=(UserBlobInfo *) NULL;
4818 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
4820 if (blob == (unsigned char *) NULL)
4822 ThrowFileException(exception,BlobError,"UnableToReadBlob",
4823 image_info->filename);
4824 blob_info=DestroyImageInfo(blob_info);
4825 return((Image *) NULL);
4827 file=AcquireUniqueFileResource(unique);
4830 ThrowFileException(exception,BlobError,"UnableToReadBlob",
4831 image_info->filename);
4832 blob=(unsigned char *) RelinquishMagickMemory(blob);
4833 blob_info=DestroyImageInfo(blob_info);
4834 return((Image *) NULL);
4836 clone_info=CloneImageInfo(blob_info);
4837 blob_info->file=fdopen(file,"wb+");
4838 if (blob_info->file != (FILE *) NULL)
4843 count=(ssize_t) MagickMaxBufferExtent;
4844 while (count == (ssize_t) MagickMaxBufferExtent)
4846 count=user_info->handler(blob,MagickMaxBufferExtent,
4848 count=(ssize_t) write(file,(const char *) blob,count);
4850 (void) fclose(blob_info->file);
4851 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,
4852 "%s:%s",blob_info->magick,unique);
4853 image=ReadImage(clone_info,exception);
4854 if (image != (Image *) NULL)
4860 Restore original filenames and image format.
4862 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
4864 (void) CopyMagickString(images->filename,image_info->filename,
4866 (void) CopyMagickString(images->magick_filename,
4867 image_info->filename,MagickPathExtent);
4868 (void) CopyMagickString(images->magick,magick_info->name,
4870 (void) CloseBlob(images);
4871 images=GetNextImageInList(images);
4875 clone_info=DestroyImageInfo(clone_info);
4876 blob=(unsigned char *) RelinquishMagickMemory(blob);
4877 (void) RelinquishUniqueFileResource(unique);
4879 blob_info=DestroyImageInfo(blob_info);
4884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4888 + W r i t e B l o b %
4892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4894 % WriteBlob() writes data to a blob or image file. It returns the number of
4897 % The format of the WriteBlob method is:
4899 % ssize_t WriteBlob(Image *image,const size_t length,const void *data)
4901 % A description of each parameter follows:
4903 % o image: the image.
4905 % o length: Specifies an integer representing the number of bytes to
4906 % write to the file.
4908 % o data: The address of the data to write to the blob or file.
4911 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4917 register const unsigned char
4923 assert(image != (Image *) NULL);
4924 assert(image->signature == MagickCoreSignature);
4925 assert(data != (const void *) NULL);
4926 assert(image->blob != (BlobInfo *) NULL);
4927 assert(image->blob->type != UndefinedStream);
4931 p=(const unsigned char *) data;
4932 switch (image->blob->type)
4934 case UndefinedStream:
4936 case StandardStream:
4944 count=(ssize_t) fwrite((const char *) data,1,length,
4945 image->blob->file_info.file);
4950 c=putc((int) *p++,image->blob->file_info.file);
4957 c=putc((int) *p++,image->blob->file_info.file);
4964 c=putc((int) *p++,image->blob->file_info.file);
4971 c=putc((int) *p++,image->blob->file_info.file);
4983 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4988 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4989 (unsigned int) length);
4994 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5001 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5008 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5015 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5028 #if defined(MAGICKCORE_BZLIB_DELEGATE)
5029 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
5036 count=(ssize_t) image->blob->stream(image,data,length);
5041 register unsigned char
5044 if ((image->blob->offset+(MagickOffsetType) length) >=
5045 (MagickOffsetType) image->blob->extent)
5047 if (image->blob->mapped != MagickFalse)
5049 image->blob->extent+=length+image->blob->quantum;
5050 image->blob->quantum<<=1;
5051 image->blob->data=(unsigned char *) ResizeQuantumMemory(
5052 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
5053 (void) SyncBlob(image);
5054 if (image->blob->data == (unsigned char *) NULL)
5056 (void) DetachBlob(image->blob);
5060 q=image->blob->data+image->blob->offset;
5061 (void) memcpy(q,p,length);
5062 image->blob->offset+=length;
5063 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
5064 image->blob->length=(size_t) image->blob->offset;
5065 count=(ssize_t) length;
5070 count=image->blob->user_info->handler((const unsigned char *) data,
5071 length,image->blob->user_info->data);
5079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5083 + W r i t e B l o b B y t e %
5087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5089 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
5090 % written (either 0 or 1);
5092 % The format of the WriteBlobByte method is:
5094 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
5096 % A description of each parameter follows.
5098 % o image: the image.
5100 % o value: Specifies the value to write.
5103 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
5105 assert(image != (Image *) NULL);
5106 assert(image->signature == MagickCoreSignature);
5107 return(WriteBlobStream(image,1,&value));
5111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5115 + W r i t e B l o b F l o a t %
5119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5121 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
5122 % specified by the endian member of the image structure.
5124 % The format of the WriteBlobFloat method is:
5126 % ssize_t WriteBlobFloat(Image *image,const float value)
5128 % A description of each parameter follows.
5130 % o image: the image.
5132 % o value: Specifies the value to write.
5135 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
5146 quantum.unsigned_value=0U;
5147 quantum.float_value=value;
5148 return(WriteBlobLong(image,quantum.unsigned_value));
5152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5156 + W r i t e B l o b L o n g %
5160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5162 % WriteBlobLong() writes a unsigned int value as a 32-bit quantity in the
5163 % byte-order specified by the endian member of the image structure.
5165 % The format of the WriteBlobLong method is:
5167 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
5169 % A description of each parameter follows.
5171 % o image: the image.
5173 % o value: Specifies the value to write.
5176 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
5181 assert(image != (Image *) NULL);
5182 assert(image->signature == MagickCoreSignature);
5183 if (image->endian == LSBEndian)
5185 buffer[0]=(unsigned char) value;
5186 buffer[1]=(unsigned char) (value >> 8);
5187 buffer[2]=(unsigned char) (value >> 16);
5188 buffer[3]=(unsigned char) (value >> 24);
5189 return(WriteBlobStream(image,4,buffer));
5191 buffer[0]=(unsigned char) (value >> 24);
5192 buffer[1]=(unsigned char) (value >> 16);
5193 buffer[2]=(unsigned char) (value >> 8);
5194 buffer[3]=(unsigned char) value;
5195 return(WriteBlobStream(image,4,buffer));
5199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5203 + W r i t e B l o b S h o r t %
5207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5209 % WriteBlobShort() writes a short value as a 16-bit quantity in the
5210 % byte-order specified by the endian member of the image structure.
5212 % The format of the WriteBlobShort method is:
5214 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
5216 % A description of each parameter follows.
5218 % o image: the image.
5220 % o value: Specifies the value to write.
5223 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
5228 assert(image != (Image *) NULL);
5229 assert(image->signature == MagickCoreSignature);
5230 if (image->endian == LSBEndian)
5232 buffer[0]=(unsigned char) value;
5233 buffer[1]=(unsigned char) (value >> 8);
5234 return(WriteBlobStream(image,2,buffer));
5236 buffer[0]=(unsigned char) (value >> 8);
5237 buffer[1]=(unsigned char) value;
5238 return(WriteBlobStream(image,2,buffer));
5242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5246 + W r i t e B l o b L S B L o n g %
5250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5252 % WriteBlobLSBLong() writes a unsigned int value as a 32-bit quantity in
5253 % least-significant byte first order.
5255 % The format of the WriteBlobLSBLong method is:
5257 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5259 % A description of each parameter follows.
5261 % o image: the image.
5263 % o value: Specifies the value to write.
5266 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5271 assert(image != (Image *) NULL);
5272 assert(image->signature == MagickCoreSignature);
5273 buffer[0]=(unsigned char) value;
5274 buffer[1]=(unsigned char) (value >> 8);
5275 buffer[2]=(unsigned char) (value >> 16);
5276 buffer[3]=(unsigned char) (value >> 24);
5277 return(WriteBlobStream(image,4,buffer));
5281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5285 + W r i t e B l o b L S B S h o r t %
5289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5291 % WriteBlobLSBShort() writes a unsigned short value as a 16-bit quantity in
5292 % least-significant byte first order.
5294 % The format of the WriteBlobLSBShort method is:
5296 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5298 % A description of each parameter follows.
5300 % o image: the image.
5302 % o value: Specifies the value to write.
5305 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5310 assert(image != (Image *) NULL);
5311 assert(image->signature == MagickCoreSignature);
5312 buffer[0]=(unsigned char) value;
5313 buffer[1]=(unsigned char) (value >> 8);
5314 return(WriteBlobStream(image,2,buffer));
5318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5322 + W r i t e B l o b L S B S i g n e d L o n g %
5326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5328 % WriteBlobLSBSignedLong() writes a signed value as a 32-bit quantity in
5329 % least-significant byte first order.
5331 % The format of the WriteBlobLSBSignedLong method is:
5333 % ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5335 % A description of each parameter follows.
5337 % o image: the image.
5339 % o value: Specifies the value to write.
5342 MagickExport ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5356 assert(image != (Image *) NULL);
5357 assert(image->signature == MagickCoreSignature);
5358 quantum.signed_value=value;
5359 buffer[0]=(unsigned char) quantum.unsigned_value;
5360 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5361 buffer[2]=(unsigned char) (quantum.unsigned_value >> 16);
5362 buffer[3]=(unsigned char) (quantum.unsigned_value >> 24);
5363 return(WriteBlobStream(image,4,buffer));
5367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5371 + W r i t e B l o b L S B S i g n e d S h o r t %
5375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5377 % WriteBlobLSBSignedShort() writes a signed short value as a 16-bit quantity
5378 % in least-significant byte first order.
5380 % The format of the WriteBlobLSBSignedShort method is:
5382 % ssize_t WriteBlobLSBSignedShort(Image *image,const signed short value)
5384 % A description of each parameter follows.
5386 % o image: the image.
5388 % o value: Specifies the value to write.
5391 MagickExport ssize_t WriteBlobLSBSignedShort(Image *image,
5392 const signed short value)
5406 assert(image != (Image *) NULL);
5407 assert(image->signature == MagickCoreSignature);
5408 quantum.signed_value=value;
5409 buffer[0]=(unsigned char) quantum.unsigned_value;
5410 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5411 return(WriteBlobStream(image,2,buffer));
5415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5419 + W r i t e B l o b M S B L o n g %
5423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5425 % WriteBlobMSBLong() writes a unsigned int value as a 32-bit quantity in
5426 % most-significant byte first order.
5428 % The format of the WriteBlobMSBLong method is:
5430 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5432 % A description of each parameter follows.
5434 % o value: Specifies the value to write.
5436 % o image: the image.
5439 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5444 assert(image != (Image *) NULL);
5445 assert(image->signature == MagickCoreSignature);
5446 buffer[0]=(unsigned char) (value >> 24);
5447 buffer[1]=(unsigned char) (value >> 16);
5448 buffer[2]=(unsigned char) (value >> 8);
5449 buffer[3]=(unsigned char) value;
5450 return(WriteBlobStream(image,4,buffer));
5454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5458 + W r i t e B l o b M S B L o n g L o n g %
5462 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5464 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
5465 % most-significant byte first order.
5467 % The format of the WriteBlobMSBLongLong method is:
5469 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
5471 % A description of each parameter follows.
5473 % o value: Specifies the value to write.
5475 % o image: the image.
5478 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
5479 const MagickSizeType value)
5484 assert(image != (Image *) NULL);
5485 assert(image->signature == MagickCoreSignature);
5486 buffer[0]=(unsigned char) (value >> 56);
5487 buffer[1]=(unsigned char) (value >> 48);
5488 buffer[2]=(unsigned char) (value >> 40);
5489 buffer[3]=(unsigned char) (value >> 32);
5490 buffer[4]=(unsigned char) (value >> 24);
5491 buffer[5]=(unsigned char) (value >> 16);
5492 buffer[6]=(unsigned char) (value >> 8);
5493 buffer[7]=(unsigned char) value;
5494 return(WriteBlobStream(image,8,buffer));
5498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5502 + W r i t e B l o b M S B S i g n e d L o n g %
5506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5508 % WriteBlobMSBSignedLong() writes a signed value as a 32-bit quantity in
5509 % most-significant byte first order.
5511 % The format of the WriteBlobMSBSignedLong method is:
5513 % ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5515 % A description of each parameter follows.
5517 % o image: the image.
5519 % o value: Specifies the value to write.
5522 MagickExport ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5536 assert(image != (Image *) NULL);
5537 assert(image->signature == MagickCoreSignature);
5538 quantum.signed_value=value;
5539 buffer[0]=(unsigned char) (quantum.unsigned_value >> 24);
5540 buffer[1]=(unsigned char) (quantum.unsigned_value >> 16);
5541 buffer[2]=(unsigned char) (quantum.unsigned_value >> 8);
5542 buffer[3]=(unsigned char) quantum.unsigned_value;
5543 return(WriteBlobStream(image,4,buffer));
5547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5551 + W r i t e B l o b M S B S i g n e d S h o r t %
5555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5557 % WriteBlobMSBSignedShort() writes a signed short value as a 16-bit quantity
5558 % in most-significant byte first order.
5560 % The format of the WriteBlobMSBSignedShort method is:
5562 % ssize_t WriteBlobMSBSignedShort(Image *image,const signed 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 WriteBlobMSBSignedShort(Image *image,
5572 const signed short value)
5586 assert(image != (Image *) NULL);
5587 assert(image->signature == MagickCoreSignature);
5588 quantum.signed_value=value;
5589 buffer[0]=(unsigned char) (quantum.unsigned_value >> 8);
5590 buffer[1]=(unsigned char) quantum.unsigned_value;
5591 return(WriteBlobStream(image,2,buffer));
5595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5599 + W r i t e B l o b M S B S h o r t %
5603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5605 % WriteBlobMSBShort() writes a unsigned short value as a 16-bit quantity in
5606 % most-significant byte first order.
5608 % The format of the WriteBlobMSBShort method is:
5610 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5612 % A description of each parameter follows.
5614 % o value: Specifies the value to write.
5616 % o file: Specifies the file to write the data to.
5619 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5624 assert(image != (Image *) NULL);
5625 assert(image->signature == MagickCoreSignature);
5626 buffer[0]=(unsigned char) (value >> 8);
5627 buffer[1]=(unsigned char) value;
5628 return(WriteBlobStream(image,2,buffer));
5632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5636 + W r i t e B l o b S t r i n g %
5640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5642 % WriteBlobString() write a string to a blob. It returns the number of
5643 % characters written.
5645 % The format of the WriteBlobString method is:
5647 % ssize_t WriteBlobString(Image *image,const char *string)
5649 % A description of each parameter follows.
5651 % o image: the image.
5653 % o string: Specifies the string to write.
5656 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
5658 assert(image != (Image *) NULL);
5659 assert(image->signature == MagickCoreSignature);
5660 assert(string != (const char *) NULL);
5661 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));