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,MagickFalse,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->blob->eof=MagickFalse;
487 if (image->blob->exempt != MagickFalse)
489 image->blob->type=UndefinedStream;
493 switch (image->blob->type)
495 case UndefinedStream:
501 status=ferror(image->blob->file);
506 #if defined(MAGICKCORE_ZLIB_DELEGATE)
507 (void) gzerror(image->blob->file,&status);
513 #if defined(MAGICKCORE_BZLIB_DELEGATE)
514 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
522 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
523 switch (image->blob->type)
525 case UndefinedStream:
530 if (image->blob->synchronize != MagickFalse)
531 status=fsync(fileno(image->blob->file));
532 status=fclose(image->blob->file);
537 #if defined(MAGICKCORE_HAVE_PCLOSE)
538 status=pclose(image->blob->file);
544 #if defined(MAGICKCORE_ZLIB_DELEGATE)
545 status=gzclose(image->blob->file);
551 #if defined(MAGICKCORE_BZLIB_DELEGATE)
552 BZ2_bzclose((BZFILE *) image->blob->file);
560 (void) DetachBlob(image->blob);
561 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
562 return(image->blob->status);
566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
570 + D e s t r o y B l o b %
574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
576 % DestroyBlob() deallocates memory associated with a blob.
578 % The format of the DestroyBlob method is:
580 % void DestroyBlob(Image *image)
582 % A description of each parameter follows:
584 % o image: the image.
587 MagickExport void DestroyBlob(Image *image)
592 assert(image != (Image *) NULL);
593 assert(image->signature == MagickSignature);
594 if (image->debug != MagickFalse)
595 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
596 assert(image->blob != (BlobInfo *) NULL);
597 assert(image->blob->signature == MagickSignature);
599 (void) LockSemaphoreInfo(image->blob->semaphore);
600 image->blob->reference_count--;
601 assert(image->blob->reference_count >= 0);
602 if (image->blob->reference_count == 0)
604 (void) UnlockSemaphoreInfo(image->blob->semaphore);
605 if (destroy == MagickFalse)
607 (void) CloseBlob(image);
608 if (image->blob->mapped != MagickFalse)
609 (void) UnmapBlob(image->blob->data,image->blob->length);
610 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
611 DestroySemaphoreInfo(&image->blob->semaphore);
612 image->blob->signature=(~MagickSignature);
613 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
621 + D e t a c h B l o b %
625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
627 % DetachBlob() detaches a blob from the BlobInfo structure.
629 % The format of the DetachBlob method is:
631 % unsigned char *DetachBlob(BlobInfo *blob_info)
633 % A description of each parameter follows:
635 % o blob_info: Specifies a pointer to a BlobInfo structure.
638 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
643 assert(blob_info != (BlobInfo *) NULL);
644 if (blob_info->debug != MagickFalse)
645 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
646 if (blob_info->mapped != MagickFalse)
647 (void) UnmapBlob(blob_info->data,blob_info->length);
648 blob_info->mapped=MagickFalse;
651 blob_info->eof=MagickFalse;
652 blob_info->exempt=MagickFalse;
653 blob_info->type=UndefinedStream;
654 blob_info->file=(FILE *) NULL;
655 data=blob_info->data;
656 blob_info->data=(unsigned char *) NULL;
657 blob_info->stream=(StreamHandler) NULL;
662 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
666 + D u p l i c a t e s B l o b %
670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 % DuplicateBlob() duplicates a blob descriptor.
674 % The format of the DuplicateBlob method is:
676 % void DuplicateBlob(Image *image,const Image *duplicate)
678 % A description of each parameter follows:
680 % o image: the image.
682 % o duplicate: the duplicate image.
685 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
687 assert(image != (Image *) NULL);
688 assert(image->signature == MagickSignature);
689 if (image->debug != MagickFalse)
690 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
691 assert(duplicate != (Image *) NULL);
692 assert(duplicate->signature == MagickSignature);
694 image->blob=ReferenceBlob(duplicate->blob);
698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708 % EOFBlob() returns a non-zero value when EOF has been detected reading from
711 % The format of the EOFBlob method is:
713 % int EOFBlob(const Image *image)
715 % A description of each parameter follows:
717 % o image: the image.
720 MagickExport int EOFBlob(const Image *image)
722 assert(image != (Image *) NULL);
723 assert(image->signature == MagickSignature);
724 if (image->debug != MagickFalse)
725 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
726 assert(image->blob != (BlobInfo *) NULL);
727 assert(image->blob->type != UndefinedStream);
728 switch (image->blob->type)
730 case UndefinedStream:
736 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
741 image->blob->eof=MagickFalse;
746 #if defined(MAGICKCORE_BZLIB_DELEGATE)
751 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
752 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
758 image->blob->eof=MagickFalse;
764 return((int) image->blob->eof);
768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
772 + F i l e T o B l o b %
776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
778 % FileToBlob() returns the contents of a file as a blob. It returns the
779 % file as a blob and its length. If an error occurs, NULL is returned.
781 % The format of the FileToBlob method is:
783 % unsigned char *FileToBlob(const char *filename,const size_t extent,
784 % size_t *length,ExceptionInfo *exception)
786 % A description of each parameter follows:
788 % o blob: FileToBlob() returns the contents of a file as a blob. If
789 % an error occurs NULL is returned.
791 % o filename: the filename.
793 % o extent: The maximum length of the blob.
795 % o length: On return, this reflects the actual length of the blob.
797 % o exception: return any errors or warnings in this structure.
800 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
801 size_t *length,ExceptionInfo *exception)
821 assert(filename != (const char *) NULL);
822 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
823 assert(exception != (ExceptionInfo *) NULL);
826 if (LocaleCompare(filename,"-") != 0)
827 file=open(filename,O_RDONLY | O_BINARY);
830 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
831 return((unsigned char *) NULL);
833 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
835 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
844 Stream is not seekable.
846 quantum=(size_t) MagickMaxBufferExtent;
847 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
848 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
849 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
850 for (i=0; blob != (unsigned char *) NULL; i+=count)
852 count=(ssize_t) read(file,blob+i,quantum);
859 if (~(1UL*i) < (quantum+1))
861 blob=(unsigned char *) RelinquishMagickMemory(blob);
864 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
866 if ((size_t) (i+count) >= extent)
870 if (blob == (unsigned char *) NULL)
872 (void) ThrowMagickException(exception,GetMagickModule(),
873 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
874 return((unsigned char *) NULL);
876 *length=MagickMin(i+count,extent);
880 *length=MagickMin((size_t) offset,extent);
881 blob=(unsigned char *) NULL;
882 if (~(*length) >= MaxTextExtent)
883 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
885 if (blob == (unsigned char *) NULL)
888 (void) ThrowMagickException(exception,GetMagickModule(),
889 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
890 return((unsigned char *) NULL);
892 map=MapBlob(file,ReadMode,0,*length);
893 if (map != (unsigned char *) NULL)
895 (void) CopyMagickMemory(blob,map,*length);
896 (void) UnmapBlob(map,*length);
900 (void) MagickSeek(file,0,SEEK_SET);
901 for (i=0; i < *length; i+=count)
903 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
915 blob=(unsigned char *) RelinquishMagickMemory(blob);
916 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
917 return((unsigned char *) NULL);
926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
930 % F i l e T o I m a g e %
934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
936 % FileToImage() write the contents of a file to an image.
938 % The format of the FileToImage method is:
940 % MagickBooleanType FileToImage(Image *,const char *filename)
942 % A description of each parameter follows:
944 % o image: the image.
946 % o filename: the filename.
950 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
951 const unsigned char *data)
956 register unsigned char
959 assert(image->blob != (BlobInfo *) NULL);
960 if (image->blob->type != BlobStream)
961 return(WriteBlob(image,length,data));
962 assert(image->blob->type != UndefinedStream);
963 assert(data != (void *) NULL);
964 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
965 if (extent >= image->blob->extent)
967 image->blob->quantum<<=1;
968 extent=image->blob->extent+image->blob->quantum+length;
969 if (SetBlobExtent(image,extent) == MagickFalse)
972 q=image->blob->data+image->blob->offset;
973 (void) CopyMagickMemory(q,data,length);
974 image->blob->offset+=length;
975 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
976 image->blob->length=(size_t) image->blob->offset;
977 return((ssize_t) length);
980 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
998 assert(image != (const Image *) NULL);
999 assert(image->signature == MagickSignature);
1000 assert(filename != (const char *) NULL);
1001 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1002 file=open(filename,O_RDONLY | O_BINARY);
1005 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1007 return(MagickFalse);
1009 quantum=(size_t) MagickMaxBufferExtent;
1010 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1011 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1012 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1013 if (blob == (unsigned char *) NULL)
1015 ThrowFileException(&image->exception,ResourceLimitError,
1016 "MemoryAllocationFailed",filename);
1017 return(MagickFalse);
1021 count=(ssize_t) read(file,blob,quantum);
1028 length=(size_t) count;
1029 count=WriteBlobStream(image,length,blob);
1030 if (count != (ssize_t) length)
1032 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1038 blob=(unsigned char *) RelinquishMagickMemory(blob);
1043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1047 + G e t B l o b E r r o r %
1051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1053 % GetBlobError() returns MagickTrue if the blob associated with the specified
1054 % image encountered an error.
1056 % The format of the GetBlobError method is:
1058 % MagickBooleanType GetBlobError(const Image *image)
1060 % A description of each parameter follows:
1062 % o image: the image.
1065 MagickExport MagickBooleanType GetBlobError(const Image *image)
1067 assert(image != (const Image *) NULL);
1068 assert(image->signature == MagickSignature);
1069 if (image->debug != MagickFalse)
1070 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1071 return(image->blob->status);
1075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 + G e t B l o b F i l e H a n d l e %
1083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1085 % GetBlobFileHandle() returns the file handle associated with the image blob.
1087 % The format of the GetBlobFile method is:
1089 % FILE *GetBlobFileHandle(const Image *image)
1091 % A description of each parameter follows:
1093 % o image: the image.
1096 MagickExport FILE *GetBlobFileHandle(const Image *image)
1098 assert(image != (const Image *) NULL);
1099 assert(image->signature == MagickSignature);
1100 return(image->blob->file);
1104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1108 + G e t B l o b I n f o %
1112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1114 % GetBlobInfo() initializes the BlobInfo structure.
1116 % The format of the GetBlobInfo method is:
1118 % void GetBlobInfo(BlobInfo *blob_info)
1120 % A description of each parameter follows:
1122 % o blob_info: Specifies a pointer to a BlobInfo structure.
1125 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1127 assert(blob_info != (BlobInfo *) NULL);
1128 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1129 blob_info->type=UndefinedStream;
1130 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1131 blob_info->properties.st_mtime=time((time_t *) NULL);
1132 blob_info->properties.st_ctime=time((time_t *) NULL);
1133 blob_info->debug=IsEventLogging();
1134 blob_info->reference_count=1;
1135 blob_info->semaphore=AllocateSemaphoreInfo();
1136 blob_info->signature=MagickSignature;
1140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1144 % G e t B l o b P r o p e r t i e s %
1148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1150 % GetBlobProperties() returns information about an image blob.
1152 % The format of the GetBlobProperties method is:
1154 % const struct stat *GetBlobProperties(const Image *image)
1156 % A description of each parameter follows:
1158 % o image: the image.
1161 MagickExport const struct stat *GetBlobProperties(const Image *image)
1163 assert(image != (Image *) NULL);
1164 assert(image->signature == MagickSignature);
1165 if (image->debug != MagickFalse)
1166 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1167 return(&image->blob->properties);
1171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1175 + G e t B l o b S i z e %
1179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1181 % GetBlobSize() returns the current length of the image file or blob; zero is
1182 % returned if the size cannot be determined.
1184 % The format of the GetBlobSize method is:
1186 % MagickSizeType GetBlobSize(const Image *image)
1188 % A description of each parameter follows:
1190 % o image: the image.
1193 MagickExport MagickSizeType GetBlobSize(const Image *image)
1198 assert(image != (Image *) NULL);
1199 assert(image->signature == MagickSignature);
1200 if (image->debug != MagickFalse)
1201 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1202 assert(image->blob != (BlobInfo *) NULL);
1204 switch (image->blob->type)
1206 case UndefinedStream:
1208 length=image->blob->size;
1213 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1214 length=(MagickSizeType) image->blob->properties.st_size;
1217 case StandardStream:
1220 length=image->blob->size;
1229 status=GetPathAttributes(image->filename,&image->blob->properties);
1230 if (status != MagickFalse)
1231 length=(MagickSizeType) image->blob->properties.st_size;
1238 length=(MagickSizeType) image->blob->length;
1246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1250 + G e t B l o b S t r e a m D a t a %
1254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1256 % GetBlobStreamData() returns the stream data for the image.
1258 % The format of the GetBlobStreamData method is:
1260 % unsigned char *GetBlobStreamData(const Image *image)
1262 % A description of each parameter follows:
1264 % o image: the image.
1267 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1269 assert(image != (const Image *) NULL);
1270 assert(image->signature == MagickSignature);
1271 return(image->blob->data);
1275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1279 + G e t B l o b S t r e a m H a n d l e r %
1283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1285 % GetBlobStreamHandler() returns the stream handler for the image.
1287 % The format of the GetBlobStreamHandler method is:
1289 % StreamHandler GetBlobStreamHandler(const Image *image)
1291 % A description of each parameter follows:
1293 % o image: the image.
1296 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1298 assert(image != (const Image *) NULL);
1299 assert(image->signature == MagickSignature);
1300 if (image->debug != MagickFalse)
1301 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1302 return(image->blob->stream);
1306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1310 % I m a g e T o B l o b %
1314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1316 % ImageToBlob() implements direct to memory image formats. It returns the
1317 % image as a blob and its length. The magick member of the ImageInfo structure
1318 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1320 % The format of the ImageToBlob method is:
1322 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1323 % size_t *length,ExceptionInfo *exception)
1325 % A description of each parameter follows:
1327 % o image_info: the image info.
1329 % o image: the image.
1331 % o length: This pointer to a size_t integer sets the initial length of the
1332 % blob. On return, it reflects the actual length of the blob.
1334 % o exception: return any errors or warnings in this structure.
1337 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1338 Image *image,size_t *length,ExceptionInfo *exception)
1352 assert(image_info != (const ImageInfo *) NULL);
1353 assert(image_info->signature == MagickSignature);
1354 if (image_info->debug != MagickFalse)
1355 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1356 image_info->filename);
1357 assert(image != (Image *) NULL);
1358 assert(image->signature == MagickSignature);
1359 assert(exception != (ExceptionInfo *) NULL);
1361 blob=(unsigned char *) NULL;
1362 blob_info=CloneImageInfo(image_info);
1363 blob_info->adjoin=MagickFalse;
1364 (void) SetImageInfo(blob_info,MagickTrue,exception);
1365 if (*blob_info->magick != '\0')
1366 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1367 magick_info=GetMagickInfo(image->magick,exception);
1368 if (magick_info == (const MagickInfo *) NULL)
1370 (void) ThrowMagickException(exception,GetMagickModule(),
1371 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1375 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1376 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1379 Native blob support for this image format.
1381 blob_info->length=0;
1382 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1383 sizeof(unsigned char));
1384 if (blob_info->blob == (void *) NULL)
1385 (void) ThrowMagickException(exception,GetMagickModule(),
1386 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1389 (void) CloseBlob(image);
1390 image->blob->exempt=MagickTrue;
1391 *image->filename='\0';
1392 status=WriteImage(blob_info,image);
1393 if ((status == MagickFalse) || (image->blob->length == 0))
1394 InheritException(exception,&image->exception);
1397 *length=image->blob->length;
1398 blob=DetachBlob(image->blob);
1399 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1407 unique[MaxTextExtent];
1413 Write file to disk in blob image format.
1415 file=AcquireUniqueFileResource(unique);
1418 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1419 image_info->filename);
1423 blob_info->file=fdopen(file,"wb");
1424 if (blob_info->file != (FILE *) NULL)
1426 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1427 image->magick,unique);
1428 status=WriteImage(blob_info,image);
1429 (void) fclose(blob_info->file);
1430 if (status == MagickFalse)
1431 InheritException(exception,&image->exception);
1433 blob=FileToBlob(image->filename,~0UL,length,exception);
1435 (void) RelinquishUniqueFileResource(unique);
1438 blob_info=DestroyImageInfo(blob_info);
1443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1447 % I m a g e T o F i l e %
1451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1453 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1454 % occurs otherwise MagickTrue.
1456 % The format of the ImageToFile method is:
1458 % MagickBooleanType ImageToFile(Image *image,char *filename,
1459 % ExceptionInfo *exception)
1461 % A description of each parameter follows:
1463 % o image: the image.
1465 % o filename: Write the image to this file.
1467 % o exception: return any errors or warnings in this structure.
1471 static inline const unsigned char *ReadBlobStream(Image *image,
1472 const size_t length,unsigned char *data,ssize_t *count)
1474 assert(count != (ssize_t *) NULL);
1475 assert(image->blob != (BlobInfo *) NULL);
1476 if (image->blob->type != BlobStream)
1478 *count=ReadBlob(image,length,data);
1481 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1484 image->blob->eof=MagickTrue;
1487 data=image->blob->data+image->blob->offset;
1488 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
1489 image->blob->offset));
1490 image->blob->offset+=(*count);
1491 if (*count != (ssize_t) length)
1492 image->blob->eof=MagickTrue;
1496 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1497 ExceptionInfo *exception)
1502 register const unsigned char
1521 assert(image != (Image *) NULL);
1522 assert(image->signature == MagickSignature);
1523 assert(image->blob != (BlobInfo *) NULL);
1524 assert(image->blob->type != UndefinedStream);
1525 if (image->debug != MagickFalse)
1526 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1527 assert(filename != (const char *) NULL);
1528 if (*filename == '\0')
1529 file=AcquireUniqueFileResource(filename);
1531 if (LocaleCompare(filename,"-") == 0)
1532 file=fileno(stdout);
1534 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1537 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1538 return(MagickFalse);
1540 quantum=(size_t) MagickMaxBufferExtent;
1541 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1542 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1543 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1544 if (buffer == (unsigned char *) NULL)
1547 (void) ThrowMagickException(exception,GetMagickModule(),
1548 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1549 return(MagickFalse);
1552 p=ReadBlobStream(image,quantum,buffer,&count);
1553 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1555 length=(size_t) count;
1556 for (i=0; i < length; i+=count)
1558 count=write(file,p+i,(size_t) (length-i));
1570 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1573 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1574 return(MagickFalse);
1580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1584 % I m a g e s T o B l o b %
1588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1590 % ImagesToBlob() implements direct to memory image formats. It returns the
1591 % image sequence as a blob and its length. The magick member of the ImageInfo
1592 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1594 % Note, some image formats do not permit multiple images to the same image
1595 % stream (e.g. JPEG). in this instance, just the first image of the
1596 % sequence is returned as a blob.
1598 % The format of the ImagesToBlob method is:
1600 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1601 % size_t *length,ExceptionInfo *exception)
1603 % A description of each parameter follows:
1605 % o image_info: the image info.
1607 % o images: the image list.
1609 % o length: This pointer to a size_t integer sets the initial length of the
1610 % blob. On return, it reflects the actual length of the blob.
1612 % o exception: return any errors or warnings in this structure.
1615 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1616 Image *images,size_t *length,ExceptionInfo *exception)
1630 assert(image_info != (const ImageInfo *) NULL);
1631 assert(image_info->signature == MagickSignature);
1632 if (image_info->debug != MagickFalse)
1633 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1634 image_info->filename);
1635 assert(images != (Image *) NULL);
1636 assert(images->signature == MagickSignature);
1637 assert(exception != (ExceptionInfo *) NULL);
1639 blob=(unsigned char *) NULL;
1640 blob_info=CloneImageInfo(image_info);
1641 (void) SetImageInfo(blob_info,MagickTrue,exception);
1642 if (*blob_info->magick != '\0')
1643 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1644 if (blob_info->adjoin == MagickFalse)
1646 blob_info=DestroyImageInfo(blob_info);
1647 return(ImageToBlob(image_info,images,length,exception));
1649 magick_info=GetMagickInfo(images->magick,exception);
1650 if (magick_info == (const MagickInfo *) NULL)
1652 (void) ThrowMagickException(exception,GetMagickModule(),
1653 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1657 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1658 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1661 Native blob support for this images format.
1663 blob_info->length=0;
1664 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1665 sizeof(unsigned char));
1666 if (blob_info->blob == (void *) NULL)
1667 (void) ThrowMagickException(exception,GetMagickModule(),
1668 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1671 images->blob->exempt=MagickTrue;
1672 *images->filename='\0';
1673 status=WriteImages(blob_info,images,images->filename,exception);
1674 if ((status == MagickFalse) || (images->blob->length == 0))
1675 InheritException(exception,&images->exception);
1678 *length=images->blob->length;
1679 blob=DetachBlob(images->blob);
1680 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1688 filename[MaxTextExtent],
1689 unique[MaxTextExtent];
1695 Write file to disk in blob images format.
1697 file=AcquireUniqueFileResource(unique);
1700 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1701 image_info->filename);
1705 blob_info->file=fdopen(file,"wb");
1706 if (blob_info->file != (FILE *) NULL)
1708 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1709 images->magick,unique);
1710 status=WriteImages(blob_info,images,filename,exception);
1711 (void) fclose(blob_info->file);
1712 if (status == MagickFalse)
1713 InheritException(exception,&images->exception);
1715 blob=FileToBlob(images->filename,~0UL,length,exception);
1717 (void) RelinquishUniqueFileResource(unique);
1720 blob_info=DestroyImageInfo(blob_info);
1724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1728 % I n j e c t I m a g e B l o b %
1732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1734 % InjectImageBlob() injects the image with a copy of itself in the specified
1735 % format (e.g. inject JPEG into a PDF image).
1737 % The format of the InjectImageBlob method is:
1739 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1740 % Image *image,Image *inject_image,const char *format,
1741 % ExceptionInfo *exception)
1743 % A description of each parameter follows:
1745 % o image_info: the image info..
1747 % o image: the image.
1749 % o inject_image: inject into the image stream.
1751 % o format: the image format.
1753 % o exception: return any errors or warnings in this structure.
1756 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1757 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1760 filename[MaxTextExtent];
1793 Write inject image to a temporary file.
1795 assert(image_info != (ImageInfo *) NULL);
1796 assert(image_info->signature == MagickSignature);
1797 assert(image != (Image *) NULL);
1798 assert(image->signature == MagickSignature);
1799 if (image->debug != MagickFalse)
1800 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1801 assert(inject_image != (Image *) NULL);
1802 assert(inject_image->signature == MagickSignature);
1803 assert(exception != (ExceptionInfo *) NULL);
1804 unique_file=(FILE *) NULL;
1805 file=AcquireUniqueFileResource(filename);
1807 unique_file=fdopen(file,"wb");
1808 if ((file == -1) || (unique_file == (FILE *) NULL))
1810 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1811 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1813 return(MagickFalse);
1815 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1816 if (byte_image == (Image *) NULL)
1818 (void) fclose(unique_file);
1819 (void) RelinquishUniqueFileResource(filename);
1820 return(MagickFalse);
1822 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1824 DestroyBlob(byte_image);
1825 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1826 write_info=CloneImageInfo(image_info);
1827 SetImageInfoFile(write_info,unique_file);
1828 status=WriteImage(write_info,byte_image);
1829 write_info=DestroyImageInfo(write_info);
1830 byte_image=DestroyImage(byte_image);
1831 (void) fclose(unique_file);
1832 if (status == MagickFalse)
1834 (void) RelinquishUniqueFileResource(filename);
1835 return(MagickFalse);
1838 Inject into image stream.
1840 file=open(filename,O_RDONLY | O_BINARY);
1843 (void) RelinquishUniqueFileResource(filename);
1844 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1845 image_info->filename);
1846 return(MagickFalse);
1848 quantum=(size_t) MagickMaxBufferExtent;
1849 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1850 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1851 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1852 if (buffer == (unsigned char *) NULL)
1854 (void) RelinquishUniqueFileResource(filename);
1855 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1858 for (i=0; ; i+=count)
1860 count=(ssize_t) read(file,buffer,quantum);
1867 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1871 (void) RelinquishUniqueFileResource(filename);
1872 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1881 + I s B l o b E x e m p t %
1885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1887 % IsBlobExempt() returns true if the blob is exempt.
1889 % The format of the IsBlobExempt method is:
1891 % MagickBooleanType IsBlobExempt(const Image *image)
1893 % A description of each parameter follows:
1895 % o image: the image.
1898 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1900 assert(image != (const Image *) NULL);
1901 assert(image->signature == MagickSignature);
1902 if (image->debug != MagickFalse)
1903 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1904 return(image->blob->exempt);
1908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1912 + I s B l o b S e e k a b l e %
1916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1918 % IsBlobSeekable() returns true if the blob is seekable.
1920 % The format of the IsBlobSeekable method is:
1922 % MagickBooleanType IsBlobSeekable(const Image *image)
1924 % A description of each parameter follows:
1926 % o image: the image.
1929 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
1934 assert(image != (const Image *) NULL);
1935 assert(image->signature == MagickSignature);
1936 if (image->debug != MagickFalse)
1937 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1938 seekable=(image->blob->type == FileStream) ||
1939 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
1944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1948 + I s B l o b T e m p o r a r y %
1952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1954 % IsBlobTemporary() returns true if the blob is temporary.
1956 % The format of the IsBlobTemporary method is:
1958 % MagickBooleanType IsBlobTemporary(const Image *image)
1960 % A description of each parameter follows:
1962 % o image: the image.
1965 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
1967 assert(image != (const Image *) NULL);
1968 assert(image->signature == MagickSignature);
1969 if (image->debug != MagickFalse)
1970 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1971 return(image->blob->temporary);
1975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1985 % MapBlob() creates a mapping from a file to a binary large object.
1987 % The format of the MapBlob method is:
1989 % unsigned char *MapBlob(int file,const MapMode mode,
1990 % const MagickOffsetType offset,const size_t length)
1992 % A description of each parameter follows:
1994 % o file: map this file descriptor.
1996 % o mode: ReadMode, WriteMode, or IOMode.
1998 % o offset: starting at this offset within the file.
2000 % o length: the length of the mapping is returned in this pointer.
2003 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2004 const MagickOffsetType offset,const size_t length)
2006 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2019 #if defined(MAP_ANONYMOUS)
2020 flags|=MAP_ANONYMOUS;
2022 return((unsigned char *) NULL);
2029 protection=PROT_READ;
2031 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2037 protection=PROT_WRITE;
2039 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2045 protection=PROT_READ | PROT_WRITE;
2047 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2052 if (map == (unsigned char *) MAP_FAILED)
2053 return((unsigned char *) NULL);
2060 return((unsigned char *) NULL);
2065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2069 + M S B O r d e r L o n g %
2073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2075 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2076 % most-significant byte first.
2078 % The format of the MSBOrderLong method is:
2080 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2082 % A description of each parameter follows.
2084 % o buffer: Specifies a pointer to a buffer of integers.
2086 % o length: Specifies the length of the buffer.
2089 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2094 register unsigned char
2098 assert(buffer != (unsigned char *) NULL);
2105 *buffer++=(unsigned char) c;
2109 *buffer++=(unsigned char) c;
2115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2119 + M S B O r d e r S h o r t %
2123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2125 % MSBOrderShort() converts a least-significant byte first buffer of integers
2126 % to most-significant byte first.
2128 % The format of the MSBOrderShort method is:
2130 % void MSBOrderShort(unsigned char *p,const size_t length)
2132 % A description of each parameter follows.
2134 % o p: Specifies a pointer to a buffer of integers.
2136 % o length: Specifies the length of the buffer.
2139 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2144 register unsigned char
2147 assert(p != (unsigned char *) NULL);
2154 *p++=(unsigned char) c;
2159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2169 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2170 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2171 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2172 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2173 % from a system command.
2175 % The format of the OpenBlob method is:
2177 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2178 % const BlobMode mode,ExceptionInfo *exception)
2180 % A description of each parameter follows:
2182 % o image_info: the image info.
2184 % o image: the image.
2186 % o mode: the mode for opening the file.
2189 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2190 Image *image,const BlobMode mode,ExceptionInfo *exception)
2193 filename[MaxTextExtent];
2204 assert(image_info != (ImageInfo *) NULL);
2205 assert(image_info->signature == MagickSignature);
2206 if (image_info->debug != MagickFalse)
2207 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2208 image_info->filename);
2209 assert(image != (Image *) NULL);
2210 assert(image->signature == MagickSignature);
2211 if (image_info->blob != (void *) NULL)
2213 if (image_info->stream != (StreamHandler) NULL)
2214 image->blob->stream=(StreamHandler) image_info->stream;
2215 AttachBlob(image->blob,image_info->blob,image_info->length);
2218 (void) DetachBlob(image->blob);
2221 default: type="r"; break;
2222 case ReadBlobMode: type="r"; break;
2223 case ReadBinaryBlobMode: type="rb"; break;
2224 case WriteBlobMode: type="w"; break;
2225 case WriteBinaryBlobMode: type="w+b"; break;
2226 case AppendBlobMode: type="a"; break;
2227 case AppendBinaryBlobMode: type="a+b"; break;
2230 image->blob->synchronize=image_info->synchronize;
2231 if (image_info->stream != (StreamHandler) NULL)
2233 image->blob->stream=(StreamHandler) image_info->stream;
2236 image->blob->type=FifoStream;
2244 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2245 rights=ReadPolicyRights;
2247 rights=WritePolicyRights;
2248 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2250 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2251 "NotAuthorized","`%s'",filename);
2252 return(MagickFalse);
2254 if ((LocaleCompare(filename,"-") == 0) ||
2255 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2257 image->blob->file=(*type == 'r') ? stdin : stdout;
2258 #if defined(__WINDOWS__) || defined(__OS2__)
2259 if (strchr(type,'b') != (char *) NULL)
2260 setmode(_fileno(image->blob->file),_O_BINARY);
2262 image->blob->type=StandardStream;
2263 image->blob->exempt=MagickTrue;
2266 if (LocaleNCompare(filename,"fd:",3) == 0)
2269 mode[MaxTextExtent];
2273 image->blob->file=fdopen(StringToLong(filename+3),mode);
2274 #if defined(__WINDOWS__) || defined(__OS2__)
2275 if (strchr(type,'b') != (char *) NULL)
2276 setmode(_fileno(image->blob->file),_O_BINARY);
2278 image->blob->type=StandardStream;
2279 image->blob->exempt=MagickTrue;
2282 #if defined(MAGICKCORE_HAVE_POPEN)
2283 if (*filename == '|')
2286 mode[MaxTextExtent];
2289 Pipe image to or from a system command.
2291 #if defined(SIGPIPE)
2293 (void) signal(SIGPIPE,SIG_IGN);
2297 image->blob->file=(FILE *) popen(filename+1,mode);
2298 if (image->blob->file == (FILE *) NULL)
2300 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2301 return(MagickFalse);
2303 image->blob->type=PipeStream;
2304 image->blob->exempt=MagickTrue;
2308 status=GetPathAttributes(filename,&image->blob->properties);
2309 #if defined(S_ISFIFO)
2310 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2312 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2313 if (image->blob->file == (FILE *) NULL)
2315 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2316 return(MagickFalse);
2318 image->blob->type=FileStream;
2319 image->blob->exempt=MagickTrue;
2326 Form filename for multi-part images.
2328 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2329 image->scene,filename);
2330 if (image_info->adjoin == MagickFalse)
2331 if ((image->previous != (Image *) NULL) ||
2332 (GetNextImageInList(image) != (Image *) NULL))
2334 if (LocaleCompare(filename,image->filename) == 0)
2337 extension[MaxTextExtent],
2338 path[MaxTextExtent];
2340 GetPathComponent(image->filename,RootPath,path);
2341 GetPathComponent(image->filename,ExtensionPath,extension);
2342 if (*extension == '\0')
2343 (void) FormatMagickString(filename,MaxTextExtent,"%s-%lu",
2346 (void) FormatMagickString(filename,MaxTextExtent,"%s-%lu.%s",
2347 path,image->scene,extension);
2350 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2351 #if defined(macintosh)
2352 SetApplicationType(filename,image_info->magick,'8BIM');
2355 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2356 if (((strlen(filename) > 2) &&
2357 (LocaleCompare(filename+strlen(filename)-2,".Z") == 0)) ||
2358 ((strlen(filename) > 3) &&
2359 (LocaleCompare(filename+strlen(filename)-3,".gz") == 0)) ||
2360 ((strlen(filename) > 4) &&
2361 (LocaleCompare(filename+strlen(filename)-4,".wmz") == 0)) ||
2362 ((strlen(filename) > 5) &&
2363 (LocaleCompare(filename+strlen(filename)-5,".svgz") == 0)))
2365 image->blob->file=(FILE *) gzopen(filename,type);
2366 if (image->blob->file != (FILE *) NULL)
2367 image->blob->type=ZipStream;
2371 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2372 if ((strlen(filename) > 4) &&
2373 (LocaleCompare(filename+strlen(filename)-4,".bz2") == 0))
2375 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2376 if (image->blob->file != (FILE *) NULL)
2377 image->blob->type=BZipStream;
2381 if (image_info->file != (FILE *) NULL)
2383 image->blob->file=image_info->file;
2384 image->blob->type=FileStream;
2385 image->blob->exempt=MagickTrue;
2389 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2390 if (image->blob->file != (FILE *) NULL)
2392 image->blob->type=FileStream;
2393 #if defined(MAGICKCORE_HAVE_SETVBUF)
2394 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2405 (void) ResetMagickMemory(magick,0,sizeof(magick));
2406 count=fread(magick,1,sizeof(magick),image->blob->file);
2407 (void) rewind(image->blob->file);
2408 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2409 " read %ld magic header bytes",(long) count);
2410 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2411 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2412 ((int) magick[2] == 0x08))
2414 (void) fclose(image->blob->file);
2415 image->blob->file=(FILE *) gzopen(filename,type);
2416 if (image->blob->file != (FILE *) NULL)
2417 image->blob->type=ZipStream;
2420 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2421 if (strncmp((char *) magick,"BZh",3) == 0)
2423 (void) fclose(image->blob->file);
2424 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2425 if (image->blob->file != (FILE *) NULL)
2426 image->blob->type=BZipStream;
2432 if ((image->blob->type == FileStream) && (*type == 'r'))
2443 sans_exception=AcquireExceptionInfo();
2444 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2445 sans_exception=DestroyExceptionInfo(sans_exception);
2446 properties=(&image->blob->properties);
2447 if ((magick_info != (const MagickInfo *) NULL) &&
2448 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2449 (properties->st_size <= MagickMaxBufferExtent))
2457 length=(size_t) properties->st_size;
2458 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2459 if (blob != (void *) NULL)
2462 Format supports blobs-- use memory-mapped I/O.
2464 if (image_info->file != (FILE *) NULL)
2465 image->blob->exempt=MagickFalse;
2468 (void) fclose(image->blob->file);
2469 image->blob->file=(FILE *) NULL;
2471 AttachBlob(image->blob,blob,length);
2472 image->blob->mapped=MagickTrue;
2476 image->blob->status=MagickFalse;
2477 if (image->blob->type != UndefinedStream)
2478 image->blob->size=GetBlobSize(image);
2481 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2482 return(MagickFalse);
2488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2498 % PingBlob() returns all the attributes of an image or image sequence except
2499 % for the pixels. It is much faster and consumes far less memory than
2500 % BlobToImage(). On failure, a NULL image is returned and exception
2501 % describes the reason for the failure.
2503 % The format of the PingBlob method is:
2505 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2506 % const size_t length,ExceptionInfo *exception)
2508 % A description of each parameter follows:
2510 % o image_info: the image info.
2512 % o blob: the address of a character stream in one of the image formats
2513 % understood by ImageMagick.
2515 % o length: This size_t integer reflects the length in bytes of the blob.
2517 % o exception: return any errors or warnings in this structure.
2521 #if defined(__cplusplus) || defined(c_plusplus)
2525 static size_t PingStream(const Image *magick_unused(image),
2526 const void *magick_unused(pixels),const size_t columns)
2531 #if defined(__cplusplus) || defined(c_plusplus)
2535 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2536 const size_t length,ExceptionInfo *exception)
2544 assert(image_info != (ImageInfo *) NULL);
2545 assert(image_info->signature == MagickSignature);
2546 if (image_info->debug != MagickFalse)
2547 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2548 image_info->filename);
2549 assert(exception != (ExceptionInfo *) NULL);
2550 if ((blob == (const void *) NULL) || (length == 0))
2552 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2553 "UnrecognizedImageFormat","`%s'",image_info->magick);
2554 return((Image *) NULL);
2556 ping_info=CloneImageInfo(image_info);
2557 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2558 if (ping_info->blob == (const void *) NULL)
2560 (void) ThrowMagickException(exception,GetMagickModule(),
2561 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2562 return((Image *) NULL);
2564 (void) CopyMagickMemory(ping_info->blob,blob,length);
2565 ping_info->length=length;
2566 ping_info->ping=MagickTrue;
2567 image=ReadStream(ping_info,&PingStream,exception);
2568 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2569 ping_info=DestroyImageInfo(ping_info);
2574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2584 % ReadBlob() reads data from the blob or image file and returns it. It
2585 % returns the number of bytes read.
2587 % The format of the ReadBlob method is:
2589 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2591 % A description of each parameter follows:
2593 % o image: the image.
2595 % o length: Specifies an integer representing the number of bytes to read
2598 % o data: Specifies an area to place the information requested from the
2602 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2603 unsigned char *data)
2608 register unsigned char
2614 assert(image != (Image *) NULL);
2615 assert(image->signature == MagickSignature);
2616 assert(image->blob != (BlobInfo *) NULL);
2617 assert(image->blob->type != UndefinedStream);
2620 assert(data != (void *) NULL);
2623 switch (image->blob->type)
2625 case UndefinedStream:
2628 case StandardStream:
2635 count=(ssize_t) fread(q,1,length,image->blob->file);
2640 c=getc(image->blob->file);
2643 *q++=(unsigned char) c;
2648 c=getc(image->blob->file);
2651 *q++=(unsigned char) c;
2661 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2666 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2671 c=gzgetc(image->blob->file);
2674 *q++=(unsigned char) c;
2679 c=gzgetc(image->blob->file);
2682 *q++=(unsigned char) c;
2693 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2694 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2702 register const unsigned char
2705 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2707 image->blob->eof=MagickTrue;
2710 p=image->blob->data+image->blob->offset;
2711 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2712 image->blob->offset));
2713 image->blob->offset+=count;
2714 if (count != (ssize_t) length)
2715 image->blob->eof=MagickTrue;
2716 (void) CopyMagickMemory(q,p,(size_t) count);
2724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2728 + R e a d B l o b B y t e %
2732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2734 % ReadBlobByte() reads a single byte from the image file and returns it.
2736 % The format of the ReadBlobByte method is:
2738 % int ReadBlobByte(Image *image)
2740 % A description of each parameter follows.
2742 % o image: the image.
2745 MagickExport int ReadBlobByte(Image *image)
2747 register const unsigned char
2756 assert(image != (Image *) NULL);
2757 assert(image->signature == MagickSignature);
2758 p=ReadBlobStream(image,1,buffer,&count);
2765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2769 + R e a d B l o b D o u b l e %
2773 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2775 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2776 % specified by the endian member of the image structure.
2778 % The format of the ReadBlobDouble method is:
2780 % double ReadBlobDouble(Image *image)
2782 % A description of each parameter follows.
2784 % o image: the image.
2787 MagickExport double ReadBlobDouble(Image *image)
2798 quantum.double_value=0.0;
2799 quantum.unsigned_value=ReadBlobLongLong(image);
2800 return(quantum.double_value);
2804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2808 + R e a d B l o b F l o a t %
2812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2814 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2815 % specified by the endian member of the image structure.
2817 % The format of the ReadBlobFloat method is:
2819 % float ReadBlobFloat(Image *image)
2821 % A description of each parameter follows.
2823 % o image: the image.
2826 MagickExport float ReadBlobFloat(Image *image)
2837 quantum.float_value=0.0;
2838 quantum.unsigned_value=ReadBlobLong(image);
2839 return(quantum.float_value);
2843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2847 + R e a d B l o b L o n g %
2851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2853 % ReadBlobLong() reads a long value as a 32-bit quantity in the byte-order
2854 % specified by the endian member of the image structure.
2856 % The format of the ReadBlobLong method is:
2858 % unsigned int ReadBlobLong(Image *image)
2860 % A description of each parameter follows.
2862 % o image: the image.
2865 MagickExport unsigned int ReadBlobLong(Image *image)
2867 register const unsigned char
2879 assert(image != (Image *) NULL);
2880 assert(image->signature == MagickSignature);
2882 p=ReadBlobStream(image,4,buffer,&count);
2885 if (image->endian == LSBEndian)
2887 value=(unsigned int) (*p++);
2888 value|=((unsigned int) (*p++)) << 8;
2889 value|=((unsigned int) (*p++)) << 16;
2890 value|=((unsigned int) (*p++)) << 24;
2893 value=((unsigned int) (*p++)) << 24;
2894 value|=((unsigned int) (*p++)) << 16;
2895 value|=((unsigned int) (*p++)) << 8;
2896 value|=((unsigned int) (*p++));
2901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2905 + R e a d B l o b L o n g L o n g %
2909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2911 % ReadBlobLongLong() reads a long value as a 64-bit quantity in the byte-order
2912 % specified by the endian member of the image structure.
2914 % The format of the ReadBlobLong method is:
2916 % MagickSizeType ReadBlobLong(Image *image)
2918 % A description of each parameter follows.
2920 % o image: the image.
2923 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
2925 register const unsigned char
2937 assert(image != (Image *) NULL);
2938 assert(image->signature == MagickSignature);
2940 p=ReadBlobStream(image,8,buffer,&count);
2942 return(MagickULLConstant(0));
2943 if (image->endian == LSBEndian)
2945 value=(MagickSizeType) (*p++);
2946 value|=((MagickSizeType) (*p++)) << 8;
2947 value|=((MagickSizeType) (*p++)) << 16;
2948 value|=((MagickSizeType) (*p++)) << 24;
2949 value|=((MagickSizeType) (*p++)) << 32;
2950 value|=((MagickSizeType) (*p++)) << 40;
2951 value|=((MagickSizeType) (*p++)) << 48;
2952 value|=((MagickSizeType) (*p++)) << 56;
2953 return(value & MagickULLConstant(0xffffffffffffffff));
2955 value=((MagickSizeType) (*p++)) << 56;
2956 value|=((MagickSizeType) (*p++)) << 48;
2957 value|=((MagickSizeType) (*p++)) << 40;
2958 value|=((MagickSizeType) (*p++)) << 32;
2959 value|=((MagickSizeType) (*p++)) << 24;
2960 value|=((MagickSizeType) (*p++)) << 16;
2961 value|=((MagickSizeType) (*p++)) << 8;
2962 value|=((MagickSizeType) (*p++));
2963 return(value & MagickULLConstant(0xffffffffffffffff));
2967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2971 + R e a d B l o b S h o r t %
2975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2977 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
2978 % specified by the endian member of the image structure.
2980 % The format of the ReadBlobShort method is:
2982 % unsigned short ReadBlobShort(Image *image)
2984 % A description of each parameter follows.
2986 % o image: the image.
2989 MagickExport unsigned short ReadBlobShort(Image *image)
2991 register const unsigned char
2994 register unsigned int
3003 assert(image != (Image *) NULL);
3004 assert(image->signature == MagickSignature);
3006 p=ReadBlobStream(image,2,buffer,&count);
3008 return((unsigned short) 0U);
3009 if (image->endian == LSBEndian)
3011 value=(unsigned int) (*p++);
3012 value|=((unsigned int) (*p++)) << 8;
3013 return((unsigned short) (value & 0xffff));
3015 value=(unsigned int) ((*p++) << 8);
3016 value|=(unsigned int) (*p++);
3017 return((unsigned short) (value & 0xffff));
3021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3025 + R e a d B l o b L S B L o n g %
3029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3031 % ReadBlobLSBLong() reads a long value as a 32-bit quantity in
3032 % least-significant byte first order.
3034 % The format of the ReadBlobLSBLong method is:
3036 % unsigned int ReadBlobLSBLong(Image *image)
3038 % A description of each parameter follows.
3040 % o image: the image.
3043 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3045 register const unsigned char
3048 register unsigned int
3057 assert(image != (Image *) NULL);
3058 assert(image->signature == MagickSignature);
3060 p=ReadBlobStream(image,4,buffer,&count);
3063 value=(unsigned int) (*p++);
3064 value|=((unsigned int) (*p++)) << 8;
3065 value|=((unsigned int) (*p++)) << 16;
3066 value|=((unsigned int) (*p++)) << 24;
3071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3075 + R e a d B l o b L S B S h o r t %
3079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3081 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3082 % least-significant byte first order.
3084 % The format of the ReadBlobLSBShort method is:
3086 % unsigned short ReadBlobLSBShort(Image *image)
3088 % A description of each parameter follows.
3090 % o image: the image.
3093 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3095 register const unsigned char
3098 register unsigned int
3107 assert(image != (Image *) NULL);
3108 assert(image->signature == MagickSignature);
3110 p=ReadBlobStream(image,2,buffer,&count);
3112 return((unsigned short) 0U);
3113 value=(unsigned int) (*p++);
3114 value|=((unsigned int) ((*p++)) << 8);
3115 return((unsigned short) (value & 0xffff));
3119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3123 + R e a d B l o b M S B L o n g %
3127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3129 % ReadBlobMSBLong() reads a long value as a 32-bit quantity in
3130 % most-significant byte first order.
3132 % The format of the ReadBlobMSBLong method is:
3134 % unsigned int ReadBlobMSBLong(Image *image)
3136 % A description of each parameter follows.
3138 % o image: the image.
3141 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3143 register const unsigned char
3146 register unsigned int
3155 assert(image != (Image *) NULL);
3156 assert(image->signature == MagickSignature);
3158 p=ReadBlobStream(image,4,buffer,&count);
3161 value=((unsigned int) (*p++) << 24);
3162 value|=((unsigned int) (*p++) << 16);
3163 value|=((unsigned int) (*p++) << 8);
3164 value|=(unsigned int) (*p++);
3169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3173 + R e a d B l o b M S B S h o r t %
3177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3179 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3180 % most-significant byte first order.
3182 % The format of the ReadBlobMSBShort method is:
3184 % unsigned short ReadBlobMSBShort(Image *image)
3186 % A description of each parameter follows.
3188 % o image: the image.
3191 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3193 register const unsigned char
3196 register unsigned int
3205 assert(image != (Image *) NULL);
3206 assert(image->signature == MagickSignature);
3208 p=ReadBlobStream(image,2,buffer,&count);
3210 return((unsigned short) 0U);
3211 value=(unsigned int) ((*p++) << 8);
3212 value|=(unsigned int) (*p++);
3213 return((unsigned short) (value & 0xffff));
3217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3221 + R e a d B l o b S t r i n g %
3225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3227 % ReadBlobString() reads characters from a blob or file until a newline
3228 % character is read or an end-of-file condition is encountered.
3230 % The format of the ReadBlobString method is:
3232 % char *ReadBlobString(Image *image,char *string)
3234 % A description of each parameter follows:
3236 % o image: the image.
3238 % o string: the address of a character buffer.
3241 MagickExport char *ReadBlobString(Image *image,char *string)
3243 register const unsigned char
3255 assert(image != (Image *) NULL);
3256 assert(image->signature == MagickSignature);
3257 for (i=0; i < (MaxTextExtent-1L); i++)
3259 p=ReadBlobStream(image,1,buffer,&count);
3263 return((char *) NULL);
3266 string[i]=(char) (*p);
3267 if ((string[i] == '\n') || (string[i] == '\r'))
3275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3279 + R e f e r e n c e B l o b %
3283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3285 % ReferenceBlob() increments the reference count associated with the pixel
3286 % blob returning a pointer to the blob.
3288 % The format of the ReferenceBlob method is:
3290 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3292 % A description of each parameter follows:
3294 % o blob_info: the blob_info.
3297 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3299 assert(blob != (BlobInfo *) NULL);
3300 assert(blob->signature == MagickSignature);
3301 if (blob->debug != MagickFalse)
3302 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3303 (void) LockSemaphoreInfo(blob->semaphore);
3304 blob->reference_count++;
3305 (void) UnlockSemaphoreInfo(blob->semaphore);
3310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3320 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3321 % and returns the resulting offset.
3323 % The format of the SeekBlob method is:
3325 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3328 % A description of each parameter follows:
3330 % o image: the image.
3332 % o offset: Specifies an integer representing the offset in bytes.
3334 % o whence: Specifies an integer representing how the offset is
3335 % treated relative to the beginning of the blob as follows:
3337 % SEEK_SET Set position equal to offset bytes.
3338 % SEEK_CUR Set position to current location plus offset.
3339 % SEEK_END Set position to EOF plus offset.
3342 MagickExport MagickOffsetType SeekBlob(Image *image,
3343 const MagickOffsetType offset,const int whence)
3345 assert(image != (Image *) NULL);
3346 assert(image->signature == MagickSignature);
3347 if (image->debug != MagickFalse)
3348 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3349 assert(image->blob != (BlobInfo *) NULL);
3350 assert(image->blob->type != UndefinedStream);
3351 switch (image->blob->type)
3353 case UndefinedStream:
3357 if (fseek(image->blob->file,offset,whence) < 0)
3359 image->blob->offset=TellBlob(image);
3362 case StandardStream:
3366 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3367 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3370 image->blob->offset=TellBlob(image);
3386 image->blob->offset=offset;
3391 if ((image->blob->offset+offset) < 0)
3393 image->blob->offset+=offset;
3398 if (((MagickOffsetType) image->blob->length+offset) < 0)
3400 image->blob->offset=image->blob->length+offset;
3404 if (image->blob->offset <= (MagickOffsetType)
3405 ((off_t) image->blob->length))
3406 image->blob->eof=MagickFalse;
3408 if (image->blob->mapped != MagickFalse)
3412 image->blob->extent=(size_t) (image->blob->offset+
3413 image->blob->quantum);
3414 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3415 image->blob->data,image->blob->extent+1,
3416 sizeof(*image->blob->data));
3417 (void) SyncBlob(image);
3418 if (image->blob->data == (unsigned char *) NULL)
3420 (void) DetachBlob(image->blob);
3427 return(image->blob->offset);
3431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3435 + S e t B l o b E x e m p t %
3439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3441 % SetBlobExempt() sets the blob exempt status.
3443 % The format of the SetBlobExempt method is:
3445 % MagickBooleanType SetBlobExempt(const Image *image,
3446 % const MagickBooleanType exempt)
3448 % A description of each parameter follows:
3450 % o image: the image.
3452 % o exempt: Set to true if this blob is exempt from being closed.
3455 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3457 assert(image != (const Image *) NULL);
3458 assert(image->signature == MagickSignature);
3459 if (image->debug != MagickFalse)
3460 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3461 image->blob->exempt=exempt;
3465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3469 + S e t B l o b E x t e n t %
3473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3475 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3476 % method is successful, subsequent writes to bytes in the specified range are
3477 % guaranteed not to fail.
3479 % The format of the SetBlobExtent method is:
3481 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3483 % A description of each parameter follows:
3485 % o image: the image.
3487 % o extent: the blob maximum extent.
3490 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3491 const MagickSizeType extent)
3493 assert(image != (Image *) NULL);
3494 assert(image->signature == MagickSignature);
3495 if (image->debug != MagickFalse)
3496 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3497 assert(image->blob != (BlobInfo *) NULL);
3498 assert(image->blob->type != UndefinedStream);
3499 switch (image->blob->type)
3501 case UndefinedStream:
3505 if (extent != (MagickSizeType) ((off_t) extent))
3506 return(MagickFalse);
3507 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3508 return(MagickFalse);
3517 offset=TellBlob(image);
3518 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3519 (off_t) (extent-offset));
3521 return(MagickFalse);
3526 case StandardStream:
3529 return(MagickFalse);
3531 return(MagickFalse);
3533 return(MagickFalse);
3536 if (image->blob->mapped != MagickFalse)
3538 if (image->blob->file == (FILE *) NULL)
3539 return(MagickFalse);
3540 (void) UnmapBlob(image->blob->data,image->blob->length);
3541 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3542 return(MagickFalse);
3551 offset=TellBlob(image);
3552 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3553 (off_t) (extent-offset));
3555 return(MagickFalse);
3557 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3558 WriteMode,0,(size_t) extent);
3559 image->blob->extent=(size_t) extent;
3560 image->blob->length=(size_t) extent;
3561 (void) SyncBlob(image);
3565 if (extent != (MagickSizeType) ((size_t) extent))
3566 return(MagickFalse);
3567 image->blob->extent=(size_t) extent;
3568 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3569 image->blob->extent+1,sizeof(*image->blob->data));
3570 (void) SyncBlob(image);
3571 if (image->blob->data == (unsigned char *) NULL)
3573 (void) DetachBlob(image->blob);
3574 return(MagickFalse);
3583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3593 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3594 % attributes if it is an blob.
3596 % The format of the SyncBlob method is:
3598 % int SyncBlob(Image *image)
3600 % A description of each parameter follows:
3602 % o image: the image.
3605 static int SyncBlob(Image *image)
3610 assert(image != (Image *) NULL);
3611 assert(image->signature == MagickSignature);
3612 if (image->debug != MagickFalse)
3613 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3614 assert(image->blob != (BlobInfo *) NULL);
3615 assert(image->blob->type != UndefinedStream);
3617 switch (image->blob->type)
3619 case UndefinedStream:
3622 case StandardStream:
3625 status=fflush(image->blob->file);
3630 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3631 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3637 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3638 status=BZ2_bzflush((BZFILE *) image->blob->file);
3646 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3647 if (image->blob->mapped != MagickFalse)
3648 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3667 % TellBlob() obtains the current value of the blob or file position.
3669 % The format of the TellBlob method is:
3671 % MagickOffsetType TellBlob(const Image *image)
3673 % A description of each parameter follows:
3675 % o image: the image.
3678 MagickExport MagickOffsetType TellBlob(const Image *image)
3683 assert(image != (Image *) NULL);
3684 assert(image->signature == MagickSignature);
3685 if (image->debug != MagickFalse)
3686 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3687 assert(image->blob != (BlobInfo *) NULL);
3688 assert(image->blob->type != UndefinedStream);
3690 switch (image->blob->type)
3692 case UndefinedStream:
3696 offset=ftell(image->blob->file);
3699 case StandardStream:
3704 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3705 offset=(MagickOffsetType) gztell(image->blob->file);
3715 offset=image->blob->offset;
3723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3727 + U n m a p B l o b %
3731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3733 % UnmapBlob() deallocates the binary large object previously allocated with
3734 % the MapBlob method.
3736 % The format of the UnmapBlob method is:
3738 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3740 % A description of each parameter follows:
3742 % o map: the address of the binary large object.
3744 % o length: the length of the binary large object.
3747 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3749 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3753 status=munmap(map,length);
3754 return(status == -1 ? MagickFalse : MagickTrue);
3758 return(MagickFalse);
3763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3767 + W r i t e B l o b %
3771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3773 % WriteBlob() writes data to a blob or image file. It returns the number of
3776 % The format of the WriteBlob method is:
3778 % ssize_t WriteBlob(Image *image,const size_t length,
3779 % const unsigned char *data)
3781 % A description of each parameter follows:
3783 % o image: the image.
3785 % o length: Specifies an integer representing the number of bytes to
3786 % write to the file.
3788 % o data: The address of the data to write to the blob or file.
3791 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3792 const unsigned char *data)
3797 register const unsigned char
3803 assert(image != (Image *) NULL);
3804 assert(image->signature == MagickSignature);
3805 assert(data != (const unsigned char *) NULL);
3806 assert(image->blob != (BlobInfo *) NULL);
3807 assert(image->blob->type != UndefinedStream);
3812 switch (image->blob->type)
3814 case UndefinedStream:
3817 case StandardStream:
3824 count=(ssize_t) fwrite((const char *) data,1,length,
3830 c=putc((int) *p++,image->blob->file);
3837 c=putc((int) *p++,image->blob->file);
3849 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3854 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
3855 (unsigned int) length);
3860 c=gzputc(image->blob->file,(int) *p++);
3867 c=gzputc(image->blob->file,(int) *p++);
3880 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3881 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
3888 count=(ssize_t) image->blob->stream(image,data,length);
3893 register unsigned char
3896 if ((image->blob->offset+(MagickOffsetType) length) >=
3897 (MagickOffsetType) image->blob->extent)
3899 if (image->blob->mapped != MagickFalse)
3901 image->blob->quantum<<=1;
3902 image->blob->extent+=length+image->blob->quantum;
3903 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3904 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
3905 (void) SyncBlob(image);
3906 if (image->blob->data == (unsigned char *) NULL)
3908 (void) DetachBlob(image->blob);
3912 q=image->blob->data+image->blob->offset;
3913 (void) CopyMagickMemory(q,p,length);
3914 image->blob->offset+=length;
3915 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
3916 image->blob->length=(size_t) image->blob->offset;
3917 count=(ssize_t) length;
3924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3928 + W r i t e B l o b B y t e %
3932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3934 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
3935 % written (either 0 or 1);
3937 % The format of the WriteBlobByte method is:
3939 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
3941 % A description of each parameter follows.
3943 % o image: the image.
3945 % o value: Specifies the value to write.
3948 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
3950 assert(image != (Image *) NULL);
3951 assert(image->signature == MagickSignature);
3952 return(WriteBlobStream(image,1,&value));
3956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3960 + W r i t e B l o b F l o a t %
3964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3966 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
3967 % specified by the endian member of the image structure.
3969 % The format of the WriteBlobFloat method is:
3971 % ssize_t WriteBlobFloat(Image *image,const float value)
3973 % A description of each parameter follows.
3975 % o image: the image.
3977 % o value: Specifies the value to write.
3980 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
3991 quantum.unsigned_value=0U;
3992 quantum.float_value=value;
3993 return(WriteBlobLong(image,quantum.unsigned_value));
3997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4001 + W r i t e B l o b L o n g %
4005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4007 % WriteBlobLong() writes a long value as a 32-bit quantity in the byte-order
4008 % specified by the endian member of the image structure.
4010 % The format of the WriteBlobLong method is:
4012 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4014 % A description of each parameter follows.
4016 % o image: the image.
4018 % o value: Specifies the value to write.
4021 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4026 assert(image != (Image *) NULL);
4027 assert(image->signature == MagickSignature);
4028 if (image->endian == LSBEndian)
4030 buffer[0]=(unsigned char) value;
4031 buffer[1]=(unsigned char) (value >> 8);
4032 buffer[2]=(unsigned char) (value >> 16);
4033 buffer[3]=(unsigned char) (value >> 24);
4034 return(WriteBlobStream(image,4,buffer));
4036 buffer[0]=(unsigned char) (value >> 24);
4037 buffer[1]=(unsigned char) (value >> 16);
4038 buffer[2]=(unsigned char) (value >> 8);
4039 buffer[3]=(unsigned char) value;
4040 return(WriteBlobStream(image,4,buffer));
4044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4048 + W r i t e B l o b S h o r t %
4052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4054 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4055 % byte-order specified by the endian member of the image structure.
4057 % The format of the WriteBlobShort method is:
4059 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4061 % A description of each parameter follows.
4063 % o image: the image.
4065 % o value: Specifies the value to write.
4068 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4073 assert(image != (Image *) NULL);
4074 assert(image->signature == MagickSignature);
4075 if (image->endian == LSBEndian)
4077 buffer[0]=(unsigned char) value;
4078 buffer[1]=(unsigned char) (value >> 8);
4079 return(WriteBlobStream(image,2,buffer));
4081 buffer[0]=(unsigned char) (value >> 8);
4082 buffer[1]=(unsigned char) value;
4083 return(WriteBlobStream(image,2,buffer));
4087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4091 + W r i t e B l o b L S B L o n g %
4095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4097 % WriteBlobLSBLong() writes a long value as a 32-bit quantity in
4098 % least-significant byte first order.
4100 % The format of the WriteBlobLSBLong method is:
4102 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4104 % A description of each parameter follows.
4106 % o image: the image.
4108 % o value: Specifies the value to write.
4111 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4116 assert(image != (Image *) NULL);
4117 assert(image->signature == MagickSignature);
4118 buffer[0]=(unsigned char) value;
4119 buffer[1]=(unsigned char) (value >> 8);
4120 buffer[2]=(unsigned char) (value >> 16);
4121 buffer[3]=(unsigned char) (value >> 24);
4122 return(WriteBlobStream(image,4,buffer));
4126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4130 + W r i t e B l o b L S B S h o r t %
4134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4136 % WriteBlobLSBShort() writes a long value as a 16-bit quantity in
4137 % least-significant byte first order.
4139 % The format of the WriteBlobLSBShort method is:
4141 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4143 % A description of each parameter follows.
4145 % o image: the image.
4147 % o value: Specifies the value to write.
4150 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4155 assert(image != (Image *) NULL);
4156 assert(image->signature == MagickSignature);
4157 buffer[0]=(unsigned char) value;
4158 buffer[1]=(unsigned char) (value >> 8);
4159 return(WriteBlobStream(image,2,buffer));
4163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4167 + W r i t e B l o b M S B L o n g %
4171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4173 % WriteBlobMSBLong() writes a long value as a 32-bit quantity in
4174 % most-significant byte first order.
4176 % The format of the WriteBlobMSBLong method is:
4178 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4180 % A description of each parameter follows.
4182 % o value: Specifies the value to write.
4184 % o image: the image.
4187 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4192 assert(image != (Image *) NULL);
4193 assert(image->signature == MagickSignature);
4194 buffer[0]=(unsigned char) (value >> 24);
4195 buffer[1]=(unsigned char) (value >> 16);
4196 buffer[2]=(unsigned char) (value >> 8);
4197 buffer[3]=(unsigned char) value;
4198 return(WriteBlobStream(image,4,buffer));
4202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4206 + W r i t e B l o b M S B S h o r t %
4210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4212 % WriteBlobMSBShort() writes a long value as a 16-bit quantity in
4213 % most-significant byte first order.
4215 % The format of the WriteBlobMSBShort method is:
4217 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4219 % A description of each parameter follows.
4221 % o value: Specifies the value to write.
4223 % o file: Specifies the file to write the data to.
4226 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4231 assert(image != (Image *) NULL);
4232 assert(image->signature == MagickSignature);
4233 buffer[0]=(unsigned char) (value >> 8);
4234 buffer[1]=(unsigned char) value;
4235 return(WriteBlobStream(image,2,buffer));
4239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4243 + W r i t e B l o b S t r i n g %
4247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4249 % WriteBlobString() write a string to a blob. It returns the number of
4250 % characters written.
4252 % The format of the WriteBlobString method is:
4254 % ssize_t WriteBlobString(Image *image,const char *string)
4256 % A description of each parameter follows.
4258 % o image: the image.
4260 % o string: Specifies the string to write.
4263 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4265 assert(image != (Image *) NULL);
4266 assert(image->signature == MagickSignature);
4267 assert(string != (const char *) NULL);
4268 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));