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 "magick/studio.h"
44 #include "magick/blob.h"
45 #include "magick/blob-private.h"
46 #include "magick/cache.h"
47 #include "magick/client.h"
48 #include "magick/constitute.h"
49 #include "magick/delegate.h"
50 #include "magick/exception.h"
51 #include "magick/exception-private.h"
52 #include "magick/image-private.h"
53 #include "magick/list.h"
54 #include "magick/log.h"
55 #include "magick/magick.h"
56 #include "magick/memory_.h"
57 #include "magick/policy.h"
58 #include "magick/resource_.h"
59 #include "magick/semaphore.h"
60 #include "magick/string_.h"
61 #include "magick/string-private.h"
62 #include "magick/token.h"
63 #include "magick/utility.h"
64 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
65 # include <sys/mman.h>
67 #if defined(MAGICKCORE_ZLIB_DELEGATE)
70 #if defined(MAGICKCORE_BZLIB_DELEGATE)
77 #define MagickMaxBlobExtent 65541
78 #if defined(MAGICKCORE_HAVE_FSEEKO)
82 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
83 # define MAP_ANONYMOUS MAP_ANON
85 #if !defined(MAP_FAILED)
86 #define MAP_FAILED ((void *) -1)
93 #define _O_BINARY O_BINARY
151 Forward declarations.
157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161 + A t t a c h B l o b %
165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 % AttachBlob() attaches a blob to the BlobInfo structure.
169 % The format of the AttachBlob method is:
171 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
173 % A description of each parameter follows:
175 % o blob_info: Specifies a pointer to a BlobInfo structure.
177 % o blob: the address of a character stream in one of the image formats
178 % understood by ImageMagick.
180 % o length: This size_t integer reflects the length in bytes of the blob.
183 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
186 assert(blob_info != (BlobInfo *) NULL);
187 if (blob_info->debug != MagickFalse)
188 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
189 blob_info->length=length;
190 blob_info->extent=length;
191 blob_info->quantum=(size_t) MagickMaxBlobExtent;
193 blob_info->type=BlobStream;
194 blob_info->file=(FILE *) NULL;
195 blob_info->data=(unsigned char *) blob;
196 blob_info->mapped=MagickFalse;
200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 + B l o b T o F i l e %
208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
211 % occurs otherwise MagickTrue.
213 % The format of the BlobToFile method is:
215 % MagickBooleanType BlobToFile(char *filename,const void *blob,
216 % const size_t length,ExceptionInfo *exception)
218 % A description of each parameter follows:
220 % o filename: Write the blob to this file.
222 % o blob: the address of a blob.
224 % o length: This length in bytes of the blob.
226 % o exception: return any errors or warnings in this structure.
230 static inline size_t MagickMin(const size_t x,const size_t y)
237 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
238 const size_t length,ExceptionInfo *exception)
249 assert(filename != (const char *) NULL);
250 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
251 assert(blob != (const void *) NULL);
252 if (*filename == '\0')
253 file=AcquireUniqueFileResource(filename);
255 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
258 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
261 for (i=0; i < length; i+=count)
263 count=(ssize_t) write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
273 if ((file == -1) || (i < length))
275 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286 % B l o b T o I m a g e %
290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292 % BlobToImage() implements direct to memory image formats. It returns the
295 % The format of the BlobToImage method is:
297 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
298 % const size_t length,ExceptionInfo *exception)
300 % A description of each parameter follows:
302 % o image_info: the image info.
304 % o blob: the address of a character stream in one of the image formats
305 % understood by ImageMagick.
307 % o length: This size_t integer reflects the length in bytes of the blob.
309 % o exception: return any errors or warnings in this structure.
312 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
313 const size_t length,ExceptionInfo *exception)
328 assert(image_info != (ImageInfo *) NULL);
329 assert(image_info->signature == MagickSignature);
330 if (image_info->debug != MagickFalse)
331 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
332 image_info->filename);
333 assert(exception != (ExceptionInfo *) NULL);
334 if ((blob == (const void *) NULL) || (length == 0))
336 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
337 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
338 return((Image *) NULL);
340 blob_info=CloneImageInfo(image_info);
341 blob_info->blob=(void *) blob;
342 blob_info->length=length;
343 if (*blob_info->magick == '\0')
344 (void) SetImageInfo(blob_info,0,exception);
345 magick_info=GetMagickInfo(blob_info->magick,exception);
346 if (magick_info == (const MagickInfo *) NULL)
348 blob_info=DestroyImageInfo(blob_info);
349 (void) ThrowMagickException(exception,GetMagickModule(),
350 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
351 image_info->filename);
352 return((Image *) NULL);
354 if (GetMagickBlobSupport(magick_info) != MagickFalse)
357 Native blob support for this image format.
359 (void) CopyMagickString(blob_info->filename,image_info->filename,
361 (void) CopyMagickString(blob_info->magick,image_info->magick,
363 image=ReadImage(blob_info,exception);
364 if (image != (Image *) NULL)
365 (void) DetachBlob(image->blob);
366 blob_info=DestroyImageInfo(blob_info);
370 Write blob to a temporary file on disk.
372 blob_info->blob=(void *) NULL;
374 *blob_info->filename='\0';
375 status=BlobToFile(blob_info->filename,blob,length,exception);
376 if (status == MagickFalse)
378 (void) RelinquishUniqueFileResource(blob_info->filename);
379 blob_info=DestroyImageInfo(blob_info);
380 return((Image *) NULL);
382 clone_info=CloneImageInfo(blob_info);
383 (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
384 blob_info->magick,blob_info->filename);
385 image=ReadImage(clone_info,exception);
386 clone_info=DestroyImageInfo(clone_info);
387 (void) RelinquishUniqueFileResource(blob_info->filename);
388 blob_info=DestroyImageInfo(blob_info);
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 + C l o n e B l o b I n f o %
401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
404 % blob info is NULL, a new one.
406 % The format of the CloneBlobInfo method is:
408 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
410 % A description of each parameter follows:
412 % o blob_info: the blob info.
415 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
420 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
421 if (clone_info == (BlobInfo *) NULL)
422 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
423 GetBlobInfo(clone_info);
424 if (blob_info == (BlobInfo *) NULL)
426 clone_info->length=blob_info->length;
427 clone_info->extent=blob_info->extent;
428 clone_info->synchronize=blob_info->synchronize;
429 clone_info->quantum=blob_info->quantum;
430 clone_info->mapped=blob_info->mapped;
431 clone_info->eof=blob_info->eof;
432 clone_info->offset=blob_info->offset;
433 clone_info->size=blob_info->size;
434 clone_info->exempt=blob_info->exempt;
435 clone_info->status=blob_info->status;
436 clone_info->temporary=blob_info->temporary;
437 clone_info->type=blob_info->type;
438 clone_info->file=blob_info->file;
439 clone_info->properties=blob_info->properties;
440 clone_info->stream=blob_info->stream;
441 clone_info->data=blob_info->data;
442 clone_info->debug=IsEventLogging();
443 clone_info->reference_count=1;
448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
452 + C l o s e B l o b %
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458 % CloseBlob() closes a stream associated with the image.
460 % The format of the CloseBlob method is:
462 % MagickBooleanType CloseBlob(Image *image)
464 % A description of each parameter follows:
466 % o image: the image.
469 MagickExport MagickBooleanType CloseBlob(Image *image)
477 assert(image != (Image *) NULL);
478 assert(image->signature == MagickSignature);
479 if (image->debug != MagickFalse)
480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
481 assert(image->blob != (BlobInfo *) NULL);
482 if (image->blob->type == UndefinedStream)
484 if (image->blob->synchronize != MagickFalse)
486 image->blob->size=GetBlobSize(image);
487 image->extent=image->blob->size;
488 image->blob->eof=MagickFalse;
489 if (image->blob->exempt != MagickFalse)
491 image->blob->type=UndefinedStream;
495 switch (image->blob->type)
497 case UndefinedStream:
503 status=ferror(image->blob->file);
508 #if defined(MAGICKCORE_ZLIB_DELEGATE)
509 (void) gzerror(image->blob->file,&status);
515 #if defined(MAGICKCORE_BZLIB_DELEGATE)
516 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
524 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
525 switch (image->blob->type)
527 case UndefinedStream:
532 if (image->blob->synchronize != MagickFalse)
534 status=fflush(image->blob->file);
535 status=fsync(fileno(image->blob->file));
537 status=fclose(image->blob->file);
542 #if defined(MAGICKCORE_HAVE_PCLOSE)
543 status=pclose(image->blob->file);
549 #if defined(MAGICKCORE_ZLIB_DELEGATE)
550 status=gzclose(image->blob->file);
556 #if defined(MAGICKCORE_BZLIB_DELEGATE)
557 BZ2_bzclose((BZFILE *) image->blob->file);
565 if (image->blob->file != (FILE *) NULL)
567 if (image->blob->synchronize != MagickFalse)
568 (void) fsync(fileno(image->blob->file));
569 status=fclose(image->blob->file);
574 (void) DetachBlob(image->blob);
575 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
576 return(image->blob->status);
580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584 + D e s t r o y B l o b %
588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590 % DestroyBlob() deallocates memory associated with a blob.
592 % The format of the DestroyBlob method is:
594 % void DestroyBlob(Image *image)
596 % A description of each parameter follows:
598 % o image: the image.
601 MagickExport void DestroyBlob(Image *image)
606 assert(image != (Image *) NULL);
607 assert(image->signature == MagickSignature);
608 if (image->debug != MagickFalse)
609 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
610 assert(image->blob != (BlobInfo *) NULL);
611 assert(image->blob->signature == MagickSignature);
613 LockSemaphoreInfo(image->blob->semaphore);
614 image->blob->reference_count--;
615 assert(image->blob->reference_count >= 0);
616 if (image->blob->reference_count == 0)
618 UnlockSemaphoreInfo(image->blob->semaphore);
619 if (destroy == MagickFalse)
621 (void) CloseBlob(image);
622 if (image->blob->mapped != MagickFalse)
623 (void) UnmapBlob(image->blob->data,image->blob->length);
624 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
625 DestroySemaphoreInfo(&image->blob->semaphore);
626 image->blob->signature=(~MagickSignature);
627 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635 + D e t a c h B l o b %
639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641 % DetachBlob() detaches a blob from the BlobInfo structure.
643 % The format of the DetachBlob method is:
645 % unsigned char *DetachBlob(BlobInfo *blob_info)
647 % A description of each parameter follows:
649 % o blob_info: Specifies a pointer to a BlobInfo structure.
652 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
657 assert(blob_info != (BlobInfo *) NULL);
658 if (blob_info->debug != MagickFalse)
659 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
660 if (blob_info->mapped != MagickFalse)
661 (void) UnmapBlob(blob_info->data,blob_info->length);
662 blob_info->mapped=MagickFalse;
665 blob_info->eof=MagickFalse;
666 blob_info->exempt=MagickFalse;
667 blob_info->type=UndefinedStream;
668 blob_info->file=(FILE *) NULL;
669 data=blob_info->data;
670 blob_info->data=(unsigned char *) NULL;
671 blob_info->stream=(StreamHandler) NULL;
676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
680 + D i s c a r d B l o b B y t e s %
684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
686 % DiscardBlobBytes() discards bytes in a blob.
688 % The format of the DiscardBlobBytes method is:
690 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
692 % A description of each parameter follows.
694 % o image: the image.
696 % o length: the number of bytes to skip.
700 static inline const unsigned char *ReadBlobStream(Image *image,
701 const size_t length,unsigned char *data,ssize_t *count)
703 assert(count != (ssize_t *) NULL);
704 assert(image->blob != (BlobInfo *) NULL);
705 if (image->blob->type != BlobStream)
707 *count=ReadBlob(image,length,data);
710 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
713 image->blob->eof=MagickTrue;
716 data=image->blob->data+image->blob->offset;
717 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
718 image->blob->offset));
719 image->blob->offset+=(*count);
720 if (*count != (ssize_t) length)
721 image->blob->eof=MagickTrue;
725 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
740 assert(image != (Image *) NULL);
741 assert(image->signature == MagickSignature);
743 for (i=0; i < (ssize_t) length; i+=count)
745 quantum=MagickMin(length-i,sizeof(buffer));
746 (void) ReadBlobStream(image,quantum,buffer,&count);
754 return(i < (ssize_t) length ? MagickFalse : MagickTrue);
758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762 + D u p l i c a t e s B l o b %
766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768 % DuplicateBlob() duplicates a blob descriptor.
770 % The format of the DuplicateBlob method is:
772 % void DuplicateBlob(Image *image,const Image *duplicate)
774 % A description of each parameter follows:
776 % o image: the image.
778 % o duplicate: the duplicate image.
781 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
783 assert(image != (Image *) NULL);
784 assert(image->signature == MagickSignature);
785 if (image->debug != MagickFalse)
786 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
787 assert(duplicate != (Image *) NULL);
788 assert(duplicate->signature == MagickSignature);
790 image->blob=ReferenceBlob(duplicate->blob);
794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804 % EOFBlob() returns a non-zero value when EOF has been detected reading from
807 % The format of the EOFBlob method is:
809 % int EOFBlob(const Image *image)
811 % A description of each parameter follows:
813 % o image: the image.
816 MagickExport int EOFBlob(const Image *image)
818 assert(image != (Image *) NULL);
819 assert(image->signature == MagickSignature);
820 if (image->debug != MagickFalse)
821 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
822 assert(image->blob != (BlobInfo *) NULL);
823 assert(image->blob->type != UndefinedStream);
824 switch (image->blob->type)
826 case UndefinedStream:
832 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
837 image->blob->eof=MagickFalse;
842 #if defined(MAGICKCORE_BZLIB_DELEGATE)
847 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
848 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
854 image->blob->eof=MagickFalse;
860 return((int) image->blob->eof);
864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868 + F i l e T o B l o b %
872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
874 % FileToBlob() returns the contents of a file as a buffer terminated with
875 % the '\0' character. The length of the buffer (not including the extra
876 % terminating '\0' character) is returned via the 'length' parameter. Free
877 % the buffer with RelinquishMagickMemory().
879 % The format of the FileToBlob method is:
881 % unsigned char *FileToBlob(const char *filename,const size_t extent,
882 % size_t *length,ExceptionInfo *exception)
884 % A description of each parameter follows:
886 % o blob: FileToBlob() returns the contents of a file as a blob. If
887 % an error occurs NULL is returned.
889 % o filename: the filename.
891 % o extent: The maximum length of the blob.
893 % o length: On return, this reflects the actual length of the blob.
895 % o exception: return any errors or warnings in this structure.
898 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
899 size_t *length,ExceptionInfo *exception)
919 assert(filename != (const char *) NULL);
920 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
921 assert(exception != (ExceptionInfo *) NULL);
924 if (LocaleCompare(filename,"-") != 0)
925 file=open(filename,O_RDONLY | O_BINARY);
928 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
929 return((unsigned char *) NULL);
931 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
933 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
942 Stream is not seekable.
944 quantum=(size_t) MagickMaxBufferExtent;
945 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
946 quantum=MagickMin((size_t) file_info.st_size,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=MagickMin(i+count,extent);
985 *length=MagickMin((size_t) offset,extent);
986 blob=(unsigned char *) NULL;
987 if (~(*length) >= MaxTextExtent)
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) MagickSeek(file,0,SEEK_SET);
1006 for (i=0; i < *length; i+=count)
1008 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
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(filename,O_RDONLY | O_BINARY);
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=MagickMin((size_t) 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 MagickExport 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 MagickExport 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 MagickExport 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 MagickExport 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);
1509 if ((status == MagickFalse) || (image->blob->length == 0))
1510 InheritException(exception,&image->exception);
1513 *length=image->blob->length;
1514 blob=DetachBlob(image->blob);
1515 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1523 unique[MaxTextExtent];
1529 Write file to disk in blob image format.
1531 file=AcquireUniqueFileResource(unique);
1534 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1535 image_info->filename);
1539 blob_info->file=fdopen(file,"wb");
1540 if (blob_info->file != (FILE *) NULL)
1542 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1543 image->magick,unique);
1544 status=WriteImage(blob_info,image);
1545 (void) fclose(blob_info->file);
1546 if (status == MagickFalse)
1547 InheritException(exception,&image->exception);
1549 blob=FileToBlob(image->filename,~0UL,length,exception);
1551 (void) RelinquishUniqueFileResource(unique);
1554 blob_info=DestroyImageInfo(blob_info);
1559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1563 % I m a g e T o F i l e %
1567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1569 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1570 % occurs otherwise MagickTrue.
1572 % The format of the ImageToFile method is:
1574 % MagickBooleanType ImageToFile(Image *image,char *filename,
1575 % ExceptionInfo *exception)
1577 % A description of each parameter follows:
1579 % o image: the image.
1581 % o filename: Write the image to this file.
1583 % o exception: return any errors or warnings in this structure.
1586 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1587 ExceptionInfo *exception)
1592 register const unsigned char
1611 assert(image != (Image *) NULL);
1612 assert(image->signature == MagickSignature);
1613 assert(image->blob != (BlobInfo *) NULL);
1614 assert(image->blob->type != UndefinedStream);
1615 if (image->debug != MagickFalse)
1616 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1617 assert(filename != (const char *) NULL);
1618 if (*filename == '\0')
1619 file=AcquireUniqueFileResource(filename);
1621 if (LocaleCompare(filename,"-") == 0)
1622 file=fileno(stdout);
1624 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1627 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1628 return(MagickFalse);
1630 quantum=(size_t) MagickMaxBufferExtent;
1631 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1632 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1633 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1634 if (buffer == (unsigned char *) NULL)
1637 (void) ThrowMagickException(exception,GetMagickModule(),
1638 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1639 return(MagickFalse);
1642 p=ReadBlobStream(image,quantum,buffer,&count);
1643 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1645 length=(size_t) count;
1646 for (i=0; i < length; i+=count)
1648 count=write(file,p+i,(size_t) (length-i));
1659 if (LocaleCompare(filename,"-") != 0)
1661 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1662 if ((file == -1) || (i < length))
1664 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1665 return(MagickFalse);
1671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1675 % I m a g e s T o B l o b %
1679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1681 % ImagesToBlob() implements direct to memory image formats. It returns the
1682 % image sequence as a blob and its length. The magick member of the ImageInfo
1683 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1685 % Note, some image formats do not permit multiple images to the same image
1686 % stream (e.g. JPEG). in this instance, just the first image of the
1687 % sequence is returned as a blob.
1689 % The format of the ImagesToBlob method is:
1691 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1692 % size_t *length,ExceptionInfo *exception)
1694 % A description of each parameter follows:
1696 % o image_info: the image info.
1698 % o images: the image list.
1700 % o length: This pointer to a size_t integer sets the initial length of the
1701 % blob. On return, it reflects the actual length of the blob.
1703 % o exception: return any errors or warnings in this structure.
1706 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1707 Image *images,size_t *length,ExceptionInfo *exception)
1721 assert(image_info != (const ImageInfo *) NULL);
1722 assert(image_info->signature == MagickSignature);
1723 if (image_info->debug != MagickFalse)
1724 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1725 image_info->filename);
1726 assert(images != (Image *) NULL);
1727 assert(images->signature == MagickSignature);
1728 assert(exception != (ExceptionInfo *) NULL);
1730 blob=(unsigned char *) NULL;
1731 blob_info=CloneImageInfo(image_info);
1732 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1734 if (*blob_info->magick != '\0')
1735 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1736 if (blob_info->adjoin == MagickFalse)
1738 blob_info=DestroyImageInfo(blob_info);
1739 return(ImageToBlob(image_info,images,length,exception));
1741 magick_info=GetMagickInfo(images->magick,exception);
1742 if (magick_info == (const MagickInfo *) NULL)
1744 (void) ThrowMagickException(exception,GetMagickModule(),
1745 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1749 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1750 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1753 Native blob support for this images format.
1755 blob_info->length=0;
1756 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1757 sizeof(unsigned char));
1758 if (blob_info->blob == (void *) NULL)
1759 (void) ThrowMagickException(exception,GetMagickModule(),
1760 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1763 images->blob->exempt=MagickTrue;
1764 *images->filename='\0';
1765 status=WriteImages(blob_info,images,images->filename,exception);
1766 if ((status == MagickFalse) || (images->blob->length == 0))
1767 InheritException(exception,&images->exception);
1770 *length=images->blob->length;
1771 blob=DetachBlob(images->blob);
1772 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1780 filename[MaxTextExtent],
1781 unique[MaxTextExtent];
1787 Write file to disk in blob images format.
1789 file=AcquireUniqueFileResource(unique);
1792 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1793 image_info->filename);
1797 blob_info->file=fdopen(file,"wb");
1798 if (blob_info->file != (FILE *) NULL)
1800 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1801 images->magick,unique);
1802 status=WriteImages(blob_info,images,filename,exception);
1803 (void) fclose(blob_info->file);
1804 if (status == MagickFalse)
1805 InheritException(exception,&images->exception);
1807 blob=FileToBlob(images->filename,~0UL,length,exception);
1809 (void) RelinquishUniqueFileResource(unique);
1812 blob_info=DestroyImageInfo(blob_info);
1816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1820 % I n j e c t I m a g e B l o b %
1824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1826 % InjectImageBlob() injects the image with a copy of itself in the specified
1827 % format (e.g. inject JPEG into a PDF image).
1829 % The format of the InjectImageBlob method is:
1831 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1832 % Image *image,Image *inject_image,const char *format,
1833 % ExceptionInfo *exception)
1835 % A description of each parameter follows:
1837 % o image_info: the image info..
1839 % o image: the image.
1841 % o inject_image: inject into the image stream.
1843 % o format: the image format.
1845 % o exception: return any errors or warnings in this structure.
1848 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1849 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1852 filename[MaxTextExtent];
1885 Write inject image to a temporary file.
1887 assert(image_info != (ImageInfo *) NULL);
1888 assert(image_info->signature == MagickSignature);
1889 assert(image != (Image *) NULL);
1890 assert(image->signature == MagickSignature);
1891 if (image->debug != MagickFalse)
1892 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1893 assert(inject_image != (Image *) NULL);
1894 assert(inject_image->signature == MagickSignature);
1895 assert(exception != (ExceptionInfo *) NULL);
1896 unique_file=(FILE *) NULL;
1897 file=AcquireUniqueFileResource(filename);
1899 unique_file=fdopen(file,"wb");
1900 if ((file == -1) || (unique_file == (FILE *) NULL))
1902 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1903 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1905 return(MagickFalse);
1907 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1908 if (byte_image == (Image *) NULL)
1910 (void) fclose(unique_file);
1911 (void) RelinquishUniqueFileResource(filename);
1912 return(MagickFalse);
1914 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1916 DestroyBlob(byte_image);
1917 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1918 write_info=CloneImageInfo(image_info);
1919 SetImageInfoFile(write_info,unique_file);
1920 status=WriteImage(write_info,byte_image);
1921 write_info=DestroyImageInfo(write_info);
1922 byte_image=DestroyImage(byte_image);
1923 (void) fclose(unique_file);
1924 if (status == MagickFalse)
1926 (void) RelinquishUniqueFileResource(filename);
1927 return(MagickFalse);
1930 Inject into image stream.
1932 file=open(filename,O_RDONLY | O_BINARY);
1935 (void) RelinquishUniqueFileResource(filename);
1936 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1937 image_info->filename);
1938 return(MagickFalse);
1940 quantum=(size_t) MagickMaxBufferExtent;
1941 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1942 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1943 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1944 if (buffer == (unsigned char *) NULL)
1946 (void) RelinquishUniqueFileResource(filename);
1947 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1950 for (i=0; ; i+=count)
1952 count=(ssize_t) read(file,buffer,quantum);
1959 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1964 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1965 (void) RelinquishUniqueFileResource(filename);
1966 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1975 + I s B l o b E x e m p t %
1979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1981 % IsBlobExempt() returns true if the blob is exempt.
1983 % The format of the IsBlobExempt method is:
1985 % MagickBooleanType IsBlobExempt(const Image *image)
1987 % A description of each parameter follows:
1989 % o image: the image.
1992 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1994 assert(image != (const Image *) NULL);
1995 assert(image->signature == MagickSignature);
1996 if (image->debug != MagickFalse)
1997 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1998 return(image->blob->exempt);
2002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2006 + I s B l o b S e e k a b l e %
2010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2012 % IsBlobSeekable() returns true if the blob is seekable.
2014 % The format of the IsBlobSeekable method is:
2016 % MagickBooleanType IsBlobSeekable(const Image *image)
2018 % A description of each parameter follows:
2020 % o image: the image.
2023 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2028 assert(image != (const Image *) NULL);
2029 assert(image->signature == MagickSignature);
2030 if (image->debug != MagickFalse)
2031 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2032 seekable=(image->blob->type == FileStream) ||
2033 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2042 + I s B l o b T e m p o r a r y %
2046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2048 % IsBlobTemporary() returns true if the blob is temporary.
2050 % The format of the IsBlobTemporary method is:
2052 % MagickBooleanType IsBlobTemporary(const Image *image)
2054 % A description of each parameter follows:
2056 % o image: the image.
2059 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2061 assert(image != (const Image *) NULL);
2062 assert(image->signature == MagickSignature);
2063 if (image->debug != MagickFalse)
2064 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2065 return(image->blob->temporary);
2069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2079 % MapBlob() creates a mapping from a file to a binary large object.
2081 % The format of the MapBlob method is:
2083 % unsigned char *MapBlob(int file,const MapMode mode,
2084 % const MagickOffsetType offset,const size_t length)
2086 % A description of each parameter follows:
2088 % o file: map this file descriptor.
2090 % o mode: ReadMode, WriteMode, or IOMode.
2092 % o offset: starting at this offset within the file.
2094 % o length: the length of the mapping is returned in this pointer.
2097 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2098 const MagickOffsetType offset,const size_t length)
2100 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2113 #if defined(MAP_ANONYMOUS)
2114 flags|=MAP_ANONYMOUS;
2116 return((unsigned char *) NULL);
2123 protection=PROT_READ;
2125 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2131 protection=PROT_WRITE;
2133 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2135 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2136 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2137 POSIX_MADV_WILLNEED);
2143 protection=PROT_READ | PROT_WRITE;
2145 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2150 if (map == (unsigned char *) MAP_FAILED)
2151 return((unsigned char *) NULL);
2158 return((unsigned char *) NULL);
2163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2167 + M S B O r d e r L o n g %
2171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2173 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2174 % most-significant byte first.
2176 % The format of the MSBOrderLong method is:
2178 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2180 % A description of each parameter follows.
2182 % o buffer: Specifies a pointer to a buffer of integers.
2184 % o length: Specifies the length of the buffer.
2187 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2192 register unsigned char
2196 assert(buffer != (unsigned char *) NULL);
2203 *buffer++=(unsigned char) c;
2207 *buffer++=(unsigned char) c;
2213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2217 + M S B O r d e r S h o r t %
2221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2223 % MSBOrderShort() converts a least-significant byte first buffer of integers
2224 % to most-significant byte first.
2226 % The format of the MSBOrderShort method is:
2228 % void MSBOrderShort(unsigned char *p,const size_t length)
2230 % A description of each parameter follows.
2232 % o p: Specifies a pointer to a buffer of integers.
2234 % o length: Specifies the length of the buffer.
2237 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2242 register unsigned char
2245 assert(p != (unsigned char *) NULL);
2252 *p++=(unsigned char) c;
2257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2267 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2268 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2269 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2270 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2271 % from a system command.
2273 % The format of the OpenBlob method is:
2275 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2276 % const BlobMode mode,ExceptionInfo *exception)
2278 % A description of each parameter follows:
2280 % o image_info: the image info.
2282 % o image: the image.
2284 % o mode: the mode for opening the file.
2287 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2288 Image *image,const BlobMode mode,ExceptionInfo *exception)
2291 extension[MaxTextExtent],
2292 filename[MaxTextExtent];
2303 assert(image_info != (ImageInfo *) NULL);
2304 assert(image_info->signature == MagickSignature);
2305 if (image_info->debug != MagickFalse)
2306 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2307 image_info->filename);
2308 assert(image != (Image *) NULL);
2309 assert(image->signature == MagickSignature);
2310 if (image_info->blob != (void *) NULL)
2312 if (image_info->stream != (StreamHandler) NULL)
2313 image->blob->stream=(StreamHandler) image_info->stream;
2314 AttachBlob(image->blob,image_info->blob,image_info->length);
2317 (void) DetachBlob(image->blob);
2320 default: type="r"; break;
2321 case ReadBlobMode: type="r"; break;
2322 case ReadBinaryBlobMode: type="rb"; break;
2323 case WriteBlobMode: type="w"; break;
2324 case WriteBinaryBlobMode: type="w+b"; break;
2325 case AppendBlobMode: type="a"; break;
2326 case AppendBinaryBlobMode: type="a+b"; break;
2329 image->blob->synchronize=image_info->synchronize;
2330 if (image_info->stream != (StreamHandler) NULL)
2332 image->blob->stream=(StreamHandler) image_info->stream;
2335 image->blob->type=FifoStream;
2343 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2344 rights=ReadPolicyRights;
2346 rights=WritePolicyRights;
2347 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2350 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2351 "NotAuthorized","`%s'",filename);
2352 return(MagickFalse);
2354 if ((LocaleCompare(filename,"-") == 0) ||
2355 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2357 image->blob->file=(*type == 'r') ? stdin : stdout;
2358 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2359 if (strchr(type,'b') != (char *) NULL)
2360 setmode(_fileno(image->blob->file),_O_BINARY);
2362 image->blob->type=StandardStream;
2363 image->blob->exempt=MagickTrue;
2366 if (LocaleNCompare(filename,"fd:",3) == 0)
2369 mode[MaxTextExtent];
2373 image->blob->file=fdopen(StringToLong(filename+3),mode);
2374 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2375 if (strchr(type,'b') != (char *) NULL)
2376 setmode(_fileno(image->blob->file),_O_BINARY);
2378 image->blob->type=StandardStream;
2379 image->blob->exempt=MagickTrue;
2382 #if defined(MAGICKCORE_HAVE_POPEN)
2383 if (*filename == '|')
2386 mode[MaxTextExtent];
2389 Pipe image to or from a system command.
2391 #if defined(SIGPIPE)
2393 (void) signal(SIGPIPE,SIG_IGN);
2397 image->blob->file=(FILE *) popen(filename+1,mode);
2398 if (image->blob->file == (FILE *) NULL)
2400 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2401 return(MagickFalse);
2403 image->blob->type=PipeStream;
2404 image->blob->exempt=MagickTrue;
2408 status=GetPathAttributes(filename,&image->blob->properties);
2409 #if defined(S_ISFIFO)
2410 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2412 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2413 if (image->blob->file == (FILE *) NULL)
2415 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2416 return(MagickFalse);
2418 image->blob->type=FileStream;
2419 image->blob->exempt=MagickTrue;
2423 GetPathComponent(image->filename,ExtensionPath,extension);
2426 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2427 if ((image_info->adjoin == MagickFalse) ||
2428 (IsGlob(filename) != MagickFalse))
2431 Form filename for multi-part images.
2433 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2434 image->scene,filename);
2435 if ((LocaleCompare(filename,image->filename) == 0) &&
2436 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2437 (GetNextImageInList(image) != (Image *) NULL)))
2440 path[MaxTextExtent];
2442 GetPathComponent(image->filename,RootPath,path);
2443 if (*extension == '\0')
2444 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2445 path,(double) image->scene);
2447 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g.%s",
2448 path,(double) image->scene,extension);
2450 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2451 #if defined(macintosh)
2452 SetApplicationType(filename,image_info->magick,'8BIM');
2456 if (image_info->file != (FILE *) NULL)
2458 image->blob->file=image_info->file;
2459 image->blob->type=FileStream;
2460 image->blob->exempt=MagickTrue;
2465 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2466 if (image->blob->file != (FILE *) NULL)
2474 image->blob->type=FileStream;
2475 #if defined(MAGICKCORE_HAVE_SETVBUF)
2476 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2478 (void) ResetMagickMemory(magick,0,sizeof(magick));
2479 count=fread(magick,1,sizeof(magick),image->blob->file);
2480 (void) rewind(image->blob->file);
2481 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2482 " read %.20g magic header bytes",(double) count);
2483 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2484 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2485 ((int) magick[2] == 0x08))
2487 (void) fclose(image->blob->file);
2488 image->blob->file=(FILE *) gzopen(filename,type);
2489 if (image->blob->file != (FILE *) NULL)
2490 image->blob->type=ZipStream;
2493 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2494 if (strncmp((char *) magick,"BZh",3) == 0)
2496 (void) fclose(image->blob->file);
2497 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2498 if (image->blob->file != (FILE *) NULL)
2499 image->blob->type=BZipStream;
2502 if (image->blob->type == FileStream)
2513 sans_exception=AcquireExceptionInfo();
2514 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2515 sans_exception=DestroyExceptionInfo(sans_exception);
2516 properties=(&image->blob->properties);
2517 if ((magick_info != (const MagickInfo *) NULL) &&
2518 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2519 (properties->st_size <= MagickMaxBufferExtent))
2527 length=(size_t) properties->st_size;
2528 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2529 if (blob != (void *) NULL)
2532 Format supports blobs-- use memory-mapped I/O.
2534 if (image_info->file != (FILE *) NULL)
2535 image->blob->exempt=MagickFalse;
2538 (void) fclose(image->blob->file);
2539 image->blob->file=(FILE *) NULL;
2541 AttachBlob(image->blob,blob,length);
2542 image->blob->mapped=MagickTrue;
2549 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2550 if ((LocaleCompare(extension,"Z") == 0) ||
2551 (LocaleCompare(extension,"gz") == 0) ||
2552 (LocaleCompare(extension,"wmz") == 0) ||
2553 (LocaleCompare(extension,"svgz") == 0))
2555 if (mode == WriteBinaryBlobMode)
2557 image->blob->file=(FILE *) gzopen(filename,type);
2558 if (image->blob->file != (FILE *) NULL)
2559 image->blob->type=ZipStream;
2563 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2564 if (LocaleCompare(extension,".bz2") == 0)
2566 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2567 if (image->blob->file != (FILE *) NULL)
2568 image->blob->type=BZipStream;
2573 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2574 if (image->blob->file != (FILE *) NULL)
2576 image->blob->type=FileStream;
2577 #if defined(MAGICKCORE_HAVE_SETVBUF)
2578 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2583 image->blob->status=MagickFalse;
2584 if (image->blob->type != UndefinedStream)
2585 image->blob->size=GetBlobSize(image);
2588 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2589 return(MagickFalse);
2595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2605 % PingBlob() returns all the attributes of an image or image sequence except
2606 % for the pixels. It is much faster and consumes far less memory than
2607 % BlobToImage(). On failure, a NULL image is returned and exception
2608 % describes the reason for the failure.
2610 % The format of the PingBlob method is:
2612 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2613 % const size_t length,ExceptionInfo *exception)
2615 % A description of each parameter follows:
2617 % o image_info: the image info.
2619 % o blob: the address of a character stream in one of the image formats
2620 % understood by ImageMagick.
2622 % o length: This size_t integer reflects the length in bytes of the blob.
2624 % o exception: return any errors or warnings in this structure.
2628 #if defined(__cplusplus) || defined(c_plusplus)
2632 static size_t PingStream(const Image *magick_unused(image),
2633 const void *magick_unused(pixels),const size_t columns)
2638 #if defined(__cplusplus) || defined(c_plusplus)
2642 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2643 const size_t length,ExceptionInfo *exception)
2651 assert(image_info != (ImageInfo *) NULL);
2652 assert(image_info->signature == MagickSignature);
2653 if (image_info->debug != MagickFalse)
2654 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2655 image_info->filename);
2656 assert(exception != (ExceptionInfo *) NULL);
2657 if ((blob == (const void *) NULL) || (length == 0))
2659 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2660 "UnrecognizedImageFormat","`%s'",image_info->magick);
2661 return((Image *) NULL);
2663 ping_info=CloneImageInfo(image_info);
2664 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2665 if (ping_info->blob == (const void *) NULL)
2667 (void) ThrowMagickException(exception,GetMagickModule(),
2668 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2669 return((Image *) NULL);
2671 (void) memcpy(ping_info->blob,blob,length);
2672 ping_info->length=length;
2673 ping_info->ping=MagickTrue;
2674 image=ReadStream(ping_info,&PingStream,exception);
2675 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2676 ping_info=DestroyImageInfo(ping_info);
2681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2691 % ReadBlob() reads data from the blob or image file and returns it. It
2692 % returns the number of bytes read.
2694 % The format of the ReadBlob method is:
2696 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2698 % A description of each parameter follows:
2700 % o image: the image.
2702 % o length: Specifies an integer representing the number of bytes to read
2705 % o data: Specifies an area to place the information requested from the
2709 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2710 unsigned char *data)
2715 register unsigned char
2721 assert(image != (Image *) NULL);
2722 assert(image->signature == MagickSignature);
2723 assert(image->blob != (BlobInfo *) NULL);
2724 assert(image->blob->type != UndefinedStream);
2727 assert(data != (void *) NULL);
2730 switch (image->blob->type)
2732 case UndefinedStream:
2735 case StandardStream:
2742 count=(ssize_t) fread(q,1,length,image->blob->file);
2747 c=getc(image->blob->file);
2750 *q++=(unsigned char) c;
2755 c=getc(image->blob->file);
2758 *q++=(unsigned char) c;
2768 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2773 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2778 c=gzgetc(image->blob->file);
2781 *q++=(unsigned char) c;
2786 c=gzgetc(image->blob->file);
2789 *q++=(unsigned char) c;
2800 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2801 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2809 register const unsigned char
2812 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2814 image->blob->eof=MagickTrue;
2817 p=image->blob->data+image->blob->offset;
2818 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2819 image->blob->offset));
2820 image->blob->offset+=count;
2821 if (count != (ssize_t) length)
2822 image->blob->eof=MagickTrue;
2823 (void) memcpy(q,p,(size_t) count);
2831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2835 + R e a d B l o b B y t e %
2839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2841 % ReadBlobByte() reads a single byte from the image file and returns it.
2843 % The format of the ReadBlobByte method is:
2845 % int ReadBlobByte(Image *image)
2847 % A description of each parameter follows.
2849 % o image: the image.
2852 MagickExport int ReadBlobByte(Image *image)
2854 register const unsigned char
2863 assert(image != (Image *) NULL);
2864 assert(image->signature == MagickSignature);
2865 p=ReadBlobStream(image,1,buffer,&count);
2872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2876 + R e a d B l o b D o u b l e %
2880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2882 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2883 % specified by the endian member of the image structure.
2885 % The format of the ReadBlobDouble method is:
2887 % double ReadBlobDouble(Image *image)
2889 % A description of each parameter follows.
2891 % o image: the image.
2894 MagickExport double ReadBlobDouble(Image *image)
2905 quantum.double_value=0.0;
2906 quantum.unsigned_value=ReadBlobLongLong(image);
2907 return(quantum.double_value);
2911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2915 + R e a d B l o b F l o a t %
2919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2921 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2922 % specified by the endian member of the image structure.
2924 % The format of the ReadBlobFloat method is:
2926 % float ReadBlobFloat(Image *image)
2928 % A description of each parameter follows.
2930 % o image: the image.
2933 MagickExport float ReadBlobFloat(Image *image)
2944 quantum.float_value=0.0;
2945 quantum.unsigned_value=ReadBlobLong(image);
2946 return(quantum.float_value);
2950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2954 + R e a d B l o b L o n g %
2958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2960 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2961 % specified by the endian member of the image structure.
2963 % The format of the ReadBlobLong method is:
2965 % unsigned int ReadBlobLong(Image *image)
2967 % A description of each parameter follows.
2969 % o image: the image.
2972 MagickExport unsigned int ReadBlobLong(Image *image)
2974 register const unsigned char
2986 assert(image != (Image *) NULL);
2987 assert(image->signature == MagickSignature);
2989 p=ReadBlobStream(image,4,buffer,&count);
2992 if (image->endian == LSBEndian)
2994 value=(unsigned int) (*p++);
2995 value|=((unsigned int) (*p++)) << 8;
2996 value|=((unsigned int) (*p++)) << 16;
2997 value|=((unsigned int) (*p++)) << 24;
3000 value=((unsigned int) (*p++)) << 24;
3001 value|=((unsigned int) (*p++)) << 16;
3002 value|=((unsigned int) (*p++)) << 8;
3003 value|=((unsigned int) (*p++));
3008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3012 + R e a d B l o b L o n g L o n g %
3016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3018 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3019 % byte-order specified by the endian member of the image structure.
3021 % The format of the ReadBlobLongLong method is:
3023 % MagickSizeType ReadBlobLongLong(Image *image)
3025 % A description of each parameter follows.
3027 % o image: the image.
3030 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3035 register const unsigned char
3044 assert(image != (Image *) NULL);
3045 assert(image->signature == MagickSignature);
3047 p=ReadBlobStream(image,8,buffer,&count);
3049 return(MagickULLConstant(0));
3050 if (image->endian == LSBEndian)
3052 value=(MagickSizeType) (*p++);
3053 value|=((MagickSizeType) (*p++)) << 8;
3054 value|=((MagickSizeType) (*p++)) << 16;
3055 value|=((MagickSizeType) (*p++)) << 24;
3056 value|=((MagickSizeType) (*p++)) << 32;
3057 value|=((MagickSizeType) (*p++)) << 40;
3058 value|=((MagickSizeType) (*p++)) << 48;
3059 value|=((MagickSizeType) (*p++)) << 56;
3060 return(value & MagickULLConstant(0xffffffffffffffff));
3062 value=((MagickSizeType) (*p++)) << 56;
3063 value|=((MagickSizeType) (*p++)) << 48;
3064 value|=((MagickSizeType) (*p++)) << 40;
3065 value|=((MagickSizeType) (*p++)) << 32;
3066 value|=((MagickSizeType) (*p++)) << 24;
3067 value|=((MagickSizeType) (*p++)) << 16;
3068 value|=((MagickSizeType) (*p++)) << 8;
3069 value|=((MagickSizeType) (*p++));
3070 return(value & MagickULLConstant(0xffffffffffffffff));
3074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3078 + R e a d B l o b S h o r t %
3082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3084 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3085 % specified by the endian member of the image structure.
3087 % The format of the ReadBlobShort method is:
3089 % unsigned short ReadBlobShort(Image *image)
3091 % A description of each parameter follows.
3093 % o image: the image.
3096 MagickExport unsigned short ReadBlobShort(Image *image)
3098 register const unsigned char
3101 register unsigned int
3110 assert(image != (Image *) NULL);
3111 assert(image->signature == MagickSignature);
3113 p=ReadBlobStream(image,2,buffer,&count);
3115 return((unsigned short) 0U);
3116 if (image->endian == LSBEndian)
3118 value=(unsigned int) (*p++);
3119 value|=((unsigned int) (*p++)) << 8;
3120 return((unsigned short) (value & 0xffff));
3122 value=(unsigned int) ((*p++) << 8);
3123 value|=(unsigned int) (*p++);
3124 return((unsigned short) (value & 0xffff));
3128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3132 + R e a d B l o b L S B L o n g %
3136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3138 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3139 % least-significant byte first order.
3141 % The format of the ReadBlobLSBLong method is:
3143 % unsigned int ReadBlobLSBLong(Image *image)
3145 % A description of each parameter follows.
3147 % o image: the image.
3150 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3152 register const unsigned char
3155 register unsigned int
3164 assert(image != (Image *) NULL);
3165 assert(image->signature == MagickSignature);
3167 p=ReadBlobStream(image,4,buffer,&count);
3170 value=(unsigned int) (*p++);
3171 value|=((unsigned int) (*p++)) << 8;
3172 value|=((unsigned int) (*p++)) << 16;
3173 value|=((unsigned int) (*p++)) << 24;
3178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3182 + R e a d B l o b L S B S h o r t %
3186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3188 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3189 % least-significant byte first order.
3191 % The format of the ReadBlobLSBShort method is:
3193 % unsigned short ReadBlobLSBShort(Image *image)
3195 % A description of each parameter follows.
3197 % o image: the image.
3200 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3202 register const unsigned char
3205 register unsigned int
3214 assert(image != (Image *) NULL);
3215 assert(image->signature == MagickSignature);
3217 p=ReadBlobStream(image,2,buffer,&count);
3219 return((unsigned short) 0U);
3220 value=(unsigned int) (*p++);
3221 value|=((unsigned int) ((*p++)) << 8);
3222 return((unsigned short) (value & 0xffff));
3226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3230 + R e a d B l o b M S B L o n g %
3234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3236 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3237 % most-significant byte first order.
3239 % The format of the ReadBlobMSBLong method is:
3241 % unsigned int ReadBlobMSBLong(Image *image)
3243 % A description of each parameter follows.
3245 % o image: the image.
3248 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3250 register const unsigned char
3253 register unsigned int
3262 assert(image != (Image *) NULL);
3263 assert(image->signature == MagickSignature);
3265 p=ReadBlobStream(image,4,buffer,&count);
3268 value=((unsigned int) (*p++) << 24);
3269 value|=((unsigned int) (*p++) << 16);
3270 value|=((unsigned int) (*p++) << 8);
3271 value|=(unsigned int) (*p++);
3276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3280 + R e a d B l o b M S B L o n g L o n g %
3284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3286 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3287 % most-significant byte first order.
3289 % The format of the ReadBlobMSBLongLong method is:
3291 % unsigned int ReadBlobMSBLongLong(Image *image)
3293 % A description of each parameter follows.
3295 % o image: the image.
3298 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3300 register const unsigned char
3303 register MagickSizeType
3312 assert(image != (Image *) NULL);
3313 assert(image->signature == MagickSignature);
3315 p=ReadBlobStream(image,8,buffer,&count);
3317 return(MagickULLConstant(0));
3318 value=((MagickSizeType) (*p++)) << 56;
3319 value|=((MagickSizeType) (*p++)) << 48;
3320 value|=((MagickSizeType) (*p++)) << 40;
3321 value|=((MagickSizeType) (*p++)) << 32;
3322 value|=((MagickSizeType) (*p++)) << 24;
3323 value|=((MagickSizeType) (*p++)) << 16;
3324 value|=((MagickSizeType) (*p++)) << 8;
3325 value|=((MagickSizeType) (*p++));
3326 return(value & MagickULLConstant(0xffffffffffffffff));
3330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3334 + R e a d B l o b M S B S h o r t %
3338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3340 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3341 % most-significant byte first order.
3343 % The format of the ReadBlobMSBShort method is:
3345 % unsigned short ReadBlobMSBShort(Image *image)
3347 % A description of each parameter follows.
3349 % o image: the image.
3352 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3354 register const unsigned char
3357 register unsigned int
3366 assert(image != (Image *) NULL);
3367 assert(image->signature == MagickSignature);
3369 p=ReadBlobStream(image,2,buffer,&count);
3371 return((unsigned short) 0U);
3372 value=(unsigned int) ((*p++) << 8);
3373 value|=(unsigned int) (*p++);
3374 return((unsigned short) (value & 0xffff));
3378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3382 + R e a d B l o b S t r i n g %
3386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3388 % ReadBlobString() reads characters from a blob or file until a newline
3389 % character is read or an end-of-file condition is encountered.
3391 % The format of the ReadBlobString method is:
3393 % char *ReadBlobString(Image *image,char *string)
3395 % A description of each parameter follows:
3397 % o image: the image.
3399 % o string: the address of a character buffer.
3402 MagickExport char *ReadBlobString(Image *image,char *string)
3404 register const unsigned char
3416 assert(image != (Image *) NULL);
3417 assert(image->signature == MagickSignature);
3418 for (i=0; i < (MaxTextExtent-1L); i++)
3420 p=ReadBlobStream(image,1,buffer,&count);
3424 return((char *) NULL);
3427 string[i]=(char) (*p);
3428 if ((string[i] == '\r') || (string[i] == '\n'))
3431 if (string[i] == '\r')
3432 (void) ReadBlobStream(image,1,buffer,&count);
3438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3442 + R e f e r e n c e B l o b %
3446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3448 % ReferenceBlob() increments the reference count associated with the pixel
3449 % blob returning a pointer to the blob.
3451 % The format of the ReferenceBlob method is:
3453 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3455 % A description of each parameter follows:
3457 % o blob_info: the blob_info.
3460 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3462 assert(blob != (BlobInfo *) NULL);
3463 assert(blob->signature == MagickSignature);
3464 if (blob->debug != MagickFalse)
3465 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3466 LockSemaphoreInfo(blob->semaphore);
3467 blob->reference_count++;
3468 UnlockSemaphoreInfo(blob->semaphore);
3473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3483 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3484 % and returns the resulting offset.
3486 % The format of the SeekBlob method is:
3488 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3491 % A description of each parameter follows:
3493 % o image: the image.
3495 % o offset: Specifies an integer representing the offset in bytes.
3497 % o whence: Specifies an integer representing how the offset is
3498 % treated relative to the beginning of the blob as follows:
3500 % SEEK_SET Set position equal to offset bytes.
3501 % SEEK_CUR Set position to current location plus offset.
3502 % SEEK_END Set position to EOF plus offset.
3505 MagickExport MagickOffsetType SeekBlob(Image *image,
3506 const MagickOffsetType offset,const int whence)
3508 assert(image != (Image *) NULL);
3509 assert(image->signature == MagickSignature);
3510 if (image->debug != MagickFalse)
3511 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3512 assert(image->blob != (BlobInfo *) NULL);
3513 assert(image->blob->type != UndefinedStream);
3514 switch (image->blob->type)
3516 case UndefinedStream:
3520 if (fseek(image->blob->file,(long) offset,whence) < 0)
3522 image->blob->offset=TellBlob(image);
3525 case StandardStream:
3529 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3530 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3533 image->blob->offset=TellBlob(image);
3549 image->blob->offset=offset;
3554 if ((image->blob->offset+offset) < 0)
3556 image->blob->offset+=offset;
3561 if (((MagickOffsetType) image->blob->length+offset) < 0)
3563 image->blob->offset=image->blob->length+offset;
3567 if (image->blob->offset <= (MagickOffsetType)
3568 ((off_t) image->blob->length))
3569 image->blob->eof=MagickFalse;
3571 if (image->blob->mapped != MagickFalse)
3575 image->blob->extent=(size_t) (image->blob->offset+
3576 image->blob->quantum);
3577 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3578 image->blob->data,image->blob->extent+1,
3579 sizeof(*image->blob->data));
3580 (void) SyncBlob(image);
3581 if (image->blob->data == (unsigned char *) NULL)
3583 (void) DetachBlob(image->blob);
3590 return(image->blob->offset);
3594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3598 + S e t B l o b E x e m p t %
3602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3604 % SetBlobExempt() sets the blob exempt status.
3606 % The format of the SetBlobExempt method is:
3608 % MagickBooleanType SetBlobExempt(const Image *image,
3609 % const MagickBooleanType exempt)
3611 % A description of each parameter follows:
3613 % o image: the image.
3615 % o exempt: Set to true if this blob is exempt from being closed.
3618 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3620 assert(image != (const Image *) NULL);
3621 assert(image->signature == MagickSignature);
3622 if (image->debug != MagickFalse)
3623 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3624 image->blob->exempt=exempt;
3628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3632 + S e t B l o b E x t e n t %
3636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3638 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3639 % method is successful, subsequent writes to bytes in the specified range are
3640 % guaranteed not to fail.
3642 % The format of the SetBlobExtent method is:
3644 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3646 % A description of each parameter follows:
3648 % o image: the image.
3650 % o extent: the blob maximum extent.
3653 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3654 const MagickSizeType extent)
3656 assert(image != (Image *) NULL);
3657 assert(image->signature == MagickSignature);
3658 if (image->debug != MagickFalse)
3659 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3660 assert(image->blob != (BlobInfo *) NULL);
3661 assert(image->blob->type != UndefinedStream);
3662 switch (image->blob->type)
3664 case UndefinedStream:
3668 if (extent != (MagickSizeType) ((off_t) extent))
3669 return(MagickFalse);
3670 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3671 return(MagickFalse);
3680 offset=TellBlob(image);
3681 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3682 (off_t) (extent-offset));
3684 return(MagickFalse);
3689 case StandardStream:
3692 return(MagickFalse);
3694 return(MagickFalse);
3696 return(MagickFalse);
3699 if (image->blob->mapped != MagickFalse)
3701 if (image->blob->file == (FILE *) NULL)
3702 return(MagickFalse);
3703 (void) UnmapBlob(image->blob->data,image->blob->length);
3704 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3705 return(MagickFalse);
3714 offset=TellBlob(image);
3715 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3716 (off_t) (extent-offset));
3718 return(MagickFalse);
3720 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3721 WriteMode,0,(size_t) extent);
3722 image->blob->extent=(size_t) extent;
3723 image->blob->length=(size_t) extent;
3724 (void) SyncBlob(image);
3728 if (extent != (MagickSizeType) ((size_t) extent))
3729 return(MagickFalse);
3730 image->blob->extent=(size_t) extent;
3731 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3732 image->blob->extent+1,sizeof(*image->blob->data));
3733 (void) SyncBlob(image);
3734 if (image->blob->data == (unsigned char *) NULL)
3736 (void) DetachBlob(image->blob);
3737 return(MagickFalse);
3746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3756 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3757 % attributes if it is an blob.
3759 % The format of the SyncBlob method is:
3761 % int SyncBlob(Image *image)
3763 % A description of each parameter follows:
3765 % o image: the image.
3768 static int SyncBlob(Image *image)
3773 assert(image != (Image *) NULL);
3774 assert(image->signature == MagickSignature);
3775 if (image->debug != MagickFalse)
3776 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3777 assert(image->blob != (BlobInfo *) NULL);
3778 assert(image->blob->type != UndefinedStream);
3780 switch (image->blob->type)
3782 case UndefinedStream:
3785 case StandardStream:
3788 status=fflush(image->blob->file);
3793 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3794 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3800 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3801 status=BZ2_bzflush((BZFILE *) image->blob->file);
3809 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3810 if (image->blob->mapped != MagickFalse)
3811 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3830 % TellBlob() obtains the current value of the blob or file position.
3832 % The format of the TellBlob method is:
3834 % MagickOffsetType TellBlob(const Image *image)
3836 % A description of each parameter follows:
3838 % o image: the image.
3841 MagickExport MagickOffsetType TellBlob(const Image *image)
3846 assert(image != (Image *) NULL);
3847 assert(image->signature == MagickSignature);
3848 if (image->debug != MagickFalse)
3849 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3850 assert(image->blob != (BlobInfo *) NULL);
3851 assert(image->blob->type != UndefinedStream);
3853 switch (image->blob->type)
3855 case UndefinedStream:
3859 offset=ftell(image->blob->file);
3862 case StandardStream:
3867 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3868 offset=(MagickOffsetType) gztell(image->blob->file);
3878 offset=image->blob->offset;
3886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3890 + U n m a p B l o b %
3894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3896 % UnmapBlob() deallocates the binary large object previously allocated with
3897 % the MapBlob method.
3899 % The format of the UnmapBlob method is:
3901 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3903 % A description of each parameter follows:
3905 % o map: the address of the binary large object.
3907 % o length: the length of the binary large object.
3910 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3912 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3916 status=munmap(map,length);
3917 return(status == -1 ? MagickFalse : MagickTrue);
3921 return(MagickFalse);
3926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3930 + W r i t e B l o b %
3934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3936 % WriteBlob() writes data to a blob or image file. It returns the number of
3939 % The format of the WriteBlob method is:
3941 % ssize_t WriteBlob(Image *image,const size_t length,
3942 % const unsigned char *data)
3944 % A description of each parameter follows:
3946 % o image: the image.
3948 % o length: Specifies an integer representing the number of bytes to
3949 % write to the file.
3951 % o data: The address of the data to write to the blob or file.
3954 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3955 const unsigned char *data)
3960 register const unsigned char
3966 assert(image != (Image *) NULL);
3967 assert(image->signature == MagickSignature);
3968 assert(data != (const unsigned char *) NULL);
3969 assert(image->blob != (BlobInfo *) NULL);
3970 assert(image->blob->type != UndefinedStream);
3975 switch (image->blob->type)
3977 case UndefinedStream:
3980 case StandardStream:
3987 count=(ssize_t) fwrite((const char *) data,1,length,
3993 c=putc((int) *p++,image->blob->file);
4000 c=putc((int) *p++,image->blob->file);
4012 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4017 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4018 (unsigned int) length);
4023 c=gzputc(image->blob->file,(int) *p++);
4030 c=gzputc(image->blob->file,(int) *p++);
4043 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4044 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4051 count=(ssize_t) image->blob->stream(image,data,length);
4056 register unsigned char
4059 if ((image->blob->offset+(MagickOffsetType) length) >=
4060 (MagickOffsetType) image->blob->extent)
4062 if (image->blob->mapped != MagickFalse)
4064 image->blob->quantum<<=1;
4065 image->blob->extent+=length+image->blob->quantum;
4066 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4067 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4068 (void) SyncBlob(image);
4069 if (image->blob->data == (unsigned char *) NULL)
4071 (void) DetachBlob(image->blob);
4075 q=image->blob->data+image->blob->offset;
4076 (void) memcpy(q,p,length);
4077 image->blob->offset+=length;
4078 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4079 image->blob->length=(size_t) image->blob->offset;
4080 count=(ssize_t) length;
4087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4091 + W r i t e B l o b B y t e %
4095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4097 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4098 % written (either 0 or 1);
4100 % The format of the WriteBlobByte method is:
4102 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4104 % A description of each parameter follows.
4106 % o image: the image.
4108 % o value: Specifies the value to write.
4111 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4113 assert(image != (Image *) NULL);
4114 assert(image->signature == MagickSignature);
4115 return(WriteBlobStream(image,1,&value));
4119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4123 + W r i t e B l o b F l o a t %
4127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4129 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4130 % specified by the endian member of the image structure.
4132 % The format of the WriteBlobFloat method is:
4134 % ssize_t WriteBlobFloat(Image *image,const float value)
4136 % A description of each parameter follows.
4138 % o image: the image.
4140 % o value: Specifies the value to write.
4143 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4154 quantum.unsigned_value=0U;
4155 quantum.float_value=value;
4156 return(WriteBlobLong(image,quantum.unsigned_value));
4160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4164 + W r i t e B l o b L o n g %
4168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4170 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4171 % specified by the endian member of the image structure.
4173 % The format of the WriteBlobLong method is:
4175 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4177 % A description of each parameter follows.
4179 % o image: the image.
4181 % o value: Specifies the value to write.
4184 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4189 assert(image != (Image *) NULL);
4190 assert(image->signature == MagickSignature);
4191 if (image->endian == LSBEndian)
4193 buffer[0]=(unsigned char) value;
4194 buffer[1]=(unsigned char) (value >> 8);
4195 buffer[2]=(unsigned char) (value >> 16);
4196 buffer[3]=(unsigned char) (value >> 24);
4197 return(WriteBlobStream(image,4,buffer));
4199 buffer[0]=(unsigned char) (value >> 24);
4200 buffer[1]=(unsigned char) (value >> 16);
4201 buffer[2]=(unsigned char) (value >> 8);
4202 buffer[3]=(unsigned char) value;
4203 return(WriteBlobStream(image,4,buffer));
4207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4211 + W r i t e B l o b S h o r t %
4215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4217 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4218 % byte-order specified by the endian member of the image structure.
4220 % The format of the WriteBlobShort method is:
4222 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4224 % A description of each parameter follows.
4226 % o image: the image.
4228 % o value: Specifies the value to write.
4231 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4236 assert(image != (Image *) NULL);
4237 assert(image->signature == MagickSignature);
4238 if (image->endian == LSBEndian)
4240 buffer[0]=(unsigned char) value;
4241 buffer[1]=(unsigned char) (value >> 8);
4242 return(WriteBlobStream(image,2,buffer));
4244 buffer[0]=(unsigned char) (value >> 8);
4245 buffer[1]=(unsigned char) value;
4246 return(WriteBlobStream(image,2,buffer));
4250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4254 + W r i t e B l o b L S B L o n g %
4258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4260 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4261 % least-significant byte first order.
4263 % The format of the WriteBlobLSBLong method is:
4265 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4267 % A description of each parameter follows.
4269 % o image: the image.
4271 % o value: Specifies the value to write.
4274 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4279 assert(image != (Image *) NULL);
4280 assert(image->signature == MagickSignature);
4281 buffer[0]=(unsigned char) value;
4282 buffer[1]=(unsigned char) (value >> 8);
4283 buffer[2]=(unsigned char) (value >> 16);
4284 buffer[3]=(unsigned char) (value >> 24);
4285 return(WriteBlobStream(image,4,buffer));
4289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4293 + W r i t e B l o b L S B S h o r t %
4297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4299 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4300 % least-significant byte first order.
4302 % The format of the WriteBlobLSBShort method is:
4304 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4306 % A description of each parameter follows.
4308 % o image: the image.
4310 % o value: Specifies the value to write.
4313 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4318 assert(image != (Image *) NULL);
4319 assert(image->signature == MagickSignature);
4320 buffer[0]=(unsigned char) value;
4321 buffer[1]=(unsigned char) (value >> 8);
4322 return(WriteBlobStream(image,2,buffer));
4326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4330 + W r i t e B l o b M S B L o n g %
4334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4336 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4337 % most-significant byte first order.
4339 % The format of the WriteBlobMSBLong method is:
4341 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4343 % A description of each parameter follows.
4345 % o value: Specifies the value to write.
4347 % o image: the image.
4350 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4355 assert(image != (Image *) NULL);
4356 assert(image->signature == MagickSignature);
4357 buffer[0]=(unsigned char) (value >> 24);
4358 buffer[1]=(unsigned char) (value >> 16);
4359 buffer[2]=(unsigned char) (value >> 8);
4360 buffer[3]=(unsigned char) value;
4361 return(WriteBlobStream(image,4,buffer));
4365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4369 + W r i t e B l o b M S B L o n g L o n g %
4373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4375 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4376 % most-significant byte first order.
4378 % The format of the WriteBlobMSBLongLong method is:
4380 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4382 % A description of each parameter follows.
4384 % o value: Specifies the value to write.
4386 % o image: the image.
4389 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4390 const MagickSizeType value)
4395 assert(image != (Image *) NULL);
4396 assert(image->signature == MagickSignature);
4397 buffer[0]=(unsigned char) (value >> 56);
4398 buffer[1]=(unsigned char) (value >> 48);
4399 buffer[2]=(unsigned char) (value >> 40);
4400 buffer[3]=(unsigned char) (value >> 32);
4401 buffer[4]=(unsigned char) (value >> 24);
4402 buffer[5]=(unsigned char) (value >> 16);
4403 buffer[6]=(unsigned char) (value >> 8);
4404 buffer[7]=(unsigned char) value;
4405 return(WriteBlobStream(image,8,buffer));
4409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4413 + W r i t e B l o b M S B S h o r t %
4417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4419 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4420 % most-significant byte first order.
4422 % The format of the WriteBlobMSBShort method is:
4424 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4426 % A description of each parameter follows.
4428 % o value: Specifies the value to write.
4430 % o file: Specifies the file to write the data to.
4433 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4438 assert(image != (Image *) NULL);
4439 assert(image->signature == MagickSignature);
4440 buffer[0]=(unsigned char) (value >> 8);
4441 buffer[1]=(unsigned char) value;
4442 return(WriteBlobStream(image,2,buffer));
4446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4450 + W r i t e B l o b S t r i n g %
4454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4456 % WriteBlobString() write a string to a blob. It returns the number of
4457 % characters written.
4459 % The format of the WriteBlobString method is:
4461 % ssize_t WriteBlobString(Image *image,const char *string)
4463 % A description of each parameter follows.
4465 % o image: the image.
4467 % o string: Specifies the string to write.
4470 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4472 assert(image != (Image *) NULL);
4473 assert(image->signature == MagickSignature);
4474 assert(string != (const char *) NULL);
4475 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));