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)
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 u p l i c a t e s B l o b %
672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
674 % DuplicateBlob() duplicates a blob descriptor.
676 % The format of the DuplicateBlob method is:
678 % void DuplicateBlob(Image *image,const Image *duplicate)
680 % A description of each parameter follows:
682 % o image: the image.
684 % o duplicate: the duplicate image.
687 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
689 assert(image != (Image *) NULL);
690 assert(image->signature == MagickSignature);
691 if (image->debug != MagickFalse)
692 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
693 assert(duplicate != (Image *) NULL);
694 assert(duplicate->signature == MagickSignature);
696 image->blob=ReferenceBlob(duplicate->blob);
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 % EOFBlob() returns a non-zero value when EOF has been detected reading from
713 % The format of the EOFBlob method is:
715 % int EOFBlob(const Image *image)
717 % A description of each parameter follows:
719 % o image: the image.
722 MagickExport int EOFBlob(const Image *image)
724 assert(image != (Image *) NULL);
725 assert(image->signature == MagickSignature);
726 if (image->debug != MagickFalse)
727 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
728 assert(image->blob != (BlobInfo *) NULL);
729 assert(image->blob->type != UndefinedStream);
730 switch (image->blob->type)
732 case UndefinedStream:
738 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
743 image->blob->eof=MagickFalse;
748 #if defined(MAGICKCORE_BZLIB_DELEGATE)
753 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
754 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
760 image->blob->eof=MagickFalse;
766 return((int) image->blob->eof);
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
774 + F i l e T o B l o b %
778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
780 % FileToBlob() returns the contents of a file as a blob. It returns the
781 % file as a blob and its length. If an error occurs, NULL is returned.
783 % The format of the FileToBlob method is:
785 % unsigned char *FileToBlob(const char *filename,const size_t extent,
786 % size_t *length,ExceptionInfo *exception)
788 % A description of each parameter follows:
790 % o blob: FileToBlob() returns the contents of a file as a blob. If
791 % an error occurs NULL is returned.
793 % o filename: the filename.
795 % o extent: The maximum length of the blob.
797 % o length: On return, this reflects the actual length of the blob.
799 % o exception: return any errors or warnings in this structure.
802 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
803 size_t *length,ExceptionInfo *exception)
823 assert(filename != (const char *) NULL);
824 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
825 assert(exception != (ExceptionInfo *) NULL);
828 if (LocaleCompare(filename,"-") != 0)
829 file=open(filename,O_RDONLY | O_BINARY);
832 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
833 return((unsigned char *) NULL);
835 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
837 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
846 Stream is not seekable.
848 quantum=(size_t) MagickMaxBufferExtent;
849 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
850 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
851 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
852 for (i=0; blob != (unsigned char *) NULL; i+=count)
854 count=(ssize_t) read(file,blob+i,quantum);
861 if (~(1UL*i) < (quantum+1))
863 blob=(unsigned char *) RelinquishMagickMemory(blob);
866 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
868 if ((size_t) (i+count) >= extent)
872 if (blob == (unsigned char *) NULL)
874 (void) ThrowMagickException(exception,GetMagickModule(),
875 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
876 return((unsigned char *) NULL);
878 *length=MagickMin(i+count,extent);
882 *length=MagickMin((size_t) offset,extent);
883 blob=(unsigned char *) NULL;
884 if (~(*length) >= MaxTextExtent)
885 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
887 if (blob == (unsigned char *) NULL)
890 (void) ThrowMagickException(exception,GetMagickModule(),
891 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
892 return((unsigned char *) NULL);
894 map=MapBlob(file,ReadMode,0,*length);
895 if (map != (unsigned char *) NULL)
897 (void) CopyMagickMemory(blob,map,*length);
898 (void) UnmapBlob(map,*length);
902 (void) MagickSeek(file,0,SEEK_SET);
903 for (i=0; i < *length; i+=count)
905 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
917 blob=(unsigned char *) RelinquishMagickMemory(blob);
918 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
919 return((unsigned char *) NULL);
928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932 % F i l e T o I m a g e %
936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
938 % FileToImage() write the contents of a file to an image.
940 % The format of the FileToImage method is:
942 % MagickBooleanType FileToImage(Image *,const char *filename)
944 % A description of each parameter follows:
946 % o image: the image.
948 % o filename: the filename.
952 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
953 const unsigned char *data)
958 register unsigned char
961 assert(image->blob != (BlobInfo *) NULL);
962 if (image->blob->type != BlobStream)
963 return(WriteBlob(image,length,data));
964 assert(image->blob->type != UndefinedStream);
965 assert(data != (void *) NULL);
966 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
967 if (extent >= image->blob->extent)
969 image->blob->quantum<<=1;
970 extent=image->blob->extent+image->blob->quantum+length;
971 if (SetBlobExtent(image,extent) == MagickFalse)
974 q=image->blob->data+image->blob->offset;
975 (void) CopyMagickMemory(q,data,length);
976 image->blob->offset+=length;
977 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
978 image->blob->length=(size_t) image->blob->offset;
979 return((ssize_t) length);
982 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1000 assert(image != (const Image *) NULL);
1001 assert(image->signature == MagickSignature);
1002 assert(filename != (const char *) NULL);
1003 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1004 file=open(filename,O_RDONLY | O_BINARY);
1007 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1009 return(MagickFalse);
1011 quantum=(size_t) MagickMaxBufferExtent;
1012 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1013 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1014 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1015 if (blob == (unsigned char *) NULL)
1017 ThrowFileException(&image->exception,ResourceLimitError,
1018 "MemoryAllocationFailed",filename);
1019 return(MagickFalse);
1023 count=(ssize_t) read(file,blob,quantum);
1030 length=(size_t) count;
1031 count=WriteBlobStream(image,length,blob);
1032 if (count != (ssize_t) length)
1034 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1040 blob=(unsigned char *) RelinquishMagickMemory(blob);
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049 + G e t B l o b E r r o r %
1053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1055 % GetBlobError() returns MagickTrue if the blob associated with the specified
1056 % image encountered an error.
1058 % The format of the GetBlobError method is:
1060 % MagickBooleanType GetBlobError(const Image *image)
1062 % A description of each parameter follows:
1064 % o image: the image.
1067 MagickExport MagickBooleanType GetBlobError(const Image *image)
1069 assert(image != (const Image *) NULL);
1070 assert(image->signature == MagickSignature);
1071 if (image->debug != MagickFalse)
1072 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1073 return(image->blob->status);
1077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081 + G e t B l o b F i l e H a n d l e %
1085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087 % GetBlobFileHandle() returns the file handle associated with the image blob.
1089 % The format of the GetBlobFile method is:
1091 % FILE *GetBlobFileHandle(const Image *image)
1093 % A description of each parameter follows:
1095 % o image: the image.
1098 MagickExport FILE *GetBlobFileHandle(const Image *image)
1100 assert(image != (const Image *) NULL);
1101 assert(image->signature == MagickSignature);
1102 return(image->blob->file);
1106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110 + G e t B l o b I n f o %
1114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1116 % GetBlobInfo() initializes the BlobInfo structure.
1118 % The format of the GetBlobInfo method is:
1120 % void GetBlobInfo(BlobInfo *blob_info)
1122 % A description of each parameter follows:
1124 % o blob_info: Specifies a pointer to a BlobInfo structure.
1127 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1129 assert(blob_info != (BlobInfo *) NULL);
1130 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1131 blob_info->type=UndefinedStream;
1132 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1133 blob_info->properties.st_mtime=time((time_t *) NULL);
1134 blob_info->properties.st_ctime=time((time_t *) NULL);
1135 blob_info->debug=IsEventLogging();
1136 blob_info->reference_count=1;
1137 blob_info->semaphore=AllocateSemaphoreInfo();
1138 blob_info->signature=MagickSignature;
1142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1146 % G e t B l o b P r o p e r t i e s %
1150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1152 % GetBlobProperties() returns information about an image blob.
1154 % The format of the GetBlobProperties method is:
1156 % const struct stat *GetBlobProperties(const Image *image)
1158 % A description of each parameter follows:
1160 % o image: the image.
1163 MagickExport const struct stat *GetBlobProperties(const Image *image)
1165 assert(image != (Image *) NULL);
1166 assert(image->signature == MagickSignature);
1167 if (image->debug != MagickFalse)
1168 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1169 return(&image->blob->properties);
1173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177 + G e t B l o b S i z e %
1181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1183 % GetBlobSize() returns the current length of the image file or blob; zero is
1184 % returned if the size cannot be determined.
1186 % The format of the GetBlobSize method is:
1188 % MagickSizeType GetBlobSize(const Image *image)
1190 % A description of each parameter follows:
1192 % o image: the image.
1195 MagickExport MagickSizeType GetBlobSize(const Image *image)
1200 assert(image != (Image *) NULL);
1201 assert(image->signature == MagickSignature);
1202 if (image->debug != MagickFalse)
1203 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1204 assert(image->blob != (BlobInfo *) NULL);
1206 switch (image->blob->type)
1208 case UndefinedStream:
1210 extent=image->blob->size;
1215 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1216 extent=(MagickSizeType) image->blob->properties.st_size;
1219 case StandardStream:
1222 extent=image->blob->size;
1231 status=GetPathAttributes(image->filename,&image->blob->properties);
1232 if (status != MagickFalse)
1233 extent=(MagickSizeType) image->blob->properties.st_size;
1240 extent=(MagickSizeType) image->blob->length;
1248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1252 + G e t B l o b S t r e a m D a t a %
1256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1258 % GetBlobStreamData() returns the stream data for the image.
1260 % The format of the GetBlobStreamData method is:
1262 % unsigned char *GetBlobStreamData(const Image *image)
1264 % A description of each parameter follows:
1266 % o image: the image.
1269 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1271 assert(image != (const Image *) NULL);
1272 assert(image->signature == MagickSignature);
1273 return(image->blob->data);
1277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1281 + G e t B l o b S t r e a m H a n d l e r %
1285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1287 % GetBlobStreamHandler() returns the stream handler for the image.
1289 % The format of the GetBlobStreamHandler method is:
1291 % StreamHandler GetBlobStreamHandler(const Image *image)
1293 % A description of each parameter follows:
1295 % o image: the image.
1298 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1300 assert(image != (const Image *) NULL);
1301 assert(image->signature == MagickSignature);
1302 if (image->debug != MagickFalse)
1303 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1304 return(image->blob->stream);
1308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1312 % I m a g e T o B l o b %
1316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318 % ImageToBlob() implements direct to memory image formats. It returns the
1319 % image as a blob and its length. The magick member of the ImageInfo structure
1320 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1322 % The format of the ImageToBlob method is:
1324 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1325 % size_t *length,ExceptionInfo *exception)
1327 % A description of each parameter follows:
1329 % o image_info: the image info.
1331 % o image: the image.
1333 % o length: This pointer to a size_t integer sets the initial length of the
1334 % blob. On return, it reflects the actual length of the blob.
1336 % o exception: return any errors or warnings in this structure.
1339 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1340 Image *image,size_t *length,ExceptionInfo *exception)
1354 assert(image_info != (const ImageInfo *) NULL);
1355 assert(image_info->signature == MagickSignature);
1356 if (image_info->debug != MagickFalse)
1357 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1358 image_info->filename);
1359 assert(image != (Image *) NULL);
1360 assert(image->signature == MagickSignature);
1361 assert(exception != (ExceptionInfo *) NULL);
1363 blob=(unsigned char *) NULL;
1364 blob_info=CloneImageInfo(image_info);
1365 blob_info->adjoin=MagickFalse;
1366 (void) SetImageInfo(blob_info,1,exception);
1367 if (*blob_info->magick != '\0')
1368 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1369 magick_info=GetMagickInfo(image->magick,exception);
1370 if (magick_info == (const MagickInfo *) NULL)
1372 (void) ThrowMagickException(exception,GetMagickModule(),
1373 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1377 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1378 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1381 Native blob support for this image format.
1383 blob_info->length=0;
1384 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1385 sizeof(unsigned char));
1386 if (blob_info->blob == (void *) NULL)
1387 (void) ThrowMagickException(exception,GetMagickModule(),
1388 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1391 (void) CloseBlob(image);
1392 image->blob->exempt=MagickTrue;
1393 *image->filename='\0';
1394 status=WriteImage(blob_info,image);
1395 if ((status == MagickFalse) || (image->blob->length == 0))
1396 InheritException(exception,&image->exception);
1399 *length=image->blob->length;
1400 blob=DetachBlob(image->blob);
1401 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1409 unique[MaxTextExtent];
1415 Write file to disk in blob image format.
1417 file=AcquireUniqueFileResource(unique);
1420 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1421 image_info->filename);
1425 blob_info->file=fdopen(file,"wb");
1426 if (blob_info->file != (FILE *) NULL)
1428 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1429 image->magick,unique);
1430 status=WriteImage(blob_info,image);
1431 (void) fclose(blob_info->file);
1432 if (status == MagickFalse)
1433 InheritException(exception,&image->exception);
1435 blob=FileToBlob(image->filename,~0UL,length,exception);
1437 (void) RelinquishUniqueFileResource(unique);
1440 blob_info=DestroyImageInfo(blob_info);
1445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1449 % I m a g e T o F i l e %
1453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1455 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1456 % occurs otherwise MagickTrue.
1458 % The format of the ImageToFile method is:
1460 % MagickBooleanType ImageToFile(Image *image,char *filename,
1461 % ExceptionInfo *exception)
1463 % A description of each parameter follows:
1465 % o image: the image.
1467 % o filename: Write the image to this file.
1469 % o exception: return any errors or warnings in this structure.
1473 static inline const unsigned char *ReadBlobStream(Image *image,
1474 const size_t length,unsigned char *data,ssize_t *count)
1476 assert(count != (ssize_t *) NULL);
1477 assert(image->blob != (BlobInfo *) NULL);
1478 if (image->blob->type != BlobStream)
1480 *count=ReadBlob(image,length,data);
1483 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1486 image->blob->eof=MagickTrue;
1489 data=image->blob->data+image->blob->offset;
1490 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
1491 image->blob->offset));
1492 image->blob->offset+=(*count);
1493 if (*count != (ssize_t) length)
1494 image->blob->eof=MagickTrue;
1498 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1499 ExceptionInfo *exception)
1504 register const unsigned char
1523 assert(image != (Image *) NULL);
1524 assert(image->signature == MagickSignature);
1525 assert(image->blob != (BlobInfo *) NULL);
1526 assert(image->blob->type != UndefinedStream);
1527 if (image->debug != MagickFalse)
1528 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1529 assert(filename != (const char *) NULL);
1530 if (*filename == '\0')
1531 file=AcquireUniqueFileResource(filename);
1533 if (LocaleCompare(filename,"-") == 0)
1534 file=fileno(stdout);
1536 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1539 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1540 return(MagickFalse);
1542 quantum=(size_t) MagickMaxBufferExtent;
1543 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1544 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1545 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1546 if (buffer == (unsigned char *) NULL)
1549 (void) ThrowMagickException(exception,GetMagickModule(),
1550 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1551 return(MagickFalse);
1554 p=ReadBlobStream(image,quantum,buffer,&count);
1555 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1557 length=(size_t) count;
1558 for (i=0; i < length; i+=count)
1560 count=write(file,p+i,(size_t) (length-i));
1572 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1575 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1576 return(MagickFalse);
1582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1586 % I m a g e s T o B l o b %
1590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1592 % ImagesToBlob() implements direct to memory image formats. It returns the
1593 % image sequence as a blob and its length. The magick member of the ImageInfo
1594 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1596 % Note, some image formats do not permit multiple images to the same image
1597 % stream (e.g. JPEG). in this instance, just the first image of the
1598 % sequence is returned as a blob.
1600 % The format of the ImagesToBlob method is:
1602 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1603 % size_t *length,ExceptionInfo *exception)
1605 % A description of each parameter follows:
1607 % o image_info: the image info.
1609 % o images: the image list.
1611 % o length: This pointer to a size_t integer sets the initial length of the
1612 % blob. On return, it reflects the actual length of the blob.
1614 % o exception: return any errors or warnings in this structure.
1617 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1618 Image *images,size_t *length,ExceptionInfo *exception)
1632 assert(image_info != (const ImageInfo *) NULL);
1633 assert(image_info->signature == MagickSignature);
1634 if (image_info->debug != MagickFalse)
1635 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1636 image_info->filename);
1637 assert(images != (Image *) NULL);
1638 assert(images->signature == MagickSignature);
1639 assert(exception != (ExceptionInfo *) NULL);
1641 blob=(unsigned char *) NULL;
1642 blob_info=CloneImageInfo(image_info);
1643 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1645 if (*blob_info->magick != '\0')
1646 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1647 if (blob_info->adjoin == MagickFalse)
1649 blob_info=DestroyImageInfo(blob_info);
1650 return(ImageToBlob(image_info,images,length,exception));
1652 magick_info=GetMagickInfo(images->magick,exception);
1653 if (magick_info == (const MagickInfo *) NULL)
1655 (void) ThrowMagickException(exception,GetMagickModule(),
1656 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1660 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1661 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1664 Native blob support for this images format.
1666 blob_info->length=0;
1667 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1668 sizeof(unsigned char));
1669 if (blob_info->blob == (void *) NULL)
1670 (void) ThrowMagickException(exception,GetMagickModule(),
1671 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1674 images->blob->exempt=MagickTrue;
1675 *images->filename='\0';
1676 status=WriteImages(blob_info,images,images->filename,exception);
1677 if ((status == MagickFalse) || (images->blob->length == 0))
1678 InheritException(exception,&images->exception);
1681 *length=images->blob->length;
1682 blob=DetachBlob(images->blob);
1683 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1691 filename[MaxTextExtent],
1692 unique[MaxTextExtent];
1698 Write file to disk in blob images format.
1700 file=AcquireUniqueFileResource(unique);
1703 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1704 image_info->filename);
1708 blob_info->file=fdopen(file,"wb");
1709 if (blob_info->file != (FILE *) NULL)
1711 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1712 images->magick,unique);
1713 status=WriteImages(blob_info,images,filename,exception);
1714 (void) fclose(blob_info->file);
1715 if (status == MagickFalse)
1716 InheritException(exception,&images->exception);
1718 blob=FileToBlob(images->filename,~0UL,length,exception);
1720 (void) RelinquishUniqueFileResource(unique);
1723 blob_info=DestroyImageInfo(blob_info);
1727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1731 % I n j e c t I m a g e B l o b %
1735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1737 % InjectImageBlob() injects the image with a copy of itself in the specified
1738 % format (e.g. inject JPEG into a PDF image).
1740 % The format of the InjectImageBlob method is:
1742 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1743 % Image *image,Image *inject_image,const char *format,
1744 % ExceptionInfo *exception)
1746 % A description of each parameter follows:
1748 % o image_info: the image info..
1750 % o image: the image.
1752 % o inject_image: inject into the image stream.
1754 % o format: the image format.
1756 % o exception: return any errors or warnings in this structure.
1759 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1760 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1763 filename[MaxTextExtent];
1796 Write inject image to a temporary file.
1798 assert(image_info != (ImageInfo *) NULL);
1799 assert(image_info->signature == MagickSignature);
1800 assert(image != (Image *) NULL);
1801 assert(image->signature == MagickSignature);
1802 if (image->debug != MagickFalse)
1803 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1804 assert(inject_image != (Image *) NULL);
1805 assert(inject_image->signature == MagickSignature);
1806 assert(exception != (ExceptionInfo *) NULL);
1807 unique_file=(FILE *) NULL;
1808 file=AcquireUniqueFileResource(filename);
1810 unique_file=fdopen(file,"wb");
1811 if ((file == -1) || (unique_file == (FILE *) NULL))
1813 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1814 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1816 return(MagickFalse);
1818 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1819 if (byte_image == (Image *) NULL)
1821 (void) fclose(unique_file);
1822 (void) RelinquishUniqueFileResource(filename);
1823 return(MagickFalse);
1825 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1827 DestroyBlob(byte_image);
1828 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1829 write_info=CloneImageInfo(image_info);
1830 SetImageInfoFile(write_info,unique_file);
1831 status=WriteImage(write_info,byte_image);
1832 write_info=DestroyImageInfo(write_info);
1833 byte_image=DestroyImage(byte_image);
1834 (void) fclose(unique_file);
1835 if (status == MagickFalse)
1837 (void) RelinquishUniqueFileResource(filename);
1838 return(MagickFalse);
1841 Inject into image stream.
1843 file=open(filename,O_RDONLY | O_BINARY);
1846 (void) RelinquishUniqueFileResource(filename);
1847 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1848 image_info->filename);
1849 return(MagickFalse);
1851 quantum=(size_t) MagickMaxBufferExtent;
1852 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1853 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1854 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1855 if (buffer == (unsigned char *) NULL)
1857 (void) RelinquishUniqueFileResource(filename);
1858 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1861 for (i=0; ; i+=count)
1863 count=(ssize_t) read(file,buffer,quantum);
1870 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1874 (void) RelinquishUniqueFileResource(filename);
1875 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1884 + I s B l o b E x e m p t %
1888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1890 % IsBlobExempt() returns true if the blob is exempt.
1892 % The format of the IsBlobExempt method is:
1894 % MagickBooleanType IsBlobExempt(const Image *image)
1896 % A description of each parameter follows:
1898 % o image: the image.
1901 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1903 assert(image != (const Image *) NULL);
1904 assert(image->signature == MagickSignature);
1905 if (image->debug != MagickFalse)
1906 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1907 return(image->blob->exempt);
1911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1915 + I s B l o b S e e k a b l e %
1919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1921 % IsBlobSeekable() returns true if the blob is seekable.
1923 % The format of the IsBlobSeekable method is:
1925 % MagickBooleanType IsBlobSeekable(const Image *image)
1927 % A description of each parameter follows:
1929 % o image: the image.
1932 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
1937 assert(image != (const Image *) NULL);
1938 assert(image->signature == MagickSignature);
1939 if (image->debug != MagickFalse)
1940 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1941 seekable=(image->blob->type == FileStream) ||
1942 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
1947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1951 + I s B l o b T e m p o r a r y %
1955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1957 % IsBlobTemporary() returns true if the blob is temporary.
1959 % The format of the IsBlobTemporary method is:
1961 % MagickBooleanType IsBlobTemporary(const Image *image)
1963 % A description of each parameter follows:
1965 % o image: the image.
1968 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
1970 assert(image != (const Image *) NULL);
1971 assert(image->signature == MagickSignature);
1972 if (image->debug != MagickFalse)
1973 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1974 return(image->blob->temporary);
1978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1988 % MapBlob() creates a mapping from a file to a binary large object.
1990 % The format of the MapBlob method is:
1992 % unsigned char *MapBlob(int file,const MapMode mode,
1993 % const MagickOffsetType offset,const size_t length)
1995 % A description of each parameter follows:
1997 % o file: map this file descriptor.
1999 % o mode: ReadMode, WriteMode, or IOMode.
2001 % o offset: starting at this offset within the file.
2003 % o length: the length of the mapping is returned in this pointer.
2006 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2007 const MagickOffsetType offset,const size_t length)
2009 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2022 #if defined(MAP_ANONYMOUS)
2023 flags|=MAP_ANONYMOUS;
2025 return((unsigned char *) NULL);
2032 protection=PROT_READ;
2034 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2040 protection=PROT_WRITE;
2042 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2044 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2045 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2046 POSIX_MADV_WILLNEED);
2052 protection=PROT_READ | PROT_WRITE;
2054 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2059 if (map == (unsigned char *) MAP_FAILED)
2060 return((unsigned char *) NULL);
2067 return((unsigned char *) NULL);
2072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2076 + M S B O r d e r L o n g %
2080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2082 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2083 % most-significant byte first.
2085 % The format of the MSBOrderLong method is:
2087 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2089 % A description of each parameter follows.
2091 % o buffer: Specifies a pointer to a buffer of integers.
2093 % o length: Specifies the length of the buffer.
2096 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2101 register unsigned char
2105 assert(buffer != (unsigned char *) NULL);
2112 *buffer++=(unsigned char) c;
2116 *buffer++=(unsigned char) c;
2122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2126 + M S B O r d e r S h o r t %
2130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2132 % MSBOrderShort() converts a least-significant byte first buffer of integers
2133 % to most-significant byte first.
2135 % The format of the MSBOrderShort method is:
2137 % void MSBOrderShort(unsigned char *p,const size_t length)
2139 % A description of each parameter follows.
2141 % o p: Specifies a pointer to a buffer of integers.
2143 % o length: Specifies the length of the buffer.
2146 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2151 register unsigned char
2154 assert(p != (unsigned char *) NULL);
2161 *p++=(unsigned char) c;
2166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2176 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2177 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2178 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2179 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2180 % from a system command.
2182 % The format of the OpenBlob method is:
2184 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2185 % const BlobMode mode,ExceptionInfo *exception)
2187 % A description of each parameter follows:
2189 % o image_info: the image info.
2191 % o image: the image.
2193 % o mode: the mode for opening the file.
2196 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2197 Image *image,const BlobMode mode,ExceptionInfo *exception)
2200 filename[MaxTextExtent];
2211 assert(image_info != (ImageInfo *) NULL);
2212 assert(image_info->signature == MagickSignature);
2213 if (image_info->debug != MagickFalse)
2214 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2215 image_info->filename);
2216 assert(image != (Image *) NULL);
2217 assert(image->signature == MagickSignature);
2218 if (image_info->blob != (void *) NULL)
2220 if (image_info->stream != (StreamHandler) NULL)
2221 image->blob->stream=(StreamHandler) image_info->stream;
2222 AttachBlob(image->blob,image_info->blob,image_info->length);
2225 (void) DetachBlob(image->blob);
2228 default: type="r"; break;
2229 case ReadBlobMode: type="r"; break;
2230 case ReadBinaryBlobMode: type="rb"; break;
2231 case WriteBlobMode: type="w"; break;
2232 case WriteBinaryBlobMode: type="w+b"; break;
2233 case AppendBlobMode: type="a"; break;
2234 case AppendBinaryBlobMode: type="a+b"; break;
2237 image->blob->synchronize=image_info->synchronize;
2238 if (image_info->stream != (StreamHandler) NULL)
2240 image->blob->stream=(StreamHandler) image_info->stream;
2243 image->blob->type=FifoStream;
2251 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2252 rights=ReadPolicyRights;
2254 rights=WritePolicyRights;
2255 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2258 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2259 "NotAuthorized","`%s'",filename);
2260 return(MagickFalse);
2262 if ((LocaleCompare(filename,"-") == 0) ||
2263 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2265 image->blob->file=(*type == 'r') ? stdin : stdout;
2266 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2267 if (strchr(type,'b') != (char *) NULL)
2268 setmode(_fileno(image->blob->file),_O_BINARY);
2270 image->blob->type=StandardStream;
2271 image->blob->exempt=MagickTrue;
2274 if (LocaleNCompare(filename,"fd:",3) == 0)
2277 mode[MaxTextExtent];
2281 image->blob->file=fdopen(StringToLong(filename+3),mode);
2282 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2283 if (strchr(type,'b') != (char *) NULL)
2284 setmode(_fileno(image->blob->file),_O_BINARY);
2286 image->blob->type=StandardStream;
2287 image->blob->exempt=MagickTrue;
2290 #if defined(MAGICKCORE_HAVE_POPEN)
2291 if (*filename == '|')
2294 mode[MaxTextExtent];
2297 Pipe image to or from a system command.
2299 #if defined(SIGPIPE)
2301 (void) signal(SIGPIPE,SIG_IGN);
2305 image->blob->file=(FILE *) popen(filename+1,mode);
2306 if (image->blob->file == (FILE *) NULL)
2308 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2309 return(MagickFalse);
2311 image->blob->type=PipeStream;
2312 image->blob->exempt=MagickTrue;
2316 status=GetPathAttributes(filename,&image->blob->properties);
2317 #if defined(S_ISFIFO)
2318 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2320 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2321 if (image->blob->file == (FILE *) NULL)
2323 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2324 return(MagickFalse);
2326 image->blob->type=FileStream;
2327 image->blob->exempt=MagickTrue;
2333 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2334 if ((image_info->adjoin == MagickFalse) ||
2335 (IsGlob(filename) != MagickFalse))
2338 Form filename for multi-part images.
2340 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2341 image->scene,filename);
2342 if ((LocaleCompare(filename,image->filename) == 0) &&
2343 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2344 (GetNextImageInList(image) != (Image *) NULL)))
2347 extension[MaxTextExtent],
2348 path[MaxTextExtent];
2350 GetPathComponent(image->filename,RootPath,path);
2351 GetPathComponent(image->filename,ExtensionPath,extension);
2352 if (*extension == '\0')
2353 (void) FormatMagickString(filename,MaxTextExtent,"%s-%lu",
2354 path,(unsigned long) image->scene);
2356 (void) FormatMagickString(filename,MaxTextExtent,
2357 "%s-%lu.%s",path,(unsigned long) image->scene,extension);
2359 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2360 #if defined(macintosh)
2361 SetApplicationType(filename,image_info->magick,'8BIM');
2365 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2366 if (((strlen(filename) > 2) &&
2367 (LocaleCompare(filename+strlen(filename)-2,".Z") == 0)) ||
2368 ((strlen(filename) > 3) &&
2369 (LocaleCompare(filename+strlen(filename)-3,".gz") == 0)) ||
2370 ((strlen(filename) > 4) &&
2371 (LocaleCompare(filename+strlen(filename)-4,".wmz") == 0)) ||
2372 ((strlen(filename) > 5) &&
2373 (LocaleCompare(filename+strlen(filename)-5,".svgz") == 0)))
2375 image->blob->file=(FILE *) gzopen(filename,type);
2376 if (image->blob->file != (FILE *) NULL)
2377 image->blob->type=ZipStream;
2381 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2382 if ((strlen(filename) > 4) &&
2383 (LocaleCompare(filename+strlen(filename)-4,".bz2") == 0))
2385 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2386 if (image->blob->file != (FILE *) NULL)
2387 image->blob->type=BZipStream;
2391 if (image_info->file != (FILE *) NULL)
2393 image->blob->file=image_info->file;
2394 image->blob->type=FileStream;
2395 image->blob->exempt=MagickTrue;
2399 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2400 if (image->blob->file != (FILE *) NULL)
2402 image->blob->type=FileStream;
2403 #if defined(MAGICKCORE_HAVE_SETVBUF)
2404 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2415 (void) ResetMagickMemory(magick,0,sizeof(magick));
2416 count=fread(magick,1,sizeof(magick),image->blob->file);
2417 (void) rewind(image->blob->file);
2418 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2419 " read %lu magic header bytes",(unsigned long) count);
2420 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2421 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2422 ((int) magick[2] == 0x08))
2424 (void) fclose(image->blob->file);
2425 image->blob->file=(FILE *) gzopen(filename,type);
2426 if (image->blob->file != (FILE *) NULL)
2427 image->blob->type=ZipStream;
2430 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2431 if (strncmp((char *) magick,"BZh",3) == 0)
2433 (void) fclose(image->blob->file);
2434 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2435 if (image->blob->file != (FILE *) NULL)
2436 image->blob->type=BZipStream;
2442 if ((image->blob->type == FileStream) && (*type == 'r'))
2453 sans_exception=AcquireExceptionInfo();
2454 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2455 sans_exception=DestroyExceptionInfo(sans_exception);
2456 properties=(&image->blob->properties);
2457 if ((magick_info != (const MagickInfo *) NULL) &&
2458 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2459 (properties->st_size <= MagickMaxBufferExtent))
2467 length=(size_t) properties->st_size;
2468 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2469 if (blob != (void *) NULL)
2472 Format supports blobs-- use memory-mapped I/O.
2474 if (image_info->file != (FILE *) NULL)
2475 image->blob->exempt=MagickFalse;
2478 (void) fclose(image->blob->file);
2479 image->blob->file=(FILE *) NULL;
2481 AttachBlob(image->blob,blob,length);
2482 image->blob->mapped=MagickTrue;
2486 image->blob->status=MagickFalse;
2487 if (image->blob->type != UndefinedStream)
2488 image->blob->size=GetBlobSize(image);
2491 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2492 return(MagickFalse);
2498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2508 % PingBlob() returns all the attributes of an image or image sequence except
2509 % for the pixels. It is much faster and consumes far less memory than
2510 % BlobToImage(). On failure, a NULL image is returned and exception
2511 % describes the reason for the failure.
2513 % The format of the PingBlob method is:
2515 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2516 % const size_t length,ExceptionInfo *exception)
2518 % A description of each parameter follows:
2520 % o image_info: the image info.
2522 % o blob: the address of a character stream in one of the image formats
2523 % understood by ImageMagick.
2525 % o length: This size_t integer reflects the length in bytes of the blob.
2527 % o exception: return any errors or warnings in this structure.
2531 #if defined(__cplusplus) || defined(c_plusplus)
2535 static size_t PingStream(const Image *magick_unused(image),
2536 const void *magick_unused(pixels),const size_t columns)
2541 #if defined(__cplusplus) || defined(c_plusplus)
2545 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2546 const size_t length,ExceptionInfo *exception)
2554 assert(image_info != (ImageInfo *) NULL);
2555 assert(image_info->signature == MagickSignature);
2556 if (image_info->debug != MagickFalse)
2557 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2558 image_info->filename);
2559 assert(exception != (ExceptionInfo *) NULL);
2560 if ((blob == (const void *) NULL) || (length == 0))
2562 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2563 "UnrecognizedImageFormat","`%s'",image_info->magick);
2564 return((Image *) NULL);
2566 ping_info=CloneImageInfo(image_info);
2567 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2568 if (ping_info->blob == (const void *) NULL)
2570 (void) ThrowMagickException(exception,GetMagickModule(),
2571 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2572 return((Image *) NULL);
2574 (void) CopyMagickMemory(ping_info->blob,blob,length);
2575 ping_info->length=length;
2576 ping_info->ping=MagickTrue;
2577 image=ReadStream(ping_info,&PingStream,exception);
2578 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2579 ping_info=DestroyImageInfo(ping_info);
2584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2594 % ReadBlob() reads data from the blob or image file and returns it. It
2595 % returns the number of bytes read.
2597 % The format of the ReadBlob method is:
2599 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2601 % A description of each parameter follows:
2603 % o image: the image.
2605 % o length: Specifies an integer representing the number of bytes to read
2608 % o data: Specifies an area to place the information requested from the
2612 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2613 unsigned char *data)
2618 register unsigned char
2624 assert(image != (Image *) NULL);
2625 assert(image->signature == MagickSignature);
2626 assert(image->blob != (BlobInfo *) NULL);
2627 assert(image->blob->type != UndefinedStream);
2630 assert(data != (void *) NULL);
2633 switch (image->blob->type)
2635 case UndefinedStream:
2638 case StandardStream:
2645 count=(ssize_t) fread(q,1,length,image->blob->file);
2650 c=getc(image->blob->file);
2653 *q++=(unsigned char) c;
2658 c=getc(image->blob->file);
2661 *q++=(unsigned char) c;
2671 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2676 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2681 c=gzgetc(image->blob->file);
2684 *q++=(unsigned char) c;
2689 c=gzgetc(image->blob->file);
2692 *q++=(unsigned char) c;
2703 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2704 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2712 register const unsigned char
2715 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2717 image->blob->eof=MagickTrue;
2720 p=image->blob->data+image->blob->offset;
2721 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2722 image->blob->offset));
2723 image->blob->offset+=count;
2724 if (count != (ssize_t) length)
2725 image->blob->eof=MagickTrue;
2726 (void) CopyMagickMemory(q,p,(size_t) count);
2734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2738 + R e a d B l o b B y t e %
2742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2744 % ReadBlobByte() reads a single byte from the image file and returns it.
2746 % The format of the ReadBlobByte method is:
2748 % int ReadBlobByte(Image *image)
2750 % A description of each parameter follows.
2752 % o image: the image.
2755 MagickExport int ReadBlobByte(Image *image)
2757 register const unsigned char
2766 assert(image != (Image *) NULL);
2767 assert(image->signature == MagickSignature);
2768 p=ReadBlobStream(image,1,buffer,&count);
2775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2779 + R e a d B l o b D o u b l e %
2783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2785 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2786 % specified by the endian member of the image structure.
2788 % The format of the ReadBlobDouble method is:
2790 % double ReadBlobDouble(Image *image)
2792 % A description of each parameter follows.
2794 % o image: the image.
2797 MagickExport double ReadBlobDouble(Image *image)
2808 quantum.double_value=0.0;
2809 quantum.unsigned_value=ReadBlobLongLong(image);
2810 return(quantum.double_value);
2814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2818 + R e a d B l o b F l o a t %
2822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2824 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2825 % specified by the endian member of the image structure.
2827 % The format of the ReadBlobFloat method is:
2829 % float ReadBlobFloat(Image *image)
2831 % A description of each parameter follows.
2833 % o image: the image.
2836 MagickExport float ReadBlobFloat(Image *image)
2847 quantum.float_value=0.0;
2848 quantum.unsigned_value=ReadBlobLong(image);
2849 return(quantum.float_value);
2853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2857 + R e a d B l o b L o n g %
2861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2863 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2864 % specified by the endian member of the image structure.
2866 % The format of the ReadBlobLong method is:
2868 % unsigned int ReadBlobLong(Image *image)
2870 % A description of each parameter follows.
2872 % o image: the image.
2875 MagickExport unsigned int ReadBlobLong(Image *image)
2877 register const unsigned char
2889 assert(image != (Image *) NULL);
2890 assert(image->signature == MagickSignature);
2892 p=ReadBlobStream(image,4,buffer,&count);
2895 if (image->endian == LSBEndian)
2897 value=(unsigned int) (*p++);
2898 value|=((unsigned int) (*p++)) << 8;
2899 value|=((unsigned int) (*p++)) << 16;
2900 value|=((unsigned int) (*p++)) << 24;
2903 value=((unsigned int) (*p++)) << 24;
2904 value|=((unsigned int) (*p++)) << 16;
2905 value|=((unsigned int) (*p++)) << 8;
2906 value|=((unsigned int) (*p++));
2911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2915 + R e a d B l o b L o n g L o n g %
2919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2921 % ReadBlobLongLong() reads a ssize_t value as a 64-bit quantity in the byte-order
2922 % specified by the endian member of the image structure.
2924 % The format of the ReadBlobLong method is:
2926 % MagickSizeType ReadBlobLong(Image *image)
2928 % A description of each parameter follows.
2930 % o image: the image.
2933 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
2935 register const unsigned char
2947 assert(image != (Image *) NULL);
2948 assert(image->signature == MagickSignature);
2950 p=ReadBlobStream(image,8,buffer,&count);
2952 return(MagickULLConstant(0));
2953 if (image->endian == LSBEndian)
2955 value=(MagickSizeType) (*p++);
2956 value|=((MagickSizeType) (*p++)) << 8;
2957 value|=((MagickSizeType) (*p++)) << 16;
2958 value|=((MagickSizeType) (*p++)) << 24;
2959 value|=((MagickSizeType) (*p++)) << 32;
2960 value|=((MagickSizeType) (*p++)) << 40;
2961 value|=((MagickSizeType) (*p++)) << 48;
2962 value|=((MagickSizeType) (*p++)) << 56;
2963 return(value & MagickULLConstant(0xffffffffffffffff));
2965 value=((MagickSizeType) (*p++)) << 56;
2966 value|=((MagickSizeType) (*p++)) << 48;
2967 value|=((MagickSizeType) (*p++)) << 40;
2968 value|=((MagickSizeType) (*p++)) << 32;
2969 value|=((MagickSizeType) (*p++)) << 24;
2970 value|=((MagickSizeType) (*p++)) << 16;
2971 value|=((MagickSizeType) (*p++)) << 8;
2972 value|=((MagickSizeType) (*p++));
2973 return(value & MagickULLConstant(0xffffffffffffffff));
2977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2981 + R e a d B l o b S h o r t %
2985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2987 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
2988 % specified by the endian member of the image structure.
2990 % The format of the ReadBlobShort method is:
2992 % unsigned short ReadBlobShort(Image *image)
2994 % A description of each parameter follows.
2996 % o image: the image.
2999 MagickExport unsigned short ReadBlobShort(Image *image)
3001 register const unsigned char
3004 register unsigned int
3013 assert(image != (Image *) NULL);
3014 assert(image->signature == MagickSignature);
3016 p=ReadBlobStream(image,2,buffer,&count);
3018 return((unsigned short) 0U);
3019 if (image->endian == LSBEndian)
3021 value=(unsigned int) (*p++);
3022 value|=((unsigned int) (*p++)) << 8;
3023 return((unsigned short) (value & 0xffff));
3025 value=(unsigned int) ((*p++) << 8);
3026 value|=(unsigned int) (*p++);
3027 return((unsigned short) (value & 0xffff));
3031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3035 + R e a d B l o b L S B L o n g %
3039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3041 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3042 % least-significant byte first order.
3044 % The format of the ReadBlobLSBLong method is:
3046 % unsigned int ReadBlobLSBLong(Image *image)
3048 % A description of each parameter follows.
3050 % o image: the image.
3053 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3055 register const unsigned char
3058 register unsigned int
3067 assert(image != (Image *) NULL);
3068 assert(image->signature == MagickSignature);
3070 p=ReadBlobStream(image,4,buffer,&count);
3073 value=(unsigned int) (*p++);
3074 value|=((unsigned int) (*p++)) << 8;
3075 value|=((unsigned int) (*p++)) << 16;
3076 value|=((unsigned int) (*p++)) << 24;
3081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3085 + R e a d B l o b L S B S h o r t %
3089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3091 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3092 % least-significant byte first order.
3094 % The format of the ReadBlobLSBShort method is:
3096 % unsigned short ReadBlobLSBShort(Image *image)
3098 % A description of each parameter follows.
3100 % o image: the image.
3103 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3105 register const unsigned char
3108 register unsigned int
3117 assert(image != (Image *) NULL);
3118 assert(image->signature == MagickSignature);
3120 p=ReadBlobStream(image,2,buffer,&count);
3122 return((unsigned short) 0U);
3123 value=(unsigned int) (*p++);
3124 value|=((unsigned int) ((*p++)) << 8);
3125 return((unsigned short) (value & 0xffff));
3129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3133 + R e a d B l o b M S B L o n g %
3137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3139 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3140 % most-significant byte first order.
3142 % The format of the ReadBlobMSBLong method is:
3144 % unsigned int ReadBlobMSBLong(Image *image)
3146 % A description of each parameter follows.
3148 % o image: the image.
3151 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3153 register const unsigned char
3156 register unsigned int
3165 assert(image != (Image *) NULL);
3166 assert(image->signature == MagickSignature);
3168 p=ReadBlobStream(image,4,buffer,&count);
3171 value=((unsigned int) (*p++) << 24);
3172 value|=((unsigned int) (*p++) << 16);
3173 value|=((unsigned int) (*p++) << 8);
3174 value|=(unsigned int) (*p++);
3179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3183 + R e a d B l o b M S B L o n g L o n g %
3187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3189 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3190 % most-significant byte first order.
3192 % The format of the ReadBlobMSBLongLong method is:
3194 % unsigned int ReadBlobMSBLongLong(Image *image)
3196 % A description of each parameter follows.
3198 % o image: the image.
3201 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3203 register const unsigned char
3206 register MagickSizeType
3215 assert(image != (Image *) NULL);
3216 assert(image->signature == MagickSignature);
3218 p=ReadBlobStream(image,8,buffer,&count);
3220 return(MagickULLConstant(0));
3221 value=((MagickSizeType) (*p++)) << 56;
3222 value|=((MagickSizeType) (*p++)) << 48;
3223 value|=((MagickSizeType) (*p++)) << 40;
3224 value|=((MagickSizeType) (*p++)) << 32;
3225 value|=((MagickSizeType) (*p++)) << 24;
3226 value|=((MagickSizeType) (*p++)) << 16;
3227 value|=((MagickSizeType) (*p++)) << 8;
3228 value|=((MagickSizeType) (*p++));
3229 return(value & MagickULLConstant(0xffffffffffffffff));
3233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3237 + R e a d B l o b M S B S h o r t %
3241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3243 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3244 % most-significant byte first order.
3246 % The format of the ReadBlobMSBShort method is:
3248 % unsigned short ReadBlobMSBShort(Image *image)
3250 % A description of each parameter follows.
3252 % o image: the image.
3255 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3257 register const unsigned char
3260 register unsigned int
3269 assert(image != (Image *) NULL);
3270 assert(image->signature == MagickSignature);
3272 p=ReadBlobStream(image,2,buffer,&count);
3274 return((unsigned short) 0U);
3275 value=(unsigned int) ((*p++) << 8);
3276 value|=(unsigned int) (*p++);
3277 return((unsigned short) (value & 0xffff));
3281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3285 + R e a d B l o b S t r i n g %
3289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3291 % ReadBlobString() reads characters from a blob or file until a newline
3292 % character is read or an end-of-file condition is encountered.
3294 % The format of the ReadBlobString method is:
3296 % char *ReadBlobString(Image *image,char *string)
3298 % A description of each parameter follows:
3300 % o image: the image.
3302 % o string: the address of a character buffer.
3305 MagickExport char *ReadBlobString(Image *image,char *string)
3307 register const unsigned char
3319 assert(image != (Image *) NULL);
3320 assert(image->signature == MagickSignature);
3321 for (i=0; i < (MaxTextExtent-1L); i++)
3323 p=ReadBlobStream(image,1,buffer,&count);
3327 return((char *) NULL);
3330 string[i]=(char) (*p);
3331 if ((string[i] == '\n') || (string[i] == '\r'))
3339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3343 + R e f e r e n c e B l o b %
3347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3349 % ReferenceBlob() increments the reference count associated with the pixel
3350 % blob returning a pointer to the blob.
3352 % The format of the ReferenceBlob method is:
3354 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3356 % A description of each parameter follows:
3358 % o blob_info: the blob_info.
3361 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3363 assert(blob != (BlobInfo *) NULL);
3364 assert(blob->signature == MagickSignature);
3365 if (blob->debug != MagickFalse)
3366 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3367 LockSemaphoreInfo(blob->semaphore);
3368 blob->reference_count++;
3369 UnlockSemaphoreInfo(blob->semaphore);
3374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3384 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3385 % and returns the resulting offset.
3387 % The format of the SeekBlob method is:
3389 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3392 % A description of each parameter follows:
3394 % o image: the image.
3396 % o offset: Specifies an integer representing the offset in bytes.
3398 % o whence: Specifies an integer representing how the offset is
3399 % treated relative to the beginning of the blob as follows:
3401 % SEEK_SET Set position equal to offset bytes.
3402 % SEEK_CUR Set position to current location plus offset.
3403 % SEEK_END Set position to EOF plus offset.
3406 MagickExport MagickOffsetType SeekBlob(Image *image,
3407 const MagickOffsetType offset,const int whence)
3409 assert(image != (Image *) NULL);
3410 assert(image->signature == MagickSignature);
3411 if (image->debug != MagickFalse)
3412 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3413 assert(image->blob != (BlobInfo *) NULL);
3414 assert(image->blob->type != UndefinedStream);
3415 switch (image->blob->type)
3417 case UndefinedStream:
3421 if (fseek(image->blob->file,offset,whence) < 0)
3423 image->blob->offset=TellBlob(image);
3426 case StandardStream:
3430 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3431 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3434 image->blob->offset=TellBlob(image);
3450 image->blob->offset=offset;
3455 if ((image->blob->offset+offset) < 0)
3457 image->blob->offset+=offset;
3462 if (((MagickOffsetType) image->blob->length+offset) < 0)
3464 image->blob->offset=image->blob->length+offset;
3468 if (image->blob->offset <= (MagickOffsetType)
3469 ((off_t) image->blob->length))
3470 image->blob->eof=MagickFalse;
3472 if (image->blob->mapped != MagickFalse)
3476 image->blob->extent=(size_t) (image->blob->offset+
3477 image->blob->quantum);
3478 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3479 image->blob->data,image->blob->extent+1,
3480 sizeof(*image->blob->data));
3481 (void) SyncBlob(image);
3482 if (image->blob->data == (unsigned char *) NULL)
3484 (void) DetachBlob(image->blob);
3491 return(image->blob->offset);
3495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3499 + S e t B l o b E x e m p t %
3503 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3505 % SetBlobExempt() sets the blob exempt status.
3507 % The format of the SetBlobExempt method is:
3509 % MagickBooleanType SetBlobExempt(const Image *image,
3510 % const MagickBooleanType exempt)
3512 % A description of each parameter follows:
3514 % o image: the image.
3516 % o exempt: Set to true if this blob is exempt from being closed.
3519 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3521 assert(image != (const Image *) NULL);
3522 assert(image->signature == MagickSignature);
3523 if (image->debug != MagickFalse)
3524 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3525 image->blob->exempt=exempt;
3529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3533 + S e t B l o b E x t e n t %
3537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3539 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3540 % method is successful, subsequent writes to bytes in the specified range are
3541 % guaranteed not to fail.
3543 % The format of the SetBlobExtent method is:
3545 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3547 % A description of each parameter follows:
3549 % o image: the image.
3551 % o extent: the blob maximum extent.
3554 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3555 const MagickSizeType extent)
3557 assert(image != (Image *) NULL);
3558 assert(image->signature == MagickSignature);
3559 if (image->debug != MagickFalse)
3560 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3561 assert(image->blob != (BlobInfo *) NULL);
3562 assert(image->blob->type != UndefinedStream);
3563 switch (image->blob->type)
3565 case UndefinedStream:
3569 if (extent != (MagickSizeType) ((off_t) extent))
3570 return(MagickFalse);
3571 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3572 return(MagickFalse);
3581 offset=TellBlob(image);
3582 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3583 (off_t) (extent-offset));
3585 return(MagickFalse);
3590 case StandardStream:
3593 return(MagickFalse);
3595 return(MagickFalse);
3597 return(MagickFalse);
3600 if (image->blob->mapped != MagickFalse)
3602 if (image->blob->file == (FILE *) NULL)
3603 return(MagickFalse);
3604 (void) UnmapBlob(image->blob->data,image->blob->length);
3605 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3606 return(MagickFalse);
3615 offset=TellBlob(image);
3616 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3617 (off_t) (extent-offset));
3619 return(MagickFalse);
3621 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3622 WriteMode,0,(size_t) extent);
3623 image->blob->extent=(size_t) extent;
3624 image->blob->length=(size_t) extent;
3625 (void) SyncBlob(image);
3629 if (extent != (MagickSizeType) ((size_t) extent))
3630 return(MagickFalse);
3631 image->blob->extent=(size_t) extent;
3632 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3633 image->blob->extent+1,sizeof(*image->blob->data));
3634 (void) SyncBlob(image);
3635 if (image->blob->data == (unsigned char *) NULL)
3637 (void) DetachBlob(image->blob);
3638 return(MagickFalse);
3647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3657 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3658 % attributes if it is an blob.
3660 % The format of the SyncBlob method is:
3662 % int SyncBlob(Image *image)
3664 % A description of each parameter follows:
3666 % o image: the image.
3669 static int SyncBlob(Image *image)
3674 assert(image != (Image *) NULL);
3675 assert(image->signature == MagickSignature);
3676 if (image->debug != MagickFalse)
3677 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3678 assert(image->blob != (BlobInfo *) NULL);
3679 assert(image->blob->type != UndefinedStream);
3681 switch (image->blob->type)
3683 case UndefinedStream:
3686 case StandardStream:
3689 status=fflush(image->blob->file);
3694 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3695 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3701 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3702 status=BZ2_bzflush((BZFILE *) image->blob->file);
3710 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3711 if (image->blob->mapped != MagickFalse)
3712 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3731 % TellBlob() obtains the current value of the blob or file position.
3733 % The format of the TellBlob method is:
3735 % MagickOffsetType TellBlob(const Image *image)
3737 % A description of each parameter follows:
3739 % o image: the image.
3742 MagickExport MagickOffsetType TellBlob(const Image *image)
3747 assert(image != (Image *) NULL);
3748 assert(image->signature == MagickSignature);
3749 if (image->debug != MagickFalse)
3750 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3751 assert(image->blob != (BlobInfo *) NULL);
3752 assert(image->blob->type != UndefinedStream);
3754 switch (image->blob->type)
3756 case UndefinedStream:
3760 offset=ftell(image->blob->file);
3763 case StandardStream:
3768 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3769 offset=(MagickOffsetType) gztell(image->blob->file);
3779 offset=image->blob->offset;
3787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3791 + U n m a p B l o b %
3795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3797 % UnmapBlob() deallocates the binary large object previously allocated with
3798 % the MapBlob method.
3800 % The format of the UnmapBlob method is:
3802 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3804 % A description of each parameter follows:
3806 % o map: the address of the binary large object.
3808 % o length: the length of the binary large object.
3811 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3813 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3817 status=munmap(map,length);
3818 return(status == -1 ? MagickFalse : MagickTrue);
3822 return(MagickFalse);
3827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3831 + W r i t e B l o b %
3835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3837 % WriteBlob() writes data to a blob or image file. It returns the number of
3840 % The format of the WriteBlob method is:
3842 % ssize_t WriteBlob(Image *image,const size_t length,
3843 % const unsigned char *data)
3845 % A description of each parameter follows:
3847 % o image: the image.
3849 % o length: Specifies an integer representing the number of bytes to
3850 % write to the file.
3852 % o data: The address of the data to write to the blob or file.
3855 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3856 const unsigned char *data)
3861 register const unsigned char
3867 assert(image != (Image *) NULL);
3868 assert(image->signature == MagickSignature);
3869 assert(data != (const unsigned char *) NULL);
3870 assert(image->blob != (BlobInfo *) NULL);
3871 assert(image->blob->type != UndefinedStream);
3876 switch (image->blob->type)
3878 case UndefinedStream:
3881 case StandardStream:
3888 count=(ssize_t) fwrite((const char *) data,1,length,
3894 c=putc((int) *p++,image->blob->file);
3901 c=putc((int) *p++,image->blob->file);
3913 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3918 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
3919 (unsigned int) length);
3924 c=gzputc(image->blob->file,(int) *p++);
3931 c=gzputc(image->blob->file,(int) *p++);
3944 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3945 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
3952 count=(ssize_t) image->blob->stream(image,data,length);
3957 register unsigned char
3960 if ((image->blob->offset+(MagickOffsetType) length) >=
3961 (MagickOffsetType) image->blob->extent)
3963 if (image->blob->mapped != MagickFalse)
3965 image->blob->quantum<<=1;
3966 image->blob->extent+=length+image->blob->quantum;
3967 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3968 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
3969 (void) SyncBlob(image);
3970 if (image->blob->data == (unsigned char *) NULL)
3972 (void) DetachBlob(image->blob);
3976 q=image->blob->data+image->blob->offset;
3977 (void) CopyMagickMemory(q,p,length);
3978 image->blob->offset+=length;
3979 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3980 image->blob->length=(size_t) image->blob->offset;
3981 count=(ssize_t) length;
3988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3992 + W r i t e B l o b B y t e %
3996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3998 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
3999 % written (either 0 or 1);
4001 % The format of the WriteBlobByte method is:
4003 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4005 % A description of each parameter follows.
4007 % o image: the image.
4009 % o value: Specifies the value to write.
4012 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4014 assert(image != (Image *) NULL);
4015 assert(image->signature == MagickSignature);
4016 return(WriteBlobStream(image,1,&value));
4020 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4024 + W r i t e B l o b F l o a t %
4028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4030 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4031 % specified by the endian member of the image structure.
4033 % The format of the WriteBlobFloat method is:
4035 % ssize_t WriteBlobFloat(Image *image,const float value)
4037 % A description of each parameter follows.
4039 % o image: the image.
4041 % o value: Specifies the value to write.
4044 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4055 quantum.unsigned_value=0U;
4056 quantum.float_value=value;
4057 return(WriteBlobLong(image,quantum.unsigned_value));
4061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4065 + W r i t e B l o b L o n g %
4069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4071 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4072 % specified by the endian member of the image structure.
4074 % The format of the WriteBlobLong method is:
4076 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4078 % A description of each parameter follows.
4080 % o image: the image.
4082 % o value: Specifies the value to write.
4085 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4090 assert(image != (Image *) NULL);
4091 assert(image->signature == MagickSignature);
4092 if (image->endian == LSBEndian)
4094 buffer[0]=(unsigned char) value;
4095 buffer[1]=(unsigned char) (value >> 8);
4096 buffer[2]=(unsigned char) (value >> 16);
4097 buffer[3]=(unsigned char) (value >> 24);
4098 return(WriteBlobStream(image,4,buffer));
4100 buffer[0]=(unsigned char) (value >> 24);
4101 buffer[1]=(unsigned char) (value >> 16);
4102 buffer[2]=(unsigned char) (value >> 8);
4103 buffer[3]=(unsigned char) value;
4104 return(WriteBlobStream(image,4,buffer));
4108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4112 + W r i t e B l o b S h o r t %
4116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4118 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4119 % byte-order specified by the endian member of the image structure.
4121 % The format of the WriteBlobShort method is:
4123 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4125 % A description of each parameter follows.
4127 % o image: the image.
4129 % o value: Specifies the value to write.
4132 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4137 assert(image != (Image *) NULL);
4138 assert(image->signature == MagickSignature);
4139 if (image->endian == LSBEndian)
4141 buffer[0]=(unsigned char) value;
4142 buffer[1]=(unsigned char) (value >> 8);
4143 return(WriteBlobStream(image,2,buffer));
4145 buffer[0]=(unsigned char) (value >> 8);
4146 buffer[1]=(unsigned char) value;
4147 return(WriteBlobStream(image,2,buffer));
4151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4155 + W r i t e B l o b L S B L o n g %
4159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4161 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4162 % least-significant byte first order.
4164 % The format of the WriteBlobLSBLong method is:
4166 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4168 % A description of each parameter follows.
4170 % o image: the image.
4172 % o value: Specifies the value to write.
4175 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4180 assert(image != (Image *) NULL);
4181 assert(image->signature == MagickSignature);
4182 buffer[0]=(unsigned char) value;
4183 buffer[1]=(unsigned char) (value >> 8);
4184 buffer[2]=(unsigned char) (value >> 16);
4185 buffer[3]=(unsigned char) (value >> 24);
4186 return(WriteBlobStream(image,4,buffer));
4190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4194 + W r i t e B l o b L S B S h o r t %
4198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4200 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4201 % least-significant byte first order.
4203 % The format of the WriteBlobLSBShort method is:
4205 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4207 % A description of each parameter follows.
4209 % o image: the image.
4211 % o value: Specifies the value to write.
4214 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4219 assert(image != (Image *) NULL);
4220 assert(image->signature == MagickSignature);
4221 buffer[0]=(unsigned char) value;
4222 buffer[1]=(unsigned char) (value >> 8);
4223 return(WriteBlobStream(image,2,buffer));
4227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4231 + W r i t e B l o b M S B L o n g %
4235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4237 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4238 % most-significant byte first order.
4240 % The format of the WriteBlobMSBLong method is:
4242 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4244 % A description of each parameter follows.
4246 % o value: Specifies the value to write.
4248 % o image: the image.
4251 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4256 assert(image != (Image *) NULL);
4257 assert(image->signature == MagickSignature);
4258 buffer[0]=(unsigned char) (value >> 24);
4259 buffer[1]=(unsigned char) (value >> 16);
4260 buffer[2]=(unsigned char) (value >> 8);
4261 buffer[3]=(unsigned char) value;
4262 return(WriteBlobStream(image,4,buffer));
4266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4270 + W r i t e B l o b M S B L o n g L o n g %
4274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4276 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4277 % most-significant byte first order.
4279 % The format of the WriteBlobMSBLongLong method is:
4281 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4283 % A description of each parameter follows.
4285 % o value: Specifies the value to write.
4287 % o image: the image.
4290 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4291 const MagickSizeType value)
4296 assert(image != (Image *) NULL);
4297 assert(image->signature == MagickSignature);
4298 buffer[0]=(unsigned char) (value >> 56);
4299 buffer[1]=(unsigned char) (value >> 48);
4300 buffer[2]=(unsigned char) (value >> 40);
4301 buffer[3]=(unsigned char) (value >> 32);
4302 buffer[4]=(unsigned char) (value >> 24);
4303 buffer[5]=(unsigned char) (value >> 16);
4304 buffer[6]=(unsigned char) (value >> 8);
4305 buffer[7]=(unsigned char) value;
4306 return(WriteBlobStream(image,8,buffer));
4310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4314 + W r i t e B l o b M S B S h o r t %
4318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4320 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4321 % most-significant byte first order.
4323 % The format of the WriteBlobMSBShort method is:
4325 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4327 % A description of each parameter follows.
4329 % o value: Specifies the value to write.
4331 % o file: Specifies the file to write the data to.
4334 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4339 assert(image != (Image *) NULL);
4340 assert(image->signature == MagickSignature);
4341 buffer[0]=(unsigned char) (value >> 8);
4342 buffer[1]=(unsigned char) value;
4343 return(WriteBlobStream(image,2,buffer));
4347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4351 + W r i t e B l o b S t r i n g %
4355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4357 % WriteBlobString() write a string to a blob. It returns the number of
4358 % characters written.
4360 % The format of the WriteBlobString method is:
4362 % ssize_t WriteBlobString(Image *image,const char *string)
4364 % A description of each parameter follows.
4366 % o image: the image.
4368 % o string: Specifies the string to write.
4371 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4373 assert(image != (Image *) NULL);
4374 assert(image->signature == MagickSignature);
4375 assert(string != (const char *) NULL);
4376 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));