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)
1109 assert(image != (const Image *) NULL);
1110 assert(image->signature == MagickSignature);
1111 assert(filename != (const char *) NULL);
1112 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1113 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1116 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
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(&image->exception,ResourceLimitError,
1127 "MemoryAllocationFailed",filename);
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(&image->exception,BlobError,"UnableToWriteBlob",
1150 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1152 blob=(unsigned char *) RelinquishMagickMemory(blob);
1157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1161 + G e t B l o b E r r o r %
1165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1167 % GetBlobError() returns MagickTrue if the blob associated with the specified
1168 % image encountered an error.
1170 % The format of the GetBlobError method is:
1172 % MagickBooleanType GetBlobError(const Image *image)
1174 % A description of each parameter follows:
1176 % o image: the image.
1179 MagickPrivate MagickBooleanType GetBlobError(const Image *image)
1181 assert(image != (const Image *) NULL);
1182 assert(image->signature == MagickSignature);
1183 if (image->debug != MagickFalse)
1184 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1185 return(image->blob->status);
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 + G e t B l o b F i l e H a n d l e %
1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1199 % GetBlobFileHandle() returns the file handle associated with the image blob.
1201 % The format of the GetBlobFile method is:
1203 % FILE *GetBlobFileHandle(const Image *image)
1205 % A description of each parameter follows:
1207 % o image: the image.
1210 MagickExport FILE *GetBlobFileHandle(const Image *image)
1212 assert(image != (const Image *) NULL);
1213 assert(image->signature == MagickSignature);
1214 return(image->blob->file);
1218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1222 + G e t B l o b I n f o %
1226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228 % GetBlobInfo() initializes the BlobInfo structure.
1230 % The format of the GetBlobInfo method is:
1232 % void GetBlobInfo(BlobInfo *blob_info)
1234 % A description of each parameter follows:
1236 % o blob_info: Specifies a pointer to a BlobInfo structure.
1239 MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
1241 assert(blob_info != (BlobInfo *) NULL);
1242 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1243 blob_info->type=UndefinedStream;
1244 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1245 blob_info->properties.st_mtime=time((time_t *) NULL);
1246 blob_info->properties.st_ctime=time((time_t *) NULL);
1247 blob_info->debug=IsEventLogging();
1248 blob_info->reference_count=1;
1249 blob_info->semaphore=AllocateSemaphoreInfo();
1250 blob_info->signature=MagickSignature;
1254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1258 % G e t B l o b P r o p e r t i e s %
1262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264 % GetBlobProperties() returns information about an image blob.
1266 % The format of the GetBlobProperties method is:
1268 % const struct stat *GetBlobProperties(const Image *image)
1270 % A description of each parameter follows:
1272 % o image: the image.
1275 MagickPrivate const struct stat *GetBlobProperties(const Image *image)
1277 assert(image != (Image *) NULL);
1278 assert(image->signature == MagickSignature);
1279 if (image->debug != MagickFalse)
1280 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1281 return(&image->blob->properties);
1285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1289 + G e t B l o b S i z e %
1293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1295 % GetBlobSize() returns the current length of the image file or blob; zero is
1296 % returned if the size cannot be determined.
1298 % The format of the GetBlobSize method is:
1300 % MagickSizeType GetBlobSize(const Image *image)
1302 % A description of each parameter follows:
1304 % o image: the image.
1307 MagickExport MagickSizeType GetBlobSize(const Image *image)
1312 assert(image != (Image *) NULL);
1313 assert(image->signature == MagickSignature);
1314 if (image->debug != MagickFalse)
1315 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1316 assert(image->blob != (BlobInfo *) NULL);
1318 switch (image->blob->type)
1320 case UndefinedStream:
1322 extent=image->blob->size;
1327 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1328 extent=(MagickSizeType) image->blob->properties.st_size;
1331 case StandardStream:
1334 extent=image->blob->size;
1343 status=GetPathAttributes(image->filename,&image->blob->properties);
1344 if (status != MagickFalse)
1345 extent=(MagickSizeType) image->blob->properties.st_size;
1352 extent=(MagickSizeType) image->blob->length;
1360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1364 + G e t B l o b S t r e a m D a t a %
1368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1370 % GetBlobStreamData() returns the stream data for the image.
1372 % The format of the GetBlobStreamData method is:
1374 % unsigned char *GetBlobStreamData(const Image *image)
1376 % A description of each parameter follows:
1378 % o image: the image.
1381 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1383 assert(image != (const Image *) NULL);
1384 assert(image->signature == MagickSignature);
1385 return(image->blob->data);
1389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1393 + G e t B l o b S t r e a m H a n d l e r %
1397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1399 % GetBlobStreamHandler() returns the stream handler for the image.
1401 % The format of the GetBlobStreamHandler method is:
1403 % StreamHandler GetBlobStreamHandler(const Image *image)
1405 % A description of each parameter follows:
1407 % o image: the image.
1410 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
1412 assert(image != (const Image *) NULL);
1413 assert(image->signature == MagickSignature);
1414 if (image->debug != MagickFalse)
1415 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1416 return(image->blob->stream);
1420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1424 % I m a g e T o B l o b %
1428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1430 % ImageToBlob() implements direct to memory image formats. It returns the
1431 % image as a formatted blob and its length. The magick member of the Image
1432 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1433 % etc.). This method is the equivalent of WriteImage(), but writes the
1434 % formatted "file" to a memory buffer rather than to an actual file.
1436 % The format of the ImageToBlob method is:
1438 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1439 % size_t *length,ExceptionInfo *exception)
1441 % A description of each parameter follows:
1443 % o image_info: the image info.
1445 % o image: the image.
1447 % o length: This pointer to a size_t integer sets the initial length of the
1448 % blob. On return, it reflects the actual length of the blob.
1450 % o exception: return any errors or warnings in this structure.
1453 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1454 Image *image,size_t *length,ExceptionInfo *exception)
1468 assert(image_info != (const ImageInfo *) NULL);
1469 assert(image_info->signature == MagickSignature);
1470 if (image_info->debug != MagickFalse)
1471 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1472 image_info->filename);
1473 assert(image != (Image *) NULL);
1474 assert(image->signature == MagickSignature);
1475 assert(exception != (ExceptionInfo *) NULL);
1477 blob=(unsigned char *) NULL;
1478 blob_info=CloneImageInfo(image_info);
1479 blob_info->adjoin=MagickFalse;
1480 (void) SetImageInfo(blob_info,1,exception);
1481 if (*blob_info->magick != '\0')
1482 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1483 magick_info=GetMagickInfo(image->magick,exception);
1484 if (magick_info == (const MagickInfo *) NULL)
1486 (void) ThrowMagickException(exception,GetMagickModule(),
1487 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1491 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1492 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1495 Native blob support for this image format.
1497 blob_info->length=0;
1498 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1499 sizeof(unsigned char));
1500 if (blob_info->blob == (void *) NULL)
1501 (void) ThrowMagickException(exception,GetMagickModule(),
1502 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1505 (void) CloseBlob(image);
1506 image->blob->exempt=MagickTrue;
1507 *image->filename='\0';
1508 status=WriteImage(blob_info,image,exception);
1509 if ((status != MagickFalse) && (image->blob->length != 0))
1511 *length=image->blob->length;
1512 blob=DetachBlob(image->blob);
1513 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1521 unique[MaxTextExtent];
1527 Write file to disk in blob image format.
1529 file=AcquireUniqueFileResource(unique);
1532 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1533 image_info->filename);
1537 blob_info->file=fdopen(file,"wb");
1538 if (blob_info->file != (FILE *) NULL)
1540 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
1541 image->magick,unique);
1542 status=WriteImage(blob_info,image,exception);
1543 (void) fclose(blob_info->file);
1544 if (status != MagickFalse)
1545 blob=FileToBlob(image->filename,~0UL,length,exception);
1547 (void) RelinquishUniqueFileResource(unique);
1550 blob_info=DestroyImageInfo(blob_info);
1555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1559 % I m a g e T o F i l e %
1563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1566 % occurs otherwise MagickTrue.
1568 % The format of the ImageToFile method is:
1570 % MagickBooleanType ImageToFile(Image *image,char *filename,
1571 % ExceptionInfo *exception)
1573 % A description of each parameter follows:
1575 % o image: the image.
1577 % o filename: Write the image to this file.
1579 % o exception: return any errors or warnings in this structure.
1582 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1583 ExceptionInfo *exception)
1588 register const unsigned char
1607 assert(image != (Image *) NULL);
1608 assert(image->signature == MagickSignature);
1609 assert(image->blob != (BlobInfo *) NULL);
1610 assert(image->blob->type != UndefinedStream);
1611 if (image->debug != MagickFalse)
1612 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1613 assert(filename != (const char *) NULL);
1614 if (*filename == '\0')
1615 file=AcquireUniqueFileResource(filename);
1617 if (LocaleCompare(filename,"-") == 0)
1618 file=fileno(stdout);
1620 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1623 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1624 return(MagickFalse);
1626 quantum=(size_t) MagickMaxBufferExtent;
1627 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1628 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
1629 MagickMaxBufferExtent);
1630 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1631 if (buffer == (unsigned char *) NULL)
1634 (void) ThrowMagickException(exception,GetMagickModule(),
1635 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1636 return(MagickFalse);
1639 p=ReadBlobStream(image,quantum,buffer,&count);
1640 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1642 length=(size_t) count;
1643 for (i=0; i < length; i+=count)
1645 count=write(file,p+i,(size_t) (length-i));
1656 if (LocaleCompare(filename,"-") != 0)
1658 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1659 if ((file == -1) || (i < length))
1661 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1662 return(MagickFalse);
1668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1672 % I m a g e s T o B l o b %
1676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1678 % ImagesToBlob() implements direct to memory image formats. It returns the
1679 % image sequence as a blob and its length. The magick member of the ImageInfo
1680 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1682 % Note, some image formats do not permit multiple images to the same image
1683 % stream (e.g. JPEG). in this instance, just the first image of the
1684 % sequence is returned as a blob.
1686 % The format of the ImagesToBlob method is:
1688 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1689 % size_t *length,ExceptionInfo *exception)
1691 % A description of each parameter follows:
1693 % o image_info: the image info.
1695 % o images: the image list.
1697 % o length: This pointer to a size_t integer sets the initial length of the
1698 % blob. On return, it reflects the actual length of the blob.
1700 % o exception: return any errors or warnings in this structure.
1703 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1704 Image *images,size_t *length,ExceptionInfo *exception)
1718 assert(image_info != (const ImageInfo *) NULL);
1719 assert(image_info->signature == MagickSignature);
1720 if (image_info->debug != MagickFalse)
1721 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1722 image_info->filename);
1723 assert(images != (Image *) NULL);
1724 assert(images->signature == MagickSignature);
1725 assert(exception != (ExceptionInfo *) NULL);
1727 blob=(unsigned char *) NULL;
1728 blob_info=CloneImageInfo(image_info);
1729 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1731 if (*blob_info->magick != '\0')
1732 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1733 if (blob_info->adjoin == MagickFalse)
1735 blob_info=DestroyImageInfo(blob_info);
1736 return(ImageToBlob(image_info,images,length,exception));
1738 magick_info=GetMagickInfo(images->magick,exception);
1739 if (magick_info == (const MagickInfo *) NULL)
1741 (void) ThrowMagickException(exception,GetMagickModule(),
1742 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1746 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1747 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1750 Native blob support for this images format.
1752 blob_info->length=0;
1753 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1754 sizeof(unsigned char));
1755 if (blob_info->blob == (void *) NULL)
1756 (void) ThrowMagickException(exception,GetMagickModule(),
1757 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1760 images->blob->exempt=MagickTrue;
1761 *images->filename='\0';
1762 status=WriteImages(blob_info,images,images->filename,exception);
1763 if ((status != MagickFalse) && (images->blob->length != 0))
1765 *length=images->blob->length;
1766 blob=DetachBlob(images->blob);
1767 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1775 filename[MaxTextExtent],
1776 unique[MaxTextExtent];
1782 Write file to disk in blob images format.
1784 file=AcquireUniqueFileResource(unique);
1787 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1788 image_info->filename);
1792 blob_info->file=fdopen(file,"wb");
1793 if (blob_info->file != (FILE *) NULL)
1795 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
1796 images->magick,unique);
1797 status=WriteImages(blob_info,images,filename,exception);
1798 (void) fclose(blob_info->file);
1799 if (status != MagickFalse)
1800 blob=FileToBlob(images->filename,~0UL,length,exception);
1802 (void) RelinquishUniqueFileResource(unique);
1805 blob_info=DestroyImageInfo(blob_info);
1809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1813 % I n j e c t I m a g e B l o b %
1817 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1819 % InjectImageBlob() injects the image with a copy of itself in the specified
1820 % format (e.g. inject JPEG into a PDF image).
1822 % The format of the InjectImageBlob method is:
1824 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1825 % Image *image,Image *inject_image,const char *format,
1826 % ExceptionInfo *exception)
1828 % A description of each parameter follows:
1830 % o image_info: the image info..
1832 % o image: the image.
1834 % o inject_image: inject into the image stream.
1836 % o format: the image format.
1838 % o exception: return any errors or warnings in this structure.
1841 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1842 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1845 filename[MaxTextExtent];
1878 Write inject image to a temporary file.
1880 assert(image_info != (ImageInfo *) NULL);
1881 assert(image_info->signature == MagickSignature);
1882 assert(image != (Image *) NULL);
1883 assert(image->signature == MagickSignature);
1884 if (image->debug != MagickFalse)
1885 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1886 assert(inject_image != (Image *) NULL);
1887 assert(inject_image->signature == MagickSignature);
1888 assert(exception != (ExceptionInfo *) NULL);
1889 unique_file=(FILE *) NULL;
1890 file=AcquireUniqueFileResource(filename);
1892 unique_file=fdopen(file,"wb");
1893 if ((file == -1) || (unique_file == (FILE *) NULL))
1895 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1896 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1898 return(MagickFalse);
1900 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1901 if (byte_image == (Image *) NULL)
1903 (void) fclose(unique_file);
1904 (void) RelinquishUniqueFileResource(filename);
1905 return(MagickFalse);
1907 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1909 DestroyBlob(byte_image);
1910 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1911 write_info=CloneImageInfo(image_info);
1912 SetImageInfoFile(write_info,unique_file);
1913 status=WriteImage(write_info,byte_image,exception);
1914 write_info=DestroyImageInfo(write_info);
1915 byte_image=DestroyImage(byte_image);
1916 (void) fclose(unique_file);
1917 if (status == MagickFalse)
1919 (void) RelinquishUniqueFileResource(filename);
1920 return(MagickFalse);
1923 Inject into image stream.
1925 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
1928 (void) RelinquishUniqueFileResource(filename);
1929 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1930 image_info->filename);
1931 return(MagickFalse);
1933 quantum=(size_t) MagickMaxBufferExtent;
1934 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1935 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1936 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1937 if (buffer == (unsigned char *) NULL)
1939 (void) RelinquishUniqueFileResource(filename);
1940 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1943 for (i=0; ; i+=count)
1945 count=(ssize_t) read(file,buffer,quantum);
1952 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1957 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1958 (void) RelinquishUniqueFileResource(filename);
1959 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1968 + I s B l o b E x e m p t %
1972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1974 % IsBlobExempt() returns true if the blob is exempt.
1976 % The format of the IsBlobExempt method is:
1978 % MagickBooleanType IsBlobExempt(const Image *image)
1980 % A description of each parameter follows:
1982 % o image: the image.
1985 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
1987 assert(image != (const Image *) NULL);
1988 assert(image->signature == MagickSignature);
1989 if (image->debug != MagickFalse)
1990 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1991 return(image->blob->exempt);
1995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1999 + I s B l o b S e e k a b l e %
2003 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005 % IsBlobSeekable() returns true if the blob is seekable.
2007 % The format of the IsBlobSeekable method is:
2009 % MagickBooleanType IsBlobSeekable(const Image *image)
2011 % A description of each parameter follows:
2013 % o image: the image.
2016 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
2021 assert(image != (const Image *) NULL);
2022 assert(image->signature == MagickSignature);
2023 if (image->debug != MagickFalse)
2024 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2025 seekable=(image->blob->type == FileStream) ||
2026 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2035 + I s B l o b T e m p o r a r y %
2039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2041 % IsBlobTemporary() returns true if the blob is temporary.
2043 % The format of the IsBlobTemporary method is:
2045 % MagickBooleanType IsBlobTemporary(const Image *image)
2047 % A description of each parameter follows:
2049 % o image: the image.
2052 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
2054 assert(image != (const Image *) NULL);
2055 assert(image->signature == MagickSignature);
2056 if (image->debug != MagickFalse)
2057 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2058 return(image->blob->temporary);
2062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2072 % MapBlob() creates a mapping from a file to a binary large object.
2074 % The format of the MapBlob method is:
2076 % unsigned char *MapBlob(int file,const MapMode mode,
2077 % const MagickOffsetType offset,const size_t length)
2079 % A description of each parameter follows:
2081 % o file: map this file descriptor.
2083 % o mode: ReadMode, WriteMode, or IOMode.
2085 % o offset: starting at this offset within the file.
2087 % o length: the length of the mapping is returned in this pointer.
2090 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2091 const MagickOffsetType offset,const size_t length)
2093 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2106 #if defined(MAP_ANONYMOUS)
2107 flags|=MAP_ANONYMOUS;
2109 return((unsigned char *) NULL);
2116 protection=PROT_READ;
2118 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2124 protection=PROT_WRITE;
2126 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2128 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2129 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2130 POSIX_MADV_WILLNEED);
2136 protection=PROT_READ | PROT_WRITE;
2138 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2143 if (map == (unsigned char *) MAP_FAILED)
2144 return((unsigned char *) NULL);
2151 return((unsigned char *) NULL);
2156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2160 + M S B O r d e r L o n g %
2164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2166 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2167 % most-significant byte first.
2169 % The format of the MSBOrderLong method is:
2171 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2173 % A description of each parameter follows.
2175 % o buffer: Specifies a pointer to a buffer of integers.
2177 % o length: Specifies the length of the buffer.
2180 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2185 register unsigned char
2189 assert(buffer != (unsigned char *) NULL);
2196 *buffer++=(unsigned char) c;
2200 *buffer++=(unsigned char) c;
2206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2210 + M S B O r d e r S h o r t %
2214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2216 % MSBOrderShort() converts a least-significant byte first buffer of integers
2217 % to most-significant byte first.
2219 % The format of the MSBOrderShort method is:
2221 % void MSBOrderShort(unsigned char *p,const size_t length)
2223 % A description of each parameter follows.
2225 % o p: Specifies a pointer to a buffer of integers.
2227 % o length: Specifies the length of the buffer.
2230 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2235 register unsigned char
2238 assert(p != (unsigned char *) NULL);
2245 *p++=(unsigned char) c;
2250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2260 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2261 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2262 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2263 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2264 % from a system command.
2266 % The format of the OpenBlob method is:
2268 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2269 % const BlobMode mode,ExceptionInfo *exception)
2271 % A description of each parameter follows:
2273 % o image_info: the image info.
2275 % o image: the image.
2277 % o mode: the mode for opening the file.
2280 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2281 Image *image,const BlobMode mode,ExceptionInfo *exception)
2284 extension[MaxTextExtent],
2285 filename[MaxTextExtent];
2296 assert(image_info != (ImageInfo *) NULL);
2297 assert(image_info->signature == MagickSignature);
2298 if (image_info->debug != MagickFalse)
2299 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2300 image_info->filename);
2301 assert(image != (Image *) NULL);
2302 assert(image->signature == MagickSignature);
2303 if (image_info->blob != (void *) NULL)
2305 if (image_info->stream != (StreamHandler) NULL)
2306 image->blob->stream=(StreamHandler) image_info->stream;
2307 AttachBlob(image->blob,image_info->blob,image_info->length);
2310 (void) DetachBlob(image->blob);
2313 default: type="r"; break;
2314 case ReadBlobMode: type="r"; break;
2315 case ReadBinaryBlobMode: type="rb"; break;
2316 case WriteBlobMode: type="w"; break;
2317 case WriteBinaryBlobMode: type="w+b"; break;
2318 case AppendBlobMode: type="a"; break;
2319 case AppendBinaryBlobMode: type="a+b"; break;
2322 image->blob->synchronize=image_info->synchronize;
2323 if (image_info->stream != (StreamHandler) NULL)
2325 image->blob->stream=(StreamHandler) image_info->stream;
2328 image->blob->type=FifoStream;
2336 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2337 rights=ReadPolicyRights;
2339 rights=WritePolicyRights;
2340 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2343 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2344 "NotAuthorized","`%s'",filename);
2345 return(MagickFalse);
2347 if ((LocaleCompare(filename,"-") == 0) ||
2348 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2350 image->blob->file=(*type == 'r') ? stdin : stdout;
2351 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2352 if (strchr(type,'b') != (char *) NULL)
2353 setmode(_fileno(image->blob->file),_O_BINARY);
2355 image->blob->type=StandardStream;
2356 image->blob->exempt=MagickTrue;
2359 if (LocaleNCompare(filename,"fd:",3) == 0)
2362 mode[MaxTextExtent];
2366 image->blob->file=fdopen(StringToLong(filename+3),mode);
2367 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2368 if (strchr(type,'b') != (char *) NULL)
2369 setmode(_fileno(image->blob->file),_O_BINARY);
2371 image->blob->type=StandardStream;
2372 image->blob->exempt=MagickTrue;
2375 #if defined(MAGICKCORE_HAVE_POPEN)
2376 if (*filename == '|')
2379 mode[MaxTextExtent];
2382 Pipe image to or from a system command.
2384 #if defined(SIGPIPE)
2386 (void) signal(SIGPIPE,SIG_IGN);
2390 image->blob->file=(FILE *) popen_utf8(filename+1,mode);
2391 if (image->blob->file == (FILE *) NULL)
2393 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2394 return(MagickFalse);
2396 image->blob->type=PipeStream;
2397 image->blob->exempt=MagickTrue;
2401 status=GetPathAttributes(filename,&image->blob->properties);
2402 #if defined(S_ISFIFO)
2403 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2405 image->blob->file=(FILE *) fopen_utf8(filename,type);
2406 if (image->blob->file == (FILE *) NULL)
2408 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2409 return(MagickFalse);
2411 image->blob->type=FileStream;
2412 image->blob->exempt=MagickTrue;
2416 GetPathComponent(image->filename,ExtensionPath,extension);
2419 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2420 if ((image_info->adjoin == MagickFalse) ||
2421 (strchr(filename,'%') != (char *) NULL))
2424 Form filename for multi-part images.
2426 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2427 image->scene,filename);
2428 if ((LocaleCompare(filename,image->filename) == 0) &&
2429 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2430 (GetNextImageInList(image) != (Image *) NULL)))
2433 path[MaxTextExtent];
2435 GetPathComponent(image->filename,RootPath,path);
2436 if (*extension == '\0')
2437 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
2438 path,(double) image->scene);
2440 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
2441 path,(double) image->scene,extension);
2443 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2444 #if defined(macintosh)
2445 SetApplicationType(filename,image_info->magick,'8BIM');
2449 if (image_info->file != (FILE *) NULL)
2451 image->blob->file=image_info->file;
2452 image->blob->type=FileStream;
2453 image->blob->exempt=MagickTrue;
2458 image->blob->file=(FILE *) fopen_utf8(filename,type);
2459 if (image->blob->file != (FILE *) NULL)
2467 image->blob->type=FileStream;
2468 #if defined(MAGICKCORE_HAVE_SETVBUF)
2469 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2471 (void) ResetMagickMemory(magick,0,sizeof(magick));
2472 count=fread(magick,1,sizeof(magick),image->blob->file);
2473 (void) rewind(image->blob->file);
2474 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2475 " read %.20g magic header bytes",(double) count);
2476 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2477 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2478 ((int) magick[2] == 0x08))
2480 (void) fclose(image->blob->file);
2481 image->blob->file=(FILE *) gzopen(filename,type);
2482 if (image->blob->file != (FILE *) NULL)
2483 image->blob->type=ZipStream;
2486 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2487 if (strncmp((char *) magick,"BZh",3) == 0)
2489 (void) fclose(image->blob->file);
2490 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2491 if (image->blob->file != (FILE *) NULL)
2492 image->blob->type=BZipStream;
2495 if (image->blob->type == FileStream)
2506 sans_exception=AcquireExceptionInfo();
2507 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2508 sans_exception=DestroyExceptionInfo(sans_exception);
2509 properties=(&image->blob->properties);
2510 if ((magick_info != (const MagickInfo *) NULL) &&
2511 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2512 (properties->st_size <= MagickMaxBufferExtent))
2520 length=(size_t) properties->st_size;
2521 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2522 if (blob != (void *) NULL)
2525 Format supports blobs-- use memory-mapped I/O.
2527 if (image_info->file != (FILE *) NULL)
2528 image->blob->exempt=MagickFalse;
2531 (void) fclose(image->blob->file);
2532 image->blob->file=(FILE *) NULL;
2534 AttachBlob(image->blob,blob,length);
2535 image->blob->mapped=MagickTrue;
2542 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2543 if ((LocaleCompare(extension,"Z") == 0) ||
2544 (LocaleCompare(extension,"gz") == 0) ||
2545 (LocaleCompare(extension,"wmz") == 0) ||
2546 (LocaleCompare(extension,"svgz") == 0))
2548 if (mode == WriteBinaryBlobMode)
2550 image->blob->file=(FILE *) gzopen(filename,type);
2551 if (image->blob->file != (FILE *) NULL)
2552 image->blob->type=ZipStream;
2556 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2557 if (LocaleCompare(extension,".bz2") == 0)
2559 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2560 if (image->blob->file != (FILE *) NULL)
2561 image->blob->type=BZipStream;
2566 image->blob->file=(FILE *) fopen_utf8(filename,type);
2567 if (image->blob->file != (FILE *) NULL)
2569 image->blob->type=FileStream;
2570 #if defined(MAGICKCORE_HAVE_SETVBUF)
2571 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2576 image->blob->status=MagickFalse;
2577 if (image->blob->type != UndefinedStream)
2578 image->blob->size=GetBlobSize(image);
2581 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2582 return(MagickFalse);
2588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2598 % PingBlob() returns all the attributes of an image or image sequence except
2599 % for the pixels. It is much faster and consumes far less memory than
2600 % BlobToImage(). On failure, a NULL image is returned and exception
2601 % describes the reason for the failure.
2603 % The format of the PingBlob method is:
2605 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2606 % const size_t length,ExceptionInfo *exception)
2608 % A description of each parameter follows:
2610 % o image_info: the image info.
2612 % o blob: the address of a character stream in one of the image formats
2613 % understood by ImageMagick.
2615 % o length: This size_t integer reflects the length in bytes of the blob.
2617 % o exception: return any errors or warnings in this structure.
2621 #if defined(__cplusplus) || defined(c_plusplus)
2625 static size_t PingStream(const Image *magick_unused(image),
2626 const void *magick_unused(pixels),const size_t columns)
2631 #if defined(__cplusplus) || defined(c_plusplus)
2635 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2636 const size_t length,ExceptionInfo *exception)
2644 assert(image_info != (ImageInfo *) NULL);
2645 assert(image_info->signature == MagickSignature);
2646 if (image_info->debug != MagickFalse)
2647 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2648 image_info->filename);
2649 assert(exception != (ExceptionInfo *) NULL);
2650 if ((blob == (const void *) NULL) || (length == 0))
2652 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2653 "UnrecognizedImageFormat","`%s'",image_info->magick);
2654 return((Image *) NULL);
2656 ping_info=CloneImageInfo(image_info);
2657 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2658 if (ping_info->blob == (const void *) NULL)
2660 (void) ThrowMagickException(exception,GetMagickModule(),
2661 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2662 return((Image *) NULL);
2664 (void) memcpy(ping_info->blob,blob,length);
2665 ping_info->length=length;
2666 ping_info->ping=MagickTrue;
2667 image=ReadStream(ping_info,&PingStream,exception);
2668 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2669 ping_info=DestroyImageInfo(ping_info);
2674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2684 % ReadBlob() reads data from the blob or image file and returns it. It
2685 % returns the number of bytes read.
2687 % The format of the ReadBlob method is:
2689 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2691 % A description of each parameter follows:
2693 % o image: the image.
2695 % o length: Specifies an integer representing the number of bytes to read
2698 % o data: Specifies an area to place the information requested from the
2702 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2703 unsigned char *data)
2708 register unsigned char
2714 assert(image != (Image *) NULL);
2715 assert(image->signature == MagickSignature);
2716 assert(image->blob != (BlobInfo *) NULL);
2717 assert(image->blob->type != UndefinedStream);
2720 assert(data != (void *) NULL);
2723 switch (image->blob->type)
2725 case UndefinedStream:
2728 case StandardStream:
2735 count=(ssize_t) fread(q,1,length,image->blob->file);
2740 c=getc(image->blob->file);
2743 *q++=(unsigned char) c;
2748 c=getc(image->blob->file);
2751 *q++=(unsigned char) c;
2761 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2766 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2771 c=gzgetc(image->blob->file);
2774 *q++=(unsigned char) c;
2779 c=gzgetc(image->blob->file);
2782 *q++=(unsigned char) c;
2793 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2794 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2802 register const unsigned char
2805 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2807 image->blob->eof=MagickTrue;
2810 p=image->blob->data+image->blob->offset;
2811 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2812 image->blob->offset+=count;
2813 if (count != (ssize_t) length)
2814 image->blob->eof=MagickTrue;
2815 (void) memcpy(q,p,(size_t) count);
2823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2827 + R e a d B l o b B y t e %
2831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2833 % ReadBlobByte() reads a single byte from the image file and returns it.
2835 % The format of the ReadBlobByte method is:
2837 % int ReadBlobByte(Image *image)
2839 % A description of each parameter follows.
2841 % o image: the image.
2844 MagickExport int ReadBlobByte(Image *image)
2846 register const unsigned char
2855 assert(image != (Image *) NULL);
2856 assert(image->signature == MagickSignature);
2857 p=ReadBlobStream(image,1,buffer,&count);
2864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2868 + R e a d B l o b D o u b l e %
2872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2874 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2875 % specified by the endian member of the image structure.
2877 % The format of the ReadBlobDouble method is:
2879 % double ReadBlobDouble(Image *image)
2881 % A description of each parameter follows.
2883 % o image: the image.
2886 MagickExport double ReadBlobDouble(Image *image)
2897 quantum.double_value=0.0;
2898 quantum.unsigned_value=ReadBlobLongLong(image);
2899 return(quantum.double_value);
2903 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2907 + R e a d B l o b F l o a t %
2911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2913 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2914 % specified by the endian member of the image structure.
2916 % The format of the ReadBlobFloat method is:
2918 % float ReadBlobFloat(Image *image)
2920 % A description of each parameter follows.
2922 % o image: the image.
2925 MagickExport float ReadBlobFloat(Image *image)
2936 quantum.float_value=0.0;
2937 quantum.unsigned_value=ReadBlobLong(image);
2938 return(quantum.float_value);
2942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2946 + R e a d B l o b L o n g %
2950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2952 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2953 % specified by the endian member of the image structure.
2955 % The format of the ReadBlobLong method is:
2957 % unsigned int ReadBlobLong(Image *image)
2959 % A description of each parameter follows.
2961 % o image: the image.
2964 MagickExport unsigned int ReadBlobLong(Image *image)
2966 register const unsigned char
2978 assert(image != (Image *) NULL);
2979 assert(image->signature == MagickSignature);
2981 p=ReadBlobStream(image,4,buffer,&count);
2984 if (image->endian == LSBEndian)
2986 value=(unsigned int) (*p++);
2987 value|=((unsigned int) (*p++)) << 8;
2988 value|=((unsigned int) (*p++)) << 16;
2989 value|=((unsigned int) (*p++)) << 24;
2992 value=((unsigned int) (*p++)) << 24;
2993 value|=((unsigned int) (*p++)) << 16;
2994 value|=((unsigned int) (*p++)) << 8;
2995 value|=((unsigned int) (*p++));
3000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3004 + R e a d B l o b L o n g L o n g %
3008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3010 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3011 % byte-order specified by the endian member of the image structure.
3013 % The format of the ReadBlobLongLong method is:
3015 % MagickSizeType ReadBlobLongLong(Image *image)
3017 % A description of each parameter follows.
3019 % o image: the image.
3022 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3027 register const unsigned char
3036 assert(image != (Image *) NULL);
3037 assert(image->signature == MagickSignature);
3039 p=ReadBlobStream(image,8,buffer,&count);
3041 return(MagickULLConstant(0));
3042 if (image->endian == LSBEndian)
3044 value=(MagickSizeType) (*p++);
3045 value|=((MagickSizeType) (*p++)) << 8;
3046 value|=((MagickSizeType) (*p++)) << 16;
3047 value|=((MagickSizeType) (*p++)) << 24;
3048 value|=((MagickSizeType) (*p++)) << 32;
3049 value|=((MagickSizeType) (*p++)) << 40;
3050 value|=((MagickSizeType) (*p++)) << 48;
3051 value|=((MagickSizeType) (*p++)) << 56;
3052 return(value & MagickULLConstant(0xffffffffffffffff));
3054 value=((MagickSizeType) (*p++)) << 56;
3055 value|=((MagickSizeType) (*p++)) << 48;
3056 value|=((MagickSizeType) (*p++)) << 40;
3057 value|=((MagickSizeType) (*p++)) << 32;
3058 value|=((MagickSizeType) (*p++)) << 24;
3059 value|=((MagickSizeType) (*p++)) << 16;
3060 value|=((MagickSizeType) (*p++)) << 8;
3061 value|=((MagickSizeType) (*p++));
3062 return(value & MagickULLConstant(0xffffffffffffffff));
3066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3070 + R e a d B l o b S h o r t %
3074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3076 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3077 % specified by the endian member of the image structure.
3079 % The format of the ReadBlobShort method is:
3081 % unsigned short ReadBlobShort(Image *image)
3083 % A description of each parameter follows.
3085 % o image: the image.
3088 MagickExport unsigned short ReadBlobShort(Image *image)
3090 register const unsigned char
3093 register unsigned int
3102 assert(image != (Image *) NULL);
3103 assert(image->signature == MagickSignature);
3105 p=ReadBlobStream(image,2,buffer,&count);
3107 return((unsigned short) 0U);
3108 if (image->endian == LSBEndian)
3110 value=(unsigned int) (*p++);
3111 value|=((unsigned int) (*p++)) << 8;
3112 return((unsigned short) (value & 0xffff));
3114 value=(unsigned int) ((*p++) << 8);
3115 value|=(unsigned int) (*p++);
3116 return((unsigned short) (value & 0xffff));
3120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3124 + R e a d B l o b L S B L o n g %
3128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3130 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3131 % least-significant byte first order.
3133 % The format of the ReadBlobLSBLong method is:
3135 % unsigned int ReadBlobLSBLong(Image *image)
3137 % A description of each parameter follows.
3139 % o image: the image.
3142 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3144 register const unsigned char
3147 register unsigned int
3156 assert(image != (Image *) NULL);
3157 assert(image->signature == MagickSignature);
3159 p=ReadBlobStream(image,4,buffer,&count);
3162 value=(unsigned int) (*p++);
3163 value|=((unsigned int) (*p++)) << 8;
3164 value|=((unsigned int) (*p++)) << 16;
3165 value|=((unsigned int) (*p++)) << 24;
3170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3174 + R e a d B l o b L S B S h o r t %
3178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3180 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3181 % least-significant byte first order.
3183 % The format of the ReadBlobLSBShort method is:
3185 % unsigned short ReadBlobLSBShort(Image *image)
3187 % A description of each parameter follows.
3189 % o image: the image.
3192 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3194 register const unsigned char
3197 register unsigned int
3206 assert(image != (Image *) NULL);
3207 assert(image->signature == MagickSignature);
3209 p=ReadBlobStream(image,2,buffer,&count);
3211 return((unsigned short) 0U);
3212 value=(unsigned int) (*p++);
3213 value|=((unsigned int) ((*p++)) << 8);
3214 return((unsigned short) (value & 0xffff));
3218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3222 + R e a d B l o b M S B L o n g %
3226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3228 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3229 % most-significant byte first order.
3231 % The format of the ReadBlobMSBLong method is:
3233 % unsigned int ReadBlobMSBLong(Image *image)
3235 % A description of each parameter follows.
3237 % o image: the image.
3240 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3242 register const unsigned char
3245 register unsigned int
3254 assert(image != (Image *) NULL);
3255 assert(image->signature == MagickSignature);
3257 p=ReadBlobStream(image,4,buffer,&count);
3260 value=((unsigned int) (*p++) << 24);
3261 value|=((unsigned int) (*p++) << 16);
3262 value|=((unsigned int) (*p++) << 8);
3263 value|=(unsigned int) (*p++);
3268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3272 + R e a d B l o b M S B L o n g L o n g %
3276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3278 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3279 % most-significant byte first order.
3281 % The format of the ReadBlobMSBLongLong method is:
3283 % unsigned int ReadBlobMSBLongLong(Image *image)
3285 % A description of each parameter follows.
3287 % o image: the image.
3290 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3292 register const unsigned char
3295 register MagickSizeType
3304 assert(image != (Image *) NULL);
3305 assert(image->signature == MagickSignature);
3307 p=ReadBlobStream(image,8,buffer,&count);
3309 return(MagickULLConstant(0));
3310 value=((MagickSizeType) (*p++)) << 56;
3311 value|=((MagickSizeType) (*p++)) << 48;
3312 value|=((MagickSizeType) (*p++)) << 40;
3313 value|=((MagickSizeType) (*p++)) << 32;
3314 value|=((MagickSizeType) (*p++)) << 24;
3315 value|=((MagickSizeType) (*p++)) << 16;
3316 value|=((MagickSizeType) (*p++)) << 8;
3317 value|=((MagickSizeType) (*p++));
3318 return(value & MagickULLConstant(0xffffffffffffffff));
3322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3326 + R e a d B l o b M S B S h o r t %
3330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3332 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3333 % most-significant byte first order.
3335 % The format of the ReadBlobMSBShort method is:
3337 % unsigned short ReadBlobMSBShort(Image *image)
3339 % A description of each parameter follows.
3341 % o image: the image.
3344 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3346 register const unsigned char
3349 register unsigned int
3358 assert(image != (Image *) NULL);
3359 assert(image->signature == MagickSignature);
3361 p=ReadBlobStream(image,2,buffer,&count);
3363 return((unsigned short) 0U);
3364 value=(unsigned int) ((*p++) << 8);
3365 value|=(unsigned int) (*p++);
3366 return((unsigned short) (value & 0xffff));
3370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3374 + R e a d B l o b S t r i n g %
3378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3380 % ReadBlobString() reads characters from a blob or file until a newline
3381 % character is read or an end-of-file condition is encountered.
3383 % The format of the ReadBlobString method is:
3385 % char *ReadBlobString(Image *image,char *string)
3387 % A description of each parameter follows:
3389 % o image: the image.
3391 % o string: the address of a character buffer.
3394 MagickExport char *ReadBlobString(Image *image,char *string)
3396 register const unsigned char
3408 assert(image != (Image *) NULL);
3409 assert(image->signature == MagickSignature);
3410 for (i=0; i < (MaxTextExtent-1L); i++)
3412 p=ReadBlobStream(image,1,buffer,&count);
3416 return((char *) NULL);
3419 string[i]=(char) (*p);
3420 if ((string[i] == '\r') || (string[i] == '\n'))
3423 if (string[i] == '\r')
3424 (void) ReadBlobStream(image,1,buffer,&count);
3430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3434 + R e f e r e n c e B l o b %
3438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3440 % ReferenceBlob() increments the reference count associated with the pixel
3441 % blob returning a pointer to the blob.
3443 % The format of the ReferenceBlob method is:
3445 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3447 % A description of each parameter follows:
3449 % o blob_info: the blob_info.
3452 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3454 assert(blob != (BlobInfo *) NULL);
3455 assert(blob->signature == MagickSignature);
3456 if (blob->debug != MagickFalse)
3457 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3458 LockSemaphoreInfo(blob->semaphore);
3459 blob->reference_count++;
3460 UnlockSemaphoreInfo(blob->semaphore);
3465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3475 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3476 % and returns the resulting offset.
3478 % The format of the SeekBlob method is:
3480 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3483 % A description of each parameter follows:
3485 % o image: the image.
3487 % o offset: Specifies an integer representing the offset in bytes.
3489 % o whence: Specifies an integer representing how the offset is
3490 % treated relative to the beginning of the blob as follows:
3492 % SEEK_SET Set position equal to offset bytes.
3493 % SEEK_CUR Set position to current location plus offset.
3494 % SEEK_END Set position to EOF plus offset.
3497 MagickExport MagickOffsetType SeekBlob(Image *image,
3498 const MagickOffsetType offset,const int whence)
3500 assert(image != (Image *) NULL);
3501 assert(image->signature == MagickSignature);
3502 if (image->debug != MagickFalse)
3503 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3504 assert(image->blob != (BlobInfo *) NULL);
3505 assert(image->blob->type != UndefinedStream);
3506 switch (image->blob->type)
3508 case UndefinedStream:
3512 if (fseek(image->blob->file,offset,whence) < 0)
3514 image->blob->offset=TellBlob(image);
3517 case StandardStream:
3521 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3522 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3525 image->blob->offset=TellBlob(image);
3541 image->blob->offset=offset;
3546 if ((image->blob->offset+offset) < 0)
3548 image->blob->offset+=offset;
3553 if (((MagickOffsetType) image->blob->length+offset) < 0)
3555 image->blob->offset=image->blob->length+offset;
3559 if (image->blob->offset <= (MagickOffsetType)
3560 ((off_t) image->blob->length))
3561 image->blob->eof=MagickFalse;
3563 if (image->blob->mapped != MagickFalse)
3567 image->blob->extent=(size_t) (image->blob->offset+
3568 image->blob->quantum);
3569 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3570 image->blob->data,image->blob->extent+1,
3571 sizeof(*image->blob->data));
3572 (void) SyncBlob(image);
3573 if (image->blob->data == (unsigned char *) NULL)
3575 (void) DetachBlob(image->blob);
3582 return(image->blob->offset);
3586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3590 + S e t B l o b E x e m p t %
3594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3596 % SetBlobExempt() sets the blob exempt status.
3598 % The format of the SetBlobExempt method is:
3600 % MagickBooleanType SetBlobExempt(const Image *image,
3601 % const MagickBooleanType exempt)
3603 % A description of each parameter follows:
3605 % o image: the image.
3607 % o exempt: Set to true if this blob is exempt from being closed.
3610 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3612 assert(image != (const Image *) NULL);
3613 assert(image->signature == MagickSignature);
3614 if (image->debug != MagickFalse)
3615 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3616 image->blob->exempt=exempt;
3620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3624 + S e t B l o b E x t e n t %
3628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3630 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3631 % method is successful, subsequent writes to bytes in the specified range are
3632 % guaranteed not to fail.
3634 % The format of the SetBlobExtent method is:
3636 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3638 % A description of each parameter follows:
3640 % o image: the image.
3642 % o extent: the blob maximum extent.
3645 MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
3646 const MagickSizeType extent)
3648 assert(image != (Image *) NULL);
3649 assert(image->signature == MagickSignature);
3650 if (image->debug != MagickFalse)
3651 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3652 assert(image->blob != (BlobInfo *) NULL);
3653 assert(image->blob->type != UndefinedStream);
3654 switch (image->blob->type)
3656 case UndefinedStream:
3660 if (extent != (MagickSizeType) ((off_t) extent))
3661 return(MagickFalse);
3662 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3663 return(MagickFalse);
3672 offset=TellBlob(image);
3673 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3674 (off_t) (extent-offset));
3676 return(MagickFalse);
3681 case StandardStream:
3684 return(MagickFalse);
3686 return(MagickFalse);
3688 return(MagickFalse);
3691 if (image->blob->mapped != MagickFalse)
3693 if (image->blob->file == (FILE *) NULL)
3694 return(MagickFalse);
3695 (void) UnmapBlob(image->blob->data,image->blob->length);
3696 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3697 return(MagickFalse);
3706 offset=TellBlob(image);
3707 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3708 (off_t) (extent-offset));
3710 return(MagickFalse);
3712 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3713 WriteMode,0,(size_t) extent);
3714 image->blob->extent=(size_t) extent;
3715 image->blob->length=(size_t) extent;
3716 (void) SyncBlob(image);
3720 if (extent != (MagickSizeType) ((size_t) extent))
3721 return(MagickFalse);
3722 image->blob->extent=(size_t) extent;
3723 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3724 image->blob->extent+1,sizeof(*image->blob->data));
3725 (void) SyncBlob(image);
3726 if (image->blob->data == (unsigned char *) NULL)
3728 (void) DetachBlob(image->blob);
3729 return(MagickFalse);
3738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3748 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3749 % attributes if it is an blob.
3751 % The format of the SyncBlob method is:
3753 % int SyncBlob(Image *image)
3755 % A description of each parameter follows:
3757 % o image: the image.
3760 static int SyncBlob(Image *image)
3765 assert(image != (Image *) NULL);
3766 assert(image->signature == MagickSignature);
3767 if (image->debug != MagickFalse)
3768 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3769 assert(image->blob != (BlobInfo *) NULL);
3770 assert(image->blob->type != UndefinedStream);
3772 switch (image->blob->type)
3774 case UndefinedStream:
3777 case StandardStream:
3780 status=fflush(image->blob->file);
3785 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3786 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3792 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3793 status=BZ2_bzflush((BZFILE *) image->blob->file);
3801 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3802 if (image->blob->mapped != MagickFalse)
3803 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3822 % TellBlob() obtains the current value of the blob or file position.
3824 % The format of the TellBlob method is:
3826 % MagickOffsetType TellBlob(const Image *image)
3828 % A description of each parameter follows:
3830 % o image: the image.
3833 MagickExport MagickOffsetType TellBlob(const Image *image)
3838 assert(image != (Image *) NULL);
3839 assert(image->signature == MagickSignature);
3840 if (image->debug != MagickFalse)
3841 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3842 assert(image->blob != (BlobInfo *) NULL);
3843 assert(image->blob->type != UndefinedStream);
3845 switch (image->blob->type)
3847 case UndefinedStream:
3851 offset=ftell(image->blob->file);
3854 case StandardStream:
3859 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3860 offset=(MagickOffsetType) gztell(image->blob->file);
3870 offset=image->blob->offset;
3878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3882 + U n m a p B l o b %
3886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3888 % UnmapBlob() deallocates the binary large object previously allocated with
3889 % the MapBlob method.
3891 % The format of the UnmapBlob method is:
3893 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3895 % A description of each parameter follows:
3897 % o map: the address of the binary large object.
3899 % o length: the length of the binary large object.
3902 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3904 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3908 status=munmap(map,length);
3909 return(status == -1 ? MagickFalse : MagickTrue);
3913 return(MagickFalse);
3918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3922 + W r i t e B l o b %
3926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3928 % WriteBlob() writes data to a blob or image file. It returns the number of
3931 % The format of the WriteBlob method is:
3933 % ssize_t WriteBlob(Image *image,const size_t length,
3934 % const unsigned char *data)
3936 % A description of each parameter follows:
3938 % o image: the image.
3940 % o length: Specifies an integer representing the number of bytes to
3941 % write to the file.
3943 % o data: The address of the data to write to the blob or file.
3946 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3947 const unsigned char *data)
3952 register const unsigned char
3958 assert(image != (Image *) NULL);
3959 assert(image->signature == MagickSignature);
3960 assert(data != (const unsigned char *) NULL);
3961 assert(image->blob != (BlobInfo *) NULL);
3962 assert(image->blob->type != UndefinedStream);
3967 switch (image->blob->type)
3969 case UndefinedStream:
3972 case StandardStream:
3979 count=(ssize_t) fwrite((const char *) data,1,length,
3985 c=putc((int) *p++,image->blob->file);
3992 c=putc((int) *p++,image->blob->file);
4004 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4009 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4010 (unsigned int) length);
4015 c=gzputc(image->blob->file,(int) *p++);
4022 c=gzputc(image->blob->file,(int) *p++);
4035 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4036 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4043 count=(ssize_t) image->blob->stream(image,data,length);
4048 register unsigned char
4051 if ((image->blob->offset+(MagickOffsetType) length) >=
4052 (MagickOffsetType) image->blob->extent)
4054 if (image->blob->mapped != MagickFalse)
4056 image->blob->quantum<<=1;
4057 image->blob->extent+=length+image->blob->quantum;
4058 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4059 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4060 (void) SyncBlob(image);
4061 if (image->blob->data == (unsigned char *) NULL)
4063 (void) DetachBlob(image->blob);
4067 q=image->blob->data+image->blob->offset;
4068 (void) memcpy(q,p,length);
4069 image->blob->offset+=length;
4070 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4071 image->blob->length=(size_t) image->blob->offset;
4072 count=(ssize_t) length;
4079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4083 + W r i t e B l o b B y t e %
4087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4089 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4090 % written (either 0 or 1);
4092 % The format of the WriteBlobByte method is:
4094 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4096 % A description of each parameter follows.
4098 % o image: the image.
4100 % o value: Specifies the value to write.
4103 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4105 assert(image != (Image *) NULL);
4106 assert(image->signature == MagickSignature);
4107 return(WriteBlobStream(image,1,&value));
4111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4115 + W r i t e B l o b F l o a t %
4119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4121 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4122 % specified by the endian member of the image structure.
4124 % The format of the WriteBlobFloat method is:
4126 % ssize_t WriteBlobFloat(Image *image,const float value)
4128 % A description of each parameter follows.
4130 % o image: the image.
4132 % o value: Specifies the value to write.
4135 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4146 quantum.unsigned_value=0U;
4147 quantum.float_value=value;
4148 return(WriteBlobLong(image,quantum.unsigned_value));
4152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4156 + W r i t e B l o b L o n g %
4160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4162 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4163 % specified by the endian member of the image structure.
4165 % The format of the WriteBlobLong method is:
4167 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4169 % A description of each parameter follows.
4171 % o image: the image.
4173 % o value: Specifies the value to write.
4176 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4181 assert(image != (Image *) NULL);
4182 assert(image->signature == MagickSignature);
4183 if (image->endian == LSBEndian)
4185 buffer[0]=(unsigned char) value;
4186 buffer[1]=(unsigned char) (value >> 8);
4187 buffer[2]=(unsigned char) (value >> 16);
4188 buffer[3]=(unsigned char) (value >> 24);
4189 return(WriteBlobStream(image,4,buffer));
4191 buffer[0]=(unsigned char) (value >> 24);
4192 buffer[1]=(unsigned char) (value >> 16);
4193 buffer[2]=(unsigned char) (value >> 8);
4194 buffer[3]=(unsigned char) value;
4195 return(WriteBlobStream(image,4,buffer));
4199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4203 + W r i t e B l o b S h o r t %
4207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4209 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4210 % byte-order specified by the endian member of the image structure.
4212 % The format of the WriteBlobShort method is:
4214 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4216 % A description of each parameter follows.
4218 % o image: the image.
4220 % o value: Specifies the value to write.
4223 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4228 assert(image != (Image *) NULL);
4229 assert(image->signature == MagickSignature);
4230 if (image->endian == LSBEndian)
4232 buffer[0]=(unsigned char) value;
4233 buffer[1]=(unsigned char) (value >> 8);
4234 return(WriteBlobStream(image,2,buffer));
4236 buffer[0]=(unsigned char) (value >> 8);
4237 buffer[1]=(unsigned char) value;
4238 return(WriteBlobStream(image,2,buffer));
4242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4246 + W r i t e B l o b L S B L o n g %
4250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4252 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4253 % least-significant byte first order.
4255 % The format of the WriteBlobLSBLong method is:
4257 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4259 % A description of each parameter follows.
4261 % o image: the image.
4263 % o value: Specifies the value to write.
4266 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4271 assert(image != (Image *) NULL);
4272 assert(image->signature == MagickSignature);
4273 buffer[0]=(unsigned char) value;
4274 buffer[1]=(unsigned char) (value >> 8);
4275 buffer[2]=(unsigned char) (value >> 16);
4276 buffer[3]=(unsigned char) (value >> 24);
4277 return(WriteBlobStream(image,4,buffer));
4281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4285 + W r i t e B l o b L S B S h o r t %
4289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4291 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4292 % least-significant byte first order.
4294 % The format of the WriteBlobLSBShort method is:
4296 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4298 % A description of each parameter follows.
4300 % o image: the image.
4302 % o value: Specifies the value to write.
4305 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4310 assert(image != (Image *) NULL);
4311 assert(image->signature == MagickSignature);
4312 buffer[0]=(unsigned char) value;
4313 buffer[1]=(unsigned char) (value >> 8);
4314 return(WriteBlobStream(image,2,buffer));
4318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4322 + W r i t e B l o b M S B L o n g %
4326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4328 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4329 % most-significant byte first order.
4331 % The format of the WriteBlobMSBLong method is:
4333 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4335 % A description of each parameter follows.
4337 % o value: Specifies the value to write.
4339 % o image: the image.
4342 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4347 assert(image != (Image *) NULL);
4348 assert(image->signature == MagickSignature);
4349 buffer[0]=(unsigned char) (value >> 24);
4350 buffer[1]=(unsigned char) (value >> 16);
4351 buffer[2]=(unsigned char) (value >> 8);
4352 buffer[3]=(unsigned char) value;
4353 return(WriteBlobStream(image,4,buffer));
4357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4361 + W r i t e B l o b M S B L o n g L o n g %
4365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4367 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4368 % most-significant byte first order.
4370 % The format of the WriteBlobMSBLongLong method is:
4372 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4374 % A description of each parameter follows.
4376 % o value: Specifies the value to write.
4378 % o image: the image.
4381 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4382 const MagickSizeType value)
4387 assert(image != (Image *) NULL);
4388 assert(image->signature == MagickSignature);
4389 buffer[0]=(unsigned char) (value >> 56);
4390 buffer[1]=(unsigned char) (value >> 48);
4391 buffer[2]=(unsigned char) (value >> 40);
4392 buffer[3]=(unsigned char) (value >> 32);
4393 buffer[4]=(unsigned char) (value >> 24);
4394 buffer[5]=(unsigned char) (value >> 16);
4395 buffer[6]=(unsigned char) (value >> 8);
4396 buffer[7]=(unsigned char) value;
4397 return(WriteBlobStream(image,8,buffer));
4401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4405 + W r i t e B l o b M S B S h o r t %
4409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4411 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4412 % most-significant byte first order.
4414 % The format of the WriteBlobMSBShort method is:
4416 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4418 % A description of each parameter follows.
4420 % o value: Specifies the value to write.
4422 % o file: Specifies the file to write the data to.
4425 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4430 assert(image != (Image *) NULL);
4431 assert(image->signature == MagickSignature);
4432 buffer[0]=(unsigned char) (value >> 8);
4433 buffer[1]=(unsigned char) value;
4434 return(WriteBlobStream(image,2,buffer));
4438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4442 + W r i t e B l o b S t r i n g %
4446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4448 % WriteBlobString() write a string to a blob. It returns the number of
4449 % characters written.
4451 % The format of the WriteBlobString method is:
4453 % ssize_t WriteBlobString(Image *image,const char *string)
4455 % A description of each parameter follows.
4457 % o image: the image.
4459 % o string: Specifies the string to write.
4462 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4464 assert(image != (Image *) NULL);
4465 assert(image->signature == MagickSignature);
4466 assert(string != (const char *) NULL);
4467 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));