2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2015 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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/client.h"
48 #include "MagickCore/constitute.h"
49 #include "MagickCore/delegate.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image-private.h"
53 #include "MagickCore/list.h"
54 #include "MagickCore/locale_.h"
55 #include "MagickCore/log.h"
56 #include "MagickCore/magick.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/nt-base-private.h"
59 #include "MagickCore/option.h"
60 #include "MagickCore/policy.h"
61 #include "MagickCore/resource_.h"
62 #include "MagickCore/semaphore.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/string-private.h"
65 #include "MagickCore/token.h"
66 #include "MagickCore/utility.h"
67 #include "MagickCore/utility-private.h"
68 #if defined(MAGICKCORE_ZLIB_DELEGATE)
71 #if defined(MAGICKCORE_BZLIB_DELEGATE)
78 #define MagickMaxBlobExtent (8*8192)
79 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
80 # define MAP_ANONYMOUS MAP_ANON
82 #if !defined(MAP_FAILED)
83 #define MAP_FAILED ((void *) -1)
87 #define _O_BINARY O_BINARY
93 typedef union FileInfo
98 #if defined(MAGICKCORE_ZLIB_DELEGATE)
103 #if defined(MAGICKCORE_BZLIB_DELEGATE)
161 Forward declarations.
167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 + A t t a c h B l o b %
175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 % AttachBlob() attaches a blob to the BlobInfo structure.
179 % The format of the AttachBlob method is:
181 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
183 % A description of each parameter follows:
185 % o blob_info: Specifies a pointer to a BlobInfo structure.
187 % o blob: the address of a character stream in one of the image formats
188 % understood by ImageMagick.
190 % o length: This size_t integer reflects the length in bytes of the blob.
193 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
196 assert(blob_info != (BlobInfo *) NULL);
197 if (blob_info->debug != MagickFalse)
198 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
199 blob_info->length=length;
200 blob_info->extent=length;
201 blob_info->quantum=(size_t) MagickMaxBlobExtent;
203 blob_info->type=BlobStream;
204 blob_info->file_info.file=(FILE *) NULL;
205 blob_info->data=(unsigned char *) blob;
206 blob_info->mapped=MagickFalse;
210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214 + B l o b T o F i l e %
218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
221 % occurs otherwise MagickTrue.
223 % The format of the BlobToFile method is:
225 % MagickBooleanType BlobToFile(char *filename,const void *blob,
226 % const size_t length,ExceptionInfo *exception)
228 % A description of each parameter follows:
230 % o filename: Write the blob to this file.
232 % o blob: the address of a blob.
234 % o length: This length in bytes of the blob.
236 % o exception: return any errors or warnings in this structure.
239 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
240 const size_t length,ExceptionInfo *exception)
251 assert(filename != (const char *) NULL);
252 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
253 assert(blob != (const void *) NULL);
254 if (*filename == '\0')
255 file=AcquireUniqueFileResource(filename);
257 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
260 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
263 for (i=0; i < length; i+=count)
265 count=write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
275 if ((file == -1) || (i < length))
277 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288 % B l o b T o I m a g e %
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294 % BlobToImage() implements direct to memory image formats. It returns the
297 % The format of the BlobToImage method is:
299 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
300 % const size_t length,ExceptionInfo *exception)
302 % A description of each parameter follows:
304 % o image_info: the image info.
306 % o blob: the address of a character stream in one of the image formats
307 % understood by ImageMagick.
309 % o length: This size_t integer reflects the length in bytes of the blob.
311 % o exception: return any errors or warnings in this structure.
314 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
315 const size_t length,ExceptionInfo *exception)
330 assert(image_info != (ImageInfo *) NULL);
331 assert(image_info->signature == MagickSignature);
332 if (image_info->debug != MagickFalse)
333 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
334 image_info->filename);
335 assert(exception != (ExceptionInfo *) NULL);
336 if ((blob == (const void *) NULL) || (length == 0))
338 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
339 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
340 return((Image *) NULL);
342 blob_info=CloneImageInfo(image_info);
343 blob_info->blob=(void *) blob;
344 blob_info->length=length;
345 if (*blob_info->magick == '\0')
346 (void) SetImageInfo(blob_info,0,exception);
347 magick_info=GetMagickInfo(blob_info->magick,exception);
348 if (magick_info == (const MagickInfo *) NULL)
350 (void) ThrowMagickException(exception,GetMagickModule(),
351 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
353 blob_info=DestroyImageInfo(blob_info);
354 return((Image *) NULL);
356 if (GetMagickBlobSupport(magick_info) != MagickFalse)
359 Native blob support for this image format.
361 (void) CopyMagickString(blob_info->filename,image_info->filename,
363 (void) CopyMagickString(blob_info->magick,image_info->magick,
365 image=ReadImage(blob_info,exception);
366 if (image != (Image *) NULL)
367 (void) DetachBlob(image->blob);
368 blob_info=DestroyImageInfo(blob_info);
372 Write blob to a temporary file on disk.
374 blob_info->blob=(void *) NULL;
376 *blob_info->filename='\0';
377 status=BlobToFile(blob_info->filename,blob,length,exception);
378 if (status == MagickFalse)
380 (void) RelinquishUniqueFileResource(blob_info->filename);
381 blob_info=DestroyImageInfo(blob_info);
382 return((Image *) NULL);
384 clone_info=CloneImageInfo(blob_info);
385 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
386 blob_info->magick,blob_info->filename);
387 image=ReadImage(clone_info,exception);
388 if (image != (Image *) NULL)
394 Restore original filenames and image format.
396 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
398 (void) CopyMagickString(images->filename,image_info->filename,
400 (void) CopyMagickString(images->magick_filename,image_info->filename,
402 (void) CopyMagickString(images->magick,magick_info->name,
404 images=GetNextImageInList(images);
407 clone_info=DestroyImageInfo(clone_info);
408 (void) RelinquishUniqueFileResource(blob_info->filename);
409 blob_info=DestroyImageInfo(blob_info);
414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
418 + C l o n e B l o b I n f o %
422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
425 % blob info is NULL, a new one.
427 % The format of the CloneBlobInfo method is:
429 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
431 % A description of each parameter follows:
433 % o blob_info: the blob info.
436 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
441 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
442 if (clone_info == (BlobInfo *) NULL)
443 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
444 GetBlobInfo(clone_info);
445 if (blob_info == (BlobInfo *) NULL)
447 clone_info->length=blob_info->length;
448 clone_info->extent=blob_info->extent;
449 clone_info->synchronize=blob_info->synchronize;
450 clone_info->quantum=blob_info->quantum;
451 clone_info->mapped=blob_info->mapped;
452 clone_info->eof=blob_info->eof;
453 clone_info->offset=blob_info->offset;
454 clone_info->size=blob_info->size;
455 clone_info->exempt=blob_info->exempt;
456 clone_info->status=blob_info->status;
457 clone_info->temporary=blob_info->temporary;
458 clone_info->type=blob_info->type;
459 clone_info->file_info.file=blob_info->file_info.file;
460 clone_info->properties=blob_info->properties;
461 clone_info->stream=blob_info->stream;
462 clone_info->data=blob_info->data;
463 clone_info->debug=IsEventLogging();
464 clone_info->reference_count=1;
469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 + C l o s e B l o b %
477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
479 % CloseBlob() closes a stream associated with the image.
481 % The format of the CloseBlob method is:
483 % MagickBooleanType CloseBlob(Image *image)
485 % A description of each parameter follows:
487 % o image: the image.
490 MagickExport MagickBooleanType CloseBlob(Image *image)
498 assert(image != (Image *) NULL);
499 assert(image->signature == MagickSignature);
500 if (image->debug != MagickFalse)
501 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
502 assert(image->blob != (BlobInfo *) NULL);
503 if (image->blob->type == UndefinedStream)
505 status=SyncBlob(image);
506 switch (image->blob->type)
508 case UndefinedStream:
514 if (image->blob->synchronize != MagickFalse)
515 status=fsync(fileno(image->blob->file_info.file));
516 status=ferror(image->blob->file_info.file);
521 #if defined(MAGICKCORE_ZLIB_DELEGATE)
522 (void) gzerror(image->blob->file_info.gzfile,&status);
528 #if defined(MAGICKCORE_BZLIB_DELEGATE)
529 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
537 if ((image->blob->file_info.file != (FILE *) NULL) &&
538 (image->blob->synchronize != MagickFalse))
540 (void) fsync(fileno(image->blob->file_info.file));
541 status=ferror(image->blob->file_info.file);
546 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
547 image->blob->size=GetBlobSize(image);
548 image->extent=image->blob->size;
549 image->blob->eof=MagickFalse;
550 if (image->blob->exempt != MagickFalse)
552 image->blob->type=UndefinedStream;
553 return(image->blob->status);
555 switch (image->blob->type)
557 case UndefinedStream:
562 status=fclose(image->blob->file_info.file);
567 #if defined(MAGICKCORE_HAVE_PCLOSE)
568 status=pclose(image->blob->file_info.file);
574 #if defined(MAGICKCORE_ZLIB_DELEGATE)
575 status=gzclose(image->blob->file_info.gzfile);
581 #if defined(MAGICKCORE_BZLIB_DELEGATE)
582 BZ2_bzclose(image->blob->file_info.bzfile);
590 if (image->blob->file_info.file != (FILE *) NULL)
591 status=fclose(image->blob->file_info.file);
595 (void) DetachBlob(image->blob);
596 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
597 return(image->blob->status);
601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
605 + D e s t r o y B l o b %
609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 % DestroyBlob() deallocates memory associated with a blob.
613 % The format of the DestroyBlob method is:
615 % void DestroyBlob(Image *image)
617 % A description of each parameter follows:
619 % o image: the image.
622 MagickExport void DestroyBlob(Image *image)
627 assert(image != (Image *) NULL);
628 assert(image->signature == MagickSignature);
629 if (image->debug != MagickFalse)
630 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
631 assert(image->blob != (BlobInfo *) NULL);
632 assert(image->blob->signature == MagickSignature);
634 LockSemaphoreInfo(image->blob->semaphore);
635 image->blob->reference_count--;
636 assert(image->blob->reference_count >= 0);
637 if (image->blob->reference_count == 0)
639 UnlockSemaphoreInfo(image->blob->semaphore);
640 if (destroy == MagickFalse)
642 (void) CloseBlob(image);
643 if (image->blob->mapped != MagickFalse)
645 (void) UnmapBlob(image->blob->data,image->blob->length);
646 RelinquishMagickResource(MapResource,image->blob->length);
648 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
649 RelinquishSemaphoreInfo(&image->blob->semaphore);
650 image->blob->signature=(~MagickSignature);
651 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659 + D e t a c h B l o b %
663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665 % DetachBlob() detaches a blob from the BlobInfo structure.
667 % The format of the DetachBlob method is:
669 % void *DetachBlob(BlobInfo *blob_info)
671 % A description of each parameter follows:
673 % o blob_info: Specifies a pointer to a BlobInfo structure.
676 MagickExport void *DetachBlob(BlobInfo *blob_info)
681 assert(blob_info != (BlobInfo *) NULL);
682 if (blob_info->debug != MagickFalse)
683 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
684 if (blob_info->mapped != MagickFalse)
686 (void) UnmapBlob(blob_info->data,blob_info->length);
687 blob_info->data=(unsigned char *) NULL;
688 RelinquishMagickResource(MapResource,blob_info->length);
690 blob_info->mapped=MagickFalse;
693 blob_info->eof=MagickFalse;
694 blob_info->exempt=MagickFalse;
695 blob_info->type=UndefinedStream;
696 blob_info->file_info.file=(FILE *) NULL;
697 data=blob_info->data;
698 blob_info->data=(unsigned char *) NULL;
699 blob_info->stream=(StreamHandler) NULL;
704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708 + D i s a s s o c i a t e B l o b %
712 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714 % DisassociateBlob() disassociates the image stream. It checks if the
715 % blob of the specified image is referenced by other images. If the reference
716 % count is higher then 1 a new blob is assigned to the specified image.
718 % The format of the DisassociateBlob method is:
720 % void DisassociateBlob(const Image *image)
722 % A description of each parameter follows:
724 % o image: the image.
727 MagickPrivate void DisassociateBlob(Image *image)
735 assert(image != (Image *) NULL);
736 assert(image->signature == MagickSignature);
737 if (image->debug != MagickFalse)
738 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
739 assert(image->blob != (BlobInfo *) NULL);
740 assert(image->blob->signature == MagickSignature);
742 LockSemaphoreInfo(image->blob->semaphore);
743 assert(image->blob->reference_count >= 0);
744 if (image->blob->reference_count > 1)
746 UnlockSemaphoreInfo(image->blob->semaphore);
747 if (clone == MagickFalse)
749 blob=CloneBlobInfo(image->blob);
755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759 + D i s c a r d B l o b B y t e s %
763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
765 % DiscardBlobBytes() discards bytes in a blob.
767 % The format of the DiscardBlobBytes method is:
769 % MagickBooleanType DiscardBlobBytes(Image *image,
770 % const MagickSizeType length)
772 % A description of each parameter follows.
774 % o image: the image.
776 % o length: the number of bytes to skip.
779 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
780 const MagickSizeType length)
782 register MagickOffsetType
794 assert(image != (Image *) NULL);
795 assert(image->signature == MagickSignature);
797 for (i=0; i < (MagickOffsetType) length; i+=count)
799 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
800 (void) ReadBlobStream(image,quantum,buffer,&count);
808 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816 + D u p l i c a t e s B l o b %
820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822 % DuplicateBlob() duplicates a blob descriptor.
824 % The format of the DuplicateBlob method is:
826 % void DuplicateBlob(Image *image,const Image *duplicate)
828 % A description of each parameter follows:
830 % o image: the image.
832 % o duplicate: the duplicate image.
835 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
837 assert(image != (Image *) NULL);
838 assert(image->signature == MagickSignature);
839 if (image->debug != MagickFalse)
840 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
841 assert(duplicate != (Image *) NULL);
842 assert(duplicate->signature == MagickSignature);
844 image->blob=ReferenceBlob(duplicate->blob);
848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
858 % EOFBlob() returns a non-zero value when EOF has been detected reading from
861 % The format of the EOFBlob method is:
863 % int EOFBlob(const Image *image)
865 % A description of each parameter follows:
867 % o image: the image.
870 MagickExport int EOFBlob(const Image *image)
872 assert(image != (Image *) NULL);
873 assert(image->signature == MagickSignature);
874 if (image->debug != MagickFalse)
875 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
876 assert(image->blob != (BlobInfo *) NULL);
877 assert(image->blob->type != UndefinedStream);
878 switch (image->blob->type)
880 case UndefinedStream:
886 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
892 image->blob->eof=MagickFalse;
897 #if defined(MAGICKCORE_BZLIB_DELEGATE)
902 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
903 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
909 image->blob->eof=MagickFalse;
915 return((int) image->blob->eof);
919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
923 + F i l e T o B l o b %
927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
929 % FileToBlob() returns the contents of a file as a buffer terminated with
930 % the '\0' character. The length of the buffer (not including the extra
931 % terminating '\0' character) is returned via the 'length' parameter. Free
932 % the buffer with RelinquishMagickMemory().
934 % The format of the FileToBlob method is:
936 % void *FileToBlob(const char *filename,const size_t extent,
937 % size_t *length,ExceptionInfo *exception)
939 % A description of each parameter follows:
941 % o blob: FileToBlob() returns the contents of a file as a blob. If
942 % an error occurs NULL is returned.
944 % o filename: the filename.
946 % o extent: The maximum length of the blob.
948 % o length: On return, this reflects the actual length of the blob.
950 % o exception: return any errors or warnings in this structure.
953 MagickExport void *FileToBlob(const char *filename,const size_t extent,
954 size_t *length,ExceptionInfo *exception)
974 assert(filename != (const char *) NULL);
975 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
976 assert(exception != (ExceptionInfo *) NULL);
979 if (LocaleCompare(filename,"-") != 0)
980 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
983 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
986 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
988 if ((file == fileno(stdin)) || (offset < 0) ||
989 (offset != (MagickOffsetType) ((ssize_t) offset)))
998 Stream is not seekable.
1000 offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
1001 quantum=(size_t) MagickMaxBufferExtent;
1002 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1003 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
1004 MagickMaxBufferExtent);
1005 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1006 for (i=0; blob != (unsigned char *) NULL; i+=count)
1008 count=read(file,blob+i,quantum);
1015 if (~((size_t) i) < (quantum+1))
1017 blob=(unsigned char *) RelinquishMagickMemory(blob);
1020 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
1022 if ((size_t) (i+count) >= extent)
1025 if (LocaleCompare(filename,"-") != 0)
1027 if (blob == (unsigned char *) NULL)
1029 (void) ThrowMagickException(exception,GetMagickModule(),
1030 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1035 blob=(unsigned char *) RelinquishMagickMemory(blob);
1036 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1039 *length=(size_t) MagickMin(i+count,extent);
1043 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
1044 blob=(unsigned char *) NULL;
1045 if (~(*length) >= (MaxTextExtent-1))
1046 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
1048 if (blob == (unsigned char *) NULL)
1051 (void) ThrowMagickException(exception,GetMagickModule(),
1052 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1055 map=MapBlob(file,ReadMode,0,*length);
1056 if (map != (unsigned char *) NULL)
1058 (void) memcpy(blob,map,*length);
1059 (void) UnmapBlob(map,*length);
1063 (void) lseek(file,0,SEEK_SET);
1064 for (i=0; i < *length; i+=count)
1066 count=read(file,blob+i,(size_t) MagickMin(*length-i,(size_t)
1078 blob=(unsigned char *) RelinquishMagickMemory(blob);
1079 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1084 if (LocaleCompare(filename,"-") != 0)
1088 blob=(unsigned char *) RelinquishMagickMemory(blob);
1089 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1099 % F i l e T o I m a g e %
1103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1105 % FileToImage() write the contents of a file to an image.
1107 % The format of the FileToImage method is:
1109 % MagickBooleanType FileToImage(Image *,const char *filename)
1111 % A description of each parameter follows:
1113 % o image: the image.
1115 % o filename: the filename.
1119 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1125 register unsigned char
1128 assert(image->blob != (BlobInfo *) NULL);
1129 assert(image->blob->type != UndefinedStream);
1130 assert(data != NULL);
1131 if (image->blob->type != BlobStream)
1132 return(WriteBlob(image,length,data));
1133 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1134 if (extent >= image->blob->extent)
1136 extent=image->blob->extent+image->blob->quantum+length;
1137 image->blob->quantum<<=1;
1138 if (SetBlobExtent(image,extent) == MagickFalse)
1141 q=image->blob->data+image->blob->offset;
1142 (void) memcpy(q,data,length);
1143 image->blob->offset+=length;
1144 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1145 image->blob->length=(size_t) image->blob->offset;
1146 return((ssize_t) length);
1149 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1150 ExceptionInfo *exception)
1168 assert(image != (const Image *) NULL);
1169 assert(image->signature == MagickSignature);
1170 assert(filename != (const char *) NULL);
1171 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1173 if (LocaleCompare(filename,"-") != 0)
1174 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1177 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1178 return(MagickFalse);
1180 quantum=(size_t) MagickMaxBufferExtent;
1181 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1182 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1183 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1184 if (blob == (unsigned char *) NULL)
1187 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1189 return(MagickFalse);
1193 count=read(file,blob,quantum);
1200 length=(size_t) count;
1201 count=WriteBlobStream(image,length,blob);
1202 if (count != (ssize_t) length)
1204 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1210 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1211 blob=(unsigned char *) RelinquishMagickMemory(blob);
1217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1221 + G e t B l o b E r r o r %
1225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1227 % GetBlobError() returns MagickTrue if the blob associated with the specified
1228 % image encountered an error.
1230 % The format of the GetBlobError method is:
1232 % MagickBooleanType GetBlobError(const Image *image)
1234 % A description of each parameter follows:
1236 % o image: the image.
1239 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1241 assert(image != (const Image *) NULL);
1242 assert(image->signature == MagickSignature);
1243 if (image->debug != MagickFalse)
1244 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1245 return(image->blob->status);
1249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1253 + G e t B l o b F i l e H a n d l e %
1257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259 % GetBlobFileHandle() returns the file handle associated with the image blob.
1261 % The format of the GetBlobFile method is:
1263 % FILE *GetBlobFileHandle(const Image *image)
1265 % A description of each parameter follows:
1267 % o image: the image.
1270 MagickExport FILE *GetBlobFileHandle(const Image *image)
1272 assert(image != (const Image *) NULL);
1273 assert(image->signature == MagickSignature);
1274 return(image->blob->file_info.file);
1278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1282 + G e t B l o b I n f o %
1286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1288 % GetBlobInfo() initializes the BlobInfo structure.
1290 % The format of the GetBlobInfo method is:
1292 % void GetBlobInfo(BlobInfo *blob_info)
1294 % A description of each parameter follows:
1296 % o blob_info: Specifies a pointer to a BlobInfo structure.
1299 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1301 assert(blob_info != (BlobInfo *) NULL);
1302 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1303 blob_info->type=UndefinedStream;
1304 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1305 blob_info->properties.st_mtime=time((time_t *) NULL);
1306 blob_info->properties.st_ctime=time((time_t *) NULL);
1307 blob_info->debug=IsEventLogging();
1308 blob_info->reference_count=1;
1309 blob_info->semaphore=AcquireSemaphoreInfo();
1310 blob_info->signature=MagickSignature;
1314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318 % G e t B l o b P r o p e r t i e s %
1322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1324 % GetBlobProperties() returns information about an image blob.
1326 % The format of the GetBlobProperties method is:
1328 % const struct stat *GetBlobProperties(const Image *image)
1330 % A description of each parameter follows:
1332 % o image: the image.
1335 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1337 assert(image != (Image *) NULL);
1338 assert(image->signature == MagickSignature);
1339 if (image->debug != MagickFalse)
1340 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1341 return(&image->blob->properties);
1345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1349 + G e t B l o b S i z e %
1353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1355 % GetBlobSize() returns the current length of the image file or blob; zero is
1356 % returned if the size cannot be determined.
1358 % The format of the GetBlobSize method is:
1360 % MagickSizeType GetBlobSize(const Image *image)
1362 % A description of each parameter follows:
1364 % o image: the image.
1367 MagickExport MagickSizeType GetBlobSize(const Image *image)
1372 assert(image != (Image *) NULL);
1373 assert(image->signature == MagickSignature);
1374 if (image->debug != MagickFalse)
1375 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1376 assert(image->blob != (BlobInfo *) NULL);
1378 switch (image->blob->type)
1380 case UndefinedStream:
1382 extent=image->blob->size;
1385 case StandardStream:
1387 extent=image->blob->size;
1392 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1393 extent=(MagickSizeType) image->blob->properties.st_size;
1398 extent=image->blob->size;
1407 status=GetPathAttributes(image->filename,&image->blob->properties);
1408 if (status != MagickFalse)
1409 extent=(MagickSizeType) image->blob->properties.st_size;
1416 extent=(MagickSizeType) image->blob->length;
1424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 + G e t B l o b S t r e a m D a t a %
1432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1434 % GetBlobStreamData() returns the stream data for the image.
1436 % The format of the GetBlobStreamData method is:
1438 % void *GetBlobStreamData(const Image *image)
1440 % A description of each parameter follows:
1442 % o image: the image.
1445 MagickExport void *GetBlobStreamData(const Image *image)
1447 assert(image != (const Image *) NULL);
1448 assert(image->signature == MagickSignature);
1449 return(image->blob->data);
1453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1457 + G e t B l o b S t r e a m H a n d l e r %
1461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1463 % GetBlobStreamHandler() returns the stream handler for the image.
1465 % The format of the GetBlobStreamHandler method is:
1467 % StreamHandler GetBlobStreamHandler(const Image *image)
1469 % A description of each parameter follows:
1471 % o image: the image.
1474 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1476 assert(image != (const Image *) NULL);
1477 assert(image->signature == MagickSignature);
1478 if (image->debug != MagickFalse)
1479 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1480 return(image->blob->stream);
1484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1488 % I m a g e T o B l o b %
1492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1494 % ImageToBlob() implements direct to memory image formats. It returns the
1495 % image as a formatted blob and its length. The magick member of the Image
1496 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1497 % etc.). This method is the equivalent of WriteImage(), but writes the
1498 % formatted "file" to a memory buffer rather than to an actual file.
1500 % The format of the ImageToBlob method is:
1502 % void *ImageToBlob(const ImageInfo *image_info,Image *image,
1503 % size_t *length,ExceptionInfo *exception)
1505 % A description of each parameter follows:
1507 % o image_info: the image info.
1509 % o image: the image.
1511 % o length: return the actual length of the blob.
1513 % o exception: return any errors or warnings in this structure.
1516 MagickExport void *ImageToBlob(const ImageInfo *image_info,
1517 Image *image,size_t *length,ExceptionInfo *exception)
1531 assert(image_info != (const ImageInfo *) NULL);
1532 assert(image_info->signature == MagickSignature);
1533 if (image_info->debug != MagickFalse)
1534 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1535 image_info->filename);
1536 assert(image != (Image *) NULL);
1537 assert(image->signature == MagickSignature);
1538 assert(exception != (ExceptionInfo *) NULL);
1540 blob=(unsigned char *) NULL;
1541 blob_info=CloneImageInfo(image_info);
1542 blob_info->adjoin=MagickFalse;
1543 (void) SetImageInfo(blob_info,1,exception);
1544 if (*blob_info->magick != '\0')
1545 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1546 magick_info=GetMagickInfo(image->magick,exception);
1547 if (magick_info == (const MagickInfo *) NULL)
1549 (void) ThrowMagickException(exception,GetMagickModule(),
1550 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1552 blob_info=DestroyImageInfo(blob_info);
1555 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1556 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1559 Native blob support for this image format.
1561 blob_info->length=0;
1562 blob_info->blob=AcquireQuantumMemory(MagickMaxBlobExtent,
1563 sizeof(unsigned char));
1564 if (blob_info->blob == NULL)
1565 (void) ThrowMagickException(exception,GetMagickModule(),
1566 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1569 (void) CloseBlob(image);
1570 image->blob->exempt=MagickTrue;
1571 *image->filename='\0';
1572 status=WriteImage(blob_info,image,exception);
1573 *length=image->blob->length;
1574 blob=DetachBlob(image->blob);
1575 if (status == MagickFalse)
1576 blob=(unsigned char *) RelinquishMagickMemory(blob);
1578 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1585 unique[MaxTextExtent];
1591 Write file to disk in blob image format.
1593 file=AcquireUniqueFileResource(unique);
1596 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1597 image_info->filename);
1601 blob_info->file=fdopen(file,"wb");
1602 if (blob_info->file != (FILE *) NULL)
1604 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1605 image->magick,unique);
1606 status=WriteImage(blob_info,image,exception);
1607 (void) CloseBlob(image);
1608 (void) fclose(blob_info->file);
1609 if (status != MagickFalse)
1610 blob=FileToBlob(unique,~0UL,length,exception);
1612 (void) RelinquishUniqueFileResource(unique);
1615 blob_info=DestroyImageInfo(blob_info);
1620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1624 % I m a g e T o F i l e %
1628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1630 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1631 % occurs otherwise MagickTrue.
1633 % The format of the ImageToFile method is:
1635 % MagickBooleanType ImageToFile(Image *image,char *filename,
1636 % ExceptionInfo *exception)
1638 % A description of each parameter follows:
1640 % o image: the image.
1642 % o filename: Write the image to this file.
1644 % o exception: return any errors or warnings in this structure.
1647 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1648 ExceptionInfo *exception)
1653 register const unsigned char
1672 assert(image != (Image *) NULL);
1673 assert(image->signature == MagickSignature);
1674 assert(image->blob != (BlobInfo *) NULL);
1675 assert(image->blob->type != UndefinedStream);
1676 if (image->debug != MagickFalse)
1677 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1678 assert(filename != (const char *) NULL);
1679 if (*filename == '\0')
1680 file=AcquireUniqueFileResource(filename);
1682 if (LocaleCompare(filename,"-") == 0)
1683 file=fileno(stdout);
1685 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1688 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1689 return(MagickFalse);
1691 quantum=(size_t) MagickMaxBufferExtent;
1692 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1693 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
1694 MagickMaxBufferExtent);
1695 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1696 if (buffer == (unsigned char *) NULL)
1699 (void) ThrowMagickException(exception,GetMagickModule(),
1700 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1701 return(MagickFalse);
1704 p=ReadBlobStream(image,quantum,buffer,&count);
1705 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1707 length=(size_t) count;
1708 for (i=0; i < length; i+=count)
1710 count=write(file,p+i,(size_t) (length-i));
1721 if (LocaleCompare(filename,"-") != 0)
1723 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1724 if ((file == -1) || (i < length))
1728 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1729 return(MagickFalse);
1735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1739 % I m a g e s T o B l o b %
1743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1745 % ImagesToBlob() implements direct to memory image formats. It returns the
1746 % image sequence as a blob and its length. The magick member of the ImageInfo
1747 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1749 % Note, some image formats do not permit multiple images to the same image
1750 % stream (e.g. JPEG). in this instance, just the first image of the
1751 % sequence is returned as a blob.
1753 % The format of the ImagesToBlob method is:
1755 % void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1756 % size_t *length,ExceptionInfo *exception)
1758 % A description of each parameter follows:
1760 % o image_info: the image info.
1762 % o images: the image list.
1764 % o length: return the actual length of the blob.
1766 % o exception: return any errors or warnings in this structure.
1769 MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
1770 size_t *length,ExceptionInfo *exception)
1784 assert(image_info != (const ImageInfo *) NULL);
1785 assert(image_info->signature == MagickSignature);
1786 if (image_info->debug != MagickFalse)
1787 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1788 image_info->filename);
1789 assert(images != (Image *) NULL);
1790 assert(images->signature == MagickSignature);
1791 assert(exception != (ExceptionInfo *) NULL);
1793 blob=(unsigned char *) NULL;
1794 blob_info=CloneImageInfo(image_info);
1795 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1797 if (*blob_info->magick != '\0')
1798 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1799 magick_info=GetMagickInfo(images->magick,exception);
1800 if (magick_info == (const MagickInfo *) NULL)
1802 (void) ThrowMagickException(exception,GetMagickModule(),
1803 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1805 blob_info=DestroyImageInfo(blob_info);
1808 if (GetMagickAdjoin(magick_info) == MagickFalse)
1810 blob_info=DestroyImageInfo(blob_info);
1811 return(ImageToBlob(image_info,images,length,exception));
1813 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1814 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1817 Native blob support for this images format.
1819 blob_info->length=0;
1820 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1821 sizeof(unsigned char));
1822 if (blob_info->blob == (void *) NULL)
1823 (void) ThrowMagickException(exception,GetMagickModule(),
1824 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1827 (void) CloseBlob(images);
1828 images->blob->exempt=MagickTrue;
1829 *images->filename='\0';
1830 status=WriteImages(blob_info,images,images->filename,exception);
1831 *length=images->blob->length;
1832 blob=DetachBlob(images->blob);
1833 if (status == MagickFalse)
1834 blob=(unsigned char *) RelinquishMagickMemory(blob);
1836 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1843 filename[MaxTextExtent],
1844 unique[MaxTextExtent];
1850 Write file to disk in blob images format.
1852 file=AcquireUniqueFileResource(unique);
1855 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1856 image_info->filename);
1860 blob_info->file=fdopen(file,"wb");
1861 if (blob_info->file != (FILE *) NULL)
1863 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1864 images->magick,unique);
1865 status=WriteImages(blob_info,images,filename,exception);
1866 (void) CloseBlob(images);
1867 (void) fclose(blob_info->file);
1868 if (status != MagickFalse)
1869 blob=FileToBlob(unique,~0UL,length,exception);
1871 (void) RelinquishUniqueFileResource(unique);
1874 blob_info=DestroyImageInfo(blob_info);
1878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1882 % I n j e c t I m a g e B l o b %
1886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1888 % InjectImageBlob() injects the image with a copy of itself in the specified
1889 % format (e.g. inject JPEG into a PDF image).
1891 % The format of the InjectImageBlob method is:
1893 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1894 % Image *image,Image *inject_image,const char *format,
1895 % ExceptionInfo *exception)
1897 % A description of each parameter follows:
1899 % o image_info: the image info..
1901 % o image: the image.
1903 % o inject_image: inject into the image stream.
1905 % o format: the image format.
1907 % o exception: return any errors or warnings in this structure.
1910 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1911 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1914 filename[MaxTextExtent];
1947 Write inject image to a temporary file.
1949 assert(image_info != (ImageInfo *) NULL);
1950 assert(image_info->signature == MagickSignature);
1951 assert(image != (Image *) NULL);
1952 assert(image->signature == MagickSignature);
1953 if (image->debug != MagickFalse)
1954 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1955 assert(inject_image != (Image *) NULL);
1956 assert(inject_image->signature == MagickSignature);
1957 assert(exception != (ExceptionInfo *) NULL);
1958 unique_file=(FILE *) NULL;
1959 file=AcquireUniqueFileResource(filename);
1961 unique_file=fdopen(file,"wb");
1962 if ((file == -1) || (unique_file == (FILE *) NULL))
1964 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1965 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1967 return(MagickFalse);
1969 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1970 if (byte_image == (Image *) NULL)
1972 (void) fclose(unique_file);
1973 (void) RelinquishUniqueFileResource(filename);
1974 return(MagickFalse);
1976 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1978 DestroyBlob(byte_image);
1979 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1980 write_info=CloneImageInfo(image_info);
1981 SetImageInfoFile(write_info,unique_file);
1982 status=WriteImage(write_info,byte_image,exception);
1983 write_info=DestroyImageInfo(write_info);
1984 byte_image=DestroyImage(byte_image);
1985 (void) fclose(unique_file);
1986 if (status == MagickFalse)
1988 (void) RelinquishUniqueFileResource(filename);
1989 return(MagickFalse);
1992 Inject into image stream.
1994 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1997 (void) RelinquishUniqueFileResource(filename);
1998 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1999 image_info->filename);
2000 return(MagickFalse);
2002 quantum=(size_t) MagickMaxBufferExtent;
2003 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
2004 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
2005 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
2006 if (buffer == (unsigned char *) NULL)
2008 (void) RelinquishUniqueFileResource(filename);
2010 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2013 for (i=0; ; i+=count)
2015 count=read(file,buffer,quantum);
2022 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
2027 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
2028 (void) RelinquishUniqueFileResource(filename);
2029 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2038 + I s B l o b E x e m p t %
2042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2044 % IsBlobExempt() returns true if the blob is exempt.
2046 % The format of the IsBlobExempt method is:
2048 % MagickBooleanType IsBlobExempt(const Image *image)
2050 % A description of each parameter follows:
2052 % o image: the image.
2055 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
2057 assert(image != (const Image *) NULL);
2058 assert(image->signature == MagickSignature);
2059 if (image->debug != MagickFalse)
2060 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2061 return(image->blob->exempt);
2065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2069 + I s B l o b S e e k a b l e %
2073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2075 % IsBlobSeekable() returns true if the blob is seekable.
2077 % The format of the IsBlobSeekable method is:
2079 % MagickBooleanType IsBlobSeekable(const Image *image)
2081 % A description of each parameter follows:
2083 % o image: the image.
2086 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2091 assert(image != (const Image *) NULL);
2092 assert(image->signature == MagickSignature);
2093 if (image->debug != MagickFalse)
2094 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2095 switch (image->blob->type)
2101 seekable=MagickTrue;
2106 seekable=MagickFalse;
2114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2118 + I s B l o b T e m p o r a r y %
2122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2124 % IsBlobTemporary() returns true if the blob is temporary.
2126 % The format of the IsBlobTemporary method is:
2128 % MagickBooleanType IsBlobTemporary(const Image *image)
2130 % A description of each parameter follows:
2132 % o image: the image.
2135 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2137 assert(image != (const Image *) NULL);
2138 assert(image->signature == MagickSignature);
2139 if (image->debug != MagickFalse)
2140 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2141 return(image->blob->temporary);
2145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2155 % MapBlob() creates a mapping from a file to a binary large object.
2157 % The format of the MapBlob method is:
2159 % void *MapBlob(int file,const MapMode mode,const MagickOffsetType offset,
2160 % const size_t length)
2162 % A description of each parameter follows:
2164 % o file: map this file descriptor.
2166 % o mode: ReadMode, WriteMode, or IOMode.
2168 % o offset: starting at this offset within the file.
2170 % o length: the length of the mapping is returned in this pointer.
2173 MagickExport void *MapBlob(int file,const MapMode mode,
2174 const MagickOffsetType offset,const size_t length)
2176 #if defined(MAGICKCORE_HAVE_MMAP)
2189 #if defined(MAP_ANONYMOUS)
2190 flags|=MAP_ANONYMOUS;
2199 protection=PROT_READ;
2205 protection=PROT_WRITE;
2211 protection=PROT_READ | PROT_WRITE;
2216 #if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
2217 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2219 map=mmap((char *) NULL,length,protection,flags | MAP_HUGETLB,file,(off_t)
2221 if (map == MAP_FAILED)
2222 map=mmap((char *) NULL,length,protection,flags,file,(off_t) offset);
2224 if (map == MAP_FAILED)
2237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2241 + M S B O r d e r L o n g %
2245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2247 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2248 % most-significant byte first.
2250 % The format of the MSBOrderLong method is:
2252 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2254 % A description of each parameter follows.
2256 % o buffer: Specifies a pointer to a buffer of integers.
2258 % o length: Specifies the length of the buffer.
2261 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2266 register unsigned char
2270 assert(buffer != (unsigned char *) NULL);
2277 *buffer++=(unsigned char) c;
2281 *buffer++=(unsigned char) c;
2287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2291 + M S B O r d e r S h o r t %
2295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2297 % MSBOrderShort() converts a least-significant byte first buffer of integers
2298 % to most-significant byte first.
2300 % The format of the MSBOrderShort method is:
2302 % void MSBOrderShort(unsigned char *p,const size_t length)
2304 % A description of each parameter follows.
2306 % o p: Specifies a pointer to a buffer of integers.
2308 % o length: Specifies the length of the buffer.
2311 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2316 register unsigned char
2319 assert(p != (unsigned char *) NULL);
2326 *p++=(unsigned char) c;
2331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2341 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2342 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2343 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2344 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2345 % from a system command.
2347 % The format of the OpenBlob method is:
2349 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2350 % const BlobMode mode,ExceptionInfo *exception)
2352 % A description of each parameter follows:
2354 % o image_info: the image info.
2356 % o image: the image.
2358 % o mode: the mode for opening the file.
2362 static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
2375 option=GetImageOption(image_info,"stream:buffer-size");
2376 if (option != (const char *) NULL)
2377 size=StringToUnsignedLong(option);
2378 status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
2379 _IONBF : _IOFBF,size);
2380 return(status == 0 ? MagickTrue : MagickFalse);
2383 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2384 Image *image,const BlobMode mode,ExceptionInfo *exception)
2387 extension[MaxTextExtent],
2388 filename[MaxTextExtent];
2399 assert(image_info != (ImageInfo *) NULL);
2400 assert(image_info->signature == MagickSignature);
2401 if (image_info->debug != MagickFalse)
2402 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2403 image_info->filename);
2404 assert(image != (Image *) NULL);
2405 assert(image->signature == MagickSignature);
2406 if (image_info->blob != (void *) NULL)
2408 if (image_info->stream != (StreamHandler) NULL)
2409 image->blob->stream=(StreamHandler) image_info->stream;
2410 AttachBlob(image->blob,image_info->blob,image_info->length);
2413 (void) DetachBlob(image->blob);
2416 default: type="r"; break;
2417 case ReadBlobMode: type="r"; break;
2418 case ReadBinaryBlobMode: type="rb"; break;
2419 case WriteBlobMode: type="w"; break;
2420 case WriteBinaryBlobMode: type="w+b"; break;
2421 case AppendBlobMode: type="a"; break;
2422 case AppendBinaryBlobMode: type="a+b"; break;
2425 image->blob->synchronize=image_info->synchronize;
2426 if (image_info->stream != (StreamHandler) NULL)
2428 image->blob->stream=(StreamHandler) image_info->stream;
2431 image->blob->type=FifoStream;
2439 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2440 rights=ReadPolicyRights;
2442 rights=WritePolicyRights;
2443 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2446 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2447 "NotAuthorized","`%s'",filename);
2448 return(MagickFalse);
2450 if ((LocaleCompare(filename,"-") == 0) ||
2451 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2453 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2454 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2455 if (strchr(type,'b') != (char *) NULL)
2456 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2458 image->blob->type=StandardStream;
2459 image->blob->exempt=MagickTrue;
2460 return(SetStreamBuffering(image_info,image));
2462 if (LocaleNCompare(filename,"fd:",3) == 0)
2465 mode[MaxTextExtent];
2469 image->blob->file_info.file=fdopen(StringToLong(filename+3),mode);
2470 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2471 if (strchr(type,'b') != (char *) NULL)
2472 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2474 image->blob->type=StandardStream;
2475 image->blob->exempt=MagickTrue;
2476 return(SetStreamBuffering(image_info,image));
2478 #if defined(MAGICKCORE_HAVE_POPEN)
2479 if (*filename == '|')
2482 mode[MaxTextExtent];
2485 Pipe image to or from a system command.
2487 #if defined(SIGPIPE)
2489 (void) signal(SIGPIPE,SIG_IGN);
2493 image->blob->file_info.file=(FILE *) popen_utf8(filename+1,mode);
2494 if (image->blob->file_info.file == (FILE *) NULL)
2496 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2497 return(MagickFalse);
2499 image->blob->type=PipeStream;
2500 image->blob->exempt=MagickTrue;
2501 return(SetStreamBuffering(image_info,image));
2504 status=GetPathAttributes(filename,&image->blob->properties);
2505 #if defined(S_ISFIFO)
2506 if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
2508 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2509 if (image->blob->file_info.file == (FILE *) NULL)
2511 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2512 return(MagickFalse);
2514 image->blob->type=FileStream;
2515 image->blob->exempt=MagickTrue;
2516 return(SetStreamBuffering(image_info,image));
2519 GetPathComponent(image->filename,ExtensionPath,extension);
2522 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2523 if ((image_info->adjoin == MagickFalse) ||
2524 (strchr(filename,'%') != (char *) NULL))
2527 Form filename for multi-part images.
2529 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2530 image->scene,filename,exception);
2531 if ((LocaleCompare(filename,image->filename) == 0) &&
2532 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2533 (GetNextImageInList(image) != (Image *) NULL)))
2536 path[MaxTextExtent];
2538 GetPathComponent(image->filename,RootPath,path);
2539 if (*extension == '\0')
2540 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2541 path,(double) image->scene);
2543 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2544 path,(double) image->scene,extension);
2546 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2547 #if defined(macintosh)
2548 SetApplicationType(filename,image_info->magick,'8BIM');
2552 if (image_info->file != (FILE *) NULL)
2554 image->blob->file_info.file=image_info->file;
2555 image->blob->type=FileStream;
2556 image->blob->exempt=MagickTrue;
2561 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2562 if (image->blob->file_info.file != (FILE *) NULL)
2570 image->blob->type=FileStream;
2571 (void) SetStreamBuffering(image_info,image);
2572 (void) ResetMagickMemory(magick,0,sizeof(magick));
2573 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2574 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2575 (void) fflush(image->blob->file_info.file);
2576 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2577 " read %.20g magic header bytes",(double) count);
2578 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2579 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2580 ((int) magick[2] == 0x08))
2582 if (image->blob->file_info.file != (FILE *) NULL)
2583 (void) fclose(image->blob->file_info.file);
2584 image->blob->file_info.file=(FILE *) NULL;
2585 image->blob->file_info.gzfile=gzopen(filename,type);
2586 if (image->blob->file_info.gzfile != (gzFile) NULL)
2587 image->blob->type=ZipStream;
2590 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2591 if (strncmp((char *) magick,"BZh",3) == 0)
2593 if (image->blob->file_info.file != (FILE *) NULL)
2594 (void) fclose(image->blob->file_info.file);
2595 image->blob->file_info.file=(FILE *) NULL;
2596 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2597 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2598 image->blob->type=BZipStream;
2601 if (image->blob->type == FileStream)
2612 sans_exception=AcquireExceptionInfo();
2613 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2614 sans_exception=DestroyExceptionInfo(sans_exception);
2615 length=(size_t) image->blob->properties.st_size;
2616 if ((magick_info != (const MagickInfo *) NULL) &&
2617 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2618 (length > MagickMaxBufferExtent) &&
2619 (AcquireMagickResource(MapResource,length) != MagickFalse))
2624 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
2626 if (blob == (void *) NULL)
2627 RelinquishMagickResource(MapResource,length);
2631 Format supports blobs-- use memory-mapped I/O.
2633 if (image_info->file != (FILE *) NULL)
2634 image->blob->exempt=MagickFalse;
2637 (void) fclose(image->blob->file_info.file);
2638 image->blob->file_info.file=(FILE *) NULL;
2640 AttachBlob(image->blob,blob,length);
2641 image->blob->mapped=MagickTrue;
2648 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2649 if ((LocaleCompare(extension,"Z") == 0) ||
2650 (LocaleCompare(extension,"gz") == 0) ||
2651 (LocaleCompare(extension,"wmz") == 0) ||
2652 (LocaleCompare(extension,"svgz") == 0))
2654 if (mode == WriteBinaryBlobMode)
2656 image->blob->file_info.gzfile=gzopen(filename,type);
2657 if (image->blob->file_info.gzfile != (gzFile) NULL)
2658 image->blob->type=ZipStream;
2662 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2663 if (LocaleCompare(extension,"bz2") == 0)
2665 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2666 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2667 image->blob->type=BZipStream;
2672 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2673 if (image->blob->file_info.file != (FILE *) NULL)
2675 image->blob->type=FileStream;
2676 (void) SetStreamBuffering(image_info,image);
2679 image->blob->status=MagickFalse;
2680 if (image->blob->type != UndefinedStream)
2681 image->blob->size=GetBlobSize(image);
2684 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2685 return(MagickFalse);
2691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2701 % PingBlob() returns all the attributes of an image or image sequence except
2702 % for the pixels. It is much faster and consumes far less memory than
2703 % BlobToImage(). On failure, a NULL image is returned and exception
2704 % describes the reason for the failure.
2706 % The format of the PingBlob method is:
2708 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2709 % const size_t length,ExceptionInfo *exception)
2711 % A description of each parameter follows:
2713 % o image_info: the image info.
2715 % o blob: the address of a character stream in one of the image formats
2716 % understood by ImageMagick.
2718 % o length: This size_t integer reflects the length in bytes of the blob.
2720 % o exception: return any errors or warnings in this structure.
2724 #if defined(__cplusplus) || defined(c_plusplus)
2728 static size_t PingStream(const Image *magick_unused(image),
2729 const void *magick_unused(pixels),const size_t columns)
2734 #if defined(__cplusplus) || defined(c_plusplus)
2738 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2739 const size_t length,ExceptionInfo *exception)
2747 assert(image_info != (ImageInfo *) NULL);
2748 assert(image_info->signature == MagickSignature);
2749 if (image_info->debug != MagickFalse)
2750 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2751 image_info->filename);
2752 assert(exception != (ExceptionInfo *) NULL);
2753 if ((blob == (const void *) NULL) || (length == 0))
2755 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2756 "UnrecognizedImageFormat","`%s'",image_info->magick);
2757 return((Image *) NULL);
2759 ping_info=CloneImageInfo(image_info);
2760 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2761 if (ping_info->blob == (const void *) NULL)
2763 (void) ThrowMagickException(exception,GetMagickModule(),
2764 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2765 return((Image *) NULL);
2767 (void) memcpy(ping_info->blob,blob,length);
2768 ping_info->length=length;
2769 ping_info->ping=MagickTrue;
2770 image=ReadStream(ping_info,&PingStream,exception);
2771 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2772 ping_info=DestroyImageInfo(ping_info);
2777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2787 % ReadBlob() reads data from the blob or image file and returns it. It
2788 % returns the number of bytes read. If length is zero, ReadBlob() returns
2789 % zero and has no other results. If length is greater than SSIZE_MAX, the
2790 % result is unspecified.
2792 % The format of the ReadBlob method is:
2794 % ssize_t ReadBlob(Image *image,const size_t length,void *data)
2796 % A description of each parameter follows:
2798 % o image: the image.
2800 % o length: Specifies an integer representing the number of bytes to read
2803 % o data: Specifies an area to place the information requested from the
2807 MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
2812 register unsigned char
2818 assert(image != (Image *) NULL);
2819 assert(image->signature == MagickSignature);
2820 assert(image->blob != (BlobInfo *) NULL);
2821 assert(image->blob->type != UndefinedStream);
2824 assert(data != (void *) NULL);
2827 switch (image->blob->type)
2829 case UndefinedStream:
2831 case StandardStream:
2839 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
2844 c=getc(image->blob->file_info.file);
2847 *q++=(unsigned char) c;
2852 c=getc(image->blob->file_info.file);
2855 *q++=(unsigned char) c;
2860 c=getc(image->blob->file_info.file);
2863 *q++=(unsigned char) c;
2868 c=getc(image->blob->file_info.file);
2871 *q++=(unsigned char) c;
2881 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2886 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
2887 (unsigned int) length);
2892 c=gzgetc(image->blob->file_info.gzfile);
2895 *q++=(unsigned char) c;
2900 c=gzgetc(image->blob->file_info.gzfile);
2903 *q++=(unsigned char) c;
2908 c=gzgetc(image->blob->file_info.gzfile);
2911 *q++=(unsigned char) c;
2916 c=gzgetc(image->blob->file_info.gzfile);
2919 *q++=(unsigned char) c;
2930 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2931 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
2939 register const unsigned char
2942 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2944 image->blob->eof=MagickTrue;
2947 p=image->blob->data+image->blob->offset;
2948 count=(ssize_t) MagickMin((MagickOffsetType) length,image->blob->length-
2949 image->blob->offset);
2950 image->blob->offset+=count;
2951 if (count != (ssize_t) length)
2952 image->blob->eof=MagickTrue;
2953 (void) memcpy(q,p,(size_t) count);
2961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2965 + R e a d B l o b B y t e %
2969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2971 % ReadBlobByte() reads a single byte from the image file and returns it.
2973 % The format of the ReadBlobByte method is:
2975 % int ReadBlobByte(Image *image)
2977 % A description of each parameter follows.
2979 % o image: the image.
2982 MagickExport int ReadBlobByte(Image *image)
2984 register const unsigned char
2993 assert(image != (Image *) NULL);
2994 assert(image->signature == MagickSignature);
2995 p=ReadBlobStream(image,1,buffer,&count);
3002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3006 + R e a d B l o b D o u b l e %
3010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3012 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
3013 % specified by the endian member of the image structure.
3015 % The format of the ReadBlobDouble method is:
3017 % double ReadBlobDouble(Image *image)
3019 % A description of each parameter follows.
3021 % o image: the image.
3024 MagickExport double ReadBlobDouble(Image *image)
3035 quantum.double_value=0.0;
3036 quantum.unsigned_value=ReadBlobLongLong(image);
3037 return(quantum.double_value);
3041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3045 + R e a d B l o b F l o a t %
3049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3051 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
3052 % specified by the endian member of the image structure.
3054 % The format of the ReadBlobFloat method is:
3056 % float ReadBlobFloat(Image *image)
3058 % A description of each parameter follows.
3060 % o image: the image.
3063 MagickExport float ReadBlobFloat(Image *image)
3074 quantum.float_value=0.0;
3075 quantum.unsigned_value=ReadBlobLong(image);
3076 return(quantum.float_value);
3080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3084 + R e a d B l o b L o n g %
3088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3090 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
3091 % specified by the endian member of the image structure.
3093 % The format of the ReadBlobLong method is:
3095 % unsigned int ReadBlobLong(Image *image)
3097 % A description of each parameter follows.
3099 % o image: the image.
3102 MagickExport unsigned int ReadBlobLong(Image *image)
3104 register const unsigned char
3116 assert(image != (Image *) NULL);
3117 assert(image->signature == MagickSignature);
3119 p=ReadBlobStream(image,4,buffer,&count);
3122 if (image->endian == LSBEndian)
3124 value=(unsigned int) (*p++);
3125 value|=((unsigned int) (*p++)) << 8;
3126 value|=((unsigned int) (*p++)) << 16;
3127 value|=((unsigned int) (*p++)) << 24;
3130 value=((unsigned int) (*p++)) << 24;
3131 value|=((unsigned int) (*p++)) << 16;
3132 value|=((unsigned int) (*p++)) << 8;
3133 value|=((unsigned int) (*p++));
3138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3142 + R e a d B l o b L o n g L o n g %
3146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3148 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3149 % byte-order specified by the endian member of the image structure.
3151 % The format of the ReadBlobLongLong method is:
3153 % MagickSizeType ReadBlobLongLong(Image *image)
3155 % A description of each parameter follows.
3157 % o image: the image.
3160 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3165 register const unsigned char
3174 assert(image != (Image *) NULL);
3175 assert(image->signature == MagickSignature);
3177 p=ReadBlobStream(image,8,buffer,&count);
3179 return(MagickULLConstant(0));
3180 if (image->endian == LSBEndian)
3182 value=(MagickSizeType) (*p++);
3183 value|=((MagickSizeType) (*p++)) << 8;
3184 value|=((MagickSizeType) (*p++)) << 16;
3185 value|=((MagickSizeType) (*p++)) << 24;
3186 value|=((MagickSizeType) (*p++)) << 32;
3187 value|=((MagickSizeType) (*p++)) << 40;
3188 value|=((MagickSizeType) (*p++)) << 48;
3189 value|=((MagickSizeType) (*p++)) << 56;
3190 return(value & MagickULLConstant(0xffffffffffffffff));
3192 value=((MagickSizeType) (*p++)) << 56;
3193 value|=((MagickSizeType) (*p++)) << 48;
3194 value|=((MagickSizeType) (*p++)) << 40;
3195 value|=((MagickSizeType) (*p++)) << 32;
3196 value|=((MagickSizeType) (*p++)) << 24;
3197 value|=((MagickSizeType) (*p++)) << 16;
3198 value|=((MagickSizeType) (*p++)) << 8;
3199 value|=((MagickSizeType) (*p++));
3200 return(value & MagickULLConstant(0xffffffffffffffff));
3204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3208 + R e a d B l o b S h o r t %
3212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3214 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3215 % specified by the endian member of the image structure.
3217 % The format of the ReadBlobShort method is:
3219 % unsigned short ReadBlobShort(Image *image)
3221 % A description of each parameter follows.
3223 % o image: the image.
3226 MagickExport unsigned short ReadBlobShort(Image *image)
3228 register const unsigned char
3231 register unsigned int
3240 assert(image != (Image *) NULL);
3241 assert(image->signature == MagickSignature);
3243 p=ReadBlobStream(image,2,buffer,&count);
3245 return((unsigned short) 0U);
3246 if (image->endian == LSBEndian)
3248 value=(unsigned int) (*p++);
3249 value|=((unsigned int) (*p++)) << 8;
3250 return((unsigned short) (value & 0xffff));
3252 value=(unsigned int) ((*p++) << 8);
3253 value|=(unsigned int) (*p++);
3254 return((unsigned short) (value & 0xffff));
3258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3262 + R e a d B l o b L S B L o n g %
3266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3268 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3269 % least-significant byte first order.
3271 % The format of the ReadBlobLSBLong method is:
3273 % unsigned int ReadBlobLSBLong(Image *image)
3275 % A description of each parameter follows.
3277 % o image: the image.
3280 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3282 register const unsigned char
3285 register unsigned int
3294 assert(image != (Image *) NULL);
3295 assert(image->signature == MagickSignature);
3297 p=ReadBlobStream(image,4,buffer,&count);
3300 value=(unsigned int) (*p++);
3301 value|=((unsigned int) (*p++)) << 8;
3302 value|=((unsigned int) (*p++)) << 16;
3303 value|=((unsigned int) (*p++)) << 24;
3308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3312 + R e a d B l o b L S B S h o r t %
3316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3318 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3319 % least-significant byte first order.
3321 % The format of the ReadBlobLSBShort method is:
3323 % unsigned short ReadBlobLSBShort(Image *image)
3325 % A description of each parameter follows.
3327 % o image: the image.
3330 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3332 register const unsigned char
3335 register unsigned int
3344 assert(image != (Image *) NULL);
3345 assert(image->signature == MagickSignature);
3347 p=ReadBlobStream(image,2,buffer,&count);
3349 return((unsigned short) 0U);
3350 value=(unsigned int) (*p++);
3351 value|=((unsigned int) ((*p++)) << 8);
3352 return((unsigned short) (value & 0xffff));
3356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3360 + R e a d B l o b M S B L o n g %
3364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3366 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3367 % most-significant byte first order.
3369 % The format of the ReadBlobMSBLong method is:
3371 % unsigned int ReadBlobMSBLong(Image *image)
3373 % A description of each parameter follows.
3375 % o image: the image.
3378 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3380 register const unsigned char
3383 register unsigned int
3392 assert(image != (Image *) NULL);
3393 assert(image->signature == MagickSignature);
3395 p=ReadBlobStream(image,4,buffer,&count);
3398 value=((unsigned int) (*p++) << 24);
3399 value|=((unsigned int) (*p++) << 16);
3400 value|=((unsigned int) (*p++) << 8);
3401 value|=(unsigned int) (*p++);
3406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3410 + R e a d B l o b M S B L o n g L o n g %
3414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3416 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3417 % most-significant byte first order.
3419 % The format of the ReadBlobMSBLongLong method is:
3421 % unsigned int ReadBlobMSBLongLong(Image *image)
3423 % A description of each parameter follows.
3425 % o image: the image.
3428 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3430 register const unsigned char
3433 register MagickSizeType
3442 assert(image != (Image *) NULL);
3443 assert(image->signature == MagickSignature);
3445 p=ReadBlobStream(image,8,buffer,&count);
3447 return(MagickULLConstant(0));
3448 value=((MagickSizeType) (*p++)) << 56;
3449 value|=((MagickSizeType) (*p++)) << 48;
3450 value|=((MagickSizeType) (*p++)) << 40;
3451 value|=((MagickSizeType) (*p++)) << 32;
3452 value|=((MagickSizeType) (*p++)) << 24;
3453 value|=((MagickSizeType) (*p++)) << 16;
3454 value|=((MagickSizeType) (*p++)) << 8;
3455 value|=((MagickSizeType) (*p++));
3456 return(value & MagickULLConstant(0xffffffffffffffff));
3460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3464 + R e a d B l o b M S B S h o r t %
3468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3470 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3471 % most-significant byte first order.
3473 % The format of the ReadBlobMSBShort method is:
3475 % unsigned short ReadBlobMSBShort(Image *image)
3477 % A description of each parameter follows.
3479 % o image: the image.
3482 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3484 register const unsigned char
3487 register unsigned int
3496 assert(image != (Image *) NULL);
3497 assert(image->signature == MagickSignature);
3499 p=ReadBlobStream(image,2,buffer,&count);
3501 return((unsigned short) 0U);
3502 value=(unsigned int) ((*p++) << 8);
3503 value|=(unsigned int) (*p++);
3504 return((unsigned short) (value & 0xffff));
3508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3512 + R e a d B l o b S t r e a m %
3516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3518 % ReadBlobStream() reads data from the blob or image file and returns it. It
3519 % returns a pointer to the data buffer you supply or to the image memory
3520 % buffer if its supported (zero-copy). If length is zero, ReadBlobStream()
3521 % returns a count of zero and has no other results. If length is greater than
3522 % SSIZE_MAX, the result is unspecified.
3524 % The format of the ReadBlobStream method is:
3526 % const void *ReadBlobStream(Image *image,const size_t length,void *data,
3529 % A description of each parameter follows:
3531 % o image: the image.
3533 % o length: Specifies an integer representing the number of bytes to read
3536 % o count: returns the number of bytes read.
3538 % o data: Specifies an area to place the information requested from the
3542 MagickExport const void *ReadBlobStream(Image *image,const size_t length,
3543 void *data,ssize_t *count)
3545 assert(image != (Image *) NULL);
3546 assert(image->signature == MagickSignature);
3547 assert(image->blob != (BlobInfo *) NULL);
3548 assert(image->blob->type != UndefinedStream);
3549 assert(count != (ssize_t *) NULL);
3550 if (image->blob->type != BlobStream)
3552 assert(data != NULL);
3553 *count=ReadBlob(image,length,data);
3556 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3559 image->blob->eof=MagickTrue;
3562 data=image->blob->data+image->blob->offset;
3563 *count=(ssize_t) MagickMin((MagickOffsetType) length,image->blob->length-
3564 image->blob->offset);
3565 image->blob->offset+=(*count);
3566 if (*count != (ssize_t) length)
3567 image->blob->eof=MagickTrue;
3572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3576 + R e a d B l o b S t r i n g %
3580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3582 % ReadBlobString() reads characters from a blob or file until a newline
3583 % character is read or an end-of-file condition is encountered.
3585 % The format of the ReadBlobString method is:
3587 % char *ReadBlobString(Image *image,char *string)
3589 % A description of each parameter follows:
3591 % o image: the image.
3593 % o string: the address of a character buffer.
3596 MagickExport char *ReadBlobString(Image *image,char *string)
3598 register const unsigned char
3610 assert(image != (Image *) NULL);
3611 assert(image->signature == MagickSignature);
3612 for (i=0; i < (MaxTextExtent-1L); i++)
3614 p=ReadBlobStream(image,1,buffer,&count);
3618 return((char *) NULL);
3621 string[i]=(char) (*p);
3622 if ((string[i] == '\r') || (string[i] == '\n'))
3625 if (string[i] == '\r')
3626 (void) ReadBlobStream(image,1,buffer,&count);
3632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3636 + R e f e r e n c e B l o b %
3640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3642 % ReferenceBlob() increments the reference count associated with the pixel
3643 % blob returning a pointer to the blob.
3645 % The format of the ReferenceBlob method is:
3647 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3649 % A description of each parameter follows:
3651 % o blob_info: the blob_info.
3654 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3656 assert(blob != (BlobInfo *) NULL);
3657 assert(blob->signature == MagickSignature);
3658 if (blob->debug != MagickFalse)
3659 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3660 LockSemaphoreInfo(blob->semaphore);
3661 blob->reference_count++;
3662 UnlockSemaphoreInfo(blob->semaphore);
3667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3677 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3678 % and returns the resulting offset.
3680 % The format of the SeekBlob method is:
3682 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3685 % A description of each parameter follows:
3687 % o image: the image.
3689 % o offset: Specifies an integer representing the offset in bytes.
3691 % o whence: Specifies an integer representing how the offset is
3692 % treated relative to the beginning of the blob as follows:
3694 % SEEK_SET Set position equal to offset bytes.
3695 % SEEK_CUR Set position to current location plus offset.
3696 % SEEK_END Set position to EOF plus offset.
3699 MagickExport MagickOffsetType SeekBlob(Image *image,
3700 const MagickOffsetType offset,const int whence)
3702 assert(image != (Image *) NULL);
3703 assert(image->signature == MagickSignature);
3704 if (image->debug != MagickFalse)
3705 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3706 assert(image->blob != (BlobInfo *) NULL);
3707 assert(image->blob->type != UndefinedStream);
3708 switch (image->blob->type)
3710 case UndefinedStream:
3712 case StandardStream:
3716 if ((whence == SEEK_SET) && (offset < 0))
3718 if (fseek(image->blob->file_info.file,offset,whence) < 0)
3720 image->blob->offset=TellBlob(image);
3726 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3727 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
3730 image->blob->offset=TellBlob(image);
3746 image->blob->offset=offset;
3751 if ((image->blob->offset+offset) < 0)
3753 image->blob->offset+=offset;
3758 if (((MagickOffsetType) image->blob->length+offset) < 0)
3760 image->blob->offset=image->blob->length+offset;
3764 if (image->blob->offset < (MagickOffsetType)
3765 ((off_t) image->blob->length))
3767 image->blob->eof=MagickFalse;
3770 if (image->blob->mapped != MagickFalse)
3772 if (image->blob->offset < (MagickOffsetType)
3773 ((off_t) image->blob->extent))
3775 image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
3776 image->blob->quantum<<=1;
3777 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3778 image->blob->extent+1,sizeof(*image->blob->data));
3779 (void) SyncBlob(image);
3780 if (image->blob->data == NULL)
3782 (void) DetachBlob(image->blob);
3788 return(image->blob->offset);
3792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3796 + S e t B l o b E x e m p t %
3800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3802 % SetBlobExempt() sets the blob exempt status.
3804 % The format of the SetBlobExempt method is:
3806 % MagickBooleanType SetBlobExempt(const Image *image,
3807 % const MagickBooleanType exempt)
3809 % A description of each parameter follows:
3811 % o image: the image.
3813 % o exempt: Set to true if this blob is exempt from being closed.
3816 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3818 assert(image != (const Image *) NULL);
3819 assert(image->signature == MagickSignature);
3820 if (image->debug != MagickFalse)
3821 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3822 image->blob->exempt=exempt;
3826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3830 + S e t B l o b E x t e n t %
3834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3836 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3837 % method is successful, subsequent writes to bytes in the specified range are
3838 % guaranteed not to fail.
3840 % The format of the SetBlobExtent method is:
3842 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3844 % A description of each parameter follows:
3846 % o image: the image.
3848 % o extent: the blob maximum extent.
3851 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3852 const MagickSizeType extent)
3854 assert(image != (Image *) NULL);
3855 assert(image->signature == MagickSignature);
3856 if (image->debug != MagickFalse)
3857 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3858 assert(image->blob != (BlobInfo *) NULL);
3859 assert(image->blob->type != UndefinedStream);
3860 switch (image->blob->type)
3862 case UndefinedStream:
3864 case StandardStream:
3865 return(MagickFalse);
3874 if (extent != (MagickSizeType) ((off_t) extent))
3875 return(MagickFalse);
3876 offset=SeekBlob(image,0,SEEK_END);
3878 return(MagickFalse);
3879 if ((MagickSizeType) offset >= extent)
3881 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3884 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3885 image->blob->file_info.file);
3886 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3887 if (image->blob->synchronize != MagickFalse)
3892 file=fileno(image->blob->file_info.file);
3893 if ((file == -1) || (offset < 0))
3894 return(MagickFalse);
3895 (void) posix_fallocate(file,offset,extent-offset);
3898 offset=SeekBlob(image,offset,SEEK_SET);
3900 return(MagickFalse);
3905 return(MagickFalse);
3907 return(MagickFalse);
3909 return(MagickFalse);
3912 if (extent != (MagickSizeType) ((size_t) extent))
3913 return(MagickFalse);
3914 if (image->blob->mapped != MagickFalse)
3922 (void) UnmapBlob(image->blob->data,image->blob->length);
3923 RelinquishMagickResource(MapResource,image->blob->length);
3924 if (extent != (MagickSizeType) ((off_t) extent))
3925 return(MagickFalse);
3926 offset=SeekBlob(image,0,SEEK_END);
3928 return(MagickFalse);
3929 if ((MagickSizeType) offset >= extent)
3931 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3932 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3933 image->blob->file_info.file);
3934 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3935 if (image->blob->synchronize != MagickFalse)
3940 file=fileno(image->blob->file_info.file);
3941 if ((file == -1) || (offset < 0))
3942 return(MagickFalse);
3943 (void) posix_fallocate(file,offset,extent-offset);
3946 offset=SeekBlob(image,offset,SEEK_SET);
3948 return(MagickFalse);
3949 (void) AcquireMagickResource(MapResource,extent);
3950 image->blob->data=(unsigned char*) MapBlob(fileno(
3951 image->blob->file_info.file),WriteMode,0,(size_t) extent);
3952 image->blob->extent=(size_t) extent;
3953 image->blob->length=(size_t) extent;
3954 (void) SyncBlob(image);
3957 image->blob->extent=(size_t) extent;
3958 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3959 image->blob->extent+1,sizeof(*image->blob->data));
3960 (void) SyncBlob(image);
3961 if (image->blob->data == (unsigned char *) NULL)
3963 (void) DetachBlob(image->blob);
3964 return(MagickFalse);
3973 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3981 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3983 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3984 % attributes if it is an blob.
3986 % The format of the SyncBlob method is:
3988 % int SyncBlob(Image *image)
3990 % A description of each parameter follows:
3992 % o image: the image.
3995 static int SyncBlob(Image *image)
4000 assert(image != (Image *) NULL);
4001 assert(image->signature == MagickSignature);
4002 if (image->debug != MagickFalse)
4003 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4004 assert(image->blob != (BlobInfo *) NULL);
4005 assert(image->blob->type != UndefinedStream);
4007 switch (image->blob->type)
4009 case UndefinedStream:
4010 case StandardStream:
4015 status=fflush(image->blob->file_info.file);
4020 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4021 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
4027 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4028 status=BZ2_bzflush(image->blob->file_info.bzfile);
4041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4051 % TellBlob() obtains the current value of the blob or file position.
4053 % The format of the TellBlob method is:
4055 % MagickOffsetType TellBlob(const Image *image)
4057 % A description of each parameter follows:
4059 % o image: the image.
4062 MagickExport MagickOffsetType TellBlob(const Image *image)
4067 assert(image != (Image *) NULL);
4068 assert(image->signature == MagickSignature);
4069 if (image->debug != MagickFalse)
4070 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4071 assert(image->blob != (BlobInfo *) NULL);
4072 assert(image->blob->type != UndefinedStream);
4074 switch (image->blob->type)
4076 case UndefinedStream:
4077 case StandardStream:
4081 offset=ftell(image->blob->file_info.file);
4088 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4089 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
4099 offset=image->blob->offset;
4107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4111 + U n m a p B l o b %
4115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4117 % UnmapBlob() deallocates the binary large object previously allocated with
4118 % the MapBlob method.
4120 % The format of the UnmapBlob method is:
4122 % MagickBooleanType UnmapBlob(void *map,const size_t length)
4124 % A description of each parameter follows:
4126 % o map: the address of the binary large object.
4128 % o length: the length of the binary large object.
4131 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
4133 #if defined(MAGICKCORE_HAVE_MMAP)
4137 status=munmap(map,length);
4138 return(status == -1 ? MagickFalse : MagickTrue);
4142 return(MagickFalse);
4147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4151 + W r i t e B l o b %
4155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4157 % WriteBlob() writes data to a blob or image file. It returns the number of
4160 % The format of the WriteBlob method is:
4162 % ssize_t WriteBlob(Image *image,const size_t length,
4163 % const unsigned char *data)
4165 % A description of each parameter follows:
4167 % o image: the image.
4169 % o length: Specifies an integer representing the number of bytes to
4170 % write to the file.
4172 % o data: The address of the data to write to the blob or file.
4175 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4176 const unsigned char *data)
4181 register const unsigned char
4187 assert(image != (Image *) NULL);
4188 assert(image->signature == MagickSignature);
4189 assert(data != (const unsigned char *) NULL);
4190 assert(image->blob != (BlobInfo *) NULL);
4191 assert(image->blob->type != UndefinedStream);
4196 switch (image->blob->type)
4198 case UndefinedStream:
4200 case StandardStream:
4208 count=(ssize_t) fwrite((const char *) data,1,length,
4209 image->blob->file_info.file);
4214 c=putc((int) *p++,image->blob->file_info.file);
4221 c=putc((int) *p++,image->blob->file_info.file);
4228 c=putc((int) *p++,image->blob->file_info.file);
4235 c=putc((int) *p++,image->blob->file_info.file);
4247 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4252 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4253 (unsigned int) length);
4258 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4265 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4272 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4279 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4292 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4293 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
4300 count=(ssize_t) image->blob->stream(image,data,length);
4305 register unsigned char
4308 if ((image->blob->offset+(MagickOffsetType) length) >=
4309 (MagickOffsetType) image->blob->extent)
4311 if (image->blob->mapped != MagickFalse)
4313 image->blob->extent+=length+image->blob->quantum;
4314 image->blob->quantum<<=1;
4315 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4316 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4317 (void) SyncBlob(image);
4318 if (image->blob->data == (unsigned char *) NULL)
4320 (void) DetachBlob(image->blob);
4324 q=image->blob->data+image->blob->offset;
4325 (void) memcpy(q,p,length);
4326 image->blob->offset+=length;
4327 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4328 image->blob->length=(size_t) image->blob->offset;
4329 count=(ssize_t) length;
4336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4340 + W r i t e B l o b B y t e %
4344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4346 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4347 % written (either 0 or 1);
4349 % The format of the WriteBlobByte method is:
4351 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4353 % A description of each parameter follows.
4355 % o image: the image.
4357 % o value: Specifies the value to write.
4360 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4362 assert(image != (Image *) NULL);
4363 assert(image->signature == MagickSignature);
4364 return(WriteBlobStream(image,1,&value));
4368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4372 + W r i t e B l o b F l o a t %
4376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4378 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4379 % specified by the endian member of the image structure.
4381 % The format of the WriteBlobFloat method is:
4383 % ssize_t WriteBlobFloat(Image *image,const float value)
4385 % A description of each parameter follows.
4387 % o image: the image.
4389 % o value: Specifies the value to write.
4392 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4403 quantum.unsigned_value=0U;
4404 quantum.float_value=value;
4405 return(WriteBlobLong(image,quantum.unsigned_value));
4409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4413 + W r i t e B l o b L o n g %
4417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4419 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4420 % specified by the endian member of the image structure.
4422 % The format of the WriteBlobLong method is:
4424 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4426 % A description of each parameter follows.
4428 % o image: the image.
4430 % o value: Specifies the value to write.
4433 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4438 assert(image != (Image *) NULL);
4439 assert(image->signature == MagickSignature);
4440 if (image->endian == LSBEndian)
4442 buffer[0]=(unsigned char) value;
4443 buffer[1]=(unsigned char) (value >> 8);
4444 buffer[2]=(unsigned char) (value >> 16);
4445 buffer[3]=(unsigned char) (value >> 24);
4446 return(WriteBlobStream(image,4,buffer));
4448 buffer[0]=(unsigned char) (value >> 24);
4449 buffer[1]=(unsigned char) (value >> 16);
4450 buffer[2]=(unsigned char) (value >> 8);
4451 buffer[3]=(unsigned char) value;
4452 return(WriteBlobStream(image,4,buffer));
4456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4460 + W r i t e B l o b S h o r t %
4464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4466 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4467 % byte-order specified by the endian member of the image structure.
4469 % The format of the WriteBlobShort method is:
4471 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4473 % A description of each parameter follows.
4475 % o image: the image.
4477 % o value: Specifies the value to write.
4480 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4485 assert(image != (Image *) NULL);
4486 assert(image->signature == MagickSignature);
4487 if (image->endian == LSBEndian)
4489 buffer[0]=(unsigned char) value;
4490 buffer[1]=(unsigned char) (value >> 8);
4491 return(WriteBlobStream(image,2,buffer));
4493 buffer[0]=(unsigned char) (value >> 8);
4494 buffer[1]=(unsigned char) value;
4495 return(WriteBlobStream(image,2,buffer));
4499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4503 + W r i t e B l o b L S B L o n g %
4507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4509 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4510 % least-significant byte first order.
4512 % The format of the WriteBlobLSBLong method is:
4514 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4516 % A description of each parameter follows.
4518 % o image: the image.
4520 % o value: Specifies the value to write.
4523 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4528 assert(image != (Image *) NULL);
4529 assert(image->signature == MagickSignature);
4530 buffer[0]=(unsigned char) value;
4531 buffer[1]=(unsigned char) (value >> 8);
4532 buffer[2]=(unsigned char) (value >> 16);
4533 buffer[3]=(unsigned char) (value >> 24);
4534 return(WriteBlobStream(image,4,buffer));
4538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4542 + W r i t e B l o b L S B S h o r t %
4546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4548 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4549 % least-significant byte first order.
4551 % The format of the WriteBlobLSBShort method is:
4553 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4555 % A description of each parameter follows.
4557 % o image: the image.
4559 % o value: Specifies the value to write.
4562 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4567 assert(image != (Image *) NULL);
4568 assert(image->signature == MagickSignature);
4569 buffer[0]=(unsigned char) value;
4570 buffer[1]=(unsigned char) (value >> 8);
4571 return(WriteBlobStream(image,2,buffer));
4575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4579 + W r i t e B l o b M S B L o n g %
4583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4585 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4586 % most-significant byte first order.
4588 % The format of the WriteBlobMSBLong method is:
4590 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4592 % A description of each parameter follows.
4594 % o value: Specifies the value to write.
4596 % o image: the image.
4599 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4604 assert(image != (Image *) NULL);
4605 assert(image->signature == MagickSignature);
4606 buffer[0]=(unsigned char) (value >> 24);
4607 buffer[1]=(unsigned char) (value >> 16);
4608 buffer[2]=(unsigned char) (value >> 8);
4609 buffer[3]=(unsigned char) value;
4610 return(WriteBlobStream(image,4,buffer));
4614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4618 + W r i t e B l o b M S B L o n g L o n g %
4622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4624 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4625 % most-significant byte first order.
4627 % The format of the WriteBlobMSBLongLong method is:
4629 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4631 % A description of each parameter follows.
4633 % o value: Specifies the value to write.
4635 % o image: the image.
4638 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4639 const MagickSizeType value)
4644 assert(image != (Image *) NULL);
4645 assert(image->signature == MagickSignature);
4646 buffer[0]=(unsigned char) (value >> 56);
4647 buffer[1]=(unsigned char) (value >> 48);
4648 buffer[2]=(unsigned char) (value >> 40);
4649 buffer[3]=(unsigned char) (value >> 32);
4650 buffer[4]=(unsigned char) (value >> 24);
4651 buffer[5]=(unsigned char) (value >> 16);
4652 buffer[6]=(unsigned char) (value >> 8);
4653 buffer[7]=(unsigned char) value;
4654 return(WriteBlobStream(image,8,buffer));
4658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4662 + W r i t e B l o b M S B S h o r t %
4666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4668 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4669 % most-significant byte first order.
4671 % The format of the WriteBlobMSBShort method is:
4673 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4675 % A description of each parameter follows.
4677 % o value: Specifies the value to write.
4679 % o file: Specifies the file to write the data to.
4682 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4687 assert(image != (Image *) NULL);
4688 assert(image->signature == MagickSignature);
4689 buffer[0]=(unsigned char) (value >> 8);
4690 buffer[1]=(unsigned char) value;
4691 return(WriteBlobStream(image,2,buffer));
4695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4699 + W r i t e B l o b S t r i n g %
4703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4705 % WriteBlobString() write a string to a blob. It returns the number of
4706 % characters written.
4708 % The format of the WriteBlobString method is:
4710 % ssize_t WriteBlobString(Image *image,const char *string)
4712 % A description of each parameter follows.
4714 % o image: the image.
4716 % o string: Specifies the string to write.
4719 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4721 assert(image != (Image *) NULL);
4722 assert(image->signature == MagickSignature);
4723 assert(string != (const char *) NULL);
4724 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));