2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % BBBB LLLLL OOO BBBB %
13 % MagickCore Binary Large OBjectS Methods %
20 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "magick/studio.h"
44 #include "magick/blob.h"
45 #include "magick/blob-private.h"
46 #include "magick/cache.h"
47 #include "magick/client.h"
48 #include "magick/constitute.h"
49 #include "magick/delegate.h"
50 #include "magick/exception.h"
51 #include "magick/exception-private.h"
52 #include "magick/image-private.h"
53 #include "magick/list.h"
54 #include "magick/log.h"
55 #include "magick/magick.h"
56 #include "magick/memory_.h"
57 #include "magick/policy.h"
58 #include "magick/resource_.h"
59 #include "magick/semaphore.h"
60 #include "magick/string_.h"
61 #include "magick/string-private.h"
62 #include "magick/token.h"
63 #include "magick/utility.h"
64 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
65 # include <sys/mman.h>
67 #if defined(MAGICKCORE_ZLIB_DELEGATE)
70 #if defined(MAGICKCORE_BZLIB_DELEGATE)
77 #define MagickMaxBlobExtent 65541
78 #if defined(MAGICKCORE_HAVE_FSEEKO)
82 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
83 # define MAP_ANONYMOUS MAP_ANON
85 #if !defined(MAP_FAILED)
86 #define MAP_FAILED ((void *) -1)
93 #define _O_BINARY O_BINARY
151 Forward declarations.
157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161 + A t t a c h B l o b %
165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 % AttachBlob() attaches a blob to the BlobInfo structure.
169 % The format of the AttachBlob method is:
171 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
173 % A description of each parameter follows:
175 % o blob_info: Specifies a pointer to a BlobInfo structure.
177 % o blob: the address of a character stream in one of the image formats
178 % understood by ImageMagick.
180 % o length: This size_t integer reflects the length in bytes of the blob.
183 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
186 assert(blob_info != (BlobInfo *) NULL);
187 if (blob_info->debug != MagickFalse)
188 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
189 blob_info->length=length;
190 blob_info->extent=length;
191 blob_info->quantum=(size_t) MagickMaxBlobExtent;
193 blob_info->type=BlobStream;
194 blob_info->file=(FILE *) NULL;
195 blob_info->data=(unsigned char *) blob;
196 blob_info->mapped=MagickFalse;
200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 + B l o b T o F i l e %
208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
211 % occurs otherwise MagickTrue.
213 % The format of the BlobToFile method is:
215 % MagickBooleanType BlobToFile(char *filename,const void *blob,
216 % const size_t length,ExceptionInfo *exception)
218 % A description of each parameter follows:
220 % o filename: Write the blob to this file.
222 % o blob: the address of a blob.
224 % o length: This length in bytes of the blob.
226 % o exception: return any errors or warnings in this structure.
230 static inline size_t MagickMin(const size_t x,const size_t y)
237 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
238 const size_t length,ExceptionInfo *exception)
249 assert(filename != (const char *) NULL);
250 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
251 assert(blob != (const void *) NULL);
252 if (*filename == '\0')
253 file=AcquireUniqueFileResource(filename);
255 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
258 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
261 for (i=0; i < length; i+=count)
263 count=(ssize_t) write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
273 if ((file == -1) || (i < length))
275 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286 % B l o b T o I m a g e %
290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292 % BlobToImage() implements direct to memory image formats. It returns the
295 % The format of the BlobToImage method is:
297 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
298 % const size_t length,ExceptionInfo *exception)
300 % A description of each parameter follows:
302 % o image_info: the image info.
304 % o blob: the address of a character stream in one of the image formats
305 % understood by ImageMagick.
307 % o length: This size_t integer reflects the length in bytes of the blob.
309 % o exception: return any errors or warnings in this structure.
312 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
313 const size_t length,ExceptionInfo *exception)
328 assert(image_info != (ImageInfo *) NULL);
329 assert(image_info->signature == MagickSignature);
330 if (image_info->debug != MagickFalse)
331 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
332 image_info->filename);
333 assert(exception != (ExceptionInfo *) NULL);
334 if ((blob == (const void *) NULL) || (length == 0))
336 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
337 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
338 return((Image *) NULL);
340 blob_info=CloneImageInfo(image_info);
341 blob_info->blob=(void *) blob;
342 blob_info->length=length;
343 if (*blob_info->magick == '\0')
344 (void) SetImageInfo(blob_info,0,exception);
345 magick_info=GetMagickInfo(blob_info->magick,exception);
346 if (magick_info == (const MagickInfo *) NULL)
348 blob_info=DestroyImageInfo(blob_info);
349 (void) ThrowMagickException(exception,GetMagickModule(),
350 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
351 image_info->filename);
352 return((Image *) NULL);
354 if (GetMagickBlobSupport(magick_info) != MagickFalse)
357 Native blob support for this image format.
359 (void) CopyMagickString(blob_info->filename,image_info->filename,
361 (void) CopyMagickString(blob_info->magick,image_info->magick,
363 image=ReadImage(blob_info,exception);
364 if (image != (Image *) NULL)
365 (void) DetachBlob(image->blob);
366 blob_info=DestroyImageInfo(blob_info);
370 Write blob to a temporary file on disk.
372 blob_info->blob=(void *) NULL;
374 *blob_info->filename='\0';
375 status=BlobToFile(blob_info->filename,blob,length,exception);
376 if (status == MagickFalse)
378 (void) RelinquishUniqueFileResource(blob_info->filename);
379 blob_info=DestroyImageInfo(blob_info);
380 return((Image *) NULL);
382 clone_info=CloneImageInfo(blob_info);
383 (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
384 blob_info->magick,blob_info->filename);
385 image=ReadImage(clone_info,exception);
386 clone_info=DestroyImageInfo(clone_info);
387 (void) RelinquishUniqueFileResource(blob_info->filename);
388 blob_info=DestroyImageInfo(blob_info);
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 + C l o n e B l o b I n f o %
401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
404 % blob info is NULL, a new one.
406 % The format of the CloneBlobInfo method is:
408 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
410 % A description of each parameter follows:
412 % o blob_info: the blob info.
415 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
420 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
421 if (clone_info == (BlobInfo *) NULL)
422 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
423 GetBlobInfo(clone_info);
424 if (blob_info == (BlobInfo *) NULL)
426 clone_info->length=blob_info->length;
427 clone_info->extent=blob_info->extent;
428 clone_info->synchronize=blob_info->synchronize;
429 clone_info->quantum=blob_info->quantum;
430 clone_info->mapped=blob_info->mapped;
431 clone_info->eof=blob_info->eof;
432 clone_info->offset=blob_info->offset;
433 clone_info->size=blob_info->size;
434 clone_info->exempt=blob_info->exempt;
435 clone_info->status=blob_info->status;
436 clone_info->temporary=blob_info->temporary;
437 clone_info->type=blob_info->type;
438 clone_info->file=blob_info->file;
439 clone_info->properties=blob_info->properties;
440 clone_info->stream=blob_info->stream;
441 clone_info->data=blob_info->data;
442 clone_info->debug=IsEventLogging();
443 clone_info->reference_count=1;
448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
452 + C l o s e B l o b %
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458 % CloseBlob() closes a stream associated with the image.
460 % The format of the CloseBlob method is:
462 % MagickBooleanType CloseBlob(Image *image)
464 % A description of each parameter follows:
466 % o image: the image.
469 MagickExport MagickBooleanType CloseBlob(Image *image)
477 assert(image != (Image *) NULL);
478 assert(image->signature == MagickSignature);
479 if (image->debug != MagickFalse)
480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
481 assert(image->blob != (BlobInfo *) NULL);
482 if (image->blob->type == UndefinedStream)
484 if (image->blob->synchronize != MagickFalse)
486 image->blob->size=GetBlobSize(image);
487 image->extent=image->blob->size;
488 image->blob->eof=MagickFalse;
489 if (image->blob->exempt != MagickFalse)
491 image->blob->type=UndefinedStream;
495 switch (image->blob->type)
497 case UndefinedStream:
503 status=ferror(image->blob->file);
508 #if defined(MAGICKCORE_ZLIB_DELEGATE)
509 (void) gzerror(image->blob->file,&status);
515 #if defined(MAGICKCORE_BZLIB_DELEGATE)
516 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
524 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
525 switch (image->blob->type)
527 case UndefinedStream:
532 if (image->blob->synchronize != MagickFalse)
534 status=fflush(image->blob->file);
535 status=fsync(fileno(image->blob->file));
537 status=fclose(image->blob->file);
542 #if defined(MAGICKCORE_HAVE_PCLOSE)
543 status=pclose(image->blob->file);
549 #if defined(MAGICKCORE_ZLIB_DELEGATE)
550 status=gzclose(image->blob->file);
556 #if defined(MAGICKCORE_BZLIB_DELEGATE)
557 BZ2_bzclose((BZFILE *) image->blob->file);
565 if (image->blob->file != (FILE *) NULL)
567 if (image->blob->synchronize != MagickFalse)
568 (void) fsync(fileno(image->blob->file));
569 status=fclose(image->blob->file);
574 (void) DetachBlob(image->blob);
575 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
576 return(image->blob->status);
580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584 + D e s t r o y B l o b %
588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590 % DestroyBlob() deallocates memory associated with a blob.
592 % The format of the DestroyBlob method is:
594 % void DestroyBlob(Image *image)
596 % A description of each parameter follows:
598 % o image: the image.
601 MagickExport void DestroyBlob(Image *image)
606 assert(image != (Image *) NULL);
607 assert(image->signature == MagickSignature);
608 if (image->debug != MagickFalse)
609 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
610 assert(image->blob != (BlobInfo *) NULL);
611 assert(image->blob->signature == MagickSignature);
613 LockSemaphoreInfo(image->blob->semaphore);
614 image->blob->reference_count--;
615 assert(image->blob->reference_count >= 0);
616 if (image->blob->reference_count == 0)
618 UnlockSemaphoreInfo(image->blob->semaphore);
619 if (destroy == MagickFalse)
621 (void) CloseBlob(image);
622 if (image->blob->mapped != MagickFalse)
623 (void) UnmapBlob(image->blob->data,image->blob->length);
624 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
625 DestroySemaphoreInfo(&image->blob->semaphore);
626 image->blob->signature=(~MagickSignature);
627 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635 + D e t a c h B l o b %
639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641 % DetachBlob() detaches a blob from the BlobInfo structure.
643 % The format of the DetachBlob method is:
645 % unsigned char *DetachBlob(BlobInfo *blob_info)
647 % A description of each parameter follows:
649 % o blob_info: Specifies a pointer to a BlobInfo structure.
652 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
657 assert(blob_info != (BlobInfo *) NULL);
658 if (blob_info->debug != MagickFalse)
659 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
660 if (blob_info->mapped != MagickFalse)
661 (void) UnmapBlob(blob_info->data,blob_info->length);
662 blob_info->mapped=MagickFalse;
665 blob_info->eof=MagickFalse;
666 blob_info->exempt=MagickFalse;
667 blob_info->type=UndefinedStream;
668 blob_info->file=(FILE *) NULL;
669 data=blob_info->data;
670 blob_info->data=(unsigned char *) NULL;
671 blob_info->stream=(StreamHandler) NULL;
676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
680 + D i s c a r d B l o b B y t e s %
684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
686 % DiscardBlobBytes() discards bytes in a blob.
688 % The format of the DiscardBlobBytes method is:
690 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
692 % A description of each parameter follows.
694 % o image: the image.
696 % o length: the number of bytes to skip.
700 static inline const unsigned char *ReadBlobStream(Image *image,
701 const size_t length,unsigned char *data,ssize_t *count)
703 assert(count != (ssize_t *) NULL);
704 assert(image->blob != (BlobInfo *) NULL);
705 if (image->blob->type != BlobStream)
707 *count=ReadBlob(image,length,data);
710 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
713 image->blob->eof=MagickTrue;
716 data=image->blob->data+image->blob->offset;
717 *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
718 image->blob->offset));
719 image->blob->offset+=(*count);
720 if (*count != (ssize_t) length)
721 image->blob->eof=MagickTrue;
725 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
740 assert(image != (Image *) NULL);
741 assert(image->signature == MagickSignature);
743 for (i=0; i < (ssize_t) length; i+=count)
745 quantum=MagickMin(length-i,sizeof(buffer));
746 (void) ReadBlobStream(image,quantum,buffer,&count);
754 return(i < (ssize_t) length ? MagickFalse : MagickTrue);
758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762 + D u p l i c a t e s B l o b %
766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768 % DuplicateBlob() duplicates a blob descriptor.
770 % The format of the DuplicateBlob method is:
772 % void DuplicateBlob(Image *image,const Image *duplicate)
774 % A description of each parameter follows:
776 % o image: the image.
778 % o duplicate: the duplicate image.
781 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
783 assert(image != (Image *) NULL);
784 assert(image->signature == MagickSignature);
785 if (image->debug != MagickFalse)
786 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
787 assert(duplicate != (Image *) NULL);
788 assert(duplicate->signature == MagickSignature);
790 image->blob=ReferenceBlob(duplicate->blob);
794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804 % EOFBlob() returns a non-zero value when EOF has been detected reading from
807 % The format of the EOFBlob method is:
809 % int EOFBlob(const Image *image)
811 % A description of each parameter follows:
813 % o image: the image.
816 MagickExport int EOFBlob(const Image *image)
818 assert(image != (Image *) NULL);
819 assert(image->signature == MagickSignature);
820 if (image->debug != MagickFalse)
821 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
822 assert(image->blob != (BlobInfo *) NULL);
823 assert(image->blob->type != UndefinedStream);
824 switch (image->blob->type)
826 case UndefinedStream:
832 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
837 image->blob->eof=MagickFalse;
842 #if defined(MAGICKCORE_BZLIB_DELEGATE)
847 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
848 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
854 image->blob->eof=MagickFalse;
860 return((int) image->blob->eof);
864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868 + F i l e T o B l o b %
872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
874 % FileToBlob() returns the contents of a file as a buffer terminated with
875 % the '\0' character. The length of the buffer (not including the extra
876 % terminating '\0' character) is returned via the 'length' parameter. Free
877 % the buffer with RelinquishMagickMemory().
879 % The format of the FileToBlob method is:
881 % unsigned char *FileToBlob(const char *filename,const size_t extent,
882 % size_t *length,ExceptionInfo *exception)
884 % A description of each parameter follows:
886 % o blob: FileToBlob() returns the contents of a file as a blob. If
887 % an error occurs NULL is returned.
889 % o filename: the filename.
891 % o extent: The maximum length of the blob.
893 % o length: On return, this reflects the actual length of the blob.
895 % o exception: return any errors or warnings in this structure.
898 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
899 size_t *length,ExceptionInfo *exception)
919 assert(filename != (const char *) NULL);
920 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
921 assert(exception != (ExceptionInfo *) NULL);
924 if (LocaleCompare(filename,"-") != 0)
925 file=open(filename,O_RDONLY | O_BINARY);
928 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
929 return((unsigned char *) NULL);
931 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
933 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
942 Stream is not seekable.
944 quantum=(size_t) MagickMaxBufferExtent;
945 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
946 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
947 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
948 for (i=0; blob != (unsigned char *) NULL; i+=count)
950 count=(ssize_t) read(file,blob+i,quantum);
957 if (~(1UL*i) < (quantum+1))
959 blob=(unsigned char *) RelinquishMagickMemory(blob);
962 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
964 if ((size_t) (i+count) >= extent)
967 if (LocaleCompare(filename,"-") != 0)
969 if (blob == (unsigned char *) NULL)
971 (void) ThrowMagickException(exception,GetMagickModule(),
972 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
973 return((unsigned char *) NULL);
977 blob=(unsigned char *) RelinquishMagickMemory(blob);
978 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
979 return((unsigned char *) NULL);
981 *length=MagickMin(i+count,extent);
985 *length=MagickMin((size_t) offset,extent);
986 blob=(unsigned char *) NULL;
987 if (~(*length) >= MaxTextExtent)
988 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
990 if (blob == (unsigned char *) NULL)
993 (void) ThrowMagickException(exception,GetMagickModule(),
994 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
995 return((unsigned char *) NULL);
997 map=MapBlob(file,ReadMode,0,*length);
998 if (map != (unsigned char *) NULL)
1000 (void) memcpy(blob,map,*length);
1001 (void) UnmapBlob(map,*length);
1005 (void) MagickSeek(file,0,SEEK_SET);
1006 for (i=0; i < *length; i+=count)
1008 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
1020 blob=(unsigned char *) RelinquishMagickMemory(blob);
1021 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1022 return((unsigned char *) NULL);
1026 if (LocaleCompare(filename,"-") != 0)
1030 blob=(unsigned char *) RelinquishMagickMemory(blob);
1031 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1041 % F i l e T o I m a g e %
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1047 % FileToImage() write the contents of a file to an image.
1049 % The format of the FileToImage method is:
1051 % MagickBooleanType FileToImage(Image *,const char *filename)
1053 % A description of each parameter follows:
1055 % o image: the image.
1057 % o filename: the filename.
1061 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1062 const unsigned char *data)
1067 register unsigned char
1070 assert(image->blob != (BlobInfo *) NULL);
1071 if (image->blob->type != BlobStream)
1072 return(WriteBlob(image,length,data));
1073 assert(image->blob->type != UndefinedStream);
1074 assert(data != (void *) NULL);
1075 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1076 if (extent >= image->blob->extent)
1078 image->blob->quantum<<=1;
1079 extent=image->blob->extent+image->blob->quantum+length;
1080 if (SetBlobExtent(image,extent) == MagickFalse)
1083 q=image->blob->data+image->blob->offset;
1084 (void) memcpy(q,data,length);
1085 image->blob->offset+=length;
1086 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1087 image->blob->length=(size_t) image->blob->offset;
1088 return((ssize_t) length);
1091 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1109 assert(image != (const Image *) NULL);
1110 assert(image->signature == MagickSignature);
1111 assert(filename != (const char *) NULL);
1112 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1113 file=open(filename,O_RDONLY | O_BINARY);
1116 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1118 return(MagickFalse);
1120 quantum=(size_t) MagickMaxBufferExtent;
1121 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1122 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1123 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1124 if (blob == (unsigned char *) NULL)
1126 ThrowFileException(&image->exception,ResourceLimitError,
1127 "MemoryAllocationFailed",filename);
1128 return(MagickFalse);
1132 count=(ssize_t) read(file,blob,quantum);
1139 length=(size_t) count;
1140 count=WriteBlobStream(image,length,blob);
1141 if (count != (ssize_t) length)
1143 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1150 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1152 blob=(unsigned char *) RelinquishMagickMemory(blob);
1157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1161 + G e t B l o b E r r o r %
1165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1167 % GetBlobError() returns MagickTrue if the blob associated with the specified
1168 % image encountered an error.
1170 % The format of the GetBlobError method is:
1172 % MagickBooleanType GetBlobError(const Image *image)
1174 % A description of each parameter follows:
1176 % o image: the image.
1179 MagickExport MagickBooleanType GetBlobError(const Image *image)
1181 assert(image != (const Image *) NULL);
1182 assert(image->signature == MagickSignature);
1183 if (image->debug != MagickFalse)
1184 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1185 return(image->blob->status);
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 + G e t B l o b F i l e H a n d l e %
1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1199 % GetBlobFileHandle() returns the file handle associated with the image blob.
1201 % The format of the GetBlobFile method is:
1203 % FILE *GetBlobFileHandle(const Image *image)
1205 % A description of each parameter follows:
1207 % o image: the image.
1210 MagickExport FILE *GetBlobFileHandle(const Image *image)
1212 assert(image != (const Image *) NULL);
1213 assert(image->signature == MagickSignature);
1214 return(image->blob->file);
1218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1222 + G e t B l o b I n f o %
1226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228 % GetBlobInfo() initializes the BlobInfo structure.
1230 % The format of the GetBlobInfo method is:
1232 % void GetBlobInfo(BlobInfo *blob_info)
1234 % A description of each parameter follows:
1236 % o blob_info: Specifies a pointer to a BlobInfo structure.
1239 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1241 assert(blob_info != (BlobInfo *) NULL);
1242 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1243 blob_info->type=UndefinedStream;
1244 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1245 blob_info->properties.st_mtime=time((time_t *) NULL);
1246 blob_info->properties.st_ctime=time((time_t *) NULL);
1247 blob_info->debug=IsEventLogging();
1248 blob_info->reference_count=1;
1249 blob_info->semaphore=AllocateSemaphoreInfo();
1250 blob_info->signature=MagickSignature;
1254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1258 % G e t B l o b P r o p e r t i e s %
1262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264 % GetBlobProperties() returns information about an image blob.
1266 % The format of the GetBlobProperties method is:
1268 % const struct stat *GetBlobProperties(const Image *image)
1270 % A description of each parameter follows:
1272 % o image: the image.
1275 MagickExport const struct stat *GetBlobProperties(const Image *image)
1277 assert(image != (Image *) NULL);
1278 assert(image->signature == MagickSignature);
1279 if (image->debug != MagickFalse)
1280 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1281 return(&image->blob->properties);
1285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1289 + G e t B l o b S i z e %
1293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1295 % GetBlobSize() returns the current length of the image file or blob; zero is
1296 % returned if the size cannot be determined.
1298 % The format of the GetBlobSize method is:
1300 % MagickSizeType GetBlobSize(const Image *image)
1302 % A description of each parameter follows:
1304 % o image: the image.
1307 MagickExport MagickSizeType GetBlobSize(const Image *image)
1312 assert(image != (Image *) NULL);
1313 assert(image->signature == MagickSignature);
1314 if (image->debug != MagickFalse)
1315 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1316 assert(image->blob != (BlobInfo *) NULL);
1318 switch (image->blob->type)
1320 case UndefinedStream:
1322 extent=image->blob->size;
1327 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1328 extent=(MagickSizeType) image->blob->properties.st_size;
1331 case StandardStream:
1334 extent=image->blob->size;
1343 status=GetPathAttributes(image->filename,&image->blob->properties);
1344 if (status != MagickFalse)
1345 extent=(MagickSizeType) image->blob->properties.st_size;
1352 extent=(MagickSizeType) image->blob->length;
1360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1364 + G e t B l o b S t r e a m D a t a %
1368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1370 % GetBlobStreamData() returns the stream data for the image.
1372 % The format of the GetBlobStreamData method is:
1374 % unsigned char *GetBlobStreamData(const Image *image)
1376 % A description of each parameter follows:
1378 % o image: the image.
1381 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1383 assert(image != (const Image *) NULL);
1384 assert(image->signature == MagickSignature);
1385 return(image->blob->data);
1389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1393 + G e t B l o b S t r e a m H a n d l e r %
1397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1399 % GetBlobStreamHandler() returns the stream handler for the image.
1401 % The format of the GetBlobStreamHandler method is:
1403 % StreamHandler GetBlobStreamHandler(const Image *image)
1405 % A description of each parameter follows:
1407 % o image: the image.
1410 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1412 assert(image != (const Image *) NULL);
1413 assert(image->signature == MagickSignature);
1414 if (image->debug != MagickFalse)
1415 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1416 return(image->blob->stream);
1420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1424 % I m a g e T o B l o b %
1428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1430 % ImageToBlob() implements direct to memory image formats. It returns the
1431 % image as a blob and its length. The magick member of the ImageInfo structure
1432 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1434 % The format of the ImageToBlob method is:
1436 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1437 % size_t *length,ExceptionInfo *exception)
1439 % A description of each parameter follows:
1441 % o image_info: the image info.
1443 % o image: the image.
1445 % o length: This pointer to a size_t integer sets the initial length of the
1446 % blob. On return, it reflects the actual length of the blob.
1448 % o exception: return any errors or warnings in this structure.
1451 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1452 Image *image,size_t *length,ExceptionInfo *exception)
1466 assert(image_info != (const ImageInfo *) NULL);
1467 assert(image_info->signature == MagickSignature);
1468 if (image_info->debug != MagickFalse)
1469 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1470 image_info->filename);
1471 assert(image != (Image *) NULL);
1472 assert(image->signature == MagickSignature);
1473 assert(exception != (ExceptionInfo *) NULL);
1475 blob=(unsigned char *) NULL;
1476 blob_info=CloneImageInfo(image_info);
1477 blob_info->adjoin=MagickFalse;
1478 (void) SetImageInfo(blob_info,1,exception);
1479 if (*blob_info->magick != '\0')
1480 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1481 magick_info=GetMagickInfo(image->magick,exception);
1482 if (magick_info == (const MagickInfo *) NULL)
1484 (void) ThrowMagickException(exception,GetMagickModule(),
1485 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1489 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1490 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1493 Native blob support for this image format.
1495 blob_info->length=0;
1496 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1497 sizeof(unsigned char));
1498 if (blob_info->blob == (void *) NULL)
1499 (void) ThrowMagickException(exception,GetMagickModule(),
1500 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1503 (void) CloseBlob(image);
1504 image->blob->exempt=MagickTrue;
1505 *image->filename='\0';
1506 status=WriteImage(blob_info,image);
1507 if ((status == MagickFalse) || (image->blob->length == 0))
1508 InheritException(exception,&image->exception);
1511 *length=image->blob->length;
1512 blob=DetachBlob(image->blob);
1513 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1521 unique[MaxTextExtent];
1527 Write file to disk in blob image format.
1529 file=AcquireUniqueFileResource(unique);
1532 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1533 image_info->filename);
1537 blob_info->file=fdopen(file,"wb");
1538 if (blob_info->file != (FILE *) NULL)
1540 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1541 image->magick,unique);
1542 status=WriteImage(blob_info,image);
1543 (void) fclose(blob_info->file);
1544 if (status == MagickFalse)
1545 InheritException(exception,&image->exception);
1547 blob=FileToBlob(image->filename,~0UL,length,exception);
1549 (void) RelinquishUniqueFileResource(unique);
1552 blob_info=DestroyImageInfo(blob_info);
1557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1561 % I m a g e T o F i l e %
1565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1567 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1568 % occurs otherwise MagickTrue.
1570 % The format of the ImageToFile method is:
1572 % MagickBooleanType ImageToFile(Image *image,char *filename,
1573 % ExceptionInfo *exception)
1575 % A description of each parameter follows:
1577 % o image: the image.
1579 % o filename: Write the image to this file.
1581 % o exception: return any errors or warnings in this structure.
1584 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1585 ExceptionInfo *exception)
1590 register const unsigned char
1609 assert(image != (Image *) NULL);
1610 assert(image->signature == MagickSignature);
1611 assert(image->blob != (BlobInfo *) NULL);
1612 assert(image->blob->type != UndefinedStream);
1613 if (image->debug != MagickFalse)
1614 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1615 assert(filename != (const char *) NULL);
1616 if (*filename == '\0')
1617 file=AcquireUniqueFileResource(filename);
1619 if (LocaleCompare(filename,"-") == 0)
1620 file=fileno(stdout);
1622 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1625 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1626 return(MagickFalse);
1628 quantum=(size_t) MagickMaxBufferExtent;
1629 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1630 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1631 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1632 if (buffer == (unsigned char *) NULL)
1635 (void) ThrowMagickException(exception,GetMagickModule(),
1636 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1637 return(MagickFalse);
1640 p=ReadBlobStream(image,quantum,buffer,&count);
1641 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1643 length=(size_t) count;
1644 for (i=0; i < length; i+=count)
1646 count=write(file,p+i,(size_t) (length-i));
1657 if (LocaleCompare(filename,"-") != 0)
1659 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1660 if ((file == -1) || (i < length))
1662 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1663 return(MagickFalse);
1669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673 % I m a g e s T o B l o b %
1677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1679 % ImagesToBlob() implements direct to memory image formats. It returns the
1680 % image sequence as a blob and its length. The magick member of the ImageInfo
1681 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1683 % Note, some image formats do not permit multiple images to the same image
1684 % stream (e.g. JPEG). in this instance, just the first image of the
1685 % sequence is returned as a blob.
1687 % The format of the ImagesToBlob method is:
1689 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1690 % size_t *length,ExceptionInfo *exception)
1692 % A description of each parameter follows:
1694 % o image_info: the image info.
1696 % o images: the image list.
1698 % o length: This pointer to a size_t integer sets the initial length of the
1699 % blob. On return, it reflects the actual length of the blob.
1701 % o exception: return any errors or warnings in this structure.
1704 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1705 Image *images,size_t *length,ExceptionInfo *exception)
1719 assert(image_info != (const ImageInfo *) NULL);
1720 assert(image_info->signature == MagickSignature);
1721 if (image_info->debug != MagickFalse)
1722 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1723 image_info->filename);
1724 assert(images != (Image *) NULL);
1725 assert(images->signature == MagickSignature);
1726 assert(exception != (ExceptionInfo *) NULL);
1728 blob=(unsigned char *) NULL;
1729 blob_info=CloneImageInfo(image_info);
1730 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1732 if (*blob_info->magick != '\0')
1733 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1734 if (blob_info->adjoin == MagickFalse)
1736 blob_info=DestroyImageInfo(blob_info);
1737 return(ImageToBlob(image_info,images,length,exception));
1739 magick_info=GetMagickInfo(images->magick,exception);
1740 if (magick_info == (const MagickInfo *) NULL)
1742 (void) ThrowMagickException(exception,GetMagickModule(),
1743 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1747 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1748 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1751 Native blob support for this images format.
1753 blob_info->length=0;
1754 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1755 sizeof(unsigned char));
1756 if (blob_info->blob == (void *) NULL)
1757 (void) ThrowMagickException(exception,GetMagickModule(),
1758 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1761 images->blob->exempt=MagickTrue;
1762 *images->filename='\0';
1763 status=WriteImages(blob_info,images,images->filename,exception);
1764 if ((status == MagickFalse) || (images->blob->length == 0))
1765 InheritException(exception,&images->exception);
1768 *length=images->blob->length;
1769 blob=DetachBlob(images->blob);
1770 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1778 filename[MaxTextExtent],
1779 unique[MaxTextExtent];
1785 Write file to disk in blob images format.
1787 file=AcquireUniqueFileResource(unique);
1790 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1791 image_info->filename);
1795 blob_info->file=fdopen(file,"wb");
1796 if (blob_info->file != (FILE *) NULL)
1798 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1799 images->magick,unique);
1800 status=WriteImages(blob_info,images,filename,exception);
1801 (void) fclose(blob_info->file);
1802 if (status == MagickFalse)
1803 InheritException(exception,&images->exception);
1805 blob=FileToBlob(images->filename,~0UL,length,exception);
1807 (void) RelinquishUniqueFileResource(unique);
1810 blob_info=DestroyImageInfo(blob_info);
1814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1818 % I n j e c t I m a g e B l o b %
1822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1824 % InjectImageBlob() injects the image with a copy of itself in the specified
1825 % format (e.g. inject JPEG into a PDF image).
1827 % The format of the InjectImageBlob method is:
1829 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1830 % Image *image,Image *inject_image,const char *format,
1831 % ExceptionInfo *exception)
1833 % A description of each parameter follows:
1835 % o image_info: the image info..
1837 % o image: the image.
1839 % o inject_image: inject into the image stream.
1841 % o format: the image format.
1843 % o exception: return any errors or warnings in this structure.
1846 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1847 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1850 filename[MaxTextExtent];
1883 Write inject image to a temporary file.
1885 assert(image_info != (ImageInfo *) NULL);
1886 assert(image_info->signature == MagickSignature);
1887 assert(image != (Image *) NULL);
1888 assert(image->signature == MagickSignature);
1889 if (image->debug != MagickFalse)
1890 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1891 assert(inject_image != (Image *) NULL);
1892 assert(inject_image->signature == MagickSignature);
1893 assert(exception != (ExceptionInfo *) NULL);
1894 unique_file=(FILE *) NULL;
1895 file=AcquireUniqueFileResource(filename);
1897 unique_file=fdopen(file,"wb");
1898 if ((file == -1) || (unique_file == (FILE *) NULL))
1900 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1901 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1903 return(MagickFalse);
1905 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1906 if (byte_image == (Image *) NULL)
1908 (void) fclose(unique_file);
1909 (void) RelinquishUniqueFileResource(filename);
1910 return(MagickFalse);
1912 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1914 DestroyBlob(byte_image);
1915 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1916 write_info=CloneImageInfo(image_info);
1917 SetImageInfoFile(write_info,unique_file);
1918 status=WriteImage(write_info,byte_image);
1919 write_info=DestroyImageInfo(write_info);
1920 byte_image=DestroyImage(byte_image);
1921 (void) fclose(unique_file);
1922 if (status == MagickFalse)
1924 (void) RelinquishUniqueFileResource(filename);
1925 return(MagickFalse);
1928 Inject into image stream.
1930 file=open(filename,O_RDONLY | O_BINARY);
1933 (void) RelinquishUniqueFileResource(filename);
1934 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1935 image_info->filename);
1936 return(MagickFalse);
1938 quantum=(size_t) MagickMaxBufferExtent;
1939 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1940 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1941 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1942 if (buffer == (unsigned char *) NULL)
1944 (void) RelinquishUniqueFileResource(filename);
1945 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1948 for (i=0; ; i+=count)
1950 count=(ssize_t) read(file,buffer,quantum);
1957 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1962 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1963 (void) RelinquishUniqueFileResource(filename);
1964 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1973 + I s B l o b E x e m p t %
1977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1979 % IsBlobExempt() returns true if the blob is exempt.
1981 % The format of the IsBlobExempt method is:
1983 % MagickBooleanType IsBlobExempt(const Image *image)
1985 % A description of each parameter follows:
1987 % o image: the image.
1990 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1992 assert(image != (const Image *) NULL);
1993 assert(image->signature == MagickSignature);
1994 if (image->debug != MagickFalse)
1995 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1996 return(image->blob->exempt);
2000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2004 + I s B l o b S e e k a b l e %
2008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2010 % IsBlobSeekable() returns true if the blob is seekable.
2012 % The format of the IsBlobSeekable method is:
2014 % MagickBooleanType IsBlobSeekable(const Image *image)
2016 % A description of each parameter follows:
2018 % o image: the image.
2021 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2026 assert(image != (const Image *) NULL);
2027 assert(image->signature == MagickSignature);
2028 if (image->debug != MagickFalse)
2029 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2030 seekable=(image->blob->type == FileStream) ||
2031 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2040 + I s B l o b T e m p o r a r y %
2044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2046 % IsBlobTemporary() returns true if the blob is temporary.
2048 % The format of the IsBlobTemporary method is:
2050 % MagickBooleanType IsBlobTemporary(const Image *image)
2052 % A description of each parameter follows:
2054 % o image: the image.
2057 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2059 assert(image != (const Image *) NULL);
2060 assert(image->signature == MagickSignature);
2061 if (image->debug != MagickFalse)
2062 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2063 return(image->blob->temporary);
2067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2077 % MapBlob() creates a mapping from a file to a binary large object.
2079 % The format of the MapBlob method is:
2081 % unsigned char *MapBlob(int file,const MapMode mode,
2082 % const MagickOffsetType offset,const size_t length)
2084 % A description of each parameter follows:
2086 % o file: map this file descriptor.
2088 % o mode: ReadMode, WriteMode, or IOMode.
2090 % o offset: starting at this offset within the file.
2092 % o length: the length of the mapping is returned in this pointer.
2095 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2096 const MagickOffsetType offset,const size_t length)
2098 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2111 #if defined(MAP_ANONYMOUS)
2112 flags|=MAP_ANONYMOUS;
2114 return((unsigned char *) NULL);
2121 protection=PROT_READ;
2123 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2129 protection=PROT_WRITE;
2131 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2133 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2134 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2135 POSIX_MADV_WILLNEED);
2141 protection=PROT_READ | PROT_WRITE;
2143 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2148 if (map == (unsigned char *) MAP_FAILED)
2149 return((unsigned char *) NULL);
2156 return((unsigned char *) NULL);
2161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2165 + M S B O r d e r L o n g %
2169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2171 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2172 % most-significant byte first.
2174 % The format of the MSBOrderLong method is:
2176 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2178 % A description of each parameter follows.
2180 % o buffer: Specifies a pointer to a buffer of integers.
2182 % o length: Specifies the length of the buffer.
2185 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2190 register unsigned char
2194 assert(buffer != (unsigned char *) NULL);
2201 *buffer++=(unsigned char) c;
2205 *buffer++=(unsigned char) c;
2211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2215 + M S B O r d e r S h o r t %
2219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2221 % MSBOrderShort() converts a least-significant byte first buffer of integers
2222 % to most-significant byte first.
2224 % The format of the MSBOrderShort method is:
2226 % void MSBOrderShort(unsigned char *p,const size_t length)
2228 % A description of each parameter follows.
2230 % o p: Specifies a pointer to a buffer of integers.
2232 % o length: Specifies the length of the buffer.
2235 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2240 register unsigned char
2243 assert(p != (unsigned char *) NULL);
2250 *p++=(unsigned char) c;
2255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2265 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2266 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2267 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2268 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2269 % from a system command.
2271 % The format of the OpenBlob method is:
2273 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2274 % const BlobMode mode,ExceptionInfo *exception)
2276 % A description of each parameter follows:
2278 % o image_info: the image info.
2280 % o image: the image.
2282 % o mode: the mode for opening the file.
2285 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2286 Image *image,const BlobMode mode,ExceptionInfo *exception)
2289 extension[MaxTextExtent],
2290 filename[MaxTextExtent];
2301 assert(image_info != (ImageInfo *) NULL);
2302 assert(image_info->signature == MagickSignature);
2303 if (image_info->debug != MagickFalse)
2304 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2305 image_info->filename);
2306 assert(image != (Image *) NULL);
2307 assert(image->signature == MagickSignature);
2308 if (image_info->blob != (void *) NULL)
2310 if (image_info->stream != (StreamHandler) NULL)
2311 image->blob->stream=(StreamHandler) image_info->stream;
2312 AttachBlob(image->blob,image_info->blob,image_info->length);
2315 (void) DetachBlob(image->blob);
2318 default: type="r"; break;
2319 case ReadBlobMode: type="r"; break;
2320 case ReadBinaryBlobMode: type="rb"; break;
2321 case WriteBlobMode: type="w"; break;
2322 case WriteBinaryBlobMode: type="w+b"; break;
2323 case AppendBlobMode: type="a"; break;
2324 case AppendBinaryBlobMode: type="a+b"; break;
2327 image->blob->synchronize=image_info->synchronize;
2328 if (image_info->stream != (StreamHandler) NULL)
2330 image->blob->stream=(StreamHandler) image_info->stream;
2333 image->blob->type=FifoStream;
2341 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2342 rights=ReadPolicyRights;
2344 rights=WritePolicyRights;
2345 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2348 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2349 "NotAuthorized","`%s'",filename);
2350 return(MagickFalse);
2352 if ((LocaleCompare(filename,"-") == 0) ||
2353 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2355 image->blob->file=(*type == 'r') ? stdin : stdout;
2356 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2357 if (strchr(type,'b') != (char *) NULL)
2358 setmode(_fileno(image->blob->file),_O_BINARY);
2360 image->blob->type=StandardStream;
2361 image->blob->exempt=MagickTrue;
2364 if (LocaleNCompare(filename,"fd:",3) == 0)
2367 mode[MaxTextExtent];
2371 image->blob->file=fdopen(StringToLong(filename+3),mode);
2372 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2373 if (strchr(type,'b') != (char *) NULL)
2374 setmode(_fileno(image->blob->file),_O_BINARY);
2376 image->blob->type=StandardStream;
2377 image->blob->exempt=MagickTrue;
2380 #if defined(MAGICKCORE_HAVE_POPEN)
2381 if (*filename == '|')
2384 mode[MaxTextExtent];
2387 Pipe image to or from a system command.
2389 #if defined(SIGPIPE)
2391 (void) signal(SIGPIPE,SIG_IGN);
2395 image->blob->file=(FILE *) popen(filename+1,mode);
2396 if (image->blob->file == (FILE *) NULL)
2398 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2399 return(MagickFalse);
2401 image->blob->type=PipeStream;
2402 image->blob->exempt=MagickTrue;
2406 status=GetPathAttributes(filename,&image->blob->properties);
2407 #if defined(S_ISFIFO)
2408 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2410 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2411 if (image->blob->file == (FILE *) NULL)
2413 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2414 return(MagickFalse);
2416 image->blob->type=FileStream;
2417 image->blob->exempt=MagickTrue;
2421 GetPathComponent(image->filename,ExtensionPath,extension);
2424 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2425 if ((image_info->adjoin == MagickFalse) ||
2426 (IsGlob(filename) != MagickFalse))
2429 Form filename for multi-part images.
2431 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2432 image->scene,filename);
2433 if ((LocaleCompare(filename,image->filename) == 0) &&
2434 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2435 (GetNextImageInList(image) != (Image *) NULL)))
2438 path[MaxTextExtent];
2440 GetPathComponent(image->filename,RootPath,path);
2441 if (*extension == '\0')
2442 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2443 path,(double) image->scene);
2445 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g.%s",
2446 path,(double) image->scene,extension);
2448 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2449 #if defined(macintosh)
2450 SetApplicationType(filename,image_info->magick,'8BIM');
2454 if (image_info->file != (FILE *) NULL)
2456 image->blob->file=image_info->file;
2457 image->blob->type=FileStream;
2458 image->blob->exempt=MagickTrue;
2463 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2464 if (image->blob->file != (FILE *) NULL)
2472 image->blob->type=FileStream;
2473 #if defined(MAGICKCORE_HAVE_SETVBUF)
2474 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2476 (void) ResetMagickMemory(magick,0,sizeof(magick));
2477 count=fread(magick,1,sizeof(magick),image->blob->file);
2478 (void) rewind(image->blob->file);
2479 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2480 " read %.20g magic header bytes",(double) count);
2481 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2482 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2483 ((int) magick[2] == 0x08))
2485 (void) fclose(image->blob->file);
2486 image->blob->file=(FILE *) gzopen(filename,type);
2487 if (image->blob->file != (FILE *) NULL)
2488 image->blob->type=ZipStream;
2491 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2492 if (strncmp((char *) magick,"BZh",3) == 0)
2494 (void) fclose(image->blob->file);
2495 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2496 if (image->blob->file != (FILE *) NULL)
2497 image->blob->type=BZipStream;
2500 if (image->blob->type == FileStream)
2511 sans_exception=AcquireExceptionInfo();
2512 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2513 sans_exception=DestroyExceptionInfo(sans_exception);
2514 properties=(&image->blob->properties);
2515 if ((magick_info != (const MagickInfo *) NULL) &&
2516 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2517 (properties->st_size <= MagickMaxBufferExtent))
2525 length=(size_t) properties->st_size;
2526 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2527 if (blob != (void *) NULL)
2530 Format supports blobs-- use memory-mapped I/O.
2532 if (image_info->file != (FILE *) NULL)
2533 image->blob->exempt=MagickFalse;
2536 (void) fclose(image->blob->file);
2537 image->blob->file=(FILE *) NULL;
2539 AttachBlob(image->blob,blob,length);
2540 image->blob->mapped=MagickTrue;
2547 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2548 if ((LocaleCompare(extension,"Z") == 0) ||
2549 (LocaleCompare(extension,"gz") == 0) ||
2550 (LocaleCompare(extension,"wmz") == 0) ||
2551 (LocaleCompare(extension,"svgz") == 0))
2553 if (mode == WriteBinaryBlobMode)
2555 image->blob->file=(FILE *) gzopen(filename,type);
2556 if (image->blob->file != (FILE *) NULL)
2557 image->blob->type=ZipStream;
2561 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2562 if (LocaleCompare(extension,".bz2") == 0)
2564 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2565 if (image->blob->file != (FILE *) NULL)
2566 image->blob->type=BZipStream;
2571 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2572 if (image->blob->file != (FILE *) NULL)
2574 image->blob->type=FileStream;
2575 #if defined(MAGICKCORE_HAVE_SETVBUF)
2576 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2581 image->blob->status=MagickFalse;
2582 if (image->blob->type != UndefinedStream)
2583 image->blob->size=GetBlobSize(image);
2586 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2587 return(MagickFalse);
2593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2603 % PingBlob() returns all the attributes of an image or image sequence except
2604 % for the pixels. It is much faster and consumes far less memory than
2605 % BlobToImage(). On failure, a NULL image is returned and exception
2606 % describes the reason for the failure.
2608 % The format of the PingBlob method is:
2610 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2611 % const size_t length,ExceptionInfo *exception)
2613 % A description of each parameter follows:
2615 % o image_info: the image info.
2617 % o blob: the address of a character stream in one of the image formats
2618 % understood by ImageMagick.
2620 % o length: This size_t integer reflects the length in bytes of the blob.
2622 % o exception: return any errors or warnings in this structure.
2626 #if defined(__cplusplus) || defined(c_plusplus)
2630 static size_t PingStream(const Image *magick_unused(image),
2631 const void *magick_unused(pixels),const size_t columns)
2636 #if defined(__cplusplus) || defined(c_plusplus)
2640 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2641 const size_t length,ExceptionInfo *exception)
2649 assert(image_info != (ImageInfo *) NULL);
2650 assert(image_info->signature == MagickSignature);
2651 if (image_info->debug != MagickFalse)
2652 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2653 image_info->filename);
2654 assert(exception != (ExceptionInfo *) NULL);
2655 if ((blob == (const void *) NULL) || (length == 0))
2657 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2658 "UnrecognizedImageFormat","`%s'",image_info->magick);
2659 return((Image *) NULL);
2661 ping_info=CloneImageInfo(image_info);
2662 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2663 if (ping_info->blob == (const void *) NULL)
2665 (void) ThrowMagickException(exception,GetMagickModule(),
2666 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2667 return((Image *) NULL);
2669 (void) memcpy(ping_info->blob,blob,length);
2670 ping_info->length=length;
2671 ping_info->ping=MagickTrue;
2672 image=ReadStream(ping_info,&PingStream,exception);
2673 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2674 ping_info=DestroyImageInfo(ping_info);
2679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2689 % ReadBlob() reads data from the blob or image file and returns it. It
2690 % returns the number of bytes read.
2692 % The format of the ReadBlob method is:
2694 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2696 % A description of each parameter follows:
2698 % o image: the image.
2700 % o length: Specifies an integer representing the number of bytes to read
2703 % o data: Specifies an area to place the information requested from the
2707 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2708 unsigned char *data)
2713 register unsigned char
2719 assert(image != (Image *) NULL);
2720 assert(image->signature == MagickSignature);
2721 assert(image->blob != (BlobInfo *) NULL);
2722 assert(image->blob->type != UndefinedStream);
2725 assert(data != (void *) NULL);
2728 switch (image->blob->type)
2730 case UndefinedStream:
2733 case StandardStream:
2740 count=(ssize_t) fread(q,1,length,image->blob->file);
2745 c=getc(image->blob->file);
2748 *q++=(unsigned char) c;
2753 c=getc(image->blob->file);
2756 *q++=(unsigned char) c;
2766 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2771 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2776 c=gzgetc(image->blob->file);
2779 *q++=(unsigned char) c;
2784 c=gzgetc(image->blob->file);
2787 *q++=(unsigned char) c;
2798 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2799 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2807 register const unsigned char
2810 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2812 image->blob->eof=MagickTrue;
2815 p=image->blob->data+image->blob->offset;
2816 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2817 image->blob->offset));
2818 image->blob->offset+=count;
2819 if (count != (ssize_t) length)
2820 image->blob->eof=MagickTrue;
2821 (void) memcpy(q,p,(size_t) count);
2829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2833 + R e a d B l o b B y t e %
2837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2839 % ReadBlobByte() reads a single byte from the image file and returns it.
2841 % The format of the ReadBlobByte method is:
2843 % int ReadBlobByte(Image *image)
2845 % A description of each parameter follows.
2847 % o image: the image.
2850 MagickExport int ReadBlobByte(Image *image)
2852 register const unsigned char
2861 assert(image != (Image *) NULL);
2862 assert(image->signature == MagickSignature);
2863 p=ReadBlobStream(image,1,buffer,&count);
2870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2874 + R e a d B l o b D o u b l e %
2878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2880 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2881 % specified by the endian member of the image structure.
2883 % The format of the ReadBlobDouble method is:
2885 % double ReadBlobDouble(Image *image)
2887 % A description of each parameter follows.
2889 % o image: the image.
2892 MagickExport double ReadBlobDouble(Image *image)
2903 quantum.double_value=0.0;
2904 quantum.unsigned_value=ReadBlobLongLong(image);
2905 return(quantum.double_value);
2909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2913 + R e a d B l o b F l o a t %
2917 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2919 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2920 % specified by the endian member of the image structure.
2922 % The format of the ReadBlobFloat method is:
2924 % float ReadBlobFloat(Image *image)
2926 % A description of each parameter follows.
2928 % o image: the image.
2931 MagickExport float ReadBlobFloat(Image *image)
2942 quantum.float_value=0.0;
2943 quantum.unsigned_value=ReadBlobLong(image);
2944 return(quantum.float_value);
2948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2952 + R e a d B l o b L o n g %
2956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2958 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2959 % specified by the endian member of the image structure.
2961 % The format of the ReadBlobLong method is:
2963 % unsigned int ReadBlobLong(Image *image)
2965 % A description of each parameter follows.
2967 % o image: the image.
2970 MagickExport unsigned int ReadBlobLong(Image *image)
2972 register const unsigned char
2984 assert(image != (Image *) NULL);
2985 assert(image->signature == MagickSignature);
2987 p=ReadBlobStream(image,4,buffer,&count);
2990 if (image->endian == LSBEndian)
2992 value=(unsigned int) (*p++);
2993 value|=((unsigned int) (*p++)) << 8;
2994 value|=((unsigned int) (*p++)) << 16;
2995 value|=((unsigned int) (*p++)) << 24;
2998 value=((unsigned int) (*p++)) << 24;
2999 value|=((unsigned int) (*p++)) << 16;
3000 value|=((unsigned int) (*p++)) << 8;
3001 value|=((unsigned int) (*p++));
3006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3010 + R e a d B l o b L o n g L o n g %
3014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3016 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3017 % byte-order specified by the endian member of the image structure.
3019 % The format of the ReadBlobLongLong method is:
3021 % MagickSizeType ReadBlobLongLong(Image *image)
3023 % A description of each parameter follows.
3025 % o image: the image.
3028 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3033 register const unsigned char
3042 assert(image != (Image *) NULL);
3043 assert(image->signature == MagickSignature);
3045 p=ReadBlobStream(image,8,buffer,&count);
3047 return(MagickULLConstant(0));
3048 if (image->endian == LSBEndian)
3050 value=(MagickSizeType) (*p++);
3051 value|=((MagickSizeType) (*p++)) << 8;
3052 value|=((MagickSizeType) (*p++)) << 16;
3053 value|=((MagickSizeType) (*p++)) << 24;
3054 value|=((MagickSizeType) (*p++)) << 32;
3055 value|=((MagickSizeType) (*p++)) << 40;
3056 value|=((MagickSizeType) (*p++)) << 48;
3057 value|=((MagickSizeType) (*p++)) << 56;
3058 return(value & MagickULLConstant(0xffffffffffffffff));
3060 value=((MagickSizeType) (*p++)) << 56;
3061 value|=((MagickSizeType) (*p++)) << 48;
3062 value|=((MagickSizeType) (*p++)) << 40;
3063 value|=((MagickSizeType) (*p++)) << 32;
3064 value|=((MagickSizeType) (*p++)) << 24;
3065 value|=((MagickSizeType) (*p++)) << 16;
3066 value|=((MagickSizeType) (*p++)) << 8;
3067 value|=((MagickSizeType) (*p++));
3068 return(value & MagickULLConstant(0xffffffffffffffff));
3072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3076 + R e a d B l o b S h o r t %
3080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3082 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3083 % specified by the endian member of the image structure.
3085 % The format of the ReadBlobShort method is:
3087 % unsigned short ReadBlobShort(Image *image)
3089 % A description of each parameter follows.
3091 % o image: the image.
3094 MagickExport unsigned short ReadBlobShort(Image *image)
3096 register const unsigned char
3099 register unsigned int
3108 assert(image != (Image *) NULL);
3109 assert(image->signature == MagickSignature);
3111 p=ReadBlobStream(image,2,buffer,&count);
3113 return((unsigned short) 0U);
3114 if (image->endian == LSBEndian)
3116 value=(unsigned int) (*p++);
3117 value|=((unsigned int) (*p++)) << 8;
3118 return((unsigned short) (value & 0xffff));
3120 value=(unsigned int) ((*p++) << 8);
3121 value|=(unsigned int) (*p++);
3122 return((unsigned short) (value & 0xffff));
3126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3130 + R e a d B l o b L S B L o n g %
3134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3136 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3137 % least-significant byte first order.
3139 % The format of the ReadBlobLSBLong method is:
3141 % unsigned int ReadBlobLSBLong(Image *image)
3143 % A description of each parameter follows.
3145 % o image: the image.
3148 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3150 register const unsigned char
3153 register unsigned int
3162 assert(image != (Image *) NULL);
3163 assert(image->signature == MagickSignature);
3165 p=ReadBlobStream(image,4,buffer,&count);
3168 value=(unsigned int) (*p++);
3169 value|=((unsigned int) (*p++)) << 8;
3170 value|=((unsigned int) (*p++)) << 16;
3171 value|=((unsigned int) (*p++)) << 24;
3176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3180 + R e a d B l o b L S B S h o r t %
3184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3186 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3187 % least-significant byte first order.
3189 % The format of the ReadBlobLSBShort method is:
3191 % unsigned short ReadBlobLSBShort(Image *image)
3193 % A description of each parameter follows.
3195 % o image: the image.
3198 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3200 register const unsigned char
3203 register unsigned int
3212 assert(image != (Image *) NULL);
3213 assert(image->signature == MagickSignature);
3215 p=ReadBlobStream(image,2,buffer,&count);
3217 return((unsigned short) 0U);
3218 value=(unsigned int) (*p++);
3219 value|=((unsigned int) ((*p++)) << 8);
3220 return((unsigned short) (value & 0xffff));
3224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3228 + R e a d B l o b M S B L o n g %
3232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3234 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3235 % most-significant byte first order.
3237 % The format of the ReadBlobMSBLong method is:
3239 % unsigned int ReadBlobMSBLong(Image *image)
3241 % A description of each parameter follows.
3243 % o image: the image.
3246 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3248 register const unsigned char
3251 register unsigned int
3260 assert(image != (Image *) NULL);
3261 assert(image->signature == MagickSignature);
3263 p=ReadBlobStream(image,4,buffer,&count);
3266 value=((unsigned int) (*p++) << 24);
3267 value|=((unsigned int) (*p++) << 16);
3268 value|=((unsigned int) (*p++) << 8);
3269 value|=(unsigned int) (*p++);
3274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3278 + R e a d B l o b M S B L o n g L o n g %
3282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3284 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3285 % most-significant byte first order.
3287 % The format of the ReadBlobMSBLongLong method is:
3289 % unsigned int ReadBlobMSBLongLong(Image *image)
3291 % A description of each parameter follows.
3293 % o image: the image.
3296 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3298 register const unsigned char
3301 register MagickSizeType
3310 assert(image != (Image *) NULL);
3311 assert(image->signature == MagickSignature);
3313 p=ReadBlobStream(image,8,buffer,&count);
3315 return(MagickULLConstant(0));
3316 value=((MagickSizeType) (*p++)) << 56;
3317 value|=((MagickSizeType) (*p++)) << 48;
3318 value|=((MagickSizeType) (*p++)) << 40;
3319 value|=((MagickSizeType) (*p++)) << 32;
3320 value|=((MagickSizeType) (*p++)) << 24;
3321 value|=((MagickSizeType) (*p++)) << 16;
3322 value|=((MagickSizeType) (*p++)) << 8;
3323 value|=((MagickSizeType) (*p++));
3324 return(value & MagickULLConstant(0xffffffffffffffff));
3328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3332 + R e a d B l o b M S B S h o r t %
3336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3338 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3339 % most-significant byte first order.
3341 % The format of the ReadBlobMSBShort method is:
3343 % unsigned short ReadBlobMSBShort(Image *image)
3345 % A description of each parameter follows.
3347 % o image: the image.
3350 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3352 register const unsigned char
3355 register unsigned int
3364 assert(image != (Image *) NULL);
3365 assert(image->signature == MagickSignature);
3367 p=ReadBlobStream(image,2,buffer,&count);
3369 return((unsigned short) 0U);
3370 value=(unsigned int) ((*p++) << 8);
3371 value|=(unsigned int) (*p++);
3372 return((unsigned short) (value & 0xffff));
3376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3380 + R e a d B l o b S t r i n g %
3384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3386 % ReadBlobString() reads characters from a blob or file until a newline
3387 % character is read or an end-of-file condition is encountered.
3389 % The format of the ReadBlobString method is:
3391 % char *ReadBlobString(Image *image,char *string)
3393 % A description of each parameter follows:
3395 % o image: the image.
3397 % o string: the address of a character buffer.
3400 MagickExport char *ReadBlobString(Image *image,char *string)
3402 register const unsigned char
3414 assert(image != (Image *) NULL);
3415 assert(image->signature == MagickSignature);
3416 for (i=0; i < (MaxTextExtent-1L); i++)
3418 p=ReadBlobStream(image,1,buffer,&count);
3422 return((char *) NULL);
3425 string[i]=(char) (*p);
3426 if ((string[i] == '\r') || (string[i] == '\n'))
3429 if (string[i] == '\r')
3430 (void) ReadBlobStream(image,1,buffer,&count);
3436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3440 + R e f e r e n c e B l o b %
3444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3446 % ReferenceBlob() increments the reference count associated with the pixel
3447 % blob returning a pointer to the blob.
3449 % The format of the ReferenceBlob method is:
3451 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3453 % A description of each parameter follows:
3455 % o blob_info: the blob_info.
3458 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3460 assert(blob != (BlobInfo *) NULL);
3461 assert(blob->signature == MagickSignature);
3462 if (blob->debug != MagickFalse)
3463 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3464 LockSemaphoreInfo(blob->semaphore);
3465 blob->reference_count++;
3466 UnlockSemaphoreInfo(blob->semaphore);
3471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3481 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3482 % and returns the resulting offset.
3484 % The format of the SeekBlob method is:
3486 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3489 % A description of each parameter follows:
3491 % o image: the image.
3493 % o offset: Specifies an integer representing the offset in bytes.
3495 % o whence: Specifies an integer representing how the offset is
3496 % treated relative to the beginning of the blob as follows:
3498 % SEEK_SET Set position equal to offset bytes.
3499 % SEEK_CUR Set position to current location plus offset.
3500 % SEEK_END Set position to EOF plus offset.
3503 MagickExport MagickOffsetType SeekBlob(Image *image,
3504 const MagickOffsetType offset,const int whence)
3506 assert(image != (Image *) NULL);
3507 assert(image->signature == MagickSignature);
3508 if (image->debug != MagickFalse)
3509 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3510 assert(image->blob != (BlobInfo *) NULL);
3511 assert(image->blob->type != UndefinedStream);
3512 switch (image->blob->type)
3514 case UndefinedStream:
3518 if (fseek(image->blob->file,(long) offset,whence) < 0)
3520 image->blob->offset=TellBlob(image);
3523 case StandardStream:
3527 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3528 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3531 image->blob->offset=TellBlob(image);
3547 image->blob->offset=offset;
3552 if ((image->blob->offset+offset) < 0)
3554 image->blob->offset+=offset;
3559 if (((MagickOffsetType) image->blob->length+offset) < 0)
3561 image->blob->offset=image->blob->length+offset;
3565 if (image->blob->offset <= (MagickOffsetType)
3566 ((off_t) image->blob->length))
3567 image->blob->eof=MagickFalse;
3569 if (image->blob->mapped != MagickFalse)
3573 image->blob->extent=(size_t) (image->blob->offset+
3574 image->blob->quantum);
3575 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3576 image->blob->data,image->blob->extent+1,
3577 sizeof(*image->blob->data));
3578 (void) SyncBlob(image);
3579 if (image->blob->data == (unsigned char *) NULL)
3581 (void) DetachBlob(image->blob);
3588 return(image->blob->offset);
3592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3596 + S e t B l o b E x e m p t %
3600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3602 % SetBlobExempt() sets the blob exempt status.
3604 % The format of the SetBlobExempt method is:
3606 % MagickBooleanType SetBlobExempt(const Image *image,
3607 % const MagickBooleanType exempt)
3609 % A description of each parameter follows:
3611 % o image: the image.
3613 % o exempt: Set to true if this blob is exempt from being closed.
3616 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3618 assert(image != (const Image *) NULL);
3619 assert(image->signature == MagickSignature);
3620 if (image->debug != MagickFalse)
3621 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3622 image->blob->exempt=exempt;
3626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3630 + S e t B l o b E x t e n t %
3634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3636 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3637 % method is successful, subsequent writes to bytes in the specified range are
3638 % guaranteed not to fail.
3640 % The format of the SetBlobExtent method is:
3642 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3644 % A description of each parameter follows:
3646 % o image: the image.
3648 % o extent: the blob maximum extent.
3651 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3652 const MagickSizeType extent)
3654 assert(image != (Image *) NULL);
3655 assert(image->signature == MagickSignature);
3656 if (image->debug != MagickFalse)
3657 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3658 assert(image->blob != (BlobInfo *) NULL);
3659 assert(image->blob->type != UndefinedStream);
3660 switch (image->blob->type)
3662 case UndefinedStream:
3666 if (extent != (MagickSizeType) ((off_t) extent))
3667 return(MagickFalse);
3668 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3669 return(MagickFalse);
3678 offset=TellBlob(image);
3679 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3680 (off_t) (extent-offset));
3682 return(MagickFalse);
3687 case StandardStream:
3690 return(MagickFalse);
3692 return(MagickFalse);
3694 return(MagickFalse);
3697 if (image->blob->mapped != MagickFalse)
3699 if (image->blob->file == (FILE *) NULL)
3700 return(MagickFalse);
3701 (void) UnmapBlob(image->blob->data,image->blob->length);
3702 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3703 return(MagickFalse);
3712 offset=TellBlob(image);
3713 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3714 (off_t) (extent-offset));
3716 return(MagickFalse);
3718 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3719 WriteMode,0,(size_t) extent);
3720 image->blob->extent=(size_t) extent;
3721 image->blob->length=(size_t) extent;
3722 (void) SyncBlob(image);
3726 if (extent != (MagickSizeType) ((size_t) extent))
3727 return(MagickFalse);
3728 image->blob->extent=(size_t) extent;
3729 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3730 image->blob->extent+1,sizeof(*image->blob->data));
3731 (void) SyncBlob(image);
3732 if (image->blob->data == (unsigned char *) NULL)
3734 (void) DetachBlob(image->blob);
3735 return(MagickFalse);
3744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3752 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3754 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3755 % attributes if it is an blob.
3757 % The format of the SyncBlob method is:
3759 % int SyncBlob(Image *image)
3761 % A description of each parameter follows:
3763 % o image: the image.
3766 static int SyncBlob(Image *image)
3771 assert(image != (Image *) NULL);
3772 assert(image->signature == MagickSignature);
3773 if (image->debug != MagickFalse)
3774 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3775 assert(image->blob != (BlobInfo *) NULL);
3776 assert(image->blob->type != UndefinedStream);
3778 switch (image->blob->type)
3780 case UndefinedStream:
3783 case StandardStream:
3786 status=fflush(image->blob->file);
3791 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3792 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3798 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3799 status=BZ2_bzflush((BZFILE *) image->blob->file);
3807 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3808 if (image->blob->mapped != MagickFalse)
3809 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3828 % TellBlob() obtains the current value of the blob or file position.
3830 % The format of the TellBlob method is:
3832 % MagickOffsetType TellBlob(const Image *image)
3834 % A description of each parameter follows:
3836 % o image: the image.
3839 MagickExport MagickOffsetType TellBlob(const Image *image)
3844 assert(image != (Image *) NULL);
3845 assert(image->signature == MagickSignature);
3846 if (image->debug != MagickFalse)
3847 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3848 assert(image->blob != (BlobInfo *) NULL);
3849 assert(image->blob->type != UndefinedStream);
3851 switch (image->blob->type)
3853 case UndefinedStream:
3857 offset=ftell(image->blob->file);
3860 case StandardStream:
3865 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3866 offset=(MagickOffsetType) gztell(image->blob->file);
3876 offset=image->blob->offset;
3884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3888 + U n m a p B l o b %
3892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3894 % UnmapBlob() deallocates the binary large object previously allocated with
3895 % the MapBlob method.
3897 % The format of the UnmapBlob method is:
3899 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3901 % A description of each parameter follows:
3903 % o map: the address of the binary large object.
3905 % o length: the length of the binary large object.
3908 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3910 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3914 status=munmap(map,length);
3915 return(status == -1 ? MagickFalse : MagickTrue);
3919 return(MagickFalse);
3924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3928 + W r i t e B l o b %
3932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3934 % WriteBlob() writes data to a blob or image file. It returns the number of
3937 % The format of the WriteBlob method is:
3939 % ssize_t WriteBlob(Image *image,const size_t length,
3940 % const unsigned char *data)
3942 % A description of each parameter follows:
3944 % o image: the image.
3946 % o length: Specifies an integer representing the number of bytes to
3947 % write to the file.
3949 % o data: The address of the data to write to the blob or file.
3952 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3953 const unsigned char *data)
3958 register const unsigned char
3964 assert(image != (Image *) NULL);
3965 assert(image->signature == MagickSignature);
3966 assert(data != (const unsigned char *) NULL);
3967 assert(image->blob != (BlobInfo *) NULL);
3968 assert(image->blob->type != UndefinedStream);
3973 switch (image->blob->type)
3975 case UndefinedStream:
3978 case StandardStream:
3985 count=(ssize_t) fwrite((const char *) data,1,length,
3991 c=putc((int) *p++,image->blob->file);
3998 c=putc((int) *p++,image->blob->file);
4010 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4015 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4016 (unsigned int) length);
4021 c=gzputc(image->blob->file,(int) *p++);
4028 c=gzputc(image->blob->file,(int) *p++);
4041 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4042 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4049 count=(ssize_t) image->blob->stream(image,data,length);
4054 register unsigned char
4057 if ((image->blob->offset+(MagickOffsetType) length) >=
4058 (MagickOffsetType) image->blob->extent)
4060 if (image->blob->mapped != MagickFalse)
4062 image->blob->quantum<<=1;
4063 image->blob->extent+=length+image->blob->quantum;
4064 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4065 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4066 (void) SyncBlob(image);
4067 if (image->blob->data == (unsigned char *) NULL)
4069 (void) DetachBlob(image->blob);
4073 q=image->blob->data+image->blob->offset;
4074 (void) memcpy(q,p,length);
4075 image->blob->offset+=length;
4076 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4077 image->blob->length=(size_t) image->blob->offset;
4078 count=(ssize_t) length;
4085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4089 + W r i t e B l o b B y t e %
4093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4095 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4096 % written (either 0 or 1);
4098 % The format of the WriteBlobByte method is:
4100 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4102 % A description of each parameter follows.
4104 % o image: the image.
4106 % o value: Specifies the value to write.
4109 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4111 assert(image != (Image *) NULL);
4112 assert(image->signature == MagickSignature);
4113 return(WriteBlobStream(image,1,&value));
4117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4121 + W r i t e B l o b F l o a t %
4125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4127 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4128 % specified by the endian member of the image structure.
4130 % The format of the WriteBlobFloat method is:
4132 % ssize_t WriteBlobFloat(Image *image,const float value)
4134 % A description of each parameter follows.
4136 % o image: the image.
4138 % o value: Specifies the value to write.
4141 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4152 quantum.unsigned_value=0U;
4153 quantum.float_value=value;
4154 return(WriteBlobLong(image,quantum.unsigned_value));
4158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4162 + W r i t e B l o b L o n g %
4166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4168 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4169 % specified by the endian member of the image structure.
4171 % The format of the WriteBlobLong method is:
4173 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4175 % A description of each parameter follows.
4177 % o image: the image.
4179 % o value: Specifies the value to write.
4182 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4187 assert(image != (Image *) NULL);
4188 assert(image->signature == MagickSignature);
4189 if (image->endian == LSBEndian)
4191 buffer[0]=(unsigned char) value;
4192 buffer[1]=(unsigned char) (value >> 8);
4193 buffer[2]=(unsigned char) (value >> 16);
4194 buffer[3]=(unsigned char) (value >> 24);
4195 return(WriteBlobStream(image,4,buffer));
4197 buffer[0]=(unsigned char) (value >> 24);
4198 buffer[1]=(unsigned char) (value >> 16);
4199 buffer[2]=(unsigned char) (value >> 8);
4200 buffer[3]=(unsigned char) value;
4201 return(WriteBlobStream(image,4,buffer));
4205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4209 + W r i t e B l o b S h o r t %
4213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4215 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4216 % byte-order specified by the endian member of the image structure.
4218 % The format of the WriteBlobShort method is:
4220 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4222 % A description of each parameter follows.
4224 % o image: the image.
4226 % o value: Specifies the value to write.
4229 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4234 assert(image != (Image *) NULL);
4235 assert(image->signature == MagickSignature);
4236 if (image->endian == LSBEndian)
4238 buffer[0]=(unsigned char) value;
4239 buffer[1]=(unsigned char) (value >> 8);
4240 return(WriteBlobStream(image,2,buffer));
4242 buffer[0]=(unsigned char) (value >> 8);
4243 buffer[1]=(unsigned char) value;
4244 return(WriteBlobStream(image,2,buffer));
4248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4252 + W r i t e B l o b L S B L o n g %
4256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4258 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4259 % least-significant byte first order.
4261 % The format of the WriteBlobLSBLong method is:
4263 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4265 % A description of each parameter follows.
4267 % o image: the image.
4269 % o value: Specifies the value to write.
4272 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4277 assert(image != (Image *) NULL);
4278 assert(image->signature == MagickSignature);
4279 buffer[0]=(unsigned char) value;
4280 buffer[1]=(unsigned char) (value >> 8);
4281 buffer[2]=(unsigned char) (value >> 16);
4282 buffer[3]=(unsigned char) (value >> 24);
4283 return(WriteBlobStream(image,4,buffer));
4287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4291 + W r i t e B l o b L S B S h o r t %
4295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4297 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4298 % least-significant byte first order.
4300 % The format of the WriteBlobLSBShort method is:
4302 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4304 % A description of each parameter follows.
4306 % o image: the image.
4308 % o value: Specifies the value to write.
4311 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4316 assert(image != (Image *) NULL);
4317 assert(image->signature == MagickSignature);
4318 buffer[0]=(unsigned char) value;
4319 buffer[1]=(unsigned char) (value >> 8);
4320 return(WriteBlobStream(image,2,buffer));
4324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4328 + W r i t e B l o b M S B L o n g %
4332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4334 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4335 % most-significant byte first order.
4337 % The format of the WriteBlobMSBLong method is:
4339 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4341 % A description of each parameter follows.
4343 % o value: Specifies the value to write.
4345 % o image: the image.
4348 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4353 assert(image != (Image *) NULL);
4354 assert(image->signature == MagickSignature);
4355 buffer[0]=(unsigned char) (value >> 24);
4356 buffer[1]=(unsigned char) (value >> 16);
4357 buffer[2]=(unsigned char) (value >> 8);
4358 buffer[3]=(unsigned char) value;
4359 return(WriteBlobStream(image,4,buffer));
4363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4367 + W r i t e B l o b M S B L o n g L o n g %
4371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4373 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4374 % most-significant byte first order.
4376 % The format of the WriteBlobMSBLongLong method is:
4378 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4380 % A description of each parameter follows.
4382 % o value: Specifies the value to write.
4384 % o image: the image.
4387 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4388 const MagickSizeType value)
4393 assert(image != (Image *) NULL);
4394 assert(image->signature == MagickSignature);
4395 buffer[0]=(unsigned char) (value >> 56);
4396 buffer[1]=(unsigned char) (value >> 48);
4397 buffer[2]=(unsigned char) (value >> 40);
4398 buffer[3]=(unsigned char) (value >> 32);
4399 buffer[4]=(unsigned char) (value >> 24);
4400 buffer[5]=(unsigned char) (value >> 16);
4401 buffer[6]=(unsigned char) (value >> 8);
4402 buffer[7]=(unsigned char) value;
4403 return(WriteBlobStream(image,8,buffer));
4407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4411 + W r i t e B l o b M S B S h o r t %
4415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4417 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4418 % most-significant byte first order.
4420 % The format of the WriteBlobMSBShort method is:
4422 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4424 % A description of each parameter follows.
4426 % o value: Specifies the value to write.
4428 % o file: Specifies the file to write the data to.
4431 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4436 assert(image != (Image *) NULL);
4437 assert(image->signature == MagickSignature);
4438 buffer[0]=(unsigned char) (value >> 8);
4439 buffer[1]=(unsigned char) value;
4440 return(WriteBlobStream(image,2,buffer));
4444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4448 + W r i t e B l o b S t r i n g %
4452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4454 % WriteBlobString() write a string to a blob. It returns the number of
4455 % characters written.
4457 % The format of the WriteBlobString method is:
4459 % ssize_t WriteBlobString(Image *image,const char *string)
4461 % A description of each parameter follows.
4463 % o image: the image.
4465 % o string: Specifies the string to write.
4468 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4470 assert(image != (Image *) NULL);
4471 assert(image->signature == MagickSignature);
4472 assert(string != (const char *) NULL);
4473 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));