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/utility.h"
63 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(__WINDOWS__)
64 # include <sys/mman.h>
66 #if defined(MAGICKCORE_ZLIB_DELEGATE)
69 #if defined(MAGICKCORE_BZLIB_DELEGATE)
76 #define MagickMaxBlobExtent 65541
77 #if defined(MAGICKCORE_HAVE_FSEEKO)
81 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
82 # define MAP_ANONYMOUS MAP_ANON
84 #if !defined(MAP_FAILED)
85 #define MAP_FAILED ((void *) -1)
92 #define _O_BINARY O_BINARY
150 Forward declarations.
156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160 + A t t a c h B l o b %
164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
166 % AttachBlob() attaches a blob to the BlobInfo structure.
168 % The format of the AttachBlob method is:
170 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
172 % A description of each parameter follows:
174 % o blob_info: Specifies a pointer to a BlobInfo structure.
176 % o blob: the address of a character stream in one of the image formats
177 % understood by ImageMagick.
179 % o length: This size_t integer reflects the length in bytes of the blob.
182 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
185 assert(blob_info != (BlobInfo *) NULL);
186 if (blob_info->debug != MagickFalse)
187 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
188 blob_info->length=length;
189 blob_info->extent=length;
190 blob_info->quantum=(size_t) MagickMaxBlobExtent;
192 blob_info->type=BlobStream;
193 blob_info->file=(FILE *) NULL;
194 blob_info->data=(unsigned char *) blob;
195 blob_info->mapped=MagickFalse;
199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 + B l o b T o F i l e %
207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
210 % occurs otherwise MagickTrue.
212 % The format of the BlobToFile method is:
214 % MagickBooleanType BlobToFile(char *filename,const void *blob,
215 % const size_t length,ExceptionInfo *exception)
217 % A description of each parameter follows:
219 % o filename: Write the blob to this file.
221 % o blob: the address of a blob.
223 % o length: This length in bytes of the blob.
225 % o exception: return any errors or warnings in this structure.
229 static inline size_t MagickMin(const size_t x,const size_t y)
236 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
237 const size_t length,ExceptionInfo *exception)
248 assert(filename != (const char *) NULL);
249 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
250 assert(blob != (const void *) NULL);
251 if (*filename == '\0')
252 file=AcquireUniqueFileResource(filename);
254 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
257 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
260 for (i=0; i < length; i+=count)
262 count=(ssize_t) write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
274 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285 % B l o b T o I m a g e %
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291 % BlobToImage() implements direct to memory image formats. It returns the
294 % The format of the BlobToImage method is:
296 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
297 % const size_t length,ExceptionInfo *exception)
299 % A description of each parameter follows:
301 % o image_info: the image info.
303 % o blob: the address of a character stream in one of the image formats
304 % understood by ImageMagick.
306 % o length: This size_t integer reflects the length in bytes of the blob.
308 % o exception: return any errors or warnings in this structure.
311 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
312 const size_t length,ExceptionInfo *exception)
327 assert(image_info != (ImageInfo *) NULL);
328 assert(image_info->signature == MagickSignature);
329 if (image_info->debug != MagickFalse)
330 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
331 image_info->filename);
332 assert(exception != (ExceptionInfo *) NULL);
333 if ((blob == (const void *) NULL) || (length == 0))
335 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
336 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
337 return((Image *) NULL);
339 blob_info=CloneImageInfo(image_info);
340 blob_info->blob=(void *) blob;
341 blob_info->length=length;
342 if (*blob_info->magick == '\0')
343 (void) SetImageInfo(blob_info,0,exception);
344 magick_info=GetMagickInfo(blob_info->magick,exception);
345 if (magick_info == (const MagickInfo *) NULL)
347 blob_info=DestroyImageInfo(blob_info);
348 (void) ThrowMagickException(exception,GetMagickModule(),
349 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
350 image_info->filename);
351 return((Image *) NULL);
353 if (GetMagickBlobSupport(magick_info) != MagickFalse)
356 Native blob support for this image format.
358 (void) CopyMagickString(blob_info->filename,image_info->filename,
360 (void) CopyMagickString(blob_info->magick,image_info->magick,
362 image=ReadImage(blob_info,exception);
363 if (image != (Image *) NULL)
364 (void) DetachBlob(image->blob);
365 blob_info=DestroyImageInfo(blob_info);
369 Write blob to a temporary file on disk.
371 blob_info->blob=(void *) NULL;
373 *blob_info->filename='\0';
374 status=BlobToFile(blob_info->filename,blob,length,exception);
375 if (status == MagickFalse)
377 (void) RelinquishUniqueFileResource(blob_info->filename);
378 blob_info=DestroyImageInfo(blob_info);
379 return((Image *) NULL);
381 clone_info=CloneImageInfo(blob_info);
382 (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
383 blob_info->magick,blob_info->filename);
384 image=ReadImage(clone_info,exception);
385 clone_info=DestroyImageInfo(clone_info);
386 (void) RelinquishUniqueFileResource(blob_info->filename);
387 blob_info=DestroyImageInfo(blob_info);
392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396 + C l o n e B l o b I n f o %
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
403 % blob info is NULL, a new one.
405 % The format of the CloneBlobInfo method is:
407 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
409 % A description of each parameter follows:
411 % o blob_info: the blob info.
414 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
419 clone_info=(BlobInfo *) AcquireAlignedMemory(1,sizeof(*clone_info));
420 if (clone_info == (BlobInfo *) NULL)
421 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
422 GetBlobInfo(clone_info);
423 if (blob_info == (BlobInfo *) NULL)
425 clone_info->length=blob_info->length;
426 clone_info->extent=blob_info->extent;
427 clone_info->synchronize=blob_info->synchronize;
428 clone_info->quantum=blob_info->quantum;
429 clone_info->mapped=blob_info->mapped;
430 clone_info->eof=blob_info->eof;
431 clone_info->offset=blob_info->offset;
432 clone_info->size=blob_info->size;
433 clone_info->exempt=blob_info->exempt;
434 clone_info->status=blob_info->status;
435 clone_info->temporary=blob_info->temporary;
436 clone_info->type=blob_info->type;
437 clone_info->file=blob_info->file;
438 clone_info->properties=blob_info->properties;
439 clone_info->stream=blob_info->stream;
440 clone_info->data=blob_info->data;
441 clone_info->debug=IsEventLogging();
442 clone_info->reference_count=1;
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451 + C l o s e B l o b %
455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457 % CloseBlob() closes a stream associated with the image.
459 % The format of the CloseBlob method is:
461 % MagickBooleanType CloseBlob(Image *image)
463 % A description of each parameter follows:
465 % o image: the image.
468 MagickExport MagickBooleanType CloseBlob(Image *image)
476 assert(image != (Image *) NULL);
477 assert(image->signature == MagickSignature);
478 if (image->debug != MagickFalse)
479 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
480 assert(image->blob != (BlobInfo *) NULL);
481 if (image->blob->type == UndefinedStream)
483 if (image->blob->synchronize != MagickFalse)
485 image->blob->size=GetBlobSize(image);
486 image->extent=image->blob->size;
487 image->blob->eof=MagickFalse;
488 if (image->blob->exempt != MagickFalse)
490 image->blob->type=UndefinedStream;
494 switch (image->blob->type)
496 case UndefinedStream:
502 status=ferror(image->blob->file);
507 #if defined(MAGICKCORE_ZLIB_DELEGATE)
508 (void) gzerror(image->blob->file,&status);
514 #if defined(MAGICKCORE_BZLIB_DELEGATE)
515 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
523 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
524 switch (image->blob->type)
526 case UndefinedStream:
531 if (image->blob->synchronize != MagickFalse)
532 status=fsync(fileno(image->blob->file));
533 status=fclose(image->blob->file);
538 #if defined(MAGICKCORE_HAVE_PCLOSE)
539 status=pclose(image->blob->file);
545 #if defined(MAGICKCORE_ZLIB_DELEGATE)
546 status=gzclose(image->blob->file);
552 #if defined(MAGICKCORE_BZLIB_DELEGATE)
553 BZ2_bzclose((BZFILE *) image->blob->file);
561 (void) DetachBlob(image->blob);
562 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
563 return(image->blob->status);
567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
571 + D e s t r o y B l o b %
575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
577 % DestroyBlob() deallocates memory associated with a blob.
579 % The format of the DestroyBlob method is:
581 % void DestroyBlob(Image *image)
583 % A description of each parameter follows:
585 % o image: the image.
588 MagickExport void DestroyBlob(Image *image)
593 assert(image != (Image *) NULL);
594 assert(image->signature == MagickSignature);
595 if (image->debug != MagickFalse)
596 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
597 assert(image->blob != (BlobInfo *) NULL);
598 assert(image->blob->signature == MagickSignature);
600 LockSemaphoreInfo(image->blob->semaphore);
601 image->blob->reference_count--;
602 assert(image->blob->reference_count >= 0);
603 if (image->blob->reference_count == 0)
605 UnlockSemaphoreInfo(image->blob->semaphore);
606 if (destroy == MagickFalse)
608 (void) CloseBlob(image);
609 if (image->blob->mapped != MagickFalse)
610 (void) UnmapBlob(image->blob->data,image->blob->length);
611 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
612 DestroySemaphoreInfo(&image->blob->semaphore);
613 image->blob->signature=(~MagickSignature);
614 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622 + D e t a c h B l o b %
626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628 % DetachBlob() detaches a blob from the BlobInfo structure.
630 % The format of the DetachBlob method is:
632 % unsigned char *DetachBlob(BlobInfo *blob_info)
634 % A description of each parameter follows:
636 % o blob_info: Specifies a pointer to a BlobInfo structure.
639 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
644 assert(blob_info != (BlobInfo *) NULL);
645 if (blob_info->debug != MagickFalse)
646 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
647 if (blob_info->mapped != MagickFalse)
648 (void) UnmapBlob(blob_info->data,blob_info->length);
649 blob_info->mapped=MagickFalse;
652 blob_info->eof=MagickFalse;
653 blob_info->exempt=MagickFalse;
654 blob_info->type=UndefinedStream;
655 blob_info->file=(FILE *) NULL;
656 data=blob_info->data;
657 blob_info->data=(unsigned char *) NULL;
658 blob_info->stream=(StreamHandler) NULL;
663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
667 + D u p l i c a t e s B l o b %
671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673 % DuplicateBlob() duplicates a blob descriptor.
675 % The format of the DuplicateBlob method is:
677 % void DuplicateBlob(Image *image,const Image *duplicate)
679 % A description of each parameter follows:
681 % o image: the image.
683 % o duplicate: the duplicate image.
686 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
688 assert(image != (Image *) NULL);
689 assert(image->signature == MagickSignature);
690 if (image->debug != MagickFalse)
691 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
692 assert(duplicate != (Image *) NULL);
693 assert(duplicate->signature == MagickSignature);
695 image->blob=ReferenceBlob(duplicate->blob);
699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
709 % EOFBlob() returns a non-zero value when EOF has been detected reading from
712 % The format of the EOFBlob method is:
714 % int EOFBlob(const Image *image)
716 % A description of each parameter follows:
718 % o image: the image.
721 MagickExport int EOFBlob(const Image *image)
723 assert(image != (Image *) NULL);
724 assert(image->signature == MagickSignature);
725 if (image->debug != MagickFalse)
726 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
727 assert(image->blob != (BlobInfo *) NULL);
728 assert(image->blob->type != UndefinedStream);
729 switch (image->blob->type)
731 case UndefinedStream:
737 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
742 image->blob->eof=MagickFalse;
747 #if defined(MAGICKCORE_BZLIB_DELEGATE)
752 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
753 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
759 image->blob->eof=MagickFalse;
765 return((int) image->blob->eof);
769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773 + F i l e T o B l o b %
777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779 % FileToBlob() returns the contents of a file as a blob. It returns the
780 % file as a blob and its length. If an error occurs, NULL is returned.
782 % The format of the FileToBlob method is:
784 % unsigned char *FileToBlob(const char *filename,const size_t extent,
785 % size_t *length,ExceptionInfo *exception)
787 % A description of each parameter follows:
789 % o blob: FileToBlob() returns the contents of a file as a blob. If
790 % an error occurs NULL is returned.
792 % o filename: the filename.
794 % o extent: The maximum length of the blob.
796 % o length: On return, this reflects the actual length of the blob.
798 % o exception: return any errors or warnings in this structure.
801 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
802 size_t *length,ExceptionInfo *exception)
822 assert(filename != (const char *) NULL);
823 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
824 assert(exception != (ExceptionInfo *) NULL);
827 if (LocaleCompare(filename,"-") != 0)
828 file=open(filename,O_RDONLY | O_BINARY);
831 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
832 return((unsigned char *) NULL);
834 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
836 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
845 Stream is not seekable.
847 quantum=(size_t) MagickMaxBufferExtent;
848 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
849 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
850 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
851 for (i=0; blob != (unsigned char *) NULL; i+=count)
853 count=(ssize_t) read(file,blob+i,quantum);
860 if (~(1UL*i) < (quantum+1))
862 blob=(unsigned char *) RelinquishMagickMemory(blob);
865 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
867 if ((size_t) (i+count) >= extent)
871 if (blob == (unsigned char *) NULL)
873 (void) ThrowMagickException(exception,GetMagickModule(),
874 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
875 return((unsigned char *) NULL);
877 *length=MagickMin(i+count,extent);
881 *length=MagickMin((size_t) offset,extent);
882 blob=(unsigned char *) NULL;
883 if (~(*length) >= MaxTextExtent)
884 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
886 if (blob == (unsigned char *) NULL)
889 (void) ThrowMagickException(exception,GetMagickModule(),
890 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
891 return((unsigned char *) NULL);
893 map=MapBlob(file,ReadMode,0,*length);
894 if (map != (unsigned char *) NULL)
896 (void) CopyMagickMemory(blob,map,*length);
897 (void) UnmapBlob(map,*length);
901 (void) MagickSeek(file,0,SEEK_SET);
902 for (i=0; i < *length; i+=count)
904 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
916 blob=(unsigned char *) RelinquishMagickMemory(blob);
917 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
918 return((unsigned char *) NULL);
927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
931 % F i l e T o I m a g e %
935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
937 % FileToImage() write the contents of a file to an image.
939 % The format of the FileToImage method is:
941 % MagickBooleanType FileToImage(Image *,const char *filename)
943 % A description of each parameter follows:
945 % o image: the image.
947 % o filename: the filename.
951 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
952 const unsigned char *data)
957 register unsigned char
960 assert(image->blob != (BlobInfo *) NULL);
961 if (image->blob->type != BlobStream)
962 return(WriteBlob(image,length,data));
963 assert(image->blob->type != UndefinedStream);
964 assert(data != (void *) NULL);
965 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
966 if (extent >= image->blob->extent)
968 image->blob->quantum<<=1;
969 extent=image->blob->extent+image->blob->quantum+length;
970 if (SetBlobExtent(image,extent) == MagickFalse)
973 q=image->blob->data+image->blob->offset;
974 (void) CopyMagickMemory(q,data,length);
975 image->blob->offset+=length;
976 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
977 image->blob->length=(size_t) image->blob->offset;
978 return((ssize_t) length);
981 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
999 assert(image != (const Image *) NULL);
1000 assert(image->signature == MagickSignature);
1001 assert(filename != (const char *) NULL);
1002 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1003 file=open(filename,O_RDONLY | O_BINARY);
1006 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1008 return(MagickFalse);
1010 quantum=(size_t) MagickMaxBufferExtent;
1011 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1012 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1013 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1014 if (blob == (unsigned char *) NULL)
1016 ThrowFileException(&image->exception,ResourceLimitError,
1017 "MemoryAllocationFailed",filename);
1018 return(MagickFalse);
1022 count=(ssize_t) read(file,blob,quantum);
1029 length=(size_t) count;
1030 count=WriteBlobStream(image,length,blob);
1031 if (count != (ssize_t) length)
1033 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1039 blob=(unsigned char *) RelinquishMagickMemory(blob);
1044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048 + G e t B l o b E r r o r %
1052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1054 % GetBlobError() returns MagickTrue if the blob associated with the specified
1055 % image encountered an error.
1057 % The format of the GetBlobError method is:
1059 % MagickBooleanType GetBlobError(const Image *image)
1061 % A description of each parameter follows:
1063 % o image: the image.
1066 MagickExport MagickBooleanType GetBlobError(const Image *image)
1068 assert(image != (const Image *) NULL);
1069 assert(image->signature == MagickSignature);
1070 if (image->debug != MagickFalse)
1071 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1072 return(image->blob->status);
1076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080 + G e t B l o b F i l e H a n d l e %
1084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1086 % GetBlobFileHandle() returns the file handle associated with the image blob.
1088 % The format of the GetBlobFile method is:
1090 % FILE *GetBlobFileHandle(const Image *image)
1092 % A description of each parameter follows:
1094 % o image: the image.
1097 MagickExport FILE *GetBlobFileHandle(const Image *image)
1099 assert(image != (const Image *) NULL);
1100 assert(image->signature == MagickSignature);
1101 return(image->blob->file);
1105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109 + G e t B l o b I n f o %
1113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1115 % GetBlobInfo() initializes the BlobInfo structure.
1117 % The format of the GetBlobInfo method is:
1119 % void GetBlobInfo(BlobInfo *blob_info)
1121 % A description of each parameter follows:
1123 % o blob_info: Specifies a pointer to a BlobInfo structure.
1126 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1128 assert(blob_info != (BlobInfo *) NULL);
1129 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1130 blob_info->type=UndefinedStream;
1131 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1132 blob_info->properties.st_mtime=time((time_t *) NULL);
1133 blob_info->properties.st_ctime=time((time_t *) NULL);
1134 blob_info->debug=IsEventLogging();
1135 blob_info->reference_count=1;
1136 blob_info->semaphore=AllocateSemaphoreInfo();
1137 blob_info->signature=MagickSignature;
1141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1145 % G e t B l o b P r o p e r t i e s %
1149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1151 % GetBlobProperties() returns information about an image blob.
1153 % The format of the GetBlobProperties method is:
1155 % const struct stat *GetBlobProperties(const Image *image)
1157 % A description of each parameter follows:
1159 % o image: the image.
1162 MagickExport const struct stat *GetBlobProperties(const Image *image)
1164 assert(image != (Image *) NULL);
1165 assert(image->signature == MagickSignature);
1166 if (image->debug != MagickFalse)
1167 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1168 return(&image->blob->properties);
1172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1176 + G e t B l o b S i z e %
1180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1182 % GetBlobSize() returns the current length of the image file or blob; zero is
1183 % returned if the size cannot be determined.
1185 % The format of the GetBlobSize method is:
1187 % MagickSizeType GetBlobSize(const Image *image)
1189 % A description of each parameter follows:
1191 % o image: the image.
1194 MagickExport MagickSizeType GetBlobSize(const Image *image)
1199 assert(image != (Image *) NULL);
1200 assert(image->signature == MagickSignature);
1201 if (image->debug != MagickFalse)
1202 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1203 assert(image->blob != (BlobInfo *) NULL);
1205 switch (image->blob->type)
1207 case UndefinedStream:
1209 extent=image->blob->size;
1214 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1215 extent=(MagickSizeType) image->blob->properties.st_size;
1218 case StandardStream:
1221 extent=image->blob->size;
1230 status=GetPathAttributes(image->filename,&image->blob->properties);
1231 if (status != MagickFalse)
1232 extent=(MagickSizeType) image->blob->properties.st_size;
1239 extent=(MagickSizeType) image->blob->length;
1247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1251 + G e t B l o b S t r e a m D a t a %
1255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1257 % GetBlobStreamData() returns the stream data for the image.
1259 % The format of the GetBlobStreamData method is:
1261 % unsigned char *GetBlobStreamData(const Image *image)
1263 % A description of each parameter follows:
1265 % o image: the image.
1268 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1270 assert(image != (const Image *) NULL);
1271 assert(image->signature == MagickSignature);
1272 return(image->blob->data);
1276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1280 + G e t B l o b S t r e a m H a n d l e r %
1284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1286 % GetBlobStreamHandler() returns the stream handler for the image.
1288 % The format of the GetBlobStreamHandler method is:
1290 % StreamHandler GetBlobStreamHandler(const Image *image)
1292 % A description of each parameter follows:
1294 % o image: the image.
1297 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1299 assert(image != (const Image *) NULL);
1300 assert(image->signature == MagickSignature);
1301 if (image->debug != MagickFalse)
1302 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1303 return(image->blob->stream);
1307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1311 % I m a g e T o B l o b %
1315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1317 % ImageToBlob() implements direct to memory image formats. It returns the
1318 % image as a blob and its length. The magick member of the ImageInfo structure
1319 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1321 % The format of the ImageToBlob method is:
1323 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1324 % size_t *length,ExceptionInfo *exception)
1326 % A description of each parameter follows:
1328 % o image_info: the image info.
1330 % o image: the image.
1332 % o length: This pointer to a size_t integer sets the initial length of the
1333 % blob. On return, it reflects the actual length of the blob.
1335 % o exception: return any errors or warnings in this structure.
1338 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1339 Image *image,size_t *length,ExceptionInfo *exception)
1353 assert(image_info != (const ImageInfo *) NULL);
1354 assert(image_info->signature == MagickSignature);
1355 if (image_info->debug != MagickFalse)
1356 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1357 image_info->filename);
1358 assert(image != (Image *) NULL);
1359 assert(image->signature == MagickSignature);
1360 assert(exception != (ExceptionInfo *) NULL);
1362 blob=(unsigned char *) NULL;
1363 blob_info=CloneImageInfo(image_info);
1364 blob_info->adjoin=MagickFalse;
1365 (void) SetImageInfo(blob_info,1,exception);
1366 if (*blob_info->magick != '\0')
1367 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1368 magick_info=GetMagickInfo(image->magick,exception);
1369 if (magick_info == (const MagickInfo *) NULL)
1371 (void) ThrowMagickException(exception,GetMagickModule(),
1372 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1376 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1377 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1380 Native blob support for this image format.
1382 blob_info->length=0;
1383 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1384 sizeof(unsigned char));
1385 if (blob_info->blob == (void *) NULL)
1386 (void) ThrowMagickException(exception,GetMagickModule(),
1387 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1390 (void) CloseBlob(image);
1391 image->blob->exempt=MagickTrue;
1392 *image->filename='\0';
1393 status=WriteImage(blob_info,image);
1394 if ((status == MagickFalse) || (image->blob->length == 0))
1395 InheritException(exception,&image->exception);
1398 *length=image->blob->length;
1399 blob=DetachBlob(image->blob);
1400 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1408 unique[MaxTextExtent];
1414 Write file to disk in blob image format.
1416 file=AcquireUniqueFileResource(unique);
1419 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1420 image_info->filename);
1424 blob_info->file=fdopen(file,"wb");
1425 if (blob_info->file != (FILE *) NULL)
1427 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1428 image->magick,unique);
1429 status=WriteImage(blob_info,image);
1430 (void) fclose(blob_info->file);
1431 if (status == MagickFalse)
1432 InheritException(exception,&image->exception);
1434 blob=FileToBlob(image->filename,~0UL,length,exception);
1436 (void) RelinquishUniqueFileResource(unique);
1439 blob_info=DestroyImageInfo(blob_info);
1444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1448 % I m a g e T o F i l e %
1452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1454 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1455 % occurs otherwise MagickTrue.
1457 % The format of the ImageToFile method is:
1459 % MagickBooleanType ImageToFile(Image *image,char *filename,
1460 % ExceptionInfo *exception)
1462 % A description of each parameter follows:
1464 % o image: the image.
1466 % o filename: Write the image to this file.
1468 % o exception: return any errors or warnings in this structure.
1472 static inline const unsigned char *ReadBlobStream(Image *image,
1473 const size_t length,unsigned char *data,ssize_t *count)
1475 assert(count != (ssize_t *) NULL);
1476 assert(image->blob != (BlobInfo *) NULL);
1477 if (image->blob->type != BlobStream)
1479 *count=ReadBlob(image,length,data);
1482 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1485 image->blob->eof=MagickTrue;
1488 data=image->blob->data+image->blob->offset;
1489 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
1490 image->blob->offset));
1491 image->blob->offset+=(*count);
1492 if (*count != (ssize_t) length)
1493 image->blob->eof=MagickTrue;
1497 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1498 ExceptionInfo *exception)
1503 register const unsigned char
1522 assert(image != (Image *) NULL);
1523 assert(image->signature == MagickSignature);
1524 assert(image->blob != (BlobInfo *) NULL);
1525 assert(image->blob->type != UndefinedStream);
1526 if (image->debug != MagickFalse)
1527 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1528 assert(filename != (const char *) NULL);
1529 if (*filename == '\0')
1530 file=AcquireUniqueFileResource(filename);
1532 if (LocaleCompare(filename,"-") == 0)
1533 file=fileno(stdout);
1535 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1538 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1539 return(MagickFalse);
1541 quantum=(size_t) MagickMaxBufferExtent;
1542 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1543 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1544 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1545 if (buffer == (unsigned char *) NULL)
1548 (void) ThrowMagickException(exception,GetMagickModule(),
1549 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1550 return(MagickFalse);
1553 p=ReadBlobStream(image,quantum,buffer,&count);
1554 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1556 length=(size_t) count;
1557 for (i=0; i < length; i+=count)
1559 count=write(file,p+i,(size_t) (length-i));
1571 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1574 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1575 return(MagickFalse);
1581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1585 % I m a g e s T o B l o b %
1589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1591 % ImagesToBlob() implements direct to memory image formats. It returns the
1592 % image sequence as a blob and its length. The magick member of the ImageInfo
1593 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1595 % Note, some image formats do not permit multiple images to the same image
1596 % stream (e.g. JPEG). in this instance, just the first image of the
1597 % sequence is returned as a blob.
1599 % The format of the ImagesToBlob method is:
1601 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1602 % size_t *length,ExceptionInfo *exception)
1604 % A description of each parameter follows:
1606 % o image_info: the image info.
1608 % o images: the image list.
1610 % o length: This pointer to a size_t integer sets the initial length of the
1611 % blob. On return, it reflects the actual length of the blob.
1613 % o exception: return any errors or warnings in this structure.
1616 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1617 Image *images,size_t *length,ExceptionInfo *exception)
1631 assert(image_info != (const ImageInfo *) NULL);
1632 assert(image_info->signature == MagickSignature);
1633 if (image_info->debug != MagickFalse)
1634 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1635 image_info->filename);
1636 assert(images != (Image *) NULL);
1637 assert(images->signature == MagickSignature);
1638 assert(exception != (ExceptionInfo *) NULL);
1640 blob=(unsigned char *) NULL;
1641 blob_info=CloneImageInfo(image_info);
1642 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1644 if (*blob_info->magick != '\0')
1645 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1646 if (blob_info->adjoin == MagickFalse)
1648 blob_info=DestroyImageInfo(blob_info);
1649 return(ImageToBlob(image_info,images,length,exception));
1651 magick_info=GetMagickInfo(images->magick,exception);
1652 if (magick_info == (const MagickInfo *) NULL)
1654 (void) ThrowMagickException(exception,GetMagickModule(),
1655 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1659 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1660 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1663 Native blob support for this images format.
1665 blob_info->length=0;
1666 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1667 sizeof(unsigned char));
1668 if (blob_info->blob == (void *) NULL)
1669 (void) ThrowMagickException(exception,GetMagickModule(),
1670 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1673 images->blob->exempt=MagickTrue;
1674 *images->filename='\0';
1675 status=WriteImages(blob_info,images,images->filename,exception);
1676 if ((status == MagickFalse) || (images->blob->length == 0))
1677 InheritException(exception,&images->exception);
1680 *length=images->blob->length;
1681 blob=DetachBlob(images->blob);
1682 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1690 filename[MaxTextExtent],
1691 unique[MaxTextExtent];
1697 Write file to disk in blob images format.
1699 file=AcquireUniqueFileResource(unique);
1702 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1703 image_info->filename);
1707 blob_info->file=fdopen(file,"wb");
1708 if (blob_info->file != (FILE *) NULL)
1710 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1711 images->magick,unique);
1712 status=WriteImages(blob_info,images,filename,exception);
1713 (void) fclose(blob_info->file);
1714 if (status == MagickFalse)
1715 InheritException(exception,&images->exception);
1717 blob=FileToBlob(images->filename,~0UL,length,exception);
1719 (void) RelinquishUniqueFileResource(unique);
1722 blob_info=DestroyImageInfo(blob_info);
1726 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1730 % I n j e c t I m a g e B l o b %
1734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1736 % InjectImageBlob() injects the image with a copy of itself in the specified
1737 % format (e.g. inject JPEG into a PDF image).
1739 % The format of the InjectImageBlob method is:
1741 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1742 % Image *image,Image *inject_image,const char *format,
1743 % ExceptionInfo *exception)
1745 % A description of each parameter follows:
1747 % o image_info: the image info..
1749 % o image: the image.
1751 % o inject_image: inject into the image stream.
1753 % o format: the image format.
1755 % o exception: return any errors or warnings in this structure.
1758 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1759 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1762 filename[MaxTextExtent];
1795 Write inject image to a temporary file.
1797 assert(image_info != (ImageInfo *) NULL);
1798 assert(image_info->signature == MagickSignature);
1799 assert(image != (Image *) NULL);
1800 assert(image->signature == MagickSignature);
1801 if (image->debug != MagickFalse)
1802 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1803 assert(inject_image != (Image *) NULL);
1804 assert(inject_image->signature == MagickSignature);
1805 assert(exception != (ExceptionInfo *) NULL);
1806 unique_file=(FILE *) NULL;
1807 file=AcquireUniqueFileResource(filename);
1809 unique_file=fdopen(file,"wb");
1810 if ((file == -1) || (unique_file == (FILE *) NULL))
1812 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1813 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1815 return(MagickFalse);
1817 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1818 if (byte_image == (Image *) NULL)
1820 (void) fclose(unique_file);
1821 (void) RelinquishUniqueFileResource(filename);
1822 return(MagickFalse);
1824 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1826 DestroyBlob(byte_image);
1827 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1828 write_info=CloneImageInfo(image_info);
1829 SetImageInfoFile(write_info,unique_file);
1830 status=WriteImage(write_info,byte_image);
1831 write_info=DestroyImageInfo(write_info);
1832 byte_image=DestroyImage(byte_image);
1833 (void) fclose(unique_file);
1834 if (status == MagickFalse)
1836 (void) RelinquishUniqueFileResource(filename);
1837 return(MagickFalse);
1840 Inject into image stream.
1842 file=open(filename,O_RDONLY | O_BINARY);
1845 (void) RelinquishUniqueFileResource(filename);
1846 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1847 image_info->filename);
1848 return(MagickFalse);
1850 quantum=(size_t) MagickMaxBufferExtent;
1851 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1852 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1853 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1854 if (buffer == (unsigned char *) NULL)
1856 (void) RelinquishUniqueFileResource(filename);
1857 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1860 for (i=0; ; i+=count)
1862 count=(ssize_t) read(file,buffer,quantum);
1869 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1873 (void) RelinquishUniqueFileResource(filename);
1874 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1883 + I s B l o b E x e m p t %
1887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1889 % IsBlobExempt() returns true if the blob is exempt.
1891 % The format of the IsBlobExempt method is:
1893 % MagickBooleanType IsBlobExempt(const Image *image)
1895 % A description of each parameter follows:
1897 % o image: the image.
1900 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1902 assert(image != (const Image *) NULL);
1903 assert(image->signature == MagickSignature);
1904 if (image->debug != MagickFalse)
1905 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1906 return(image->blob->exempt);
1910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1914 + I s B l o b S e e k a b l e %
1918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1920 % IsBlobSeekable() returns true if the blob is seekable.
1922 % The format of the IsBlobSeekable method is:
1924 % MagickBooleanType IsBlobSeekable(const Image *image)
1926 % A description of each parameter follows:
1928 % o image: the image.
1931 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
1936 assert(image != (const Image *) NULL);
1937 assert(image->signature == MagickSignature);
1938 if (image->debug != MagickFalse)
1939 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1940 seekable=(image->blob->type == FileStream) ||
1941 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
1946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1950 + I s B l o b T e m p o r a r y %
1954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1956 % IsBlobTemporary() returns true if the blob is temporary.
1958 % The format of the IsBlobTemporary method is:
1960 % MagickBooleanType IsBlobTemporary(const Image *image)
1962 % A description of each parameter follows:
1964 % o image: the image.
1967 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
1969 assert(image != (const Image *) NULL);
1970 assert(image->signature == MagickSignature);
1971 if (image->debug != MagickFalse)
1972 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1973 return(image->blob->temporary);
1977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1987 % MapBlob() creates a mapping from a file to a binary large object.
1989 % The format of the MapBlob method is:
1991 % unsigned char *MapBlob(int file,const MapMode mode,
1992 % const MagickOffsetType offset,const size_t length)
1994 % A description of each parameter follows:
1996 % o file: map this file descriptor.
1998 % o mode: ReadMode, WriteMode, or IOMode.
2000 % o offset: starting at this offset within the file.
2002 % o length: the length of the mapping is returned in this pointer.
2005 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2006 const MagickOffsetType offset,const size_t length)
2008 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2021 #if defined(MAP_ANONYMOUS)
2022 flags|=MAP_ANONYMOUS;
2024 return((unsigned char *) NULL);
2031 protection=PROT_READ;
2033 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2039 protection=PROT_WRITE;
2041 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2043 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2044 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2045 POSIX_MADV_WILLNEED);
2051 protection=PROT_READ | PROT_WRITE;
2053 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2058 if (map == (unsigned char *) MAP_FAILED)
2059 return((unsigned char *) NULL);
2066 return((unsigned char *) NULL);
2071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2075 + M S B O r d e r L o n g %
2079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2081 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2082 % most-significant byte first.
2084 % The format of the MSBOrderLong method is:
2086 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2088 % A description of each parameter follows.
2090 % o buffer: Specifies a pointer to a buffer of integers.
2092 % o length: Specifies the length of the buffer.
2095 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2100 register unsigned char
2104 assert(buffer != (unsigned char *) NULL);
2111 *buffer++=(unsigned char) c;
2115 *buffer++=(unsigned char) c;
2121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2125 + M S B O r d e r S h o r t %
2129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2131 % MSBOrderShort() converts a least-significant byte first buffer of integers
2132 % to most-significant byte first.
2134 % The format of the MSBOrderShort method is:
2136 % void MSBOrderShort(unsigned char *p,const size_t length)
2138 % A description of each parameter follows.
2140 % o p: Specifies a pointer to a buffer of integers.
2142 % o length: Specifies the length of the buffer.
2145 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2150 register unsigned char
2153 assert(p != (unsigned char *) NULL);
2160 *p++=(unsigned char) c;
2165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2175 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2176 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2177 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2178 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2179 % from a system command.
2181 % The format of the OpenBlob method is:
2183 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2184 % const BlobMode mode,ExceptionInfo *exception)
2186 % A description of each parameter follows:
2188 % o image_info: the image info.
2190 % o image: the image.
2192 % o mode: the mode for opening the file.
2195 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2196 Image *image,const BlobMode mode,ExceptionInfo *exception)
2199 filename[MaxTextExtent];
2210 assert(image_info != (ImageInfo *) NULL);
2211 assert(image_info->signature == MagickSignature);
2212 if (image_info->debug != MagickFalse)
2213 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2214 image_info->filename);
2215 assert(image != (Image *) NULL);
2216 assert(image->signature == MagickSignature);
2217 if (image_info->blob != (void *) NULL)
2219 if (image_info->stream != (StreamHandler) NULL)
2220 image->blob->stream=(StreamHandler) image_info->stream;
2221 AttachBlob(image->blob,image_info->blob,image_info->length);
2224 (void) DetachBlob(image->blob);
2227 default: type="r"; break;
2228 case ReadBlobMode: type="r"; break;
2229 case ReadBinaryBlobMode: type="rb"; break;
2230 case WriteBlobMode: type="w"; break;
2231 case WriteBinaryBlobMode: type="w+b"; break;
2232 case AppendBlobMode: type="a"; break;
2233 case AppendBinaryBlobMode: type="a+b"; break;
2236 image->blob->synchronize=image_info->synchronize;
2237 if (image_info->stream != (StreamHandler) NULL)
2239 image->blob->stream=(StreamHandler) image_info->stream;
2242 image->blob->type=FifoStream;
2250 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2251 rights=ReadPolicyRights;
2253 rights=WritePolicyRights;
2254 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2257 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2258 "NotAuthorized","`%s'",filename);
2259 return(MagickFalse);
2261 if ((LocaleCompare(filename,"-") == 0) ||
2262 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2264 image->blob->file=(*type == 'r') ? stdin : stdout;
2265 #if defined(__WINDOWS__) || defined(__OS2__)
2266 if (strchr(type,'b') != (char *) NULL)
2267 setmode(_fileno(image->blob->file),_O_BINARY);
2269 image->blob->type=StandardStream;
2270 image->blob->exempt=MagickTrue;
2273 if (LocaleNCompare(filename,"fd:",3) == 0)
2276 mode[MaxTextExtent];
2280 image->blob->file=fdopen(StringToLong(filename+3),mode);
2281 #if defined(__WINDOWS__) || defined(__OS2__)
2282 if (strchr(type,'b') != (char *) NULL)
2283 setmode(_fileno(image->blob->file),_O_BINARY);
2285 image->blob->type=StandardStream;
2286 image->blob->exempt=MagickTrue;
2289 #if defined(MAGICKCORE_HAVE_POPEN)
2290 if (*filename == '|')
2293 mode[MaxTextExtent];
2296 Pipe image to or from a system command.
2298 #if defined(SIGPIPE)
2300 (void) signal(SIGPIPE,SIG_IGN);
2304 image->blob->file=(FILE *) popen(filename+1,mode);
2305 if (image->blob->file == (FILE *) NULL)
2307 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2308 return(MagickFalse);
2310 image->blob->type=PipeStream;
2311 image->blob->exempt=MagickTrue;
2315 status=GetPathAttributes(filename,&image->blob->properties);
2316 #if defined(S_ISFIFO)
2317 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2319 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2320 if (image->blob->file == (FILE *) NULL)
2322 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2323 return(MagickFalse);
2325 image->blob->type=FileStream;
2326 image->blob->exempt=MagickTrue;
2332 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2333 if (image_info->adjoin == MagickFalse)
2336 Form filename for multi-part images.
2338 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2339 image->scene,filename);
2340 if ((LocaleCompare(filename,image->filename) == 0) &&
2341 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2342 (GetNextImageInList(image) != (Image *) NULL)))
2345 extension[MaxTextExtent],
2346 path[MaxTextExtent];
2348 GetPathComponent(image->filename,RootPath,path);
2349 GetPathComponent(image->filename,ExtensionPath,extension);
2350 if (*extension == '\0')
2351 (void) FormatMagickString(filename,MaxTextExtent,"%s-%lu",
2354 (void) FormatMagickString(filename,MaxTextExtent,
2355 "%s-%lu.%s",path,image->scene,extension);
2357 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2358 #if defined(macintosh)
2359 SetApplicationType(filename,image_info->magick,'8BIM');
2363 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2364 if (((strlen(filename) > 2) &&
2365 (LocaleCompare(filename+strlen(filename)-2,".Z") == 0)) ||
2366 ((strlen(filename) > 3) &&
2367 (LocaleCompare(filename+strlen(filename)-3,".gz") == 0)) ||
2368 ((strlen(filename) > 4) &&
2369 (LocaleCompare(filename+strlen(filename)-4,".wmz") == 0)) ||
2370 ((strlen(filename) > 5) &&
2371 (LocaleCompare(filename+strlen(filename)-5,".svgz") == 0)))
2373 image->blob->file=(FILE *) gzopen(filename,type);
2374 if (image->blob->file != (FILE *) NULL)
2375 image->blob->type=ZipStream;
2379 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2380 if ((strlen(filename) > 4) &&
2381 (LocaleCompare(filename+strlen(filename)-4,".bz2") == 0))
2383 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2384 if (image->blob->file != (FILE *) NULL)
2385 image->blob->type=BZipStream;
2389 if (image_info->file != (FILE *) NULL)
2391 image->blob->file=image_info->file;
2392 image->blob->type=FileStream;
2393 image->blob->exempt=MagickTrue;
2397 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2398 if (image->blob->file != (FILE *) NULL)
2400 image->blob->type=FileStream;
2401 #if defined(MAGICKCORE_HAVE_SETVBUF)
2402 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2413 (void) ResetMagickMemory(magick,0,sizeof(magick));
2414 count=fread(magick,1,sizeof(magick),image->blob->file);
2415 (void) rewind(image->blob->file);
2416 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2417 " read %ld magic header bytes",(long) count);
2418 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2419 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2420 ((int) magick[2] == 0x08))
2422 (void) fclose(image->blob->file);
2423 image->blob->file=(FILE *) gzopen(filename,type);
2424 if (image->blob->file != (FILE *) NULL)
2425 image->blob->type=ZipStream;
2428 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2429 if (strncmp((char *) magick,"BZh",3) == 0)
2431 (void) fclose(image->blob->file);
2432 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2433 if (image->blob->file != (FILE *) NULL)
2434 image->blob->type=BZipStream;
2440 if ((image->blob->type == FileStream) && (*type == 'r'))
2451 sans_exception=AcquireExceptionInfo();
2452 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2453 sans_exception=DestroyExceptionInfo(sans_exception);
2454 properties=(&image->blob->properties);
2455 if ((magick_info != (const MagickInfo *) NULL) &&
2456 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2457 (properties->st_size <= MagickMaxBufferExtent))
2465 length=(size_t) properties->st_size;
2466 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2467 if (blob != (void *) NULL)
2470 Format supports blobs-- use memory-mapped I/O.
2472 if (image_info->file != (FILE *) NULL)
2473 image->blob->exempt=MagickFalse;
2476 (void) fclose(image->blob->file);
2477 image->blob->file=(FILE *) NULL;
2479 AttachBlob(image->blob,blob,length);
2480 image->blob->mapped=MagickTrue;
2484 image->blob->status=MagickFalse;
2485 if (image->blob->type != UndefinedStream)
2486 image->blob->size=GetBlobSize(image);
2489 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2490 return(MagickFalse);
2496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2506 % PingBlob() returns all the attributes of an image or image sequence except
2507 % for the pixels. It is much faster and consumes far less memory than
2508 % BlobToImage(). On failure, a NULL image is returned and exception
2509 % describes the reason for the failure.
2511 % The format of the PingBlob method is:
2513 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2514 % const size_t length,ExceptionInfo *exception)
2516 % A description of each parameter follows:
2518 % o image_info: the image info.
2520 % o blob: the address of a character stream in one of the image formats
2521 % understood by ImageMagick.
2523 % o length: This size_t integer reflects the length in bytes of the blob.
2525 % o exception: return any errors or warnings in this structure.
2529 #if defined(__cplusplus) || defined(c_plusplus)
2533 static size_t PingStream(const Image *magick_unused(image),
2534 const void *magick_unused(pixels),const size_t columns)
2539 #if defined(__cplusplus) || defined(c_plusplus)
2543 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2544 const size_t length,ExceptionInfo *exception)
2552 assert(image_info != (ImageInfo *) NULL);
2553 assert(image_info->signature == MagickSignature);
2554 if (image_info->debug != MagickFalse)
2555 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2556 image_info->filename);
2557 assert(exception != (ExceptionInfo *) NULL);
2558 if ((blob == (const void *) NULL) || (length == 0))
2560 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2561 "UnrecognizedImageFormat","`%s'",image_info->magick);
2562 return((Image *) NULL);
2564 ping_info=CloneImageInfo(image_info);
2565 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2566 if (ping_info->blob == (const void *) NULL)
2568 (void) ThrowMagickException(exception,GetMagickModule(),
2569 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2570 return((Image *) NULL);
2572 (void) CopyMagickMemory(ping_info->blob,blob,length);
2573 ping_info->length=length;
2574 ping_info->ping=MagickTrue;
2575 image=ReadStream(ping_info,&PingStream,exception);
2576 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2577 ping_info=DestroyImageInfo(ping_info);
2582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2592 % ReadBlob() reads data from the blob or image file and returns it. It
2593 % returns the number of bytes read.
2595 % The format of the ReadBlob method is:
2597 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2599 % A description of each parameter follows:
2601 % o image: the image.
2603 % o length: Specifies an integer representing the number of bytes to read
2606 % o data: Specifies an area to place the information requested from the
2610 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2611 unsigned char *data)
2616 register unsigned char
2622 assert(image != (Image *) NULL);
2623 assert(image->signature == MagickSignature);
2624 assert(image->blob != (BlobInfo *) NULL);
2625 assert(image->blob->type != UndefinedStream);
2628 assert(data != (void *) NULL);
2631 switch (image->blob->type)
2633 case UndefinedStream:
2636 case StandardStream:
2643 count=(ssize_t) fread(q,1,length,image->blob->file);
2648 c=getc(image->blob->file);
2651 *q++=(unsigned char) c;
2656 c=getc(image->blob->file);
2659 *q++=(unsigned char) c;
2669 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2674 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2679 c=gzgetc(image->blob->file);
2682 *q++=(unsigned char) c;
2687 c=gzgetc(image->blob->file);
2690 *q++=(unsigned char) c;
2701 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2702 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2710 register const unsigned char
2713 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2715 image->blob->eof=MagickTrue;
2718 p=image->blob->data+image->blob->offset;
2719 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2720 image->blob->offset));
2721 image->blob->offset+=count;
2722 if (count != (ssize_t) length)
2723 image->blob->eof=MagickTrue;
2724 (void) CopyMagickMemory(q,p,(size_t) count);
2732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2736 + R e a d B l o b B y t e %
2740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2742 % ReadBlobByte() reads a single byte from the image file and returns it.
2744 % The format of the ReadBlobByte method is:
2746 % int ReadBlobByte(Image *image)
2748 % A description of each parameter follows.
2750 % o image: the image.
2753 MagickExport int ReadBlobByte(Image *image)
2755 register const unsigned char
2764 assert(image != (Image *) NULL);
2765 assert(image->signature == MagickSignature);
2766 p=ReadBlobStream(image,1,buffer,&count);
2773 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2777 + R e a d B l o b D o u b l e %
2781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2783 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2784 % specified by the endian member of the image structure.
2786 % The format of the ReadBlobDouble method is:
2788 % double ReadBlobDouble(Image *image)
2790 % A description of each parameter follows.
2792 % o image: the image.
2795 MagickExport double ReadBlobDouble(Image *image)
2806 quantum.double_value=0.0;
2807 quantum.unsigned_value=ReadBlobLongLong(image);
2808 return(quantum.double_value);
2812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2816 + R e a d B l o b F l o a t %
2820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2822 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2823 % specified by the endian member of the image structure.
2825 % The format of the ReadBlobFloat method is:
2827 % float ReadBlobFloat(Image *image)
2829 % A description of each parameter follows.
2831 % o image: the image.
2834 MagickExport float ReadBlobFloat(Image *image)
2845 quantum.float_value=0.0;
2846 quantum.unsigned_value=ReadBlobLong(image);
2847 return(quantum.float_value);
2851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2855 + R e a d B l o b L o n g %
2859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2861 % ReadBlobLong() reads a long value as a 32-bit quantity in the byte-order
2862 % specified by the endian member of the image structure.
2864 % The format of the ReadBlobLong method is:
2866 % unsigned int ReadBlobLong(Image *image)
2868 % A description of each parameter follows.
2870 % o image: the image.
2873 MagickExport unsigned int ReadBlobLong(Image *image)
2875 register const unsigned char
2887 assert(image != (Image *) NULL);
2888 assert(image->signature == MagickSignature);
2890 p=ReadBlobStream(image,4,buffer,&count);
2893 if (image->endian == LSBEndian)
2895 value=(unsigned int) (*p++);
2896 value|=((unsigned int) (*p++)) << 8;
2897 value|=((unsigned int) (*p++)) << 16;
2898 value|=((unsigned int) (*p++)) << 24;
2901 value=((unsigned int) (*p++)) << 24;
2902 value|=((unsigned int) (*p++)) << 16;
2903 value|=((unsigned int) (*p++)) << 8;
2904 value|=((unsigned int) (*p++));
2909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2913 + R e a d B l o b L o n g L o n g %
2917 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2919 % ReadBlobLongLong() reads a long value as a 64-bit quantity in the byte-order
2920 % specified by the endian member of the image structure.
2922 % The format of the ReadBlobLong method is:
2924 % MagickSizeType ReadBlobLong(Image *image)
2926 % A description of each parameter follows.
2928 % o image: the image.
2931 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
2933 register const unsigned char
2945 assert(image != (Image *) NULL);
2946 assert(image->signature == MagickSignature);
2948 p=ReadBlobStream(image,8,buffer,&count);
2950 return(MagickULLConstant(0));
2951 if (image->endian == LSBEndian)
2953 value=(MagickSizeType) (*p++);
2954 value|=((MagickSizeType) (*p++)) << 8;
2955 value|=((MagickSizeType) (*p++)) << 16;
2956 value|=((MagickSizeType) (*p++)) << 24;
2957 value|=((MagickSizeType) (*p++)) << 32;
2958 value|=((MagickSizeType) (*p++)) << 40;
2959 value|=((MagickSizeType) (*p++)) << 48;
2960 value|=((MagickSizeType) (*p++)) << 56;
2961 return(value & MagickULLConstant(0xffffffffffffffff));
2963 value=((MagickSizeType) (*p++)) << 56;
2964 value|=((MagickSizeType) (*p++)) << 48;
2965 value|=((MagickSizeType) (*p++)) << 40;
2966 value|=((MagickSizeType) (*p++)) << 32;
2967 value|=((MagickSizeType) (*p++)) << 24;
2968 value|=((MagickSizeType) (*p++)) << 16;
2969 value|=((MagickSizeType) (*p++)) << 8;
2970 value|=((MagickSizeType) (*p++));
2971 return(value & MagickULLConstant(0xffffffffffffffff));
2975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2979 + R e a d B l o b S h o r t %
2983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2985 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
2986 % specified by the endian member of the image structure.
2988 % The format of the ReadBlobShort method is:
2990 % unsigned short ReadBlobShort(Image *image)
2992 % A description of each parameter follows.
2994 % o image: the image.
2997 MagickExport unsigned short ReadBlobShort(Image *image)
2999 register const unsigned char
3002 register unsigned int
3011 assert(image != (Image *) NULL);
3012 assert(image->signature == MagickSignature);
3014 p=ReadBlobStream(image,2,buffer,&count);
3016 return((unsigned short) 0U);
3017 if (image->endian == LSBEndian)
3019 value=(unsigned int) (*p++);
3020 value|=((unsigned int) (*p++)) << 8;
3021 return((unsigned short) (value & 0xffff));
3023 value=(unsigned int) ((*p++) << 8);
3024 value|=(unsigned int) (*p++);
3025 return((unsigned short) (value & 0xffff));
3029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3033 + R e a d B l o b L S B L o n g %
3037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3039 % ReadBlobLSBLong() reads a long value as a 32-bit quantity in
3040 % least-significant byte first order.
3042 % The format of the ReadBlobLSBLong method is:
3044 % unsigned int ReadBlobLSBLong(Image *image)
3046 % A description of each parameter follows.
3048 % o image: the image.
3051 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3053 register const unsigned char
3056 register unsigned int
3065 assert(image != (Image *) NULL);
3066 assert(image->signature == MagickSignature);
3068 p=ReadBlobStream(image,4,buffer,&count);
3071 value=(unsigned int) (*p++);
3072 value|=((unsigned int) (*p++)) << 8;
3073 value|=((unsigned int) (*p++)) << 16;
3074 value|=((unsigned int) (*p++)) << 24;
3079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3083 + R e a d B l o b L S B S h o r t %
3087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3089 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3090 % least-significant byte first order.
3092 % The format of the ReadBlobLSBShort method is:
3094 % unsigned short ReadBlobLSBShort(Image *image)
3096 % A description of each parameter follows.
3098 % o image: the image.
3101 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3103 register const unsigned char
3106 register unsigned int
3115 assert(image != (Image *) NULL);
3116 assert(image->signature == MagickSignature);
3118 p=ReadBlobStream(image,2,buffer,&count);
3120 return((unsigned short) 0U);
3121 value=(unsigned int) (*p++);
3122 value|=((unsigned int) ((*p++)) << 8);
3123 return((unsigned short) (value & 0xffff));
3127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3131 + R e a d B l o b M S B L o n g %
3135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3137 % ReadBlobMSBLong() reads a long value as a 32-bit quantity in
3138 % most-significant byte first order.
3140 % The format of the ReadBlobMSBLong method is:
3142 % unsigned int ReadBlobMSBLong(Image *image)
3144 % A description of each parameter follows.
3146 % o image: the image.
3149 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3151 register const unsigned char
3154 register unsigned int
3163 assert(image != (Image *) NULL);
3164 assert(image->signature == MagickSignature);
3166 p=ReadBlobStream(image,4,buffer,&count);
3169 value=((unsigned int) (*p++) << 24);
3170 value|=((unsigned int) (*p++) << 16);
3171 value|=((unsigned int) (*p++) << 8);
3172 value|=(unsigned int) (*p++);
3177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3181 + R e a d B l o b M S B L o n g L o n g %
3185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3187 % ReadBlobMSBLongLong() reads a long value as a 64-bit quantity in
3188 % most-significant byte first order.
3190 % The format of the ReadBlobMSBLongLong method is:
3192 % unsigned int ReadBlobMSBLongLong(Image *image)
3194 % A description of each parameter follows.
3196 % o image: the image.
3199 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3201 register const unsigned char
3204 register MagickSizeType
3213 assert(image != (Image *) NULL);
3214 assert(image->signature == MagickSignature);
3216 p=ReadBlobStream(image,8,buffer,&count);
3218 return(MagickULLConstant(0));
3219 value=((MagickSizeType) (*p++)) << 56;
3220 value|=((MagickSizeType) (*p++)) << 48;
3221 value|=((MagickSizeType) (*p++)) << 40;
3222 value|=((MagickSizeType) (*p++)) << 32;
3223 value|=((MagickSizeType) (*p++)) << 24;
3224 value|=((MagickSizeType) (*p++)) << 16;
3225 value|=((MagickSizeType) (*p++)) << 8;
3226 value|=((MagickSizeType) (*p++));
3227 return(value & MagickULLConstant(0xffffffffffffffff));
3231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3235 + R e a d B l o b M S B S h o r t %
3239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3241 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3242 % most-significant byte first order.
3244 % The format of the ReadBlobMSBShort method is:
3246 % unsigned short ReadBlobMSBShort(Image *image)
3248 % A description of each parameter follows.
3250 % o image: the image.
3253 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3255 register const unsigned char
3258 register unsigned int
3267 assert(image != (Image *) NULL);
3268 assert(image->signature == MagickSignature);
3270 p=ReadBlobStream(image,2,buffer,&count);
3272 return((unsigned short) 0U);
3273 value=(unsigned int) ((*p++) << 8);
3274 value|=(unsigned int) (*p++);
3275 return((unsigned short) (value & 0xffff));
3279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3283 + R e a d B l o b S t r i n g %
3287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3289 % ReadBlobString() reads characters from a blob or file until a newline
3290 % character is read or an end-of-file condition is encountered.
3292 % The format of the ReadBlobString method is:
3294 % char *ReadBlobString(Image *image,char *string)
3296 % A description of each parameter follows:
3298 % o image: the image.
3300 % o string: the address of a character buffer.
3303 MagickExport char *ReadBlobString(Image *image,char *string)
3305 register const unsigned char
3317 assert(image != (Image *) NULL);
3318 assert(image->signature == MagickSignature);
3319 for (i=0; i < (MaxTextExtent-1L); i++)
3321 p=ReadBlobStream(image,1,buffer,&count);
3325 return((char *) NULL);
3328 string[i]=(char) (*p);
3329 if ((string[i] == '\n') || (string[i] == '\r'))
3337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3341 + R e f e r e n c e B l o b %
3345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3347 % ReferenceBlob() increments the reference count associated with the pixel
3348 % blob returning a pointer to the blob.
3350 % The format of the ReferenceBlob method is:
3352 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3354 % A description of each parameter follows:
3356 % o blob_info: the blob_info.
3359 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3361 assert(blob != (BlobInfo *) NULL);
3362 assert(blob->signature == MagickSignature);
3363 if (blob->debug != MagickFalse)
3364 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3365 LockSemaphoreInfo(blob->semaphore);
3366 blob->reference_count++;
3367 UnlockSemaphoreInfo(blob->semaphore);
3372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3382 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3383 % and returns the resulting offset.
3385 % The format of the SeekBlob method is:
3387 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3390 % A description of each parameter follows:
3392 % o image: the image.
3394 % o offset: Specifies an integer representing the offset in bytes.
3396 % o whence: Specifies an integer representing how the offset is
3397 % treated relative to the beginning of the blob as follows:
3399 % SEEK_SET Set position equal to offset bytes.
3400 % SEEK_CUR Set position to current location plus offset.
3401 % SEEK_END Set position to EOF plus offset.
3404 MagickExport MagickOffsetType SeekBlob(Image *image,
3405 const MagickOffsetType offset,const int whence)
3407 assert(image != (Image *) NULL);
3408 assert(image->signature == MagickSignature);
3409 if (image->debug != MagickFalse)
3410 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3411 assert(image->blob != (BlobInfo *) NULL);
3412 assert(image->blob->type != UndefinedStream);
3413 switch (image->blob->type)
3415 case UndefinedStream:
3419 if (fseek(image->blob->file,offset,whence) < 0)
3421 image->blob->offset=TellBlob(image);
3424 case StandardStream:
3428 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3429 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3432 image->blob->offset=TellBlob(image);
3448 image->blob->offset=offset;
3453 if ((image->blob->offset+offset) < 0)
3455 image->blob->offset+=offset;
3460 if (((MagickOffsetType) image->blob->length+offset) < 0)
3462 image->blob->offset=image->blob->length+offset;
3466 if (image->blob->offset <= (MagickOffsetType)
3467 ((off_t) image->blob->length))
3468 image->blob->eof=MagickFalse;
3470 if (image->blob->mapped != MagickFalse)
3474 image->blob->extent=(size_t) (image->blob->offset+
3475 image->blob->quantum);
3476 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3477 image->blob->data,image->blob->extent+1,
3478 sizeof(*image->blob->data));
3479 (void) SyncBlob(image);
3480 if (image->blob->data == (unsigned char *) NULL)
3482 (void) DetachBlob(image->blob);
3489 return(image->blob->offset);
3493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3497 + S e t B l o b E x e m p t %
3501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3503 % SetBlobExempt() sets the blob exempt status.
3505 % The format of the SetBlobExempt method is:
3507 % MagickBooleanType SetBlobExempt(const Image *image,
3508 % const MagickBooleanType exempt)
3510 % A description of each parameter follows:
3512 % o image: the image.
3514 % o exempt: Set to true if this blob is exempt from being closed.
3517 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3519 assert(image != (const Image *) NULL);
3520 assert(image->signature == MagickSignature);
3521 if (image->debug != MagickFalse)
3522 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3523 image->blob->exempt=exempt;
3527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3531 + S e t B l o b E x t e n t %
3535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3537 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3538 % method is successful, subsequent writes to bytes in the specified range are
3539 % guaranteed not to fail.
3541 % The format of the SetBlobExtent method is:
3543 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3545 % A description of each parameter follows:
3547 % o image: the image.
3549 % o extent: the blob maximum extent.
3552 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3553 const MagickSizeType extent)
3555 assert(image != (Image *) NULL);
3556 assert(image->signature == MagickSignature);
3557 if (image->debug != MagickFalse)
3558 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3559 assert(image->blob != (BlobInfo *) NULL);
3560 assert(image->blob->type != UndefinedStream);
3561 switch (image->blob->type)
3563 case UndefinedStream:
3567 if (extent != (MagickSizeType) ((off_t) extent))
3568 return(MagickFalse);
3569 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3570 return(MagickFalse);
3579 offset=TellBlob(image);
3580 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3581 (off_t) (extent-offset));
3583 return(MagickFalse);
3588 case StandardStream:
3591 return(MagickFalse);
3593 return(MagickFalse);
3595 return(MagickFalse);
3598 if (image->blob->mapped != MagickFalse)
3600 if (image->blob->file == (FILE *) NULL)
3601 return(MagickFalse);
3602 (void) UnmapBlob(image->blob->data,image->blob->length);
3603 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3604 return(MagickFalse);
3613 offset=TellBlob(image);
3614 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3615 (off_t) (extent-offset));
3617 return(MagickFalse);
3619 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3620 WriteMode,0,(size_t) extent);
3621 image->blob->extent=(size_t) extent;
3622 image->blob->length=(size_t) extent;
3623 (void) SyncBlob(image);
3627 if (extent != (MagickSizeType) ((size_t) extent))
3628 return(MagickFalse);
3629 image->blob->extent=(size_t) extent;
3630 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3631 image->blob->extent+1,sizeof(*image->blob->data));
3632 (void) SyncBlob(image);
3633 if (image->blob->data == (unsigned char *) NULL)
3635 (void) DetachBlob(image->blob);
3636 return(MagickFalse);
3645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3655 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3656 % attributes if it is an blob.
3658 % The format of the SyncBlob method is:
3660 % int SyncBlob(Image *image)
3662 % A description of each parameter follows:
3664 % o image: the image.
3667 static int SyncBlob(Image *image)
3672 assert(image != (Image *) NULL);
3673 assert(image->signature == MagickSignature);
3674 if (image->debug != MagickFalse)
3675 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3676 assert(image->blob != (BlobInfo *) NULL);
3677 assert(image->blob->type != UndefinedStream);
3679 switch (image->blob->type)
3681 case UndefinedStream:
3684 case StandardStream:
3687 status=fflush(image->blob->file);
3692 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3693 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3699 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3700 status=BZ2_bzflush((BZFILE *) image->blob->file);
3708 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3709 if (image->blob->mapped != MagickFalse)
3710 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3729 % TellBlob() obtains the current value of the blob or file position.
3731 % The format of the TellBlob method is:
3733 % MagickOffsetType TellBlob(const Image *image)
3735 % A description of each parameter follows:
3737 % o image: the image.
3740 MagickExport MagickOffsetType TellBlob(const Image *image)
3745 assert(image != (Image *) NULL);
3746 assert(image->signature == MagickSignature);
3747 if (image->debug != MagickFalse)
3748 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3749 assert(image->blob != (BlobInfo *) NULL);
3750 assert(image->blob->type != UndefinedStream);
3752 switch (image->blob->type)
3754 case UndefinedStream:
3758 offset=ftell(image->blob->file);
3761 case StandardStream:
3766 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3767 offset=(MagickOffsetType) gztell(image->blob->file);
3777 offset=image->blob->offset;
3785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3789 + U n m a p B l o b %
3793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3795 % UnmapBlob() deallocates the binary large object previously allocated with
3796 % the MapBlob method.
3798 % The format of the UnmapBlob method is:
3800 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3802 % A description of each parameter follows:
3804 % o map: the address of the binary large object.
3806 % o length: the length of the binary large object.
3809 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3811 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3815 status=munmap(map,length);
3816 return(status == -1 ? MagickFalse : MagickTrue);
3820 return(MagickFalse);
3825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3829 + W r i t e B l o b %
3833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3835 % WriteBlob() writes data to a blob or image file. It returns the number of
3838 % The format of the WriteBlob method is:
3840 % ssize_t WriteBlob(Image *image,const size_t length,
3841 % const unsigned char *data)
3843 % A description of each parameter follows:
3845 % o image: the image.
3847 % o length: Specifies an integer representing the number of bytes to
3848 % write to the file.
3850 % o data: The address of the data to write to the blob or file.
3853 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3854 const unsigned char *data)
3859 register const unsigned char
3865 assert(image != (Image *) NULL);
3866 assert(image->signature == MagickSignature);
3867 assert(data != (const unsigned char *) NULL);
3868 assert(image->blob != (BlobInfo *) NULL);
3869 assert(image->blob->type != UndefinedStream);
3874 switch (image->blob->type)
3876 case UndefinedStream:
3879 case StandardStream:
3886 count=(ssize_t) fwrite((const char *) data,1,length,
3892 c=putc((int) *p++,image->blob->file);
3899 c=putc((int) *p++,image->blob->file);
3911 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3916 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
3917 (unsigned int) length);
3922 c=gzputc(image->blob->file,(int) *p++);
3929 c=gzputc(image->blob->file,(int) *p++);
3942 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3943 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
3950 count=(ssize_t) image->blob->stream(image,data,length);
3955 register unsigned char
3958 if ((image->blob->offset+(MagickOffsetType) length) >=
3959 (MagickOffsetType) image->blob->extent)
3961 if (image->blob->mapped != MagickFalse)
3963 image->blob->quantum<<=1;
3964 image->blob->extent+=length+image->blob->quantum;
3965 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3966 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
3967 (void) SyncBlob(image);
3968 if (image->blob->data == (unsigned char *) NULL)
3970 (void) DetachBlob(image->blob);
3974 q=image->blob->data+image->blob->offset;
3975 (void) CopyMagickMemory(q,p,length);
3976 image->blob->offset+=length;
3977 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3978 image->blob->length=(size_t) image->blob->offset;
3979 count=(ssize_t) length;
3986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3990 + W r i t e B l o b B y t e %
3994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3996 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
3997 % written (either 0 or 1);
3999 % The format of the WriteBlobByte method is:
4001 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4003 % A description of each parameter follows.
4005 % o image: the image.
4007 % o value: Specifies the value to write.
4010 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4012 assert(image != (Image *) NULL);
4013 assert(image->signature == MagickSignature);
4014 return(WriteBlobStream(image,1,&value));
4018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4022 + W r i t e B l o b F l o a t %
4026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4028 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4029 % specified by the endian member of the image structure.
4031 % The format of the WriteBlobFloat method is:
4033 % ssize_t WriteBlobFloat(Image *image,const float value)
4035 % A description of each parameter follows.
4037 % o image: the image.
4039 % o value: Specifies the value to write.
4042 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4053 quantum.unsigned_value=0U;
4054 quantum.float_value=value;
4055 return(WriteBlobLong(image,quantum.unsigned_value));
4059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4063 + W r i t e B l o b L o n g %
4067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4069 % WriteBlobLong() writes a long value as a 32-bit quantity in the byte-order
4070 % specified by the endian member of the image structure.
4072 % The format of the WriteBlobLong method is:
4074 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4076 % A description of each parameter follows.
4078 % o image: the image.
4080 % o value: Specifies the value to write.
4083 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4088 assert(image != (Image *) NULL);
4089 assert(image->signature == MagickSignature);
4090 if (image->endian == LSBEndian)
4092 buffer[0]=(unsigned char) value;
4093 buffer[1]=(unsigned char) (value >> 8);
4094 buffer[2]=(unsigned char) (value >> 16);
4095 buffer[3]=(unsigned char) (value >> 24);
4096 return(WriteBlobStream(image,4,buffer));
4098 buffer[0]=(unsigned char) (value >> 24);
4099 buffer[1]=(unsigned char) (value >> 16);
4100 buffer[2]=(unsigned char) (value >> 8);
4101 buffer[3]=(unsigned char) value;
4102 return(WriteBlobStream(image,4,buffer));
4106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4110 + W r i t e B l o b S h o r t %
4114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4116 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4117 % byte-order specified by the endian member of the image structure.
4119 % The format of the WriteBlobShort method is:
4121 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4123 % A description of each parameter follows.
4125 % o image: the image.
4127 % o value: Specifies the value to write.
4130 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4135 assert(image != (Image *) NULL);
4136 assert(image->signature == MagickSignature);
4137 if (image->endian == LSBEndian)
4139 buffer[0]=(unsigned char) value;
4140 buffer[1]=(unsigned char) (value >> 8);
4141 return(WriteBlobStream(image,2,buffer));
4143 buffer[0]=(unsigned char) (value >> 8);
4144 buffer[1]=(unsigned char) value;
4145 return(WriteBlobStream(image,2,buffer));
4149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4153 + W r i t e B l o b L S B L o n g %
4157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4159 % WriteBlobLSBLong() writes a long value as a 32-bit quantity in
4160 % least-significant byte first order.
4162 % The format of the WriteBlobLSBLong method is:
4164 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4166 % A description of each parameter follows.
4168 % o image: the image.
4170 % o value: Specifies the value to write.
4173 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4178 assert(image != (Image *) NULL);
4179 assert(image->signature == MagickSignature);
4180 buffer[0]=(unsigned char) value;
4181 buffer[1]=(unsigned char) (value >> 8);
4182 buffer[2]=(unsigned char) (value >> 16);
4183 buffer[3]=(unsigned char) (value >> 24);
4184 return(WriteBlobStream(image,4,buffer));
4188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4192 + W r i t e B l o b L S B S h o r t %
4196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4198 % WriteBlobLSBShort() writes a long value as a 16-bit quantity in
4199 % least-significant byte first order.
4201 % The format of the WriteBlobLSBShort method is:
4203 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4205 % A description of each parameter follows.
4207 % o image: the image.
4209 % o value: Specifies the value to write.
4212 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4217 assert(image != (Image *) NULL);
4218 assert(image->signature == MagickSignature);
4219 buffer[0]=(unsigned char) value;
4220 buffer[1]=(unsigned char) (value >> 8);
4221 return(WriteBlobStream(image,2,buffer));
4225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4229 + W r i t e B l o b M S B L o n g %
4233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4235 % WriteBlobMSBLong() writes a long value as a 32-bit quantity in
4236 % most-significant byte first order.
4238 % The format of the WriteBlobMSBLong method is:
4240 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4242 % A description of each parameter follows.
4244 % o value: Specifies the value to write.
4246 % o image: the image.
4249 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4254 assert(image != (Image *) NULL);
4255 assert(image->signature == MagickSignature);
4256 buffer[0]=(unsigned char) (value >> 24);
4257 buffer[1]=(unsigned char) (value >> 16);
4258 buffer[2]=(unsigned char) (value >> 8);
4259 buffer[3]=(unsigned char) value;
4260 return(WriteBlobStream(image,4,buffer));
4264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4268 + W r i t e B l o b M S B S h o r t %
4272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4274 % WriteBlobMSBShort() writes a long value as a 16-bit quantity in
4275 % most-significant byte first order.
4277 % The format of the WriteBlobMSBShort method is:
4279 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4281 % A description of each parameter follows.
4283 % o value: Specifies the value to write.
4285 % o file: Specifies the file to write the data to.
4288 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4293 assert(image != (Image *) NULL);
4294 assert(image->signature == MagickSignature);
4295 buffer[0]=(unsigned char) (value >> 8);
4296 buffer[1]=(unsigned char) value;
4297 return(WriteBlobStream(image,2,buffer));
4301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4305 + W r i t e B l o b S t r i n g %
4309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4311 % WriteBlobString() write a string to a blob. It returns the number of
4312 % characters written.
4314 % The format of the WriteBlobString method is:
4316 % ssize_t WriteBlobString(Image *image,const char *string)
4318 % A description of each parameter follows.
4320 % o image: the image.
4322 % o string: Specifies the string to write.
4325 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4327 assert(image != (Image *) NULL);
4328 assert(image->signature == MagickSignature);
4329 assert(string != (const char *) NULL);
4330 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));