2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "magick/studio.h"
44 #include "magick/blob.h"
45 #include "magick/blob-private.h"
46 #include "magick/cache.h"
47 #include "magick/client.h"
48 #include "magick/constitute.h"
49 #include "magick/delegate.h"
50 #include "magick/exception.h"
51 #include "magick/exception-private.h"
52 #include "magick/image-private.h"
53 #include "magick/list.h"
54 #include "magick/log.h"
55 #include "magick/magick.h"
56 #include "magick/memory_.h"
57 #include "magick/policy.h"
58 #include "magick/resource_.h"
59 #include "magick/semaphore.h"
60 #include "magick/string_.h"
61 #include "magick/string-private.h"
62 #include "magick/token.h"
63 #include "magick/utility.h"
64 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
65 # include <sys/mman.h>
67 #if defined(MAGICKCORE_ZLIB_DELEGATE)
70 #if defined(MAGICKCORE_BZLIB_DELEGATE)
77 #define MagickMaxBlobExtent 65541
78 #if defined(MAGICKCORE_HAVE_FSEEKO)
82 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
83 # define MAP_ANONYMOUS MAP_ANON
85 #if !defined(MAP_FAILED)
86 #define MAP_FAILED ((void *) -1)
93 #define _O_BINARY O_BINARY
151 Forward declarations.
157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161 + A t t a c h B l o b %
165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 % AttachBlob() attaches a blob to the BlobInfo structure.
169 % The format of the AttachBlob method is:
171 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
173 % A description of each parameter follows:
175 % o blob_info: Specifies a pointer to a BlobInfo structure.
177 % o blob: the address of a character stream in one of the image formats
178 % understood by ImageMagick.
180 % o length: This size_t integer reflects the length in bytes of the blob.
183 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
186 assert(blob_info != (BlobInfo *) NULL);
187 if (blob_info->debug != MagickFalse)
188 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
189 blob_info->length=length;
190 blob_info->extent=length;
191 blob_info->quantum=(size_t) MagickMaxBlobExtent;
193 blob_info->type=BlobStream;
194 blob_info->file=(FILE *) NULL;
195 blob_info->data=(unsigned char *) blob;
196 blob_info->mapped=MagickFalse;
200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 + B l o b T o F i l e %
208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
211 % occurs otherwise MagickTrue.
213 % The format of the BlobToFile method is:
215 % MagickBooleanType BlobToFile(char *filename,const void *blob,
216 % const size_t length,ExceptionInfo *exception)
218 % A description of each parameter follows:
220 % o filename: Write the blob to this file.
222 % o blob: the address of a blob.
224 % o length: This length in bytes of the blob.
226 % o exception: return any errors or warnings in this structure.
230 static inline size_t MagickMin(const size_t x,const size_t y)
237 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
238 const size_t length,ExceptionInfo *exception)
249 assert(filename != (const char *) NULL);
250 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
251 assert(blob != (const void *) NULL);
252 if (*filename == '\0')
253 file=AcquireUniqueFileResource(filename);
255 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
258 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
261 for (i=0; i < length; i+=count)
263 count=(ssize_t) write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
273 if ((file == -1) || (i < length))
275 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286 % B l o b T o I m a g e %
290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292 % BlobToImage() implements direct to memory image formats. It returns the
295 % The format of the BlobToImage method is:
297 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
298 % const size_t length,ExceptionInfo *exception)
300 % A description of each parameter follows:
302 % o image_info: the image info.
304 % o blob: the address of a character stream in one of the image formats
305 % understood by ImageMagick.
307 % o length: This size_t integer reflects the length in bytes of the blob.
309 % o exception: return any errors or warnings in this structure.
312 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
313 const size_t length,ExceptionInfo *exception)
328 assert(image_info != (ImageInfo *) NULL);
329 assert(image_info->signature == MagickSignature);
330 if (image_info->debug != MagickFalse)
331 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
332 image_info->filename);
333 assert(exception != (ExceptionInfo *) NULL);
334 if ((blob == (const void *) NULL) || (length == 0))
336 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
337 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
338 return((Image *) NULL);
340 blob_info=CloneImageInfo(image_info);
341 blob_info->blob=(void *) blob;
342 blob_info->length=length;
343 if (*blob_info->magick == '\0')
344 (void) SetImageInfo(blob_info,0,exception);
345 magick_info=GetMagickInfo(blob_info->magick,exception);
346 if (magick_info == (const MagickInfo *) NULL)
348 blob_info=DestroyImageInfo(blob_info);
349 (void) ThrowMagickException(exception,GetMagickModule(),
350 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
351 image_info->filename);
352 return((Image *) NULL);
354 if (GetMagickBlobSupport(magick_info) != MagickFalse)
357 Native blob support for this image format.
359 (void) CopyMagickString(blob_info->filename,image_info->filename,
361 (void) CopyMagickString(blob_info->magick,image_info->magick,
363 image=ReadImage(blob_info,exception);
364 if (image != (Image *) NULL)
365 (void) DetachBlob(image->blob);
366 blob_info=DestroyImageInfo(blob_info);
370 Write blob to a temporary file on disk.
372 blob_info->blob=(void *) NULL;
374 *blob_info->filename='\0';
375 status=BlobToFile(blob_info->filename,blob,length,exception);
376 if (status == MagickFalse)
378 (void) RelinquishUniqueFileResource(blob_info->filename);
379 blob_info=DestroyImageInfo(blob_info);
380 return((Image *) NULL);
382 clone_info=CloneImageInfo(blob_info);
383 (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
384 blob_info->magick,blob_info->filename);
385 image=ReadImage(clone_info,exception);
386 clone_info=DestroyImageInfo(clone_info);
387 (void) RelinquishUniqueFileResource(blob_info->filename);
388 blob_info=DestroyImageInfo(blob_info);
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 + C l o n e B l o b I n f o %
401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
404 % blob info is NULL, a new one.
406 % The format of the CloneBlobInfo method is:
408 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
410 % A description of each parameter follows:
412 % o blob_info: the blob info.
415 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
420 clone_info=(BlobInfo *) AcquireAlignedMemory(1,sizeof(*clone_info));
421 if (clone_info == (BlobInfo *) NULL)
422 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
423 GetBlobInfo(clone_info);
424 if (blob_info == (BlobInfo *) NULL)
426 clone_info->length=blob_info->length;
427 clone_info->extent=blob_info->extent;
428 clone_info->synchronize=blob_info->synchronize;
429 clone_info->quantum=blob_info->quantum;
430 clone_info->mapped=blob_info->mapped;
431 clone_info->eof=blob_info->eof;
432 clone_info->offset=blob_info->offset;
433 clone_info->size=blob_info->size;
434 clone_info->exempt=blob_info->exempt;
435 clone_info->status=blob_info->status;
436 clone_info->temporary=blob_info->temporary;
437 clone_info->type=blob_info->type;
438 clone_info->file=blob_info->file;
439 clone_info->properties=blob_info->properties;
440 clone_info->stream=blob_info->stream;
441 clone_info->data=blob_info->data;
442 clone_info->debug=IsEventLogging();
443 clone_info->reference_count=1;
448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
452 + C l o s e B l o b %
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458 % CloseBlob() closes a stream associated with the image.
460 % The format of the CloseBlob method is:
462 % MagickBooleanType CloseBlob(Image *image)
464 % A description of each parameter follows:
466 % o image: the image.
469 MagickExport MagickBooleanType CloseBlob(Image *image)
477 assert(image != (Image *) NULL);
478 assert(image->signature == MagickSignature);
479 if (image->debug != MagickFalse)
480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
481 assert(image->blob != (BlobInfo *) NULL);
482 if (image->blob->type == UndefinedStream)
484 if (image->blob->synchronize != MagickFalse)
486 image->blob->size=GetBlobSize(image);
487 image->extent=image->blob->size;
488 image->blob->eof=MagickFalse;
489 if (image->blob->exempt != MagickFalse)
491 image->blob->type=UndefinedStream;
495 switch (image->blob->type)
497 case UndefinedStream:
503 status=ferror(image->blob->file);
508 #if defined(MAGICKCORE_ZLIB_DELEGATE)
509 (void) gzerror(image->blob->file,&status);
515 #if defined(MAGICKCORE_BZLIB_DELEGATE)
516 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
524 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
525 switch (image->blob->type)
527 case UndefinedStream:
532 if (image->blob->synchronize != MagickFalse)
533 status=fsync(fileno(image->blob->file));
534 status=fclose(image->blob->file);
539 #if defined(MAGICKCORE_HAVE_PCLOSE)
540 status=pclose(image->blob->file);
546 #if defined(MAGICKCORE_ZLIB_DELEGATE)
547 status=gzclose(image->blob->file);
553 #if defined(MAGICKCORE_BZLIB_DELEGATE)
554 BZ2_bzclose((BZFILE *) image->blob->file);
562 (void) DetachBlob(image->blob);
563 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
564 return(image->blob->status);
568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572 + D e s t r o y B l o b %
576 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578 % DestroyBlob() deallocates memory associated with a blob.
580 % The format of the DestroyBlob method is:
582 % void DestroyBlob(Image *image)
584 % A description of each parameter follows:
586 % o image: the image.
589 MagickExport void DestroyBlob(Image *image)
594 assert(image != (Image *) NULL);
595 assert(image->signature == MagickSignature);
596 if (image->debug != MagickFalse)
597 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
598 assert(image->blob != (BlobInfo *) NULL);
599 assert(image->blob->signature == MagickSignature);
601 LockSemaphoreInfo(image->blob->semaphore);
602 image->blob->reference_count--;
603 assert(image->blob->reference_count >= 0);
604 if (image->blob->reference_count == 0)
606 UnlockSemaphoreInfo(image->blob->semaphore);
607 if (destroy == MagickFalse)
609 (void) CloseBlob(image);
610 if (image->blob->mapped != MagickFalse)
611 (void) UnmapBlob(image->blob->data,image->blob->length);
612 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
613 DestroySemaphoreInfo(&image->blob->semaphore);
614 image->blob->signature=(~MagickSignature);
615 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623 + D e t a c h B l o b %
627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 % DetachBlob() detaches a blob from the BlobInfo structure.
631 % The format of the DetachBlob method is:
633 % unsigned char *DetachBlob(BlobInfo *blob_info)
635 % A description of each parameter follows:
637 % o blob_info: Specifies a pointer to a BlobInfo structure.
640 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
645 assert(blob_info != (BlobInfo *) NULL);
646 if (blob_info->debug != MagickFalse)
647 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
648 if (blob_info->mapped != MagickFalse)
649 (void) UnmapBlob(blob_info->data,blob_info->length);
650 blob_info->mapped=MagickFalse;
653 blob_info->eof=MagickFalse;
654 blob_info->exempt=MagickFalse;
655 blob_info->type=UndefinedStream;
656 blob_info->file=(FILE *) NULL;
657 data=blob_info->data;
658 blob_info->data=(unsigned char *) NULL;
659 blob_info->stream=(StreamHandler) NULL;
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 + D 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);
880 blob=(unsigned char *) RelinquishMagickMemory(blob);
881 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
882 return((unsigned char *) NULL);
884 *length=MagickMin(i+count,extent);
888 *length=MagickMin((size_t) offset,extent);
889 blob=(unsigned char *) NULL;
890 if (~(*length) >= MaxTextExtent)
891 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
893 if (blob == (unsigned char *) NULL)
896 (void) ThrowMagickException(exception,GetMagickModule(),
897 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
898 return((unsigned char *) NULL);
900 map=MapBlob(file,ReadMode,0,*length);
901 if (map != (unsigned char *) NULL)
903 (void) CopyMagickMemory(blob,map,*length);
904 (void) UnmapBlob(map,*length);
908 (void) MagickSeek(file,0,SEEK_SET);
909 for (i=0; i < *length; i+=count)
911 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
923 blob=(unsigned char *) RelinquishMagickMemory(blob);
924 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
925 return((unsigned char *) NULL);
932 blob=(unsigned char *) RelinquishMagickMemory(blob);
933 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
943 % F i l e T o I m a g e %
947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949 % FileToImage() write the contents of a file to an image.
951 % The format of the FileToImage method is:
953 % MagickBooleanType FileToImage(Image *,const char *filename)
955 % A description of each parameter follows:
957 % o image: the image.
959 % o filename: the filename.
963 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
964 const unsigned char *data)
969 register unsigned char
972 assert(image->blob != (BlobInfo *) NULL);
973 if (image->blob->type != BlobStream)
974 return(WriteBlob(image,length,data));
975 assert(image->blob->type != UndefinedStream);
976 assert(data != (void *) NULL);
977 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
978 if (extent >= image->blob->extent)
980 image->blob->quantum<<=1;
981 extent=image->blob->extent+image->blob->quantum+length;
982 if (SetBlobExtent(image,extent) == MagickFalse)
985 q=image->blob->data+image->blob->offset;
986 (void) CopyMagickMemory(q,data,length);
987 image->blob->offset+=length;
988 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
989 image->blob->length=(size_t) image->blob->offset;
990 return((ssize_t) length);
993 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1011 assert(image != (const Image *) NULL);
1012 assert(image->signature == MagickSignature);
1013 assert(filename != (const char *) NULL);
1014 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1015 file=open(filename,O_RDONLY | O_BINARY);
1018 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1020 return(MagickFalse);
1022 quantum=(size_t) MagickMaxBufferExtent;
1023 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1024 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1025 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1026 if (blob == (unsigned char *) NULL)
1028 ThrowFileException(&image->exception,ResourceLimitError,
1029 "MemoryAllocationFailed",filename);
1030 return(MagickFalse);
1034 count=(ssize_t) read(file,blob,quantum);
1041 length=(size_t) count;
1042 count=WriteBlobStream(image,length,blob);
1043 if (count != (ssize_t) length)
1045 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1052 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1054 blob=(unsigned char *) RelinquishMagickMemory(blob);
1059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1063 + G e t B l o b E r r o r %
1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1069 % GetBlobError() returns MagickTrue if the blob associated with the specified
1070 % image encountered an error.
1072 % The format of the GetBlobError method is:
1074 % MagickBooleanType GetBlobError(const Image *image)
1076 % A description of each parameter follows:
1078 % o image: the image.
1081 MagickExport MagickBooleanType GetBlobError(const Image *image)
1083 assert(image != (const Image *) NULL);
1084 assert(image->signature == MagickSignature);
1085 if (image->debug != MagickFalse)
1086 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1087 return(image->blob->status);
1091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1095 + G e t B l o b F i l e H a n d l e %
1099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1101 % GetBlobFileHandle() returns the file handle associated with the image blob.
1103 % The format of the GetBlobFile method is:
1105 % FILE *GetBlobFileHandle(const Image *image)
1107 % A description of each parameter follows:
1109 % o image: the image.
1112 MagickExport FILE *GetBlobFileHandle(const Image *image)
1114 assert(image != (const Image *) NULL);
1115 assert(image->signature == MagickSignature);
1116 return(image->blob->file);
1120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1124 + G e t B l o b I n f o %
1128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1130 % GetBlobInfo() initializes the BlobInfo structure.
1132 % The format of the GetBlobInfo method is:
1134 % void GetBlobInfo(BlobInfo *blob_info)
1136 % A description of each parameter follows:
1138 % o blob_info: Specifies a pointer to a BlobInfo structure.
1141 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1143 assert(blob_info != (BlobInfo *) NULL);
1144 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1145 blob_info->type=UndefinedStream;
1146 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1147 blob_info->properties.st_mtime=time((time_t *) NULL);
1148 blob_info->properties.st_ctime=time((time_t *) NULL);
1149 blob_info->debug=IsEventLogging();
1150 blob_info->reference_count=1;
1151 blob_info->semaphore=AllocateSemaphoreInfo();
1152 blob_info->signature=MagickSignature;
1156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1160 % G e t B l o b P r o p e r t i e s %
1164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1166 % GetBlobProperties() returns information about an image blob.
1168 % The format of the GetBlobProperties method is:
1170 % const struct stat *GetBlobProperties(const Image *image)
1172 % A description of each parameter follows:
1174 % o image: the image.
1177 MagickExport const struct stat *GetBlobProperties(const Image *image)
1179 assert(image != (Image *) NULL);
1180 assert(image->signature == MagickSignature);
1181 if (image->debug != MagickFalse)
1182 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1183 return(&image->blob->properties);
1187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191 + G e t B l o b S i z e %
1195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1197 % GetBlobSize() returns the current length of the image file or blob; zero is
1198 % returned if the size cannot be determined.
1200 % The format of the GetBlobSize method is:
1202 % MagickSizeType GetBlobSize(const Image *image)
1204 % A description of each parameter follows:
1206 % o image: the image.
1209 MagickExport MagickSizeType GetBlobSize(const Image *image)
1214 assert(image != (Image *) NULL);
1215 assert(image->signature == MagickSignature);
1216 if (image->debug != MagickFalse)
1217 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1218 assert(image->blob != (BlobInfo *) NULL);
1220 switch (image->blob->type)
1222 case UndefinedStream:
1224 extent=image->blob->size;
1229 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1230 extent=(MagickSizeType) image->blob->properties.st_size;
1233 case StandardStream:
1236 extent=image->blob->size;
1245 status=GetPathAttributes(image->filename,&image->blob->properties);
1246 if (status != MagickFalse)
1247 extent=(MagickSizeType) image->blob->properties.st_size;
1254 extent=(MagickSizeType) image->blob->length;
1262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1266 + G e t B l o b S t r e a m D a t a %
1270 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272 % GetBlobStreamData() returns the stream data for the image.
1274 % The format of the GetBlobStreamData method is:
1276 % unsigned char *GetBlobStreamData(const Image *image)
1278 % A description of each parameter follows:
1280 % o image: the image.
1283 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1285 assert(image != (const Image *) NULL);
1286 assert(image->signature == MagickSignature);
1287 return(image->blob->data);
1291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1295 + G e t B l o b S t r e a m H a n d l e r %
1299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1301 % GetBlobStreamHandler() returns the stream handler for the image.
1303 % The format of the GetBlobStreamHandler method is:
1305 % StreamHandler GetBlobStreamHandler(const Image *image)
1307 % A description of each parameter follows:
1309 % o image: the image.
1312 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1314 assert(image != (const Image *) NULL);
1315 assert(image->signature == MagickSignature);
1316 if (image->debug != MagickFalse)
1317 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1318 return(image->blob->stream);
1322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326 % I m a g e T o B l o b %
1330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332 % ImageToBlob() implements direct to memory image formats. It returns the
1333 % image as a blob and its length. The magick member of the ImageInfo structure
1334 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1336 % The format of the ImageToBlob method is:
1338 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1339 % size_t *length,ExceptionInfo *exception)
1341 % A description of each parameter follows:
1343 % o image_info: the image info.
1345 % o image: the image.
1347 % o length: This pointer to a size_t integer sets the initial length of the
1348 % blob. On return, it reflects the actual length of the blob.
1350 % o exception: return any errors or warnings in this structure.
1353 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1354 Image *image,size_t *length,ExceptionInfo *exception)
1368 assert(image_info != (const ImageInfo *) NULL);
1369 assert(image_info->signature == MagickSignature);
1370 if (image_info->debug != MagickFalse)
1371 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1372 image_info->filename);
1373 assert(image != (Image *) NULL);
1374 assert(image->signature == MagickSignature);
1375 assert(exception != (ExceptionInfo *) NULL);
1377 blob=(unsigned char *) NULL;
1378 blob_info=CloneImageInfo(image_info);
1379 blob_info->adjoin=MagickFalse;
1380 (void) SetImageInfo(blob_info,1,exception);
1381 if (*blob_info->magick != '\0')
1382 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1383 magick_info=GetMagickInfo(image->magick,exception);
1384 if (magick_info == (const MagickInfo *) NULL)
1386 (void) ThrowMagickException(exception,GetMagickModule(),
1387 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1391 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1392 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1395 Native blob support for this image format.
1397 blob_info->length=0;
1398 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1399 sizeof(unsigned char));
1400 if (blob_info->blob == (void *) NULL)
1401 (void) ThrowMagickException(exception,GetMagickModule(),
1402 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1405 (void) CloseBlob(image);
1406 image->blob->exempt=MagickTrue;
1407 *image->filename='\0';
1408 status=WriteImage(blob_info,image);
1409 if ((status == MagickFalse) || (image->blob->length == 0))
1410 InheritException(exception,&image->exception);
1413 *length=image->blob->length;
1414 blob=DetachBlob(image->blob);
1415 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1423 unique[MaxTextExtent];
1429 Write file to disk in blob image format.
1431 file=AcquireUniqueFileResource(unique);
1434 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1435 image_info->filename);
1439 blob_info->file=fdopen(file,"wb");
1440 if (blob_info->file != (FILE *) NULL)
1442 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1443 image->magick,unique);
1444 status=WriteImage(blob_info,image);
1445 (void) fclose(blob_info->file);
1446 if (status == MagickFalse)
1447 InheritException(exception,&image->exception);
1449 blob=FileToBlob(image->filename,~0UL,length,exception);
1451 (void) RelinquishUniqueFileResource(unique);
1454 blob_info=DestroyImageInfo(blob_info);
1459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1463 % I m a g e T o F i l e %
1467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1469 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1470 % occurs otherwise MagickTrue.
1472 % The format of the ImageToFile method is:
1474 % MagickBooleanType ImageToFile(Image *image,char *filename,
1475 % ExceptionInfo *exception)
1477 % A description of each parameter follows:
1479 % o image: the image.
1481 % o filename: Write the image to this file.
1483 % o exception: return any errors or warnings in this structure.
1487 static inline const unsigned char *ReadBlobStream(Image *image,
1488 const size_t length,unsigned char *data,ssize_t *count)
1490 assert(count != (ssize_t *) NULL);
1491 assert(image->blob != (BlobInfo *) NULL);
1492 if (image->blob->type != BlobStream)
1494 *count=ReadBlob(image,length,data);
1497 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1500 image->blob->eof=MagickTrue;
1503 data=image->blob->data+image->blob->offset;
1504 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
1505 image->blob->offset));
1506 image->blob->offset+=(*count);
1507 if (*count != (ssize_t) length)
1508 image->blob->eof=MagickTrue;
1512 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1513 ExceptionInfo *exception)
1518 register const unsigned char
1537 assert(image != (Image *) NULL);
1538 assert(image->signature == MagickSignature);
1539 assert(image->blob != (BlobInfo *) NULL);
1540 assert(image->blob->type != UndefinedStream);
1541 if (image->debug != MagickFalse)
1542 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1543 assert(filename != (const char *) NULL);
1544 if (*filename == '\0')
1545 file=AcquireUniqueFileResource(filename);
1547 if (LocaleCompare(filename,"-") == 0)
1548 file=fileno(stdout);
1550 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1553 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1554 return(MagickFalse);
1556 quantum=(size_t) MagickMaxBufferExtent;
1557 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1558 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1559 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1560 if (buffer == (unsigned char *) NULL)
1563 (void) ThrowMagickException(exception,GetMagickModule(),
1564 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1565 return(MagickFalse);
1568 p=ReadBlobStream(image,quantum,buffer,&count);
1569 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1571 length=(size_t) count;
1572 for (i=0; i < length; i+=count)
1574 count=write(file,p+i,(size_t) (length-i));
1586 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1587 if ((file == -1) || (i < length))
1589 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1590 return(MagickFalse);
1596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1600 % I m a g e s T o B l o b %
1604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1606 % ImagesToBlob() implements direct to memory image formats. It returns the
1607 % image sequence as a blob and its length. The magick member of the ImageInfo
1608 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1610 % Note, some image formats do not permit multiple images to the same image
1611 % stream (e.g. JPEG). in this instance, just the first image of the
1612 % sequence is returned as a blob.
1614 % The format of the ImagesToBlob method is:
1616 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1617 % size_t *length,ExceptionInfo *exception)
1619 % A description of each parameter follows:
1621 % o image_info: the image info.
1623 % o images: the image list.
1625 % o length: This pointer to a size_t integer sets the initial length of the
1626 % blob. On return, it reflects the actual length of the blob.
1628 % o exception: return any errors or warnings in this structure.
1631 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1632 Image *images,size_t *length,ExceptionInfo *exception)
1646 assert(image_info != (const ImageInfo *) NULL);
1647 assert(image_info->signature == MagickSignature);
1648 if (image_info->debug != MagickFalse)
1649 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1650 image_info->filename);
1651 assert(images != (Image *) NULL);
1652 assert(images->signature == MagickSignature);
1653 assert(exception != (ExceptionInfo *) NULL);
1655 blob=(unsigned char *) NULL;
1656 blob_info=CloneImageInfo(image_info);
1657 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1659 if (*blob_info->magick != '\0')
1660 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1661 if (blob_info->adjoin == MagickFalse)
1663 blob_info=DestroyImageInfo(blob_info);
1664 return(ImageToBlob(image_info,images,length,exception));
1666 magick_info=GetMagickInfo(images->magick,exception);
1667 if (magick_info == (const MagickInfo *) NULL)
1669 (void) ThrowMagickException(exception,GetMagickModule(),
1670 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1674 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1675 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1678 Native blob support for this images format.
1680 blob_info->length=0;
1681 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1682 sizeof(unsigned char));
1683 if (blob_info->blob == (void *) NULL)
1684 (void) ThrowMagickException(exception,GetMagickModule(),
1685 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1688 images->blob->exempt=MagickTrue;
1689 *images->filename='\0';
1690 status=WriteImages(blob_info,images,images->filename,exception);
1691 if ((status == MagickFalse) || (images->blob->length == 0))
1692 InheritException(exception,&images->exception);
1695 *length=images->blob->length;
1696 blob=DetachBlob(images->blob);
1697 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1705 filename[MaxTextExtent],
1706 unique[MaxTextExtent];
1712 Write file to disk in blob images format.
1714 file=AcquireUniqueFileResource(unique);
1717 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1718 image_info->filename);
1722 blob_info->file=fdopen(file,"wb");
1723 if (blob_info->file != (FILE *) NULL)
1725 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1726 images->magick,unique);
1727 status=WriteImages(blob_info,images,filename,exception);
1728 (void) fclose(blob_info->file);
1729 if (status == MagickFalse)
1730 InheritException(exception,&images->exception);
1732 blob=FileToBlob(images->filename,~0UL,length,exception);
1734 (void) RelinquishUniqueFileResource(unique);
1737 blob_info=DestroyImageInfo(blob_info);
1741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1745 % I n j e c t I m a g e B l o b %
1749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1751 % InjectImageBlob() injects the image with a copy of itself in the specified
1752 % format (e.g. inject JPEG into a PDF image).
1754 % The format of the InjectImageBlob method is:
1756 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1757 % Image *image,Image *inject_image,const char *format,
1758 % ExceptionInfo *exception)
1760 % A description of each parameter follows:
1762 % o image_info: the image info..
1764 % o image: the image.
1766 % o inject_image: inject into the image stream.
1768 % o format: the image format.
1770 % o exception: return any errors or warnings in this structure.
1773 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1774 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1777 filename[MaxTextExtent];
1810 Write inject image to a temporary file.
1812 assert(image_info != (ImageInfo *) NULL);
1813 assert(image_info->signature == MagickSignature);
1814 assert(image != (Image *) NULL);
1815 assert(image->signature == MagickSignature);
1816 if (image->debug != MagickFalse)
1817 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1818 assert(inject_image != (Image *) NULL);
1819 assert(inject_image->signature == MagickSignature);
1820 assert(exception != (ExceptionInfo *) NULL);
1821 unique_file=(FILE *) NULL;
1822 file=AcquireUniqueFileResource(filename);
1824 unique_file=fdopen(file,"wb");
1825 if ((file == -1) || (unique_file == (FILE *) NULL))
1827 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1828 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1830 return(MagickFalse);
1832 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1833 if (byte_image == (Image *) NULL)
1835 (void) fclose(unique_file);
1836 (void) RelinquishUniqueFileResource(filename);
1837 return(MagickFalse);
1839 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1841 DestroyBlob(byte_image);
1842 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1843 write_info=CloneImageInfo(image_info);
1844 SetImageInfoFile(write_info,unique_file);
1845 status=WriteImage(write_info,byte_image);
1846 write_info=DestroyImageInfo(write_info);
1847 byte_image=DestroyImage(byte_image);
1848 (void) fclose(unique_file);
1849 if (status == MagickFalse)
1851 (void) RelinquishUniqueFileResource(filename);
1852 return(MagickFalse);
1855 Inject into image stream.
1857 file=open(filename,O_RDONLY | O_BINARY);
1860 (void) RelinquishUniqueFileResource(filename);
1861 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1862 image_info->filename);
1863 return(MagickFalse);
1865 quantum=(size_t) MagickMaxBufferExtent;
1866 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1867 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1868 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1869 if (buffer == (unsigned char *) NULL)
1871 (void) RelinquishUniqueFileResource(filename);
1872 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1875 for (i=0; ; i+=count)
1877 count=(ssize_t) read(file,buffer,quantum);
1884 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1889 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1890 (void) RelinquishUniqueFileResource(filename);
1891 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1900 + I s B l o b E x e m p t %
1904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1906 % IsBlobExempt() returns true if the blob is exempt.
1908 % The format of the IsBlobExempt method is:
1910 % MagickBooleanType IsBlobExempt(const Image *image)
1912 % A description of each parameter follows:
1914 % o image: the image.
1917 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1919 assert(image != (const Image *) NULL);
1920 assert(image->signature == MagickSignature);
1921 if (image->debug != MagickFalse)
1922 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1923 return(image->blob->exempt);
1927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1931 + I s B l o b S e e k a b l e %
1935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1937 % IsBlobSeekable() returns true if the blob is seekable.
1939 % The format of the IsBlobSeekable method is:
1941 % MagickBooleanType IsBlobSeekable(const Image *image)
1943 % A description of each parameter follows:
1945 % o image: the image.
1948 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
1953 assert(image != (const Image *) NULL);
1954 assert(image->signature == MagickSignature);
1955 if (image->debug != MagickFalse)
1956 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1957 seekable=(image->blob->type == FileStream) ||
1958 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
1963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1967 + I s B l o b T e m p o r a r y %
1971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1973 % IsBlobTemporary() returns true if the blob is temporary.
1975 % The format of the IsBlobTemporary method is:
1977 % MagickBooleanType IsBlobTemporary(const Image *image)
1979 % A description of each parameter follows:
1981 % o image: the image.
1984 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
1986 assert(image != (const Image *) NULL);
1987 assert(image->signature == MagickSignature);
1988 if (image->debug != MagickFalse)
1989 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1990 return(image->blob->temporary);
1994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2004 % MapBlob() creates a mapping from a file to a binary large object.
2006 % The format of the MapBlob method is:
2008 % unsigned char *MapBlob(int file,const MapMode mode,
2009 % const MagickOffsetType offset,const size_t length)
2011 % A description of each parameter follows:
2013 % o file: map this file descriptor.
2015 % o mode: ReadMode, WriteMode, or IOMode.
2017 % o offset: starting at this offset within the file.
2019 % o length: the length of the mapping is returned in this pointer.
2022 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2023 const MagickOffsetType offset,const size_t length)
2025 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2038 #if defined(MAP_ANONYMOUS)
2039 flags|=MAP_ANONYMOUS;
2041 return((unsigned char *) NULL);
2048 protection=PROT_READ;
2050 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2056 protection=PROT_WRITE;
2058 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2060 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2061 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2062 POSIX_MADV_WILLNEED);
2068 protection=PROT_READ | PROT_WRITE;
2070 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2075 if (map == (unsigned char *) MAP_FAILED)
2076 return((unsigned char *) NULL);
2083 return((unsigned char *) NULL);
2088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2092 + M S B O r d e r L o n g %
2096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2098 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2099 % most-significant byte first.
2101 % The format of the MSBOrderLong method is:
2103 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2105 % A description of each parameter follows.
2107 % o buffer: Specifies a pointer to a buffer of integers.
2109 % o length: Specifies the length of the buffer.
2112 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2117 register unsigned char
2121 assert(buffer != (unsigned char *) NULL);
2128 *buffer++=(unsigned char) c;
2132 *buffer++=(unsigned char) c;
2138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2142 + M S B O r d e r S h o r t %
2146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2148 % MSBOrderShort() converts a least-significant byte first buffer of integers
2149 % to most-significant byte first.
2151 % The format of the MSBOrderShort method is:
2153 % void MSBOrderShort(unsigned char *p,const size_t length)
2155 % A description of each parameter follows.
2157 % o p: Specifies a pointer to a buffer of integers.
2159 % o length: Specifies the length of the buffer.
2162 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2167 register unsigned char
2170 assert(p != (unsigned char *) NULL);
2177 *p++=(unsigned char) c;
2182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2192 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2193 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2194 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2195 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2196 % from a system command.
2198 % The format of the OpenBlob method is:
2200 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2201 % const BlobMode mode,ExceptionInfo *exception)
2203 % A description of each parameter follows:
2205 % o image_info: the image info.
2207 % o image: the image.
2209 % o mode: the mode for opening the file.
2212 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2213 Image *image,const BlobMode mode,ExceptionInfo *exception)
2216 extension[MaxTextExtent],
2217 filename[MaxTextExtent];
2228 assert(image_info != (ImageInfo *) NULL);
2229 assert(image_info->signature == MagickSignature);
2230 if (image_info->debug != MagickFalse)
2231 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2232 image_info->filename);
2233 assert(image != (Image *) NULL);
2234 assert(image->signature == MagickSignature);
2235 if (image_info->blob != (void *) NULL)
2237 if (image_info->stream != (StreamHandler) NULL)
2238 image->blob->stream=(StreamHandler) image_info->stream;
2239 AttachBlob(image->blob,image_info->blob,image_info->length);
2242 (void) DetachBlob(image->blob);
2245 default: type="r"; break;
2246 case ReadBlobMode: type="r"; break;
2247 case ReadBinaryBlobMode: type="rb"; break;
2248 case WriteBlobMode: type="w"; break;
2249 case WriteBinaryBlobMode: type="w+b"; break;
2250 case AppendBlobMode: type="a"; break;
2251 case AppendBinaryBlobMode: type="a+b"; break;
2254 image->blob->synchronize=image_info->synchronize;
2255 if (image_info->stream != (StreamHandler) NULL)
2257 image->blob->stream=(StreamHandler) image_info->stream;
2260 image->blob->type=FifoStream;
2268 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2269 rights=ReadPolicyRights;
2271 rights=WritePolicyRights;
2272 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2275 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2276 "NotAuthorized","`%s'",filename);
2277 return(MagickFalse);
2279 if ((LocaleCompare(filename,"-") == 0) ||
2280 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2282 image->blob->file=(*type == 'r') ? stdin : stdout;
2283 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2284 if (strchr(type,'b') != (char *) NULL)
2285 setmode(_fileno(image->blob->file),_O_BINARY);
2287 image->blob->type=StandardStream;
2288 image->blob->exempt=MagickTrue;
2291 if (LocaleNCompare(filename,"fd:",3) == 0)
2294 mode[MaxTextExtent];
2298 image->blob->file=fdopen(StringToLong(filename+3),mode);
2299 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2300 if (strchr(type,'b') != (char *) NULL)
2301 setmode(_fileno(image->blob->file),_O_BINARY);
2303 image->blob->type=StandardStream;
2304 image->blob->exempt=MagickTrue;
2307 #if defined(MAGICKCORE_HAVE_POPEN)
2308 if (*filename == '|')
2311 mode[MaxTextExtent];
2314 Pipe image to or from a system command.
2316 #if defined(SIGPIPE)
2318 (void) signal(SIGPIPE,SIG_IGN);
2322 image->blob->file=(FILE *) popen(filename+1,mode);
2323 if (image->blob->file == (FILE *) NULL)
2325 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2326 return(MagickFalse);
2328 image->blob->type=PipeStream;
2329 image->blob->exempt=MagickTrue;
2333 status=GetPathAttributes(filename,&image->blob->properties);
2334 #if defined(S_ISFIFO)
2335 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2337 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2338 if (image->blob->file == (FILE *) NULL)
2340 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2341 return(MagickFalse);
2343 image->blob->type=FileStream;
2344 image->blob->exempt=MagickTrue;
2348 GetPathComponent(image->filename,ExtensionPath,extension);
2351 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2352 if ((image_info->adjoin == MagickFalse) ||
2353 (IsGlob(filename) != MagickFalse))
2356 Form filename for multi-part images.
2358 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2359 image->scene,filename);
2360 if ((LocaleCompare(filename,image->filename) == 0) &&
2361 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2362 (GetNextImageInList(image) != (Image *) NULL)))
2365 path[MaxTextExtent];
2367 GetPathComponent(image->filename,RootPath,path);
2368 if (*extension == '\0')
2369 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2370 path,(double) image->scene);
2372 (void) FormatMagickString(filename,MaxTextExtent,
2373 "%s-%.20g.%s",path,(double) image->scene,extension);
2375 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2376 #if defined(macintosh)
2377 SetApplicationType(filename,image_info->magick,'8BIM');
2381 if (image_info->file != (FILE *) NULL)
2383 image->blob->file=image_info->file;
2384 image->blob->type=FileStream;
2385 image->blob->exempt=MagickTrue;
2390 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2391 if (image->blob->file != (FILE *) NULL)
2399 image->blob->type=FileStream;
2400 #if defined(MAGICKCORE_HAVE_SETVBUF)
2401 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2404 (void) ResetMagickMemory(magick,0,sizeof(magick));
2405 count=fread(magick,1,sizeof(magick),image->blob->file);
2406 (void) rewind(image->blob->file);
2407 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2408 " read %.20g magic header bytes",(double) count);
2409 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2410 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2411 ((int) magick[2] == 0x08))
2413 (void) fclose(image->blob->file);
2414 image->blob->file=(FILE *) gzopen(filename,type);
2415 if (image->blob->file != (FILE *) NULL)
2416 image->blob->type=ZipStream;
2419 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2420 if (strncmp((char *) magick,"BZh",3) == 0)
2422 (void) fclose(image->blob->file);
2423 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2424 if (image->blob->file != (FILE *) NULL)
2425 image->blob->type=BZipStream;
2428 if (image->blob->type == FileStream)
2439 sans_exception=AcquireExceptionInfo();
2440 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2441 sans_exception=DestroyExceptionInfo(sans_exception);
2442 properties=(&image->blob->properties);
2443 if ((magick_info != (const MagickInfo *) NULL) &&
2444 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2445 (properties->st_size <= MagickMaxBufferExtent))
2453 length=(size_t) properties->st_size;
2454 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2455 if (blob != (void *) NULL)
2458 Format supports blobs-- use memory-mapped I/O.
2460 if (image_info->file != (FILE *) NULL)
2461 image->blob->exempt=MagickFalse;
2464 (void) fclose(image->blob->file);
2465 image->blob->file=(FILE *) NULL;
2467 AttachBlob(image->blob,blob,length);
2468 image->blob->mapped=MagickTrue;
2475 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2476 if ((LocaleCompare(extension,"Z") == 0) ||
2477 (LocaleCompare(extension,"gz") == 0) ||
2478 (LocaleCompare(extension,"wmz") == 0) ||
2479 (LocaleCompare(extension,"svgz") == 0))
2481 if (mode == WriteBinaryBlobMode)
2483 image->blob->file=(FILE *) gzopen(filename,type);
2484 if (image->blob->file != (FILE *) NULL)
2485 image->blob->type=ZipStream;
2489 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2490 if (LocaleCompare(extension,".bz2") == 0)
2492 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2493 if (image->blob->file != (FILE *) NULL)
2494 image->blob->type=BZipStream;
2499 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2500 if (image->blob->file != (FILE *) NULL)
2502 image->blob->type=FileStream;
2503 #if defined(MAGICKCORE_HAVE_SETVBUF)
2504 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2509 image->blob->status=MagickFalse;
2510 if (image->blob->type != UndefinedStream)
2511 image->blob->size=GetBlobSize(image);
2514 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2515 return(MagickFalse);
2521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2531 % PingBlob() returns all the attributes of an image or image sequence except
2532 % for the pixels. It is much faster and consumes far less memory than
2533 % BlobToImage(). On failure, a NULL image is returned and exception
2534 % describes the reason for the failure.
2536 % The format of the PingBlob method is:
2538 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2539 % const size_t length,ExceptionInfo *exception)
2541 % A description of each parameter follows:
2543 % o image_info: the image info.
2545 % o blob: the address of a character stream in one of the image formats
2546 % understood by ImageMagick.
2548 % o length: This size_t integer reflects the length in bytes of the blob.
2550 % o exception: return any errors or warnings in this structure.
2554 #if defined(__cplusplus) || defined(c_plusplus)
2558 static size_t PingStream(const Image *magick_unused(image),
2559 const void *magick_unused(pixels),const size_t columns)
2564 #if defined(__cplusplus) || defined(c_plusplus)
2568 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2569 const size_t length,ExceptionInfo *exception)
2577 assert(image_info != (ImageInfo *) NULL);
2578 assert(image_info->signature == MagickSignature);
2579 if (image_info->debug != MagickFalse)
2580 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2581 image_info->filename);
2582 assert(exception != (ExceptionInfo *) NULL);
2583 if ((blob == (const void *) NULL) || (length == 0))
2585 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2586 "UnrecognizedImageFormat","`%s'",image_info->magick);
2587 return((Image *) NULL);
2589 ping_info=CloneImageInfo(image_info);
2590 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2591 if (ping_info->blob == (const void *) NULL)
2593 (void) ThrowMagickException(exception,GetMagickModule(),
2594 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2595 return((Image *) NULL);
2597 (void) CopyMagickMemory(ping_info->blob,blob,length);
2598 ping_info->length=length;
2599 ping_info->ping=MagickTrue;
2600 image=ReadStream(ping_info,&PingStream,exception);
2601 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2602 ping_info=DestroyImageInfo(ping_info);
2607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2617 % ReadBlob() reads data from the blob or image file and returns it. It
2618 % returns the number of bytes read.
2620 % The format of the ReadBlob method is:
2622 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2624 % A description of each parameter follows:
2626 % o image: the image.
2628 % o length: Specifies an integer representing the number of bytes to read
2631 % o data: Specifies an area to place the information requested from the
2635 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2636 unsigned char *data)
2641 register unsigned char
2647 assert(image != (Image *) NULL);
2648 assert(image->signature == MagickSignature);
2649 assert(image->blob != (BlobInfo *) NULL);
2650 assert(image->blob->type != UndefinedStream);
2653 assert(data != (void *) NULL);
2656 switch (image->blob->type)
2658 case UndefinedStream:
2661 case StandardStream:
2668 count=(ssize_t) fread(q,1,length,image->blob->file);
2673 c=getc(image->blob->file);
2676 *q++=(unsigned char) c;
2681 c=getc(image->blob->file);
2684 *q++=(unsigned char) c;
2694 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2699 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2704 c=gzgetc(image->blob->file);
2707 *q++=(unsigned char) c;
2712 c=gzgetc(image->blob->file);
2715 *q++=(unsigned char) c;
2726 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2727 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2735 register const unsigned char
2738 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2740 image->blob->eof=MagickTrue;
2743 p=image->blob->data+image->blob->offset;
2744 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2745 image->blob->offset));
2746 image->blob->offset+=count;
2747 if (count != (ssize_t) length)
2748 image->blob->eof=MagickTrue;
2749 (void) CopyMagickMemory(q,p,(size_t) count);
2757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2761 + R e a d B l o b B y t e %
2765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2767 % ReadBlobByte() reads a single byte from the image file and returns it.
2769 % The format of the ReadBlobByte method is:
2771 % int ReadBlobByte(Image *image)
2773 % A description of each parameter follows.
2775 % o image: the image.
2778 MagickExport int ReadBlobByte(Image *image)
2780 register const unsigned char
2789 assert(image != (Image *) NULL);
2790 assert(image->signature == MagickSignature);
2791 p=ReadBlobStream(image,1,buffer,&count);
2798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2802 + R e a d B l o b D o u b l e %
2806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2808 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2809 % specified by the endian member of the image structure.
2811 % The format of the ReadBlobDouble method is:
2813 % double ReadBlobDouble(Image *image)
2815 % A description of each parameter follows.
2817 % o image: the image.
2820 MagickExport double ReadBlobDouble(Image *image)
2831 quantum.double_value=0.0;
2832 quantum.unsigned_value=ReadBlobLongLong(image);
2833 return(quantum.double_value);
2837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2841 + R e a d B l o b F l o a t %
2845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2847 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2848 % specified by the endian member of the image structure.
2850 % The format of the ReadBlobFloat method is:
2852 % float ReadBlobFloat(Image *image)
2854 % A description of each parameter follows.
2856 % o image: the image.
2859 MagickExport float ReadBlobFloat(Image *image)
2870 quantum.float_value=0.0;
2871 quantum.unsigned_value=ReadBlobLong(image);
2872 return(quantum.float_value);
2876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2880 + R e a d B l o b L o n g %
2884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2886 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2887 % specified by the endian member of the image structure.
2889 % The format of the ReadBlobLong method is:
2891 % unsigned int ReadBlobLong(Image *image)
2893 % A description of each parameter follows.
2895 % o image: the image.
2898 MagickExport unsigned int ReadBlobLong(Image *image)
2900 register const unsigned char
2912 assert(image != (Image *) NULL);
2913 assert(image->signature == MagickSignature);
2915 p=ReadBlobStream(image,4,buffer,&count);
2918 if (image->endian == LSBEndian)
2920 value=(unsigned int) (*p++);
2921 value|=((unsigned int) (*p++)) << 8;
2922 value|=((unsigned int) (*p++)) << 16;
2923 value|=((unsigned int) (*p++)) << 24;
2926 value=((unsigned int) (*p++)) << 24;
2927 value|=((unsigned int) (*p++)) << 16;
2928 value|=((unsigned int) (*p++)) << 8;
2929 value|=((unsigned int) (*p++));
2934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2938 + R e a d B l o b L o n g L o n g %
2942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2944 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
2945 % byte-order specified by the endian member of the image structure.
2947 % The format of the ReadBlobLongLong method is:
2949 % MagickSizeType ReadBlobLongLong(Image *image)
2951 % A description of each parameter follows.
2953 % o image: the image.
2956 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
2958 register const unsigned char
2970 assert(image != (Image *) NULL);
2971 assert(image->signature == MagickSignature);
2973 p=ReadBlobStream(image,8,buffer,&count);
2975 return(MagickULLConstant(0));
2976 if (image->endian == LSBEndian)
2978 value=(MagickSizeType) (*p++);
2979 value|=((MagickSizeType) (*p++)) << 8;
2980 value|=((MagickSizeType) (*p++)) << 16;
2981 value|=((MagickSizeType) (*p++)) << 24;
2982 value|=((MagickSizeType) (*p++)) << 32;
2983 value|=((MagickSizeType) (*p++)) << 40;
2984 value|=((MagickSizeType) (*p++)) << 48;
2985 value|=((MagickSizeType) (*p++)) << 56;
2986 return(value & MagickULLConstant(0xffffffffffffffff));
2988 value=((MagickSizeType) (*p++)) << 56;
2989 value|=((MagickSizeType) (*p++)) << 48;
2990 value|=((MagickSizeType) (*p++)) << 40;
2991 value|=((MagickSizeType) (*p++)) << 32;
2992 value|=((MagickSizeType) (*p++)) << 24;
2993 value|=((MagickSizeType) (*p++)) << 16;
2994 value|=((MagickSizeType) (*p++)) << 8;
2995 value|=((MagickSizeType) (*p++));
2996 return(value & MagickULLConstant(0xffffffffffffffff));
3000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3004 + R e a d B l o b S h o r t %
3008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3010 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3011 % specified by the endian member of the image structure.
3013 % The format of the ReadBlobShort method is:
3015 % unsigned short ReadBlobShort(Image *image)
3017 % A description of each parameter follows.
3019 % o image: the image.
3022 MagickExport unsigned short ReadBlobShort(Image *image)
3024 register const unsigned char
3027 register unsigned int
3036 assert(image != (Image *) NULL);
3037 assert(image->signature == MagickSignature);
3039 p=ReadBlobStream(image,2,buffer,&count);
3041 return((unsigned short) 0U);
3042 if (image->endian == LSBEndian)
3044 value=(unsigned int) (*p++);
3045 value|=((unsigned int) (*p++)) << 8;
3046 return((unsigned short) (value & 0xffff));
3048 value=(unsigned int) ((*p++) << 8);
3049 value|=(unsigned int) (*p++);
3050 return((unsigned short) (value & 0xffff));
3054 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3058 + R e a d B l o b L S B L o n g %
3062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3064 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3065 % least-significant byte first order.
3067 % The format of the ReadBlobLSBLong method is:
3069 % unsigned int ReadBlobLSBLong(Image *image)
3071 % A description of each parameter follows.
3073 % o image: the image.
3076 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3078 register const unsigned char
3081 register unsigned int
3090 assert(image != (Image *) NULL);
3091 assert(image->signature == MagickSignature);
3093 p=ReadBlobStream(image,4,buffer,&count);
3096 value=(unsigned int) (*p++);
3097 value|=((unsigned int) (*p++)) << 8;
3098 value|=((unsigned int) (*p++)) << 16;
3099 value|=((unsigned int) (*p++)) << 24;
3104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3108 + R e a d B l o b L S B S h o r t %
3112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3114 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3115 % least-significant byte first order.
3117 % The format of the ReadBlobLSBShort method is:
3119 % unsigned short ReadBlobLSBShort(Image *image)
3121 % A description of each parameter follows.
3123 % o image: the image.
3126 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3128 register const unsigned char
3131 register unsigned int
3140 assert(image != (Image *) NULL);
3141 assert(image->signature == MagickSignature);
3143 p=ReadBlobStream(image,2,buffer,&count);
3145 return((unsigned short) 0U);
3146 value=(unsigned int) (*p++);
3147 value|=((unsigned int) ((*p++)) << 8);
3148 return((unsigned short) (value & 0xffff));
3152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3156 + R e a d B l o b M S B L o n g %
3160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3162 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3163 % most-significant byte first order.
3165 % The format of the ReadBlobMSBLong method is:
3167 % unsigned int ReadBlobMSBLong(Image *image)
3169 % A description of each parameter follows.
3171 % o image: the image.
3174 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3176 register const unsigned char
3179 register unsigned int
3188 assert(image != (Image *) NULL);
3189 assert(image->signature == MagickSignature);
3191 p=ReadBlobStream(image,4,buffer,&count);
3194 value=((unsigned int) (*p++) << 24);
3195 value|=((unsigned int) (*p++) << 16);
3196 value|=((unsigned int) (*p++) << 8);
3197 value|=(unsigned int) (*p++);
3202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3206 + R e a d B l o b M S B L o n g L o n g %
3210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3212 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3213 % most-significant byte first order.
3215 % The format of the ReadBlobMSBLongLong method is:
3217 % unsigned int ReadBlobMSBLongLong(Image *image)
3219 % A description of each parameter follows.
3221 % o image: the image.
3224 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3226 register const unsigned char
3229 register MagickSizeType
3238 assert(image != (Image *) NULL);
3239 assert(image->signature == MagickSignature);
3241 p=ReadBlobStream(image,8,buffer,&count);
3243 return(MagickULLConstant(0));
3244 value=((MagickSizeType) (*p++)) << 56;
3245 value|=((MagickSizeType) (*p++)) << 48;
3246 value|=((MagickSizeType) (*p++)) << 40;
3247 value|=((MagickSizeType) (*p++)) << 32;
3248 value|=((MagickSizeType) (*p++)) << 24;
3249 value|=((MagickSizeType) (*p++)) << 16;
3250 value|=((MagickSizeType) (*p++)) << 8;
3251 value|=((MagickSizeType) (*p++));
3252 return(value & MagickULLConstant(0xffffffffffffffff));
3256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3260 + R e a d B l o b M S B S h o r t %
3264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3266 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3267 % most-significant byte first order.
3269 % The format of the ReadBlobMSBShort method is:
3271 % unsigned short ReadBlobMSBShort(Image *image)
3273 % A description of each parameter follows.
3275 % o image: the image.
3278 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3280 register const unsigned char
3283 register unsigned int
3292 assert(image != (Image *) NULL);
3293 assert(image->signature == MagickSignature);
3295 p=ReadBlobStream(image,2,buffer,&count);
3297 return((unsigned short) 0U);
3298 value=(unsigned int) ((*p++) << 8);
3299 value|=(unsigned int) (*p++);
3300 return((unsigned short) (value & 0xffff));
3304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3308 + R e a d B l o b S t r i n g %
3312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3314 % ReadBlobString() reads characters from a blob or file until a newline
3315 % character is read or an end-of-file condition is encountered.
3317 % The format of the ReadBlobString method is:
3319 % char *ReadBlobString(Image *image,char *string)
3321 % A description of each parameter follows:
3323 % o image: the image.
3325 % o string: the address of a character buffer.
3328 MagickExport char *ReadBlobString(Image *image,char *string)
3330 register const unsigned char
3342 assert(image != (Image *) NULL);
3343 assert(image->signature == MagickSignature);
3344 for (i=0; i < (MaxTextExtent-1L); i++)
3346 p=ReadBlobStream(image,1,buffer,&count);
3350 return((char *) NULL);
3353 string[i]=(char) (*p);
3354 if ((string[i] == '\r') || (string[i] == '\n'))
3357 if (string[i] == '\r')
3358 (void) ReadBlobStream(image,1,buffer,&count);
3364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3368 + R e f e r e n c e B l o b %
3372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3374 % ReferenceBlob() increments the reference count associated with the pixel
3375 % blob returning a pointer to the blob.
3377 % The format of the ReferenceBlob method is:
3379 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3381 % A description of each parameter follows:
3383 % o blob_info: the blob_info.
3386 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3388 assert(blob != (BlobInfo *) NULL);
3389 assert(blob->signature == MagickSignature);
3390 if (blob->debug != MagickFalse)
3391 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3392 LockSemaphoreInfo(blob->semaphore);
3393 blob->reference_count++;
3394 UnlockSemaphoreInfo(blob->semaphore);
3399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3409 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3410 % and returns the resulting offset.
3412 % The format of the SeekBlob method is:
3414 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3417 % A description of each parameter follows:
3419 % o image: the image.
3421 % o offset: Specifies an integer representing the offset in bytes.
3423 % o whence: Specifies an integer representing how the offset is
3424 % treated relative to the beginning of the blob as follows:
3426 % SEEK_SET Set position equal to offset bytes.
3427 % SEEK_CUR Set position to current location plus offset.
3428 % SEEK_END Set position to EOF plus offset.
3431 MagickExport MagickOffsetType SeekBlob(Image *image,
3432 const MagickOffsetType offset,const int whence)
3434 assert(image != (Image *) NULL);
3435 assert(image->signature == MagickSignature);
3436 if (image->debug != MagickFalse)
3437 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3438 assert(image->blob != (BlobInfo *) NULL);
3439 assert(image->blob->type != UndefinedStream);
3440 switch (image->blob->type)
3442 case UndefinedStream:
3446 if (fseek(image->blob->file,(long) offset,whence) < 0)
3448 image->blob->offset=TellBlob(image);
3451 case StandardStream:
3455 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3456 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3459 image->blob->offset=TellBlob(image);
3475 image->blob->offset=offset;
3480 if ((image->blob->offset+offset) < 0)
3482 image->blob->offset+=offset;
3487 if (((MagickOffsetType) image->blob->length+offset) < 0)
3489 image->blob->offset=image->blob->length+offset;
3493 if (image->blob->offset <= (MagickOffsetType)
3494 ((off_t) image->blob->length))
3495 image->blob->eof=MagickFalse;
3497 if (image->blob->mapped != MagickFalse)
3501 image->blob->extent=(size_t) (image->blob->offset+
3502 image->blob->quantum);
3503 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3504 image->blob->data,image->blob->extent+1,
3505 sizeof(*image->blob->data));
3506 (void) SyncBlob(image);
3507 if (image->blob->data == (unsigned char *) NULL)
3509 (void) DetachBlob(image->blob);
3516 return(image->blob->offset);
3520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3524 + S e t B l o b E x e m p t %
3528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3530 % SetBlobExempt() sets the blob exempt status.
3532 % The format of the SetBlobExempt method is:
3534 % MagickBooleanType SetBlobExempt(const Image *image,
3535 % const MagickBooleanType exempt)
3537 % A description of each parameter follows:
3539 % o image: the image.
3541 % o exempt: Set to true if this blob is exempt from being closed.
3544 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3546 assert(image != (const Image *) NULL);
3547 assert(image->signature == MagickSignature);
3548 if (image->debug != MagickFalse)
3549 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3550 image->blob->exempt=exempt;
3554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3558 + S e t B l o b E x t e n t %
3562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3564 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3565 % method is successful, subsequent writes to bytes in the specified range are
3566 % guaranteed not to fail.
3568 % The format of the SetBlobExtent method is:
3570 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3572 % A description of each parameter follows:
3574 % o image: the image.
3576 % o extent: the blob maximum extent.
3579 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3580 const MagickSizeType extent)
3582 assert(image != (Image *) NULL);
3583 assert(image->signature == MagickSignature);
3584 if (image->debug != MagickFalse)
3585 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3586 assert(image->blob != (BlobInfo *) NULL);
3587 assert(image->blob->type != UndefinedStream);
3588 switch (image->blob->type)
3590 case UndefinedStream:
3594 if (extent != (MagickSizeType) ((off_t) extent))
3595 return(MagickFalse);
3596 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3597 return(MagickFalse);
3606 offset=TellBlob(image);
3607 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3608 (off_t) (extent-offset));
3610 return(MagickFalse);
3615 case StandardStream:
3618 return(MagickFalse);
3620 return(MagickFalse);
3622 return(MagickFalse);
3625 if (image->blob->mapped != MagickFalse)
3627 if (image->blob->file == (FILE *) NULL)
3628 return(MagickFalse);
3629 (void) UnmapBlob(image->blob->data,image->blob->length);
3630 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3631 return(MagickFalse);
3640 offset=TellBlob(image);
3641 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3642 (off_t) (extent-offset));
3644 return(MagickFalse);
3646 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3647 WriteMode,0,(size_t) extent);
3648 image->blob->extent=(size_t) extent;
3649 image->blob->length=(size_t) extent;
3650 (void) SyncBlob(image);
3654 if (extent != (MagickSizeType) ((size_t) extent))
3655 return(MagickFalse);
3656 image->blob->extent=(size_t) extent;
3657 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3658 image->blob->extent+1,sizeof(*image->blob->data));
3659 (void) SyncBlob(image);
3660 if (image->blob->data == (unsigned char *) NULL)
3662 (void) DetachBlob(image->blob);
3663 return(MagickFalse);
3672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3682 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3683 % attributes if it is an blob.
3685 % The format of the SyncBlob method is:
3687 % int SyncBlob(Image *image)
3689 % A description of each parameter follows:
3691 % o image: the image.
3694 static int SyncBlob(Image *image)
3699 assert(image != (Image *) NULL);
3700 assert(image->signature == MagickSignature);
3701 if (image->debug != MagickFalse)
3702 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3703 assert(image->blob != (BlobInfo *) NULL);
3704 assert(image->blob->type != UndefinedStream);
3706 switch (image->blob->type)
3708 case UndefinedStream:
3711 case StandardStream:
3714 status=fflush(image->blob->file);
3719 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3720 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3726 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3727 status=BZ2_bzflush((BZFILE *) image->blob->file);
3735 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3736 if (image->blob->mapped != MagickFalse)
3737 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3756 % TellBlob() obtains the current value of the blob or file position.
3758 % The format of the TellBlob method is:
3760 % MagickOffsetType TellBlob(const Image *image)
3762 % A description of each parameter follows:
3764 % o image: the image.
3767 MagickExport MagickOffsetType TellBlob(const Image *image)
3772 assert(image != (Image *) NULL);
3773 assert(image->signature == MagickSignature);
3774 if (image->debug != MagickFalse)
3775 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3776 assert(image->blob != (BlobInfo *) NULL);
3777 assert(image->blob->type != UndefinedStream);
3779 switch (image->blob->type)
3781 case UndefinedStream:
3785 offset=ftell(image->blob->file);
3788 case StandardStream:
3793 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3794 offset=(MagickOffsetType) gztell(image->blob->file);
3804 offset=image->blob->offset;
3812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3816 + U n m a p B l o b %
3820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3822 % UnmapBlob() deallocates the binary large object previously allocated with
3823 % the MapBlob method.
3825 % The format of the UnmapBlob method is:
3827 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3829 % A description of each parameter follows:
3831 % o map: the address of the binary large object.
3833 % o length: the length of the binary large object.
3836 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3838 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3842 status=munmap(map,length);
3843 return(status == -1 ? MagickFalse : MagickTrue);
3847 return(MagickFalse);
3852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3856 + W r i t e B l o b %
3860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3862 % WriteBlob() writes data to a blob or image file. It returns the number of
3865 % The format of the WriteBlob method is:
3867 % ssize_t WriteBlob(Image *image,const size_t length,
3868 % const unsigned char *data)
3870 % A description of each parameter follows:
3872 % o image: the image.
3874 % o length: Specifies an integer representing the number of bytes to
3875 % write to the file.
3877 % o data: The address of the data to write to the blob or file.
3880 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3881 const unsigned char *data)
3886 register const unsigned char
3892 assert(image != (Image *) NULL);
3893 assert(image->signature == MagickSignature);
3894 assert(data != (const unsigned char *) NULL);
3895 assert(image->blob != (BlobInfo *) NULL);
3896 assert(image->blob->type != UndefinedStream);
3901 switch (image->blob->type)
3903 case UndefinedStream:
3906 case StandardStream:
3913 count=(ssize_t) fwrite((const char *) data,1,length,
3919 c=putc((int) *p++,image->blob->file);
3926 c=putc((int) *p++,image->blob->file);
3938 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3943 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
3944 (unsigned int) length);
3949 c=gzputc(image->blob->file,(int) *p++);
3956 c=gzputc(image->blob->file,(int) *p++);
3969 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3970 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
3977 count=(ssize_t) image->blob->stream(image,data,length);
3982 register unsigned char
3985 if ((image->blob->offset+(MagickOffsetType) length) >=
3986 (MagickOffsetType) image->blob->extent)
3988 if (image->blob->mapped != MagickFalse)
3990 image->blob->quantum<<=1;
3991 image->blob->extent+=length+image->blob->quantum;
3992 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3993 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
3994 (void) SyncBlob(image);
3995 if (image->blob->data == (unsigned char *) NULL)
3997 (void) DetachBlob(image->blob);
4001 q=image->blob->data+image->blob->offset;
4002 (void) CopyMagickMemory(q,p,length);
4003 image->blob->offset+=length;
4004 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4005 image->blob->length=(size_t) image->blob->offset;
4006 count=(ssize_t) length;
4013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4017 + W r i t e B l o b B y t e %
4021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4023 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4024 % written (either 0 or 1);
4026 % The format of the WriteBlobByte method is:
4028 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4030 % A description of each parameter follows.
4032 % o image: the image.
4034 % o value: Specifies the value to write.
4037 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4039 assert(image != (Image *) NULL);
4040 assert(image->signature == MagickSignature);
4041 return(WriteBlobStream(image,1,&value));
4045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4049 + W r i t e B l o b F l o a t %
4053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4055 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4056 % specified by the endian member of the image structure.
4058 % The format of the WriteBlobFloat method is:
4060 % ssize_t WriteBlobFloat(Image *image,const float value)
4062 % A description of each parameter follows.
4064 % o image: the image.
4066 % o value: Specifies the value to write.
4069 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4080 quantum.unsigned_value=0U;
4081 quantum.float_value=value;
4082 return(WriteBlobLong(image,quantum.unsigned_value));
4086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4090 + W r i t e B l o b L o n g %
4094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4096 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4097 % specified by the endian member of the image structure.
4099 % The format of the WriteBlobLong method is:
4101 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4103 % A description of each parameter follows.
4105 % o image: the image.
4107 % o value: Specifies the value to write.
4110 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4115 assert(image != (Image *) NULL);
4116 assert(image->signature == MagickSignature);
4117 if (image->endian == LSBEndian)
4119 buffer[0]=(unsigned char) value;
4120 buffer[1]=(unsigned char) (value >> 8);
4121 buffer[2]=(unsigned char) (value >> 16);
4122 buffer[3]=(unsigned char) (value >> 24);
4123 return(WriteBlobStream(image,4,buffer));
4125 buffer[0]=(unsigned char) (value >> 24);
4126 buffer[1]=(unsigned char) (value >> 16);
4127 buffer[2]=(unsigned char) (value >> 8);
4128 buffer[3]=(unsigned char) value;
4129 return(WriteBlobStream(image,4,buffer));
4133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4137 + W r i t e B l o b S h o r t %
4141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4143 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4144 % byte-order specified by the endian member of the image structure.
4146 % The format of the WriteBlobShort method is:
4148 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4150 % A description of each parameter follows.
4152 % o image: the image.
4154 % o value: Specifies the value to write.
4157 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4162 assert(image != (Image *) NULL);
4163 assert(image->signature == MagickSignature);
4164 if (image->endian == LSBEndian)
4166 buffer[0]=(unsigned char) value;
4167 buffer[1]=(unsigned char) (value >> 8);
4168 return(WriteBlobStream(image,2,buffer));
4170 buffer[0]=(unsigned char) (value >> 8);
4171 buffer[1]=(unsigned char) value;
4172 return(WriteBlobStream(image,2,buffer));
4176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4180 + W r i t e B l o b L S B L o n g %
4184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4186 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4187 % least-significant byte first order.
4189 % The format of the WriteBlobLSBLong method is:
4191 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4193 % A description of each parameter follows.
4195 % o image: the image.
4197 % o value: Specifies the value to write.
4200 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4205 assert(image != (Image *) NULL);
4206 assert(image->signature == MagickSignature);
4207 buffer[0]=(unsigned char) value;
4208 buffer[1]=(unsigned char) (value >> 8);
4209 buffer[2]=(unsigned char) (value >> 16);
4210 buffer[3]=(unsigned char) (value >> 24);
4211 return(WriteBlobStream(image,4,buffer));
4215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4219 + W r i t e B l o b L S B S h o r t %
4223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4225 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4226 % least-significant byte first order.
4228 % The format of the WriteBlobLSBShort method is:
4230 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4232 % A description of each parameter follows.
4234 % o image: the image.
4236 % o value: Specifies the value to write.
4239 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4244 assert(image != (Image *) NULL);
4245 assert(image->signature == MagickSignature);
4246 buffer[0]=(unsigned char) value;
4247 buffer[1]=(unsigned char) (value >> 8);
4248 return(WriteBlobStream(image,2,buffer));
4252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4256 + W r i t e B l o b M S B L o n g %
4260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4262 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4263 % most-significant byte first order.
4265 % The format of the WriteBlobMSBLong method is:
4267 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4269 % A description of each parameter follows.
4271 % o value: Specifies the value to write.
4273 % o image: the image.
4276 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4281 assert(image != (Image *) NULL);
4282 assert(image->signature == MagickSignature);
4283 buffer[0]=(unsigned char) (value >> 24);
4284 buffer[1]=(unsigned char) (value >> 16);
4285 buffer[2]=(unsigned char) (value >> 8);
4286 buffer[3]=(unsigned char) value;
4287 return(WriteBlobStream(image,4,buffer));
4291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4295 + W r i t e B l o b M S B L o n g L o n g %
4299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4301 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4302 % most-significant byte first order.
4304 % The format of the WriteBlobMSBLongLong method is:
4306 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4308 % A description of each parameter follows.
4310 % o value: Specifies the value to write.
4312 % o image: the image.
4315 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4316 const MagickSizeType value)
4321 assert(image != (Image *) NULL);
4322 assert(image->signature == MagickSignature);
4323 buffer[0]=(unsigned char) (value >> 56);
4324 buffer[1]=(unsigned char) (value >> 48);
4325 buffer[2]=(unsigned char) (value >> 40);
4326 buffer[3]=(unsigned char) (value >> 32);
4327 buffer[4]=(unsigned char) (value >> 24);
4328 buffer[5]=(unsigned char) (value >> 16);
4329 buffer[6]=(unsigned char) (value >> 8);
4330 buffer[7]=(unsigned char) value;
4331 return(WriteBlobStream(image,8,buffer));
4335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4339 + W r i t e B l o b M S B S h o r t %
4343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4345 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4346 % most-significant byte first order.
4348 % The format of the WriteBlobMSBShort method is:
4350 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4352 % A description of each parameter follows.
4354 % o value: Specifies the value to write.
4356 % o file: Specifies the file to write the data to.
4359 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4364 assert(image != (Image *) NULL);
4365 assert(image->signature == MagickSignature);
4366 buffer[0]=(unsigned char) (value >> 8);
4367 buffer[1]=(unsigned char) value;
4368 return(WriteBlobStream(image,2,buffer));
4372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4376 + W r i t e B l o b S t r i n g %
4380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4382 % WriteBlobString() write a string to a blob. It returns the number of
4383 % characters written.
4385 % The format of the WriteBlobString method is:
4387 % ssize_t WriteBlobString(Image *image,const char *string)
4389 % A description of each parameter follows.
4391 % o image: the image.
4393 % o string: Specifies the string to write.
4396 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4398 assert(image != (Image *) NULL);
4399 assert(image->signature == MagickSignature);
4400 assert(string != (const char *) NULL);
4401 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));