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->reader != (BlobHandler) NULL);
1681 assert(user_info->writer != (BlobHandler) NULL);
1682 assert(exception != (ExceptionInfo *) NULL);
1683 blob_info=CloneImageInfo(image_info);
1684 blob_info->adjoin=MagickFalse;
1685 blob_info->user_info=user_info;
1686 (void) SetImageInfo(blob_info,1,exception);
1687 if (*blob_info->magick != '\0')
1688 (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
1689 magick_info=GetMagickInfo(image->magick,exception);
1690 if (magick_info == (const MagickInfo *) NULL)
1692 (void) ThrowMagickException(exception,GetMagickModule(),
1693 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1695 blob_info=DestroyImageInfo(blob_info);
1698 (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
1699 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1702 Native blob support for this image format.
1704 (void) CloseBlob(image);
1705 *image->filename='\0';
1706 (void) WriteImage(blob_info,image,exception);
1707 (void) CloseBlob(image);
1712 unique[MagickPathExtent];
1721 Write file to disk in blob image format.
1723 blob_info->user_info=(UserBlobInfo *) NULL;
1724 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
1726 if (blob == (unsigned char *) NULL)
1728 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1729 image_info->filename);
1730 blob_info=DestroyImageInfo(blob_info);
1733 file=AcquireUniqueFileResource(unique);
1736 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1737 image_info->filename);
1738 blob=(unsigned char *) RelinquishMagickMemory(blob);
1739 blob_info=DestroyImageInfo(blob_info);
1742 blob_info->file=fdopen(file,"wb+");
1743 if (blob_info->file != (FILE *) NULL)
1748 (void) FormatLocaleString(image->filename,MagickPathExtent,
1749 "%s:%s",image->magick,unique);
1750 status=WriteImage(blob_info,image,exception);
1751 (void) CloseBlob(image);
1752 if (status != MagickFalse)
1754 (void) fseek(blob_info->file,0,SEEK_SET);
1755 count=(ssize_t) MagickMaxBufferExtent;
1756 while (count == (ssize_t) MagickMaxBufferExtent)
1758 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
1760 user_info->writer(blob,count,user_info->data);
1763 (void) fclose(blob_info->file);
1765 blob=(unsigned char *) RelinquishMagickMemory(blob);
1766 (void) RelinquishUniqueFileResource(unique);
1768 blob_info=DestroyImageInfo(blob_info);
1772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1776 % I m a g e T o F i l e %
1780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1782 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1783 % occurs otherwise MagickTrue.
1785 % The format of the ImageToFile method is:
1787 % MagickBooleanType ImageToFile(Image *image,char *filename,
1788 % ExceptionInfo *exception)
1790 % A description of each parameter follows:
1792 % o image: the image.
1794 % o filename: Write the image to this file.
1796 % o exception: return any errors or warnings in this structure.
1799 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1800 ExceptionInfo *exception)
1805 register const unsigned char
1824 assert(image != (Image *) NULL);
1825 assert(image->signature == MagickCoreSignature);
1826 assert(image->blob != (BlobInfo *) NULL);
1827 assert(image->blob->type != UndefinedStream);
1828 if (image->debug != MagickFalse)
1829 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1830 assert(filename != (const char *) NULL);
1831 if (*filename == '\0')
1832 file=AcquireUniqueFileResource(filename);
1834 if (LocaleCompare(filename,"-") == 0)
1835 file=fileno(stdout);
1837 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1840 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1841 return(MagickFalse);
1843 quantum=(size_t) MagickMaxBufferExtent;
1844 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
1845 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1846 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1847 if (buffer == (unsigned char *) NULL)
1850 (void) ThrowMagickException(exception,GetMagickModule(),
1851 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1852 return(MagickFalse);
1855 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1856 for (i=0; count > 0; )
1858 length=(size_t) count;
1859 for (i=0; i < length; i+=count)
1861 count=write(file,p+i,(size_t) (length-i));
1871 p=(const unsigned char *) ReadBlobStream(image,quantum,buffer,&count);
1873 if (LocaleCompare(filename,"-") != 0)
1875 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1876 if ((file == -1) || (i < length))
1880 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1881 return(MagickFalse);
1887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1891 % I m a g e s T o B l o b %
1895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1897 % ImagesToBlob() implements direct to memory image formats. It returns the
1898 % image sequence as a blob and its length. The magick member of the ImageInfo
1899 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1901 % Note, some image formats do not permit multiple images to the same image
1902 % stream (e.g. JPEG). in this instance, just the first image of the
1903 % sequence is returned as a blob.
1905 % The format of the ImagesToBlob method is:
1907 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1908 % size_t *length,ExceptionInfo *exception)
1910 % A description of each parameter follows:
1912 % o image_info: the image info.
1914 % o images: the image list.
1916 % o length: return the actual length of the blob.
1918 % o exception: return any errors or warnings in this structure.
1921 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1922 size_t *length,ExceptionInfo *exception)
1936 assert(image_info != (const ImageInfo *) NULL);
1937 assert(image_info->signature == MagickCoreSignature);
1938 if (image_info->debug != MagickFalse)
1939 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1940 image_info->filename);
1941 assert(images != (Image *) NULL);
1942 assert(images->signature == MagickCoreSignature);
1943 assert(exception != (ExceptionInfo *) NULL);
1945 blob=(unsigned char *) NULL;
1946 blob_info=CloneImageInfo(image_info);
1947 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1949 if (*blob_info->magick != '\0')
1950 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
1951 magick_info=GetMagickInfo(images->magick,exception);
1952 if (magick_info == (const MagickInfo *) NULL)
1954 (void) ThrowMagickException(exception,GetMagickModule(),
1955 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1957 blob_info=DestroyImageInfo(blob_info);
1960 if (GetMagickAdjoin(magick_info) == MagickFalse)
1962 blob_info=DestroyImageInfo(blob_info);
1963 return(ImageToBlob(image_info,images,length,exception));
1965 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
1966 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1969 Native blob support for this images format.
1971 blob_info->length=0;
1972 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1973 sizeof(unsigned char));
1974 if (blob_info->blob == (void *) NULL)
1975 (void) ThrowMagickException(exception,GetMagickModule(),
1976 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1979 (void) CloseBlob(images);
1980 images->blob->exempt=MagickTrue;
1981 *images->filename='\0';
1982 status=WriteImages(blob_info,images,images->filename,exception);
1983 *length=images->blob->length;
1984 blob=DetachBlob(images->blob);
1985 if (status == MagickFalse)
1986 blob=RelinquishMagickMemory(blob);
1988 blob=ResizeQuantumMemory(blob,*length+1,sizeof(unsigned char));
1994 filename[MagickPathExtent],
1995 unique[MagickPathExtent];
2001 Write file to disk in blob images format.
2003 file=AcquireUniqueFileResource(unique);
2006 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
2007 image_info->filename);
2011 blob_info->file=fdopen(file,"wb");
2012 if (blob_info->file != (FILE *) NULL)
2014 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2015 images->magick,unique);
2016 status=WriteImages(blob_info,images,filename,exception);
2017 (void) CloseBlob(images);
2018 (void) fclose(blob_info->file);
2019 if (status != MagickFalse)
2020 blob=FileToBlob(unique,~0UL,length,exception);
2022 (void) RelinquishUniqueFileResource(unique);
2025 blob_info=DestroyImageInfo(blob_info);
2030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2034 + I m a g e s T o U s e r B l o b %
2038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2040 % ImagesToUserBlob() is the equivalent of WriteImages(), but writes the
2041 % formatted "file" to the suplied method rather than to an actual file.
2043 % The format of the ImageToUserBlob method is:
2045 % void ImagesToUserBlob(const ImageInfo *image_info,Image *images,
2046 % UserBlobInfo *user_info,ExceptionInfo *exception)
2048 % A description of each parameter follows:
2050 % o image_info: the image info.
2052 % o images: the image list.
2054 % o user_info: the methods to use when writing and seeking.
2056 % o exception: return any errors or warnings in this structure.
2059 MagickExport void ImagesToUserBlob(const ImageInfo *image_info,Image *images,
2060 UserBlobInfo *user_info,ExceptionInfo *exception)
2071 assert(image_info != (const ImageInfo *) NULL);
2072 assert(image_info->signature == MagickCoreSignature);
2073 if (image_info->debug != MagickFalse)
2074 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2075 image_info->filename);
2076 assert(images != (Image *) NULL);
2077 assert(images->signature == MagickCoreSignature);
2078 assert(user_info != (UserBlobInfo *) NULL);
2079 assert(user_info->reader != (BlobHandler) NULL);
2080 assert(user_info->writer != (BlobHandler) NULL);
2081 assert(exception != (ExceptionInfo *) NULL);
2082 blob_info=CloneImageInfo(image_info);
2083 blob_info->user_info=user_info;
2084 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
2086 if (*blob_info->magick != '\0')
2087 (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
2088 magick_info=GetMagickInfo(images->magick,exception);
2089 if (magick_info == (const MagickInfo *) NULL)
2091 (void) ThrowMagickException(exception,GetMagickModule(),
2092 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
2094 blob_info=DestroyImageInfo(blob_info);
2097 (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
2098 if (GetMagickBlobSupport(magick_info) != MagickFalse)
2101 Native blob support for this image format.
2103 (void) CloseBlob(images);
2104 *images->filename='\0';
2105 (void) WriteImages(blob_info,images,images->filename,exception);
2106 (void) CloseBlob(images);
2111 filename[MagickPathExtent],
2112 unique[MagickPathExtent];
2121 Write file to disk in blob image format.
2123 blob_info->user_info=(UserBlobInfo *) NULL;
2124 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
2126 if (blob == (unsigned char *) NULL)
2128 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2129 image_info->filename);
2130 blob_info=DestroyImageInfo(blob_info);
2133 file=AcquireUniqueFileResource(unique);
2136 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
2137 image_info->filename);
2138 blob=(unsigned char *) RelinquishMagickMemory(blob);
2139 blob_info=DestroyImageInfo(blob_info);
2142 blob_info->file=fdopen(file,"wb+");
2143 if (blob_info->file != (FILE *) NULL)
2148 (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
2149 images->magick,unique);
2150 status=WriteImages(blob_info,images,filename,exception);
2151 (void) CloseBlob(images);
2152 if (status != MagickFalse)
2154 (void) fseek(blob_info->file,0,SEEK_SET);
2155 count=(ssize_t) MagickMaxBufferExtent;
2156 while (count == (ssize_t) MagickMaxBufferExtent)
2158 count=(ssize_t) fread(blob,sizeof(*blob),MagickMaxBufferExtent,
2160 user_info->writer(blob,count,user_info->data);
2163 (void) fclose(blob_info->file);
2165 blob=(unsigned char *) RelinquishMagickMemory(blob);
2166 (void) RelinquishUniqueFileResource(unique);
2168 blob_info=DestroyImageInfo(blob_info);
2173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2177 % I n j e c t I m a g e B l o b %
2181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2183 % InjectImageBlob() injects the image with a copy of itself in the specified
2184 % format (e.g. inject JPEG into a PDF image).
2186 % The format of the InjectImageBlob method is:
2188 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2189 % Image *image,Image *inject_image,const char *format,
2190 % ExceptionInfo *exception)
2192 % A description of each parameter follows:
2194 % o image_info: the image info..
2196 % o image: the image.
2198 % o inject_image: inject into the image stream.
2200 % o format: the image format.
2202 % o exception: return any errors or warnings in this structure.
2205 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
2206 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
2209 filename[MagickPathExtent];
2242 Write inject image to a temporary file.
2244 assert(image_info != (ImageInfo *) NULL);
2245 assert(image_info->signature == MagickCoreSignature);
2246 assert(image != (Image *) NULL);
2247 assert(image->signature == MagickCoreSignature);
2248 if (image->debug != MagickFalse)
2249 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2250 assert(inject_image != (Image *) NULL);
2251 assert(inject_image->signature == MagickCoreSignature);
2252 assert(exception != (ExceptionInfo *) NULL);
2253 unique_file=(FILE *) NULL;
2254 file=AcquireUniqueFileResource(filename);
2256 unique_file=fdopen(file,"wb");
2257 if ((file == -1) || (unique_file == (FILE *) NULL))
2259 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2260 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
2262 return(MagickFalse);
2264 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
2265 if (byte_image == (Image *) NULL)
2267 (void) fclose(unique_file);
2268 (void) RelinquishUniqueFileResource(filename);
2269 return(MagickFalse);
2271 (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",format,
2273 DestroyBlob(byte_image);
2274 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
2275 write_info=CloneImageInfo(image_info);
2276 SetImageInfoFile(write_info,unique_file);
2277 status=WriteImage(write_info,byte_image,exception);
2278 write_info=DestroyImageInfo(write_info);
2279 byte_image=DestroyImage(byte_image);
2280 (void) fclose(unique_file);
2281 if (status == MagickFalse)
2283 (void) RelinquishUniqueFileResource(filename);
2284 return(MagickFalse);
2287 Inject into image stream.
2289 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
2292 (void) RelinquishUniqueFileResource(filename);
2293 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
2294 image_info->filename);
2295 return(MagickFalse);
2297 quantum=(size_t) MagickMaxBufferExtent;
2298 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
2299 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2300 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2301 if (buffer == (unsigned char *) NULL)
2303 (void) RelinquishUniqueFileResource(filename);
2305 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2308 for (i=0; ; i+=count)
2310 count=read(file,buffer,quantum);
2317 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2322 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2323 (void) RelinquishUniqueFileResource(filename);
2324 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2333 % I s B l o b E x e m p t %
2337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2339 % IsBlobExempt() returns true if the blob is exempt.
2341 % The format of the IsBlobExempt method is:
2343 % MagickBooleanType IsBlobExempt(const Image *image)
2345 % A description of each parameter follows:
2347 % o image: the image.
2350 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
2352 assert(image != (const Image *) NULL);
2353 assert(image->signature == MagickCoreSignature);
2354 if (image->debug != MagickFalse)
2355 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2356 return(image->blob->exempt);
2360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2364 % I s B l o b S e e k a b l e %
2368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2370 % IsBlobSeekable() returns true if the blob is seekable.
2372 % The format of the IsBlobSeekable method is:
2374 % MagickBooleanType IsBlobSeekable(const Image *image)
2376 % A description of each parameter follows:
2378 % o image: the image.
2381 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2386 assert(image != (const Image *) NULL);
2387 assert(image->signature == MagickCoreSignature);
2388 if (image->debug != MagickFalse)
2389 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2390 switch (image->blob->type)
2396 seekable=MagickTrue;
2399 case UndefinedStream:
2400 case StandardStream:
2406 seekable=MagickFalse;
2411 if ((image->blob->user_info->seeker != (BlobSeeker) NULL) &&
2412 (image->blob->user_info->teller != (BlobTeller) NULL))
2413 seekable=MagickTrue;
2415 seekable=MagickFalse;
2423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2427 % I s B l o b T e m p o r a r y %
2431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2433 % IsBlobTemporary() returns true if the blob is temporary.
2435 % The format of the IsBlobTemporary method is:
2437 % MagickBooleanType IsBlobTemporary(const Image *image)
2439 % A description of each parameter follows:
2441 % o image: the image.
2444 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2446 assert(image != (const Image *) NULL);
2447 assert(image->signature == MagickCoreSignature);
2448 if (image->debug != MagickFalse)
2449 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2450 return(image->blob->temporary);
2454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2462 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2464 % MapBlob() creates a mapping from a file to a binary large object.
2466 % The format of the MapBlob method is:
2468 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2469 % const size_t length)
2471 % A description of each parameter follows:
2473 % o file: map this file descriptor.
2475 % o mode: ReadMode, WriteMode, or IOMode.
2477 % o offset: starting at this offset within the file.
2479 % o length: the length of the mapping is returned in this pointer.
2482 MagickExport void *MapBlob(int file,const MapMode mode,
2483 const MagickOffsetType offset,const size_t length)
2485 #if defined(MAGICKCORE_HAVE_MMAP)
2498 #if defined(MAP_ANONYMOUS)
2499 flags|=MAP_ANONYMOUS;
2508 protection=PROT_READ;
2514 protection=PROT_WRITE;
2520 protection=PROT_READ | PROT_WRITE;
2525 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2526 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2528 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2530 if (map == MAP_FAILED)
2531 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2533 if (map == MAP_FAILED)
2546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2550 + M S B O r d e r L o n g %
2554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2556 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2557 % most-significant byte first.
2559 % The format of the MSBOrderLong method is:
2561 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2563 % A description of each parameter follows.
2565 % o buffer: Specifies a pointer to a buffer of integers.
2567 % o length: Specifies the length of the buffer.
2570 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2575 register unsigned char
2579 assert(buffer != (unsigned char *) NULL);
2586 *buffer++=(unsigned char) c;
2590 *buffer++=(unsigned char) c;
2596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2600 + M S B O r d e r S h o r t %
2604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2606 % MSBOrderShort() converts a least-significant byte first buffer of integers
2607 % to most-significant byte first.
2609 % The format of the MSBOrderShort method is:
2611 % void MSBOrderShort(unsigned char *p,const size_t length)
2613 % A description of each parameter follows.
2615 % o p: Specifies a pointer to a buffer of integers.
2617 % o length: Specifies the length of the buffer.
2620 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2625 register unsigned char
2628 assert(p != (unsigned char *) NULL);
2635 *p++=(unsigned char) c;
2640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2650 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2651 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2652 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2653 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2654 % from a system command.
2656 % The format of the OpenBlob method is:
2658 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2659 % const BlobMode mode,ExceptionInfo *exception)
2661 % A description of each parameter follows:
2663 % o image_info: the image info.
2665 % o image: the image.
2667 % o mode: the mode for opening the file.
2671 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2684 option=GetImageOption(image_info,"stream:buffer-size");
2685 if (option != (const char *) NULL)
2686 size=StringToUnsignedLong(option);
2687 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2688 _IONBF : _IOFBF,size);
2689 return(status == 0 ? MagickTrue : MagickFalse);
2692 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2693 Image *image,const BlobMode mode,ExceptionInfo *exception)
2696 extension[MagickPathExtent],
2697 filename[MagickPathExtent];
2708 assert(image_info != (ImageInfo *) NULL);
2709 assert(image_info->signature == MagickCoreSignature);
2710 if (image_info->debug != MagickFalse)
2711 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2712 image_info->filename);
2713 assert(image != (Image *) NULL);
2714 assert(image->signature == MagickCoreSignature);
2715 if (image_info->blob != (void *) NULL)
2717 if (image_info->stream != (StreamHandler) NULL)
2718 image->blob->stream=(StreamHandler) image_info->stream;
2719 AttachBlob(image->blob,image_info->blob,image_info->length);
2722 if (image_info->user_info != (UserBlobInfo *) NULL)
2724 image->blob->type=UserStream;
2725 image->blob->user_info=image_info->user_info;
2728 (void) DetachBlob(image->blob);
2731 default: type="r"; break;
2732 case ReadBlobMode: type="r"; break;
2733 case ReadBinaryBlobMode: type="rb"; break;
2734 case WriteBlobMode: type="w"; break;
2735 case WriteBinaryBlobMode: type="w+b"; break;
2736 case AppendBlobMode: type="a"; break;
2737 case AppendBinaryBlobMode: type="a+b"; break;
2740 image->blob->synchronize=image_info->synchronize;
2741 if (image_info->stream != (StreamHandler) NULL)
2743 image->blob->stream=(StreamHandler) image_info->stream;
2746 image->blob->type=FifoStream;
2754 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2755 rights=ReadPolicyRights;
2757 rights=WritePolicyRights;
2758 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2761 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2762 "NotAuthorized","`%s'",filename);
2763 return(MagickFalse);
2765 if ((LocaleCompare(filename,"-") == 0) ||
2766 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2768 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2769 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2770 if (strchr(type,'b') != (char *) NULL)
2771 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2773 image->blob->type=StandardStream;
2774 image->blob->exempt=MagickTrue;
2775 return(SetStreamBuffering(image_info,image));
2777 if (LocaleNCompare(filename,"fd:",3) == 0)
2780 fileMode[MagickPathExtent];
2784 image->blob->file_info.file=fdopen(StringToLong(filename+3),fileMode);
2785 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2786 if (strchr(type,'b') != (char *) NULL)
2787 setmode(fileno(image->blob->file_info.file),_O_BINARY);
2789 image->blob->type=StandardStream;
2790 image->blob->exempt=MagickTrue;
2791 return(SetStreamBuffering(image_info,image));
2793 #if defined(MAGICKCORE_HAVE_POPEN) && defined(MAGICKCORE_PIPES_SUPPORT)
2794 if (*filename == '|')
2797 fileMode[MagickPathExtent],
2801 Pipe image to or from a system command.
2803 #if defined(SIGPIPE)
2805 (void) signal(SIGPIPE,SIG_IGN);
2809 sanitize_command=SanitizeString(filename+1);
2810 image->blob->file_info.file=(FILE *) popen_utf8(sanitize_command,
2812 sanitize_command=DestroyString(sanitize_command);
2813 if (image->blob->file_info.file == (FILE *) NULL)
2815 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2816 return(MagickFalse);
2818 image->blob->type=PipeStream;
2819 image->blob->exempt=MagickTrue;
2820 return(SetStreamBuffering(image_info,image));
2823 status=GetPathAttributes(filename,&image->blob->properties);
2824 #if defined(S_ISFIFO)
2825 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2827 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2828 if (image->blob->file_info.file == (FILE *) NULL)
2830 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2831 return(MagickFalse);
2833 image->blob->type=FileStream;
2834 image->blob->exempt=MagickTrue;
2835 return(SetStreamBuffering(image_info,image));
2838 GetPathComponent(image->filename,ExtensionPath,extension);
2841 (void) CopyMagickString(filename,image->filename,MagickPathExtent);
2842 if ((image_info->adjoin == MagickFalse) ||
2843 (strchr(filename,'%') != (char *) NULL))
2846 Form filename for multi-part images.
2848 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2849 image->scene,filename,exception);
2850 if ((LocaleCompare(filename,image->filename) == 0) &&
2851 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2852 (GetNextImageInList(image) != (Image *) NULL)))
2855 path[MagickPathExtent];
2857 GetPathComponent(image->filename,RootPath,path);
2858 if (*extension == '\0')
2859 (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
2860 path,(double) image->scene);
2862 (void) FormatLocaleString(filename,MagickPathExtent,
2863 "%s-%.20g.%s",path,(double) image->scene,extension);
2865 (void) CopyMagickString(image->filename,filename,MagickPathExtent);
2866 #if defined(macintosh)
2867 SetApplicationType(filename,image_info->magick,'8BIM');
2871 if (image_info->file != (FILE *) NULL)
2873 image->blob->file_info.file=image_info->file;
2874 image->blob->type=FileStream;
2875 image->blob->exempt=MagickTrue;
2880 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2881 if (image->blob->file_info.file != (FILE *) NULL)
2889 image->blob->type=FileStream;
2890 (void) SetStreamBuffering(image_info,image);
2891 (void) ResetMagickMemory(magick,0,sizeof(magick));
2892 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2893 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2894 #if defined(MAGICKCORE_POSIX_SUPPORT)
2895 (void) fflush(image->blob->file_info.file);
2897 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2898 " read %.20g magic header bytes",(double) count);
2899 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2900 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2901 ((int) magick[2] == 0x08))
2903 if (image->blob->file_info.file != (FILE *) NULL)
2904 (void) fclose(image->blob->file_info.file);
2905 image->blob->file_info.file=(FILE *) NULL;
2906 image->blob->file_info.gzfile=gzopen(filename,type);
2907 if (image->blob->file_info.gzfile != (gzFile) NULL)
2908 image->blob->type=ZipStream;
2911 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2912 if (strncmp((char *) magick,"BZh",3) == 0)
2914 if (image->blob->file_info.file != (FILE *) NULL)
2915 (void) fclose(image->blob->file_info.file);
2916 image->blob->file_info.file=(FILE *) NULL;
2917 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2918 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2919 image->blob->type=BZipStream;
2922 if (image->blob->type == FileStream)
2933 sans_exception=AcquireExceptionInfo();
2934 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2935 sans_exception=DestroyExceptionInfo(sans_exception);
2936 length=(size_t) image->blob->properties.st_size;
2937 if ((magick_info != (const MagickInfo *) NULL) &&
2938 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2939 (length > MagickMaxBufferExtent) &&
2940 (AcquireMagickResource(MapResource,length) != MagickFalse))
2945 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
2947 if (blob == (void *) NULL)
2948 RelinquishMagickResource(MapResource,length);
2952 Format supports blobs-- use memory-mapped I/O.
2954 if (image_info->file != (FILE *) NULL)
2955 image->blob->exempt=MagickFalse;
2958 (void) fclose(image->blob->file_info.file);
2959 image->blob->file_info.file=(FILE *) NULL;
2961 AttachBlob(image->blob,blob,length);
2962 image->blob->mapped=MagickTrue;
2969 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2970 if ((LocaleCompare(extension,"Z") == 0) ||
2971 (LocaleCompare(extension,"gz") == 0) ||
2972 (LocaleCompare(extension,"wmz") == 0) ||
2973 (LocaleCompare(extension,"svgz") == 0))
2975 if (mode == WriteBinaryBlobMode)
2977 image->blob->file_info.gzfile=gzopen(filename,type);
2978 if (image->blob->file_info.gzfile != (gzFile) NULL)
2979 image->blob->type=ZipStream;
2983 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2984 if (LocaleCompare(extension,"bz2") == 0)
2986 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2987 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2988 image->blob->type=BZipStream;
2993 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2994 if (image->blob->file_info.file != (FILE *) NULL)
2996 image->blob->type=FileStream;
2997 (void) SetStreamBuffering(image_info,image);
3000 image->blob->status=MagickFalse;
3001 if (image->blob->type != UndefinedStream)
3002 image->blob->size=GetBlobSize(image);
3005 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
3006 return(MagickFalse);
3012 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3020 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3022 % PingBlob() returns all the attributes of an image or image sequence except
3023 % for the pixels. It is much faster and consumes far less memory than
3024 % BlobToImage(). On failure, a NULL image is returned and exception
3025 % describes the reason for the failure.
3027 % The format of the PingBlob method is:
3029 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
3030 % const size_t length,ExceptionInfo *exception)
3032 % A description of each parameter follows:
3034 % o image_info: the image info.
3036 % o blob: the address of a character stream in one of the image formats
3037 % understood by ImageMagick.
3039 % o length: This size_t integer reflects the length in bytes of the blob.
3041 % o exception: return any errors or warnings in this structure.
3045 #if defined(__cplusplus) || defined(c_plusplus)
3049 static size_t PingStream(const Image *magick_unused(image),
3050 const void *magick_unused(pixels),const size_t columns)
3052 magick_unreferenced(image);
3053 magick_unreferenced(pixels);
3057 #if defined(__cplusplus) || defined(c_plusplus)
3061 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
3062 const size_t length,ExceptionInfo *exception)
3070 assert(image_info != (ImageInfo *) NULL);
3071 assert(image_info->signature == MagickCoreSignature);
3072 if (image_info->debug != MagickFalse)
3073 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3074 image_info->filename);
3075 assert(exception != (ExceptionInfo *) NULL);
3076 if ((blob == (const void *) NULL) || (length == 0))
3078 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
3079 "UnrecognizedImageFormat","`%s'",image_info->magick);
3080 return((Image *) NULL);
3082 ping_info=CloneImageInfo(image_info);
3083 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
3084 if (ping_info->blob == (const void *) NULL)
3086 (void) ThrowMagickException(exception,GetMagickModule(),
3087 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
3088 return((Image *) NULL);
3090 (void) memcpy(ping_info->blob,blob,length);
3091 ping_info->length=length;
3092 ping_info->ping=MagickTrue;
3093 image=ReadStream(ping_info,&PingStream,exception);
3094 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
3095 ping_info=DestroyImageInfo(ping_info);
3100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3110 % ReadBlob() reads data from the blob or image file and returns it. It
3111 % returns the number of bytes read. If length is zero, ReadBlob() returns
3112 % zero and has no other results. If length is greater than SSIZE_MAX, the
3113 % result is unspecified.
3115 % The format of the ReadBlob method is:
3117 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
3119 % A description of each parameter follows:
3121 % o image: the image.
3123 % o length: Specifies an integer representing the number of bytes to read
3126 % o data: Specifies an area to place the information requested from the
3130 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
3135 register unsigned char
3141 assert(image != (Image *) NULL);
3142 assert(image->signature == MagickCoreSignature);
3143 assert(image->blob != (BlobInfo *) NULL);
3144 assert(image->blob->type != UndefinedStream);
3147 assert(data != (void *) NULL);
3149 q=(unsigned char *) data;
3150 switch (image->blob->type)
3152 case UndefinedStream:
3154 case StandardStream:
3162 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
3167 c=getc(image->blob->file_info.file);
3170 *q++=(unsigned char) c;
3175 c=getc(image->blob->file_info.file);
3178 *q++=(unsigned char) c;
3183 c=getc(image->blob->file_info.file);
3186 *q++=(unsigned char) c;
3191 c=getc(image->blob->file_info.file);
3194 *q++=(unsigned char) c;
3204 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3209 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
3210 (unsigned int) length);
3215 c=gzgetc(image->blob->file_info.gzfile);
3218 *q++=(unsigned char) c;
3223 c=gzgetc(image->blob->file_info.gzfile);
3226 *q++=(unsigned char) c;
3231 c=gzgetc(image->blob->file_info.gzfile);
3234 *q++=(unsigned char) c;
3239 c=gzgetc(image->blob->file_info.gzfile);
3242 *q++=(unsigned char) c;
3253 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3254 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
3262 register const unsigned char
3265 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3267 image->blob->eof=MagickTrue;
3270 p=image->blob->data+image->blob->offset;
3271 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
3272 image->blob->offset+=count;
3273 if (count != (ssize_t) length)
3274 image->blob->eof=MagickTrue;
3275 (void) memcpy(q,p,(size_t) count);
3280 count=image->blob->user_info->reader(q,length,
3281 image->blob->user_info->data);
3289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3293 + R e a d B l o b B y t e %
3297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3299 % ReadBlobByte() reads a single byte from the image file and returns it.
3301 % The format of the ReadBlobByte method is:
3303 % int ReadBlobByte(Image *image)
3305 % A description of each parameter follows.
3307 % o image: the image.
3310 MagickExport int ReadBlobByte(Image *image)
3312 register const unsigned char
3321 assert(image != (Image *) NULL);
3322 assert(image->signature == MagickCoreSignature);
3323 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
3330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3334 + R e a d B l o b D o u b l e %
3338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3340 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3341 % specified by the endian member of the image structure.
3343 % The format of the ReadBlobDouble method is:
3345 % double ReadBlobDouble(Image *image)
3347 % A description of each parameter follows.
3349 % o image: the image.
3352 MagickExport double ReadBlobDouble(Image *image)
3363 quantum.double_value=0.0;
3364 quantum.unsigned_value=ReadBlobLongLong(image);
3365 return(quantum.double_value);
3369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3373 + R e a d B l o b F l o a t %
3377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3379 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3380 % specified by the endian member of the image structure.
3382 % The format of the ReadBlobFloat method is:
3384 % float ReadBlobFloat(Image *image)
3386 % A description of each parameter follows.
3388 % o image: the image.
3391 MagickExport float ReadBlobFloat(Image *image)
3402 quantum.float_value=0.0;
3403 quantum.unsigned_value=ReadBlobLong(image);
3404 return(quantum.float_value);
3408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3412 + R e a d B l o b L o n g %
3416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3418 % ReadBlobLong() reads a unsigned int value as a 32-bit quantity in the
3419 % byte-order specified by the endian member of the image structure.
3421 % The format of the ReadBlobLong method is:
3423 % unsigned int ReadBlobLong(Image *image)
3425 % A description of each parameter follows.
3427 % o image: the image.
3430 MagickExport unsigned int ReadBlobLong(Image *image)
3432 register const unsigned char
3444 assert(image != (Image *) NULL);
3445 assert(image->signature == MagickCoreSignature);
3447 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3450 if (image->endian == LSBEndian)
3452 value=(unsigned int) (*p++);
3453 value|=(unsigned int) (*p++) << 8;
3454 value|=(unsigned int) (*p++) << 16;
3455 value|=(unsigned int) (*p++) << 24;
3456 return(value & 0xffffffff);
3458 value=(unsigned int) (*p++) << 24;
3459 value|=(unsigned int) (*p++) << 16;
3460 value|=(unsigned int) (*p++) << 8;
3461 value|=(unsigned int) (*p++);
3462 return(value & 0xffffffff);
3466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3470 + R e a d B l o b L o n g L o n g %
3474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3476 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3477 % byte-order specified by the endian member of the image structure.
3479 % The format of the ReadBlobLongLong method is:
3481 % MagickSizeType ReadBlobLongLong(Image *image)
3483 % A description of each parameter follows.
3485 % o image: the image.
3488 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3493 register const unsigned char
3502 assert(image != (Image *) NULL);
3503 assert(image->signature == MagickCoreSignature);
3505 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3507 return(MagickULLConstant(0));
3508 if (image->endian == LSBEndian)
3510 value=(MagickSizeType) (*p++);
3511 value|=(MagickSizeType) (*p++) << 8;
3512 value|=(MagickSizeType) (*p++) << 16;
3513 value|=(MagickSizeType) (*p++) << 24;
3514 value|=(MagickSizeType) (*p++) << 32;
3515 value|=(MagickSizeType) (*p++) << 40;
3516 value|=(MagickSizeType) (*p++) << 48;
3517 value|=(MagickSizeType) (*p++) << 56;
3518 return(value & MagickULLConstant(0xffffffffffffffff));
3520 value=(MagickSizeType) (*p++) << 56;
3521 value|=(MagickSizeType) (*p++) << 48;
3522 value|=(MagickSizeType) (*p++) << 40;
3523 value|=(MagickSizeType) (*p++) << 32;
3524 value|=(MagickSizeType) (*p++) << 24;
3525 value|=(MagickSizeType) (*p++) << 16;
3526 value|=(MagickSizeType) (*p++) << 8;
3527 value|=(MagickSizeType) (*p++);
3528 return(value & MagickULLConstant(0xffffffffffffffff));
3532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3536 + R e a d B l o b S h o r t %
3540 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3542 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3543 % specified by the endian member of the image structure.
3545 % The format of the ReadBlobShort method is:
3547 % unsigned short ReadBlobShort(Image *image)
3549 % A description of each parameter follows.
3551 % o image: the image.
3554 MagickExport unsigned short ReadBlobShort(Image *image)
3556 register const unsigned char
3559 register unsigned short
3568 assert(image != (Image *) NULL);
3569 assert(image->signature == MagickCoreSignature);
3571 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3573 return((unsigned short) 0U);
3574 if (image->endian == LSBEndian)
3576 value=(unsigned short) (*p++);
3577 value|=(unsigned short) (*p++) << 8;
3580 value=(unsigned short) (*p++) << 8;
3581 value|=(unsigned short) (*p++);
3586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3590 + R e a d B l o b L S B L o n g %
3594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3596 % ReadBlobLSBLong() reads a unsigned int value as a 32-bit quantity in
3597 % least-significant byte first order.
3599 % The format of the ReadBlobLSBLong method is:
3601 % unsigned int ReadBlobLSBLong(Image *image)
3603 % A description of each parameter follows.
3605 % o image: the image.
3608 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3610 register const unsigned char
3613 register unsigned int
3622 assert(image != (Image *) NULL);
3623 assert(image->signature == MagickCoreSignature);
3625 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3628 value=(unsigned int) (*p++);
3629 value|=(unsigned int) (*p++) << 8;
3630 value|=(unsigned int) (*p++) << 16;
3631 value|=(unsigned int) (*p++) << 24;
3632 return(value & 0xffffffff);
3636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3640 + R e a d B l o b L S B S i g n e d L o n g %
3644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3646 % ReadBlobLSBSignedLong() reads a signed int value as a 32-bit quantity in
3647 % least-significant byte first order.
3649 % The format of the ReadBlobLSBSignedLong method is:
3651 % signed int ReadBlobLSBSignedLong(Image *image)
3653 % A description of each parameter follows.
3655 % o image: the image.
3658 MagickExport signed int ReadBlobLSBSignedLong(Image *image)
3669 quantum.unsigned_value=ReadBlobLSBLong(image);
3670 return(quantum.signed_value);
3674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3678 + R e a d B l o b L S B S h o r t %
3682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3684 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3685 % least-significant byte first order.
3687 % The format of the ReadBlobLSBShort method is:
3689 % unsigned short ReadBlobLSBShort(Image *image)
3691 % A description of each parameter follows.
3693 % o image: the image.
3696 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3698 register const unsigned char
3701 register unsigned short
3710 assert(image != (Image *) NULL);
3711 assert(image->signature == MagickCoreSignature);
3713 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3715 return((unsigned short) 0U);
3716 value=(unsigned int) (*p++);
3717 value|=(unsigned int) (*p++) << 8;
3718 return(value & 0xffff);
3722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3726 + R e a d B l o b L S B S i g n e d S h o r t %
3730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3732 % ReadBlobLSBSignedShort() reads a signed short value as a 16-bit quantity in
3733 % least-significant byte-order.
3735 % The format of the ReadBlobLSBSignedShort method is:
3737 % signed short ReadBlobLSBSignedShort(Image *image)
3739 % A description of each parameter follows.
3741 % o image: the image.
3744 MagickExport signed short ReadBlobLSBSignedShort(Image *image)
3755 quantum.unsigned_value=ReadBlobLSBShort(image);
3756 return(quantum.signed_value);
3760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3764 + R e a d B l o b M S B L o n g %
3768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3770 % ReadBlobMSBLong() reads a unsigned int value as a 32-bit quantity in
3771 % most-significant byte first order.
3773 % The format of the ReadBlobMSBLong method is:
3775 % unsigned int ReadBlobMSBLong(Image *image)
3777 % A description of each parameter follows.
3779 % o image: the image.
3782 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3784 register const unsigned char
3787 register unsigned int
3796 assert(image != (Image *) NULL);
3797 assert(image->signature == MagickCoreSignature);
3799 p=(const unsigned char *) ReadBlobStream(image,4,buffer,&count);
3802 value=(unsigned int) (*p++) << 24;
3803 value|=(unsigned int) (*p++) << 16;
3804 value|=(unsigned int) (*p++) << 8;
3805 value|=(unsigned int) (*p++);
3810 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3814 + R e a d B l o b M S B L o n g L o n g %
3818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3820 % ReadBlobMSBLongLong() reads a unsigned long long value as a 64-bit quantity
3821 % in most-significant byte first order.
3823 % The format of the ReadBlobMSBLongLong method is:
3825 % unsigned int ReadBlobMSBLongLong(Image *image)
3827 % A description of each parameter follows.
3829 % o image: the image.
3832 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3834 register const unsigned char
3837 register MagickSizeType
3846 assert(image != (Image *) NULL);
3847 assert(image->signature == MagickCoreSignature);
3849 p=(const unsigned char *) ReadBlobStream(image,8,buffer,&count);
3851 return(MagickULLConstant(0));
3852 value=(MagickSizeType) (*p++) << 56;
3853 value|=(MagickSizeType) (*p++) << 48;
3854 value|=(MagickSizeType) (*p++) << 40;
3855 value|=(MagickSizeType) (*p++) << 32;
3856 value|=(MagickSizeType) (*p++) << 24;
3857 value|=(MagickSizeType) (*p++) << 16;
3858 value|=(MagickSizeType) (*p++) << 8;
3859 value|=(MagickSizeType) (*p++);
3860 return(value & MagickULLConstant(0xffffffffffffffff));
3864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3868 + R e a d B l o b M S B S h o r t %
3872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3874 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3875 % most-significant byte first order.
3877 % The format of the ReadBlobMSBShort method is:
3879 % unsigned short ReadBlobMSBShort(Image *image)
3881 % A description of each parameter follows.
3883 % o image: the image.
3886 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3888 register const unsigned char
3891 register unsigned short
3900 assert(image != (Image *) NULL);
3901 assert(image->signature == MagickCoreSignature);
3903 p=(const unsigned char *) ReadBlobStream(image,2,buffer,&count);
3905 return((unsigned short) 0U);
3906 value=(unsigned short) (*p++) << 8;
3907 value|=(unsigned short) (*p++);
3908 return(value & 0xffff);
3912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3916 + R e a d B l o b M S B S i g n e d L o n g %
3920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3922 % ReadBlobMSBSignedLong() reads a signed int value as a 32-bit quantity in
3923 % most-significant byte-order.
3925 % The format of the ReadBlobMSBSignedLong method is:
3927 % signed int ReadBlobMSBSignedLong(Image *image)
3929 % A description of each parameter follows.
3931 % o image: the image.
3934 MagickExport signed int ReadBlobMSBSignedLong(Image *image)
3945 quantum.unsigned_value=ReadBlobMSBLong(image);
3946 return(quantum.signed_value);
3950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3954 + R e a d B l o b M S B S i g n e d S h o r t %
3958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3960 % ReadBlobMSBSignedShort() reads a signed short value as a 16-bit quantity in
3961 % most-significant byte-order.
3963 % The format of the ReadBlobMSBSignedShort method is:
3965 % signed short ReadBlobMSBSignedShort(Image *image)
3967 % A description of each parameter follows.
3969 % o image: the image.
3972 MagickExport signed short ReadBlobMSBSignedShort(Image *image)
3983 quantum.unsigned_value=ReadBlobMSBShort(image);
3984 return(quantum.signed_value);
3988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3992 + R e a d B l o b S i g n e d L o n g %
3996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3998 % ReadBlobSignedLong() reads a signed int value as a 32-bit quantity in the
3999 % byte-order specified by the endian member of the image structure.
4001 % The format of the ReadBlobSignedLong method is:
4003 % signed int ReadBlobSignedLong(Image *image)
4005 % A description of each parameter follows.
4007 % o image: the image.
4010 MagickExport signed int ReadBlobSignedLong(Image *image)
4021 quantum.unsigned_value=ReadBlobLong(image);
4022 return(quantum.signed_value);
4026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4030 + R e a d B l o b S i g n e d S h o r t %
4034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4036 % ReadBlobSignedShort() reads a signed short value as a 16-bit quantity in the
4037 % byte-order specified by the endian member of the image structure.
4039 % The format of the ReadBlobSignedShort method is:
4041 % signed short ReadBlobSignedShort(Image *image)
4043 % A description of each parameter follows.
4045 % o image: the image.
4048 MagickExport signed short ReadBlobSignedShort(Image *image)
4059 quantum.unsigned_value=ReadBlobShort(image);
4060 return(quantum.signed_value);
4064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4068 + R e a d B l o b S t r e a m %
4072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4074 % ReadBlobStream() reads data from the blob or image file and returns it. It
4075 % returns a pointer to the data buffer you supply or to the image memory
4076 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
4077 % returns a count of zero and has no other results. If length is greater than
4078 % SSIZE_MAX, the result is unspecified.
4080 % The format of the ReadBlobStream method is:
4082 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
4085 % A description of each parameter follows:
4087 % o image: the image.
4089 % o length: Specifies an integer representing the number of bytes to read
4092 % o count: returns the number of bytes read.
4094 % o data: Specifies an area to place the information requested from the
4098 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
4099 void *data,ssize_t *count)
4101 assert(image != (Image *) NULL);
4102 assert(image->signature == MagickCoreSignature);
4103 assert(image->blob != (BlobInfo *) NULL);
4104 assert(image->blob->type != UndefinedStream);
4105 assert(count != (ssize_t *) NULL);
4106 if (image->blob->type != BlobStream)
4108 assert(data != NULL);
4109 *count=ReadBlob(image,length,(unsigned char *) data);
4112 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4115 image->blob->eof=MagickTrue;
4118 data=image->blob->data+image->blob->offset;
4119 *count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
4120 image->blob->offset+=(*count);
4121 if (*count != (ssize_t) length)
4122 image->blob->eof=MagickTrue;
4127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4131 + R e a d B l o b S t r i n g %
4135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4137 % ReadBlobString() reads characters from a blob or file until a newline
4138 % character is read or an end-of-file condition is encountered.
4140 % The format of the ReadBlobString method is:
4142 % char *ReadBlobString(Image *image,char *string)
4144 % A description of each parameter follows:
4146 % o image: the image.
4148 % o string: the address of a character buffer.
4151 MagickExport char *ReadBlobString(Image *image,char *string)
4153 register const unsigned char
4165 assert(image != (Image *) NULL);
4166 assert(image->signature == MagickCoreSignature);
4167 for (i=0; i < (MagickPathExtent-1L); i++)
4169 p=(const unsigned char *) ReadBlobStream(image,1,buffer,&count);
4173 return((char *) NULL);
4176 string[i]=(char) (*p);
4177 if ((string[i] == '\r') || (string[i] == '\n'))
4180 if (string[i] == '\r')
4181 (void) ReadBlobStream(image,1,buffer,&count);
4187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4191 + R e f e r e n c e B l o b %
4195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4197 % ReferenceBlob() increments the reference count associated with the pixel
4198 % blob returning a pointer to the blob.
4200 % The format of the ReferenceBlob method is:
4202 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
4204 % A description of each parameter follows:
4206 % o blob_info: the blob_info.
4209 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
4211 assert(blob != (BlobInfo *) NULL);
4212 assert(blob->signature == MagickCoreSignature);
4213 if (blob->debug != MagickFalse)
4214 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4215 LockSemaphoreInfo(blob->semaphore);
4216 blob->reference_count++;
4217 UnlockSemaphoreInfo(blob->semaphore);
4222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4232 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
4233 % and returns the resulting offset.
4235 % The format of the SeekBlob method is:
4237 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
4240 % A description of each parameter follows:
4242 % o image: the image.
4244 % o offset: Specifies an integer representing the offset in bytes.
4246 % o whence: Specifies an integer representing how the offset is
4247 % treated relative to the beginning of the blob as follows:
4249 % SEEK_SET Set position equal to offset bytes.
4250 % SEEK_CUR Set position to current location plus offset.
4251 % SEEK_END Set position to EOF plus offset.
4254 MagickExport MagickOffsetType SeekBlob(Image *image,
4255 const MagickOffsetType offset,const int whence)
4257 assert(image != (Image *) NULL);
4258 assert(image->signature == MagickCoreSignature);
4259 if (image->debug != MagickFalse)
4260 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4261 assert(image->blob != (BlobInfo *) NULL);
4262 assert(image->blob->type != UndefinedStream);
4263 switch (image->blob->type)
4265 case UndefinedStream:
4267 case StandardStream:
4272 if ((offset < 0) && (whence == SEEK_SET))
4274 if (fseek(image->blob->file_info.file,offset,whence) < 0)
4276 image->blob->offset=TellBlob(image);
4281 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4282 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
4285 image->blob->offset=TellBlob(image);
4301 image->blob->offset=offset;
4306 if ((image->blob->offset+offset) < 0)
4308 image->blob->offset+=offset;
4313 if (((MagickOffsetType) image->blob->length+offset) < 0)
4315 image->blob->offset=image->blob->length+offset;
4319 if (image->blob->offset < (MagickOffsetType)
4320 ((off_t) image->blob->length))
4322 image->blob->eof=MagickFalse;
4325 if (image->blob->offset < (MagickOffsetType)
4326 ((off_t) image->blob->extent))
4328 if (image->blob->mapped != MagickFalse)
4330 image->blob->eof=MagickTrue;
4333 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
4334 image->blob->quantum<<=1;
4335 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
4336 image->blob->extent+1,sizeof(*image->blob->data));
4337 (void) SyncBlob(image);
4338 if (image->blob->data == NULL)
4340 (void) DetachBlob(image->blob);
4347 if (image->blob->user_info->seeker == (BlobSeeker) NULL)
4349 image->blob->offset=image->blob->user_info->seeker(offset,whence,
4350 image->blob->user_info->data);
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->reader != (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) ||
4788 (blob_info->user_info == (UserBlobInfo *) NULL))
4791 Native blob support for this image format or SetImageInfo changed the
4794 image=ReadImage(blob_info,exception);
4795 if (image != (Image *) NULL)
4796 (void) CloseBlob(image);
4801 unique[MagickPathExtent];
4813 Write data to file on disk.
4815 blob_info->user_info=(UserBlobInfo *) NULL;
4816 blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
4818 if (blob == (unsigned char *) NULL)
4820 ThrowFileException(exception,BlobError,"UnableToReadBlob",
4821 image_info->filename);
4822 blob_info=DestroyImageInfo(blob_info);
4823 return((Image *) NULL);
4825 file=AcquireUniqueFileResource(unique);
4828 ThrowFileException(exception,BlobError,"UnableToReadBlob",
4829 image_info->filename);
4830 blob=(unsigned char *) RelinquishMagickMemory(blob);
4831 blob_info=DestroyImageInfo(blob_info);
4832 return((Image *) NULL);
4834 clone_info=CloneImageInfo(blob_info);
4835 blob_info->file=fdopen(file,"wb+");
4836 if (blob_info->file != (FILE *) NULL)
4841 count=(ssize_t) MagickMaxBufferExtent;
4842 while (count == (ssize_t) MagickMaxBufferExtent)
4844 count=user_info->reader(blob,MagickMaxBufferExtent,
4846 count=(ssize_t) write(file,(const char *) blob,count);
4848 (void) fclose(blob_info->file);
4849 (void) FormatLocaleString(clone_info->filename,MagickPathExtent,
4850 "%s:%s",blob_info->magick,unique);
4851 image=ReadImage(clone_info,exception);
4852 if (image != (Image *) NULL)
4858 Restore original filenames and image format.
4860 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
4862 (void) CopyMagickString(images->filename,image_info->filename,
4864 (void) CopyMagickString(images->magick_filename,
4865 image_info->filename,MagickPathExtent);
4866 (void) CopyMagickString(images->magick,magick_info->name,
4868 (void) CloseBlob(images);
4869 images=GetNextImageInList(images);
4873 clone_info=DestroyImageInfo(clone_info);
4874 blob=(unsigned char *) RelinquishMagickMemory(blob);
4875 (void) RelinquishUniqueFileResource(unique);
4877 blob_info=DestroyImageInfo(blob_info);
4882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4886 + W r i t e B l o b %
4890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4892 % WriteBlob() writes data to a blob or image file. It returns the number of
4895 % The format of the WriteBlob method is:
4897 % ssize_t WriteBlob(Image *image,const size_t length,const void *data)
4899 % A description of each parameter follows:
4901 % o image: the image.
4903 % o length: Specifies an integer representing the number of bytes to
4904 % write to the file.
4906 % o data: The address of the data to write to the blob or file.
4909 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4915 register const unsigned char
4921 assert(image != (Image *) NULL);
4922 assert(image->signature == MagickCoreSignature);
4923 assert(data != (const void *) NULL);
4924 assert(image->blob != (BlobInfo *) NULL);
4925 assert(image->blob->type != UndefinedStream);
4929 p=(const unsigned char *) data;
4930 switch (image->blob->type)
4932 case UndefinedStream:
4934 case StandardStream:
4942 count=(ssize_t) fwrite((const char *) data,1,length,
4943 image->blob->file_info.file);
4948 c=putc((int) *p++,image->blob->file_info.file);
4955 c=putc((int) *p++,image->blob->file_info.file);
4962 c=putc((int) *p++,image->blob->file_info.file);
4969 c=putc((int) *p++,image->blob->file_info.file);
4981 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4986 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4987 (unsigned int) length);
4992 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4999 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5006 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5013 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
5026 #if defined(MAGICKCORE_BZLIB_DELEGATE)
5027 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
5034 count=(ssize_t) image->blob->stream(image,data,length);
5039 register unsigned char
5042 if ((image->blob->offset+(MagickOffsetType) length) >=
5043 (MagickOffsetType) image->blob->extent)
5045 if (image->blob->mapped != MagickFalse)
5047 image->blob->extent+=length+image->blob->quantum;
5048 image->blob->quantum<<=1;
5049 image->blob->data=(unsigned char *) ResizeQuantumMemory(
5050 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
5051 (void) SyncBlob(image);
5052 if (image->blob->data == (unsigned char *) NULL)
5054 (void) DetachBlob(image->blob);
5058 q=image->blob->data+image->blob->offset;
5059 (void) memcpy(q,p,length);
5060 image->blob->offset+=length;
5061 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
5062 image->blob->length=(size_t) image->blob->offset;
5063 count=(ssize_t) length;
5068 count=image->blob->user_info->writer((const unsigned char *) data,
5069 length,image->blob->user_info->data);
5077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5081 + W r i t e B l o b B y t e %
5085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5087 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
5088 % written (either 0 or 1);
5090 % The format of the WriteBlobByte method is:
5092 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
5094 % A description of each parameter follows.
5096 % o image: the image.
5098 % o value: Specifies the value to write.
5101 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
5103 assert(image != (Image *) NULL);
5104 assert(image->signature == MagickCoreSignature);
5105 return(WriteBlobStream(image,1,&value));
5109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5113 + W r i t e B l o b F l o a t %
5117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5119 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
5120 % specified by the endian member of the image structure.
5122 % The format of the WriteBlobFloat method is:
5124 % ssize_t WriteBlobFloat(Image *image,const float value)
5126 % A description of each parameter follows.
5128 % o image: the image.
5130 % o value: Specifies the value to write.
5133 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
5144 quantum.unsigned_value=0U;
5145 quantum.float_value=value;
5146 return(WriteBlobLong(image,quantum.unsigned_value));
5150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5154 + W r i t e B l o b L o n g %
5158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5160 % WriteBlobLong() writes a unsigned int value as a 32-bit quantity in the
5161 % byte-order specified by the endian member of the image structure.
5163 % The format of the WriteBlobLong method is:
5165 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
5167 % A description of each parameter follows.
5169 % o image: the image.
5171 % o value: Specifies the value to write.
5174 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
5179 assert(image != (Image *) NULL);
5180 assert(image->signature == MagickCoreSignature);
5181 if (image->endian == LSBEndian)
5183 buffer[0]=(unsigned char) value;
5184 buffer[1]=(unsigned char) (value >> 8);
5185 buffer[2]=(unsigned char) (value >> 16);
5186 buffer[3]=(unsigned char) (value >> 24);
5187 return(WriteBlobStream(image,4,buffer));
5189 buffer[0]=(unsigned char) (value >> 24);
5190 buffer[1]=(unsigned char) (value >> 16);
5191 buffer[2]=(unsigned char) (value >> 8);
5192 buffer[3]=(unsigned char) value;
5193 return(WriteBlobStream(image,4,buffer));
5197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5201 + W r i t e B l o b S h o r t %
5205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5207 % WriteBlobShort() writes a short value as a 16-bit quantity in the
5208 % byte-order specified by the endian member of the image structure.
5210 % The format of the WriteBlobShort method is:
5212 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
5214 % A description of each parameter follows.
5216 % o image: the image.
5218 % o value: Specifies the value to write.
5221 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
5226 assert(image != (Image *) NULL);
5227 assert(image->signature == MagickCoreSignature);
5228 if (image->endian == LSBEndian)
5230 buffer[0]=(unsigned char) value;
5231 buffer[1]=(unsigned char) (value >> 8);
5232 return(WriteBlobStream(image,2,buffer));
5234 buffer[0]=(unsigned char) (value >> 8);
5235 buffer[1]=(unsigned char) value;
5236 return(WriteBlobStream(image,2,buffer));
5240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5244 + W r i t e B l o b L S B L o n g %
5248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5250 % WriteBlobLSBLong() writes a unsigned int value as a 32-bit quantity in
5251 % least-significant byte first order.
5253 % The format of the WriteBlobLSBLong method is:
5255 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5257 % A description of each parameter follows.
5259 % o image: the image.
5261 % o value: Specifies the value to write.
5264 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
5269 assert(image != (Image *) NULL);
5270 assert(image->signature == MagickCoreSignature);
5271 buffer[0]=(unsigned char) value;
5272 buffer[1]=(unsigned char) (value >> 8);
5273 buffer[2]=(unsigned char) (value >> 16);
5274 buffer[3]=(unsigned char) (value >> 24);
5275 return(WriteBlobStream(image,4,buffer));
5279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5283 + W r i t e B l o b L S B S h o r t %
5287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5289 % WriteBlobLSBShort() writes a unsigned short value as a 16-bit quantity in
5290 % least-significant byte first order.
5292 % The format of the WriteBlobLSBShort method is:
5294 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5296 % A description of each parameter follows.
5298 % o image: the image.
5300 % o value: Specifies the value to write.
5303 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
5308 assert(image != (Image *) NULL);
5309 assert(image->signature == MagickCoreSignature);
5310 buffer[0]=(unsigned char) value;
5311 buffer[1]=(unsigned char) (value >> 8);
5312 return(WriteBlobStream(image,2,buffer));
5316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5320 + W r i t e B l o b L S B S i g n e d L o n g %
5324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5326 % WriteBlobLSBSignedLong() writes a signed value as a 32-bit quantity in
5327 % least-significant byte first order.
5329 % The format of the WriteBlobLSBSignedLong method is:
5331 % ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5333 % A description of each parameter follows.
5335 % o image: the image.
5337 % o value: Specifies the value to write.
5340 MagickExport ssize_t WriteBlobLSBSignedLong(Image *image,const signed int value)
5354 assert(image != (Image *) NULL);
5355 assert(image->signature == MagickCoreSignature);
5356 quantum.signed_value=value;
5357 buffer[0]=(unsigned char) quantum.unsigned_value;
5358 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5359 buffer[2]=(unsigned char) (quantum.unsigned_value >> 16);
5360 buffer[3]=(unsigned char) (quantum.unsigned_value >> 24);
5361 return(WriteBlobStream(image,4,buffer));
5365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5369 + W r i t e B l o b L S B S i g n e d S h o r t %
5373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5375 % WriteBlobLSBSignedShort() writes a signed short value as a 16-bit quantity
5376 % in least-significant byte first order.
5378 % The format of the WriteBlobLSBSignedShort method is:
5380 % ssize_t WriteBlobLSBSignedShort(Image *image,const signed short value)
5382 % A description of each parameter follows.
5384 % o image: the image.
5386 % o value: Specifies the value to write.
5389 MagickExport ssize_t WriteBlobLSBSignedShort(Image *image,
5390 const signed short value)
5404 assert(image != (Image *) NULL);
5405 assert(image->signature == MagickCoreSignature);
5406 quantum.signed_value=value;
5407 buffer[0]=(unsigned char) quantum.unsigned_value;
5408 buffer[1]=(unsigned char) (quantum.unsigned_value >> 8);
5409 return(WriteBlobStream(image,2,buffer));
5413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5417 + W r i t e B l o b M S B L o n g %
5421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5423 % WriteBlobMSBLong() writes a unsigned int value as a 32-bit quantity in
5424 % most-significant byte first order.
5426 % The format of the WriteBlobMSBLong method is:
5428 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5430 % A description of each parameter follows.
5432 % o value: Specifies the value to write.
5434 % o image: the image.
5437 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
5442 assert(image != (Image *) NULL);
5443 assert(image->signature == MagickCoreSignature);
5444 buffer[0]=(unsigned char) (value >> 24);
5445 buffer[1]=(unsigned char) (value >> 16);
5446 buffer[2]=(unsigned char) (value >> 8);
5447 buffer[3]=(unsigned char) value;
5448 return(WriteBlobStream(image,4,buffer));
5452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5456 + W r i t e B l o b M S B L o n g L o n g %
5460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5462 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
5463 % most-significant byte first order.
5465 % The format of the WriteBlobMSBLongLong method is:
5467 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
5469 % A description of each parameter follows.
5471 % o value: Specifies the value to write.
5473 % o image: the image.
5476 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
5477 const MagickSizeType value)
5482 assert(image != (Image *) NULL);
5483 assert(image->signature == MagickCoreSignature);
5484 buffer[0]=(unsigned char) (value >> 56);
5485 buffer[1]=(unsigned char) (value >> 48);
5486 buffer[2]=(unsigned char) (value >> 40);
5487 buffer[3]=(unsigned char) (value >> 32);
5488 buffer[4]=(unsigned char) (value >> 24);
5489 buffer[5]=(unsigned char) (value >> 16);
5490 buffer[6]=(unsigned char) (value >> 8);
5491 buffer[7]=(unsigned char) value;
5492 return(WriteBlobStream(image,8,buffer));
5496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5500 + W r i t e B l o b M S B S i g n e d L o n g %
5504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5506 % WriteBlobMSBSignedLong() writes a signed value as a 32-bit quantity in
5507 % most-significant byte first order.
5509 % The format of the WriteBlobMSBSignedLong method is:
5511 % ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5513 % A description of each parameter follows.
5515 % o image: the image.
5517 % o value: Specifies the value to write.
5520 MagickExport ssize_t WriteBlobMSBSignedLong(Image *image,const signed int value)
5534 assert(image != (Image *) NULL);
5535 assert(image->signature == MagickCoreSignature);
5536 quantum.signed_value=value;
5537 buffer[0]=(unsigned char) (quantum.unsigned_value >> 24);
5538 buffer[1]=(unsigned char) (quantum.unsigned_value >> 16);
5539 buffer[2]=(unsigned char) (quantum.unsigned_value >> 8);
5540 buffer[3]=(unsigned char) quantum.unsigned_value;
5541 return(WriteBlobStream(image,4,buffer));
5545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5549 + W r i t e B l o b M S B S i g n e d S h o r t %
5553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5555 % WriteBlobMSBSignedShort() writes a signed short value as a 16-bit quantity
5556 % in most-significant byte first order.
5558 % The format of the WriteBlobMSBSignedShort method is:
5560 % ssize_t WriteBlobMSBSignedShort(Image *image,const signed short value)
5562 % A description of each parameter follows.
5564 % o image: the image.
5566 % o value: Specifies the value to write.
5569 MagickExport ssize_t WriteBlobMSBSignedShort(Image *image,
5570 const signed short value)
5584 assert(image != (Image *) NULL);
5585 assert(image->signature == MagickCoreSignature);
5586 quantum.signed_value=value;
5587 buffer[0]=(unsigned char) (quantum.unsigned_value >> 8);
5588 buffer[1]=(unsigned char) quantum.unsigned_value;
5589 return(WriteBlobStream(image,2,buffer));
5593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5597 + W r i t e B l o b M S B S h o r t %
5601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5603 % WriteBlobMSBShort() writes a unsigned short value as a 16-bit quantity in
5604 % most-significant byte first order.
5606 % The format of the WriteBlobMSBShort method is:
5608 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5610 % A description of each parameter follows.
5612 % o value: Specifies the value to write.
5614 % o file: Specifies the file to write the data to.
5617 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
5622 assert(image != (Image *) NULL);
5623 assert(image->signature == MagickCoreSignature);
5624 buffer[0]=(unsigned char) (value >> 8);
5625 buffer[1]=(unsigned char) value;
5626 return(WriteBlobStream(image,2,buffer));
5630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5634 + W r i t e B l o b S t r i n g %
5638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5640 % WriteBlobString() write a string to a blob. It returns the number of
5641 % characters written.
5643 % The format of the WriteBlobString method is:
5645 % ssize_t WriteBlobString(Image *image,const char *string)
5647 % A description of each parameter follows.
5649 % o image: the image.
5651 % o string: Specifies the string to write.
5654 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
5656 assert(image != (Image *) NULL);
5657 assert(image->signature == MagickCoreSignature);
5658 assert(string != (const char *) NULL);
5659 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));