2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2010 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 *) AcquireAlignedMemory(1,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)
533 status=fsync(fileno(image->blob->file));
534 status=fclose(image->blob->file);
539 #if defined(MAGICKCORE_HAVE_PCLOSE)
540 status=pclose(image->blob->file);
546 #if defined(MAGICKCORE_ZLIB_DELEGATE)
547 status=gzclose(image->blob->file);
553 #if defined(MAGICKCORE_BZLIB_DELEGATE)
554 BZ2_bzclose((BZFILE *) image->blob->file);
562 (void) DetachBlob(image->blob);
563 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
564 return(image->blob->status);
568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572 + D e s t r o y B l o b %
576 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578 % DestroyBlob() deallocates memory associated with a blob.
580 % The format of the DestroyBlob method is:
582 % void DestroyBlob(Image *image)
584 % A description of each parameter follows:
586 % o image: the image.
589 MagickExport void DestroyBlob(Image *image)
594 assert(image != (Image *) NULL);
595 assert(image->signature == MagickSignature);
596 if (image->debug != MagickFalse)
597 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
598 assert(image->blob != (BlobInfo *) NULL);
599 assert(image->blob->signature == MagickSignature);
601 LockSemaphoreInfo(image->blob->semaphore);
602 image->blob->reference_count--;
603 assert(image->blob->reference_count >= 0);
604 if (image->blob->reference_count == 0)
606 UnlockSemaphoreInfo(image->blob->semaphore);
607 if (destroy == MagickFalse)
609 (void) CloseBlob(image);
610 if (image->blob->mapped != MagickFalse)
611 (void) UnmapBlob(image->blob->data,image->blob->length);
612 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
613 DestroySemaphoreInfo(&image->blob->semaphore);
614 image->blob->signature=(~MagickSignature);
615 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623 + D e t a c h B l o b %
627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 % DetachBlob() detaches a blob from the BlobInfo structure.
631 % The format of the DetachBlob method is:
633 % unsigned char *DetachBlob(BlobInfo *blob_info)
635 % A description of each parameter follows:
637 % o blob_info: Specifies a pointer to a BlobInfo structure.
640 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
645 assert(blob_info != (BlobInfo *) NULL);
646 if (blob_info->debug != MagickFalse)
647 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
648 if (blob_info->mapped != MagickFalse)
649 (void) UnmapBlob(blob_info->data,blob_info->length);
650 blob_info->mapped=MagickFalse;
653 blob_info->eof=MagickFalse;
654 blob_info->exempt=MagickFalse;
655 blob_info->type=UndefinedStream;
656 blob_info->file=(FILE *) NULL;
657 data=blob_info->data;
658 blob_info->data=(unsigned char *) NULL;
659 blob_info->stream=(StreamHandler) NULL;
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 + D i s c a r d B l o b B y t e s %
672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
674 % DiscardBlobBytes() discards bytes in a blob.
676 % The format of the DiscardBlobBytes method is:
678 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
680 % A description of each parameter follows.
682 % o image: the image.
684 % o length: the number of bytes to skip.
688 static inline const unsigned char *ReadBlobStream(Image *image,
689 const size_t length,unsigned char *data,ssize_t *count)
691 assert(count != (ssize_t *) NULL);
692 assert(image->blob != (BlobInfo *) NULL);
693 if (image->blob->type != BlobStream)
695 *count=ReadBlob(image,length,data);
698 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
701 image->blob->eof=MagickTrue;
704 data=image->blob->data+image->blob->offset;
705 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
706 image->blob->offset));
707 image->blob->offset+=(*count);
708 if (*count != (ssize_t) length)
709 image->blob->eof=MagickTrue;
713 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
728 assert(image != (Image *) NULL);
729 assert(image->signature == MagickSignature);
731 for (i=0; i < (ssize_t) length; i+=count)
733 quantum=MagickMin(length-i,sizeof(buffer));
734 (void) ReadBlobStream(image,quantum,buffer,&count);
742 return(i < (ssize_t) length ? MagickFalse : MagickTrue);
746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
750 + D u p l i c a t e s B l o b %
754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
756 % DuplicateBlob() duplicates a blob descriptor.
758 % The format of the DuplicateBlob method is:
760 % void DuplicateBlob(Image *image,const Image *duplicate)
762 % A description of each parameter follows:
764 % o image: the image.
766 % o duplicate: the duplicate image.
769 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
771 assert(image != (Image *) NULL);
772 assert(image->signature == MagickSignature);
773 if (image->debug != MagickFalse)
774 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
775 assert(duplicate != (Image *) NULL);
776 assert(duplicate->signature == MagickSignature);
778 image->blob=ReferenceBlob(duplicate->blob);
782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792 % EOFBlob() returns a non-zero value when EOF has been detected reading from
795 % The format of the EOFBlob method is:
797 % int EOFBlob(const Image *image)
799 % A description of each parameter follows:
801 % o image: the image.
804 MagickExport int EOFBlob(const Image *image)
806 assert(image != (Image *) NULL);
807 assert(image->signature == MagickSignature);
808 if (image->debug != MagickFalse)
809 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
810 assert(image->blob != (BlobInfo *) NULL);
811 assert(image->blob->type != UndefinedStream);
812 switch (image->blob->type)
814 case UndefinedStream:
820 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
825 image->blob->eof=MagickFalse;
830 #if defined(MAGICKCORE_BZLIB_DELEGATE)
835 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
836 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
842 image->blob->eof=MagickFalse;
848 return((int) image->blob->eof);
852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 + F i l e T o B l o b %
860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
862 % FileToBlob() returns the contents of a file as a blob. It returns the
863 % file as a blob and its length. If an error occurs, NULL is returned.
865 % The format of the FileToBlob method is:
867 % unsigned char *FileToBlob(const char *filename,const size_t extent,
868 % size_t *length,ExceptionInfo *exception)
870 % A description of each parameter follows:
872 % o blob: FileToBlob() returns the contents of a file as a blob. If
873 % an error occurs NULL is returned.
875 % o filename: the filename.
877 % o extent: The maximum length of the blob.
879 % o length: On return, this reflects the actual length of the blob.
881 % o exception: return any errors or warnings in this structure.
884 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
885 size_t *length,ExceptionInfo *exception)
905 assert(filename != (const char *) NULL);
906 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
907 assert(exception != (ExceptionInfo *) NULL);
910 if (LocaleCompare(filename,"-") != 0)
911 file=open(filename,O_RDONLY | O_BINARY);
914 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
915 return((unsigned char *) NULL);
917 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
919 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
928 Stream is not seekable.
930 quantum=(size_t) MagickMaxBufferExtent;
931 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
932 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
933 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
934 for (i=0; blob != (unsigned char *) NULL; i+=count)
936 count=(ssize_t) read(file,blob+i,quantum);
943 if (~(1UL*i) < (quantum+1))
945 blob=(unsigned char *) RelinquishMagickMemory(blob);
948 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
950 if ((size_t) (i+count) >= extent)
953 if (LocaleCompare(filename,"-") != 0)
955 if (blob == (unsigned char *) NULL)
957 (void) ThrowMagickException(exception,GetMagickModule(),
958 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
959 return((unsigned char *) NULL);
963 blob=(unsigned char *) RelinquishMagickMemory(blob);
964 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
965 return((unsigned char *) NULL);
967 *length=MagickMin(i+count,extent);
971 *length=MagickMin((size_t) offset,extent);
972 blob=(unsigned char *) NULL;
973 if (~(*length) >= MaxTextExtent)
974 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
976 if (blob == (unsigned char *) NULL)
979 (void) ThrowMagickException(exception,GetMagickModule(),
980 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
981 return((unsigned char *) NULL);
983 map=MapBlob(file,ReadMode,0,*length);
984 if (map != (unsigned char *) NULL)
986 (void) memcpy(blob,map,*length);
987 (void) UnmapBlob(map,*length);
991 (void) MagickSeek(file,0,SEEK_SET);
992 for (i=0; i < *length; i+=count)
994 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
1006 blob=(unsigned char *) RelinquishMagickMemory(blob);
1007 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1008 return((unsigned char *) NULL);
1012 if (LocaleCompare(filename,"-") != 0)
1016 blob=(unsigned char *) RelinquishMagickMemory(blob);
1017 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1027 % F i l e T o I m a g e %
1031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1033 % FileToImage() write the contents of a file to an image.
1035 % The format of the FileToImage method is:
1037 % MagickBooleanType FileToImage(Image *,const char *filename)
1039 % A description of each parameter follows:
1041 % o image: the image.
1043 % o filename: the filename.
1047 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1048 const unsigned char *data)
1053 register unsigned char
1056 assert(image->blob != (BlobInfo *) NULL);
1057 if (image->blob->type != BlobStream)
1058 return(WriteBlob(image,length,data));
1059 assert(image->blob->type != UndefinedStream);
1060 assert(data != (void *) NULL);
1061 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1062 if (extent >= image->blob->extent)
1064 image->blob->quantum<<=1;
1065 extent=image->blob->extent+image->blob->quantum+length;
1066 if (SetBlobExtent(image,extent) == MagickFalse)
1069 q=image->blob->data+image->blob->offset;
1070 (void) memcpy(q,data,length);
1071 image->blob->offset+=length;
1072 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1073 image->blob->length=(size_t) image->blob->offset;
1074 return((ssize_t) length);
1077 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1095 assert(image != (const Image *) NULL);
1096 assert(image->signature == MagickSignature);
1097 assert(filename != (const char *) NULL);
1098 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1099 file=open(filename,O_RDONLY | O_BINARY);
1102 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1104 return(MagickFalse);
1106 quantum=(size_t) MagickMaxBufferExtent;
1107 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1108 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1109 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1110 if (blob == (unsigned char *) NULL)
1112 ThrowFileException(&image->exception,ResourceLimitError,
1113 "MemoryAllocationFailed",filename);
1114 return(MagickFalse);
1118 count=(ssize_t) read(file,blob,quantum);
1125 length=(size_t) count;
1126 count=WriteBlobStream(image,length,blob);
1127 if (count != (ssize_t) length)
1129 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1136 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1138 blob=(unsigned char *) RelinquishMagickMemory(blob);
1143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1147 + G e t B l o b E r r o r %
1151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1153 % GetBlobError() returns MagickTrue if the blob associated with the specified
1154 % image encountered an error.
1156 % The format of the GetBlobError method is:
1158 % MagickBooleanType GetBlobError(const Image *image)
1160 % A description of each parameter follows:
1162 % o image: the image.
1165 MagickExport MagickBooleanType GetBlobError(const Image *image)
1167 assert(image != (const Image *) NULL);
1168 assert(image->signature == MagickSignature);
1169 if (image->debug != MagickFalse)
1170 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1171 return(image->blob->status);
1175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1179 + G e t B l o b F i l e H a n d l e %
1183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1185 % GetBlobFileHandle() returns the file handle associated with the image blob.
1187 % The format of the GetBlobFile method is:
1189 % FILE *GetBlobFileHandle(const Image *image)
1191 % A description of each parameter follows:
1193 % o image: the image.
1196 MagickExport FILE *GetBlobFileHandle(const Image *image)
1198 assert(image != (const Image *) NULL);
1199 assert(image->signature == MagickSignature);
1200 return(image->blob->file);
1204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1208 + G e t B l o b I n f o %
1212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1214 % GetBlobInfo() initializes the BlobInfo structure.
1216 % The format of the GetBlobInfo method is:
1218 % void GetBlobInfo(BlobInfo *blob_info)
1220 % A description of each parameter follows:
1222 % o blob_info: Specifies a pointer to a BlobInfo structure.
1225 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1227 assert(blob_info != (BlobInfo *) NULL);
1228 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1229 blob_info->type=UndefinedStream;
1230 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1231 blob_info->properties.st_mtime=time((time_t *) NULL);
1232 blob_info->properties.st_ctime=time((time_t *) NULL);
1233 blob_info->debug=IsEventLogging();
1234 blob_info->reference_count=1;
1235 blob_info->semaphore=AllocateSemaphoreInfo();
1236 blob_info->signature=MagickSignature;
1240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1244 % G e t B l o b P r o p e r t i e s %
1248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1250 % GetBlobProperties() returns information about an image blob.
1252 % The format of the GetBlobProperties method is:
1254 % const struct stat *GetBlobProperties(const Image *image)
1256 % A description of each parameter follows:
1258 % o image: the image.
1261 MagickExport const struct stat *GetBlobProperties(const Image *image)
1263 assert(image != (Image *) NULL);
1264 assert(image->signature == MagickSignature);
1265 if (image->debug != MagickFalse)
1266 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1267 return(&image->blob->properties);
1271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1275 + G e t B l o b S i z e %
1279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1281 % GetBlobSize() returns the current length of the image file or blob; zero is
1282 % returned if the size cannot be determined.
1284 % The format of the GetBlobSize method is:
1286 % MagickSizeType GetBlobSize(const Image *image)
1288 % A description of each parameter follows:
1290 % o image: the image.
1293 MagickExport MagickSizeType GetBlobSize(const Image *image)
1298 assert(image != (Image *) NULL);
1299 assert(image->signature == MagickSignature);
1300 if (image->debug != MagickFalse)
1301 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1302 assert(image->blob != (BlobInfo *) NULL);
1304 switch (image->blob->type)
1306 case UndefinedStream:
1308 extent=image->blob->size;
1313 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1314 extent=(MagickSizeType) image->blob->properties.st_size;
1317 case StandardStream:
1320 extent=image->blob->size;
1329 status=GetPathAttributes(image->filename,&image->blob->properties);
1330 if (status != MagickFalse)
1331 extent=(MagickSizeType) image->blob->properties.st_size;
1338 extent=(MagickSizeType) image->blob->length;
1346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1350 + G e t B l o b S t r e a m D a t a %
1354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1356 % GetBlobStreamData() returns the stream data for the image.
1358 % The format of the GetBlobStreamData method is:
1360 % unsigned char *GetBlobStreamData(const Image *image)
1362 % A description of each parameter follows:
1364 % o image: the image.
1367 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1369 assert(image != (const Image *) NULL);
1370 assert(image->signature == MagickSignature);
1371 return(image->blob->data);
1375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1379 + G e t B l o b S t r e a m H a n d l e r %
1383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1385 % GetBlobStreamHandler() returns the stream handler for the image.
1387 % The format of the GetBlobStreamHandler method is:
1389 % StreamHandler GetBlobStreamHandler(const Image *image)
1391 % A description of each parameter follows:
1393 % o image: the image.
1396 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1398 assert(image != (const Image *) NULL);
1399 assert(image->signature == MagickSignature);
1400 if (image->debug != MagickFalse)
1401 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1402 return(image->blob->stream);
1406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410 % I m a g e T o B l o b %
1414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1416 % ImageToBlob() implements direct to memory image formats. It returns the
1417 % image as a blob and its length. The magick member of the ImageInfo structure
1418 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1420 % The format of the ImageToBlob method is:
1422 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1423 % size_t *length,ExceptionInfo *exception)
1425 % A description of each parameter follows:
1427 % o image_info: the image info.
1429 % o image: the image.
1431 % o length: This pointer to a size_t integer sets the initial length of the
1432 % blob. On return, it reflects the actual length of the blob.
1434 % o exception: return any errors or warnings in this structure.
1437 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1438 Image *image,size_t *length,ExceptionInfo *exception)
1452 assert(image_info != (const ImageInfo *) NULL);
1453 assert(image_info->signature == MagickSignature);
1454 if (image_info->debug != MagickFalse)
1455 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1456 image_info->filename);
1457 assert(image != (Image *) NULL);
1458 assert(image->signature == MagickSignature);
1459 assert(exception != (ExceptionInfo *) NULL);
1461 blob=(unsigned char *) NULL;
1462 blob_info=CloneImageInfo(image_info);
1463 blob_info->adjoin=MagickFalse;
1464 (void) SetImageInfo(blob_info,1,exception);
1465 if (*blob_info->magick != '\0')
1466 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1467 magick_info=GetMagickInfo(image->magick,exception);
1468 if (magick_info == (const MagickInfo *) NULL)
1470 (void) ThrowMagickException(exception,GetMagickModule(),
1471 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1475 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1476 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1479 Native blob support for this image format.
1481 blob_info->length=0;
1482 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1483 sizeof(unsigned char));
1484 if (blob_info->blob == (void *) NULL)
1485 (void) ThrowMagickException(exception,GetMagickModule(),
1486 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1489 (void) CloseBlob(image);
1490 image->blob->exempt=MagickTrue;
1491 *image->filename='\0';
1492 status=WriteImage(blob_info,image);
1493 if ((status == MagickFalse) || (image->blob->length == 0))
1494 InheritException(exception,&image->exception);
1497 *length=image->blob->length;
1498 blob=DetachBlob(image->blob);
1499 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1507 unique[MaxTextExtent];
1513 Write file to disk in blob image format.
1515 file=AcquireUniqueFileResource(unique);
1518 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1519 image_info->filename);
1523 blob_info->file=fdopen(file,"wb");
1524 if (blob_info->file != (FILE *) NULL)
1526 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1527 image->magick,unique);
1528 status=WriteImage(blob_info,image);
1529 (void) fclose(blob_info->file);
1530 if (status == MagickFalse)
1531 InheritException(exception,&image->exception);
1533 blob=FileToBlob(image->filename,~0UL,length,exception);
1535 (void) RelinquishUniqueFileResource(unique);
1538 blob_info=DestroyImageInfo(blob_info);
1543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1547 % I m a g e T o F i l e %
1551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1553 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1554 % occurs otherwise MagickTrue.
1556 % The format of the ImageToFile method is:
1558 % MagickBooleanType ImageToFile(Image *image,char *filename,
1559 % ExceptionInfo *exception)
1561 % A description of each parameter follows:
1563 % o image: the image.
1565 % o filename: Write the image to this file.
1567 % o exception: return any errors or warnings in this structure.
1570 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1571 ExceptionInfo *exception)
1576 register const unsigned char
1595 assert(image != (Image *) NULL);
1596 assert(image->signature == MagickSignature);
1597 assert(image->blob != (BlobInfo *) NULL);
1598 assert(image->blob->type != UndefinedStream);
1599 if (image->debug != MagickFalse)
1600 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1601 assert(filename != (const char *) NULL);
1602 if (*filename == '\0')
1603 file=AcquireUniqueFileResource(filename);
1605 if (LocaleCompare(filename,"-") == 0)
1606 file=fileno(stdout);
1608 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1611 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1612 return(MagickFalse);
1614 quantum=(size_t) MagickMaxBufferExtent;
1615 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1616 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1617 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1618 if (buffer == (unsigned char *) NULL)
1621 (void) ThrowMagickException(exception,GetMagickModule(),
1622 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1623 return(MagickFalse);
1626 p=ReadBlobStream(image,quantum,buffer,&count);
1627 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1629 length=(size_t) count;
1630 for (i=0; i < length; i+=count)
1632 count=write(file,p+i,(size_t) (length-i));
1643 if (LocaleCompare(filename,"-") != 0)
1645 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1646 if ((file == -1) || (i < length))
1648 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1649 return(MagickFalse);
1655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1659 % I m a g e s T o B l o b %
1663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1665 % ImagesToBlob() implements direct to memory image formats. It returns the
1666 % image sequence as a blob and its length. The magick member of the ImageInfo
1667 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1669 % Note, some image formats do not permit multiple images to the same image
1670 % stream (e.g. JPEG). in this instance, just the first image of the
1671 % sequence is returned as a blob.
1673 % The format of the ImagesToBlob method is:
1675 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1676 % size_t *length,ExceptionInfo *exception)
1678 % A description of each parameter follows:
1680 % o image_info: the image info.
1682 % o images: the image list.
1684 % o length: This pointer to a size_t integer sets the initial length of the
1685 % blob. On return, it reflects the actual length of the blob.
1687 % o exception: return any errors or warnings in this structure.
1690 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1691 Image *images,size_t *length,ExceptionInfo *exception)
1705 assert(image_info != (const ImageInfo *) NULL);
1706 assert(image_info->signature == MagickSignature);
1707 if (image_info->debug != MagickFalse)
1708 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1709 image_info->filename);
1710 assert(images != (Image *) NULL);
1711 assert(images->signature == MagickSignature);
1712 assert(exception != (ExceptionInfo *) NULL);
1714 blob=(unsigned char *) NULL;
1715 blob_info=CloneImageInfo(image_info);
1716 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1718 if (*blob_info->magick != '\0')
1719 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1720 if (blob_info->adjoin == MagickFalse)
1722 blob_info=DestroyImageInfo(blob_info);
1723 return(ImageToBlob(image_info,images,length,exception));
1725 magick_info=GetMagickInfo(images->magick,exception);
1726 if (magick_info == (const MagickInfo *) NULL)
1728 (void) ThrowMagickException(exception,GetMagickModule(),
1729 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1733 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1734 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1737 Native blob support for this images format.
1739 blob_info->length=0;
1740 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1741 sizeof(unsigned char));
1742 if (blob_info->blob == (void *) NULL)
1743 (void) ThrowMagickException(exception,GetMagickModule(),
1744 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1747 images->blob->exempt=MagickTrue;
1748 *images->filename='\0';
1749 status=WriteImages(blob_info,images,images->filename,exception);
1750 if ((status == MagickFalse) || (images->blob->length == 0))
1751 InheritException(exception,&images->exception);
1754 *length=images->blob->length;
1755 blob=DetachBlob(images->blob);
1756 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1764 filename[MaxTextExtent],
1765 unique[MaxTextExtent];
1771 Write file to disk in blob images format.
1773 file=AcquireUniqueFileResource(unique);
1776 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1777 image_info->filename);
1781 blob_info->file=fdopen(file,"wb");
1782 if (blob_info->file != (FILE *) NULL)
1784 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1785 images->magick,unique);
1786 status=WriteImages(blob_info,images,filename,exception);
1787 (void) fclose(blob_info->file);
1788 if (status == MagickFalse)
1789 InheritException(exception,&images->exception);
1791 blob=FileToBlob(images->filename,~0UL,length,exception);
1793 (void) RelinquishUniqueFileResource(unique);
1796 blob_info=DestroyImageInfo(blob_info);
1800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1804 % I n j e c t I m a g e B l o b %
1808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1810 % InjectImageBlob() injects the image with a copy of itself in the specified
1811 % format (e.g. inject JPEG into a PDF image).
1813 % The format of the InjectImageBlob method is:
1815 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1816 % Image *image,Image *inject_image,const char *format,
1817 % ExceptionInfo *exception)
1819 % A description of each parameter follows:
1821 % o image_info: the image info..
1823 % o image: the image.
1825 % o inject_image: inject into the image stream.
1827 % o format: the image format.
1829 % o exception: return any errors or warnings in this structure.
1832 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1833 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1836 filename[MaxTextExtent];
1869 Write inject image to a temporary file.
1871 assert(image_info != (ImageInfo *) NULL);
1872 assert(image_info->signature == MagickSignature);
1873 assert(image != (Image *) NULL);
1874 assert(image->signature == MagickSignature);
1875 if (image->debug != MagickFalse)
1876 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1877 assert(inject_image != (Image *) NULL);
1878 assert(inject_image->signature == MagickSignature);
1879 assert(exception != (ExceptionInfo *) NULL);
1880 unique_file=(FILE *) NULL;
1881 file=AcquireUniqueFileResource(filename);
1883 unique_file=fdopen(file,"wb");
1884 if ((file == -1) || (unique_file == (FILE *) NULL))
1886 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1887 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1889 return(MagickFalse);
1891 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1892 if (byte_image == (Image *) NULL)
1894 (void) fclose(unique_file);
1895 (void) RelinquishUniqueFileResource(filename);
1896 return(MagickFalse);
1898 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1900 DestroyBlob(byte_image);
1901 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1902 write_info=CloneImageInfo(image_info);
1903 SetImageInfoFile(write_info,unique_file);
1904 status=WriteImage(write_info,byte_image);
1905 write_info=DestroyImageInfo(write_info);
1906 byte_image=DestroyImage(byte_image);
1907 (void) fclose(unique_file);
1908 if (status == MagickFalse)
1910 (void) RelinquishUniqueFileResource(filename);
1911 return(MagickFalse);
1914 Inject into image stream.
1916 file=open(filename,O_RDONLY | O_BINARY);
1919 (void) RelinquishUniqueFileResource(filename);
1920 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1921 image_info->filename);
1922 return(MagickFalse);
1924 quantum=(size_t) MagickMaxBufferExtent;
1925 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1926 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1927 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1928 if (buffer == (unsigned char *) NULL)
1930 (void) RelinquishUniqueFileResource(filename);
1931 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1934 for (i=0; ; i+=count)
1936 count=(ssize_t) read(file,buffer,quantum);
1943 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1948 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1949 (void) RelinquishUniqueFileResource(filename);
1950 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1959 + I s B l o b E x e m p t %
1963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1965 % IsBlobExempt() returns true if the blob is exempt.
1967 % The format of the IsBlobExempt method is:
1969 % MagickBooleanType IsBlobExempt(const Image *image)
1971 % A description of each parameter follows:
1973 % o image: the image.
1976 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1978 assert(image != (const Image *) NULL);
1979 assert(image->signature == MagickSignature);
1980 if (image->debug != MagickFalse)
1981 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1982 return(image->blob->exempt);
1986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1990 + I s B l o b S e e k a b l e %
1994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1996 % IsBlobSeekable() returns true if the blob is seekable.
1998 % The format of the IsBlobSeekable method is:
2000 % MagickBooleanType IsBlobSeekable(const Image *image)
2002 % A description of each parameter follows:
2004 % o image: the image.
2007 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2012 assert(image != (const Image *) NULL);
2013 assert(image->signature == MagickSignature);
2014 if (image->debug != MagickFalse)
2015 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2016 seekable=(image->blob->type == FileStream) ||
2017 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2026 + I s B l o b T e m p o r a r y %
2030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2032 % IsBlobTemporary() returns true if the blob is temporary.
2034 % The format of the IsBlobTemporary method is:
2036 % MagickBooleanType IsBlobTemporary(const Image *image)
2038 % A description of each parameter follows:
2040 % o image: the image.
2043 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2045 assert(image != (const Image *) NULL);
2046 assert(image->signature == MagickSignature);
2047 if (image->debug != MagickFalse)
2048 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2049 return(image->blob->temporary);
2053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2063 % MapBlob() creates a mapping from a file to a binary large object.
2065 % The format of the MapBlob method is:
2067 % unsigned char *MapBlob(int file,const MapMode mode,
2068 % const MagickOffsetType offset,const size_t length)
2070 % A description of each parameter follows:
2072 % o file: map this file descriptor.
2074 % o mode: ReadMode, WriteMode, or IOMode.
2076 % o offset: starting at this offset within the file.
2078 % o length: the length of the mapping is returned in this pointer.
2081 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2082 const MagickOffsetType offset,const size_t length)
2084 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2097 #if defined(MAP_ANONYMOUS)
2098 flags|=MAP_ANONYMOUS;
2100 return((unsigned char *) NULL);
2107 protection=PROT_READ;
2109 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2115 protection=PROT_WRITE;
2117 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2119 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2120 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2121 POSIX_MADV_WILLNEED);
2127 protection=PROT_READ | PROT_WRITE;
2129 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2134 if (map == (unsigned char *) MAP_FAILED)
2135 return((unsigned char *) NULL);
2142 return((unsigned char *) NULL);
2147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2151 + M S B O r d e r L o n g %
2155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2157 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2158 % most-significant byte first.
2160 % The format of the MSBOrderLong method is:
2162 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2164 % A description of each parameter follows.
2166 % o buffer: Specifies a pointer to a buffer of integers.
2168 % o length: Specifies the length of the buffer.
2171 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2176 register unsigned char
2180 assert(buffer != (unsigned char *) NULL);
2187 *buffer++=(unsigned char) c;
2191 *buffer++=(unsigned char) c;
2197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2201 + M S B O r d e r S h o r t %
2205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2207 % MSBOrderShort() converts a least-significant byte first buffer of integers
2208 % to most-significant byte first.
2210 % The format of the MSBOrderShort method is:
2212 % void MSBOrderShort(unsigned char *p,const size_t length)
2214 % A description of each parameter follows.
2216 % o p: Specifies a pointer to a buffer of integers.
2218 % o length: Specifies the length of the buffer.
2221 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2226 register unsigned char
2229 assert(p != (unsigned char *) NULL);
2236 *p++=(unsigned char) c;
2241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2251 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2252 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2253 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2254 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2255 % from a system command.
2257 % The format of the OpenBlob method is:
2259 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2260 % const BlobMode mode,ExceptionInfo *exception)
2262 % A description of each parameter follows:
2264 % o image_info: the image info.
2266 % o image: the image.
2268 % o mode: the mode for opening the file.
2271 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2272 Image *image,const BlobMode mode,ExceptionInfo *exception)
2275 extension[MaxTextExtent],
2276 filename[MaxTextExtent];
2287 assert(image_info != (ImageInfo *) NULL);
2288 assert(image_info->signature == MagickSignature);
2289 if (image_info->debug != MagickFalse)
2290 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2291 image_info->filename);
2292 assert(image != (Image *) NULL);
2293 assert(image->signature == MagickSignature);
2294 if (image_info->blob != (void *) NULL)
2296 if (image_info->stream != (StreamHandler) NULL)
2297 image->blob->stream=(StreamHandler) image_info->stream;
2298 AttachBlob(image->blob,image_info->blob,image_info->length);
2301 (void) DetachBlob(image->blob);
2304 default: type="r"; break;
2305 case ReadBlobMode: type="r"; break;
2306 case ReadBinaryBlobMode: type="rb"; break;
2307 case WriteBlobMode: type="w"; break;
2308 case WriteBinaryBlobMode: type="w+b"; break;
2309 case AppendBlobMode: type="a"; break;
2310 case AppendBinaryBlobMode: type="a+b"; break;
2313 image->blob->synchronize=image_info->synchronize;
2314 if (image_info->stream != (StreamHandler) NULL)
2316 image->blob->stream=(StreamHandler) image_info->stream;
2319 image->blob->type=FifoStream;
2327 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2328 rights=ReadPolicyRights;
2330 rights=WritePolicyRights;
2331 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2334 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2335 "NotAuthorized","`%s'",filename);
2336 return(MagickFalse);
2338 if ((LocaleCompare(filename,"-") == 0) ||
2339 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2341 image->blob->file=(*type == 'r') ? stdin : stdout;
2342 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2343 if (strchr(type,'b') != (char *) NULL)
2344 setmode(_fileno(image->blob->file),_O_BINARY);
2346 image->blob->type=StandardStream;
2347 image->blob->exempt=MagickTrue;
2350 if (LocaleNCompare(filename,"fd:",3) == 0)
2353 mode[MaxTextExtent];
2357 image->blob->file=fdopen(StringToLong(filename+3),mode);
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 defined(MAGICKCORE_HAVE_POPEN)
2367 if (*filename == '|')
2370 mode[MaxTextExtent];
2373 Pipe image to or from a system command.
2375 #if defined(SIGPIPE)
2377 (void) signal(SIGPIPE,SIG_IGN);
2381 image->blob->file=(FILE *) popen(filename+1,mode);
2382 if (image->blob->file == (FILE *) NULL)
2384 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2385 return(MagickFalse);
2387 image->blob->type=PipeStream;
2388 image->blob->exempt=MagickTrue;
2392 status=GetPathAttributes(filename,&image->blob->properties);
2393 #if defined(S_ISFIFO)
2394 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2396 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2397 if (image->blob->file == (FILE *) NULL)
2399 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2400 return(MagickFalse);
2402 image->blob->type=FileStream;
2403 image->blob->exempt=MagickTrue;
2407 GetPathComponent(image->filename,ExtensionPath,extension);
2410 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2411 if ((image_info->adjoin == MagickFalse) ||
2412 (IsGlob(filename) != MagickFalse))
2415 Form filename for multi-part images.
2417 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2418 image->scene,filename);
2419 if ((LocaleCompare(filename,image->filename) == 0) &&
2420 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2421 (GetNextImageInList(image) != (Image *) NULL)))
2424 path[MaxTextExtent];
2426 GetPathComponent(image->filename,RootPath,path);
2427 if (*extension == '\0')
2428 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2429 path,(double) image->scene);
2431 (void) FormatMagickString(filename,MaxTextExtent,
2432 "%s-%.20g.%s",path,(double) image->scene,extension);
2434 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2435 #if defined(macintosh)
2436 SetApplicationType(filename,image_info->magick,'8BIM');
2440 if (image_info->file != (FILE *) NULL)
2442 image->blob->file=image_info->file;
2443 image->blob->type=FileStream;
2444 image->blob->exempt=MagickTrue;
2449 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2450 if (image->blob->file != (FILE *) NULL)
2458 image->blob->type=FileStream;
2459 #if defined(MAGICKCORE_HAVE_SETVBUF)
2460 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2463 (void) ResetMagickMemory(magick,0,sizeof(magick));
2464 count=fread(magick,1,sizeof(magick),image->blob->file);
2465 (void) rewind(image->blob->file);
2466 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2467 " read %.20g magic header bytes",(double) count);
2468 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2469 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2470 ((int) magick[2] == 0x08))
2472 (void) fclose(image->blob->file);
2473 image->blob->file=(FILE *) gzopen(filename,type);
2474 if (image->blob->file != (FILE *) NULL)
2475 image->blob->type=ZipStream;
2478 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2479 if (strncmp((char *) magick,"BZh",3) == 0)
2481 (void) fclose(image->blob->file);
2482 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2483 if (image->blob->file != (FILE *) NULL)
2484 image->blob->type=BZipStream;
2487 if (image->blob->type == FileStream)
2498 sans_exception=AcquireExceptionInfo();
2499 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2500 sans_exception=DestroyExceptionInfo(sans_exception);
2501 properties=(&image->blob->properties);
2502 if ((magick_info != (const MagickInfo *) NULL) &&
2503 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2504 (properties->st_size <= MagickMaxBufferExtent))
2512 length=(size_t) properties->st_size;
2513 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2514 if (blob != (void *) NULL)
2517 Format supports blobs-- use memory-mapped I/O.
2519 if (image_info->file != (FILE *) NULL)
2520 image->blob->exempt=MagickFalse;
2523 (void) fclose(image->blob->file);
2524 image->blob->file=(FILE *) NULL;
2526 AttachBlob(image->blob,blob,length);
2527 image->blob->mapped=MagickTrue;
2534 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2535 if ((LocaleCompare(extension,"Z") == 0) ||
2536 (LocaleCompare(extension,"gz") == 0) ||
2537 (LocaleCompare(extension,"wmz") == 0) ||
2538 (LocaleCompare(extension,"svgz") == 0))
2540 if (mode == WriteBinaryBlobMode)
2542 image->blob->file=(FILE *) gzopen(filename,type);
2543 if (image->blob->file != (FILE *) NULL)
2544 image->blob->type=ZipStream;
2548 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2549 if (LocaleCompare(extension,".bz2") == 0)
2551 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2552 if (image->blob->file != (FILE *) NULL)
2553 image->blob->type=BZipStream;
2558 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2559 if (image->blob->file != (FILE *) NULL)
2561 image->blob->type=FileStream;
2562 #if defined(MAGICKCORE_HAVE_SETVBUF)
2563 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2568 image->blob->status=MagickFalse;
2569 if (image->blob->type != UndefinedStream)
2570 image->blob->size=GetBlobSize(image);
2573 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2574 return(MagickFalse);
2580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2590 % PingBlob() returns all the attributes of an image or image sequence except
2591 % for the pixels. It is much faster and consumes far less memory than
2592 % BlobToImage(). On failure, a NULL image is returned and exception
2593 % describes the reason for the failure.
2595 % The format of the PingBlob method is:
2597 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2598 % const size_t length,ExceptionInfo *exception)
2600 % A description of each parameter follows:
2602 % o image_info: the image info.
2604 % o blob: the address of a character stream in one of the image formats
2605 % understood by ImageMagick.
2607 % o length: This size_t integer reflects the length in bytes of the blob.
2609 % o exception: return any errors or warnings in this structure.
2613 #if defined(__cplusplus) || defined(c_plusplus)
2617 static size_t PingStream(const Image *magick_unused(image),
2618 const void *magick_unused(pixels),const size_t columns)
2623 #if defined(__cplusplus) || defined(c_plusplus)
2627 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2628 const size_t length,ExceptionInfo *exception)
2636 assert(image_info != (ImageInfo *) NULL);
2637 assert(image_info->signature == MagickSignature);
2638 if (image_info->debug != MagickFalse)
2639 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2640 image_info->filename);
2641 assert(exception != (ExceptionInfo *) NULL);
2642 if ((blob == (const void *) NULL) || (length == 0))
2644 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2645 "UnrecognizedImageFormat","`%s'",image_info->magick);
2646 return((Image *) NULL);
2648 ping_info=CloneImageInfo(image_info);
2649 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2650 if (ping_info->blob == (const void *) NULL)
2652 (void) ThrowMagickException(exception,GetMagickModule(),
2653 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2654 return((Image *) NULL);
2656 (void) memcpy(ping_info->blob,blob,length);
2657 ping_info->length=length;
2658 ping_info->ping=MagickTrue;
2659 image=ReadStream(ping_info,&PingStream,exception);
2660 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2661 ping_info=DestroyImageInfo(ping_info);
2666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2676 % ReadBlob() reads data from the blob or image file and returns it. It
2677 % returns the number of bytes read.
2679 % The format of the ReadBlob method is:
2681 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2683 % A description of each parameter follows:
2685 % o image: the image.
2687 % o length: Specifies an integer representing the number of bytes to read
2690 % o data: Specifies an area to place the information requested from the
2694 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2695 unsigned char *data)
2700 register unsigned char
2706 assert(image != (Image *) NULL);
2707 assert(image->signature == MagickSignature);
2708 assert(image->blob != (BlobInfo *) NULL);
2709 assert(image->blob->type != UndefinedStream);
2712 assert(data != (void *) NULL);
2715 switch (image->blob->type)
2717 case UndefinedStream:
2720 case StandardStream:
2727 count=(ssize_t) fread(q,1,length,image->blob->file);
2732 c=getc(image->blob->file);
2735 *q++=(unsigned char) c;
2740 c=getc(image->blob->file);
2743 *q++=(unsigned char) c;
2753 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2758 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2763 c=gzgetc(image->blob->file);
2766 *q++=(unsigned char) c;
2771 c=gzgetc(image->blob->file);
2774 *q++=(unsigned char) c;
2785 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2786 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2794 register const unsigned char
2797 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2799 image->blob->eof=MagickTrue;
2802 p=image->blob->data+image->blob->offset;
2803 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2804 image->blob->offset));
2805 image->blob->offset+=count;
2806 if (count != (ssize_t) length)
2807 image->blob->eof=MagickTrue;
2808 (void) memcpy(q,p,(size_t) count);
2816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2820 + R e a d B l o b B y t e %
2824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2826 % ReadBlobByte() reads a single byte from the image file and returns it.
2828 % The format of the ReadBlobByte method is:
2830 % int ReadBlobByte(Image *image)
2832 % A description of each parameter follows.
2834 % o image: the image.
2837 MagickExport int ReadBlobByte(Image *image)
2839 register const unsigned char
2848 assert(image != (Image *) NULL);
2849 assert(image->signature == MagickSignature);
2850 p=ReadBlobStream(image,1,buffer,&count);
2857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2861 + R e a d B l o b D o u b l e %
2865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2867 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2868 % specified by the endian member of the image structure.
2870 % The format of the ReadBlobDouble method is:
2872 % double ReadBlobDouble(Image *image)
2874 % A description of each parameter follows.
2876 % o image: the image.
2879 MagickExport double ReadBlobDouble(Image *image)
2890 quantum.double_value=0.0;
2891 quantum.unsigned_value=ReadBlobLongLong(image);
2892 return(quantum.double_value);
2896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2900 + R e a d B l o b F l o a t %
2904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2906 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2907 % specified by the endian member of the image structure.
2909 % The format of the ReadBlobFloat method is:
2911 % float ReadBlobFloat(Image *image)
2913 % A description of each parameter follows.
2915 % o image: the image.
2918 MagickExport float ReadBlobFloat(Image *image)
2929 quantum.float_value=0.0;
2930 quantum.unsigned_value=ReadBlobLong(image);
2931 return(quantum.float_value);
2935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2939 + R e a d B l o b L o n g %
2943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2945 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2946 % specified by the endian member of the image structure.
2948 % The format of the ReadBlobLong method is:
2950 % unsigned int ReadBlobLong(Image *image)
2952 % A description of each parameter follows.
2954 % o image: the image.
2957 MagickExport unsigned int ReadBlobLong(Image *image)
2959 register const unsigned char
2971 assert(image != (Image *) NULL);
2972 assert(image->signature == MagickSignature);
2974 p=ReadBlobStream(image,4,buffer,&count);
2977 if (image->endian == LSBEndian)
2979 value=(unsigned int) (*p++);
2980 value|=((unsigned int) (*p++)) << 8;
2981 value|=((unsigned int) (*p++)) << 16;
2982 value|=((unsigned int) (*p++)) << 24;
2985 value=((unsigned int) (*p++)) << 24;
2986 value|=((unsigned int) (*p++)) << 16;
2987 value|=((unsigned int) (*p++)) << 8;
2988 value|=((unsigned int) (*p++));
2993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2997 + R e a d B l o b L o n g L o n g %
3001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3003 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3004 % byte-order specified by the endian member of the image structure.
3006 % The format of the ReadBlobLongLong method is:
3008 % MagickSizeType ReadBlobLongLong(Image *image)
3010 % A description of each parameter follows.
3012 % o image: the image.
3015 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3017 register const unsigned char
3029 assert(image != (Image *) NULL);
3030 assert(image->signature == MagickSignature);
3032 p=ReadBlobStream(image,8,buffer,&count);
3034 return(MagickULLConstant(0));
3035 if (image->endian == LSBEndian)
3037 value=(MagickSizeType) (*p++);
3038 value|=((MagickSizeType) (*p++)) << 8;
3039 value|=((MagickSizeType) (*p++)) << 16;
3040 value|=((MagickSizeType) (*p++)) << 24;
3041 value|=((MagickSizeType) (*p++)) << 32;
3042 value|=((MagickSizeType) (*p++)) << 40;
3043 value|=((MagickSizeType) (*p++)) << 48;
3044 value|=((MagickSizeType) (*p++)) << 56;
3045 return(value & MagickULLConstant(0xffffffffffffffff));
3047 value=((MagickSizeType) (*p++)) << 56;
3048 value|=((MagickSizeType) (*p++)) << 48;
3049 value|=((MagickSizeType) (*p++)) << 40;
3050 value|=((MagickSizeType) (*p++)) << 32;
3051 value|=((MagickSizeType) (*p++)) << 24;
3052 value|=((MagickSizeType) (*p++)) << 16;
3053 value|=((MagickSizeType) (*p++)) << 8;
3054 value|=((MagickSizeType) (*p++));
3055 return(value & MagickULLConstant(0xffffffffffffffff));
3059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3063 + R e a d B l o b S h o r t %
3067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3069 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3070 % specified by the endian member of the image structure.
3072 % The format of the ReadBlobShort method is:
3074 % unsigned short ReadBlobShort(Image *image)
3076 % A description of each parameter follows.
3078 % o image: the image.
3081 MagickExport unsigned short ReadBlobShort(Image *image)
3083 register const unsigned char
3086 register unsigned int
3095 assert(image != (Image *) NULL);
3096 assert(image->signature == MagickSignature);
3098 p=ReadBlobStream(image,2,buffer,&count);
3100 return((unsigned short) 0U);
3101 if (image->endian == LSBEndian)
3103 value=(unsigned int) (*p++);
3104 value|=((unsigned int) (*p++)) << 8;
3105 return((unsigned short) (value & 0xffff));
3107 value=(unsigned int) ((*p++) << 8);
3108 value|=(unsigned int) (*p++);
3109 return((unsigned short) (value & 0xffff));
3113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3117 + R e a d B l o b L S B L o n g %
3121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3123 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3124 % least-significant byte first order.
3126 % The format of the ReadBlobLSBLong method is:
3128 % unsigned int ReadBlobLSBLong(Image *image)
3130 % A description of each parameter follows.
3132 % o image: the image.
3135 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3137 register const unsigned char
3140 register unsigned int
3149 assert(image != (Image *) NULL);
3150 assert(image->signature == MagickSignature);
3152 p=ReadBlobStream(image,4,buffer,&count);
3155 value=(unsigned int) (*p++);
3156 value|=((unsigned int) (*p++)) << 8;
3157 value|=((unsigned int) (*p++)) << 16;
3158 value|=((unsigned int) (*p++)) << 24;
3163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3167 + R e a d B l o b L S B S h o r t %
3171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3173 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3174 % least-significant byte first order.
3176 % The format of the ReadBlobLSBShort method is:
3178 % unsigned short ReadBlobLSBShort(Image *image)
3180 % A description of each parameter follows.
3182 % o image: the image.
3185 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3187 register const unsigned char
3190 register unsigned int
3199 assert(image != (Image *) NULL);
3200 assert(image->signature == MagickSignature);
3202 p=ReadBlobStream(image,2,buffer,&count);
3204 return((unsigned short) 0U);
3205 value=(unsigned int) (*p++);
3206 value|=((unsigned int) ((*p++)) << 8);
3207 return((unsigned short) (value & 0xffff));
3211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3215 + R e a d B l o b M S B L o n g %
3219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3221 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3222 % most-significant byte first order.
3224 % The format of the ReadBlobMSBLong method is:
3226 % unsigned int ReadBlobMSBLong(Image *image)
3228 % A description of each parameter follows.
3230 % o image: the image.
3233 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3235 register const unsigned char
3238 register unsigned int
3247 assert(image != (Image *) NULL);
3248 assert(image->signature == MagickSignature);
3250 p=ReadBlobStream(image,4,buffer,&count);
3253 value=((unsigned int) (*p++) << 24);
3254 value|=((unsigned int) (*p++) << 16);
3255 value|=((unsigned int) (*p++) << 8);
3256 value|=(unsigned int) (*p++);
3261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3265 + R e a d B l o b M S B L o n g L o n g %
3269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3271 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3272 % most-significant byte first order.
3274 % The format of the ReadBlobMSBLongLong method is:
3276 % unsigned int ReadBlobMSBLongLong(Image *image)
3278 % A description of each parameter follows.
3280 % o image: the image.
3283 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3285 register const unsigned char
3288 register MagickSizeType
3297 assert(image != (Image *) NULL);
3298 assert(image->signature == MagickSignature);
3300 p=ReadBlobStream(image,8,buffer,&count);
3302 return(MagickULLConstant(0));
3303 value=((MagickSizeType) (*p++)) << 56;
3304 value|=((MagickSizeType) (*p++)) << 48;
3305 value|=((MagickSizeType) (*p++)) << 40;
3306 value|=((MagickSizeType) (*p++)) << 32;
3307 value|=((MagickSizeType) (*p++)) << 24;
3308 value|=((MagickSizeType) (*p++)) << 16;
3309 value|=((MagickSizeType) (*p++)) << 8;
3310 value|=((MagickSizeType) (*p++));
3311 return(value & MagickULLConstant(0xffffffffffffffff));
3315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3319 + R e a d B l o b M S B S h o r t %
3323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3325 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3326 % most-significant byte first order.
3328 % The format of the ReadBlobMSBShort method is:
3330 % unsigned short ReadBlobMSBShort(Image *image)
3332 % A description of each parameter follows.
3334 % o image: the image.
3337 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3339 register const unsigned char
3342 register unsigned int
3351 assert(image != (Image *) NULL);
3352 assert(image->signature == MagickSignature);
3354 p=ReadBlobStream(image,2,buffer,&count);
3356 return((unsigned short) 0U);
3357 value=(unsigned int) ((*p++) << 8);
3358 value|=(unsigned int) (*p++);
3359 return((unsigned short) (value & 0xffff));
3363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3367 + R e a d B l o b S t r i n g %
3371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3373 % ReadBlobString() reads characters from a blob or file until a newline
3374 % character is read or an end-of-file condition is encountered.
3376 % The format of the ReadBlobString method is:
3378 % char *ReadBlobString(Image *image,char *string)
3380 % A description of each parameter follows:
3382 % o image: the image.
3384 % o string: the address of a character buffer.
3387 MagickExport char *ReadBlobString(Image *image,char *string)
3389 register const unsigned char
3401 assert(image != (Image *) NULL);
3402 assert(image->signature == MagickSignature);
3403 for (i=0; i < (MaxTextExtent-1L); i++)
3405 p=ReadBlobStream(image,1,buffer,&count);
3409 return((char *) NULL);
3412 string[i]=(char) (*p);
3413 if ((string[i] == '\r') || (string[i] == '\n'))
3416 if (string[i] == '\r')
3417 (void) ReadBlobStream(image,1,buffer,&count);
3423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3427 + R e f e r e n c e B l o b %
3431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3433 % ReferenceBlob() increments the reference count associated with the pixel
3434 % blob returning a pointer to the blob.
3436 % The format of the ReferenceBlob method is:
3438 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3440 % A description of each parameter follows:
3442 % o blob_info: the blob_info.
3445 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3447 assert(blob != (BlobInfo *) NULL);
3448 assert(blob->signature == MagickSignature);
3449 if (blob->debug != MagickFalse)
3450 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3451 LockSemaphoreInfo(blob->semaphore);
3452 blob->reference_count++;
3453 UnlockSemaphoreInfo(blob->semaphore);
3458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3468 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3469 % and returns the resulting offset.
3471 % The format of the SeekBlob method is:
3473 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3476 % A description of each parameter follows:
3478 % o image: the image.
3480 % o offset: Specifies an integer representing the offset in bytes.
3482 % o whence: Specifies an integer representing how the offset is
3483 % treated relative to the beginning of the blob as follows:
3485 % SEEK_SET Set position equal to offset bytes.
3486 % SEEK_CUR Set position to current location plus offset.
3487 % SEEK_END Set position to EOF plus offset.
3490 MagickExport MagickOffsetType SeekBlob(Image *image,
3491 const MagickOffsetType offset,const int whence)
3493 assert(image != (Image *) NULL);
3494 assert(image->signature == MagickSignature);
3495 if (image->debug != MagickFalse)
3496 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3497 assert(image->blob != (BlobInfo *) NULL);
3498 assert(image->blob->type != UndefinedStream);
3499 switch (image->blob->type)
3501 case UndefinedStream:
3505 if (fseek(image->blob->file,(long) offset,whence) < 0)
3507 image->blob->offset=TellBlob(image);
3510 case StandardStream:
3514 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3515 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3518 image->blob->offset=TellBlob(image);
3534 image->blob->offset=offset;
3539 if ((image->blob->offset+offset) < 0)
3541 image->blob->offset+=offset;
3546 if (((MagickOffsetType) image->blob->length+offset) < 0)
3548 image->blob->offset=image->blob->length+offset;
3552 if (image->blob->offset <= (MagickOffsetType)
3553 ((off_t) image->blob->length))
3554 image->blob->eof=MagickFalse;
3556 if (image->blob->mapped != MagickFalse)
3560 image->blob->extent=(size_t) (image->blob->offset+
3561 image->blob->quantum);
3562 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3563 image->blob->data,image->blob->extent+1,
3564 sizeof(*image->blob->data));
3565 (void) SyncBlob(image);
3566 if (image->blob->data == (unsigned char *) NULL)
3568 (void) DetachBlob(image->blob);
3575 return(image->blob->offset);
3579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3583 + S e t B l o b E x e m p t %
3587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3589 % SetBlobExempt() sets the blob exempt status.
3591 % The format of the SetBlobExempt method is:
3593 % MagickBooleanType SetBlobExempt(const Image *image,
3594 % const MagickBooleanType exempt)
3596 % A description of each parameter follows:
3598 % o image: the image.
3600 % o exempt: Set to true if this blob is exempt from being closed.
3603 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3605 assert(image != (const Image *) NULL);
3606 assert(image->signature == MagickSignature);
3607 if (image->debug != MagickFalse)
3608 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3609 image->blob->exempt=exempt;
3613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3617 + S e t B l o b E x t e n t %
3621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3623 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3624 % method is successful, subsequent writes to bytes in the specified range are
3625 % guaranteed not to fail.
3627 % The format of the SetBlobExtent method is:
3629 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3631 % A description of each parameter follows:
3633 % o image: the image.
3635 % o extent: the blob maximum extent.
3638 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3639 const MagickSizeType extent)
3641 assert(image != (Image *) NULL);
3642 assert(image->signature == MagickSignature);
3643 if (image->debug != MagickFalse)
3644 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3645 assert(image->blob != (BlobInfo *) NULL);
3646 assert(image->blob->type != UndefinedStream);
3647 switch (image->blob->type)
3649 case UndefinedStream:
3653 if (extent != (MagickSizeType) ((off_t) extent))
3654 return(MagickFalse);
3655 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3656 return(MagickFalse);
3665 offset=TellBlob(image);
3666 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3667 (off_t) (extent-offset));
3669 return(MagickFalse);
3674 case StandardStream:
3677 return(MagickFalse);
3679 return(MagickFalse);
3681 return(MagickFalse);
3684 if (image->blob->mapped != MagickFalse)
3686 if (image->blob->file == (FILE *) NULL)
3687 return(MagickFalse);
3688 (void) UnmapBlob(image->blob->data,image->blob->length);
3689 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3690 return(MagickFalse);
3699 offset=TellBlob(image);
3700 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3701 (off_t) (extent-offset));
3703 return(MagickFalse);
3705 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3706 WriteMode,0,(size_t) extent);
3707 image->blob->extent=(size_t) extent;
3708 image->blob->length=(size_t) extent;
3709 (void) SyncBlob(image);
3713 if (extent != (MagickSizeType) ((size_t) extent))
3714 return(MagickFalse);
3715 image->blob->extent=(size_t) extent;
3716 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3717 image->blob->extent+1,sizeof(*image->blob->data));
3718 (void) SyncBlob(image);
3719 if (image->blob->data == (unsigned char *) NULL)
3721 (void) DetachBlob(image->blob);
3722 return(MagickFalse);
3731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3741 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3742 % attributes if it is an blob.
3744 % The format of the SyncBlob method is:
3746 % int SyncBlob(Image *image)
3748 % A description of each parameter follows:
3750 % o image: the image.
3753 static int SyncBlob(Image *image)
3758 assert(image != (Image *) NULL);
3759 assert(image->signature == MagickSignature);
3760 if (image->debug != MagickFalse)
3761 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3762 assert(image->blob != (BlobInfo *) NULL);
3763 assert(image->blob->type != UndefinedStream);
3765 switch (image->blob->type)
3767 case UndefinedStream:
3770 case StandardStream:
3773 status=fflush(image->blob->file);
3778 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3779 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3785 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3786 status=BZ2_bzflush((BZFILE *) image->blob->file);
3794 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3795 if (image->blob->mapped != MagickFalse)
3796 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3815 % TellBlob() obtains the current value of the blob or file position.
3817 % The format of the TellBlob method is:
3819 % MagickOffsetType TellBlob(const Image *image)
3821 % A description of each parameter follows:
3823 % o image: the image.
3826 MagickExport MagickOffsetType TellBlob(const Image *image)
3831 assert(image != (Image *) NULL);
3832 assert(image->signature == MagickSignature);
3833 if (image->debug != MagickFalse)
3834 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3835 assert(image->blob != (BlobInfo *) NULL);
3836 assert(image->blob->type != UndefinedStream);
3838 switch (image->blob->type)
3840 case UndefinedStream:
3844 offset=ftell(image->blob->file);
3847 case StandardStream:
3852 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3853 offset=(MagickOffsetType) gztell(image->blob->file);
3863 offset=image->blob->offset;
3871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3875 + U n m a p B l o b %
3879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3881 % UnmapBlob() deallocates the binary large object previously allocated with
3882 % the MapBlob method.
3884 % The format of the UnmapBlob method is:
3886 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3888 % A description of each parameter follows:
3890 % o map: the address of the binary large object.
3892 % o length: the length of the binary large object.
3895 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3897 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3901 status=munmap(map,length);
3902 return(status == -1 ? MagickFalse : MagickTrue);
3906 return(MagickFalse);
3911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3915 + W r i t e B l o b %
3919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3921 % WriteBlob() writes data to a blob or image file. It returns the number of
3924 % The format of the WriteBlob method is:
3926 % ssize_t WriteBlob(Image *image,const size_t length,
3927 % const unsigned char *data)
3929 % A description of each parameter follows:
3931 % o image: the image.
3933 % o length: Specifies an integer representing the number of bytes to
3934 % write to the file.
3936 % o data: The address of the data to write to the blob or file.
3939 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3940 const unsigned char *data)
3945 register const unsigned char
3951 assert(image != (Image *) NULL);
3952 assert(image->signature == MagickSignature);
3953 assert(data != (const unsigned char *) NULL);
3954 assert(image->blob != (BlobInfo *) NULL);
3955 assert(image->blob->type != UndefinedStream);
3960 switch (image->blob->type)
3962 case UndefinedStream:
3965 case StandardStream:
3972 count=(ssize_t) fwrite((const char *) data,1,length,
3978 c=putc((int) *p++,image->blob->file);
3985 c=putc((int) *p++,image->blob->file);
3997 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4002 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4003 (unsigned int) length);
4008 c=gzputc(image->blob->file,(int) *p++);
4015 c=gzputc(image->blob->file,(int) *p++);
4028 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4029 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4036 count=(ssize_t) image->blob->stream(image,data,length);
4041 register unsigned char
4044 if ((image->blob->offset+(MagickOffsetType) length) >=
4045 (MagickOffsetType) image->blob->extent)
4047 if (image->blob->mapped != MagickFalse)
4049 image->blob->quantum<<=1;
4050 image->blob->extent+=length+image->blob->quantum;
4051 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4052 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4053 (void) SyncBlob(image);
4054 if (image->blob->data == (unsigned char *) NULL)
4056 (void) DetachBlob(image->blob);
4060 q=image->blob->data+image->blob->offset;
4061 (void) memcpy(q,p,length);
4062 image->blob->offset+=length;
4063 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4064 image->blob->length=(size_t) image->blob->offset;
4065 count=(ssize_t) length;
4072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4076 + W r i t e B l o b B y t e %
4080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4082 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4083 % written (either 0 or 1);
4085 % The format of the WriteBlobByte method is:
4087 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4089 % A description of each parameter follows.
4091 % o image: the image.
4093 % o value: Specifies the value to write.
4096 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4098 assert(image != (Image *) NULL);
4099 assert(image->signature == MagickSignature);
4100 return(WriteBlobStream(image,1,&value));
4104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4108 + W r i t e B l o b F l o a t %
4112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4114 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4115 % specified by the endian member of the image structure.
4117 % The format of the WriteBlobFloat method is:
4119 % ssize_t WriteBlobFloat(Image *image,const float value)
4121 % A description of each parameter follows.
4123 % o image: the image.
4125 % o value: Specifies the value to write.
4128 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4139 quantum.unsigned_value=0U;
4140 quantum.float_value=value;
4141 return(WriteBlobLong(image,quantum.unsigned_value));
4145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4149 + W r i t e B l o b L o n g %
4153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4155 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4156 % specified by the endian member of the image structure.
4158 % The format of the WriteBlobLong method is:
4160 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4162 % A description of each parameter follows.
4164 % o image: the image.
4166 % o value: Specifies the value to write.
4169 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4174 assert(image != (Image *) NULL);
4175 assert(image->signature == MagickSignature);
4176 if (image->endian == LSBEndian)
4178 buffer[0]=(unsigned char) value;
4179 buffer[1]=(unsigned char) (value >> 8);
4180 buffer[2]=(unsigned char) (value >> 16);
4181 buffer[3]=(unsigned char) (value >> 24);
4182 return(WriteBlobStream(image,4,buffer));
4184 buffer[0]=(unsigned char) (value >> 24);
4185 buffer[1]=(unsigned char) (value >> 16);
4186 buffer[2]=(unsigned char) (value >> 8);
4187 buffer[3]=(unsigned char) value;
4188 return(WriteBlobStream(image,4,buffer));
4192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4196 + W r i t e B l o b S h o r t %
4200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4202 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4203 % byte-order specified by the endian member of the image structure.
4205 % The format of the WriteBlobShort method is:
4207 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4209 % A description of each parameter follows.
4211 % o image: the image.
4213 % o value: Specifies the value to write.
4216 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4221 assert(image != (Image *) NULL);
4222 assert(image->signature == MagickSignature);
4223 if (image->endian == LSBEndian)
4225 buffer[0]=(unsigned char) value;
4226 buffer[1]=(unsigned char) (value >> 8);
4227 return(WriteBlobStream(image,2,buffer));
4229 buffer[0]=(unsigned char) (value >> 8);
4230 buffer[1]=(unsigned char) value;
4231 return(WriteBlobStream(image,2,buffer));
4235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4239 + W r i t e B l o b L S B L o n g %
4243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4245 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4246 % least-significant byte first order.
4248 % The format of the WriteBlobLSBLong method is:
4250 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4252 % A description of each parameter follows.
4254 % o image: the image.
4256 % o value: Specifies the value to write.
4259 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4264 assert(image != (Image *) NULL);
4265 assert(image->signature == MagickSignature);
4266 buffer[0]=(unsigned char) value;
4267 buffer[1]=(unsigned char) (value >> 8);
4268 buffer[2]=(unsigned char) (value >> 16);
4269 buffer[3]=(unsigned char) (value >> 24);
4270 return(WriteBlobStream(image,4,buffer));
4274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4278 + W r i t e B l o b L S B S h o r t %
4282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4284 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4285 % least-significant byte first order.
4287 % The format of the WriteBlobLSBShort method is:
4289 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4291 % A description of each parameter follows.
4293 % o image: the image.
4295 % o value: Specifies the value to write.
4298 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4303 assert(image != (Image *) NULL);
4304 assert(image->signature == MagickSignature);
4305 buffer[0]=(unsigned char) value;
4306 buffer[1]=(unsigned char) (value >> 8);
4307 return(WriteBlobStream(image,2,buffer));
4311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4315 + W r i t e B l o b M S B L o n g %
4319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4321 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4322 % most-significant byte first order.
4324 % The format of the WriteBlobMSBLong method is:
4326 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4328 % A description of each parameter follows.
4330 % o value: Specifies the value to write.
4332 % o image: the image.
4335 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4340 assert(image != (Image *) NULL);
4341 assert(image->signature == MagickSignature);
4342 buffer[0]=(unsigned char) (value >> 24);
4343 buffer[1]=(unsigned char) (value >> 16);
4344 buffer[2]=(unsigned char) (value >> 8);
4345 buffer[3]=(unsigned char) value;
4346 return(WriteBlobStream(image,4,buffer));
4350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4354 + W r i t e B l o b M S B L o n g L o n g %
4358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4360 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4361 % most-significant byte first order.
4363 % The format of the WriteBlobMSBLongLong method is:
4365 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4367 % A description of each parameter follows.
4369 % o value: Specifies the value to write.
4371 % o image: the image.
4374 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4375 const MagickSizeType value)
4380 assert(image != (Image *) NULL);
4381 assert(image->signature == MagickSignature);
4382 buffer[0]=(unsigned char) (value >> 56);
4383 buffer[1]=(unsigned char) (value >> 48);
4384 buffer[2]=(unsigned char) (value >> 40);
4385 buffer[3]=(unsigned char) (value >> 32);
4386 buffer[4]=(unsigned char) (value >> 24);
4387 buffer[5]=(unsigned char) (value >> 16);
4388 buffer[6]=(unsigned char) (value >> 8);
4389 buffer[7]=(unsigned char) value;
4390 return(WriteBlobStream(image,8,buffer));
4394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4398 + W r i t e B l o b M S B S h o r t %
4402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4404 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4405 % most-significant byte first order.
4407 % The format of the WriteBlobMSBShort method is:
4409 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4411 % A description of each parameter follows.
4413 % o value: Specifies the value to write.
4415 % o file: Specifies the file to write the data to.
4418 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4423 assert(image != (Image *) NULL);
4424 assert(image->signature == MagickSignature);
4425 buffer[0]=(unsigned char) (value >> 8);
4426 buffer[1]=(unsigned char) value;
4427 return(WriteBlobStream(image,2,buffer));
4431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4435 + W r i t e B l o b S t r i n g %
4439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4441 % WriteBlobString() write a string to a blob. It returns the number of
4442 % characters written.
4444 % The format of the WriteBlobString method is:
4446 % ssize_t WriteBlobString(Image *image,const char *string)
4448 % A description of each parameter follows.
4450 % o image: the image.
4452 % o string: Specifies the string to write.
4455 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4457 assert(image != (Image *) NULL);
4458 assert(image->signature == MagickSignature);
4459 assert(string != (const char *) NULL);
4460 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));