2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2013 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/nt-base-private.h"
45 #include "MagickCore/blob.h"
46 #include "MagickCore/blob-private.h"
47 #include "MagickCore/cache.h"
48 #include "MagickCore/client.h"
49 #include "MagickCore/constitute.h"
50 #include "MagickCore/delegate.h"
51 #include "MagickCore/exception.h"
52 #include "MagickCore/exception-private.h"
53 #include "MagickCore/image-private.h"
54 #include "MagickCore/list.h"
55 #include "MagickCore/locale_.h"
56 #include "MagickCore/log.h"
57 #include "MagickCore/magick.h"
58 #include "MagickCore/memory_.h"
59 #include "MagickCore/policy.h"
60 #include "MagickCore/resource_.h"
61 #include "MagickCore/semaphore.h"
62 #include "MagickCore/string_.h"
63 #include "MagickCore/string-private.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/utility.h"
66 #include "MagickCore/utility-private.h"
67 #if defined(MAGICKCORE_ZLIB_DELEGATE)
70 #if defined(MAGICKCORE_BZLIB_DELEGATE)
77 #define MagickMaxBlobExtent 65541
78 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
79 # define MAP_ANONYMOUS MAP_ANON
81 #if !defined(MAP_FAILED)
82 #define MAP_FAILED ((void *) -1)
89 #define _O_BINARY O_BINARY
95 typedef union FileInfo
100 #if defined(MAGICKCORE_ZLIB_DELEGATE)
105 #if defined(MAGICKCORE_BZLIB_DELEGATE)
163 Forward declarations.
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 + A t t a c h B l o b %
177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179 % AttachBlob() attaches a blob to the BlobInfo structure.
181 % The format of the AttachBlob method is:
183 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
185 % A description of each parameter follows:
187 % o blob_info: Specifies a pointer to a BlobInfo structure.
189 % o blob: the address of a character stream in one of the image formats
190 % understood by ImageMagick.
192 % o length: This size_t integer reflects the length in bytes of the blob.
195 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
198 assert(blob_info != (BlobInfo *) NULL);
199 if (blob_info->debug != MagickFalse)
200 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
201 blob_info->length=length;
202 blob_info->extent=length;
203 blob_info->quantum=(size_t) MagickMaxBlobExtent;
205 blob_info->type=BlobStream;
206 blob_info->file_info.file=(FILE *) NULL;
207 blob_info->data=(unsigned char *) blob;
208 blob_info->mapped=MagickFalse;
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216 + B l o b T o F i l e %
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
223 % occurs otherwise MagickTrue.
225 % The format of the BlobToFile method is:
227 % MagickBooleanType BlobToFile(char *filename,const void *blob,
228 % const size_t length,ExceptionInfo *exception)
230 % A description of each parameter follows:
232 % o filename: Write the blob to this file.
234 % o blob: the address of a blob.
236 % o length: This length in bytes of the blob.
238 % o exception: return any errors or warnings in this structure.
242 static inline MagickSizeType MagickMin(const MagickSizeType x,
243 const MagickSizeType y)
250 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
251 const size_t length,ExceptionInfo *exception)
262 assert(filename != (const char *) NULL);
263 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
264 assert(blob != (const void *) NULL);
265 if (*filename == '\0')
266 file=AcquireUniqueFileResource(filename);
268 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
271 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
274 for (i=0; i < length; i+=count)
276 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
277 i,(MagickSizeType) SSIZE_MAX));
286 if ((file == -1) || (i < length))
288 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299 % B l o b T o I m a g e %
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 % BlobToImage() implements direct to memory image formats. It returns the
308 % The format of the BlobToImage method is:
310 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
311 % const size_t length,ExceptionInfo *exception)
313 % A description of each parameter follows:
315 % o image_info: the image info.
317 % o blob: the address of a character stream in one of the image formats
318 % understood by ImageMagick.
320 % o length: This size_t integer reflects the length in bytes of the blob.
322 % o exception: return any errors or warnings in this structure.
325 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
326 const size_t length,ExceptionInfo *exception)
341 assert(image_info != (ImageInfo *) NULL);
342 assert(image_info->signature == MagickSignature);
343 if (image_info->debug != MagickFalse)
344 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
345 image_info->filename);
346 assert(exception != (ExceptionInfo *) NULL);
347 if ((blob == (const void *) NULL) || (length == 0))
349 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
350 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
351 return((Image *) NULL);
353 blob_info=CloneImageInfo(image_info);
354 blob_info->blob=(void *) blob;
355 blob_info->length=length;
356 if (*blob_info->magick == '\0')
357 (void) SetImageInfo(blob_info,0,exception);
358 magick_info=GetMagickInfo(blob_info->magick,exception);
359 if (magick_info == (const MagickInfo *) NULL)
361 blob_info=DestroyImageInfo(blob_info);
362 (void) ThrowMagickException(exception,GetMagickModule(),
363 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
364 image_info->filename);
365 return((Image *) NULL);
367 if (GetMagickBlobSupport(magick_info) != MagickFalse)
370 Native blob support for this image format.
372 (void) CopyMagickString(blob_info->filename,image_info->filename,
374 (void) CopyMagickString(blob_info->magick,image_info->magick,
376 image=ReadImage(blob_info,exception);
377 if (image != (Image *) NULL)
378 (void) DetachBlob(image->blob);
379 blob_info=DestroyImageInfo(blob_info);
383 Write blob to a temporary file on disk.
385 blob_info->blob=(void *) NULL;
387 *blob_info->filename='\0';
388 status=BlobToFile(blob_info->filename,blob,length,exception);
389 if (status == MagickFalse)
391 (void) RelinquishUniqueFileResource(blob_info->filename);
392 blob_info=DestroyImageInfo(blob_info);
393 return((Image *) NULL);
395 clone_info=CloneImageInfo(blob_info);
396 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
397 blob_info->magick,blob_info->filename);
398 image=ReadImage(clone_info,exception);
399 if (image != (Image *) NULL)
405 Restore original filenames.
407 for (images=GetFirstImageInList(image); images != (Image *) NULL; )
409 (void) CopyMagickMemory(images->filename,image_info->filename,
410 sizeof(images->filename));
411 (void) CopyMagickMemory(images->magick_filename,image_info->filename,
412 sizeof(images->magick_filename));
413 images=GetNextImageInList(images);
416 clone_info=DestroyImageInfo(clone_info);
417 (void) RelinquishUniqueFileResource(blob_info->filename);
418 blob_info=DestroyImageInfo(blob_info);
423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
427 + C l o n e B l o b I n f o %
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
434 % blob info is NULL, a new one.
436 % The format of the CloneBlobInfo method is:
438 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
440 % A description of each parameter follows:
442 % o blob_info: the blob info.
445 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
450 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
451 if (clone_info == (BlobInfo *) NULL)
452 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
453 GetBlobInfo(clone_info);
454 if (blob_info == (BlobInfo *) NULL)
456 clone_info->length=blob_info->length;
457 clone_info->extent=blob_info->extent;
458 clone_info->synchronize=blob_info->synchronize;
459 clone_info->quantum=blob_info->quantum;
460 clone_info->mapped=blob_info->mapped;
461 clone_info->eof=blob_info->eof;
462 clone_info->offset=blob_info->offset;
463 clone_info->size=blob_info->size;
464 clone_info->exempt=blob_info->exempt;
465 clone_info->status=blob_info->status;
466 clone_info->temporary=blob_info->temporary;
467 clone_info->type=blob_info->type;
468 clone_info->file_info.file=blob_info->file_info.file;
469 clone_info->properties=blob_info->properties;
470 clone_info->stream=blob_info->stream;
471 clone_info->data=blob_info->data;
472 clone_info->debug=IsEventLogging();
473 clone_info->reference_count=1;
478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482 + C l o s e B l o b %
486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488 % CloseBlob() closes a stream associated with the image.
490 % The format of the CloseBlob method is:
492 % MagickBooleanType CloseBlob(Image *image)
494 % A description of each parameter follows:
496 % o image: the image.
499 MagickExport MagickBooleanType CloseBlob(Image *image)
507 assert(image != (Image *) NULL);
508 assert(image->signature == MagickSignature);
509 if (image->debug != MagickFalse)
510 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
511 assert(image->blob != (BlobInfo *) NULL);
512 if (image->blob->type == UndefinedStream)
514 status=SyncBlob(image);
515 switch (image->blob->type)
517 case UndefinedStream:
523 if (image->blob->synchronize != MagickFalse)
524 status=fsync(fileno(image->blob->file_info.file));
525 status=ferror(image->blob->file_info.file);
530 #if defined(MAGICKCORE_ZLIB_DELEGATE)
531 (void) gzerror(image->blob->file_info.gzfile,&status);
537 #if defined(MAGICKCORE_BZLIB_DELEGATE)
538 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
546 if ((image->blob->file_info.file != (FILE *) NULL) &&
547 (image->blob->synchronize != MagickFalse))
549 (void) fsync(fileno(image->blob->file_info.file));
550 status=ferror(image->blob->file_info.file);
555 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
556 image->blob->size=GetBlobSize(image);
557 image->extent=image->blob->size;
558 image->blob->eof=MagickFalse;
559 if (image->blob->exempt != MagickFalse)
561 image->blob->type=UndefinedStream;
562 return(image->blob->status);
564 switch (image->blob->type)
566 case UndefinedStream:
571 status=fclose(image->blob->file_info.file);
576 #if defined(MAGICKCORE_HAVE_PCLOSE)
577 status=pclose(image->blob->file_info.file);
583 #if defined(MAGICKCORE_ZLIB_DELEGATE)
584 status=gzclose(image->blob->file_info.gzfile);
590 #if defined(MAGICKCORE_BZLIB_DELEGATE)
591 BZ2_bzclose(image->blob->file_info.bzfile);
599 if (image->blob->file_info.file != (FILE *) NULL)
600 status=fclose(image->blob->file_info.file);
604 (void) DetachBlob(image->blob);
605 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
606 return(image->blob->status);
610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614 + D e s t r o y B l o b %
618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620 % DestroyBlob() deallocates memory associated with a blob.
622 % The format of the DestroyBlob method is:
624 % void DestroyBlob(Image *image)
626 % A description of each parameter follows:
628 % o image: the image.
631 MagickExport void DestroyBlob(Image *image)
636 assert(image != (Image *) NULL);
637 assert(image->signature == MagickSignature);
638 if (image->debug != MagickFalse)
639 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
640 assert(image->blob != (BlobInfo *) NULL);
641 assert(image->blob->signature == MagickSignature);
643 LockSemaphoreInfo(image->blob->semaphore);
644 image->blob->reference_count--;
645 assert(image->blob->reference_count >= 0);
646 if (image->blob->reference_count == 0)
648 UnlockSemaphoreInfo(image->blob->semaphore);
649 if (destroy == MagickFalse)
651 (void) CloseBlob(image);
652 if (image->blob->mapped != MagickFalse)
653 (void) UnmapBlob(image->blob->data,image->blob->length);
654 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
655 DestroySemaphoreInfo(&image->blob->semaphore);
656 image->blob->signature=(~MagickSignature);
657 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665 + D e t a c h B l o b %
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 % DetachBlob() detaches a blob from the BlobInfo structure.
673 % The format of the DetachBlob method is:
675 % unsigned char *DetachBlob(BlobInfo *blob_info)
677 % A description of each parameter follows:
679 % o blob_info: Specifies a pointer to a BlobInfo structure.
682 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
687 assert(blob_info != (BlobInfo *) NULL);
688 if (blob_info->debug != MagickFalse)
689 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
690 if (blob_info->mapped != MagickFalse)
691 (void) UnmapBlob(blob_info->data,blob_info->length);
692 blob_info->mapped=MagickFalse;
695 blob_info->eof=MagickFalse;
696 blob_info->exempt=MagickFalse;
697 blob_info->type=UndefinedStream;
698 blob_info->file_info.file=(FILE *) NULL;
699 data=blob_info->data;
700 blob_info->data=(unsigned char *) NULL;
701 blob_info->stream=(StreamHandler) NULL;
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 + D i s c a r d B l o b B y t e s %
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716 % DiscardBlobBytes() discards bytes in a blob.
718 % The format of the DiscardBlobBytes method is:
720 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
722 % A description of each parameter follows.
724 % o image: the image.
726 % o length: the number of bytes to skip.
730 static inline const unsigned char *ReadBlobStream(Image *image,
731 const size_t length,unsigned char *data,ssize_t *count)
733 assert(count != (ssize_t *) NULL);
734 assert(image->blob != (BlobInfo *) NULL);
735 if (image->blob->type != BlobStream)
737 *count=ReadBlob(image,length,data);
740 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
743 image->blob->eof=MagickTrue;
746 data=image->blob->data+image->blob->offset;
747 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
748 image->blob->offset));
749 image->blob->offset+=(*count);
750 if (*count != (ssize_t) length)
751 image->blob->eof=MagickTrue;
755 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
756 const MagickSizeType length)
758 register MagickOffsetType
770 assert(image != (Image *) NULL);
771 assert(image->signature == MagickSignature);
773 for (i=0; i < (MagickOffsetType) length; i+=count)
775 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
776 (void) ReadBlobStream(image,quantum,buffer,&count);
784 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792 + D u p l i c a t e s B l o b %
796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798 % DuplicateBlob() duplicates a blob descriptor.
800 % The format of the DuplicateBlob method is:
802 % void DuplicateBlob(Image *image,const Image *duplicate)
804 % A description of each parameter follows:
806 % o image: the image.
808 % o duplicate: the duplicate image.
811 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
813 assert(image != (Image *) NULL);
814 assert(image->signature == MagickSignature);
815 if (image->debug != MagickFalse)
816 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
817 assert(duplicate != (Image *) NULL);
818 assert(duplicate->signature == MagickSignature);
820 image->blob=ReferenceBlob(duplicate->blob);
824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834 % EOFBlob() returns a non-zero value when EOF has been detected reading from
837 % The format of the EOFBlob method is:
839 % int EOFBlob(const Image *image)
841 % A description of each parameter follows:
843 % o image: the image.
846 MagickExport int EOFBlob(const Image *image)
848 assert(image != (Image *) NULL);
849 assert(image->signature == MagickSignature);
850 if (image->debug != MagickFalse)
851 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
852 assert(image->blob != (BlobInfo *) NULL);
853 assert(image->blob->type != UndefinedStream);
854 switch (image->blob->type)
856 case UndefinedStream:
862 image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
868 image->blob->eof=MagickFalse;
873 #if defined(MAGICKCORE_BZLIB_DELEGATE)
878 (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
879 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
885 image->blob->eof=MagickFalse;
891 return((int) image->blob->eof);
895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
899 + F i l e T o B l o b %
903 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
905 % FileToBlob() returns the contents of a file as a buffer terminated with
906 % the '\0' character. The length of the buffer (not including the extra
907 % terminating '\0' character) is returned via the 'length' parameter. Free
908 % the buffer with RelinquishMagickMemory().
910 % The format of the FileToBlob method is:
912 % unsigned char *FileToBlob(const char *filename,const size_t extent,
913 % size_t *length,ExceptionInfo *exception)
915 % A description of each parameter follows:
917 % o blob: FileToBlob() returns the contents of a file as a blob. If
918 % an error occurs NULL is returned.
920 % o filename: the filename.
922 % o extent: The maximum length of the blob.
924 % o length: On return, this reflects the actual length of the blob.
926 % o exception: return any errors or warnings in this structure.
929 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
930 size_t *length,ExceptionInfo *exception)
950 assert(filename != (const char *) NULL);
951 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
952 assert(exception != (ExceptionInfo *) NULL);
955 if (LocaleCompare(filename,"-") != 0)
956 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
959 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
960 return((unsigned char *) NULL);
962 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
964 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
973 Stream is not seekable.
975 quantum=(size_t) MagickMaxBufferExtent;
976 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
977 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
978 MagickMaxBufferExtent);
979 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
980 for (i=0; blob != (unsigned char *) NULL; i+=count)
982 count=(ssize_t) read(file,blob+i,quantum);
989 if (~((size_t) i) < (quantum+1))
991 blob=(unsigned char *) RelinquishMagickMemory(blob);
994 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
996 if ((size_t) (i+count) >= extent)
999 if (LocaleCompare(filename,"-") != 0)
1001 if (blob == (unsigned char *) NULL)
1003 (void) ThrowMagickException(exception,GetMagickModule(),
1004 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1005 return((unsigned char *) NULL);
1009 blob=(unsigned char *) RelinquishMagickMemory(blob);
1010 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1011 return((unsigned char *) NULL);
1013 *length=(size_t) MagickMin(i+count,extent);
1017 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
1018 blob=(unsigned char *) NULL;
1019 if (~(*length) >= (MaxTextExtent-1))
1020 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
1022 if (blob == (unsigned char *) NULL)
1025 (void) ThrowMagickException(exception,GetMagickModule(),
1026 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
1027 return((unsigned char *) NULL);
1029 map=MapBlob(file,ReadMode,0,*length);
1030 if (map != (unsigned char *) NULL)
1032 (void) memcpy(blob,map,*length);
1033 (void) UnmapBlob(map,*length);
1037 (void) lseek(file,0,SEEK_SET);
1038 for (i=0; i < *length; i+=count)
1040 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1041 (MagickSizeType) SSIZE_MAX));
1052 blob=(unsigned char *) RelinquishMagickMemory(blob);
1053 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1054 return((unsigned char *) NULL);
1058 if (LocaleCompare(filename,"-") != 0)
1062 blob=(unsigned char *) RelinquishMagickMemory(blob);
1063 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1073 % F i l e T o I m a g e %
1077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 % FileToImage() write the contents of a file to an image.
1081 % The format of the FileToImage method is:
1083 % MagickBooleanType FileToImage(Image *,const char *filename)
1085 % A description of each parameter follows:
1087 % o image: the image.
1089 % o filename: the filename.
1093 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1094 const unsigned char *data)
1099 register unsigned char
1102 assert(image->blob != (BlobInfo *) NULL);
1103 if (image->blob->type != BlobStream)
1104 return(WriteBlob(image,length,data));
1105 assert(image->blob->type != UndefinedStream);
1106 assert(data != (void *) NULL);
1107 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1108 if (extent >= image->blob->extent)
1110 image->blob->quantum<<=1;
1111 extent=image->blob->extent+image->blob->quantum+length;
1112 if (SetBlobExtent(image,extent) == MagickFalse)
1115 q=image->blob->data+image->blob->offset;
1116 (void) memcpy(q,data,length);
1117 image->blob->offset+=length;
1118 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1119 image->blob->length=(size_t) image->blob->offset;
1120 return((ssize_t) length);
1123 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1124 ExceptionInfo *exception)
1142 assert(image != (const Image *) NULL);
1143 assert(image->signature == MagickSignature);
1144 assert(filename != (const char *) NULL);
1145 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1147 if (LocaleCompare(filename,"-") != 0)
1148 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1151 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1152 return(MagickFalse);
1154 quantum=(size_t) MagickMaxBufferExtent;
1155 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1156 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1157 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1158 if (blob == (unsigned char *) NULL)
1160 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1162 return(MagickFalse);
1166 count=(ssize_t) read(file,blob,quantum);
1173 length=(size_t) count;
1174 count=WriteBlobStream(image,length,blob);
1175 if (count != (ssize_t) length)
1177 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1183 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1184 blob=(unsigned char *) RelinquishMagickMemory(blob);
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 + G e t B l o b E r r o r %
1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1199 % GetBlobError() returns MagickTrue if the blob associated with the specified
1200 % image encountered an error.
1202 % The format of the GetBlobError method is:
1204 % MagickBooleanType GetBlobError(const Image *image)
1206 % A description of each parameter follows:
1208 % o image: the image.
1211 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1213 assert(image != (const Image *) NULL);
1214 assert(image->signature == MagickSignature);
1215 if (image->debug != MagickFalse)
1216 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1217 return(image->blob->status);
1221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1225 + G e t B l o b F i l e H a n d l e %
1229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1231 % GetBlobFileHandle() returns the file handle associated with the image blob.
1233 % The format of the GetBlobFile method is:
1235 % FILE *GetBlobFileHandle(const Image *image)
1237 % A description of each parameter follows:
1239 % o image: the image.
1242 MagickExport FILE *GetBlobFileHandle(const Image *image)
1244 assert(image != (const Image *) NULL);
1245 assert(image->signature == MagickSignature);
1246 return(image->blob->file_info.file);
1250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1254 + G e t B l o b I n f o %
1258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1260 % GetBlobInfo() initializes the BlobInfo structure.
1262 % The format of the GetBlobInfo method is:
1264 % void GetBlobInfo(BlobInfo *blob_info)
1266 % A description of each parameter follows:
1268 % o blob_info: Specifies a pointer to a BlobInfo structure.
1271 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1273 assert(blob_info != (BlobInfo *) NULL);
1274 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1275 blob_info->type=UndefinedStream;
1276 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1277 blob_info->properties.st_mtime=time((time_t *) NULL);
1278 blob_info->properties.st_ctime=time((time_t *) NULL);
1279 blob_info->debug=IsEventLogging();
1280 blob_info->reference_count=1;
1281 blob_info->semaphore=AllocateSemaphoreInfo();
1282 blob_info->signature=MagickSignature;
1286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1290 % G e t B l o b P r o p e r t i e s %
1294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296 % GetBlobProperties() returns information about an image blob.
1298 % The format of the GetBlobProperties method is:
1300 % const struct stat *GetBlobProperties(const Image *image)
1302 % A description of each parameter follows:
1304 % o image: the image.
1307 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1309 assert(image != (Image *) NULL);
1310 assert(image->signature == MagickSignature);
1311 if (image->debug != MagickFalse)
1312 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1313 return(&image->blob->properties);
1317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1321 + G e t B l o b S i z e %
1325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1327 % GetBlobSize() returns the current length of the image file or blob; zero is
1328 % returned if the size cannot be determined.
1330 % The format of the GetBlobSize method is:
1332 % MagickSizeType GetBlobSize(const Image *image)
1334 % A description of each parameter follows:
1336 % o image: the image.
1339 MagickExport MagickSizeType GetBlobSize(const Image *image)
1344 assert(image != (Image *) NULL);
1345 assert(image->signature == MagickSignature);
1346 if (image->debug != MagickFalse)
1347 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1348 assert(image->blob != (BlobInfo *) NULL);
1350 switch (image->blob->type)
1352 case UndefinedStream:
1354 extent=image->blob->size;
1357 case StandardStream:
1359 extent=image->blob->size;
1364 if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
1365 extent=(MagickSizeType) image->blob->properties.st_size;
1370 extent=image->blob->size;
1379 status=GetPathAttributes(image->filename,&image->blob->properties);
1380 if (status != MagickFalse)
1381 extent=(MagickSizeType) image->blob->properties.st_size;
1388 extent=(MagickSizeType) image->blob->length;
1396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1400 + G e t B l o b S t r e a m D a t a %
1404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1406 % GetBlobStreamData() returns the stream data for the image.
1408 % The format of the GetBlobStreamData method is:
1410 % unsigned char *GetBlobStreamData(const Image *image)
1412 % A description of each parameter follows:
1414 % o image: the image.
1417 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1419 assert(image != (const Image *) NULL);
1420 assert(image->signature == MagickSignature);
1421 return(image->blob->data);
1425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1429 + G e t B l o b S t r e a m H a n d l e r %
1433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1435 % GetBlobStreamHandler() returns the stream handler for the image.
1437 % The format of the GetBlobStreamHandler method is:
1439 % StreamHandler GetBlobStreamHandler(const Image *image)
1441 % A description of each parameter follows:
1443 % o image: the image.
1446 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1448 assert(image != (const Image *) NULL);
1449 assert(image->signature == MagickSignature);
1450 if (image->debug != MagickFalse)
1451 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1452 return(image->blob->stream);
1456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1460 % I m a g e T o B l o b %
1464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1466 % ImageToBlob() implements direct to memory image formats. It returns the
1467 % image as a formatted blob and its length. The magick member of the Image
1468 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1469 % etc.). This method is the equivalent of WriteImage(), but writes the
1470 % formatted "file" to a memory buffer rather than to an actual file.
1472 % The format of the ImageToBlob method is:
1474 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1475 % size_t *length,ExceptionInfo *exception)
1477 % A description of each parameter follows:
1479 % o image_info: the image info.
1481 % o image: the image.
1483 % o length: This pointer to a size_t integer sets the initial length of the
1484 % blob. On return, it reflects the actual length of the blob.
1486 % o exception: return any errors or warnings in this structure.
1489 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1490 Image *image,size_t *length,ExceptionInfo *exception)
1504 assert(image_info != (const ImageInfo *) NULL);
1505 assert(image_info->signature == MagickSignature);
1506 if (image_info->debug != MagickFalse)
1507 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1508 image_info->filename);
1509 assert(image != (Image *) NULL);
1510 assert(image->signature == MagickSignature);
1511 assert(exception != (ExceptionInfo *) NULL);
1513 blob=(unsigned char *) NULL;
1514 blob_info=CloneImageInfo(image_info);
1515 blob_info->adjoin=MagickFalse;
1516 (void) SetImageInfo(blob_info,1,exception);
1517 if (*blob_info->magick != '\0')
1518 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1519 magick_info=GetMagickInfo(image->magick,exception);
1520 if (magick_info == (const MagickInfo *) NULL)
1522 (void) ThrowMagickException(exception,GetMagickModule(),
1523 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1527 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1528 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1531 Native blob support for this image format.
1533 blob_info->length=0;
1534 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1535 sizeof(unsigned char));
1536 if (blob_info->blob == (void *) NULL)
1537 (void) ThrowMagickException(exception,GetMagickModule(),
1538 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1541 (void) CloseBlob(image);
1542 image->blob->exempt=MagickTrue;
1543 *image->filename='\0';
1544 status=WriteImage(blob_info,image,exception);
1545 *length=image->blob->length;
1546 blob=DetachBlob(image->blob);
1547 if (status == MagickFalse)
1548 blob=(unsigned char *) RelinquishMagickMemory(blob);
1550 blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
1557 unique[MaxTextExtent];
1563 Write file to disk in blob image format.
1565 file=AcquireUniqueFileResource(unique);
1568 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1569 image_info->filename);
1573 blob_info->file=fdopen(file,"wb");
1574 if (blob_info->file != (FILE *) NULL)
1576 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1577 image->magick,unique);
1578 status=WriteImage(blob_info,image,exception);
1579 (void) fclose(blob_info->file);
1580 if (status != MagickFalse)
1581 blob=FileToBlob(image->filename,~0UL,length,exception);
1583 (void) RelinquishUniqueFileResource(unique);
1586 blob_info=DestroyImageInfo(blob_info);
1591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1595 % I m a g e T o F i l e %
1599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1601 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1602 % occurs otherwise MagickTrue.
1604 % The format of the ImageToFile method is:
1606 % MagickBooleanType ImageToFile(Image *image,char *filename,
1607 % ExceptionInfo *exception)
1609 % A description of each parameter follows:
1611 % o image: the image.
1613 % o filename: Write the image to this file.
1615 % o exception: return any errors or warnings in this structure.
1618 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1619 ExceptionInfo *exception)
1624 register const unsigned char
1643 assert(image != (Image *) NULL);
1644 assert(image->signature == MagickSignature);
1645 assert(image->blob != (BlobInfo *) NULL);
1646 assert(image->blob->type != UndefinedStream);
1647 if (image->debug != MagickFalse)
1648 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1649 assert(filename != (const char *) NULL);
1650 if (*filename == '\0')
1651 file=AcquireUniqueFileResource(filename);
1653 if (LocaleCompare(filename,"-") == 0)
1654 file=fileno(stdout);
1656 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1659 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1660 return(MagickFalse);
1662 quantum=(size_t) MagickMaxBufferExtent;
1663 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1664 quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
1665 MagickMaxBufferExtent);
1666 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1667 if (buffer == (unsigned char *) NULL)
1670 (void) ThrowMagickException(exception,GetMagickModule(),
1671 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1672 return(MagickFalse);
1675 p=ReadBlobStream(image,quantum,buffer,&count);
1676 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1678 length=(size_t) count;
1679 for (i=0; i < length; i+=count)
1681 count=write(file,p+i,(size_t) (length-i));
1692 if (LocaleCompare(filename,"-") != 0)
1694 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1695 if ((file == -1) || (i < length))
1697 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1698 return(MagickFalse);
1704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1708 % I m a g e s T o B l o b %
1712 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1714 % ImagesToBlob() implements direct to memory image formats. It returns the
1715 % image sequence as a blob and its length. The magick member of the ImageInfo
1716 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1718 % Note, some image formats do not permit multiple images to the same image
1719 % stream (e.g. JPEG). in this instance, just the first image of the
1720 % sequence is returned as a blob.
1722 % The format of the ImagesToBlob method is:
1724 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1725 % size_t *length,ExceptionInfo *exception)
1727 % A description of each parameter follows:
1729 % o image_info: the image info.
1731 % o images: the image list.
1733 % o length: This pointer to a size_t integer sets the initial length of the
1734 % blob. On return, it reflects the actual length of the blob.
1736 % o exception: return any errors or warnings in this structure.
1739 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1740 Image *images,size_t *length,ExceptionInfo *exception)
1754 assert(image_info != (const ImageInfo *) NULL);
1755 assert(image_info->signature == MagickSignature);
1756 if (image_info->debug != MagickFalse)
1757 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1758 image_info->filename);
1759 assert(images != (Image *) NULL);
1760 assert(images->signature == MagickSignature);
1761 assert(exception != (ExceptionInfo *) NULL);
1763 blob=(unsigned char *) NULL;
1764 blob_info=CloneImageInfo(image_info);
1765 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1767 if (*blob_info->magick != '\0')
1768 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1769 if (blob_info->adjoin == MagickFalse)
1771 blob_info=DestroyImageInfo(blob_info);
1772 return(ImageToBlob(image_info,images,length,exception));
1774 magick_info=GetMagickInfo(images->magick,exception);
1775 if (magick_info == (const MagickInfo *) NULL)
1777 (void) ThrowMagickException(exception,GetMagickModule(),
1778 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1782 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1783 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1786 Native blob support for this images format.
1788 blob_info->length=0;
1789 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1790 sizeof(unsigned char));
1791 if (blob_info->blob == (void *) NULL)
1792 (void) ThrowMagickException(exception,GetMagickModule(),
1793 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1796 images->blob->exempt=MagickTrue;
1797 *images->filename='\0';
1798 status=WriteImages(blob_info,images,images->filename,exception);
1799 if ((status != MagickFalse) && (images->blob->length != 0))
1801 *length=images->blob->length;
1802 blob=DetachBlob(images->blob);
1803 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1811 filename[MaxTextExtent],
1812 unique[MaxTextExtent];
1818 Write file to disk in blob images format.
1820 file=AcquireUniqueFileResource(unique);
1823 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1824 image_info->filename);
1828 blob_info->file=fdopen(file,"wb");
1829 if (blob_info->file != (FILE *) NULL)
1831 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1832 images->magick,unique);
1833 status=WriteImages(blob_info,images,filename,exception);
1834 (void) fclose(blob_info->file);
1835 if (status != MagickFalse)
1836 blob=FileToBlob(images->filename,~0UL,length,exception);
1838 (void) RelinquishUniqueFileResource(unique);
1841 blob_info=DestroyImageInfo(blob_info);
1845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1849 % I n j e c t I m a g e B l o b %
1853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1855 % InjectImageBlob() injects the image with a copy of itself in the specified
1856 % format (e.g. inject JPEG into a PDF image).
1858 % The format of the InjectImageBlob method is:
1860 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1861 % Image *image,Image *inject_image,const char *format,
1862 % ExceptionInfo *exception)
1864 % A description of each parameter follows:
1866 % o image_info: the image info..
1868 % o image: the image.
1870 % o inject_image: inject into the image stream.
1872 % o format: the image format.
1874 % o exception: return any errors or warnings in this structure.
1877 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1878 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1881 filename[MaxTextExtent];
1914 Write inject image to a temporary file.
1916 assert(image_info != (ImageInfo *) NULL);
1917 assert(image_info->signature == MagickSignature);
1918 assert(image != (Image *) NULL);
1919 assert(image->signature == MagickSignature);
1920 if (image->debug != MagickFalse)
1921 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1922 assert(inject_image != (Image *) NULL);
1923 assert(inject_image->signature == MagickSignature);
1924 assert(exception != (ExceptionInfo *) NULL);
1925 unique_file=(FILE *) NULL;
1926 file=AcquireUniqueFileResource(filename);
1928 unique_file=fdopen(file,"wb");
1929 if ((file == -1) || (unique_file == (FILE *) NULL))
1931 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1932 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1934 return(MagickFalse);
1936 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1937 if (byte_image == (Image *) NULL)
1939 (void) fclose(unique_file);
1940 (void) RelinquishUniqueFileResource(filename);
1941 return(MagickFalse);
1943 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1945 DestroyBlob(byte_image);
1946 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1947 write_info=CloneImageInfo(image_info);
1948 SetImageInfoFile(write_info,unique_file);
1949 status=WriteImage(write_info,byte_image,exception);
1950 write_info=DestroyImageInfo(write_info);
1951 byte_image=DestroyImage(byte_image);
1952 (void) fclose(unique_file);
1953 if (status == MagickFalse)
1955 (void) RelinquishUniqueFileResource(filename);
1956 return(MagickFalse);
1959 Inject into image stream.
1961 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1964 (void) RelinquishUniqueFileResource(filename);
1965 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1966 image_info->filename);
1967 return(MagickFalse);
1969 quantum=(size_t) MagickMaxBufferExtent;
1970 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
1971 quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
1972 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1973 if (buffer == (unsigned char *) NULL)
1975 (void) RelinquishUniqueFileResource(filename);
1976 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1979 for (i=0; ; i+=count)
1981 count=(ssize_t) read(file,buffer,quantum);
1988 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1993 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1994 (void) RelinquishUniqueFileResource(filename);
1995 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
2000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2004 + I s B l o b E x e m p t %
2008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2010 % IsBlobExempt() returns true if the blob is exempt.
2012 % The format of the IsBlobExempt method is:
2014 % MagickBooleanType IsBlobExempt(const Image *image)
2016 % A description of each parameter follows:
2018 % o image: the image.
2021 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
2023 assert(image != (const Image *) NULL);
2024 assert(image->signature == MagickSignature);
2025 if (image->debug != MagickFalse)
2026 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2027 return(image->blob->exempt);
2031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2035 + I s B l o b S e e k a b l e %
2039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2041 % IsBlobSeekable() returns true if the blob is seekable.
2043 % The format of the IsBlobSeekable method is:
2045 % MagickBooleanType IsBlobSeekable(const Image *image)
2047 % A description of each parameter follows:
2049 % o image: the image.
2052 MagickPrivate MagickBooleanType IsBlobSeekable(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 switch (image->blob->type)
2067 seekable=MagickTrue;
2072 seekable=MagickFalse;
2080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2084 + I s B l o b T e m p o r a r y %
2088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2090 % IsBlobTemporary() returns true if the blob is temporary.
2092 % The format of the IsBlobTemporary method is:
2094 % MagickBooleanType IsBlobTemporary(const Image *image)
2096 % A description of each parameter follows:
2098 % o image: the image.
2101 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2103 assert(image != (const Image *) NULL);
2104 assert(image->signature == MagickSignature);
2105 if (image->debug != MagickFalse)
2106 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2107 return(image->blob->temporary);
2111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2121 % MapBlob() creates a mapping from a file to a binary large object.
2123 % The format of the MapBlob method is:
2125 % unsigned char *MapBlob(int file,const MapMode mode,
2126 % const MagickOffsetType offset,const size_t length)
2128 % A description of each parameter follows:
2130 % o file: map this file descriptor.
2132 % o mode: ReadMode, WriteMode, or IOMode.
2134 % o offset: starting at this offset within the file.
2136 % o length: the length of the mapping is returned in this pointer.
2139 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2140 const MagickOffsetType offset,const size_t length)
2142 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2155 #if defined(MAP_ANONYMOUS)
2156 flags|=MAP_ANONYMOUS;
2158 return((unsigned char *) NULL);
2165 protection=PROT_READ;
2167 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2173 protection=PROT_WRITE;
2175 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2177 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2178 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2179 POSIX_MADV_WILLNEED);
2185 protection=PROT_READ | PROT_WRITE;
2187 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2192 if (map == (unsigned char *) MAP_FAILED)
2193 return((unsigned char *) NULL);
2200 return((unsigned char *) NULL);
2205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2209 + M S B O r d e r L o n g %
2213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2215 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2216 % most-significant byte first.
2218 % The format of the MSBOrderLong method is:
2220 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2222 % A description of each parameter follows.
2224 % o buffer: Specifies a pointer to a buffer of integers.
2226 % o length: Specifies the length of the buffer.
2229 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2234 register unsigned char
2238 assert(buffer != (unsigned char *) NULL);
2245 *buffer++=(unsigned char) c;
2249 *buffer++=(unsigned char) c;
2255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2259 + M S B O r d e r S h o r t %
2263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2265 % MSBOrderShort() converts a least-significant byte first buffer of integers
2266 % to most-significant byte first.
2268 % The format of the MSBOrderShort method is:
2270 % void MSBOrderShort(unsigned char *p,const size_t length)
2272 % A description of each parameter follows.
2274 % o p: Specifies a pointer to a buffer of integers.
2276 % o length: Specifies the length of the buffer.
2279 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2284 register unsigned char
2287 assert(p != (unsigned char *) NULL);
2294 *p++=(unsigned char) c;
2299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2309 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2310 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2311 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2312 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2313 % from a system command.
2315 % The format of the OpenBlob method is:
2317 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2318 % const BlobMode mode,ExceptionInfo *exception)
2320 % A description of each parameter follows:
2322 % o image_info: the image info.
2324 % o image: the image.
2326 % o mode: the mode for opening the file.
2329 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2330 Image *image,const BlobMode mode,ExceptionInfo *exception)
2333 extension[MaxTextExtent],
2334 filename[MaxTextExtent];
2345 assert(image_info != (ImageInfo *) NULL);
2346 assert(image_info->signature == MagickSignature);
2347 if (image_info->debug != MagickFalse)
2348 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2349 image_info->filename);
2350 assert(image != (Image *) NULL);
2351 assert(image->signature == MagickSignature);
2352 if (image_info->blob != (void *) NULL)
2354 if (image_info->stream != (StreamHandler) NULL)
2355 image->blob->stream=(StreamHandler) image_info->stream;
2356 AttachBlob(image->blob,image_info->blob,image_info->length);
2359 (void) DetachBlob(image->blob);
2362 default: type="r"; break;
2363 case ReadBlobMode: type="r"; break;
2364 case ReadBinaryBlobMode: type="rb"; break;
2365 case WriteBlobMode: type="w"; break;
2366 case WriteBinaryBlobMode: type="w+b"; break;
2367 case AppendBlobMode: type="a"; break;
2368 case AppendBinaryBlobMode: type="a+b"; break;
2371 image->blob->synchronize=image_info->synchronize;
2372 if (image_info->stream != (StreamHandler) NULL)
2374 image->blob->stream=(StreamHandler) image_info->stream;
2377 image->blob->type=FifoStream;
2385 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2386 rights=ReadPolicyRights;
2388 rights=WritePolicyRights;
2389 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2392 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2393 "NotAuthorized","`%s'",filename);
2394 return(MagickFalse);
2396 if ((LocaleCompare(filename,"-") == 0) ||
2397 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2399 image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
2400 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2401 if (strchr(type,'b') != (char *) NULL)
2402 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2404 image->blob->type=StandardStream;
2405 image->blob->exempt=MagickTrue;
2408 if (LocaleNCompare(filename,"fd:",3) == 0)
2411 mode[MaxTextExtent];
2415 image->blob->file_info.file=fdopen(StringToLong(filename+3),mode);
2416 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2417 if (strchr(type,'b') != (char *) NULL)
2418 setmode(_fileno(image->blob->file_info.file),_O_BINARY);
2420 image->blob->type=StandardStream;
2421 image->blob->exempt=MagickTrue;
2424 #if defined(MAGICKCORE_HAVE_POPEN)
2425 if (*filename == '|')
2428 mode[MaxTextExtent];
2431 Pipe image to or from a system command.
2433 #if defined(SIGPIPE)
2435 (void) signal(SIGPIPE,SIG_IGN);
2439 image->blob->file_info.file=(FILE *) popen_utf8(filename+1,mode);
2440 if (image->blob->file_info.file == (FILE *) NULL)
2442 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2443 return(MagickFalse);
2445 image->blob->type=PipeStream;
2446 image->blob->exempt=MagickTrue;
2450 status=GetPathAttributes(filename,&image->blob->properties);
2451 #if defined(S_ISFIFO)
2452 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2454 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2455 if (image->blob->file_info.file == (FILE *) NULL)
2457 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2458 return(MagickFalse);
2460 image->blob->type=FileStream;
2461 image->blob->exempt=MagickTrue;
2465 GetPathComponent(image->filename,ExtensionPath,extension);
2468 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2469 if ((image_info->adjoin == MagickFalse) ||
2470 (strchr(filename,'%') != (char *) NULL))
2473 Form filename for multi-part images.
2475 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2476 image->scene,filename,exception);
2477 if ((LocaleCompare(filename,image->filename) == 0) &&
2478 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2479 (GetNextImageInList(image) != (Image *) NULL)))
2482 path[MaxTextExtent];
2484 GetPathComponent(image->filename,RootPath,path);
2485 if (*extension == '\0')
2486 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2487 path,(double) image->scene);
2489 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2490 path,(double) image->scene,extension);
2492 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2493 #if defined(macintosh)
2494 SetApplicationType(filename,image_info->magick,'8BIM');
2498 if (image_info->file != (FILE *) NULL)
2500 image->blob->file_info.file=image_info->file;
2501 image->blob->type=FileStream;
2502 image->blob->exempt=MagickTrue;
2507 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2508 if (image->blob->file_info.file != (FILE *) NULL)
2516 image->blob->type=FileStream;
2517 #if defined(MAGICKCORE_HAVE_SETVBUF)
2518 (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
2521 (void) ResetMagickMemory(magick,0,sizeof(magick));
2522 count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
2523 (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
2524 (void) fflush(image->blob->file_info.file);
2525 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2526 " read %.20g magic header bytes",(double) count);
2527 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2528 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2529 ((int) magick[2] == 0x08))
2531 (void) fclose(image->blob->file_info.file);
2532 image->blob->file_info.gzfile=gzopen(filename,type);
2533 if (image->blob->file_info.gzfile != (gzFile) NULL)
2534 image->blob->type=ZipStream;
2537 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2538 if (strncmp((char *) magick,"BZh",3) == 0)
2540 (void) fclose(image->blob->file_info.file);
2541 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2542 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2543 image->blob->type=BZipStream;
2546 if (image->blob->type == FileStream)
2557 sans_exception=AcquireExceptionInfo();
2558 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2559 sans_exception=DestroyExceptionInfo(sans_exception);
2560 properties=(&image->blob->properties);
2561 if ((magick_info != (const MagickInfo *) NULL) &&
2562 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2563 (properties->st_size <= MagickMaxBufferExtent))
2571 length=(size_t) properties->st_size;
2572 blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,
2574 if (blob != (void *) NULL)
2577 Format supports blobs-- use memory-mapped I/O.
2579 if (image_info->file != (FILE *) NULL)
2580 image->blob->exempt=MagickFalse;
2583 (void) fclose(image->blob->file_info.file);
2584 image->blob->file_info.file=(FILE *) NULL;
2586 AttachBlob(image->blob,blob,length);
2587 image->blob->mapped=MagickTrue;
2594 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2595 if ((LocaleCompare(extension,"Z") == 0) ||
2596 (LocaleCompare(extension,"gz") == 0) ||
2597 (LocaleCompare(extension,"wmz") == 0) ||
2598 (LocaleCompare(extension,"svgz") == 0))
2600 if (mode == WriteBinaryBlobMode)
2602 image->blob->file_info.gzfile=gzopen(filename,type);
2603 if (image->blob->file_info.gzfile != (gzFile) NULL)
2604 image->blob->type=ZipStream;
2608 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2609 if (LocaleCompare(extension,"bz2") == 0)
2611 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
2612 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
2613 image->blob->type=BZipStream;
2618 image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
2619 if (image->blob->file_info.file != (FILE *) NULL)
2621 image->blob->type=FileStream;
2622 #if defined(MAGICKCORE_HAVE_SETVBUF)
2623 (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
2628 image->blob->status=MagickFalse;
2629 if (image->blob->type != UndefinedStream)
2630 image->blob->size=GetBlobSize(image);
2633 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2634 return(MagickFalse);
2640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2650 % PingBlob() returns all the attributes of an image or image sequence except
2651 % for the pixels. It is much faster and consumes far less memory than
2652 % BlobToImage(). On failure, a NULL image is returned and exception
2653 % describes the reason for the failure.
2655 % The format of the PingBlob method is:
2657 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2658 % const size_t length,ExceptionInfo *exception)
2660 % A description of each parameter follows:
2662 % o image_info: the image info.
2664 % o blob: the address of a character stream in one of the image formats
2665 % understood by ImageMagick.
2667 % o length: This size_t integer reflects the length in bytes of the blob.
2669 % o exception: return any errors or warnings in this structure.
2673 #if defined(__cplusplus) || defined(c_plusplus)
2677 static size_t PingStream(const Image *magick_unused(image),
2678 const void *magick_unused(pixels),const size_t columns)
2683 #if defined(__cplusplus) || defined(c_plusplus)
2687 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2688 const size_t length,ExceptionInfo *exception)
2696 assert(image_info != (ImageInfo *) NULL);
2697 assert(image_info->signature == MagickSignature);
2698 if (image_info->debug != MagickFalse)
2699 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2700 image_info->filename);
2701 assert(exception != (ExceptionInfo *) NULL);
2702 if ((blob == (const void *) NULL) || (length == 0))
2704 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2705 "UnrecognizedImageFormat","`%s'",image_info->magick);
2706 return((Image *) NULL);
2708 ping_info=CloneImageInfo(image_info);
2709 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2710 if (ping_info->blob == (const void *) NULL)
2712 (void) ThrowMagickException(exception,GetMagickModule(),
2713 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2714 return((Image *) NULL);
2716 (void) memcpy(ping_info->blob,blob,length);
2717 ping_info->length=length;
2718 ping_info->ping=MagickTrue;
2719 image=ReadStream(ping_info,&PingStream,exception);
2720 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2721 ping_info=DestroyImageInfo(ping_info);
2726 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2736 % ReadBlob() reads data from the blob or image file and returns it. It
2737 % returns the number of bytes read. If length is zero, ReadBlob() returns
2738 % zero and has no other results. If length is greater than SSIZE_MAX, the
2739 % result is unspecified.
2741 % The format of the ReadBlob method is:
2743 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2745 % A description of each parameter follows:
2747 % o image: the image.
2749 % o length: Specifies an integer representing the number of bytes to read
2752 % o data: Specifies an area to place the information requested from the
2756 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2757 unsigned char *data)
2762 register unsigned char
2768 assert(image != (Image *) NULL);
2769 assert(image->signature == MagickSignature);
2770 assert(image->blob != (BlobInfo *) NULL);
2771 assert(image->blob->type != UndefinedStream);
2774 assert(data != (void *) NULL);
2777 switch (image->blob->type)
2779 case UndefinedStream:
2781 case StandardStream:
2783 count=read(fileno(image->blob->file_info.file),q,length);
2793 count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
2798 c=getc(image->blob->file_info.file);
2801 *q++=(unsigned char) c;
2806 c=getc(image->blob->file_info.file);
2809 *q++=(unsigned char) c;
2819 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2824 count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
2825 (unsigned int) length);
2830 c=gzgetc(image->blob->file_info.gzfile);
2833 *q++=(unsigned char) c;
2838 c=gzgetc(image->blob->file_info.gzfile);
2841 *q++=(unsigned char) c;
2852 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2853 count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
2861 register const unsigned char
2864 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2866 image->blob->eof=MagickTrue;
2869 p=image->blob->data+image->blob->offset;
2870 count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
2871 image->blob->offset));
2872 image->blob->offset+=count;
2873 if (count != (ssize_t) length)
2874 image->blob->eof=MagickTrue;
2875 (void) memcpy(q,p,(size_t) count);
2883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2887 + R e a d B l o b B y t e %
2891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2893 % ReadBlobByte() reads a single byte from the image file and returns it.
2895 % The format of the ReadBlobByte method is:
2897 % int ReadBlobByte(Image *image)
2899 % A description of each parameter follows.
2901 % o image: the image.
2904 MagickExport int ReadBlobByte(Image *image)
2906 register const unsigned char
2915 assert(image != (Image *) NULL);
2916 assert(image->signature == MagickSignature);
2917 p=ReadBlobStream(image,1,buffer,&count);
2924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2928 + R e a d B l o b D o u b l e %
2932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2934 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2935 % specified by the endian member of the image structure.
2937 % The format of the ReadBlobDouble method is:
2939 % double ReadBlobDouble(Image *image)
2941 % A description of each parameter follows.
2943 % o image: the image.
2946 MagickExport double ReadBlobDouble(Image *image)
2957 quantum.double_value=0.0;
2958 quantum.unsigned_value=ReadBlobLongLong(image);
2959 return(quantum.double_value);
2963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2967 + R e a d B l o b F l o a t %
2971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2973 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2974 % specified by the endian member of the image structure.
2976 % The format of the ReadBlobFloat method is:
2978 % float ReadBlobFloat(Image *image)
2980 % A description of each parameter follows.
2982 % o image: the image.
2985 MagickExport float ReadBlobFloat(Image *image)
2996 quantum.float_value=0.0;
2997 quantum.unsigned_value=ReadBlobLong(image);
2998 return(quantum.float_value);
3002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3006 + R e a d B l o b L o n g %
3010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3012 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
3013 % specified by the endian member of the image structure.
3015 % The format of the ReadBlobLong method is:
3017 % unsigned int ReadBlobLong(Image *image)
3019 % A description of each parameter follows.
3021 % o image: the image.
3024 MagickExport unsigned int ReadBlobLong(Image *image)
3026 register const unsigned char
3038 assert(image != (Image *) NULL);
3039 assert(image->signature == MagickSignature);
3041 p=ReadBlobStream(image,4,buffer,&count);
3044 if (image->endian == LSBEndian)
3046 value=(unsigned int) (*p++);
3047 value|=((unsigned int) (*p++)) << 8;
3048 value|=((unsigned int) (*p++)) << 16;
3049 value|=((unsigned int) (*p++)) << 24;
3052 value=((unsigned int) (*p++)) << 24;
3053 value|=((unsigned int) (*p++)) << 16;
3054 value|=((unsigned int) (*p++)) << 8;
3055 value|=((unsigned int) (*p++));
3060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3064 + R e a d B l o b L o n g L o n g %
3068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3070 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3071 % byte-order specified by the endian member of the image structure.
3073 % The format of the ReadBlobLongLong method is:
3075 % MagickSizeType ReadBlobLongLong(Image *image)
3077 % A description of each parameter follows.
3079 % o image: the image.
3082 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3087 register const unsigned char
3096 assert(image != (Image *) NULL);
3097 assert(image->signature == MagickSignature);
3099 p=ReadBlobStream(image,8,buffer,&count);
3101 return(MagickULLConstant(0));
3102 if (image->endian == LSBEndian)
3104 value=(MagickSizeType) (*p++);
3105 value|=((MagickSizeType) (*p++)) << 8;
3106 value|=((MagickSizeType) (*p++)) << 16;
3107 value|=((MagickSizeType) (*p++)) << 24;
3108 value|=((MagickSizeType) (*p++)) << 32;
3109 value|=((MagickSizeType) (*p++)) << 40;
3110 value|=((MagickSizeType) (*p++)) << 48;
3111 value|=((MagickSizeType) (*p++)) << 56;
3112 return(value & MagickULLConstant(0xffffffffffffffff));
3114 value=((MagickSizeType) (*p++)) << 56;
3115 value|=((MagickSizeType) (*p++)) << 48;
3116 value|=((MagickSizeType) (*p++)) << 40;
3117 value|=((MagickSizeType) (*p++)) << 32;
3118 value|=((MagickSizeType) (*p++)) << 24;
3119 value|=((MagickSizeType) (*p++)) << 16;
3120 value|=((MagickSizeType) (*p++)) << 8;
3121 value|=((MagickSizeType) (*p++));
3122 return(value & MagickULLConstant(0xffffffffffffffff));
3126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3130 + R e a d B l o b S h o r t %
3134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3136 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3137 % specified by the endian member of the image structure.
3139 % The format of the ReadBlobShort method is:
3141 % unsigned short ReadBlobShort(Image *image)
3143 % A description of each parameter follows.
3145 % o image: the image.
3148 MagickExport unsigned short ReadBlobShort(Image *image)
3150 register const unsigned char
3153 register unsigned int
3162 assert(image != (Image *) NULL);
3163 assert(image->signature == MagickSignature);
3165 p=ReadBlobStream(image,2,buffer,&count);
3167 return((unsigned short) 0U);
3168 if (image->endian == LSBEndian)
3170 value=(unsigned int) (*p++);
3171 value|=((unsigned int) (*p++)) << 8;
3172 return((unsigned short) (value & 0xffff));
3174 value=(unsigned int) ((*p++) << 8);
3175 value|=(unsigned int) (*p++);
3176 return((unsigned short) (value & 0xffff));
3180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3184 + R e a d B l o b L S B L o n g %
3188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3190 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3191 % least-significant byte first order.
3193 % The format of the ReadBlobLSBLong method is:
3195 % unsigned int ReadBlobLSBLong(Image *image)
3197 % A description of each parameter follows.
3199 % o image: the image.
3202 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3204 register const unsigned char
3207 register unsigned int
3216 assert(image != (Image *) NULL);
3217 assert(image->signature == MagickSignature);
3219 p=ReadBlobStream(image,4,buffer,&count);
3222 value=(unsigned int) (*p++);
3223 value|=((unsigned int) (*p++)) << 8;
3224 value|=((unsigned int) (*p++)) << 16;
3225 value|=((unsigned int) (*p++)) << 24;
3230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3234 + R e a d B l o b L S B S h o r t %
3238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3240 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3241 % least-significant byte first order.
3243 % The format of the ReadBlobLSBShort method is:
3245 % unsigned short ReadBlobLSBShort(Image *image)
3247 % A description of each parameter follows.
3249 % o image: the image.
3252 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3254 register const unsigned char
3257 register unsigned int
3266 assert(image != (Image *) NULL);
3267 assert(image->signature == MagickSignature);
3269 p=ReadBlobStream(image,2,buffer,&count);
3271 return((unsigned short) 0U);
3272 value=(unsigned int) (*p++);
3273 value|=((unsigned int) ((*p++)) << 8);
3274 return((unsigned short) (value & 0xffff));
3278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3282 + R e a d B l o b M S B L o n g %
3286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3288 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3289 % most-significant byte first order.
3291 % The format of the ReadBlobMSBLong method is:
3293 % unsigned int ReadBlobMSBLong(Image *image)
3295 % A description of each parameter follows.
3297 % o image: the image.
3300 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3302 register const unsigned char
3305 register unsigned int
3314 assert(image != (Image *) NULL);
3315 assert(image->signature == MagickSignature);
3317 p=ReadBlobStream(image,4,buffer,&count);
3320 value=((unsigned int) (*p++) << 24);
3321 value|=((unsigned int) (*p++) << 16);
3322 value|=((unsigned int) (*p++) << 8);
3323 value|=(unsigned int) (*p++);
3328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3332 + R e a d B l o b M S B L o n g L o n g %
3336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3338 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3339 % most-significant byte first order.
3341 % The format of the ReadBlobMSBLongLong method is:
3343 % unsigned int ReadBlobMSBLongLong(Image *image)
3345 % A description of each parameter follows.
3347 % o image: the image.
3350 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3352 register const unsigned char
3355 register MagickSizeType
3364 assert(image != (Image *) NULL);
3365 assert(image->signature == MagickSignature);
3367 p=ReadBlobStream(image,8,buffer,&count);
3369 return(MagickULLConstant(0));
3370 value=((MagickSizeType) (*p++)) << 56;
3371 value|=((MagickSizeType) (*p++)) << 48;
3372 value|=((MagickSizeType) (*p++)) << 40;
3373 value|=((MagickSizeType) (*p++)) << 32;
3374 value|=((MagickSizeType) (*p++)) << 24;
3375 value|=((MagickSizeType) (*p++)) << 16;
3376 value|=((MagickSizeType) (*p++)) << 8;
3377 value|=((MagickSizeType) (*p++));
3378 return(value & MagickULLConstant(0xffffffffffffffff));
3382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3386 + R e a d B l o b M S B S h o r t %
3390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3392 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3393 % most-significant byte first order.
3395 % The format of the ReadBlobMSBShort method is:
3397 % unsigned short ReadBlobMSBShort(Image *image)
3399 % A description of each parameter follows.
3401 % o image: the image.
3404 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3406 register const unsigned char
3409 register unsigned int
3418 assert(image != (Image *) NULL);
3419 assert(image->signature == MagickSignature);
3421 p=ReadBlobStream(image,2,buffer,&count);
3423 return((unsigned short) 0U);
3424 value=(unsigned int) ((*p++) << 8);
3425 value|=(unsigned int) (*p++);
3426 return((unsigned short) (value & 0xffff));
3430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3434 + R e a d B l o b S t r i n g %
3438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3440 % ReadBlobString() reads characters from a blob or file until a newline
3441 % character is read or an end-of-file condition is encountered.
3443 % The format of the ReadBlobString method is:
3445 % char *ReadBlobString(Image *image,char *string)
3447 % A description of each parameter follows:
3449 % o image: the image.
3451 % o string: the address of a character buffer.
3454 MagickExport char *ReadBlobString(Image *image,char *string)
3456 register const unsigned char
3468 assert(image != (Image *) NULL);
3469 assert(image->signature == MagickSignature);
3470 for (i=0; i < (MaxTextExtent-1L); i++)
3472 p=ReadBlobStream(image,1,buffer,&count);
3476 return((char *) NULL);
3479 string[i]=(char) (*p);
3480 if ((string[i] == '\r') || (string[i] == '\n'))
3483 if (string[i] == '\r')
3484 (void) ReadBlobStream(image,1,buffer,&count);
3490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3494 + R e f e r e n c e B l o b %
3498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3500 % ReferenceBlob() increments the reference count associated with the pixel
3501 % blob returning a pointer to the blob.
3503 % The format of the ReferenceBlob method is:
3505 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3507 % A description of each parameter follows:
3509 % o blob_info: the blob_info.
3512 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3514 assert(blob != (BlobInfo *) NULL);
3515 assert(blob->signature == MagickSignature);
3516 if (blob->debug != MagickFalse)
3517 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3518 LockSemaphoreInfo(blob->semaphore);
3519 blob->reference_count++;
3520 UnlockSemaphoreInfo(blob->semaphore);
3525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3533 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3535 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3536 % and returns the resulting offset.
3538 % The format of the SeekBlob method is:
3540 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3543 % A description of each parameter follows:
3545 % o image: the image.
3547 % o offset: Specifies an integer representing the offset in bytes.
3549 % o whence: Specifies an integer representing how the offset is
3550 % treated relative to the beginning of the blob as follows:
3552 % SEEK_SET Set position equal to offset bytes.
3553 % SEEK_CUR Set position to current location plus offset.
3554 % SEEK_END Set position to EOF plus offset.
3557 MagickExport MagickOffsetType SeekBlob(Image *image,
3558 const MagickOffsetType offset,const int whence)
3560 assert(image != (Image *) NULL);
3561 assert(image->signature == MagickSignature);
3562 if (image->debug != MagickFalse)
3563 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3564 assert(image->blob != (BlobInfo *) NULL);
3565 assert(image->blob->type != UndefinedStream);
3566 switch (image->blob->type)
3568 case UndefinedStream:
3570 case StandardStream:
3574 if (fseek(image->blob->file_info.file,offset,whence) < 0)
3576 image->blob->offset=TellBlob(image);
3582 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3583 if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
3586 image->blob->offset=TellBlob(image);
3602 image->blob->offset=offset;
3607 if ((image->blob->offset+offset) < 0)
3609 image->blob->offset+=offset;
3614 if (((MagickOffsetType) image->blob->length+offset) < 0)
3616 image->blob->offset=image->blob->length+offset;
3620 if (image->blob->offset <= (MagickOffsetType)
3621 ((off_t) image->blob->length))
3622 image->blob->eof=MagickFalse;
3624 if (image->blob->mapped != MagickFalse)
3628 image->blob->extent=(size_t) (image->blob->offset+
3629 image->blob->quantum);
3630 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3631 image->blob->data,image->blob->extent+1,
3632 sizeof(*image->blob->data));
3633 (void) SyncBlob(image);
3634 if (image->blob->data == (unsigned char *) NULL)
3636 (void) DetachBlob(image->blob);
3643 return(image->blob->offset);
3647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3651 + S e t B l o b E x e m p t %
3655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3657 % SetBlobExempt() sets the blob exempt status.
3659 % The format of the SetBlobExempt method is:
3661 % MagickBooleanType SetBlobExempt(const Image *image,
3662 % const MagickBooleanType exempt)
3664 % A description of each parameter follows:
3666 % o image: the image.
3668 % o exempt: Set to true if this blob is exempt from being closed.
3671 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3673 assert(image != (const Image *) NULL);
3674 assert(image->signature == MagickSignature);
3675 if (image->debug != MagickFalse)
3676 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3677 image->blob->exempt=exempt;
3681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3685 + S e t B l o b E x t e n t %
3689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3691 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3692 % method is successful, subsequent writes to bytes in the specified range are
3693 % guaranteed not to fail.
3695 % The format of the SetBlobExtent method is:
3697 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3699 % A description of each parameter follows:
3701 % o image: the image.
3703 % o extent: the blob maximum extent.
3706 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3707 const MagickSizeType extent)
3709 assert(image != (Image *) NULL);
3710 assert(image->signature == MagickSignature);
3711 if (image->debug != MagickFalse)
3712 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3713 assert(image->blob != (BlobInfo *) NULL);
3714 assert(image->blob->type != UndefinedStream);
3715 switch (image->blob->type)
3717 case UndefinedStream:
3719 case StandardStream:
3720 return(MagickFalse);
3729 if (extent != (MagickSizeType) ((off_t) extent))
3730 return(MagickFalse);
3731 offset=SeekBlob(image,0,SEEK_END);
3733 return(MagickFalse);
3734 if ((MagickSizeType) offset >= extent)
3736 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3737 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3738 image->blob->file_info.file);
3739 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3740 if (image->blob->synchronize != MagickFalse)
3745 status=posix_fallocate(fileno(image->blob->file_info.file),offset,
3748 return(MagickFalse);
3751 offset=SeekBlob(image,offset,SEEK_SET);
3753 return(MagickFalse);
3758 return(MagickFalse);
3760 return(MagickFalse);
3762 return(MagickFalse);
3765 if (extent != (MagickSizeType) ((size_t) extent))
3766 return(MagickFalse);
3767 if (image->blob->mapped != MagickFalse)
3775 (void) UnmapBlob(image->blob->data,image->blob->length);
3776 if (extent != (MagickSizeType) ((off_t) extent))
3777 return(MagickFalse);
3778 offset=SeekBlob(image,0,SEEK_END);
3780 return(MagickFalse);
3781 if ((MagickSizeType) offset >= extent)
3783 offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
3784 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
3785 image->blob->file_info.file);
3786 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
3787 if (image->blob->synchronize != MagickFalse)
3792 status=posix_fallocate(fileno(image->blob->file_info.file),offset,
3795 return(MagickFalse);
3798 offset=SeekBlob(image,offset,SEEK_SET);
3800 return(MagickFalse);
3801 image->blob->data=(unsigned char*) MapBlob(fileno(
3802 image->blob->file_info.file),WriteMode,0,(size_t) extent);
3803 image->blob->extent=(size_t) extent;
3804 image->blob->length=(size_t) extent;
3805 (void) SyncBlob(image);
3808 image->blob->extent=(size_t) extent;
3809 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3810 image->blob->extent+1,sizeof(*image->blob->data));
3811 (void) SyncBlob(image);
3812 if (image->blob->data == (unsigned char *) NULL)
3814 (void) DetachBlob(image->blob);
3815 return(MagickFalse);
3824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3834 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3835 % attributes if it is an blob.
3837 % The format of the SyncBlob method is:
3839 % int SyncBlob(Image *image)
3841 % A description of each parameter follows:
3843 % o image: the image.
3846 static int SyncBlob(Image *image)
3851 assert(image != (Image *) NULL);
3852 assert(image->signature == MagickSignature);
3853 if (image->debug != MagickFalse)
3854 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3855 assert(image->blob != (BlobInfo *) NULL);
3856 assert(image->blob->type != UndefinedStream);
3858 switch (image->blob->type)
3860 case UndefinedStream:
3861 case StandardStream:
3866 status=fflush(image->blob->file_info.file);
3871 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3872 status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
3878 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3879 status=BZ2_bzflush(image->blob->file_info.bzfile);
3887 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3888 if (image->blob->mapped != MagickFalse)
3889 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3908 % TellBlob() obtains the current value of the blob or file position.
3910 % The format of the TellBlob method is:
3912 % MagickOffsetType TellBlob(const Image *image)
3914 % A description of each parameter follows:
3916 % o image: the image.
3919 MagickExport MagickOffsetType TellBlob(const Image *image)
3924 assert(image != (Image *) NULL);
3925 assert(image->signature == MagickSignature);
3926 if (image->debug != MagickFalse)
3927 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3928 assert(image->blob != (BlobInfo *) NULL);
3929 assert(image->blob->type != UndefinedStream);
3931 switch (image->blob->type)
3933 case UndefinedStream:
3934 case StandardStream:
3938 offset=ftell(image->blob->file_info.file);
3945 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3946 offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
3956 offset=image->blob->offset;
3964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3968 + U n m a p B l o b %
3972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3974 % UnmapBlob() deallocates the binary large object previously allocated with
3975 % the MapBlob method.
3977 % The format of the UnmapBlob method is:
3979 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3981 % A description of each parameter follows:
3983 % o map: the address of the binary large object.
3985 % o length: the length of the binary large object.
3988 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3990 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3994 status=munmap(map,length);
3995 return(status == -1 ? MagickFalse : MagickTrue);
3999 return(MagickFalse);
4004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4008 + W r i t e B l o b %
4012 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4014 % WriteBlob() writes data to a blob or image file. It returns the number of
4017 % The format of the WriteBlob method is:
4019 % ssize_t WriteBlob(Image *image,const size_t length,
4020 % const unsigned char *data)
4022 % A description of each parameter follows:
4024 % o image: the image.
4026 % o length: Specifies an integer representing the number of bytes to
4027 % write to the file.
4029 % o data: The address of the data to write to the blob or file.
4032 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
4033 const unsigned char *data)
4038 register const unsigned char
4044 assert(image != (Image *) NULL);
4045 assert(image->signature == MagickSignature);
4046 assert(data != (const unsigned char *) NULL);
4047 assert(image->blob != (BlobInfo *) NULL);
4048 assert(image->blob->type != UndefinedStream);
4053 switch (image->blob->type)
4055 case UndefinedStream:
4057 case StandardStream:
4059 count=write(fileno(image->blob->file_info.file),data,length);
4069 count=(ssize_t) fwrite((const char *) data,1,length,
4070 image->blob->file_info.file);
4075 c=putc((int) *p++,image->blob->file_info.file);
4082 c=putc((int) *p++,image->blob->file_info.file);
4094 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4099 count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
4100 (unsigned int) length);
4105 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4112 c=gzputc(image->blob->file_info.gzfile,(int) *p++);
4125 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4126 count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
4133 count=(ssize_t) image->blob->stream(image,data,length);
4138 register unsigned char
4141 if ((image->blob->offset+(MagickOffsetType) length) >=
4142 (MagickOffsetType) image->blob->extent)
4144 if (image->blob->mapped != MagickFalse)
4146 image->blob->quantum<<=1;
4147 image->blob->extent+=length+image->blob->quantum;
4148 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4149 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4150 (void) SyncBlob(image);
4151 if (image->blob->data == (unsigned char *) NULL)
4153 (void) DetachBlob(image->blob);
4157 q=image->blob->data+image->blob->offset;
4158 (void) memcpy(q,p,length);
4159 image->blob->offset+=length;
4160 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4161 image->blob->length=(size_t) image->blob->offset;
4162 count=(ssize_t) length;
4169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4173 + W r i t e B l o b B y t e %
4177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4179 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4180 % written (either 0 or 1);
4182 % The format of the WriteBlobByte method is:
4184 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4186 % A description of each parameter follows.
4188 % o image: the image.
4190 % o value: Specifies the value to write.
4193 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4195 assert(image != (Image *) NULL);
4196 assert(image->signature == MagickSignature);
4197 return(WriteBlobStream(image,1,&value));
4201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4205 + W r i t e B l o b F l o a t %
4209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4211 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4212 % specified by the endian member of the image structure.
4214 % The format of the WriteBlobFloat method is:
4216 % ssize_t WriteBlobFloat(Image *image,const float value)
4218 % A description of each parameter follows.
4220 % o image: the image.
4222 % o value: Specifies the value to write.
4225 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4236 quantum.unsigned_value=0U;
4237 quantum.float_value=value;
4238 return(WriteBlobLong(image,quantum.unsigned_value));
4242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4246 + W r i t e B l o b L o n g %
4250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4252 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4253 % specified by the endian member of the image structure.
4255 % The format of the WriteBlobLong method is:
4257 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4259 % A description of each parameter follows.
4261 % o image: the image.
4263 % o value: Specifies the value to write.
4266 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4271 assert(image != (Image *) NULL);
4272 assert(image->signature == MagickSignature);
4273 if (image->endian == LSBEndian)
4275 buffer[0]=(unsigned char) value;
4276 buffer[1]=(unsigned char) (value >> 8);
4277 buffer[2]=(unsigned char) (value >> 16);
4278 buffer[3]=(unsigned char) (value >> 24);
4279 return(WriteBlobStream(image,4,buffer));
4281 buffer[0]=(unsigned char) (value >> 24);
4282 buffer[1]=(unsigned char) (value >> 16);
4283 buffer[2]=(unsigned char) (value >> 8);
4284 buffer[3]=(unsigned char) value;
4285 return(WriteBlobStream(image,4,buffer));
4289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4293 + W r i t e B l o b S h o r t %
4297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4299 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4300 % byte-order specified by the endian member of the image structure.
4302 % The format of the WriteBlobShort method is:
4304 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4306 % A description of each parameter follows.
4308 % o image: the image.
4310 % o value: Specifies the value to write.
4313 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4318 assert(image != (Image *) NULL);
4319 assert(image->signature == MagickSignature);
4320 if (image->endian == LSBEndian)
4322 buffer[0]=(unsigned char) value;
4323 buffer[1]=(unsigned char) (value >> 8);
4324 return(WriteBlobStream(image,2,buffer));
4326 buffer[0]=(unsigned char) (value >> 8);
4327 buffer[1]=(unsigned char) value;
4328 return(WriteBlobStream(image,2,buffer));
4332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4336 + W r i t e B l o b L S B L o n g %
4340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4342 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4343 % least-significant byte first order.
4345 % The format of the WriteBlobLSBLong method is:
4347 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4349 % A description of each parameter follows.
4351 % o image: the image.
4353 % o value: Specifies the value to write.
4356 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4361 assert(image != (Image *) NULL);
4362 assert(image->signature == MagickSignature);
4363 buffer[0]=(unsigned char) value;
4364 buffer[1]=(unsigned char) (value >> 8);
4365 buffer[2]=(unsigned char) (value >> 16);
4366 buffer[3]=(unsigned char) (value >> 24);
4367 return(WriteBlobStream(image,4,buffer));
4371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4375 + W r i t e B l o b L S B S h o r t %
4379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4381 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4382 % least-significant byte first order.
4384 % The format of the WriteBlobLSBShort method is:
4386 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4388 % A description of each parameter follows.
4390 % o image: the image.
4392 % o value: Specifies the value to write.
4395 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4400 assert(image != (Image *) NULL);
4401 assert(image->signature == MagickSignature);
4402 buffer[0]=(unsigned char) value;
4403 buffer[1]=(unsigned char) (value >> 8);
4404 return(WriteBlobStream(image,2,buffer));
4408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4412 + W r i t e B l o b M S B L o n g %
4416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4418 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4419 % most-significant byte first order.
4421 % The format of the WriteBlobMSBLong method is:
4423 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4425 % A description of each parameter follows.
4427 % o value: Specifies the value to write.
4429 % o image: the image.
4432 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4437 assert(image != (Image *) NULL);
4438 assert(image->signature == MagickSignature);
4439 buffer[0]=(unsigned char) (value >> 24);
4440 buffer[1]=(unsigned char) (value >> 16);
4441 buffer[2]=(unsigned char) (value >> 8);
4442 buffer[3]=(unsigned char) value;
4443 return(WriteBlobStream(image,4,buffer));
4447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4451 + W r i t e B l o b M S B L o n g L o n g %
4455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4457 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4458 % most-significant byte first order.
4460 % The format of the WriteBlobMSBLongLong method is:
4462 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4464 % A description of each parameter follows.
4466 % o value: Specifies the value to write.
4468 % o image: the image.
4471 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4472 const MagickSizeType value)
4477 assert(image != (Image *) NULL);
4478 assert(image->signature == MagickSignature);
4479 buffer[0]=(unsigned char) (value >> 56);
4480 buffer[1]=(unsigned char) (value >> 48);
4481 buffer[2]=(unsigned char) (value >> 40);
4482 buffer[3]=(unsigned char) (value >> 32);
4483 buffer[4]=(unsigned char) (value >> 24);
4484 buffer[5]=(unsigned char) (value >> 16);
4485 buffer[6]=(unsigned char) (value >> 8);
4486 buffer[7]=(unsigned char) value;
4487 return(WriteBlobStream(image,8,buffer));
4491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4495 + W r i t e B l o b M S B S h o r t %
4499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4501 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4502 % most-significant byte first order.
4504 % The format of the WriteBlobMSBShort method is:
4506 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4508 % A description of each parameter follows.
4510 % o value: Specifies the value to write.
4512 % o file: Specifies the file to write the data to.
4515 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4520 assert(image != (Image *) NULL);
4521 assert(image->signature == MagickSignature);
4522 buffer[0]=(unsigned char) (value >> 8);
4523 buffer[1]=(unsigned char) value;
4524 return(WriteBlobStream(image,2,buffer));
4528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4532 + W r i t e B l o b S t r i n g %
4536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4538 % WriteBlobString() write a string to a blob. It returns the number of
4539 % characters written.
4541 % The format of the WriteBlobString method is:
4543 % ssize_t WriteBlobString(Image *image,const char *string)
4545 % A description of each parameter follows.
4547 % o image: the image.
4549 % o string: Specifies the string to write.
4552 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4554 assert(image != (Image *) NULL);
4555 assert(image->signature == MagickSignature);
4556 assert(string != (const char *) NULL);
4557 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));