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 blob. It returns the
875 % file as a blob and its length. If an error occurs, NULL is returned.
877 % The format of the FileToBlob method is:
879 % unsigned char *FileToBlob(const char *filename,const size_t extent,
880 % size_t *length,ExceptionInfo *exception)
882 % A description of each parameter follows:
884 % o blob: FileToBlob() returns the contents of a file as a blob. If
885 % an error occurs NULL is returned.
887 % o filename: the filename.
889 % o extent: The maximum length of the blob.
891 % o length: On return, this reflects the actual length of the blob.
893 % o exception: return any errors or warnings in this structure.
896 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
897 size_t *length,ExceptionInfo *exception)
917 assert(filename != (const char *) NULL);
918 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
919 assert(exception != (ExceptionInfo *) NULL);
922 if (LocaleCompare(filename,"-") != 0)
923 file=open(filename,O_RDONLY | O_BINARY);
926 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
927 return((unsigned char *) NULL);
929 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
931 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
940 Stream is not seekable.
942 quantum=(size_t) MagickMaxBufferExtent;
943 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
944 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
945 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
946 for (i=0; blob != (unsigned char *) NULL; i+=count)
948 count=(ssize_t) read(file,blob+i,quantum);
955 if (~(1UL*i) < (quantum+1))
957 blob=(unsigned char *) RelinquishMagickMemory(blob);
960 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
962 if ((size_t) (i+count) >= extent)
965 if (LocaleCompare(filename,"-") != 0)
967 if (blob == (unsigned char *) NULL)
969 (void) ThrowMagickException(exception,GetMagickModule(),
970 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
971 return((unsigned char *) NULL);
975 blob=(unsigned char *) RelinquishMagickMemory(blob);
976 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
977 return((unsigned char *) NULL);
979 *length=MagickMin(i+count,extent);
983 *length=MagickMin((size_t) offset,extent);
984 blob=(unsigned char *) NULL;
985 if (~(*length) >= MaxTextExtent)
986 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
988 if (blob == (unsigned char *) NULL)
991 (void) ThrowMagickException(exception,GetMagickModule(),
992 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
993 return((unsigned char *) NULL);
995 map=MapBlob(file,ReadMode,0,*length);
996 if (map != (unsigned char *) NULL)
998 (void) memcpy(blob,map,*length);
999 (void) UnmapBlob(map,*length);
1003 (void) MagickSeek(file,0,SEEK_SET);
1004 for (i=0; i < *length; i+=count)
1006 count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
1018 blob=(unsigned char *) RelinquishMagickMemory(blob);
1019 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1020 return((unsigned char *) NULL);
1024 if (LocaleCompare(filename,"-") != 0)
1028 blob=(unsigned char *) RelinquishMagickMemory(blob);
1029 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1035 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039 % F i l e T o I m a g e %
1043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1045 % FileToImage() write the contents of a file to an image.
1047 % The format of the FileToImage method is:
1049 % MagickBooleanType FileToImage(Image *,const char *filename)
1051 % A description of each parameter follows:
1053 % o image: the image.
1055 % o filename: the filename.
1059 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1060 const unsigned char *data)
1065 register unsigned char
1068 assert(image->blob != (BlobInfo *) NULL);
1069 if (image->blob->type != BlobStream)
1070 return(WriteBlob(image,length,data));
1071 assert(image->blob->type != UndefinedStream);
1072 assert(data != (void *) NULL);
1073 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1074 if (extent >= image->blob->extent)
1076 image->blob->quantum<<=1;
1077 extent=image->blob->extent+image->blob->quantum+length;
1078 if (SetBlobExtent(image,extent) == MagickFalse)
1081 q=image->blob->data+image->blob->offset;
1082 (void) memcpy(q,data,length);
1083 image->blob->offset+=length;
1084 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1085 image->blob->length=(size_t) image->blob->offset;
1086 return((ssize_t) length);
1089 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1107 assert(image != (const Image *) NULL);
1108 assert(image->signature == MagickSignature);
1109 assert(filename != (const char *) NULL);
1110 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1111 file=open(filename,O_RDONLY | O_BINARY);
1114 ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1116 return(MagickFalse);
1118 quantum=(size_t) MagickMaxBufferExtent;
1119 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1120 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1121 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1122 if (blob == (unsigned char *) NULL)
1124 ThrowFileException(&image->exception,ResourceLimitError,
1125 "MemoryAllocationFailed",filename);
1126 return(MagickFalse);
1130 count=(ssize_t) read(file,blob,quantum);
1137 length=(size_t) count;
1138 count=WriteBlobStream(image,length,blob);
1139 if (count != (ssize_t) length)
1141 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1148 ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1150 blob=(unsigned char *) RelinquishMagickMemory(blob);
1155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1159 + G e t B l o b E r r o r %
1163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1165 % GetBlobError() returns MagickTrue if the blob associated with the specified
1166 % image encountered an error.
1168 % The format of the GetBlobError method is:
1170 % MagickBooleanType GetBlobError(const Image *image)
1172 % A description of each parameter follows:
1174 % o image: the image.
1177 MagickExport MagickBooleanType GetBlobError(const Image *image)
1179 assert(image != (const Image *) NULL);
1180 assert(image->signature == MagickSignature);
1181 if (image->debug != MagickFalse)
1182 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1183 return(image->blob->status);
1187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191 + G e t B l o b F i l e H a n d l e %
1195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1197 % GetBlobFileHandle() returns the file handle associated with the image blob.
1199 % The format of the GetBlobFile method is:
1201 % FILE *GetBlobFileHandle(const Image *image)
1203 % A description of each parameter follows:
1205 % o image: the image.
1208 MagickExport FILE *GetBlobFileHandle(const Image *image)
1210 assert(image != (const Image *) NULL);
1211 assert(image->signature == MagickSignature);
1212 return(image->blob->file);
1216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220 + G e t B l o b I n f o %
1224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226 % GetBlobInfo() initializes the BlobInfo structure.
1228 % The format of the GetBlobInfo method is:
1230 % void GetBlobInfo(BlobInfo *blob_info)
1232 % A description of each parameter follows:
1234 % o blob_info: Specifies a pointer to a BlobInfo structure.
1237 MagickExport void GetBlobInfo(BlobInfo *blob_info)
1239 assert(blob_info != (BlobInfo *) NULL);
1240 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1241 blob_info->type=UndefinedStream;
1242 blob_info->quantum=(size_t) MagickMaxBlobExtent;
1243 blob_info->properties.st_mtime=time((time_t *) NULL);
1244 blob_info->properties.st_ctime=time((time_t *) NULL);
1245 blob_info->debug=IsEventLogging();
1246 blob_info->reference_count=1;
1247 blob_info->semaphore=AllocateSemaphoreInfo();
1248 blob_info->signature=MagickSignature;
1252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1256 % G e t B l o b P r o p e r t i e s %
1260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262 % GetBlobProperties() returns information about an image blob.
1264 % The format of the GetBlobProperties method is:
1266 % const struct stat *GetBlobProperties(const Image *image)
1268 % A description of each parameter follows:
1270 % o image: the image.
1273 MagickExport const struct stat *GetBlobProperties(const Image *image)
1275 assert(image != (Image *) NULL);
1276 assert(image->signature == MagickSignature);
1277 if (image->debug != MagickFalse)
1278 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1279 return(&image->blob->properties);
1283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1287 + G e t B l o b S i z e %
1291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293 % GetBlobSize() returns the current length of the image file or blob; zero is
1294 % returned if the size cannot be determined.
1296 % The format of the GetBlobSize method is:
1298 % MagickSizeType GetBlobSize(const Image *image)
1300 % A description of each parameter follows:
1302 % o image: the image.
1305 MagickExport MagickSizeType GetBlobSize(const Image *image)
1310 assert(image != (Image *) NULL);
1311 assert(image->signature == MagickSignature);
1312 if (image->debug != MagickFalse)
1313 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1314 assert(image->blob != (BlobInfo *) NULL);
1316 switch (image->blob->type)
1318 case UndefinedStream:
1320 extent=image->blob->size;
1325 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1326 extent=(MagickSizeType) image->blob->properties.st_size;
1329 case StandardStream:
1332 extent=image->blob->size;
1341 status=GetPathAttributes(image->filename,&image->blob->properties);
1342 if (status != MagickFalse)
1343 extent=(MagickSizeType) image->blob->properties.st_size;
1350 extent=(MagickSizeType) image->blob->length;
1358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1362 + G e t B l o b S t r e a m D a t a %
1366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1368 % GetBlobStreamData() returns the stream data for the image.
1370 % The format of the GetBlobStreamData method is:
1372 % unsigned char *GetBlobStreamData(const Image *image)
1374 % A description of each parameter follows:
1376 % o image: the image.
1379 MagickExport unsigned char *GetBlobStreamData(const Image *image)
1381 assert(image != (const Image *) NULL);
1382 assert(image->signature == MagickSignature);
1383 return(image->blob->data);
1387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1391 + G e t B l o b S t r e a m H a n d l e r %
1395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1397 % GetBlobStreamHandler() returns the stream handler for the image.
1399 % The format of the GetBlobStreamHandler method is:
1401 % StreamHandler GetBlobStreamHandler(const Image *image)
1403 % A description of each parameter follows:
1405 % o image: the image.
1408 MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1410 assert(image != (const Image *) NULL);
1411 assert(image->signature == MagickSignature);
1412 if (image->debug != MagickFalse)
1413 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1414 return(image->blob->stream);
1418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1422 % I m a g e T o B l o b %
1426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 % ImageToBlob() implements direct to memory image formats. It returns the
1429 % image as a blob and its length. The magick member of the ImageInfo structure
1430 % determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1432 % The format of the ImageToBlob method is:
1434 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1435 % size_t *length,ExceptionInfo *exception)
1437 % A description of each parameter follows:
1439 % o image_info: the image info.
1441 % o image: the image.
1443 % o length: This pointer to a size_t integer sets the initial length of the
1444 % blob. On return, it reflects the actual length of the blob.
1446 % o exception: return any errors or warnings in this structure.
1449 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1450 Image *image,size_t *length,ExceptionInfo *exception)
1464 assert(image_info != (const ImageInfo *) NULL);
1465 assert(image_info->signature == MagickSignature);
1466 if (image_info->debug != MagickFalse)
1467 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1468 image_info->filename);
1469 assert(image != (Image *) NULL);
1470 assert(image->signature == MagickSignature);
1471 assert(exception != (ExceptionInfo *) NULL);
1473 blob=(unsigned char *) NULL;
1474 blob_info=CloneImageInfo(image_info);
1475 blob_info->adjoin=MagickFalse;
1476 (void) SetImageInfo(blob_info,1,exception);
1477 if (*blob_info->magick != '\0')
1478 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1479 magick_info=GetMagickInfo(image->magick,exception);
1480 if (magick_info == (const MagickInfo *) NULL)
1482 (void) ThrowMagickException(exception,GetMagickModule(),
1483 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1487 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1488 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1491 Native blob support for this image format.
1493 blob_info->length=0;
1494 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1495 sizeof(unsigned char));
1496 if (blob_info->blob == (void *) NULL)
1497 (void) ThrowMagickException(exception,GetMagickModule(),
1498 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1501 (void) CloseBlob(image);
1502 image->blob->exempt=MagickTrue;
1503 *image->filename='\0';
1504 status=WriteImage(blob_info,image);
1505 if ((status == MagickFalse) || (image->blob->length == 0))
1506 InheritException(exception,&image->exception);
1509 *length=image->blob->length;
1510 blob=DetachBlob(image->blob);
1511 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1519 unique[MaxTextExtent];
1525 Write file to disk in blob image format.
1527 file=AcquireUniqueFileResource(unique);
1530 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1531 image_info->filename);
1535 blob_info->file=fdopen(file,"wb");
1536 if (blob_info->file != (FILE *) NULL)
1538 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1539 image->magick,unique);
1540 status=WriteImage(blob_info,image);
1541 (void) fclose(blob_info->file);
1542 if (status == MagickFalse)
1543 InheritException(exception,&image->exception);
1545 blob=FileToBlob(image->filename,~0UL,length,exception);
1547 (void) RelinquishUniqueFileResource(unique);
1550 blob_info=DestroyImageInfo(blob_info);
1555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1559 % I m a g e T o F i l e %
1563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1566 % occurs otherwise MagickTrue.
1568 % The format of the ImageToFile method is:
1570 % MagickBooleanType ImageToFile(Image *image,char *filename,
1571 % ExceptionInfo *exception)
1573 % A description of each parameter follows:
1575 % o image: the image.
1577 % o filename: Write the image to this file.
1579 % o exception: return any errors or warnings in this structure.
1582 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1583 ExceptionInfo *exception)
1588 register const unsigned char
1607 assert(image != (Image *) NULL);
1608 assert(image->signature == MagickSignature);
1609 assert(image->blob != (BlobInfo *) NULL);
1610 assert(image->blob->type != UndefinedStream);
1611 if (image->debug != MagickFalse)
1612 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1613 assert(filename != (const char *) NULL);
1614 if (*filename == '\0')
1615 file=AcquireUniqueFileResource(filename);
1617 if (LocaleCompare(filename,"-") == 0)
1618 file=fileno(stdout);
1620 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1623 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1624 return(MagickFalse);
1626 quantum=(size_t) MagickMaxBufferExtent;
1627 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1628 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1629 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1630 if (buffer == (unsigned char *) NULL)
1633 (void) ThrowMagickException(exception,GetMagickModule(),
1634 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1635 return(MagickFalse);
1638 p=ReadBlobStream(image,quantum,buffer,&count);
1639 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1641 length=(size_t) count;
1642 for (i=0; i < length; i+=count)
1644 count=write(file,p+i,(size_t) (length-i));
1655 if (LocaleCompare(filename,"-") != 0)
1657 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1658 if ((file == -1) || (i < length))
1660 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1661 return(MagickFalse);
1667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1671 % I m a g e s T o B l o b %
1675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1677 % ImagesToBlob() implements direct to memory image formats. It returns the
1678 % image sequence as a blob and its length. The magick member of the ImageInfo
1679 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1681 % Note, some image formats do not permit multiple images to the same image
1682 % stream (e.g. JPEG). in this instance, just the first image of the
1683 % sequence is returned as a blob.
1685 % The format of the ImagesToBlob method is:
1687 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1688 % size_t *length,ExceptionInfo *exception)
1690 % A description of each parameter follows:
1692 % o image_info: the image info.
1694 % o images: the image list.
1696 % o length: This pointer to a size_t integer sets the initial length of the
1697 % blob. On return, it reflects the actual length of the blob.
1699 % o exception: return any errors or warnings in this structure.
1702 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1703 Image *images,size_t *length,ExceptionInfo *exception)
1717 assert(image_info != (const ImageInfo *) NULL);
1718 assert(image_info->signature == MagickSignature);
1719 if (image_info->debug != MagickFalse)
1720 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1721 image_info->filename);
1722 assert(images != (Image *) NULL);
1723 assert(images->signature == MagickSignature);
1724 assert(exception != (ExceptionInfo *) NULL);
1726 blob=(unsigned char *) NULL;
1727 blob_info=CloneImageInfo(image_info);
1728 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1730 if (*blob_info->magick != '\0')
1731 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1732 if (blob_info->adjoin == MagickFalse)
1734 blob_info=DestroyImageInfo(blob_info);
1735 return(ImageToBlob(image_info,images,length,exception));
1737 magick_info=GetMagickInfo(images->magick,exception);
1738 if (magick_info == (const MagickInfo *) NULL)
1740 (void) ThrowMagickException(exception,GetMagickModule(),
1741 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1745 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1746 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1749 Native blob support for this images format.
1751 blob_info->length=0;
1752 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1753 sizeof(unsigned char));
1754 if (blob_info->blob == (void *) NULL)
1755 (void) ThrowMagickException(exception,GetMagickModule(),
1756 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1759 images->blob->exempt=MagickTrue;
1760 *images->filename='\0';
1761 status=WriteImages(blob_info,images,images->filename,exception);
1762 if ((status == MagickFalse) || (images->blob->length == 0))
1763 InheritException(exception,&images->exception);
1766 *length=images->blob->length;
1767 blob=DetachBlob(images->blob);
1768 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1776 filename[MaxTextExtent],
1777 unique[MaxTextExtent];
1783 Write file to disk in blob images format.
1785 file=AcquireUniqueFileResource(unique);
1788 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1789 image_info->filename);
1793 blob_info->file=fdopen(file,"wb");
1794 if (blob_info->file != (FILE *) NULL)
1796 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1797 images->magick,unique);
1798 status=WriteImages(blob_info,images,filename,exception);
1799 (void) fclose(blob_info->file);
1800 if (status == MagickFalse)
1801 InheritException(exception,&images->exception);
1803 blob=FileToBlob(images->filename,~0UL,length,exception);
1805 (void) RelinquishUniqueFileResource(unique);
1808 blob_info=DestroyImageInfo(blob_info);
1812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1816 % I n j e c t I m a g e B l o b %
1820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1822 % InjectImageBlob() injects the image with a copy of itself in the specified
1823 % format (e.g. inject JPEG into a PDF image).
1825 % The format of the InjectImageBlob method is:
1827 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1828 % Image *image,Image *inject_image,const char *format,
1829 % ExceptionInfo *exception)
1831 % A description of each parameter follows:
1833 % o image_info: the image info..
1835 % o image: the image.
1837 % o inject_image: inject into the image stream.
1839 % o format: the image format.
1841 % o exception: return any errors or warnings in this structure.
1844 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1845 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1848 filename[MaxTextExtent];
1881 Write inject image to a temporary file.
1883 assert(image_info != (ImageInfo *) NULL);
1884 assert(image_info->signature == MagickSignature);
1885 assert(image != (Image *) NULL);
1886 assert(image->signature == MagickSignature);
1887 if (image->debug != MagickFalse)
1888 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1889 assert(inject_image != (Image *) NULL);
1890 assert(inject_image->signature == MagickSignature);
1891 assert(exception != (ExceptionInfo *) NULL);
1892 unique_file=(FILE *) NULL;
1893 file=AcquireUniqueFileResource(filename);
1895 unique_file=fdopen(file,"wb");
1896 if ((file == -1) || (unique_file == (FILE *) NULL))
1898 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1899 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1901 return(MagickFalse);
1903 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1904 if (byte_image == (Image *) NULL)
1906 (void) fclose(unique_file);
1907 (void) RelinquishUniqueFileResource(filename);
1908 return(MagickFalse);
1910 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1912 DestroyBlob(byte_image);
1913 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1914 write_info=CloneImageInfo(image_info);
1915 SetImageInfoFile(write_info,unique_file);
1916 status=WriteImage(write_info,byte_image);
1917 write_info=DestroyImageInfo(write_info);
1918 byte_image=DestroyImage(byte_image);
1919 (void) fclose(unique_file);
1920 if (status == MagickFalse)
1922 (void) RelinquishUniqueFileResource(filename);
1923 return(MagickFalse);
1926 Inject into image stream.
1928 file=open(filename,O_RDONLY | O_BINARY);
1931 (void) RelinquishUniqueFileResource(filename);
1932 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1933 image_info->filename);
1934 return(MagickFalse);
1936 quantum=(size_t) MagickMaxBufferExtent;
1937 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1938 quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
1939 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1940 if (buffer == (unsigned char *) NULL)
1942 (void) RelinquishUniqueFileResource(filename);
1943 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1946 for (i=0; ; i+=count)
1948 count=(ssize_t) read(file,buffer,quantum);
1955 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1960 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1961 (void) RelinquishUniqueFileResource(filename);
1962 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1971 + I s B l o b E x e m p t %
1975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1977 % IsBlobExempt() returns true if the blob is exempt.
1979 % The format of the IsBlobExempt method is:
1981 % MagickBooleanType IsBlobExempt(const Image *image)
1983 % A description of each parameter follows:
1985 % o image: the image.
1988 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1990 assert(image != (const Image *) NULL);
1991 assert(image->signature == MagickSignature);
1992 if (image->debug != MagickFalse)
1993 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1994 return(image->blob->exempt);
1998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2002 + I s B l o b S e e k a b l e %
2006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2008 % IsBlobSeekable() returns true if the blob is seekable.
2010 % The format of the IsBlobSeekable method is:
2012 % MagickBooleanType IsBlobSeekable(const Image *image)
2014 % A description of each parameter follows:
2016 % o image: the image.
2019 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2024 assert(image != (const Image *) NULL);
2025 assert(image->signature == MagickSignature);
2026 if (image->debug != MagickFalse)
2027 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2028 seekable=(image->blob->type == FileStream) ||
2029 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2038 + I s B l o b T e m p o r a r y %
2042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2044 % IsBlobTemporary() returns true if the blob is temporary.
2046 % The format of the IsBlobTemporary method is:
2048 % MagickBooleanType IsBlobTemporary(const Image *image)
2050 % A description of each parameter follows:
2052 % o image: the image.
2055 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2057 assert(image != (const Image *) NULL);
2058 assert(image->signature == MagickSignature);
2059 if (image->debug != MagickFalse)
2060 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2061 return(image->blob->temporary);
2065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2075 % MapBlob() creates a mapping from a file to a binary large object.
2077 % The format of the MapBlob method is:
2079 % unsigned char *MapBlob(int file,const MapMode mode,
2080 % const MagickOffsetType offset,const size_t length)
2082 % A description of each parameter follows:
2084 % o file: map this file descriptor.
2086 % o mode: ReadMode, WriteMode, or IOMode.
2088 % o offset: starting at this offset within the file.
2090 % o length: the length of the mapping is returned in this pointer.
2093 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2094 const MagickOffsetType offset,const size_t length)
2096 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2109 #if defined(MAP_ANONYMOUS)
2110 flags|=MAP_ANONYMOUS;
2112 return((unsigned char *) NULL);
2119 protection=PROT_READ;
2121 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2127 protection=PROT_WRITE;
2129 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2131 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2132 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2133 POSIX_MADV_WILLNEED);
2139 protection=PROT_READ | PROT_WRITE;
2141 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2146 if (map == (unsigned char *) MAP_FAILED)
2147 return((unsigned char *) NULL);
2154 return((unsigned char *) NULL);
2159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2163 + M S B O r d e r L o n g %
2167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2169 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2170 % most-significant byte first.
2172 % The format of the MSBOrderLong method is:
2174 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2176 % A description of each parameter follows.
2178 % o buffer: Specifies a pointer to a buffer of integers.
2180 % o length: Specifies the length of the buffer.
2183 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2188 register unsigned char
2192 assert(buffer != (unsigned char *) NULL);
2199 *buffer++=(unsigned char) c;
2203 *buffer++=(unsigned char) c;
2209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2213 + M S B O r d e r S h o r t %
2217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2219 % MSBOrderShort() converts a least-significant byte first buffer of integers
2220 % to most-significant byte first.
2222 % The format of the MSBOrderShort method is:
2224 % void MSBOrderShort(unsigned char *p,const size_t length)
2226 % A description of each parameter follows.
2228 % o p: Specifies a pointer to a buffer of integers.
2230 % o length: Specifies the length of the buffer.
2233 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2238 register unsigned char
2241 assert(p != (unsigned char *) NULL);
2248 *p++=(unsigned char) c;
2253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2263 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2264 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2265 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2266 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2267 % from a system command.
2269 % The format of the OpenBlob method is:
2271 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2272 % const BlobMode mode,ExceptionInfo *exception)
2274 % A description of each parameter follows:
2276 % o image_info: the image info.
2278 % o image: the image.
2280 % o mode: the mode for opening the file.
2283 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2284 Image *image,const BlobMode mode,ExceptionInfo *exception)
2287 extension[MaxTextExtent],
2288 filename[MaxTextExtent];
2299 assert(image_info != (ImageInfo *) NULL);
2300 assert(image_info->signature == MagickSignature);
2301 if (image_info->debug != MagickFalse)
2302 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2303 image_info->filename);
2304 assert(image != (Image *) NULL);
2305 assert(image->signature == MagickSignature);
2306 if (image_info->blob != (void *) NULL)
2308 if (image_info->stream != (StreamHandler) NULL)
2309 image->blob->stream=(StreamHandler) image_info->stream;
2310 AttachBlob(image->blob,image_info->blob,image_info->length);
2313 (void) DetachBlob(image->blob);
2316 default: type="r"; break;
2317 case ReadBlobMode: type="r"; break;
2318 case ReadBinaryBlobMode: type="rb"; break;
2319 case WriteBlobMode: type="w"; break;
2320 case WriteBinaryBlobMode: type="w+b"; break;
2321 case AppendBlobMode: type="a"; break;
2322 case AppendBinaryBlobMode: type="a+b"; break;
2325 image->blob->synchronize=image_info->synchronize;
2326 if (image_info->stream != (StreamHandler) NULL)
2328 image->blob->stream=(StreamHandler) image_info->stream;
2331 image->blob->type=FifoStream;
2339 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2340 rights=ReadPolicyRights;
2342 rights=WritePolicyRights;
2343 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2346 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2347 "NotAuthorized","`%s'",filename);
2348 return(MagickFalse);
2350 if ((LocaleCompare(filename,"-") == 0) ||
2351 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2353 image->blob->file=(*type == 'r') ? stdin : stdout;
2354 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2355 if (strchr(type,'b') != (char *) NULL)
2356 setmode(_fileno(image->blob->file),_O_BINARY);
2358 image->blob->type=StandardStream;
2359 image->blob->exempt=MagickTrue;
2362 if (LocaleNCompare(filename,"fd:",3) == 0)
2365 mode[MaxTextExtent];
2369 image->blob->file=fdopen(StringToLong(filename+3),mode);
2370 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2371 if (strchr(type,'b') != (char *) NULL)
2372 setmode(_fileno(image->blob->file),_O_BINARY);
2374 image->blob->type=StandardStream;
2375 image->blob->exempt=MagickTrue;
2378 #if defined(MAGICKCORE_HAVE_POPEN)
2379 if (*filename == '|')
2382 mode[MaxTextExtent];
2385 Pipe image to or from a system command.
2387 #if defined(SIGPIPE)
2389 (void) signal(SIGPIPE,SIG_IGN);
2393 image->blob->file=(FILE *) popen(filename+1,mode);
2394 if (image->blob->file == (FILE *) NULL)
2396 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2397 return(MagickFalse);
2399 image->blob->type=PipeStream;
2400 image->blob->exempt=MagickTrue;
2404 status=GetPathAttributes(filename,&image->blob->properties);
2405 #if defined(S_ISFIFO)
2406 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2408 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2409 if (image->blob->file == (FILE *) NULL)
2411 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2412 return(MagickFalse);
2414 image->blob->type=FileStream;
2415 image->blob->exempt=MagickTrue;
2419 GetPathComponent(image->filename,ExtensionPath,extension);
2422 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2423 if ((image_info->adjoin == MagickFalse) ||
2424 (IsGlob(filename) != MagickFalse))
2427 Form filename for multi-part images.
2429 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2430 image->scene,filename);
2431 if ((LocaleCompare(filename,image->filename) == 0) &&
2432 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2433 (GetNextImageInList(image) != (Image *) NULL)))
2436 path[MaxTextExtent];
2438 GetPathComponent(image->filename,RootPath,path);
2439 if (*extension == '\0')
2440 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2441 path,(double) image->scene);
2443 (void) FormatMagickString(filename,MaxTextExtent,
2444 "%s-%.20g.%s",path,(double) image->scene,extension);
2446 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2447 #if defined(macintosh)
2448 SetApplicationType(filename,image_info->magick,'8BIM');
2452 if (image_info->file != (FILE *) NULL)
2454 image->blob->file=image_info->file;
2455 image->blob->type=FileStream;
2456 image->blob->exempt=MagickTrue;
2461 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2462 if (image->blob->file != (FILE *) NULL)
2470 image->blob->type=FileStream;
2471 #if defined(MAGICKCORE_HAVE_SETVBUF)
2472 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2474 (void) ResetMagickMemory(magick,0,sizeof(magick));
2475 count=fread(magick,1,sizeof(magick),image->blob->file);
2476 (void) rewind(image->blob->file);
2477 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2478 " read %.20g magic header bytes",(double) count);
2479 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2480 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2481 ((int) magick[2] == 0x08))
2483 (void) fclose(image->blob->file);
2484 image->blob->file=(FILE *) gzopen(filename,type);
2485 if (image->blob->file != (FILE *) NULL)
2486 image->blob->type=ZipStream;
2489 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2490 if (strncmp((char *) magick,"BZh",3) == 0)
2492 (void) fclose(image->blob->file);
2493 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2494 if (image->blob->file != (FILE *) NULL)
2495 image->blob->type=BZipStream;
2498 if (image->blob->type == FileStream)
2509 sans_exception=AcquireExceptionInfo();
2510 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2511 sans_exception=DestroyExceptionInfo(sans_exception);
2512 properties=(&image->blob->properties);
2513 if ((magick_info != (const MagickInfo *) NULL) &&
2514 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2515 (properties->st_size <= MagickMaxBufferExtent))
2523 length=(size_t) properties->st_size;
2524 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2525 if (blob != (void *) NULL)
2528 Format supports blobs-- use memory-mapped I/O.
2530 if (image_info->file != (FILE *) NULL)
2531 image->blob->exempt=MagickFalse;
2534 (void) fclose(image->blob->file);
2535 image->blob->file=(FILE *) NULL;
2537 AttachBlob(image->blob,blob,length);
2538 image->blob->mapped=MagickTrue;
2545 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2546 if ((LocaleCompare(extension,"Z") == 0) ||
2547 (LocaleCompare(extension,"gz") == 0) ||
2548 (LocaleCompare(extension,"wmz") == 0) ||
2549 (LocaleCompare(extension,"svgz") == 0))
2551 if (mode == WriteBinaryBlobMode)
2553 image->blob->file=(FILE *) gzopen(filename,type);
2554 if (image->blob->file != (FILE *) NULL)
2555 image->blob->type=ZipStream;
2559 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2560 if (LocaleCompare(extension,".bz2") == 0)
2562 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2563 if (image->blob->file != (FILE *) NULL)
2564 image->blob->type=BZipStream;
2569 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2570 if (image->blob->file != (FILE *) NULL)
2572 image->blob->type=FileStream;
2573 #if defined(MAGICKCORE_HAVE_SETVBUF)
2574 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2579 image->blob->status=MagickFalse;
2580 if (image->blob->type != UndefinedStream)
2581 image->blob->size=GetBlobSize(image);
2584 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2585 return(MagickFalse);
2591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2601 % PingBlob() returns all the attributes of an image or image sequence except
2602 % for the pixels. It is much faster and consumes far less memory than
2603 % BlobToImage(). On failure, a NULL image is returned and exception
2604 % describes the reason for the failure.
2606 % The format of the PingBlob method is:
2608 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2609 % const size_t length,ExceptionInfo *exception)
2611 % A description of each parameter follows:
2613 % o image_info: the image info.
2615 % o blob: the address of a character stream in one of the image formats
2616 % understood by ImageMagick.
2618 % o length: This size_t integer reflects the length in bytes of the blob.
2620 % o exception: return any errors or warnings in this structure.
2624 #if defined(__cplusplus) || defined(c_plusplus)
2628 static size_t PingStream(const Image *magick_unused(image),
2629 const void *magick_unused(pixels),const size_t columns)
2634 #if defined(__cplusplus) || defined(c_plusplus)
2638 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2639 const size_t length,ExceptionInfo *exception)
2647 assert(image_info != (ImageInfo *) NULL);
2648 assert(image_info->signature == MagickSignature);
2649 if (image_info->debug != MagickFalse)
2650 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2651 image_info->filename);
2652 assert(exception != (ExceptionInfo *) NULL);
2653 if ((blob == (const void *) NULL) || (length == 0))
2655 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2656 "UnrecognizedImageFormat","`%s'",image_info->magick);
2657 return((Image *) NULL);
2659 ping_info=CloneImageInfo(image_info);
2660 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2661 if (ping_info->blob == (const void *) NULL)
2663 (void) ThrowMagickException(exception,GetMagickModule(),
2664 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2665 return((Image *) NULL);
2667 (void) memcpy(ping_info->blob,blob,length);
2668 ping_info->length=length;
2669 ping_info->ping=MagickTrue;
2670 image=ReadStream(ping_info,&PingStream,exception);
2671 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2672 ping_info=DestroyImageInfo(ping_info);
2677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2687 % ReadBlob() reads data from the blob or image file and returns it. It
2688 % returns the number of bytes read.
2690 % The format of the ReadBlob method is:
2692 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2694 % A description of each parameter follows:
2696 % o image: the image.
2698 % o length: Specifies an integer representing the number of bytes to read
2701 % o data: Specifies an area to place the information requested from the
2705 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2706 unsigned char *data)
2711 register unsigned char
2717 assert(image != (Image *) NULL);
2718 assert(image->signature == MagickSignature);
2719 assert(image->blob != (BlobInfo *) NULL);
2720 assert(image->blob->type != UndefinedStream);
2723 assert(data != (void *) NULL);
2726 switch (image->blob->type)
2728 case UndefinedStream:
2731 case StandardStream:
2738 count=(ssize_t) fread(q,1,length,image->blob->file);
2743 c=getc(image->blob->file);
2746 *q++=(unsigned char) c;
2751 c=getc(image->blob->file);
2754 *q++=(unsigned char) c;
2764 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2769 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2774 c=gzgetc(image->blob->file);
2777 *q++=(unsigned char) c;
2782 c=gzgetc(image->blob->file);
2785 *q++=(unsigned char) c;
2796 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2797 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2805 register const unsigned char
2808 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2810 image->blob->eof=MagickTrue;
2813 p=image->blob->data+image->blob->offset;
2814 count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
2815 image->blob->offset));
2816 image->blob->offset+=count;
2817 if (count != (ssize_t) length)
2818 image->blob->eof=MagickTrue;
2819 (void) memcpy(q,p,(size_t) count);
2827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2831 + R e a d B l o b B y t e %
2835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2837 % ReadBlobByte() reads a single byte from the image file and returns it.
2839 % The format of the ReadBlobByte method is:
2841 % int ReadBlobByte(Image *image)
2843 % A description of each parameter follows.
2845 % o image: the image.
2848 MagickExport int ReadBlobByte(Image *image)
2850 register const unsigned char
2859 assert(image != (Image *) NULL);
2860 assert(image->signature == MagickSignature);
2861 p=ReadBlobStream(image,1,buffer,&count);
2868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2872 + R e a d B l o b D o u b l e %
2876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2878 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2879 % specified by the endian member of the image structure.
2881 % The format of the ReadBlobDouble method is:
2883 % double ReadBlobDouble(Image *image)
2885 % A description of each parameter follows.
2887 % o image: the image.
2890 MagickExport double ReadBlobDouble(Image *image)
2901 quantum.double_value=0.0;
2902 quantum.unsigned_value=ReadBlobLongLong(image);
2903 return(quantum.double_value);
2907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2911 + R e a d B l o b F l o a t %
2915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2917 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2918 % specified by the endian member of the image structure.
2920 % The format of the ReadBlobFloat method is:
2922 % float ReadBlobFloat(Image *image)
2924 % A description of each parameter follows.
2926 % o image: the image.
2929 MagickExport float ReadBlobFloat(Image *image)
2940 quantum.float_value=0.0;
2941 quantum.unsigned_value=ReadBlobLong(image);
2942 return(quantum.float_value);
2946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2950 + R e a d B l o b L o n g %
2954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2956 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2957 % specified by the endian member of the image structure.
2959 % The format of the ReadBlobLong method is:
2961 % unsigned int ReadBlobLong(Image *image)
2963 % A description of each parameter follows.
2965 % o image: the image.
2968 MagickExport unsigned int ReadBlobLong(Image *image)
2970 register const unsigned char
2982 assert(image != (Image *) NULL);
2983 assert(image->signature == MagickSignature);
2985 p=ReadBlobStream(image,4,buffer,&count);
2988 if (image->endian == LSBEndian)
2990 value=(unsigned int) (*p++);
2991 value|=((unsigned int) (*p++)) << 8;
2992 value|=((unsigned int) (*p++)) << 16;
2993 value|=((unsigned int) (*p++)) << 24;
2996 value=((unsigned int) (*p++)) << 24;
2997 value|=((unsigned int) (*p++)) << 16;
2998 value|=((unsigned int) (*p++)) << 8;
2999 value|=((unsigned int) (*p++));
3004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3008 + R e a d B l o b L o n g L o n g %
3012 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3014 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3015 % byte-order specified by the endian member of the image structure.
3017 % The format of the ReadBlobLongLong method is:
3019 % MagickSizeType ReadBlobLongLong(Image *image)
3021 % A description of each parameter follows.
3023 % o image: the image.
3026 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3031 register const unsigned char
3040 assert(image != (Image *) NULL);
3041 assert(image->signature == MagickSignature);
3043 p=ReadBlobStream(image,8,buffer,&count);
3045 return(MagickULLConstant(0));
3046 if (image->endian == LSBEndian)
3048 value=(MagickSizeType) (*p++);
3049 value|=((MagickSizeType) (*p++)) << 8;
3050 value|=((MagickSizeType) (*p++)) << 16;
3051 value|=((MagickSizeType) (*p++)) << 24;
3052 value|=((MagickSizeType) (*p++)) << 32;
3053 value|=((MagickSizeType) (*p++)) << 40;
3054 value|=((MagickSizeType) (*p++)) << 48;
3055 value|=((MagickSizeType) (*p++)) << 56;
3056 return(value & MagickULLConstant(0xffffffffffffffff));
3058 value=((MagickSizeType) (*p++)) << 56;
3059 value|=((MagickSizeType) (*p++)) << 48;
3060 value|=((MagickSizeType) (*p++)) << 40;
3061 value|=((MagickSizeType) (*p++)) << 32;
3062 value|=((MagickSizeType) (*p++)) << 24;
3063 value|=((MagickSizeType) (*p++)) << 16;
3064 value|=((MagickSizeType) (*p++)) << 8;
3065 value|=((MagickSizeType) (*p++));
3066 return(value & MagickULLConstant(0xffffffffffffffff));
3070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3074 + R e a d B l o b S h o r t %
3078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3080 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3081 % specified by the endian member of the image structure.
3083 % The format of the ReadBlobShort method is:
3085 % unsigned short ReadBlobShort(Image *image)
3087 % A description of each parameter follows.
3089 % o image: the image.
3092 MagickExport unsigned short ReadBlobShort(Image *image)
3094 register const unsigned char
3097 register unsigned int
3106 assert(image != (Image *) NULL);
3107 assert(image->signature == MagickSignature);
3109 p=ReadBlobStream(image,2,buffer,&count);
3111 return((unsigned short) 0U);
3112 if (image->endian == LSBEndian)
3114 value=(unsigned int) (*p++);
3115 value|=((unsigned int) (*p++)) << 8;
3116 return((unsigned short) (value & 0xffff));
3118 value=(unsigned int) ((*p++) << 8);
3119 value|=(unsigned int) (*p++);
3120 return((unsigned short) (value & 0xffff));
3124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3128 + R e a d B l o b L S B L o n g %
3132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3134 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3135 % least-significant byte first order.
3137 % The format of the ReadBlobLSBLong method is:
3139 % unsigned int ReadBlobLSBLong(Image *image)
3141 % A description of each parameter follows.
3143 % o image: the image.
3146 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3148 register const unsigned char
3151 register unsigned int
3160 assert(image != (Image *) NULL);
3161 assert(image->signature == MagickSignature);
3163 p=ReadBlobStream(image,4,buffer,&count);
3166 value=(unsigned int) (*p++);
3167 value|=((unsigned int) (*p++)) << 8;
3168 value|=((unsigned int) (*p++)) << 16;
3169 value|=((unsigned int) (*p++)) << 24;
3174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3178 + R e a d B l o b L S B S h o r t %
3182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3184 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3185 % least-significant byte first order.
3187 % The format of the ReadBlobLSBShort method is:
3189 % unsigned short ReadBlobLSBShort(Image *image)
3191 % A description of each parameter follows.
3193 % o image: the image.
3196 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3198 register const unsigned char
3201 register unsigned int
3210 assert(image != (Image *) NULL);
3211 assert(image->signature == MagickSignature);
3213 p=ReadBlobStream(image,2,buffer,&count);
3215 return((unsigned short) 0U);
3216 value=(unsigned int) (*p++);
3217 value|=((unsigned int) ((*p++)) << 8);
3218 return((unsigned short) (value & 0xffff));
3222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3226 + R e a d B l o b M S B L o n g %
3230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3232 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3233 % most-significant byte first order.
3235 % The format of the ReadBlobMSBLong method is:
3237 % unsigned int ReadBlobMSBLong(Image *image)
3239 % A description of each parameter follows.
3241 % o image: the image.
3244 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3246 register const unsigned char
3249 register unsigned int
3258 assert(image != (Image *) NULL);
3259 assert(image->signature == MagickSignature);
3261 p=ReadBlobStream(image,4,buffer,&count);
3264 value=((unsigned int) (*p++) << 24);
3265 value|=((unsigned int) (*p++) << 16);
3266 value|=((unsigned int) (*p++) << 8);
3267 value|=(unsigned int) (*p++);
3272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3276 + R e a d B l o b M S B L o n g L o n g %
3280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3282 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3283 % most-significant byte first order.
3285 % The format of the ReadBlobMSBLongLong method is:
3287 % unsigned int ReadBlobMSBLongLong(Image *image)
3289 % A description of each parameter follows.
3291 % o image: the image.
3294 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3296 register const unsigned char
3299 register MagickSizeType
3308 assert(image != (Image *) NULL);
3309 assert(image->signature == MagickSignature);
3311 p=ReadBlobStream(image,8,buffer,&count);
3313 return(MagickULLConstant(0));
3314 value=((MagickSizeType) (*p++)) << 56;
3315 value|=((MagickSizeType) (*p++)) << 48;
3316 value|=((MagickSizeType) (*p++)) << 40;
3317 value|=((MagickSizeType) (*p++)) << 32;
3318 value|=((MagickSizeType) (*p++)) << 24;
3319 value|=((MagickSizeType) (*p++)) << 16;
3320 value|=((MagickSizeType) (*p++)) << 8;
3321 value|=((MagickSizeType) (*p++));
3322 return(value & MagickULLConstant(0xffffffffffffffff));
3326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3330 + R e a d B l o b M S B S h o r t %
3334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3336 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3337 % most-significant byte first order.
3339 % The format of the ReadBlobMSBShort method is:
3341 % unsigned short ReadBlobMSBShort(Image *image)
3343 % A description of each parameter follows.
3345 % o image: the image.
3348 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3350 register const unsigned char
3353 register unsigned int
3362 assert(image != (Image *) NULL);
3363 assert(image->signature == MagickSignature);
3365 p=ReadBlobStream(image,2,buffer,&count);
3367 return((unsigned short) 0U);
3368 value=(unsigned int) ((*p++) << 8);
3369 value|=(unsigned int) (*p++);
3370 return((unsigned short) (value & 0xffff));
3374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3378 + R e a d B l o b S t r i n g %
3382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3384 % ReadBlobString() reads characters from a blob or file until a newline
3385 % character is read or an end-of-file condition is encountered.
3387 % The format of the ReadBlobString method is:
3389 % char *ReadBlobString(Image *image,char *string)
3391 % A description of each parameter follows:
3393 % o image: the image.
3395 % o string: the address of a character buffer.
3398 MagickExport char *ReadBlobString(Image *image,char *string)
3400 register const unsigned char
3412 assert(image != (Image *) NULL);
3413 assert(image->signature == MagickSignature);
3414 for (i=0; i < (MaxTextExtent-1L); i++)
3416 p=ReadBlobStream(image,1,buffer,&count);
3420 return((char *) NULL);
3423 string[i]=(char) (*p);
3424 if ((string[i] == '\r') || (string[i] == '\n'))
3427 if (string[i] == '\r')
3428 (void) ReadBlobStream(image,1,buffer,&count);
3434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3438 + R e f e r e n c e B l o b %
3442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3444 % ReferenceBlob() increments the reference count associated with the pixel
3445 % blob returning a pointer to the blob.
3447 % The format of the ReferenceBlob method is:
3449 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3451 % A description of each parameter follows:
3453 % o blob_info: the blob_info.
3456 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3458 assert(blob != (BlobInfo *) NULL);
3459 assert(blob->signature == MagickSignature);
3460 if (blob->debug != MagickFalse)
3461 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3462 LockSemaphoreInfo(blob->semaphore);
3463 blob->reference_count++;
3464 UnlockSemaphoreInfo(blob->semaphore);
3469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3479 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3480 % and returns the resulting offset.
3482 % The format of the SeekBlob method is:
3484 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3487 % A description of each parameter follows:
3489 % o image: the image.
3491 % o offset: Specifies an integer representing the offset in bytes.
3493 % o whence: Specifies an integer representing how the offset is
3494 % treated relative to the beginning of the blob as follows:
3496 % SEEK_SET Set position equal to offset bytes.
3497 % SEEK_CUR Set position to current location plus offset.
3498 % SEEK_END Set position to EOF plus offset.
3501 MagickExport MagickOffsetType SeekBlob(Image *image,
3502 const MagickOffsetType offset,const int whence)
3504 assert(image != (Image *) NULL);
3505 assert(image->signature == MagickSignature);
3506 if (image->debug != MagickFalse)
3507 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3508 assert(image->blob != (BlobInfo *) NULL);
3509 assert(image->blob->type != UndefinedStream);
3510 switch (image->blob->type)
3512 case UndefinedStream:
3516 if (fseek(image->blob->file,(long) offset,whence) < 0)
3518 image->blob->offset=TellBlob(image);
3521 case StandardStream:
3525 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3526 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3529 image->blob->offset=TellBlob(image);
3545 image->blob->offset=offset;
3550 if ((image->blob->offset+offset) < 0)
3552 image->blob->offset+=offset;
3557 if (((MagickOffsetType) image->blob->length+offset) < 0)
3559 image->blob->offset=image->blob->length+offset;
3563 if (image->blob->offset <= (MagickOffsetType)
3564 ((off_t) image->blob->length))
3565 image->blob->eof=MagickFalse;
3567 if (image->blob->mapped != MagickFalse)
3571 image->blob->extent=(size_t) (image->blob->offset+
3572 image->blob->quantum);
3573 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3574 image->blob->data,image->blob->extent+1,
3575 sizeof(*image->blob->data));
3576 (void) SyncBlob(image);
3577 if (image->blob->data == (unsigned char *) NULL)
3579 (void) DetachBlob(image->blob);
3586 return(image->blob->offset);
3590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3594 + S e t B l o b E x e m p t %
3598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3600 % SetBlobExempt() sets the blob exempt status.
3602 % The format of the SetBlobExempt method is:
3604 % MagickBooleanType SetBlobExempt(const Image *image,
3605 % const MagickBooleanType exempt)
3607 % A description of each parameter follows:
3609 % o image: the image.
3611 % o exempt: Set to true if this blob is exempt from being closed.
3614 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3616 assert(image != (const Image *) NULL);
3617 assert(image->signature == MagickSignature);
3618 if (image->debug != MagickFalse)
3619 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3620 image->blob->exempt=exempt;
3624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3628 + S e t B l o b E x t e n t %
3632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3634 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3635 % method is successful, subsequent writes to bytes in the specified range are
3636 % guaranteed not to fail.
3638 % The format of the SetBlobExtent method is:
3640 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3642 % A description of each parameter follows:
3644 % o image: the image.
3646 % o extent: the blob maximum extent.
3649 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3650 const MagickSizeType extent)
3652 assert(image != (Image *) NULL);
3653 assert(image->signature == MagickSignature);
3654 if (image->debug != MagickFalse)
3655 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3656 assert(image->blob != (BlobInfo *) NULL);
3657 assert(image->blob->type != UndefinedStream);
3658 switch (image->blob->type)
3660 case UndefinedStream:
3664 if (extent != (MagickSizeType) ((off_t) extent))
3665 return(MagickFalse);
3666 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3667 return(MagickFalse);
3676 offset=TellBlob(image);
3677 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3678 (off_t) (extent-offset));
3680 return(MagickFalse);
3685 case StandardStream:
3688 return(MagickFalse);
3690 return(MagickFalse);
3692 return(MagickFalse);
3695 if (image->blob->mapped != MagickFalse)
3697 if (image->blob->file == (FILE *) NULL)
3698 return(MagickFalse);
3699 (void) UnmapBlob(image->blob->data,image->blob->length);
3700 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3701 return(MagickFalse);
3710 offset=TellBlob(image);
3711 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3712 (off_t) (extent-offset));
3714 return(MagickFalse);
3716 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3717 WriteMode,0,(size_t) extent);
3718 image->blob->extent=(size_t) extent;
3719 image->blob->length=(size_t) extent;
3720 (void) SyncBlob(image);
3724 if (extent != (MagickSizeType) ((size_t) extent))
3725 return(MagickFalse);
3726 image->blob->extent=(size_t) extent;
3727 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3728 image->blob->extent+1,sizeof(*image->blob->data));
3729 (void) SyncBlob(image);
3730 if (image->blob->data == (unsigned char *) NULL)
3732 (void) DetachBlob(image->blob);
3733 return(MagickFalse);
3742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3752 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3753 % attributes if it is an blob.
3755 % The format of the SyncBlob method is:
3757 % int SyncBlob(Image *image)
3759 % A description of each parameter follows:
3761 % o image: the image.
3764 static int SyncBlob(Image *image)
3769 assert(image != (Image *) NULL);
3770 assert(image->signature == MagickSignature);
3771 if (image->debug != MagickFalse)
3772 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3773 assert(image->blob != (BlobInfo *) NULL);
3774 assert(image->blob->type != UndefinedStream);
3776 switch (image->blob->type)
3778 case UndefinedStream:
3781 case StandardStream:
3784 status=fflush(image->blob->file);
3789 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3790 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3796 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3797 status=BZ2_bzflush((BZFILE *) image->blob->file);
3805 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3806 if (image->blob->mapped != MagickFalse)
3807 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3826 % TellBlob() obtains the current value of the blob or file position.
3828 % The format of the TellBlob method is:
3830 % MagickOffsetType TellBlob(const Image *image)
3832 % A description of each parameter follows:
3834 % o image: the image.
3837 MagickExport MagickOffsetType TellBlob(const Image *image)
3842 assert(image != (Image *) NULL);
3843 assert(image->signature == MagickSignature);
3844 if (image->debug != MagickFalse)
3845 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3846 assert(image->blob != (BlobInfo *) NULL);
3847 assert(image->blob->type != UndefinedStream);
3849 switch (image->blob->type)
3851 case UndefinedStream:
3855 offset=ftell(image->blob->file);
3858 case StandardStream:
3863 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3864 offset=(MagickOffsetType) gztell(image->blob->file);
3874 offset=image->blob->offset;
3882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3886 + U n m a p B l o b %
3890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3892 % UnmapBlob() deallocates the binary large object previously allocated with
3893 % the MapBlob method.
3895 % The format of the UnmapBlob method is:
3897 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3899 % A description of each parameter follows:
3901 % o map: the address of the binary large object.
3903 % o length: the length of the binary large object.
3906 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3908 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3912 status=munmap(map,length);
3913 return(status == -1 ? MagickFalse : MagickTrue);
3917 return(MagickFalse);
3922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3926 + W r i t e B l o b %
3930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3932 % WriteBlob() writes data to a blob or image file. It returns the number of
3935 % The format of the WriteBlob method is:
3937 % ssize_t WriteBlob(Image *image,const size_t length,
3938 % const unsigned char *data)
3940 % A description of each parameter follows:
3942 % o image: the image.
3944 % o length: Specifies an integer representing the number of bytes to
3945 % write to the file.
3947 % o data: The address of the data to write to the blob or file.
3950 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3951 const unsigned char *data)
3956 register const unsigned char
3962 assert(image != (Image *) NULL);
3963 assert(image->signature == MagickSignature);
3964 assert(data != (const unsigned char *) NULL);
3965 assert(image->blob != (BlobInfo *) NULL);
3966 assert(image->blob->type != UndefinedStream);
3971 switch (image->blob->type)
3973 case UndefinedStream:
3976 case StandardStream:
3983 count=(ssize_t) fwrite((const char *) data,1,length,
3989 c=putc((int) *p++,image->blob->file);
3996 c=putc((int) *p++,image->blob->file);
4008 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4013 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4014 (unsigned int) length);
4019 c=gzputc(image->blob->file,(int) *p++);
4026 c=gzputc(image->blob->file,(int) *p++);
4039 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4040 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4047 count=(ssize_t) image->blob->stream(image,data,length);
4052 register unsigned char
4055 if ((image->blob->offset+(MagickOffsetType) length) >=
4056 (MagickOffsetType) image->blob->extent)
4058 if (image->blob->mapped != MagickFalse)
4060 image->blob->quantum<<=1;
4061 image->blob->extent+=length+image->blob->quantum;
4062 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4063 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4064 (void) SyncBlob(image);
4065 if (image->blob->data == (unsigned char *) NULL)
4067 (void) DetachBlob(image->blob);
4071 q=image->blob->data+image->blob->offset;
4072 (void) memcpy(q,p,length);
4073 image->blob->offset+=length;
4074 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4075 image->blob->length=(size_t) image->blob->offset;
4076 count=(ssize_t) length;
4083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4087 + W r i t e B l o b B y t e %
4091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4093 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4094 % written (either 0 or 1);
4096 % The format of the WriteBlobByte method is:
4098 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4100 % A description of each parameter follows.
4102 % o image: the image.
4104 % o value: Specifies the value to write.
4107 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4109 assert(image != (Image *) NULL);
4110 assert(image->signature == MagickSignature);
4111 return(WriteBlobStream(image,1,&value));
4115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4119 + W r i t e B l o b F l o a t %
4123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4125 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4126 % specified by the endian member of the image structure.
4128 % The format of the WriteBlobFloat method is:
4130 % ssize_t WriteBlobFloat(Image *image,const float value)
4132 % A description of each parameter follows.
4134 % o image: the image.
4136 % o value: Specifies the value to write.
4139 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4150 quantum.unsigned_value=0U;
4151 quantum.float_value=value;
4152 return(WriteBlobLong(image,quantum.unsigned_value));
4156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4160 + W r i t e B l o b L o n g %
4164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4166 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4167 % specified by the endian member of the image structure.
4169 % The format of the WriteBlobLong method is:
4171 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4173 % A description of each parameter follows.
4175 % o image: the image.
4177 % o value: Specifies the value to write.
4180 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4185 assert(image != (Image *) NULL);
4186 assert(image->signature == MagickSignature);
4187 if (image->endian == LSBEndian)
4189 buffer[0]=(unsigned char) value;
4190 buffer[1]=(unsigned char) (value >> 8);
4191 buffer[2]=(unsigned char) (value >> 16);
4192 buffer[3]=(unsigned char) (value >> 24);
4193 return(WriteBlobStream(image,4,buffer));
4195 buffer[0]=(unsigned char) (value >> 24);
4196 buffer[1]=(unsigned char) (value >> 16);
4197 buffer[2]=(unsigned char) (value >> 8);
4198 buffer[3]=(unsigned char) value;
4199 return(WriteBlobStream(image,4,buffer));
4203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4207 + W r i t e B l o b S h o r t %
4211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4213 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4214 % byte-order specified by the endian member of the image structure.
4216 % The format of the WriteBlobShort method is:
4218 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4220 % A description of each parameter follows.
4222 % o image: the image.
4224 % o value: Specifies the value to write.
4227 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4232 assert(image != (Image *) NULL);
4233 assert(image->signature == MagickSignature);
4234 if (image->endian == LSBEndian)
4236 buffer[0]=(unsigned char) value;
4237 buffer[1]=(unsigned char) (value >> 8);
4238 return(WriteBlobStream(image,2,buffer));
4240 buffer[0]=(unsigned char) (value >> 8);
4241 buffer[1]=(unsigned char) value;
4242 return(WriteBlobStream(image,2,buffer));
4246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4250 + W r i t e B l o b L S B L o n g %
4254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4256 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4257 % least-significant byte first order.
4259 % The format of the WriteBlobLSBLong method is:
4261 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4263 % A description of each parameter follows.
4265 % o image: the image.
4267 % o value: Specifies the value to write.
4270 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4275 assert(image != (Image *) NULL);
4276 assert(image->signature == MagickSignature);
4277 buffer[0]=(unsigned char) value;
4278 buffer[1]=(unsigned char) (value >> 8);
4279 buffer[2]=(unsigned char) (value >> 16);
4280 buffer[3]=(unsigned char) (value >> 24);
4281 return(WriteBlobStream(image,4,buffer));
4285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4289 + W r i t e B l o b L S B S h o r t %
4293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4295 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4296 % least-significant byte first order.
4298 % The format of the WriteBlobLSBShort method is:
4300 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4302 % A description of each parameter follows.
4304 % o image: the image.
4306 % o value: Specifies the value to write.
4309 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4314 assert(image != (Image *) NULL);
4315 assert(image->signature == MagickSignature);
4316 buffer[0]=(unsigned char) value;
4317 buffer[1]=(unsigned char) (value >> 8);
4318 return(WriteBlobStream(image,2,buffer));
4322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4326 + W r i t e B l o b M S B L o n g %
4330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4332 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4333 % most-significant byte first order.
4335 % The format of the WriteBlobMSBLong method is:
4337 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4339 % A description of each parameter follows.
4341 % o value: Specifies the value to write.
4343 % o image: the image.
4346 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4351 assert(image != (Image *) NULL);
4352 assert(image->signature == MagickSignature);
4353 buffer[0]=(unsigned char) (value >> 24);
4354 buffer[1]=(unsigned char) (value >> 16);
4355 buffer[2]=(unsigned char) (value >> 8);
4356 buffer[3]=(unsigned char) value;
4357 return(WriteBlobStream(image,4,buffer));
4361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4365 + W r i t e B l o b M S B L o n g L o n g %
4369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4371 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4372 % most-significant byte first order.
4374 % The format of the WriteBlobMSBLongLong method is:
4376 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4378 % A description of each parameter follows.
4380 % o value: Specifies the value to write.
4382 % o image: the image.
4385 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4386 const MagickSizeType value)
4391 assert(image != (Image *) NULL);
4392 assert(image->signature == MagickSignature);
4393 buffer[0]=(unsigned char) (value >> 56);
4394 buffer[1]=(unsigned char) (value >> 48);
4395 buffer[2]=(unsigned char) (value >> 40);
4396 buffer[3]=(unsigned char) (value >> 32);
4397 buffer[4]=(unsigned char) (value >> 24);
4398 buffer[5]=(unsigned char) (value >> 16);
4399 buffer[6]=(unsigned char) (value >> 8);
4400 buffer[7]=(unsigned char) value;
4401 return(WriteBlobStream(image,8,buffer));
4405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4409 + W r i t e B l o b M S B S h o r t %
4413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4415 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4416 % most-significant byte first order.
4418 % The format of the WriteBlobMSBShort method is:
4420 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4422 % A description of each parameter follows.
4424 % o value: Specifies the value to write.
4426 % o file: Specifies the file to write the data to.
4429 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4434 assert(image != (Image *) NULL);
4435 assert(image->signature == MagickSignature);
4436 buffer[0]=(unsigned char) (value >> 8);
4437 buffer[1]=(unsigned char) value;
4438 return(WriteBlobStream(image,2,buffer));
4442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4446 + W r i t e B l o b S t r i n g %
4450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4452 % WriteBlobString() write a string to a blob. It returns the number of
4453 % characters written.
4455 % The format of the WriteBlobString method is:
4457 % ssize_t WriteBlobString(Image *image,const char *string)
4459 % A description of each parameter follows.
4461 % o image: the image.
4463 % o string: Specifies the string to write.
4466 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4468 assert(image != (Image *) NULL);
4469 assert(image->signature == MagickSignature);
4470 assert(string != (const char *) NULL);
4471 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));