2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/client.h"
48 #include "MagickCore/constitute.h"
49 #include "MagickCore/delegate.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image-private.h"
53 #include "MagickCore/list.h"
54 #include "MagickCore/locale_.h"
55 #include "MagickCore/log.h"
56 #include "MagickCore/magick.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/policy.h"
59 #include "MagickCore/resource_.h"
60 #include "MagickCore/semaphore.h"
61 #include "MagickCore/string_.h"
62 #include "MagickCore/string-private.h"
63 #include "MagickCore/token.h"
64 #include "MagickCore/utility.h"
65 #include "MagickCore/utility-private.h"
66 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
67 # include <sys/mman.h>
69 #if defined(MAGICKCORE_ZLIB_DELEGATE)
72 #if defined(MAGICKCORE_BZLIB_DELEGATE)
79 #define MagickMaxBlobExtent 65541
80 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
81 # define MAP_ANONYMOUS MAP_ANON
83 #if !defined(MAP_FAILED)
84 #define MAP_FAILED ((void *) -1)
91 #define _O_BINARY O_BINARY
149 Forward declarations.
155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159 + A t t a c h B l o b %
163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165 % AttachBlob() attaches a blob to the BlobInfo structure.
167 % The format of the AttachBlob method is:
169 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
171 % A description of each parameter follows:
173 % o blob_info: Specifies a pointer to a BlobInfo structure.
175 % o blob: the address of a character stream in one of the image formats
176 % understood by ImageMagick.
178 % o length: This size_t integer reflects the length in bytes of the blob.
181 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
184 assert(blob_info != (BlobInfo *) NULL);
185 if (blob_info->debug != MagickFalse)
186 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
187 blob_info->length=length;
188 blob_info->extent=length;
189 blob_info->quantum=(size_t) MagickMaxBlobExtent;
191 blob_info->type=BlobStream;
192 blob_info->file=(FILE *) NULL;
193 blob_info->data=(unsigned char *) blob;
194 blob_info->mapped=MagickFalse;
198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202 + B l o b T o F i l e %
206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
209 % occurs otherwise MagickTrue.
211 % The format of the BlobToFile method is:
213 % MagickBooleanType BlobToFile(char *filename,const void *blob,
214 % const size_t length,ExceptionInfo *exception)
216 % A description of each parameter follows:
218 % o filename: Write the blob to this file.
220 % o blob: the address of a blob.
222 % o length: This length in bytes of the blob.
224 % o exception: return any errors or warnings in this structure.
228 static inline MagickSizeType MagickMin(const MagickSizeType x,
229 const MagickSizeType y)
236 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
237 const size_t length,ExceptionInfo *exception)
248 assert(filename != (const char *) NULL);
249 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
250 assert(blob != (const void *) NULL);
251 if (*filename == '\0')
252 file=AcquireUniqueFileResource(filename);
254 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
257 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
260 for (i=0; i < length; i+=count)
262 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
263 i,(MagickSizeType) SSIZE_MAX));
272 if ((file == -1) || (i < length))
274 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285 % B l o b T o I m a g e %
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291 % BlobToImage() implements direct to memory image formats. It returns the
294 % The format of the BlobToImage method is:
296 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
297 % const size_t length,ExceptionInfo *exception)
299 % A description of each parameter follows:
301 % o image_info: the image info.
303 % o blob: the address of a character stream in one of the image formats
304 % understood by ImageMagick.
306 % o length: This size_t integer reflects the length in bytes of the blob.
308 % o exception: return any errors or warnings in this structure.
311 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
312 const size_t length,ExceptionInfo *exception)
327 assert(image_info != (ImageInfo *) NULL);
328 assert(image_info->signature == MagickSignature);
329 if (image_info->debug != MagickFalse)
330 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
331 image_info->filename);
332 assert(exception != (ExceptionInfo *) NULL);
333 if ((blob == (const void *) NULL) || (length == 0))
335 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
336 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
337 return((Image *) NULL);
339 blob_info=CloneImageInfo(image_info);
340 blob_info->blob=(void *) blob;
341 blob_info->length=length;
342 if (*blob_info->magick == '\0')
343 (void) SetImageInfo(blob_info,0,exception);
344 magick_info=GetMagickInfo(blob_info->magick,exception);
345 if (magick_info == (const MagickInfo *) NULL)
347 blob_info=DestroyImageInfo(blob_info);
348 (void) ThrowMagickException(exception,GetMagickModule(),
349 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
350 image_info->filename);
351 return((Image *) NULL);
353 if (GetMagickBlobSupport(magick_info) != MagickFalse)
356 Native blob support for this image format.
358 (void) CopyMagickString(blob_info->filename,image_info->filename,
360 (void) CopyMagickString(blob_info->magick,image_info->magick,
362 image=ReadImage(blob_info,exception);
363 if (image != (Image *) NULL)
364 (void) DetachBlob(image->blob);
365 blob_info=DestroyImageInfo(blob_info);
369 Write blob to a temporary file on disk.
371 blob_info->blob=(void *) NULL;
373 *blob_info->filename='\0';
374 status=BlobToFile(blob_info->filename,blob,length,exception);
375 if (status == MagickFalse)
377 (void) RelinquishUniqueFileResource(blob_info->filename);
378 blob_info=DestroyImageInfo(blob_info);
379 return((Image *) NULL);
381 clone_info=CloneImageInfo(blob_info);
382 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
383 blob_info->magick,blob_info->filename);
384 image=ReadImage(clone_info,exception);
385 clone_info=DestroyImageInfo(clone_info);
386 (void) RelinquishUniqueFileResource(blob_info->filename);
387 blob_info=DestroyImageInfo(blob_info);
392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396 + C l o n e B l o b I n f o %
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
403 % blob info is NULL, a new one.
405 % The format of the CloneBlobInfo method is:
407 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
409 % A description of each parameter follows:
411 % o blob_info: the blob info.
414 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
419 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
420 if (clone_info == (BlobInfo *) NULL)
421 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
422 GetBlobInfo(clone_info);
423 if (blob_info == (BlobInfo *) NULL)
425 clone_info->length=blob_info->length;
426 clone_info->extent=blob_info->extent;
427 clone_info->synchronize=blob_info->synchronize;
428 clone_info->quantum=blob_info->quantum;
429 clone_info->mapped=blob_info->mapped;
430 clone_info->eof=blob_info->eof;
431 clone_info->offset=blob_info->offset;
432 clone_info->size=blob_info->size;
433 clone_info->exempt=blob_info->exempt;
434 clone_info->status=blob_info->status;
435 clone_info->temporary=blob_info->temporary;
436 clone_info->type=blob_info->type;
437 clone_info->file=blob_info->file;
438 clone_info->properties=blob_info->properties;
439 clone_info->stream=blob_info->stream;
440 clone_info->data=blob_info->data;
441 clone_info->debug=IsEventLogging();
442 clone_info->reference_count=1;
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451 + C l o s e B l o b %
455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457 % CloseBlob() closes a stream associated with the image.
459 % The format of the CloseBlob method is:
461 % MagickBooleanType CloseBlob(Image *image)
463 % A description of each parameter follows:
465 % o image: the image.
468 MagickExport MagickBooleanType CloseBlob(Image *image)
476 assert(image != (Image *) NULL);
477 assert(image->signature == MagickSignature);
478 if (image->debug != MagickFalse)
479 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
480 assert(image->blob != (BlobInfo *) NULL);
481 if (image->blob->type == UndefinedStream)
483 if (image->blob->synchronize != MagickFalse)
485 image->blob->size=GetBlobSize(image);
486 image->extent=image->blob->size;
487 image->blob->eof=MagickFalse;
488 if (image->blob->exempt != MagickFalse)
490 image->blob->type=UndefinedStream;
494 switch (image->blob->type)
496 case UndefinedStream:
502 status=ferror(image->blob->file);
507 #if defined(MAGICKCORE_ZLIB_DELEGATE)
508 (void) gzerror(image->blob->file,&status);
514 #if defined(MAGICKCORE_BZLIB_DELEGATE)
515 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
523 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
524 switch (image->blob->type)
526 case UndefinedStream:
531 if (image->blob->synchronize != MagickFalse)
533 status=fflush(image->blob->file);
534 status=fsync(fileno(image->blob->file));
536 status=fclose(image->blob->file);
541 #if defined(MAGICKCORE_HAVE_PCLOSE)
542 status=pclose(image->blob->file);
548 #if defined(MAGICKCORE_ZLIB_DELEGATE)
549 status=gzclose(image->blob->file);
555 #if defined(MAGICKCORE_BZLIB_DELEGATE)
556 BZ2_bzclose((BZFILE *) image->blob->file);
564 if (image->blob->file != (FILE *) NULL)
566 if (image->blob->synchronize != MagickFalse)
567 (void) fsync(fileno(image->blob->file));
568 status=fclose(image->blob->file);
573 (void) DetachBlob(image->blob);
574 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
575 return(image->blob->status);
579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
583 + D e s t r o y B l o b %
587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589 % DestroyBlob() deallocates memory associated with a blob.
591 % The format of the DestroyBlob method is:
593 % void DestroyBlob(Image *image)
595 % A description of each parameter follows:
597 % o image: the image.
600 MagickExport void DestroyBlob(Image *image)
605 assert(image != (Image *) NULL);
606 assert(image->signature == MagickSignature);
607 if (image->debug != MagickFalse)
608 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
609 assert(image->blob != (BlobInfo *) NULL);
610 assert(image->blob->signature == MagickSignature);
612 LockSemaphoreInfo(image->blob->semaphore);
613 image->blob->reference_count--;
614 assert(image->blob->reference_count >= 0);
615 if (image->blob->reference_count == 0)
617 UnlockSemaphoreInfo(image->blob->semaphore);
618 if (destroy == MagickFalse)
620 (void) CloseBlob(image);
621 if (image->blob->mapped != MagickFalse)
622 (void) UnmapBlob(image->blob->data,image->blob->length);
623 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
624 DestroySemaphoreInfo(&image->blob->semaphore);
625 image->blob->signature=(~MagickSignature);
626 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634 + D e t a c h B l o b %
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 % DetachBlob() detaches a blob from the BlobInfo structure.
642 % The format of the DetachBlob method is:
644 % unsigned char *DetachBlob(BlobInfo *blob_info)
646 % A description of each parameter follows:
648 % o blob_info: Specifies a pointer to a BlobInfo structure.
651 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
656 assert(blob_info != (BlobInfo *) NULL);
657 if (blob_info->debug != MagickFalse)
658 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
659 if (blob_info->mapped != MagickFalse)
660 (void) UnmapBlob(blob_info->data,blob_info->length);
661 blob_info->mapped=MagickFalse;
664 blob_info->eof=MagickFalse;
665 blob_info->exempt=MagickFalse;
666 blob_info->type=UndefinedStream;
667 blob_info->file=(FILE *) NULL;
668 data=blob_info->data;
669 blob_info->data=(unsigned char *) NULL;
670 blob_info->stream=(StreamHandler) NULL;
675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 + D i s c a r d B l o b B y t e s %
683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
685 % DiscardBlobBytes() discards bytes in a blob.
687 % The format of the DiscardBlobBytes method is:
689 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
691 % A description of each parameter follows.
693 % o image: the image.
695 % o length: the number of bytes to skip.
699 static inline const unsigned char *ReadBlobStream(Image *image,
700 const size_t length,unsigned char *data,ssize_t *count)
702 assert(count != (ssize_t *) NULL);
703 assert(image->blob != (BlobInfo *) NULL);
704 if (image->blob->type != BlobStream)
706 *count=ReadBlob(image,length,data);
709 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
712 image->blob->eof=MagickTrue;
715 data=image->blob->data+image->blob->offset;
716 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
717 image->blob->offset));
718 image->blob->offset+=(*count);
719 if (*count != (ssize_t) length)
720 image->blob->eof=MagickTrue;
724 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
725 const MagickSizeType length)
727 register MagickOffsetType
739 assert(image != (Image *) NULL);
740 assert(image->signature == MagickSignature);
742 for (i=0; i < (MagickOffsetType) length; i+=count)
744 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
745 (void) ReadBlobStream(image,quantum,buffer,&count);
753 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
761 + D u p l i c a t e s B l o b %
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767 % DuplicateBlob() duplicates a blob descriptor.
769 % The format of the DuplicateBlob method is:
771 % void DuplicateBlob(Image *image,const Image *duplicate)
773 % A description of each parameter follows:
775 % o image: the image.
777 % o duplicate: the duplicate image.
780 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
782 assert(image != (Image *) NULL);
783 assert(image->signature == MagickSignature);
784 if (image->debug != MagickFalse)
785 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
786 assert(duplicate != (Image *) NULL);
787 assert(duplicate->signature == MagickSignature);
789 image->blob=ReferenceBlob(duplicate->blob);
793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803 % EOFBlob() returns a non-zero value when EOF has been detected reading from
806 % The format of the EOFBlob method is:
808 % int EOFBlob(const Image *image)
810 % A description of each parameter follows:
812 % o image: the image.
815 MagickExport int EOFBlob(const Image *image)
817 assert(image != (Image *) NULL);
818 assert(image->signature == MagickSignature);
819 if (image->debug != MagickFalse)
820 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
821 assert(image->blob != (BlobInfo *) NULL);
822 assert(image->blob->type != UndefinedStream);
823 switch (image->blob->type)
825 case UndefinedStream:
831 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
836 image->blob->eof=MagickFalse;
841 #if defined(MAGICKCORE_BZLIB_DELEGATE)
846 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
847 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
853 image->blob->eof=MagickFalse;
859 return((int) image->blob->eof);
863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
867 + F i l e T o B l o b %
871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
873 % FileToBlob() returns the contents of a file as a buffer terminated with
874 % the '\0' character. The length of the buffer (not including the extra
875 % terminating '\0' character) is returned via the 'length' parameter. Free
876 % the buffer with RelinquishMagickMemory().
878 % The format of the FileToBlob method is:
880 % unsigned char *FileToBlob(const char *filename,const size_t extent,
881 % size_t *length,ExceptionInfo *exception)
883 % A description of each parameter follows:
885 % o blob: FileToBlob() returns the contents of a file as a blob. If
886 % an error occurs NULL is returned.
888 % o filename: the filename.
890 % o extent: The maximum length of the blob.
892 % o length: On return, this reflects the actual length of the blob.
894 % o exception: return any errors or warnings in this structure.
897 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
898 size_t *length,ExceptionInfo *exception)
918 assert(filename != (const char *) NULL);
919 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
920 assert(exception != (ExceptionInfo *) NULL);
923 if (LocaleCompare(filename,"-") != 0)
924 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
927 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
928 return((unsigned char *) NULL);
930 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
932 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
941 Stream is not seekable.
943 quantum=(size_t) MagickMaxBufferExtent;
944 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
945 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
946 MagickMaxBufferExtent);
947 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
948 for (i=0; blob != (unsigned char *) NULL; i+=count)
950 count=(ssize_t) read(file,blob+i,quantum);
957 if (~(1UL*i) < (quantum+1))
959 blob=(unsigned char *) RelinquishMagickMemory(blob);
962 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
964 if ((size_t) (i+count) >= extent)
967 if (LocaleCompare(filename,"-") != 0)
969 if (blob == (unsigned char *) NULL)
971 (void) ThrowMagickException(exception,GetMagickModule(),
972 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
973 return((unsigned char *) NULL);
977 blob=(unsigned char *) RelinquishMagickMemory(blob);
978 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
979 return((unsigned char *) NULL);
981 *length=(size_t) MagickMin(i+count,extent);
985 *length=(size_t) MagickMin((MagickSizeType) offset,extent);
986 blob=(unsigned char *) NULL;
987 if (~(*length) >= (MaxTextExtent-1))
988 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
990 if (blob == (unsigned char *) NULL)
993 (void) ThrowMagickException(exception,GetMagickModule(),
994 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
995 return((unsigned char *) NULL);
997 map=MapBlob(file,ReadMode,0,*length);
998 if (map != (unsigned char *) NULL)
1000 (void) memcpy(blob,map,*length);
1001 (void) UnmapBlob(map,*length);
1005 (void) lseek(file,0,SEEK_SET);
1006 for (i=0; i < *length; i+=count)
1008 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1009 (MagickSizeType) SSIZE_MAX));
1020 blob=(unsigned char *) RelinquishMagickMemory(blob);
1021 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1022 return((unsigned char *) NULL);
1026 if (LocaleCompare(filename,"-") != 0)
1030 blob=(unsigned char *) RelinquishMagickMemory(blob);
1031 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1041 % F i l e T o I m a g e %
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1047 % FileToImage() write the contents of a file to an image.
1049 % The format of the FileToImage method is:
1051 % MagickBooleanType FileToImage(Image *,const char *filename)
1053 % A description of each parameter follows:
1055 % o image: the image.
1057 % o filename: the filename.
1061 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1062 const unsigned char *data)
1067 register unsigned char
1070 assert(image->blob != (BlobInfo *) NULL);
1071 if (image->blob->type != BlobStream)
1072 return(WriteBlob(image,length,data));
1073 assert(image->blob->type != UndefinedStream);
1074 assert(data != (void *) NULL);
1075 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1076 if (extent >= image->blob->extent)
1078 image->blob->quantum<<=1;
1079 extent=image->blob->extent+image->blob->quantum+length;
1080 if (SetBlobExtent(image,extent) == MagickFalse)
1083 q=image->blob->data+image->blob->offset;
1084 (void) memcpy(q,data,length);
1085 image->blob->offset+=length;
1086 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1087 image->blob->length=(size_t) image->blob->offset;
1088 return((ssize_t) length);
1091 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
1092 ExceptionInfo *exception)
1110 assert(image != (const Image *) NULL);
1111 assert(image->signature == MagickSignature);
1112 assert(filename != (const char *) NULL);
1113 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1114 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1117 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
1118 return(MagickFalse);
1120 quantum=(size_t) MagickMaxBufferExtent;
1121 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1122 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1123 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1124 if (blob == (unsigned char *) NULL)
1126 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
1128 return(MagickFalse);
1132 count=(ssize_t) read(file,blob,quantum);
1139 length=(size_t) count;
1140 count=WriteBlobStream(image,length,blob);
1141 if (count != (ssize_t) length)
1143 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1149 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1150 blob=(unsigned char *) RelinquishMagickMemory(blob);
1155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1159 + G e t B l o b E r r o r %
1163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1165 % GetBlobError() returns MagickTrue if the blob associated with the specified
1166 % image encountered an error.
1168 % The format of the GetBlobError method is:
1170 % MagickBooleanType GetBlobError(const Image *image)
1172 % A description of each parameter follows:
1174 % o image: the image.
1177 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1179 assert(image != (const Image *) NULL);
1180 assert(image->signature == MagickSignature);
1181 if (image->debug != MagickFalse)
1182 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1183 return(image->blob->status);
1187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191 + G e t B l o b F i l e H a n d l e %
1195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1197 % GetBlobFileHandle() returns the file handle associated with the image blob.
1199 % The format of the GetBlobFile method is:
1201 % FILE *GetBlobFileHandle(const Image *image)
1203 % A description of each parameter follows:
1205 % o image: the image.
1208 MagickExport FILE *GetBlobFileHandle(const Image *image)
1210 assert(image != (const Image *) NULL);
1211 assert(image->signature == MagickSignature);
1212 return(image->blob->file);
1216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220 + G e t B l o b I n f o %
1224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226 % GetBlobInfo() initializes the BlobInfo structure.
1228 % The format of the GetBlobInfo method is:
1230 % void GetBlobInfo(BlobInfo *blob_info)
1232 % A description of each parameter follows:
1234 % o blob_info: Specifies a pointer to a BlobInfo structure.
1237 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1239 assert(blob_info != (BlobInfo *) NULL);
1240 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1241 blob_info->type=UndefinedStream;
1242 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1243 blob_info->properties.st_mtime=time((time_t *) NULL);
1244 blob_info->properties.st_ctime=time((time_t *) NULL);
1245 blob_info->debug=IsEventLogging();
1246 blob_info->reference_count=1;
1247 blob_info->semaphore=AllocateSemaphoreInfo();
1248 blob_info->signature=MagickSignature;
1252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1256 % G e t B l o b P r o p e r t i e s %
1260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262 % GetBlobProperties() returns information about an image blob.
1264 % The format of the GetBlobProperties method is:
1266 % const struct stat *GetBlobProperties(const Image *image)
1268 % A description of each parameter follows:
1270 % o image: the image.
1273 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1275 assert(image != (Image *) NULL);
1276 assert(image->signature == MagickSignature);
1277 if (image->debug != MagickFalse)
1278 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1279 return(&image->blob->properties);
1283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1287 + G e t B l o b S i z e %
1291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293 % GetBlobSize() returns the current length of the image file or blob; zero is
1294 % returned if the size cannot be determined.
1296 % The format of the GetBlobSize method is:
1298 % MagickSizeType GetBlobSize(const Image *image)
1300 % A description of each parameter follows:
1302 % o image: the image.
1305 MagickExport MagickSizeType GetBlobSize(const Image *image)
1310 assert(image != (Image *) NULL);
1311 assert(image->signature == MagickSignature);
1312 if (image->debug != MagickFalse)
1313 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1314 assert(image->blob != (BlobInfo *) NULL);
1316 switch (image->blob->type)
1318 case UndefinedStream:
1320 extent=image->blob->size;
1325 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1326 extent=(MagickSizeType) image->blob->properties.st_size;
1329 case StandardStream:
1332 extent=image->blob->size;
1341 status=GetPathAttributes(image->filename,&image->blob->properties);
1342 if (status != MagickFalse)
1343 extent=(MagickSizeType) image->blob->properties.st_size;
1350 extent=(MagickSizeType) image->blob->length;
1358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1362 + G e t B l o b S t r e a m D a t a %
1366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1368 % GetBlobStreamData() returns the stream data for the image.
1370 % The format of the GetBlobStreamData method is:
1372 % unsigned char *GetBlobStreamData(const Image *image)
1374 % A description of each parameter follows:
1376 % o image: the image.
1379 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1381 assert(image != (const Image *) NULL);
1382 assert(image->signature == MagickSignature);
1383 return(image->blob->data);
1387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1391 + G e t B l o b S t r e a m H a n d l e r %
1395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1397 % GetBlobStreamHandler() returns the stream handler for the image.
1399 % The format of the GetBlobStreamHandler method is:
1401 % StreamHandler GetBlobStreamHandler(const Image *image)
1403 % A description of each parameter follows:
1405 % o image: the image.
1408 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1410 assert(image != (const Image *) NULL);
1411 assert(image->signature == MagickSignature);
1412 if (image->debug != MagickFalse)
1413 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1414 return(image->blob->stream);
1418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1422 % I m a g e T o B l o b %
1426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 % ImageToBlob() implements direct to memory image formats. It returns the
1429 % image as a formatted blob and its length. The magick member of the Image
1430 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1431 % etc.). This method is the equivalent of WriteImage(), but writes the
1432 % formatted "file" to a memory buffer rather than to an actual file.
1434 % The format of the ImageToBlob method is:
1436 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1437 % size_t *length,ExceptionInfo *exception)
1439 % A description of each parameter follows:
1441 % o image_info: the image info.
1443 % o image: the image.
1445 % o length: This pointer to a size_t integer sets the initial length of the
1446 % blob. On return, it reflects the actual length of the blob.
1448 % o exception: return any errors or warnings in this structure.
1451 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1452 Image *image,size_t *length,ExceptionInfo *exception)
1466 assert(image_info != (const ImageInfo *) NULL);
1467 assert(image_info->signature == MagickSignature);
1468 if (image_info->debug != MagickFalse)
1469 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1470 image_info->filename);
1471 assert(image != (Image *) NULL);
1472 assert(image->signature == MagickSignature);
1473 assert(exception != (ExceptionInfo *) NULL);
1475 blob=(unsigned char *) NULL;
1476 blob_info=CloneImageInfo(image_info);
1477 blob_info->adjoin=MagickFalse;
1478 (void) SetImageInfo(blob_info,1,exception);
1479 if (*blob_info->magick != '\0')
1480 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1481 magick_info=GetMagickInfo(image->magick,exception);
1482 if (magick_info == (const MagickInfo *) NULL)
1484 (void) ThrowMagickException(exception,GetMagickModule(),
1485 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1489 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1490 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1493 Native blob support for this image format.
1495 blob_info->length=0;
1496 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1497 sizeof(unsigned char));
1498 if (blob_info->blob == (void *) NULL)
1499 (void) ThrowMagickException(exception,GetMagickModule(),
1500 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1503 (void) CloseBlob(image);
1504 image->blob->exempt=MagickTrue;
1505 *image->filename='\0';
1506 status=WriteImage(blob_info,image,exception);
1507 if ((status != MagickFalse) && (image->blob->length != 0))
1509 *length=image->blob->length;
1510 blob=DetachBlob(image->blob);
1511 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1519 unique[MaxTextExtent];
1525 Write file to disk in blob image format.
1527 file=AcquireUniqueFileResource(unique);
1530 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1531 image_info->filename);
1535 blob_info->file=fdopen(file,"wb");
1536 if (blob_info->file != (FILE *) NULL)
1538 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1539 image->magick,unique);
1540 status=WriteImage(blob_info,image,exception);
1541 (void) fclose(blob_info->file);
1542 if (status != MagickFalse)
1543 blob=FileToBlob(image->filename,~0UL,length,exception);
1545 (void) RelinquishUniqueFileResource(unique);
1548 blob_info=DestroyImageInfo(blob_info);
1553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1557 % I m a g e T o F i l e %
1561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1563 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1564 % occurs otherwise MagickTrue.
1566 % The format of the ImageToFile method is:
1568 % MagickBooleanType ImageToFile(Image *image,char *filename,
1569 % ExceptionInfo *exception)
1571 % A description of each parameter follows:
1573 % o image: the image.
1575 % o filename: Write the image to this file.
1577 % o exception: return any errors or warnings in this structure.
1580 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1581 ExceptionInfo *exception)
1586 register const unsigned char
1605 assert(image != (Image *) NULL);
1606 assert(image->signature == MagickSignature);
1607 assert(image->blob != (BlobInfo *) NULL);
1608 assert(image->blob->type != UndefinedStream);
1609 if (image->debug != MagickFalse)
1610 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1611 assert(filename != (const char *) NULL);
1612 if (*filename == '\0')
1613 file=AcquireUniqueFileResource(filename);
1615 if (LocaleCompare(filename,"-") == 0)
1616 file=fileno(stdout);
1618 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1621 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1622 return(MagickFalse);
1624 quantum=(size_t) MagickMaxBufferExtent;
1625 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1626 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
1627 MagickMaxBufferExtent);
1628 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1629 if (buffer == (unsigned char *) NULL)
1632 (void) ThrowMagickException(exception,GetMagickModule(),
1633 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1634 return(MagickFalse);
1637 p=ReadBlobStream(image,quantum,buffer,&count);
1638 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1640 length=(size_t) count;
1641 for (i=0; i < length; i+=count)
1643 count=write(file,p+i,(size_t) (length-i));
1654 if (LocaleCompare(filename,"-") != 0)
1656 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1657 if ((file == -1) || (i < length))
1659 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1660 return(MagickFalse);
1666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1670 % I m a g e s T o B l o b %
1674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1676 % ImagesToBlob() implements direct to memory image formats. It returns the
1677 % image sequence as a blob and its length. The magick member of the ImageInfo
1678 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1680 % Note, some image formats do not permit multiple images to the same image
1681 % stream (e.g. JPEG). in this instance, just the first image of the
1682 % sequence is returned as a blob.
1684 % The format of the ImagesToBlob method is:
1686 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1687 % size_t *length,ExceptionInfo *exception)
1689 % A description of each parameter follows:
1691 % o image_info: the image info.
1693 % o images: the image list.
1695 % o length: This pointer to a size_t integer sets the initial length of the
1696 % blob. On return, it reflects the actual length of the blob.
1698 % o exception: return any errors or warnings in this structure.
1701 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1702 Image *images,size_t *length,ExceptionInfo *exception)
1716 assert(image_info != (const ImageInfo *) NULL);
1717 assert(image_info->signature == MagickSignature);
1718 if (image_info->debug != MagickFalse)
1719 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1720 image_info->filename);
1721 assert(images != (Image *) NULL);
1722 assert(images->signature == MagickSignature);
1723 assert(exception != (ExceptionInfo *) NULL);
1725 blob=(unsigned char *) NULL;
1726 blob_info=CloneImageInfo(image_info);
1727 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1729 if (*blob_info->magick != '\0')
1730 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1731 if (blob_info->adjoin == MagickFalse)
1733 blob_info=DestroyImageInfo(blob_info);
1734 return(ImageToBlob(image_info,images,length,exception));
1736 magick_info=GetMagickInfo(images->magick,exception);
1737 if (magick_info == (const MagickInfo *) NULL)
1739 (void) ThrowMagickException(exception,GetMagickModule(),
1740 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1744 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1745 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1748 Native blob support for this images format.
1750 blob_info->length=0;
1751 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1752 sizeof(unsigned char));
1753 if (blob_info->blob == (void *) NULL)
1754 (void) ThrowMagickException(exception,GetMagickModule(),
1755 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1758 images->blob->exempt=MagickTrue;
1759 *images->filename='\0';
1760 status=WriteImages(blob_info,images,images->filename,exception);
1761 if ((status != MagickFalse) && (images->blob->length != 0))
1763 *length=images->blob->length;
1764 blob=DetachBlob(images->blob);
1765 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1773 filename[MaxTextExtent],
1774 unique[MaxTextExtent];
1780 Write file to disk in blob images format.
1782 file=AcquireUniqueFileResource(unique);
1785 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1786 image_info->filename);
1790 blob_info->file=fdopen(file,"wb");
1791 if (blob_info->file != (FILE *) NULL)
1793 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1794 images->magick,unique);
1795 status=WriteImages(blob_info,images,filename,exception);
1796 (void) fclose(blob_info->file);
1797 if (status != MagickFalse)
1798 blob=FileToBlob(images->filename,~0UL,length,exception);
1800 (void) RelinquishUniqueFileResource(unique);
1803 blob_info=DestroyImageInfo(blob_info);
1807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1811 % I n j e c t I m a g e B l o b %
1815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1817 % InjectImageBlob() injects the image with a copy of itself in the specified
1818 % format (e.g. inject JPEG into a PDF image).
1820 % The format of the InjectImageBlob method is:
1822 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1823 % Image *image,Image *inject_image,const char *format,
1824 % ExceptionInfo *exception)
1826 % A description of each parameter follows:
1828 % o image_info: the image info..
1830 % o image: the image.
1832 % o inject_image: inject into the image stream.
1834 % o format: the image format.
1836 % o exception: return any errors or warnings in this structure.
1839 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1840 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1843 filename[MaxTextExtent];
1876 Write inject image to a temporary file.
1878 assert(image_info != (ImageInfo *) NULL);
1879 assert(image_info->signature == MagickSignature);
1880 assert(image != (Image *) NULL);
1881 assert(image->signature == MagickSignature);
1882 if (image->debug != MagickFalse)
1883 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1884 assert(inject_image != (Image *) NULL);
1885 assert(inject_image->signature == MagickSignature);
1886 assert(exception != (ExceptionInfo *) NULL);
1887 unique_file=(FILE *) NULL;
1888 file=AcquireUniqueFileResource(filename);
1890 unique_file=fdopen(file,"wb");
1891 if ((file == -1) || (unique_file == (FILE *) NULL))
1893 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1894 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1896 return(MagickFalse);
1898 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1899 if (byte_image == (Image *) NULL)
1901 (void) fclose(unique_file);
1902 (void) RelinquishUniqueFileResource(filename);
1903 return(MagickFalse);
1905 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1907 DestroyBlob(byte_image);
1908 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1909 write_info=CloneImageInfo(image_info);
1910 SetImageInfoFile(write_info,unique_file);
1911 status=WriteImage(write_info,byte_image,exception);
1912 write_info=DestroyImageInfo(write_info);
1913 byte_image=DestroyImage(byte_image);
1914 (void) fclose(unique_file);
1915 if (status == MagickFalse)
1917 (void) RelinquishUniqueFileResource(filename);
1918 return(MagickFalse);
1921 Inject into image stream.
1923 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1926 (void) RelinquishUniqueFileResource(filename);
1927 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1928 image_info->filename);
1929 return(MagickFalse);
1931 quantum=(size_t) MagickMaxBufferExtent;
1932 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1933 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1934 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1935 if (buffer == (unsigned char *) NULL)
1937 (void) RelinquishUniqueFileResource(filename);
1938 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1941 for (i=0; ; i+=count)
1943 count=(ssize_t) read(file,buffer,quantum);
1950 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1955 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1956 (void) RelinquishUniqueFileResource(filename);
1957 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1966 + I s B l o b E x e m p t %
1970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1972 % IsBlobExempt() returns true if the blob is exempt.
1974 % The format of the IsBlobExempt method is:
1976 % MagickBooleanType IsBlobExempt(const Image *image)
1978 % A description of each parameter follows:
1980 % o image: the image.
1983 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
1985 assert(image != (const Image *) NULL);
1986 assert(image->signature == MagickSignature);
1987 if (image->debug != MagickFalse)
1988 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1989 return(image->blob->exempt);
1993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1997 + I s B l o b S e e k a b l e %
2001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2003 % IsBlobSeekable() returns true if the blob is seekable.
2005 % The format of the IsBlobSeekable method is:
2007 % MagickBooleanType IsBlobSeekable(const Image *image)
2009 % A description of each parameter follows:
2011 % o image: the image.
2014 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2019 assert(image != (const Image *) NULL);
2020 assert(image->signature == MagickSignature);
2021 if (image->debug != MagickFalse)
2022 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2023 seekable=(image->blob->type == FileStream) ||
2024 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2033 + I s B l o b T e m p o r a r y %
2037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2039 % IsBlobTemporary() returns true if the blob is temporary.
2041 % The format of the IsBlobTemporary method is:
2043 % MagickBooleanType IsBlobTemporary(const Image *image)
2045 % A description of each parameter follows:
2047 % o image: the image.
2050 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2052 assert(image != (const Image *) NULL);
2053 assert(image->signature == MagickSignature);
2054 if (image->debug != MagickFalse)
2055 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2056 return(image->blob->temporary);
2060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2070 % MapBlob() creates a mapping from a file to a binary large object.
2072 % The format of the MapBlob method is:
2074 % unsigned char *MapBlob(int file,const MapMode mode,
2075 % const MagickOffsetType offset,const size_t length)
2077 % A description of each parameter follows:
2079 % o file: map this file descriptor.
2081 % o mode: ReadMode, WriteMode, or IOMode.
2083 % o offset: starting at this offset within the file.
2085 % o length: the length of the mapping is returned in this pointer.
2088 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2089 const MagickOffsetType offset,const size_t length)
2091 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2104 #if defined(MAP_ANONYMOUS)
2105 flags|=MAP_ANONYMOUS;
2107 return((unsigned char *) NULL);
2114 protection=PROT_READ;
2116 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2122 protection=PROT_WRITE;
2124 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2126 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2127 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2128 POSIX_MADV_WILLNEED);
2134 protection=PROT_READ | PROT_WRITE;
2136 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2141 if (map == (unsigned char *) MAP_FAILED)
2142 return((unsigned char *) NULL);
2149 return((unsigned char *) NULL);
2154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2158 + M S B O r d e r L o n g %
2162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2164 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2165 % most-significant byte first.
2167 % The format of the MSBOrderLong method is:
2169 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2171 % A description of each parameter follows.
2173 % o buffer: Specifies a pointer to a buffer of integers.
2175 % o length: Specifies the length of the buffer.
2178 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2183 register unsigned char
2187 assert(buffer != (unsigned char *) NULL);
2194 *buffer++=(unsigned char) c;
2198 *buffer++=(unsigned char) c;
2204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2208 + M S B O r d e r S h o r t %
2212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2214 % MSBOrderShort() converts a least-significant byte first buffer of integers
2215 % to most-significant byte first.
2217 % The format of the MSBOrderShort method is:
2219 % void MSBOrderShort(unsigned char *p,const size_t length)
2221 % A description of each parameter follows.
2223 % o p: Specifies a pointer to a buffer of integers.
2225 % o length: Specifies the length of the buffer.
2228 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2233 register unsigned char
2236 assert(p != (unsigned char *) NULL);
2243 *p++=(unsigned char) c;
2248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2258 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2259 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2260 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2261 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2262 % from a system command.
2264 % The format of the OpenBlob method is:
2266 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2267 % const BlobMode mode,ExceptionInfo *exception)
2269 % A description of each parameter follows:
2271 % o image_info: the image info.
2273 % o image: the image.
2275 % o mode: the mode for opening the file.
2278 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2279 Image *image,const BlobMode mode,ExceptionInfo *exception)
2282 extension[MaxTextExtent],
2283 filename[MaxTextExtent];
2294 assert(image_info != (ImageInfo *) NULL);
2295 assert(image_info->signature == MagickSignature);
2296 if (image_info->debug != MagickFalse)
2297 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2298 image_info->filename);
2299 assert(image != (Image *) NULL);
2300 assert(image->signature == MagickSignature);
2301 if (image_info->blob != (void *) NULL)
2303 if (image_info->stream != (StreamHandler) NULL)
2304 image->blob->stream=(StreamHandler) image_info->stream;
2305 AttachBlob(image->blob,image_info->blob,image_info->length);
2308 (void) DetachBlob(image->blob);
2311 default: type="r"; break;
2312 case ReadBlobMode: type="r"; break;
2313 case ReadBinaryBlobMode: type="rb"; break;
2314 case WriteBlobMode: type="w"; break;
2315 case WriteBinaryBlobMode: type="w+b"; break;
2316 case AppendBlobMode: type="a"; break;
2317 case AppendBinaryBlobMode: type="a+b"; break;
2320 image->blob->synchronize=image_info->synchronize;
2321 if (image_info->stream != (StreamHandler) NULL)
2323 image->blob->stream=(StreamHandler) image_info->stream;
2326 image->blob->type=FifoStream;
2334 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2335 rights=ReadPolicyRights;
2337 rights=WritePolicyRights;
2338 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2341 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2342 "NotAuthorized","`%s'",filename);
2343 return(MagickFalse);
2345 if ((LocaleCompare(filename,"-") == 0) ||
2346 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2348 image->blob->file=(*type == 'r') ? stdin : stdout;
2349 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2350 if (strchr(type,'b') != (char *) NULL)
2351 setmode(_fileno(image->blob->file),_O_BINARY);
2353 image->blob->type=StandardStream;
2354 image->blob->exempt=MagickTrue;
2357 if (LocaleNCompare(filename,"fd:",3) == 0)
2360 mode[MaxTextExtent];
2364 image->blob->file=fdopen(StringToLong(filename+3),mode);
2365 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2366 if (strchr(type,'b') != (char *) NULL)
2367 setmode(_fileno(image->blob->file),_O_BINARY);
2369 image->blob->type=StandardStream;
2370 image->blob->exempt=MagickTrue;
2373 #if defined(MAGICKCORE_HAVE_POPEN)
2374 if (*filename == '|')
2377 mode[MaxTextExtent];
2380 Pipe image to or from a system command.
2382 #if defined(SIGPIPE)
2384 (void) signal(SIGPIPE,SIG_IGN);
2388 image->blob->file=(FILE *) popen_utf8(filename+1,mode);
2389 if (image->blob->file == (FILE *) NULL)
2391 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2392 return(MagickFalse);
2394 image->blob->type=PipeStream;
2395 image->blob->exempt=MagickTrue;
2399 status=GetPathAttributes(filename,&image->blob->properties);
2400 #if defined(S_ISFIFO)
2401 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2403 image->blob->file=(FILE *) fopen_utf8(filename,type);
2404 if (image->blob->file == (FILE *) NULL)
2406 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2407 return(MagickFalse);
2409 image->blob->type=FileStream;
2410 image->blob->exempt=MagickTrue;
2414 GetPathComponent(image->filename,ExtensionPath,extension);
2417 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2418 if ((image_info->adjoin == MagickFalse) ||
2419 (strchr(filename,'%') != (char *) NULL))
2422 Form filename for multi-part images.
2424 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2425 image->scene,filename,exception);
2426 if ((LocaleCompare(filename,image->filename) == 0) &&
2427 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2428 (GetNextImageInList(image) != (Image *) NULL)))
2431 path[MaxTextExtent];
2433 GetPathComponent(image->filename,RootPath,path);
2434 if (*extension == '\0')
2435 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2436 path,(double) image->scene);
2438 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2439 path,(double) image->scene,extension);
2441 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2442 #if defined(macintosh)
2443 SetApplicationType(filename,image_info->magick,'8BIM');
2447 if (image_info->file != (FILE *) NULL)
2449 image->blob->file=image_info->file;
2450 image->blob->type=FileStream;
2451 image->blob->exempt=MagickTrue;
2456 image->blob->file=(FILE *) fopen_utf8(filename,type);
2457 if (image->blob->file != (FILE *) NULL)
2465 image->blob->type=FileStream;
2466 #if defined(MAGICKCORE_HAVE_SETVBUF)
2467 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2469 (void) ResetMagickMemory(magick,0,sizeof(magick));
2470 count=fread(magick,1,sizeof(magick),image->blob->file);
2471 (void) rewind(image->blob->file);
2472 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2473 " read %.20g magic header bytes",(double) count);
2474 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2475 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2476 ((int) magick[2] == 0x08))
2478 (void) fclose(image->blob->file);
2479 image->blob->file=(FILE *) gzopen(filename,type);
2480 if (image->blob->file != (FILE *) NULL)
2481 image->blob->type=ZipStream;
2484 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2485 if (strncmp((char *) magick,"BZh",3) == 0)
2487 (void) fclose(image->blob->file);
2488 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2489 if (image->blob->file != (FILE *) NULL)
2490 image->blob->type=BZipStream;
2493 if (image->blob->type == FileStream)
2504 sans_exception=AcquireExceptionInfo();
2505 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2506 sans_exception=DestroyExceptionInfo(sans_exception);
2507 properties=(&image->blob->properties);
2508 if ((magick_info != (const MagickInfo *) NULL) &&
2509 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2510 (properties->st_size <= MagickMaxBufferExtent))
2518 length=(size_t) properties->st_size;
2519 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2520 if (blob != (void *) NULL)
2523 Format supports blobs-- use memory-mapped I/O.
2525 if (image_info->file != (FILE *) NULL)
2526 image->blob->exempt=MagickFalse;
2529 (void) fclose(image->blob->file);
2530 image->blob->file=(FILE *) NULL;
2532 AttachBlob(image->blob,blob,length);
2533 image->blob->mapped=MagickTrue;
2540 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2541 if ((LocaleCompare(extension,"Z") == 0) ||
2542 (LocaleCompare(extension,"gz") == 0) ||
2543 (LocaleCompare(extension,"wmz") == 0) ||
2544 (LocaleCompare(extension,"svgz") == 0))
2546 if (mode == WriteBinaryBlobMode)
2548 image->blob->file=(FILE *) gzopen(filename,type);
2549 if (image->blob->file != (FILE *) NULL)
2550 image->blob->type=ZipStream;
2554 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2555 if (LocaleCompare(extension,".bz2") == 0)
2557 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2558 if (image->blob->file != (FILE *) NULL)
2559 image->blob->type=BZipStream;
2564 image->blob->file=(FILE *) fopen_utf8(filename,type);
2565 if (image->blob->file != (FILE *) NULL)
2567 image->blob->type=FileStream;
2568 #if defined(MAGICKCORE_HAVE_SETVBUF)
2569 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2574 image->blob->status=MagickFalse;
2575 if (image->blob->type != UndefinedStream)
2576 image->blob->size=GetBlobSize(image);
2579 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2580 return(MagickFalse);
2586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2596 % PingBlob() returns all the attributes of an image or image sequence except
2597 % for the pixels. It is much faster and consumes far less memory than
2598 % BlobToImage(). On failure, a NULL image is returned and exception
2599 % describes the reason for the failure.
2601 % The format of the PingBlob method is:
2603 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2604 % const size_t length,ExceptionInfo *exception)
2606 % A description of each parameter follows:
2608 % o image_info: the image info.
2610 % o blob: the address of a character stream in one of the image formats
2611 % understood by ImageMagick.
2613 % o length: This size_t integer reflects the length in bytes of the blob.
2615 % o exception: return any errors or warnings in this structure.
2619 #if defined(__cplusplus) || defined(c_plusplus)
2623 static size_t PingStream(const Image *magick_unused(image),
2624 const void *magick_unused(pixels),const size_t columns)
2629 #if defined(__cplusplus) || defined(c_plusplus)
2633 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2634 const size_t length,ExceptionInfo *exception)
2642 assert(image_info != (ImageInfo *) NULL);
2643 assert(image_info->signature == MagickSignature);
2644 if (image_info->debug != MagickFalse)
2645 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2646 image_info->filename);
2647 assert(exception != (ExceptionInfo *) NULL);
2648 if ((blob == (const void *) NULL) || (length == 0))
2650 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2651 "UnrecognizedImageFormat","`%s'",image_info->magick);
2652 return((Image *) NULL);
2654 ping_info=CloneImageInfo(image_info);
2655 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2656 if (ping_info->blob == (const void *) NULL)
2658 (void) ThrowMagickException(exception,GetMagickModule(),
2659 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2660 return((Image *) NULL);
2662 (void) memcpy(ping_info->blob,blob,length);
2663 ping_info->length=length;
2664 ping_info->ping=MagickTrue;
2665 image=ReadStream(ping_info,&PingStream,exception);
2666 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2667 ping_info=DestroyImageInfo(ping_info);
2672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2682 % ReadBlob() reads data from the blob or image file and returns it. It
2683 % returns the number of bytes read.
2685 % The format of the ReadBlob method is:
2687 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2689 % A description of each parameter follows:
2691 % o image: the image.
2693 % o length: Specifies an integer representing the number of bytes to read
2696 % o data: Specifies an area to place the information requested from the
2700 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2701 unsigned char *data)
2706 register unsigned char
2712 assert(image != (Image *) NULL);
2713 assert(image->signature == MagickSignature);
2714 assert(image->blob != (BlobInfo *) NULL);
2715 assert(image->blob->type != UndefinedStream);
2718 assert(data != (void *) NULL);
2721 switch (image->blob->type)
2723 case UndefinedStream:
2726 case StandardStream:
2733 count=(ssize_t) fread(q,1,length,image->blob->file);
2738 c=getc(image->blob->file);
2741 *q++=(unsigned char) c;
2746 c=getc(image->blob->file);
2749 *q++=(unsigned char) c;
2759 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2764 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2769 c=gzgetc(image->blob->file);
2772 *q++=(unsigned char) c;
2777 c=gzgetc(image->blob->file);
2780 *q++=(unsigned char) c;
2791 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2792 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2800 register const unsigned char
2803 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2805 image->blob->eof=MagickTrue;
2808 p=image->blob->data+image->blob->offset;
2809 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2810 image->blob->offset+=count;
2811 if (count != (ssize_t) length)
2812 image->blob->eof=MagickTrue;
2813 (void) memcpy(q,p,(size_t) count);
2821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2825 + R e a d B l o b B y t e %
2829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2831 % ReadBlobByte() reads a single byte from the image file and returns it.
2833 % The format of the ReadBlobByte method is:
2835 % int ReadBlobByte(Image *image)
2837 % A description of each parameter follows.
2839 % o image: the image.
2842 MagickExport int ReadBlobByte(Image *image)
2844 register const unsigned char
2853 assert(image != (Image *) NULL);
2854 assert(image->signature == MagickSignature);
2855 p=ReadBlobStream(image,1,buffer,&count);
2862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2866 + R e a d B l o b D o u b l e %
2870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2872 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2873 % specified by the endian member of the image structure.
2875 % The format of the ReadBlobDouble method is:
2877 % double ReadBlobDouble(Image *image)
2879 % A description of each parameter follows.
2881 % o image: the image.
2884 MagickExport double ReadBlobDouble(Image *image)
2895 quantum.double_value=0.0;
2896 quantum.unsigned_value=ReadBlobLongLong(image);
2897 return(quantum.double_value);
2901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2905 + R e a d B l o b F l o a t %
2909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2911 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2912 % specified by the endian member of the image structure.
2914 % The format of the ReadBlobFloat method is:
2916 % float ReadBlobFloat(Image *image)
2918 % A description of each parameter follows.
2920 % o image: the image.
2923 MagickExport float ReadBlobFloat(Image *image)
2934 quantum.float_value=0.0;
2935 quantum.unsigned_value=ReadBlobLong(image);
2936 return(quantum.float_value);
2940 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2944 + R e a d B l o b L o n g %
2948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2950 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2951 % specified by the endian member of the image structure.
2953 % The format of the ReadBlobLong method is:
2955 % unsigned int ReadBlobLong(Image *image)
2957 % A description of each parameter follows.
2959 % o image: the image.
2962 MagickExport unsigned int ReadBlobLong(Image *image)
2964 register const unsigned char
2976 assert(image != (Image *) NULL);
2977 assert(image->signature == MagickSignature);
2979 p=ReadBlobStream(image,4,buffer,&count);
2982 if (image->endian == LSBEndian)
2984 value=(unsigned int) (*p++);
2985 value|=((unsigned int) (*p++)) << 8;
2986 value|=((unsigned int) (*p++)) << 16;
2987 value|=((unsigned int) (*p++)) << 24;
2990 value=((unsigned int) (*p++)) << 24;
2991 value|=((unsigned int) (*p++)) << 16;
2992 value|=((unsigned int) (*p++)) << 8;
2993 value|=((unsigned int) (*p++));
2998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3002 + R e a d B l o b L o n g L o n g %
3006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3008 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3009 % byte-order specified by the endian member of the image structure.
3011 % The format of the ReadBlobLongLong method is:
3013 % MagickSizeType ReadBlobLongLong(Image *image)
3015 % A description of each parameter follows.
3017 % o image: the image.
3020 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3025 register const unsigned char
3034 assert(image != (Image *) NULL);
3035 assert(image->signature == MagickSignature);
3037 p=ReadBlobStream(image,8,buffer,&count);
3039 return(MagickULLConstant(0));
3040 if (image->endian == LSBEndian)
3042 value=(MagickSizeType) (*p++);
3043 value|=((MagickSizeType) (*p++)) << 8;
3044 value|=((MagickSizeType) (*p++)) << 16;
3045 value|=((MagickSizeType) (*p++)) << 24;
3046 value|=((MagickSizeType) (*p++)) << 32;
3047 value|=((MagickSizeType) (*p++)) << 40;
3048 value|=((MagickSizeType) (*p++)) << 48;
3049 value|=((MagickSizeType) (*p++)) << 56;
3050 return(value & MagickULLConstant(0xffffffffffffffff));
3052 value=((MagickSizeType) (*p++)) << 56;
3053 value|=((MagickSizeType) (*p++)) << 48;
3054 value|=((MagickSizeType) (*p++)) << 40;
3055 value|=((MagickSizeType) (*p++)) << 32;
3056 value|=((MagickSizeType) (*p++)) << 24;
3057 value|=((MagickSizeType) (*p++)) << 16;
3058 value|=((MagickSizeType) (*p++)) << 8;
3059 value|=((MagickSizeType) (*p++));
3060 return(value & MagickULLConstant(0xffffffffffffffff));
3064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3068 + R e a d B l o b S h o r t %
3072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3074 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3075 % specified by the endian member of the image structure.
3077 % The format of the ReadBlobShort method is:
3079 % unsigned short ReadBlobShort(Image *image)
3081 % A description of each parameter follows.
3083 % o image: the image.
3086 MagickExport unsigned short ReadBlobShort(Image *image)
3088 register const unsigned char
3091 register unsigned int
3100 assert(image != (Image *) NULL);
3101 assert(image->signature == MagickSignature);
3103 p=ReadBlobStream(image,2,buffer,&count);
3105 return((unsigned short) 0U);
3106 if (image->endian == LSBEndian)
3108 value=(unsigned int) (*p++);
3109 value|=((unsigned int) (*p++)) << 8;
3110 return((unsigned short) (value & 0xffff));
3112 value=(unsigned int) ((*p++) << 8);
3113 value|=(unsigned int) (*p++);
3114 return((unsigned short) (value & 0xffff));
3118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3122 + R e a d B l o b L S B L o n g %
3126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3128 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3129 % least-significant byte first order.
3131 % The format of the ReadBlobLSBLong method is:
3133 % unsigned int ReadBlobLSBLong(Image *image)
3135 % A description of each parameter follows.
3137 % o image: the image.
3140 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3142 register const unsigned char
3145 register unsigned int
3154 assert(image != (Image *) NULL);
3155 assert(image->signature == MagickSignature);
3157 p=ReadBlobStream(image,4,buffer,&count);
3160 value=(unsigned int) (*p++);
3161 value|=((unsigned int) (*p++)) << 8;
3162 value|=((unsigned int) (*p++)) << 16;
3163 value|=((unsigned int) (*p++)) << 24;
3168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3172 + R e a d B l o b L S B S h o r t %
3176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3178 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3179 % least-significant byte first order.
3181 % The format of the ReadBlobLSBShort method is:
3183 % unsigned short ReadBlobLSBShort(Image *image)
3185 % A description of each parameter follows.
3187 % o image: the image.
3190 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3192 register const unsigned char
3195 register unsigned int
3204 assert(image != (Image *) NULL);
3205 assert(image->signature == MagickSignature);
3207 p=ReadBlobStream(image,2,buffer,&count);
3209 return((unsigned short) 0U);
3210 value=(unsigned int) (*p++);
3211 value|=((unsigned int) ((*p++)) << 8);
3212 return((unsigned short) (value & 0xffff));
3216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3220 + R e a d B l o b M S B L o n g %
3224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3226 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3227 % most-significant byte first order.
3229 % The format of the ReadBlobMSBLong method is:
3231 % unsigned int ReadBlobMSBLong(Image *image)
3233 % A description of each parameter follows.
3235 % o image: the image.
3238 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3240 register const unsigned char
3243 register unsigned int
3252 assert(image != (Image *) NULL);
3253 assert(image->signature == MagickSignature);
3255 p=ReadBlobStream(image,4,buffer,&count);
3258 value=((unsigned int) (*p++) << 24);
3259 value|=((unsigned int) (*p++) << 16);
3260 value|=((unsigned int) (*p++) << 8);
3261 value|=(unsigned int) (*p++);
3266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3270 + R e a d B l o b M S B L o n g L o n g %
3274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3276 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3277 % most-significant byte first order.
3279 % The format of the ReadBlobMSBLongLong method is:
3281 % unsigned int ReadBlobMSBLongLong(Image *image)
3283 % A description of each parameter follows.
3285 % o image: the image.
3288 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3290 register const unsigned char
3293 register MagickSizeType
3302 assert(image != (Image *) NULL);
3303 assert(image->signature == MagickSignature);
3305 p=ReadBlobStream(image,8,buffer,&count);
3307 return(MagickULLConstant(0));
3308 value=((MagickSizeType) (*p++)) << 56;
3309 value|=((MagickSizeType) (*p++)) << 48;
3310 value|=((MagickSizeType) (*p++)) << 40;
3311 value|=((MagickSizeType) (*p++)) << 32;
3312 value|=((MagickSizeType) (*p++)) << 24;
3313 value|=((MagickSizeType) (*p++)) << 16;
3314 value|=((MagickSizeType) (*p++)) << 8;
3315 value|=((MagickSizeType) (*p++));
3316 return(value & MagickULLConstant(0xffffffffffffffff));
3320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3324 + R e a d B l o b M S B S h o r t %
3328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3330 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3331 % most-significant byte first order.
3333 % The format of the ReadBlobMSBShort method is:
3335 % unsigned short ReadBlobMSBShort(Image *image)
3337 % A description of each parameter follows.
3339 % o image: the image.
3342 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3344 register const unsigned char
3347 register unsigned int
3356 assert(image != (Image *) NULL);
3357 assert(image->signature == MagickSignature);
3359 p=ReadBlobStream(image,2,buffer,&count);
3361 return((unsigned short) 0U);
3362 value=(unsigned int) ((*p++) << 8);
3363 value|=(unsigned int) (*p++);
3364 return((unsigned short) (value & 0xffff));
3368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3372 + R e a d B l o b S t r i n g %
3376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3378 % ReadBlobString() reads characters from a blob or file until a newline
3379 % character is read or an end-of-file condition is encountered.
3381 % The format of the ReadBlobString method is:
3383 % char *ReadBlobString(Image *image,char *string)
3385 % A description of each parameter follows:
3387 % o image: the image.
3389 % o string: the address of a character buffer.
3392 MagickExport char *ReadBlobString(Image *image,char *string)
3394 register const unsigned char
3406 assert(image != (Image *) NULL);
3407 assert(image->signature == MagickSignature);
3408 for (i=0; i < (MaxTextExtent-1L); i++)
3410 p=ReadBlobStream(image,1,buffer,&count);
3414 return((char *) NULL);
3417 string[i]=(char) (*p);
3418 if ((string[i] == '\r') || (string[i] == '\n'))
3421 if (string[i] == '\r')
3422 (void) ReadBlobStream(image,1,buffer,&count);
3428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3432 + R e f e r e n c e B l o b %
3436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3438 % ReferenceBlob() increments the reference count associated with the pixel
3439 % blob returning a pointer to the blob.
3441 % The format of the ReferenceBlob method is:
3443 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3445 % A description of each parameter follows:
3447 % o blob_info: the blob_info.
3450 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3452 assert(blob != (BlobInfo *) NULL);
3453 assert(blob->signature == MagickSignature);
3454 if (blob->debug != MagickFalse)
3455 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3456 LockSemaphoreInfo(blob->semaphore);
3457 blob->reference_count++;
3458 UnlockSemaphoreInfo(blob->semaphore);
3463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3473 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3474 % and returns the resulting offset.
3476 % The format of the SeekBlob method is:
3478 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3481 % A description of each parameter follows:
3483 % o image: the image.
3485 % o offset: Specifies an integer representing the offset in bytes.
3487 % o whence: Specifies an integer representing how the offset is
3488 % treated relative to the beginning of the blob as follows:
3490 % SEEK_SET Set position equal to offset bytes.
3491 % SEEK_CUR Set position to current location plus offset.
3492 % SEEK_END Set position to EOF plus offset.
3495 MagickExport MagickOffsetType SeekBlob(Image *image,
3496 const MagickOffsetType offset,const int whence)
3498 assert(image != (Image *) NULL);
3499 assert(image->signature == MagickSignature);
3500 if (image->debug != MagickFalse)
3501 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3502 assert(image->blob != (BlobInfo *) NULL);
3503 assert(image->blob->type != UndefinedStream);
3504 switch (image->blob->type)
3506 case UndefinedStream:
3510 if (fseek(image->blob->file,offset,whence) < 0)
3512 image->blob->offset=TellBlob(image);
3515 case StandardStream:
3519 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3520 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3523 image->blob->offset=TellBlob(image);
3539 image->blob->offset=offset;
3544 if ((image->blob->offset+offset) < 0)
3546 image->blob->offset+=offset;
3551 if (((MagickOffsetType) image->blob->length+offset) < 0)
3553 image->blob->offset=image->blob->length+offset;
3557 if (image->blob->offset <= (MagickOffsetType)
3558 ((off_t) image->blob->length))
3559 image->blob->eof=MagickFalse;
3561 if (image->blob->mapped != MagickFalse)
3565 image->blob->extent=(size_t) (image->blob->offset+
3566 image->blob->quantum);
3567 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3568 image->blob->data,image->blob->extent+1,
3569 sizeof(*image->blob->data));
3570 (void) SyncBlob(image);
3571 if (image->blob->data == (unsigned char *) NULL)
3573 (void) DetachBlob(image->blob);
3580 return(image->blob->offset);
3584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3588 + S e t B l o b E x e m p t %
3592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3594 % SetBlobExempt() sets the blob exempt status.
3596 % The format of the SetBlobExempt method is:
3598 % MagickBooleanType SetBlobExempt(const Image *image,
3599 % const MagickBooleanType exempt)
3601 % A description of each parameter follows:
3603 % o image: the image.
3605 % o exempt: Set to true if this blob is exempt from being closed.
3608 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3610 assert(image != (const Image *) NULL);
3611 assert(image->signature == MagickSignature);
3612 if (image->debug != MagickFalse)
3613 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3614 image->blob->exempt=exempt;
3618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3622 + S e t B l o b E x t e n t %
3626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3628 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3629 % method is successful, subsequent writes to bytes in the specified range are
3630 % guaranteed not to fail.
3632 % The format of the SetBlobExtent method is:
3634 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3636 % A description of each parameter follows:
3638 % o image: the image.
3640 % o extent: the blob maximum extent.
3643 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3644 const MagickSizeType extent)
3646 assert(image != (Image *) NULL);
3647 assert(image->signature == MagickSignature);
3648 if (image->debug != MagickFalse)
3649 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3650 assert(image->blob != (BlobInfo *) NULL);
3651 assert(image->blob->type != UndefinedStream);
3652 switch (image->blob->type)
3654 case UndefinedStream:
3658 if (extent != (MagickSizeType) ((off_t) extent))
3659 return(MagickFalse);
3660 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3661 return(MagickFalse);
3670 offset=TellBlob(image);
3671 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3672 (off_t) (extent-offset));
3674 return(MagickFalse);
3679 case StandardStream:
3682 return(MagickFalse);
3684 return(MagickFalse);
3686 return(MagickFalse);
3689 if (image->blob->mapped != MagickFalse)
3691 if (image->blob->file == (FILE *) NULL)
3692 return(MagickFalse);
3693 (void) UnmapBlob(image->blob->data,image->blob->length);
3694 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3695 return(MagickFalse);
3704 offset=TellBlob(image);
3705 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3706 (off_t) (extent-offset));
3708 return(MagickFalse);
3710 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3711 WriteMode,0,(size_t) extent);
3712 image->blob->extent=(size_t) extent;
3713 image->blob->length=(size_t) extent;
3714 (void) SyncBlob(image);
3718 if (extent != (MagickSizeType) ((size_t) extent))
3719 return(MagickFalse);
3720 image->blob->extent=(size_t) extent;
3721 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3722 image->blob->extent+1,sizeof(*image->blob->data));
3723 (void) SyncBlob(image);
3724 if (image->blob->data == (unsigned char *) NULL)
3726 (void) DetachBlob(image->blob);
3727 return(MagickFalse);
3736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3746 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3747 % attributes if it is an blob.
3749 % The format of the SyncBlob method is:
3751 % int SyncBlob(Image *image)
3753 % A description of each parameter follows:
3755 % o image: the image.
3758 static int SyncBlob(Image *image)
3763 assert(image != (Image *) NULL);
3764 assert(image->signature == MagickSignature);
3765 if (image->debug != MagickFalse)
3766 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3767 assert(image->blob != (BlobInfo *) NULL);
3768 assert(image->blob->type != UndefinedStream);
3770 switch (image->blob->type)
3772 case UndefinedStream:
3775 case StandardStream:
3778 status=fflush(image->blob->file);
3783 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3784 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3790 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3791 status=BZ2_bzflush((BZFILE *) image->blob->file);
3799 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3800 if (image->blob->mapped != MagickFalse)
3801 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3810 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3820 % TellBlob() obtains the current value of the blob or file position.
3822 % The format of the TellBlob method is:
3824 % MagickOffsetType TellBlob(const Image *image)
3826 % A description of each parameter follows:
3828 % o image: the image.
3831 MagickExport MagickOffsetType TellBlob(const Image *image)
3836 assert(image != (Image *) NULL);
3837 assert(image->signature == MagickSignature);
3838 if (image->debug != MagickFalse)
3839 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3840 assert(image->blob != (BlobInfo *) NULL);
3841 assert(image->blob->type != UndefinedStream);
3843 switch (image->blob->type)
3845 case UndefinedStream:
3849 offset=ftell(image->blob->file);
3852 case StandardStream:
3857 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3858 offset=(MagickOffsetType) gztell(image->blob->file);
3868 offset=image->blob->offset;
3876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3880 + U n m a p B l o b %
3884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3886 % UnmapBlob() deallocates the binary large object previously allocated with
3887 % the MapBlob method.
3889 % The format of the UnmapBlob method is:
3891 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3893 % A description of each parameter follows:
3895 % o map: the address of the binary large object.
3897 % o length: the length of the binary large object.
3900 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3902 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3906 status=munmap(map,length);
3907 return(status == -1 ? MagickFalse : MagickTrue);
3911 return(MagickFalse);
3916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3920 + W r i t e B l o b %
3924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3926 % WriteBlob() writes data to a blob or image file. It returns the number of
3929 % The format of the WriteBlob method is:
3931 % ssize_t WriteBlob(Image *image,const size_t length,
3932 % const unsigned char *data)
3934 % A description of each parameter follows:
3936 % o image: the image.
3938 % o length: Specifies an integer representing the number of bytes to
3939 % write to the file.
3941 % o data: The address of the data to write to the blob or file.
3944 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3945 const unsigned char *data)
3950 register const unsigned char
3956 assert(image != (Image *) NULL);
3957 assert(image->signature == MagickSignature);
3958 assert(data != (const unsigned char *) NULL);
3959 assert(image->blob != (BlobInfo *) NULL);
3960 assert(image->blob->type != UndefinedStream);
3965 switch (image->blob->type)
3967 case UndefinedStream:
3970 case StandardStream:
3977 count=(ssize_t) fwrite((const char *) data,1,length,
3983 c=putc((int) *p++,image->blob->file);
3990 c=putc((int) *p++,image->blob->file);
4002 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4007 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4008 (unsigned int) length);
4013 c=gzputc(image->blob->file,(int) *p++);
4020 c=gzputc(image->blob->file,(int) *p++);
4033 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4034 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4041 count=(ssize_t) image->blob->stream(image,data,length);
4046 register unsigned char
4049 if ((image->blob->offset+(MagickOffsetType) length) >=
4050 (MagickOffsetType) image->blob->extent)
4052 if (image->blob->mapped != MagickFalse)
4054 image->blob->quantum<<=1;
4055 image->blob->extent+=length+image->blob->quantum;
4056 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4057 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4058 (void) SyncBlob(image);
4059 if (image->blob->data == (unsigned char *) NULL)
4061 (void) DetachBlob(image->blob);
4065 q=image->blob->data+image->blob->offset;
4066 (void) memcpy(q,p,length);
4067 image->blob->offset+=length;
4068 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4069 image->blob->length=(size_t) image->blob->offset;
4070 count=(ssize_t) length;
4077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4081 + W r i t e B l o b B y t e %
4085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4087 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4088 % written (either 0 or 1);
4090 % The format of the WriteBlobByte method is:
4092 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4094 % A description of each parameter follows.
4096 % o image: the image.
4098 % o value: Specifies the value to write.
4101 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4103 assert(image != (Image *) NULL);
4104 assert(image->signature == MagickSignature);
4105 return(WriteBlobStream(image,1,&value));
4109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4113 + W r i t e B l o b F l o a t %
4117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4119 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4120 % specified by the endian member of the image structure.
4122 % The format of the WriteBlobFloat method is:
4124 % ssize_t WriteBlobFloat(Image *image,const float value)
4126 % A description of each parameter follows.
4128 % o image: the image.
4130 % o value: Specifies the value to write.
4133 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4144 quantum.unsigned_value=0U;
4145 quantum.float_value=value;
4146 return(WriteBlobLong(image,quantum.unsigned_value));
4150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4154 + W r i t e B l o b L o n g %
4158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4160 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4161 % specified by the endian member of the image structure.
4163 % The format of the WriteBlobLong method is:
4165 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4167 % A description of each parameter follows.
4169 % o image: the image.
4171 % o value: Specifies the value to write.
4174 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4179 assert(image != (Image *) NULL);
4180 assert(image->signature == MagickSignature);
4181 if (image->endian == LSBEndian)
4183 buffer[0]=(unsigned char) value;
4184 buffer[1]=(unsigned char) (value >> 8);
4185 buffer[2]=(unsigned char) (value >> 16);
4186 buffer[3]=(unsigned char) (value >> 24);
4187 return(WriteBlobStream(image,4,buffer));
4189 buffer[0]=(unsigned char) (value >> 24);
4190 buffer[1]=(unsigned char) (value >> 16);
4191 buffer[2]=(unsigned char) (value >> 8);
4192 buffer[3]=(unsigned char) value;
4193 return(WriteBlobStream(image,4,buffer));
4197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4201 + W r i t e B l o b S h o r t %
4205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4207 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4208 % byte-order specified by the endian member of the image structure.
4210 % The format of the WriteBlobShort method is:
4212 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4214 % A description of each parameter follows.
4216 % o image: the image.
4218 % o value: Specifies the value to write.
4221 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4226 assert(image != (Image *) NULL);
4227 assert(image->signature == MagickSignature);
4228 if (image->endian == LSBEndian)
4230 buffer[0]=(unsigned char) value;
4231 buffer[1]=(unsigned char) (value >> 8);
4232 return(WriteBlobStream(image,2,buffer));
4234 buffer[0]=(unsigned char) (value >> 8);
4235 buffer[1]=(unsigned char) value;
4236 return(WriteBlobStream(image,2,buffer));
4240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4244 + W r i t e B l o b L S B L o n g %
4248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4250 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4251 % least-significant byte first order.
4253 % The format of the WriteBlobLSBLong method is:
4255 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4257 % A description of each parameter follows.
4259 % o image: the image.
4261 % o value: Specifies the value to write.
4264 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4269 assert(image != (Image *) NULL);
4270 assert(image->signature == MagickSignature);
4271 buffer[0]=(unsigned char) value;
4272 buffer[1]=(unsigned char) (value >> 8);
4273 buffer[2]=(unsigned char) (value >> 16);
4274 buffer[3]=(unsigned char) (value >> 24);
4275 return(WriteBlobStream(image,4,buffer));
4279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4283 + W r i t e B l o b L S B S h o r t %
4287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4289 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4290 % least-significant byte first order.
4292 % The format of the WriteBlobLSBShort method is:
4294 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4296 % A description of each parameter follows.
4298 % o image: the image.
4300 % o value: Specifies the value to write.
4303 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4308 assert(image != (Image *) NULL);
4309 assert(image->signature == MagickSignature);
4310 buffer[0]=(unsigned char) value;
4311 buffer[1]=(unsigned char) (value >> 8);
4312 return(WriteBlobStream(image,2,buffer));
4316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4320 + W r i t e B l o b M S B L o n g %
4324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4326 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4327 % most-significant byte first order.
4329 % The format of the WriteBlobMSBLong method is:
4331 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4333 % A description of each parameter follows.
4335 % o value: Specifies the value to write.
4337 % o image: the image.
4340 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4345 assert(image != (Image *) NULL);
4346 assert(image->signature == MagickSignature);
4347 buffer[0]=(unsigned char) (value >> 24);
4348 buffer[1]=(unsigned char) (value >> 16);
4349 buffer[2]=(unsigned char) (value >> 8);
4350 buffer[3]=(unsigned char) value;
4351 return(WriteBlobStream(image,4,buffer));
4355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4359 + W r i t e B l o b M S B L o n g L o n g %
4363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4365 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4366 % most-significant byte first order.
4368 % The format of the WriteBlobMSBLongLong method is:
4370 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4372 % A description of each parameter follows.
4374 % o value: Specifies the value to write.
4376 % o image: the image.
4379 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4380 const MagickSizeType value)
4385 assert(image != (Image *) NULL);
4386 assert(image->signature == MagickSignature);
4387 buffer[0]=(unsigned char) (value >> 56);
4388 buffer[1]=(unsigned char) (value >> 48);
4389 buffer[2]=(unsigned char) (value >> 40);
4390 buffer[3]=(unsigned char) (value >> 32);
4391 buffer[4]=(unsigned char) (value >> 24);
4392 buffer[5]=(unsigned char) (value >> 16);
4393 buffer[6]=(unsigned char) (value >> 8);
4394 buffer[7]=(unsigned char) value;
4395 return(WriteBlobStream(image,8,buffer));
4399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4403 + W r i t e B l o b M S B S h o r t %
4407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4409 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4410 % most-significant byte first order.
4412 % The format of the WriteBlobMSBShort method is:
4414 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4416 % A description of each parameter follows.
4418 % o value: Specifies the value to write.
4420 % o file: Specifies the file to write the data to.
4423 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4428 assert(image != (Image *) NULL);
4429 assert(image->signature == MagickSignature);
4430 buffer[0]=(unsigned char) (value >> 8);
4431 buffer[1]=(unsigned char) value;
4432 return(WriteBlobStream(image,2,buffer));
4436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4440 + W r i t e B l o b S t r i n g %
4444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4446 % WriteBlobString() write a string to a blob. It returns the number of
4447 % characters written.
4449 % The format of the WriteBlobString method is:
4451 % ssize_t WriteBlobString(Image *image,const char *string)
4453 % A description of each parameter follows.
4455 % o image: the image.
4457 % o string: Specifies the string to write.
4460 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4462 assert(image != (Image *) NULL);
4463 assert(image->signature == MagickSignature);
4464 assert(string != (const char *) NULL);
4465 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));