2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2009 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/utility.h"
62 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(__WINDOWS__)
63 # include <sys/mman.h>
65 #if defined(MAGICKCORE_ZLIB_DELEGATE)
68 #if defined(MAGICKCORE_BZLIB_DELEGATE)
75 #define MagickMaxBlobExtent 65541
76 #if defined(MAGICKCORE_HAVE_FSEEKO)
80 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
81 # define MAP_ANONYMOUS MAP_ANON
83 #if !defined(MAP_FAILED)
84 #define MAP_FAILED ((void *) -1)
91 #define _O_BINARY O_BINARY
149 Forward declarations.
155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159 + A t t a c h B l o b %
163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165 % AttachBlob() attaches a blob to the BlobInfo structure.
167 % The format of the AttachBlob method is:
169 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
171 % A description of each parameter follows:
173 % o blob_info: Specifies a pointer to a BlobInfo structure.
175 % o blob: the address of a character stream in one of the image formats
176 % understood by ImageMagick.
178 % o length: This size_t integer reflects the length in bytes of the blob.
181 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
184 assert(blob_info != (BlobInfo *) NULL);
185 if (blob_info->debug != MagickFalse)
186 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
187 blob_info->length=length;
188 blob_info->extent=length;
189 blob_info->quantum=(size_t) MagickMaxBlobExtent;
191 blob_info->type=BlobStream;
192 blob_info->file=(FILE *) NULL;
193 blob_info->data=(unsigned char *) blob;
194 blob_info->mapped=MagickFalse;
198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202 + B l o b T o F i l e %
206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
209 % occurs otherwise MagickTrue.
211 % The format of the BlobToFile method is:
213 % MagickBooleanType BlobToFile(char *filename,const void *blob,
214 % const size_t length,ExceptionInfo *exception)
216 % A description of each parameter follows:
218 % o filename: Write the blob to this file.
220 % o blob: the address of a blob.
222 % o length: This length in bytes of the blob.
224 % o exception: return any errors or warnings in this structure.
228 static inline size_t MagickMin(const size_t x,const size_t y)
235 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
236 const size_t length,ExceptionInfo *exception)
247 assert(filename != (const char *) NULL);
248 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
249 assert(blob != (const void *) NULL);
250 if (*filename == '\0')
251 file=AcquireUniqueFileResource(filename);
253 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
256 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
259 for (i=0; i < length; i+=count)
261 count=(ssize_t) write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
273 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 % B l o b T o I m a g e %
288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290 % BlobToImage() implements direct to memory image formats. It returns the
293 % The format of the BlobToImage method is:
295 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
296 % const size_t length,ExceptionInfo *exception)
298 % A description of each parameter follows:
300 % o image_info: the image info.
302 % o blob: the address of a character stream in one of the image formats
303 % understood by ImageMagick.
305 % o length: This size_t integer reflects the length in bytes of the blob.
307 % o exception: return any errors or warnings in this structure.
310 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
311 const size_t length,ExceptionInfo *exception)
326 assert(image_info != (ImageInfo *) NULL);
327 assert(image_info->signature == MagickSignature);
328 if (image_info->debug != MagickFalse)
329 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
330 image_info->filename);
331 assert(exception != (ExceptionInfo *) NULL);
332 if ((blob == (const void *) NULL) || (length == 0))
334 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
335 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
336 return((Image *) NULL);
338 blob_info=CloneImageInfo(image_info);
339 blob_info->blob=(void *) blob;
340 blob_info->length=length;
341 if (*blob_info->magick == '\0')
342 (void) SetImageInfo(blob_info,MagickFalse,exception);
343 magick_info=GetMagickInfo(blob_info->magick,exception);
344 if (magick_info == (const MagickInfo *) NULL)
346 blob_info=DestroyImageInfo(blob_info);
347 (void) ThrowMagickException(exception,GetMagickModule(),
348 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
349 image_info->filename);
350 return((Image *) NULL);
352 if (GetMagickBlobSupport(magick_info) != MagickFalse)
355 Native blob support for this image format.
357 (void) CopyMagickString(blob_info->filename,image_info->filename,
359 (void) CopyMagickString(blob_info->magick,image_info->magick,
361 image=ReadImage(blob_info,exception);
362 if (image != (Image *) NULL)
363 (void) DetachBlob(image->blob);
364 blob_info=DestroyImageInfo(blob_info);
368 Write blob to a temporary file on disk.
370 blob_info->blob=(void *) NULL;
372 *blob_info->filename='\0';
373 status=BlobToFile(blob_info->filename,blob,length,exception);
374 if (status == MagickFalse)
376 (void) RelinquishUniqueFileResource(blob_info->filename);
377 blob_info=DestroyImageInfo(blob_info);
378 return((Image *) NULL);
380 clone_info=CloneImageInfo(blob_info);
381 (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
382 blob_info->magick,blob_info->filename);
383 image=ReadImage(clone_info,exception);
384 clone_info=DestroyImageInfo(clone_info);
385 (void) RelinquishUniqueFileResource(blob_info->filename);
386 blob_info=DestroyImageInfo(blob_info);
391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 + C l o n e B l o b I n f o %
399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
402 % blob info is NULL, a new one.
404 % The format of the CloneBlobInfo method is:
406 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
408 % A description of each parameter follows:
410 % o blob_info: the blob info.
413 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
418 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
419 if (clone_info == (BlobInfo *) NULL)
420 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
421 GetBlobInfo(clone_info);
422 if (blob_info == (BlobInfo *) NULL)
424 clone_info->length=blob_info->length;
425 clone_info->extent=blob_info->extent;
426 clone_info->synchronize=blob_info->synchronize;
427 clone_info->quantum=blob_info->quantum;
428 clone_info->mapped=blob_info->mapped;
429 clone_info->eof=blob_info->eof;
430 clone_info->offset=blob_info->offset;
431 clone_info->size=blob_info->size;
432 clone_info->exempt=blob_info->exempt;
433 clone_info->status=blob_info->status;
434 clone_info->temporary=blob_info->temporary;
435 clone_info->type=blob_info->type;
436 clone_info->file=blob_info->file;
437 clone_info->properties=blob_info->properties;
438 clone_info->stream=blob_info->stream;
439 clone_info->data=blob_info->data;
440 clone_info->debug=IsEventLogging();
441 clone_info->reference_count=1;
446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450 + C l o s e B l o b %
454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456 % CloseBlob() closes a stream associated with the image.
458 % The format of the CloseBlob method is:
460 % MagickBooleanType CloseBlob(Image *image)
462 % A description of each parameter follows:
464 % o image: the image.
467 MagickExport MagickBooleanType CloseBlob(Image *image)
475 assert(image != (Image *) NULL);
476 assert(image->signature == MagickSignature);
477 if (image->debug != MagickFalse)
478 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
479 assert(image->blob != (BlobInfo *) NULL);
480 if (image->blob->type == UndefinedStream)
482 if (image->blob->synchronize != MagickFalse)
484 image->blob->size=GetBlobSize(image);
485 image->blob->eof=MagickFalse;
486 if (image->blob->exempt != MagickFalse)
488 image->blob->type=UndefinedStream;
492 switch (image->blob->type)
494 case UndefinedStream:
500 status=ferror(image->blob->file);
505 #if defined(MAGICKCORE_ZLIB_DELEGATE)
506 (void) gzerror(image->blob->file,&status);
512 #if defined(MAGICKCORE_BZLIB_DELEGATE)
513 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
521 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
522 switch (image->blob->type)
524 case UndefinedStream:
529 if (image->blob->synchronize != MagickFalse)
530 status=fsync(fileno(image->blob->file));
531 status=fclose(image->blob->file);
536 #if defined(MAGICKCORE_HAVE_PCLOSE)
537 status=pclose(image->blob->file);
543 #if defined(MAGICKCORE_ZLIB_DELEGATE)
544 status=gzclose(image->blob->file);
550 #if defined(MAGICKCORE_BZLIB_DELEGATE)
551 BZ2_bzclose((BZFILE *) image->blob->file);
559 (void) DetachBlob(image->blob);
560 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
561 return(image->blob->status);
565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
569 + D e s t r o y B l o b %
573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
575 % DestroyBlob() deallocates memory associated with a blob.
577 % The format of the DestroyBlob method is:
579 % void DestroyBlob(Image *image)
581 % A description of each parameter follows:
583 % o image: the image.
586 MagickExport void DestroyBlob(Image *image)
591 assert(image != (Image *) NULL);
592 assert(image->signature == MagickSignature);
593 if (image->debug != MagickFalse)
594 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
595 assert(image->blob != (BlobInfo *) NULL);
596 assert(image->blob->signature == MagickSignature);
598 (void) LockSemaphoreInfo(image->blob->semaphore);
599 image->blob->reference_count--;
600 assert(image->blob->reference_count >= 0);
601 if (image->blob->reference_count == 0)
603 (void) UnlockSemaphoreInfo(image->blob->semaphore);
604 if (destroy == MagickFalse)
606 (void) CloseBlob(image);
607 if (image->blob->mapped != MagickFalse)
608 (void) UnmapBlob(image->blob->data,image->blob->length);
609 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
610 DestroySemaphoreInfo(&image->blob->semaphore);
611 image->blob->signature=(~MagickSignature);
612 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
616 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620 + D e t a c h B l o b %
624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
626 % DetachBlob() detaches a blob from the BlobInfo structure.
628 % The format of the DetachBlob method is:
630 % unsigned char *DetachBlob(BlobInfo *blob_info)
632 % A description of each parameter follows:
634 % o blob_info: Specifies a pointer to a BlobInfo structure.
637 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
642 assert(blob_info != (BlobInfo *) NULL);
643 if (blob_info->debug != MagickFalse)
644 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
645 if (blob_info->mapped != MagickFalse)
646 (void) UnmapBlob(blob_info->data,blob_info->length);
647 blob_info->mapped=MagickFalse;
650 blob_info->eof=MagickFalse;
651 blob_info->exempt=MagickFalse;
652 blob_info->type=UndefinedStream;
653 blob_info->file=(FILE *) NULL;
654 data=blob_info->data;
655 blob_info->data=(unsigned char *) NULL;
656 blob_info->stream=(StreamHandler) NULL;
661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665 + D u p l i c a t e s B l o b %
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 % DuplicateBlob() duplicates a blob descriptor.
673 % The format of the DuplicateBlob method is:
675 % void DuplicateBlob(Image *image,const Image *duplicate)
677 % A description of each parameter follows:
679 % o image: the image.
681 % o duplicate: the duplicate image.
684 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
686 assert(image != (Image *) NULL);
687 assert(image->signature == MagickSignature);
688 if (image->debug != MagickFalse)
689 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
690 assert(duplicate != (Image *) NULL);
691 assert(duplicate->signature == MagickSignature);
693 image->blob=ReferenceBlob(duplicate->blob);
697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 % EOFBlob() returns a non-zero value when EOF has been detected reading from
710 % The format of the EOFBlob method is:
712 % int EOFBlob(const Image *image)
714 % A description of each parameter follows:
716 % o image: the image.
719 MagickExport int EOFBlob(const Image *image)
721 assert(image != (Image *) NULL);
722 assert(image->signature == MagickSignature);
723 if (image->debug != MagickFalse)
724 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
725 assert(image->blob != (BlobInfo *) NULL);
726 assert(image->blob->type != UndefinedStream);
727 switch (image->blob->type)
729 case UndefinedStream:
735 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
740 image->blob->eof=MagickFalse;
745 #if defined(MAGICKCORE_BZLIB_DELEGATE)
750 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
751 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
757 image->blob->eof=MagickFalse;
763 return((int) image->blob->eof);
767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
771 + F i l e T o B l o b %
775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777 % FileToBlob() returns the contents of a file as a blob. It returns the
778 % file as a blob and its length. If an error occurs, NULL is returned.
780 % The format of the FileToBlob method is:
782 % unsigned char *FileToBlob(const char *filename,const size_t extent,
783 % size_t *length,ExceptionInfo *exception)
785 % A description of each parameter follows:
787 % o blob: FileToBlob() returns the contents of a file as a blob. If
788 % an error occurs NULL is returned.
790 % o filename: the filename.
792 % o extent: The maximum length of the blob.
794 % o length: On return, this reflects the actual length of the blob.
796 % o exception: return any errors or warnings in this structure.
799 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
800 size_t *length,ExceptionInfo *exception)
820 assert(filename != (const char *) NULL);
821 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
822 assert(exception != (ExceptionInfo *) NULL);
825 if (LocaleCompare(filename,"-") != 0)
826 file=open(filename,O_RDONLY | O_BINARY);
829 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
830 return((unsigned char *) NULL);
832 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
834 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
843 Stream is not seekable.
845 quantum=(size_t) MagickMaxBufferExtent;
846 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
847 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
848 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
849 for (i=0; blob != (unsigned char *) NULL; i+=count)
851 count=(ssize_t) read(file,blob+i,quantum);
858 if (~(1UL*i) < (quantum+1))
860 blob=(unsigned char *) RelinquishMagickMemory(blob);
863 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
865 if ((size_t) (i+count) >= extent)
869 if (blob == (unsigned char *) NULL)
871 (void) ThrowMagickException(exception,GetMagickModule(),
872 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
873 return((unsigned char *) NULL);
875 *length=MagickMin(i+count,extent);
879 *length=MagickMin((size_t) offset,extent);
880 blob=(unsigned char *) NULL;
881 if (~(*length) >= MaxTextExtent)
882 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
884 if (blob == (unsigned char *) NULL)
887 (void) ThrowMagickException(exception,GetMagickModule(),
888 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
889 return((unsigned char *) NULL);
891 map=MapBlob(file,ReadMode,0,*length);
892 if (map != (unsigned char *) NULL)
894 (void) CopyMagickMemory(blob,map,*length);
895 (void) UnmapBlob(map,*length);
899 (void) MagickSeek(file,0,SEEK_SET);
900 for (i=0; i < *length; i+=count)
902 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
914 blob=(unsigned char *) RelinquishMagickMemory(blob);
915 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
916 return((unsigned char *) NULL);
925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
929 % F i l e T o I m a g e %
933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
935 % FileToImage() write the contents of a file to an image.
937 % The format of the FileToImage method is:
939 % MagickBooleanType FileToImage(Image *,const char *filename)
941 % A description of each parameter follows:
943 % o image: the image.
945 % o filename: the filename.
949 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
950 const unsigned char *data)
955 register unsigned char
958 assert(image->blob != (BlobInfo *) NULL);
959 if (image->blob->type != BlobStream)
960 return(WriteBlob(image,length,data));
961 assert(image->blob->type != UndefinedStream);
962 assert(data != (void *) NULL);
963 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
964 if (extent >= image->blob->extent)
966 image->blob->quantum<<=1;
967 extent=image->blob->extent+image->blob->quantum+length;
968 if (SetBlobExtent(image,extent) == MagickFalse)
971 q=image->blob->data+image->blob->offset;
972 (void) CopyMagickMemory(q,data,length);
973 image->blob->offset+=length;
974 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
975 image->blob->length=(size_t) image->blob->offset;
976 return((ssize_t) length);
979 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
997 assert(image != (const Image *) NULL);
998 assert(image->signature == MagickSignature);
999 assert(filename != (const char *) NULL);
1000 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1001 file=open(filename,O_RDONLY | O_BINARY);
1004 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1006 return(MagickFalse);
1008 quantum=(size_t) MagickMaxBufferExtent;
1009 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1010 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1011 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1012 if (blob == (unsigned char *) NULL)
1014 ThrowFileException(&image->exception,ResourceLimitError,
1015 "MemoryAllocationFailed",filename);
1016 return(MagickFalse);
1020 count=(ssize_t) read(file,blob,quantum);
1027 length=(size_t) count;
1028 count=WriteBlobStream(image,length,blob);
1029 if (count != (ssize_t) length)
1031 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1037 blob=(unsigned char *) RelinquishMagickMemory(blob);
1042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 + G e t B l o b E r r o r %
1050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052 % GetBlobError() returns MagickTrue if the blob associated with the specified
1053 % image encountered an error.
1055 % The format of the GetBlobError method is:
1057 % MagickBooleanType GetBlobError(const Image *image)
1059 % A description of each parameter follows:
1061 % o image: the image.
1064 MagickExport MagickBooleanType GetBlobError(const Image *image)
1066 assert(image != (const Image *) NULL);
1067 assert(image->signature == MagickSignature);
1068 if (image->debug != MagickFalse)
1069 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1070 return(image->blob->status);
1074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1078 + G e t B l o b F i l e H a n d l e %
1082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1084 % GetBlobFileHandle() returns the file handle associated with the image blob.
1086 % The format of the GetBlobFile method is:
1088 % FILE *GetBlobFileHandle(const Image *image)
1090 % A description of each parameter follows:
1092 % o image: the image.
1095 MagickExport FILE *GetBlobFileHandle(const Image *image)
1097 assert(image != (const Image *) NULL);
1098 assert(image->signature == MagickSignature);
1099 return(image->blob->file);
1103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1107 + G e t B l o b I n f o %
1111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1113 % GetBlobInfo() initializes the BlobInfo structure.
1115 % The format of the GetBlobInfo method is:
1117 % void GetBlobInfo(BlobInfo *blob_info)
1119 % A description of each parameter follows:
1121 % o blob_info: Specifies a pointer to a BlobInfo structure.
1124 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1126 assert(blob_info != (BlobInfo *) NULL);
1127 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1128 blob_info->type=UndefinedStream;
1129 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1130 blob_info->properties.st_mtime=time((time_t *) NULL);
1131 blob_info->properties.st_ctime=time((time_t *) NULL);
1132 blob_info->debug=IsEventLogging();
1133 blob_info->reference_count=1;
1134 blob_info->semaphore=AllocateSemaphoreInfo();
1135 blob_info->signature=MagickSignature;
1139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1143 % G e t B l o b P r o p e r t i e s %
1147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1149 % GetBlobProperties() returns information about an image blob.
1151 % The format of the GetBlobProperties method is:
1153 % const struct stat *GetBlobProperties(const Image *image)
1155 % A description of each parameter follows:
1157 % o image: the image.
1160 MagickExport const struct stat *GetBlobProperties(const Image *image)
1162 assert(image != (Image *) NULL);
1163 assert(image->signature == MagickSignature);
1164 if (image->debug != MagickFalse)
1165 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1166 return(&image->blob->properties);
1170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1174 + G e t B l o b S i z e %
1178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1180 % GetBlobSize() returns the current length of the image file or blob; zero is
1181 % returned if the size cannot be determined.
1183 % The format of the GetBlobSize method is:
1185 % MagickSizeType GetBlobSize(const Image *image)
1187 % A description of each parameter follows:
1189 % o image: the image.
1192 MagickExport MagickSizeType GetBlobSize(const Image *image)
1197 assert(image != (Image *) NULL);
1198 assert(image->signature == MagickSignature);
1199 if (image->debug != MagickFalse)
1200 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1201 assert(image->blob != (BlobInfo *) NULL);
1203 switch (image->blob->type)
1205 case UndefinedStream:
1207 length=image->blob->size;
1212 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1213 length=(MagickSizeType) image->blob->properties.st_size;
1216 case StandardStream:
1219 length=image->blob->size;
1228 status=GetPathAttributes(image->filename,&image->blob->properties);
1229 if (status != MagickFalse)
1230 length=(MagickSizeType) image->blob->properties.st_size;
1237 length=(MagickSizeType) image->blob->length;
1245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1249 + G e t B l o b S t r e a m D a t a %
1253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1255 % GetBlobStreamData() returns the stream data for the image.
1257 % The format of the GetBlobStreamData method is:
1259 % unsigned char *GetBlobStreamData(const Image *image)
1261 % A description of each parameter follows:
1263 % o image: the image.
1266 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1268 assert(image != (const Image *) NULL);
1269 assert(image->signature == MagickSignature);
1270 return(image->blob->data);
1274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1278 + G e t B l o b S t r e a m H a n d l e r %
1282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1284 % GetBlobStreamHandler() returns the stream handler for the image.
1286 % The format of the GetBlobStreamHandler method is:
1288 % StreamHandler GetBlobStreamHandler(const Image *image)
1290 % A description of each parameter follows:
1292 % o image: the image.
1295 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1297 assert(image != (const Image *) NULL);
1298 assert(image->signature == MagickSignature);
1299 if (image->debug != MagickFalse)
1300 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1301 return(image->blob->stream);
1305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1309 % I m a g e T o B l o b %
1313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1315 % ImageToBlob() implements direct to memory image formats. It returns the
1316 % image as a blob and its length. The magick member of the ImageInfo structure
1317 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1319 % The format of the ImageToBlob method is:
1321 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1322 % size_t *length,ExceptionInfo *exception)
1324 % A description of each parameter follows:
1326 % o image_info: the image info.
1328 % o image: the image.
1330 % o length: This pointer to a size_t integer sets the initial length of the
1331 % blob. On return, it reflects the actual length of the blob.
1333 % o exception: return any errors or warnings in this structure.
1336 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1337 Image *image,size_t *length,ExceptionInfo *exception)
1351 assert(image_info != (const ImageInfo *) NULL);
1352 assert(image_info->signature == MagickSignature);
1353 if (image_info->debug != MagickFalse)
1354 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1355 image_info->filename);
1356 assert(image != (Image *) NULL);
1357 assert(image->signature == MagickSignature);
1358 assert(exception != (ExceptionInfo *) NULL);
1360 blob=(unsigned char *) NULL;
1361 blob_info=CloneImageInfo(image_info);
1362 blob_info->adjoin=MagickFalse;
1363 (void) SetImageInfo(blob_info,MagickTrue,exception);
1364 if (*blob_info->magick != '\0')
1365 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1366 magick_info=GetMagickInfo(image->magick,exception);
1367 if (magick_info == (const MagickInfo *) NULL)
1369 (void) ThrowMagickException(exception,GetMagickModule(),
1370 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1374 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1375 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1378 Native blob support for this image format.
1380 blob_info->length=0;
1381 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1382 sizeof(unsigned char));
1383 if (blob_info->blob == (void *) NULL)
1384 (void) ThrowMagickException(exception,GetMagickModule(),
1385 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1388 (void) CloseBlob(image);
1389 image->blob->exempt=MagickTrue;
1390 *image->filename='\0';
1391 status=WriteImage(blob_info,image);
1392 if ((status == MagickFalse) || (image->blob->length == 0))
1393 InheritException(exception,&image->exception);
1396 *length=image->blob->length;
1397 blob=DetachBlob(image->blob);
1398 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1406 unique[MaxTextExtent];
1412 Write file to disk in blob image format.
1414 file=AcquireUniqueFileResource(unique);
1417 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1418 image_info->filename);
1422 blob_info->file=fdopen(file,"wb");
1423 if (blob_info->file != (FILE *) NULL)
1425 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1426 image->magick,unique);
1427 status=WriteImage(blob_info,image);
1428 (void) fclose(blob_info->file);
1429 if (status == MagickFalse)
1430 InheritException(exception,&image->exception);
1432 blob=FileToBlob(image->filename,~0UL,length,exception);
1434 (void) RelinquishUniqueFileResource(unique);
1437 blob_info=DestroyImageInfo(blob_info);
1442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1446 % I m a g e T o F i l e %
1450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1452 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1453 % occurs otherwise MagickTrue.
1455 % The format of the ImageToFile method is:
1457 % MagickBooleanType ImageToFile(Image *image,char *filename,
1458 % ExceptionInfo *exception)
1460 % A description of each parameter follows:
1462 % o image: the image.
1464 % o filename: Write the image to this file.
1466 % o exception: return any errors or warnings in this structure.
1470 static inline const unsigned char *ReadBlobStream(Image *image,
1471 const size_t length,unsigned char *data,ssize_t *count)
1473 assert(count != (ssize_t *) NULL);
1474 assert(image->blob != (BlobInfo *) NULL);
1475 if (image->blob->type != BlobStream)
1477 *count=ReadBlob(image,length,data);
1480 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1483 image->blob->eof=MagickTrue;
1486 data=image->blob->data+image->blob->offset;
1487 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
1488 image->blob->offset));
1489 image->blob->offset+=(*count);
1490 if (*count != (ssize_t) length)
1491 image->blob->eof=MagickTrue;
1495 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1496 ExceptionInfo *exception)
1501 register const unsigned char
1520 assert(image != (Image *) NULL);
1521 assert(image->signature == MagickSignature);
1522 assert(image->blob != (BlobInfo *) NULL);
1523 assert(image->blob->type != UndefinedStream);
1524 if (image->debug != MagickFalse)
1525 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1526 assert(filename != (const char *) NULL);
1527 if (*filename == '\0')
1528 file=AcquireUniqueFileResource(filename);
1530 if (LocaleCompare(filename,"-") == 0)
1531 file=fileno(stdout);
1533 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1536 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1537 return(MagickFalse);
1539 quantum=(size_t) MagickMaxBufferExtent;
1540 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1541 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1542 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1543 if (buffer == (unsigned char *) NULL)
1546 (void) ThrowMagickException(exception,GetMagickModule(),
1547 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1548 return(MagickFalse);
1551 p=ReadBlobStream(image,quantum,buffer,&count);
1552 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1554 length=(size_t) count;
1555 for (i=0; i < length; i+=count)
1557 count=write(file,p+i,(size_t) (length-i));
1569 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1572 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1573 return(MagickFalse);
1579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1583 % I m a g e s T o B l o b %
1587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1589 % ImagesToBlob() implements direct to memory image formats. It returns the
1590 % image sequence as a blob and its length. The magick member of the ImageInfo
1591 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1593 % Note, some image formats do not permit multiple images to the same image
1594 % stream (e.g. JPEG). in this instance, just the first image of the
1595 % sequence is returned as a blob.
1597 % The format of the ImagesToBlob method is:
1599 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1600 % size_t *length,ExceptionInfo *exception)
1602 % A description of each parameter follows:
1604 % o image_info: the image info.
1606 % o images: the image list.
1608 % o length: This pointer to a size_t integer sets the initial length of the
1609 % blob. On return, it reflects the actual length of the blob.
1611 % o exception: return any errors or warnings in this structure.
1614 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1615 Image *images,size_t *length,ExceptionInfo *exception)
1629 assert(image_info != (const ImageInfo *) NULL);
1630 assert(image_info->signature == MagickSignature);
1631 if (image_info->debug != MagickFalse)
1632 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1633 image_info->filename);
1634 assert(images != (Image *) NULL);
1635 assert(images->signature == MagickSignature);
1636 assert(exception != (ExceptionInfo *) NULL);
1638 blob=(unsigned char *) NULL;
1639 blob_info=CloneImageInfo(image_info);
1640 (void) SetImageInfo(blob_info,MagickTrue,exception);
1641 if (*blob_info->magick != '\0')
1642 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1643 if (blob_info->adjoin == MagickFalse)
1645 blob_info=DestroyImageInfo(blob_info);
1646 return(ImageToBlob(image_info,images,length,exception));
1648 magick_info=GetMagickInfo(images->magick,exception);
1649 if (magick_info == (const MagickInfo *) NULL)
1651 (void) ThrowMagickException(exception,GetMagickModule(),
1652 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1656 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1657 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1660 Native blob support for this images format.
1662 blob_info->length=0;
1663 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1664 sizeof(unsigned char));
1665 if (blob_info->blob == (void *) NULL)
1666 (void) ThrowMagickException(exception,GetMagickModule(),
1667 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1670 images->blob->exempt=MagickTrue;
1671 *images->filename='\0';
1672 status=WriteImages(blob_info,images,images->filename,exception);
1673 if ((status == MagickFalse) || (images->blob->length == 0))
1674 InheritException(exception,&images->exception);
1677 *length=images->blob->length;
1678 blob=DetachBlob(images->blob);
1679 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1687 filename[MaxTextExtent],
1688 unique[MaxTextExtent];
1694 Write file to disk in blob images format.
1696 file=AcquireUniqueFileResource(unique);
1699 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1700 image_info->filename);
1704 blob_info->file=fdopen(file,"wb");
1705 if (blob_info->file != (FILE *) NULL)
1707 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1708 images->magick,unique);
1709 status=WriteImages(blob_info,images,filename,exception);
1710 (void) fclose(blob_info->file);
1711 if (status == MagickFalse)
1712 InheritException(exception,&images->exception);
1714 blob=FileToBlob(images->filename,~0UL,length,exception);
1716 (void) RelinquishUniqueFileResource(unique);
1719 blob_info=DestroyImageInfo(blob_info);
1723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1727 % I n j e c t I m a g e B l o b %
1731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1733 % InjectImageBlob() injects the image with a copy of itself in the specified
1734 % format (e.g. inject JPEG into a PDF image).
1736 % The format of the InjectImageBlob method is:
1738 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1739 % Image *image,Image *inject_image,const char *format,
1740 % ExceptionInfo *exception)
1742 % A description of each parameter follows:
1744 % o image_info: the image info..
1746 % o image: the image.
1748 % o inject_image: inject into the image stream.
1750 % o format: the image format.
1752 % o exception: return any errors or warnings in this structure.
1755 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1756 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1759 filename[MaxTextExtent];
1792 Write inject image to a temporary file.
1794 assert(image_info != (ImageInfo *) NULL);
1795 assert(image_info->signature == MagickSignature);
1796 assert(image != (Image *) NULL);
1797 assert(image->signature == MagickSignature);
1798 if (image->debug != MagickFalse)
1799 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1800 assert(inject_image != (Image *) NULL);
1801 assert(inject_image->signature == MagickSignature);
1802 assert(exception != (ExceptionInfo *) NULL);
1803 unique_file=(FILE *) NULL;
1804 file=AcquireUniqueFileResource(filename);
1806 unique_file=fdopen(file,"wb");
1807 if ((file == -1) || (unique_file == (FILE *) NULL))
1809 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1810 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1812 return(MagickFalse);
1814 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1815 if (byte_image == (Image *) NULL)
1817 (void) fclose(unique_file);
1818 (void) RelinquishUniqueFileResource(filename);
1819 return(MagickFalse);
1821 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1823 DestroyBlob(byte_image);
1824 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1825 write_info=CloneImageInfo(image_info);
1826 SetImageInfoFile(write_info,unique_file);
1827 status=WriteImage(write_info,byte_image);
1828 write_info=DestroyImageInfo(write_info);
1829 byte_image=DestroyImage(byte_image);
1830 (void) fclose(unique_file);
1831 if (status == MagickFalse)
1833 (void) RelinquishUniqueFileResource(filename);
1834 return(MagickFalse);
1837 Inject into image stream.
1839 file=open(filename,O_RDONLY | O_BINARY);
1842 (void) RelinquishUniqueFileResource(filename);
1843 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1844 image_info->filename);
1845 return(MagickFalse);
1847 quantum=(size_t) MagickMaxBufferExtent;
1848 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1849 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1850 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1851 if (buffer == (unsigned char *) NULL)
1853 (void) RelinquishUniqueFileResource(filename);
1854 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1857 for (i=0; ; i+=count)
1859 count=(ssize_t) read(file,buffer,quantum);
1866 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1870 (void) RelinquishUniqueFileResource(filename);
1871 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1880 + I s B l o b E x e m p t %
1884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1886 % IsBlobExempt() returns true if the blob is exempt.
1888 % The format of the IsBlobExempt method is:
1890 % MagickBooleanType IsBlobExempt(const Image *image)
1892 % A description of each parameter follows:
1894 % o image: the image.
1897 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1899 assert(image != (const Image *) NULL);
1900 assert(image->signature == MagickSignature);
1901 if (image->debug != MagickFalse)
1902 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1903 return(image->blob->exempt);
1907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1911 + I s B l o b S e e k a b l e %
1915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1917 % IsBlobSeekable() returns true if the blob is seekable.
1919 % The format of the IsBlobSeekable method is:
1921 % MagickBooleanType IsBlobSeekable(const Image *image)
1923 % A description of each parameter follows:
1925 % o image: the image.
1928 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
1933 assert(image != (const Image *) NULL);
1934 assert(image->signature == MagickSignature);
1935 if (image->debug != MagickFalse)
1936 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1937 seekable=(image->blob->type == FileStream) ||
1938 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
1943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1947 + I s B l o b T e m p o r a r y %
1951 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1953 % IsBlobTemporary() returns true if the blob is temporary.
1955 % The format of the IsBlobTemporary method is:
1957 % MagickBooleanType IsBlobTemporary(const Image *image)
1959 % A description of each parameter follows:
1961 % o image: the image.
1964 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
1966 assert(image != (const Image *) NULL);
1967 assert(image->signature == MagickSignature);
1968 if (image->debug != MagickFalse)
1969 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1970 return(image->blob->temporary);
1974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1984 % MapBlob() creates a mapping from a file to a binary large object.
1986 % The format of the MapBlob method is:
1988 % unsigned char *MapBlob(int file,const MapMode mode,
1989 % const MagickOffsetType offset,const size_t length)
1991 % A description of each parameter follows:
1993 % o file: map this file descriptor.
1995 % o mode: ReadMode, WriteMode, or IOMode.
1997 % o offset: starting at this offset within the file.
1999 % o length: the length of the mapping is returned in this pointer.
2002 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2003 const MagickOffsetType offset,const size_t length)
2005 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2018 #if defined(MAP_ANONYMOUS)
2019 flags|=MAP_ANONYMOUS;
2021 return((unsigned char *) NULL);
2028 protection=PROT_READ;
2030 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2036 protection=PROT_WRITE;
2038 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2044 protection=PROT_READ | PROT_WRITE;
2046 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2051 if (map == (unsigned char *) MAP_FAILED)
2052 return((unsigned char *) NULL);
2059 return((unsigned char *) NULL);
2064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2068 + M S B O r d e r L o n g %
2072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2074 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2075 % most-significant byte first.
2077 % The format of the MSBOrderLong method is:
2079 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2081 % A description of each parameter follows.
2083 % o buffer: Specifies a pointer to a buffer of integers.
2085 % o length: Specifies the length of the buffer.
2088 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2093 register unsigned char
2097 assert(buffer != (unsigned char *) NULL);
2104 *buffer++=(unsigned char) c;
2108 *buffer++=(unsigned char) c;
2114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2118 + M S B O r d e r S h o r t %
2122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2124 % MSBOrderShort() converts a least-significant byte first buffer of integers
2125 % to most-significant byte first.
2127 % The format of the MSBOrderShort method is:
2129 % void MSBOrderShort(unsigned char *p,const size_t length)
2131 % A description of each parameter follows.
2133 % o p: Specifies a pointer to a buffer of integers.
2135 % o length: Specifies the length of the buffer.
2138 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2143 register unsigned char
2146 assert(p != (unsigned char *) NULL);
2153 *p++=(unsigned char) c;
2158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2168 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2169 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2170 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2171 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2172 % from a system command.
2174 % The format of the OpenBlob method is:
2176 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2177 % const BlobMode mode,ExceptionInfo *exception)
2179 % A description of each parameter follows:
2181 % o image_info: the image info.
2183 % o image: the image.
2185 % o mode: the mode for opening the file.
2188 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2189 Image *image,const BlobMode mode,ExceptionInfo *exception)
2192 filename[MaxTextExtent];
2203 assert(image_info != (ImageInfo *) NULL);
2204 assert(image_info->signature == MagickSignature);
2205 if (image_info->debug != MagickFalse)
2206 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2207 image_info->filename);
2208 assert(image != (Image *) NULL);
2209 assert(image->signature == MagickSignature);
2210 if (image_info->blob != (void *) NULL)
2212 if (image_info->stream != (StreamHandler) NULL)
2213 image->blob->stream=(StreamHandler) image_info->stream;
2214 AttachBlob(image->blob,image_info->blob,image_info->length);
2217 (void) DetachBlob(image->blob);
2220 default: type="r"; break;
2221 case ReadBlobMode: type="r"; break;
2222 case ReadBinaryBlobMode: type="rb"; break;
2223 case WriteBlobMode: type="w"; break;
2224 case WriteBinaryBlobMode: type="w+b"; break;
2225 case AppendBlobMode: type="a"; break;
2226 case AppendBinaryBlobMode: type="a+b"; break;
2229 image->blob->synchronize=image_info->synchronize;
2230 if (image_info->stream != (StreamHandler) NULL)
2232 image->blob->stream=(StreamHandler) image_info->stream;
2235 image->blob->type=FifoStream;
2243 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2244 rights=ReadPolicyRights;
2246 rights=WritePolicyRights;
2247 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2249 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2250 "NotAuthorized","`%s'",filename);
2251 return(MagickFalse);
2253 if ((LocaleCompare(filename,"-") == 0) ||
2254 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2256 image->blob->file=(*type == 'r') ? stdin : stdout;
2257 #if defined(__WINDOWS__) || defined(__OS2__)
2258 if (strchr(type,'b') != (char *) NULL)
2259 setmode(_fileno(image->blob->file),_O_BINARY);
2261 image->blob->type=StandardStream;
2262 image->blob->exempt=MagickTrue;
2265 if (LocaleNCompare(filename,"fd:",3) == 0)
2268 mode[MaxTextExtent];
2272 image->blob->file=fdopen(atoi(filename+3),mode);
2273 #if defined(__WINDOWS__) || defined(__OS2__)
2274 if (strchr(type,'b') != (char *) NULL)
2275 setmode(_fileno(image->blob->file),_O_BINARY);
2277 image->blob->type=StandardStream;
2278 image->blob->exempt=MagickTrue;
2281 #if defined(MAGICKCORE_HAVE_POPEN)
2282 if (*filename == '|')
2285 mode[MaxTextExtent];
2288 Pipe image to or from a system command.
2290 #if defined(SIGPIPE)
2292 (void) signal(SIGPIPE,SIG_IGN);
2296 image->blob->file=(FILE *) popen(filename+1,mode);
2297 if (image->blob->file == (FILE *) NULL)
2299 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2300 return(MagickFalse);
2302 image->blob->type=PipeStream;
2303 image->blob->exempt=MagickTrue;
2307 status=GetPathAttributes(filename,&image->blob->properties);
2308 #if defined(S_ISFIFO)
2309 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2311 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2312 if (image->blob->file == (FILE *) NULL)
2314 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2315 return(MagickFalse);
2317 image->blob->type=FileStream;
2318 image->blob->exempt=MagickTrue;
2325 Form filename for multi-part images.
2327 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2328 image->scene,filename);
2329 if (image_info->adjoin == MagickFalse)
2330 if ((image->previous != (Image *) NULL) ||
2331 (GetNextImageInList(image) != (Image *) NULL))
2333 if (LocaleCompare(filename,image->filename) == 0)
2336 extension[MaxTextExtent],
2337 path[MaxTextExtent];
2339 GetPathComponent(image->filename,RootPath,path);
2340 GetPathComponent(image->filename,ExtensionPath,extension);
2341 if (*extension == '\0')
2342 (void) FormatMagickString(filename,MaxTextExtent,"%s-%lu",
2345 (void) FormatMagickString(filename,MaxTextExtent,"%s-%lu.%s",
2346 path,image->scene,extension);
2349 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2350 #if defined(macintosh)
2351 SetApplicationType(filename,image_info->magick,'8BIM');
2354 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2355 if (((strlen(filename) > 2) &&
2356 (LocaleCompare(filename+strlen(filename)-2,".Z") == 0)) ||
2357 ((strlen(filename) > 3) &&
2358 (LocaleCompare(filename+strlen(filename)-3,".gz") == 0)) ||
2359 ((strlen(filename) > 4) &&
2360 (LocaleCompare(filename+strlen(filename)-4,".wmz") == 0)) ||
2361 ((strlen(filename) > 5) &&
2362 (LocaleCompare(filename+strlen(filename)-5,".svgz") == 0)))
2364 image->blob->file=(FILE *) gzopen(filename,type);
2365 if (image->blob->file != (FILE *) NULL)
2366 image->blob->type=ZipStream;
2370 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2371 if ((strlen(filename) > 4) &&
2372 (LocaleCompare(filename+strlen(filename)-4,".bz2") == 0))
2374 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2375 if (image->blob->file != (FILE *) NULL)
2376 image->blob->type=BZipStream;
2380 if (image_info->file != (FILE *) NULL)
2382 image->blob->file=image_info->file;
2383 image->blob->type=FileStream;
2384 image->blob->exempt=MagickTrue;
2388 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2389 if (image->blob->file != (FILE *) NULL)
2391 image->blob->type=FileStream;
2392 #if defined(MAGICKCORE_HAVE_SETVBUF)
2393 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2404 (void) ResetMagickMemory(magick,0,sizeof(magick));
2405 count=fread(magick,1,sizeof(magick),image->blob->file);
2406 (void) rewind(image->blob->file);
2407 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2408 " read %ld magic header bytes",(long) count);
2409 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2410 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2411 ((int) magick[2] == 0x08))
2413 (void) fclose(image->blob->file);
2414 image->blob->file=(FILE *) gzopen(filename,type);
2415 if (image->blob->file != (FILE *) NULL)
2416 image->blob->type=ZipStream;
2419 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2420 if (strncmp((char *) magick,"BZh",3) == 0)
2422 (void) fclose(image->blob->file);
2423 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2424 if (image->blob->file != (FILE *) NULL)
2425 image->blob->type=BZipStream;
2431 if ((image->blob->type == FileStream) && (*type == 'r'))
2442 sans_exception=AcquireExceptionInfo();
2443 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2444 sans_exception=DestroyExceptionInfo(sans_exception);
2445 properties=(&image->blob->properties);
2446 if ((magick_info != (const MagickInfo *) NULL) &&
2447 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2448 (properties->st_size <= MagickMaxBufferExtent))
2456 length=(size_t) properties->st_size;
2457 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2458 if (blob != (void *) NULL)
2461 Format supports blobs-- use memory-mapped I/O.
2463 if (image_info->file != (FILE *) NULL)
2464 image->blob->exempt=MagickFalse;
2467 (void) fclose(image->blob->file);
2468 image->blob->file=(FILE *) NULL;
2470 AttachBlob(image->blob,blob,length);
2471 image->blob->mapped=MagickTrue;
2475 image->blob->status=MagickFalse;
2476 if (image->blob->type != UndefinedStream)
2477 image->blob->size=GetBlobSize(image);
2480 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2481 return(MagickFalse);
2487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2497 % PingBlob() returns all the attributes of an image or image sequence except
2498 % for the pixels. It is much faster and consumes far less memory than
2499 % BlobToImage(). On failure, a NULL image is returned and exception
2500 % describes the reason for the failure.
2502 % The format of the PingBlob method is:
2504 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2505 % const size_t length,ExceptionInfo *exception)
2507 % A description of each parameter follows:
2509 % o image_info: the image info.
2511 % o blob: the address of a character stream in one of the image formats
2512 % understood by ImageMagick.
2514 % o length: This size_t integer reflects the length in bytes of the blob.
2516 % o exception: return any errors or warnings in this structure.
2520 #if defined(__cplusplus) || defined(c_plusplus)
2524 static size_t PingStream(const Image *magick_unused(image),
2525 const void *magick_unused(pixels),const size_t columns)
2530 #if defined(__cplusplus) || defined(c_plusplus)
2534 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2535 const size_t length,ExceptionInfo *exception)
2543 assert(image_info != (ImageInfo *) NULL);
2544 assert(image_info->signature == MagickSignature);
2545 if (image_info->debug != MagickFalse)
2546 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2547 image_info->filename);
2548 assert(exception != (ExceptionInfo *) NULL);
2549 if ((blob == (const void *) NULL) || (length == 0))
2551 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2552 "UnrecognizedImageFormat","`%s'",image_info->magick);
2553 return((Image *) NULL);
2555 ping_info=CloneImageInfo(image_info);
2556 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2557 if (ping_info->blob == (const void *) NULL)
2559 (void) ThrowMagickException(exception,GetMagickModule(),
2560 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2561 return((Image *) NULL);
2563 (void) CopyMagickMemory(ping_info->blob,blob,length);
2564 ping_info->length=length;
2565 ping_info->ping=MagickTrue;
2566 image=ReadStream(ping_info,&PingStream,exception);
2567 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2568 ping_info=DestroyImageInfo(ping_info);
2573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2583 % ReadBlob() reads data from the blob or image file and returns it. It
2584 % returns the number of bytes read.
2586 % The format of the ReadBlob method is:
2588 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2590 % A description of each parameter follows:
2592 % o image: the image.
2594 % o length: Specifies an integer representing the number of bytes to read
2597 % o data: Specifies an area to place the information requested from the
2601 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2602 unsigned char *data)
2607 register unsigned char
2613 assert(image != (Image *) NULL);
2614 assert(image->signature == MagickSignature);
2615 assert(image->blob != (BlobInfo *) NULL);
2616 assert(image->blob->type != UndefinedStream);
2619 assert(data != (void *) NULL);
2622 switch (image->blob->type)
2624 case UndefinedStream:
2627 case StandardStream:
2634 count=(ssize_t) fread(q,1,length,image->blob->file);
2639 c=getc(image->blob->file);
2642 *q++=(unsigned char) c;
2647 c=getc(image->blob->file);
2650 *q++=(unsigned char) c;
2660 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2665 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2670 c=gzgetc(image->blob->file);
2673 *q++=(unsigned char) c;
2678 c=gzgetc(image->blob->file);
2681 *q++=(unsigned char) c;
2692 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2693 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2701 register const unsigned char
2704 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2706 image->blob->eof=MagickTrue;
2709 p=image->blob->data+image->blob->offset;
2710 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2711 image->blob->offset));
2712 image->blob->offset+=count;
2713 if (count != (ssize_t) length)
2714 image->blob->eof=MagickTrue;
2715 (void) CopyMagickMemory(q,p,(size_t) count);
2723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2727 + R e a d B l o b B y t e %
2731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2733 % ReadBlobByte() reads a single byte from the image file and returns it.
2735 % The format of the ReadBlobByte method is:
2737 % int ReadBlobByte(Image *image)
2739 % A description of each parameter follows.
2741 % o image: the image.
2744 MagickExport int ReadBlobByte(Image *image)
2746 register const unsigned char
2755 assert(image != (Image *) NULL);
2756 assert(image->signature == MagickSignature);
2757 p=ReadBlobStream(image,1,buffer,&count);
2764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2768 + R e a d B l o b D o u b l e %
2772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2774 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2775 % specified by the endian member of the image structure.
2777 % The format of the ReadBlobDouble method is:
2779 % double ReadBlobDouble(Image *image)
2781 % A description of each parameter follows.
2783 % o image: the image.
2786 MagickExport double ReadBlobDouble(Image *image)
2797 quantum.double_value=0.0;
2798 quantum.unsigned_value=ReadBlobLongLong(image);
2799 return(quantum.double_value);
2803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2807 + R e a d B l o b F l o a t %
2811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2813 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2814 % specified by the endian member of the image structure.
2816 % The format of the ReadBlobFloat method is:
2818 % float ReadBlobFloat(Image *image)
2820 % A description of each parameter follows.
2822 % o image: the image.
2825 MagickExport float ReadBlobFloat(Image *image)
2836 quantum.float_value=0.0;
2837 quantum.unsigned_value=ReadBlobLong(image);
2838 return(quantum.float_value);
2842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2846 + R e a d B l o b L o n g %
2850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2852 % ReadBlobLong() reads a long value as a 32-bit quantity in the byte-order
2853 % specified by the endian member of the image structure.
2855 % The format of the ReadBlobLong method is:
2857 % unsigned int ReadBlobLong(Image *image)
2859 % A description of each parameter follows.
2861 % o image: the image.
2864 MagickExport unsigned int ReadBlobLong(Image *image)
2866 register const unsigned char
2878 assert(image != (Image *) NULL);
2879 assert(image->signature == MagickSignature);
2881 p=ReadBlobStream(image,4,buffer,&count);
2884 if (image->endian == LSBEndian)
2886 value=(unsigned int) (*p++);
2887 value|=((unsigned int) (*p++)) << 8;
2888 value|=((unsigned int) (*p++)) << 16;
2889 value|=((unsigned int) (*p++)) << 24;
2892 value=((unsigned int) (*p++)) << 24;
2893 value|=((unsigned int) (*p++)) << 16;
2894 value|=((unsigned int) (*p++)) << 8;
2895 value|=((unsigned int) (*p++));
2900 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2904 + R e a d B l o b L o n g L o n g %
2908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2910 % ReadBlobLongLong() reads a long value as a 64-bit quantity in the byte-order
2911 % specified by the endian member of the image structure.
2913 % The format of the ReadBlobLong method is:
2915 % MagickSizeType ReadBlobLong(Image *image)
2917 % A description of each parameter follows.
2919 % o image: the image.
2922 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
2924 register const unsigned char
2936 assert(image != (Image *) NULL);
2937 assert(image->signature == MagickSignature);
2939 p=ReadBlobStream(image,8,buffer,&count);
2941 return(MagickULLConstant(0));
2942 if (image->endian == LSBEndian)
2944 value=(MagickSizeType) (*p++);
2945 value|=((MagickSizeType) (*p++)) << 8;
2946 value|=((MagickSizeType) (*p++)) << 16;
2947 value|=((MagickSizeType) (*p++)) << 24;
2948 value|=((MagickSizeType) (*p++)) << 32;
2949 value|=((MagickSizeType) (*p++)) << 40;
2950 value|=((MagickSizeType) (*p++)) << 48;
2951 value|=((MagickSizeType) (*p++)) << 56;
2952 return(value & MagickULLConstant(0xffffffffffffffff));
2954 value=((MagickSizeType) (*p++)) << 56;
2955 value|=((MagickSizeType) (*p++)) << 48;
2956 value|=((MagickSizeType) (*p++)) << 40;
2957 value|=((MagickSizeType) (*p++)) << 32;
2958 value|=((MagickSizeType) (*p++)) << 24;
2959 value|=((MagickSizeType) (*p++)) << 16;
2960 value|=((MagickSizeType) (*p++)) << 8;
2961 value|=((MagickSizeType) (*p++));
2962 return(value & MagickULLConstant(0xffffffffffffffff));
2966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2970 + R e a d B l o b S h o r t %
2974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2976 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
2977 % specified by the endian member of the image structure.
2979 % The format of the ReadBlobShort method is:
2981 % unsigned short ReadBlobShort(Image *image)
2983 % A description of each parameter follows.
2985 % o image: the image.
2988 MagickExport unsigned short ReadBlobShort(Image *image)
2990 register const unsigned char
2993 register unsigned int
3002 assert(image != (Image *) NULL);
3003 assert(image->signature == MagickSignature);
3005 p=ReadBlobStream(image,2,buffer,&count);
3007 return((unsigned short) 0U);
3008 if (image->endian == LSBEndian)
3010 value=(unsigned int) (*p++);
3011 value|=((unsigned int) (*p++)) << 8;
3012 return((unsigned short) (value & 0xffff));
3014 value=(unsigned int) ((*p++) << 8);
3015 value|=(unsigned int) (*p++);
3016 return((unsigned short) (value & 0xffff));
3020 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3024 + R e a d B l o b L S B L o n g %
3028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3030 % ReadBlobLSBLong() reads a long value as a 32-bit quantity in
3031 % least-significant byte first order.
3033 % The format of the ReadBlobLSBLong method is:
3035 % unsigned int ReadBlobLSBLong(Image *image)
3037 % A description of each parameter follows.
3039 % o image: the image.
3042 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3044 register const unsigned char
3047 register unsigned int
3056 assert(image != (Image *) NULL);
3057 assert(image->signature == MagickSignature);
3059 p=ReadBlobStream(image,4,buffer,&count);
3062 value=(unsigned int) (*p++);
3063 value|=((unsigned int) (*p++)) << 8;
3064 value|=((unsigned int) (*p++)) << 16;
3065 value|=((unsigned int) (*p++)) << 24;
3070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3074 + R e a d B l o b L S B S h o r t %
3078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3080 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3081 % least-significant byte first order.
3083 % The format of the ReadBlobLSBShort method is:
3085 % unsigned short ReadBlobLSBShort(Image *image)
3087 % A description of each parameter follows.
3089 % o image: the image.
3092 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3094 register const unsigned char
3097 register unsigned int
3106 assert(image != (Image *) NULL);
3107 assert(image->signature == MagickSignature);
3109 p=ReadBlobStream(image,2,buffer,&count);
3111 return((unsigned short) 0U);
3112 value=(unsigned int) (*p++);
3113 value|=((unsigned int) ((*p++)) << 8);
3114 return((unsigned short) (value & 0xffff));
3118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3122 + R e a d B l o b M S B L o n g %
3126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3128 % ReadBlobMSBLong() reads a long value as a 32-bit quantity in
3129 % most-significant byte first order.
3131 % The format of the ReadBlobMSBLong method is:
3133 % unsigned int ReadBlobMSBLong(Image *image)
3135 % A description of each parameter follows.
3137 % o image: the image.
3140 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3142 register const unsigned char
3145 register unsigned int
3154 assert(image != (Image *) NULL);
3155 assert(image->signature == MagickSignature);
3157 p=ReadBlobStream(image,4,buffer,&count);
3160 value=((unsigned int) (*p++) << 24);
3161 value|=((unsigned int) (*p++) << 16);
3162 value|=((unsigned int) (*p++) << 8);
3163 value|=(unsigned int) (*p++);
3168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3172 + R e a d B l o b M S B S h o r t %
3176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3178 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3179 % most-significant byte first order.
3181 % The format of the ReadBlobMSBShort method is:
3183 % unsigned short ReadBlobMSBShort(Image *image)
3185 % A description of each parameter follows.
3187 % o image: the image.
3190 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3192 register const unsigned char
3195 register unsigned int
3204 assert(image != (Image *) NULL);
3205 assert(image->signature == MagickSignature);
3207 p=ReadBlobStream(image,2,buffer,&count);
3209 return((unsigned short) 0U);
3210 value=(unsigned int) ((*p++) << 8);
3211 value|=(unsigned int) (*p++);
3212 return((unsigned short) (value & 0xffff));
3216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3220 + R e a d B l o b S t r i n g %
3224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3226 % ReadBlobString() reads characters from a blob or file until a newline
3227 % character is read or an end-of-file condition is encountered.
3229 % The format of the ReadBlobString method is:
3231 % char *ReadBlobString(Image *image,char *string)
3233 % A description of each parameter follows:
3235 % o image: the image.
3237 % o string: the address of a character buffer.
3240 MagickExport char *ReadBlobString(Image *image,char *string)
3242 register const unsigned char
3254 assert(image != (Image *) NULL);
3255 assert(image->signature == MagickSignature);
3256 for (i=0; i < (MaxTextExtent-1L); i++)
3258 p=ReadBlobStream(image,1,buffer,&count);
3262 return((char *) NULL);
3265 string[i]=(char) (*p);
3266 if ((string[i] == '\n') || (string[i] == '\r'))
3274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3278 + R e f e r e n c e B l o b %
3282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3284 % ReferenceBlob() increments the reference count associated with the pixel
3285 % blob returning a pointer to the blob.
3287 % The format of the ReferenceBlob method is:
3289 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3291 % A description of each parameter follows:
3293 % o blob_info: the blob_info.
3296 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3298 assert(blob != (BlobInfo *) NULL);
3299 assert(blob->signature == MagickSignature);
3300 if (blob->debug != MagickFalse)
3301 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3302 (void) LockSemaphoreInfo(blob->semaphore);
3303 blob->reference_count++;
3304 (void) UnlockSemaphoreInfo(blob->semaphore);
3309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3319 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3320 % and returns the resulting offset.
3322 % The format of the SeekBlob method is:
3324 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3327 % A description of each parameter follows:
3329 % o image: the image.
3331 % o offset: Specifies an integer representing the offset in bytes.
3333 % o whence: Specifies an integer representing how the offset is
3334 % treated relative to the beginning of the blob as follows:
3336 % SEEK_SET Set position equal to offset bytes.
3337 % SEEK_CUR Set position to current location plus offset.
3338 % SEEK_END Set position to EOF plus offset.
3341 MagickExport MagickOffsetType SeekBlob(Image *image,
3342 const MagickOffsetType offset,const int whence)
3344 assert(image != (Image *) NULL);
3345 assert(image->signature == MagickSignature);
3346 if (image->debug != MagickFalse)
3347 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3348 assert(image->blob != (BlobInfo *) NULL);
3349 assert(image->blob->type != UndefinedStream);
3350 switch (image->blob->type)
3352 case UndefinedStream:
3356 if (fseek(image->blob->file,offset,whence) < 0)
3358 image->blob->offset=TellBlob(image);
3361 case StandardStream:
3365 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3366 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3369 image->blob->offset=TellBlob(image);
3385 image->blob->offset=offset;
3390 if ((image->blob->offset+offset) < 0)
3392 image->blob->offset+=offset;
3397 if (((MagickOffsetType) image->blob->length+offset) < 0)
3399 image->blob->offset=image->blob->length+offset;
3403 if (image->blob->offset <= (MagickOffsetType)
3404 ((off_t) image->blob->length))
3405 image->blob->eof=MagickFalse;
3407 if (image->blob->mapped != MagickFalse)
3411 image->blob->extent=(size_t) (image->blob->offset+
3412 image->blob->quantum);
3413 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3414 image->blob->data,image->blob->extent+1,
3415 sizeof(*image->blob->data));
3416 (void) SyncBlob(image);
3417 if (image->blob->data == (unsigned char *) NULL)
3419 (void) DetachBlob(image->blob);
3426 return(image->blob->offset);
3430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3434 + S e t B l o b E x e m p t %
3438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3440 % SetBlobExempt() sets the blob exempt status.
3442 % The format of the SetBlobExempt method is:
3444 % MagickBooleanType SetBlobExempt(const Image *image,
3445 % const MagickBooleanType exempt)
3447 % A description of each parameter follows:
3449 % o image: the image.
3451 % o exempt: Set to true if this blob is exempt from being closed.
3454 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3456 assert(image != (const Image *) NULL);
3457 assert(image->signature == MagickSignature);
3458 if (image->debug != MagickFalse)
3459 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3460 image->blob->exempt=exempt;
3464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3468 + S e t B l o b E x t e n t %
3472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3474 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3475 % method is successful, subsequent writes to bytes in the specified range are
3476 % guaranteed not to fail.
3478 % The format of the SetBlobExtent method is:
3480 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3482 % A description of each parameter follows:
3484 % o image: the image.
3486 % o extent: the blob maximum extent.
3489 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3490 const MagickSizeType extent)
3492 assert(image != (Image *) NULL);
3493 assert(image->signature == MagickSignature);
3494 if (image->debug != MagickFalse)
3495 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3496 assert(image->blob != (BlobInfo *) NULL);
3497 assert(image->blob->type != UndefinedStream);
3498 switch (image->blob->type)
3500 case UndefinedStream:
3504 if (extent != (MagickSizeType) ((off_t) extent))
3505 return(MagickFalse);
3506 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3507 return(MagickFalse);
3516 offset=TellBlob(image);
3517 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3518 (off_t) (extent-offset));
3520 return(MagickFalse);
3525 case StandardStream:
3528 return(MagickFalse);
3530 return(MagickFalse);
3532 return(MagickFalse);
3535 if (image->blob->mapped != MagickFalse)
3537 if (image->blob->file == (FILE *) NULL)
3538 return(MagickFalse);
3539 (void) UnmapBlob(image->blob->data,image->blob->length);
3540 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3541 return(MagickFalse);
3550 offset=TellBlob(image);
3551 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3552 (off_t) (extent-offset));
3554 return(MagickFalse);
3556 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3557 WriteMode,0,(size_t) extent);
3558 image->blob->extent=(size_t) extent;
3559 image->blob->length=(size_t) extent;
3560 (void) SyncBlob(image);
3564 if (extent != (MagickSizeType) ((size_t) extent))
3565 return(MagickFalse);
3566 image->blob->extent=(size_t) extent;
3567 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3568 image->blob->extent+1,sizeof(*image->blob->data));
3569 (void) SyncBlob(image);
3570 if (image->blob->data == (unsigned char *) NULL)
3572 (void) DetachBlob(image->blob);
3573 return(MagickFalse);
3582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3592 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3593 % attributes if it is an blob.
3595 % The format of the SyncBlob method is:
3597 % int SyncBlob(Image *image)
3599 % A description of each parameter follows:
3601 % o image: the image.
3604 static int SyncBlob(Image *image)
3609 assert(image != (Image *) NULL);
3610 assert(image->signature == MagickSignature);
3611 if (image->debug != MagickFalse)
3612 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3613 assert(image->blob != (BlobInfo *) NULL);
3614 assert(image->blob->type != UndefinedStream);
3616 switch (image->blob->type)
3618 case UndefinedStream:
3621 case StandardStream:
3624 status=fflush(image->blob->file);
3629 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3630 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3636 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3637 status=BZ2_bzflush((BZFILE *) image->blob->file);
3645 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3646 if (image->blob->mapped != MagickFalse)
3647 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3666 % TellBlob() obtains the current value of the blob or file position.
3668 % The format of the TellBlob method is:
3670 % MagickOffsetType TellBlob(const Image *image)
3672 % A description of each parameter follows:
3674 % o image: the image.
3677 MagickExport MagickOffsetType TellBlob(const Image *image)
3682 assert(image != (Image *) NULL);
3683 assert(image->signature == MagickSignature);
3684 if (image->debug != MagickFalse)
3685 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3686 assert(image->blob != (BlobInfo *) NULL);
3687 assert(image->blob->type != UndefinedStream);
3689 switch (image->blob->type)
3691 case UndefinedStream:
3695 offset=ftell(image->blob->file);
3698 case StandardStream:
3703 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3704 offset=(MagickOffsetType) gztell(image->blob->file);
3714 offset=image->blob->offset;
3722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3726 + U n m a p B l o b %
3730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3732 % UnmapBlob() deallocates the binary large object previously allocated with
3733 % the MapBlob method.
3735 % The format of the UnmapBlob method is:
3737 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3739 % A description of each parameter follows:
3741 % o map: the address of the binary large object.
3743 % o length: the length of the binary large object.
3746 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3748 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3752 status=munmap(map,length);
3753 return(status == -1 ? MagickFalse : MagickTrue);
3757 return(MagickFalse);
3762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3766 + W r i t e B l o b %
3770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3772 % WriteBlob() writes data to a blob or image file. It returns the number of
3775 % The format of the WriteBlob method is:
3777 % ssize_t WriteBlob(Image *image,const size_t length,
3778 % const unsigned char *data)
3780 % A description of each parameter follows:
3782 % o image: the image.
3784 % o length: Specifies an integer representing the number of bytes to
3785 % write to the file.
3787 % o data: The address of the data to write to the blob or file.
3790 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3791 const unsigned char *data)
3796 register const unsigned char
3802 assert(image != (Image *) NULL);
3803 assert(image->signature == MagickSignature);
3804 assert(data != (const unsigned char *) NULL);
3805 assert(image->blob != (BlobInfo *) NULL);
3806 assert(image->blob->type != UndefinedStream);
3811 switch (image->blob->type)
3813 case UndefinedStream:
3816 case StandardStream:
3823 count=(ssize_t) fwrite((const char *) data,1,length,
3829 c=putc((int) *p++,image->blob->file);
3836 c=putc((int) *p++,image->blob->file);
3848 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3853 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
3854 (unsigned int) length);
3859 c=gzputc(image->blob->file,(int) *p++);
3866 c=gzputc(image->blob->file,(int) *p++);
3879 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3880 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
3887 count=(ssize_t) image->blob->stream(image,data,length);
3892 register unsigned char
3895 if ((image->blob->offset+(MagickOffsetType) length) >=
3896 (MagickOffsetType) image->blob->extent)
3898 if (image->blob->mapped != MagickFalse)
3900 image->blob->quantum<<=1;
3901 image->blob->extent+=length+image->blob->quantum;
3902 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3903 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
3904 (void) SyncBlob(image);
3905 if (image->blob->data == (unsigned char *) NULL)
3907 (void) DetachBlob(image->blob);
3911 q=image->blob->data+image->blob->offset;
3912 (void) CopyMagickMemory(q,p,length);
3913 image->blob->offset+=length;
3914 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3915 image->blob->length=(size_t) image->blob->offset;
3916 count=(ssize_t) length;
3923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3927 + W r i t e B l o b B y t e %
3931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3933 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
3934 % written (either 0 or 1);
3936 % The format of the WriteBlobByte method is:
3938 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
3940 % A description of each parameter follows.
3942 % o image: the image.
3944 % o value: Specifies the value to write.
3947 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
3949 assert(image != (Image *) NULL);
3950 assert(image->signature == MagickSignature);
3951 return(WriteBlobStream(image,1,&value));
3955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3959 + W r i t e B l o b F l o a t %
3963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3965 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
3966 % specified by the endian member of the image structure.
3968 % The format of the WriteBlobFloat method is:
3970 % ssize_t WriteBlobFloat(Image *image,const float value)
3972 % A description of each parameter follows.
3974 % o image: the image.
3976 % o value: Specifies the value to write.
3979 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
3990 quantum.unsigned_value=0U;
3991 quantum.float_value=value;
3992 return(WriteBlobLong(image,quantum.unsigned_value));
3996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4000 + W r i t e B l o b L o n g %
4004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4006 % WriteBlobLong() writes a long value as a 32-bit quantity in the byte-order
4007 % specified by the endian member of the image structure.
4009 % The format of the WriteBlobLong method is:
4011 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4013 % A description of each parameter follows.
4015 % o image: the image.
4017 % o value: Specifies the value to write.
4020 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4025 assert(image != (Image *) NULL);
4026 assert(image->signature == MagickSignature);
4027 if (image->endian == LSBEndian)
4029 buffer[0]=(unsigned char) value;
4030 buffer[1]=(unsigned char) (value >> 8);
4031 buffer[2]=(unsigned char) (value >> 16);
4032 buffer[3]=(unsigned char) (value >> 24);
4033 return(WriteBlobStream(image,4,buffer));
4035 buffer[0]=(unsigned char) (value >> 24);
4036 buffer[1]=(unsigned char) (value >> 16);
4037 buffer[2]=(unsigned char) (value >> 8);
4038 buffer[3]=(unsigned char) value;
4039 return(WriteBlobStream(image,4,buffer));
4043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4047 + W r i t e B l o b S h o r t %
4051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4053 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4054 % byte-order specified by the endian member of the image structure.
4056 % The format of the WriteBlobShort method is:
4058 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4060 % A description of each parameter follows.
4062 % o image: the image.
4064 % o value: Specifies the value to write.
4067 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4072 assert(image != (Image *) NULL);
4073 assert(image->signature == MagickSignature);
4074 if (image->endian == LSBEndian)
4076 buffer[0]=(unsigned char) value;
4077 buffer[1]=(unsigned char) (value >> 8);
4078 return(WriteBlobStream(image,2,buffer));
4080 buffer[0]=(unsigned char) (value >> 8);
4081 buffer[1]=(unsigned char) value;
4082 return(WriteBlobStream(image,2,buffer));
4086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4090 + W r i t e B l o b L S B L o n g %
4094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4096 % WriteBlobLSBLong() writes a long value as a 32-bit quantity in
4097 % least-significant byte first order.
4099 % The format of the WriteBlobLSBLong method is:
4101 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4103 % A description of each parameter follows.
4105 % o image: the image.
4107 % o value: Specifies the value to write.
4110 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4115 assert(image != (Image *) NULL);
4116 assert(image->signature == MagickSignature);
4117 buffer[0]=(unsigned char) value;
4118 buffer[1]=(unsigned char) (value >> 8);
4119 buffer[2]=(unsigned char) (value >> 16);
4120 buffer[3]=(unsigned char) (value >> 24);
4121 return(WriteBlobStream(image,4,buffer));
4125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4129 + W r i t e B l o b L S B S h o r t %
4133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4135 % WriteBlobLSBShort() writes a long value as a 16-bit quantity in
4136 % least-significant byte first order.
4138 % The format of the WriteBlobLSBShort method is:
4140 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4142 % A description of each parameter follows.
4144 % o image: the image.
4146 % o value: Specifies the value to write.
4149 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4154 assert(image != (Image *) NULL);
4155 assert(image->signature == MagickSignature);
4156 buffer[0]=(unsigned char) value;
4157 buffer[1]=(unsigned char) (value >> 8);
4158 return(WriteBlobStream(image,2,buffer));
4162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4166 + W r i t e B l o b M S B L o n g %
4170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4172 % WriteBlobMSBLong() writes a long value as a 32-bit quantity in
4173 % most-significant byte first order.
4175 % The format of the WriteBlobMSBLong method is:
4177 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4179 % A description of each parameter follows.
4181 % o value: Specifies the value to write.
4183 % o image: the image.
4186 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4191 assert(image != (Image *) NULL);
4192 assert(image->signature == MagickSignature);
4193 buffer[0]=(unsigned char) (value >> 24);
4194 buffer[1]=(unsigned char) (value >> 16);
4195 buffer[2]=(unsigned char) (value >> 8);
4196 buffer[3]=(unsigned char) value;
4197 return(WriteBlobStream(image,4,buffer));
4201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4205 + W r i t e B l o b M S B S h o r t %
4209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4211 % WriteBlobMSBShort() writes a long value as a 16-bit quantity in
4212 % most-significant byte first order.
4214 % The format of the WriteBlobMSBShort method is:
4216 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4218 % A description of each parameter follows.
4220 % o value: Specifies the value to write.
4222 % o file: Specifies the file to write the data to.
4225 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4230 assert(image != (Image *) NULL);
4231 assert(image->signature == MagickSignature);
4232 buffer[0]=(unsigned char) (value >> 8);
4233 buffer[1]=(unsigned char) value;
4234 return(WriteBlobStream(image,2,buffer));
4238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4242 + W r i t e B l o b S t r i n g %
4246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4248 % WriteBlobString() write a string to a blob. It returns the number of
4249 % characters written.
4251 % The format of the WriteBlobString method is:
4253 % ssize_t WriteBlobString(Image *image,const char *string)
4255 % A description of each parameter follows.
4257 % o image: the image.
4259 % o string: Specifies the string to write.
4262 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4264 assert(image != (Image *) NULL);
4265 assert(image->signature == MagickSignature);
4266 assert(string != (const char *) NULL);
4267 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));