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(MAP_ANONYMOUS) && defined(MAP_ANON)
79 # define MAP_ANONYMOUS MAP_ANON
81 #if !defined(MAP_FAILED)
82 #define MAP_FAILED ((void *) -1)
89 #define _O_BINARY O_BINARY
147 Forward declarations.
153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157 + A t t a c h B l o b %
161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163 % AttachBlob() attaches a blob to the BlobInfo structure.
165 % The format of the AttachBlob method is:
167 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
169 % A description of each parameter follows:
171 % o blob_info: Specifies a pointer to a BlobInfo structure.
173 % o blob: the address of a character stream in one of the image formats
174 % understood by ImageMagick.
176 % o length: This size_t integer reflects the length in bytes of the blob.
179 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
182 assert(blob_info != (BlobInfo *) NULL);
183 if (blob_info->debug != MagickFalse)
184 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
185 blob_info->length=length;
186 blob_info->extent=length;
187 blob_info->quantum=(size_t) MagickMaxBlobExtent;
189 blob_info->type=BlobStream;
190 blob_info->file=(FILE *) NULL;
191 blob_info->data=(unsigned char *) blob;
192 blob_info->mapped=MagickFalse;
196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200 + B l o b T o F i l e %
204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
206 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error
207 % occurs otherwise MagickTrue.
209 % The format of the BlobToFile method is:
211 % MagickBooleanType BlobToFile(char *filename,const void *blob,
212 % const size_t length,ExceptionInfo *exception)
214 % A description of each parameter follows:
216 % o filename: Write the blob to this file.
218 % o blob: the address of a blob.
220 % o length: This length in bytes of the blob.
222 % o exception: return any errors or warnings in this structure.
226 static inline MagickSizeType MagickMin(const MagickSizeType x,
227 const MagickSizeType y)
234 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
235 const size_t length,ExceptionInfo *exception)
246 assert(filename != (const char *) NULL);
247 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
248 assert(blob != (const void *) NULL);
249 if (*filename == '\0')
250 file=AcquireUniqueFileResource(filename);
252 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
255 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
258 for (i=0; i < length; i+=count)
260 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
261 i,(MagickSizeType) SSIZE_MAX));
270 if ((file == -1) || (i < length))
272 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 % B l o b T o I m a g e %
287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289 % BlobToImage() implements direct to memory image formats. It returns the
292 % The format of the BlobToImage method is:
294 % Image *BlobToImage(const ImageInfo *image_info,const void *blob,
295 % const size_t length,ExceptionInfo *exception)
297 % A description of each parameter follows:
299 % o image_info: the image info.
301 % o blob: the address of a character stream in one of the image formats
302 % understood by ImageMagick.
304 % o length: This size_t integer reflects the length in bytes of the blob.
306 % o exception: return any errors or warnings in this structure.
309 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
310 const size_t length,ExceptionInfo *exception)
325 assert(image_info != (ImageInfo *) NULL);
326 assert(image_info->signature == MagickSignature);
327 if (image_info->debug != MagickFalse)
328 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
329 image_info->filename);
330 assert(exception != (ExceptionInfo *) NULL);
331 if ((blob == (const void *) NULL) || (length == 0))
333 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
334 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
335 return((Image *) NULL);
337 blob_info=CloneImageInfo(image_info);
338 blob_info->blob=(void *) blob;
339 blob_info->length=length;
340 if (*blob_info->magick == '\0')
341 (void) SetImageInfo(blob_info,0,exception);
342 magick_info=GetMagickInfo(blob_info->magick,exception);
343 if (magick_info == (const MagickInfo *) NULL)
345 blob_info=DestroyImageInfo(blob_info);
346 (void) ThrowMagickException(exception,GetMagickModule(),
347 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
348 image_info->filename);
349 return((Image *) NULL);
351 if (GetMagickBlobSupport(magick_info) != MagickFalse)
354 Native blob support for this image format.
356 (void) CopyMagickString(blob_info->filename,image_info->filename,
358 (void) CopyMagickString(blob_info->magick,image_info->magick,
360 image=ReadImage(blob_info,exception);
361 if (image != (Image *) NULL)
362 (void) DetachBlob(image->blob);
363 blob_info=DestroyImageInfo(blob_info);
367 Write blob to a temporary file on disk.
369 blob_info->blob=(void *) NULL;
371 *blob_info->filename='\0';
372 status=BlobToFile(blob_info->filename,blob,length,exception);
373 if (status == MagickFalse)
375 (void) RelinquishUniqueFileResource(blob_info->filename);
376 blob_info=DestroyImageInfo(blob_info);
377 return((Image *) NULL);
379 clone_info=CloneImageInfo(blob_info);
380 (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
381 blob_info->magick,blob_info->filename);
382 image=ReadImage(clone_info,exception);
383 clone_info=DestroyImageInfo(clone_info);
384 (void) RelinquishUniqueFileResource(blob_info->filename);
385 blob_info=DestroyImageInfo(blob_info);
390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 + C l o n e B l o b I n f o %
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if
401 % blob info is NULL, a new one.
403 % The format of the CloneBlobInfo method is:
405 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
407 % A description of each parameter follows:
409 % o blob_info: the blob info.
412 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
417 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
418 if (clone_info == (BlobInfo *) NULL)
419 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
420 GetBlobInfo(clone_info);
421 if (blob_info == (BlobInfo *) NULL)
423 clone_info->length=blob_info->length;
424 clone_info->extent=blob_info->extent;
425 clone_info->synchronize=blob_info->synchronize;
426 clone_info->quantum=blob_info->quantum;
427 clone_info->mapped=blob_info->mapped;
428 clone_info->eof=blob_info->eof;
429 clone_info->offset=blob_info->offset;
430 clone_info->size=blob_info->size;
431 clone_info->exempt=blob_info->exempt;
432 clone_info->status=blob_info->status;
433 clone_info->temporary=blob_info->temporary;
434 clone_info->type=blob_info->type;
435 clone_info->file=blob_info->file;
436 clone_info->properties=blob_info->properties;
437 clone_info->stream=blob_info->stream;
438 clone_info->data=blob_info->data;
439 clone_info->debug=IsEventLogging();
440 clone_info->reference_count=1;
445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449 + C l o s e B l o b %
453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
455 % CloseBlob() closes a stream associated with the image.
457 % The format of the CloseBlob method is:
459 % MagickBooleanType CloseBlob(Image *image)
461 % A description of each parameter follows:
463 % o image: the image.
466 MagickExport MagickBooleanType CloseBlob(Image *image)
474 assert(image != (Image *) NULL);
475 assert(image->signature == MagickSignature);
476 if (image->debug != MagickFalse)
477 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
478 assert(image->blob != (BlobInfo *) NULL);
479 if (image->blob->type == UndefinedStream)
481 if (image->blob->synchronize != MagickFalse)
483 image->blob->size=GetBlobSize(image);
484 image->extent=image->blob->size;
485 image->blob->eof=MagickFalse;
486 if (image->blob->exempt != MagickFalse)
488 image->blob->type=UndefinedStream;
492 switch (image->blob->type)
494 case UndefinedStream:
500 status=ferror(image->blob->file);
505 #if defined(MAGICKCORE_ZLIB_DELEGATE)
506 (void) gzerror(image->blob->file,&status);
512 #if defined(MAGICKCORE_BZLIB_DELEGATE)
513 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
521 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
522 switch (image->blob->type)
524 case UndefinedStream:
529 if (image->blob->synchronize != MagickFalse)
531 status=fflush(image->blob->file);
532 status=fsync(fileno(image->blob->file));
534 status=fclose(image->blob->file);
539 #if defined(MAGICKCORE_HAVE_PCLOSE)
540 status=pclose(image->blob->file);
546 #if defined(MAGICKCORE_ZLIB_DELEGATE)
547 status=gzclose(image->blob->file);
553 #if defined(MAGICKCORE_BZLIB_DELEGATE)
554 BZ2_bzclose((BZFILE *) image->blob->file);
562 if (image->blob->file != (FILE *) NULL)
564 if (image->blob->synchronize != MagickFalse)
565 (void) fsync(fileno(image->blob->file));
566 status=fclose(image->blob->file);
571 (void) DetachBlob(image->blob);
572 image->blob->status=status < 0 ? MagickTrue : MagickFalse;
573 return(image->blob->status);
577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581 + D e s t r o y B l o b %
585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587 % DestroyBlob() deallocates memory associated with a blob.
589 % The format of the DestroyBlob method is:
591 % void DestroyBlob(Image *image)
593 % A description of each parameter follows:
595 % o image: the image.
598 MagickExport void DestroyBlob(Image *image)
603 assert(image != (Image *) NULL);
604 assert(image->signature == MagickSignature);
605 if (image->debug != MagickFalse)
606 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
607 assert(image->blob != (BlobInfo *) NULL);
608 assert(image->blob->signature == MagickSignature);
610 LockSemaphoreInfo(image->blob->semaphore);
611 image->blob->reference_count--;
612 assert(image->blob->reference_count >= 0);
613 if (image->blob->reference_count == 0)
615 UnlockSemaphoreInfo(image->blob->semaphore);
616 if (destroy == MagickFalse)
618 (void) CloseBlob(image);
619 if (image->blob->mapped != MagickFalse)
620 (void) UnmapBlob(image->blob->data,image->blob->length);
621 if (image->blob->semaphore != (SemaphoreInfo *) NULL)
622 DestroySemaphoreInfo(&image->blob->semaphore);
623 image->blob->signature=(~MagickSignature);
624 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632 + D e t a c h B l o b %
636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
638 % DetachBlob() detaches a blob from the BlobInfo structure.
640 % The format of the DetachBlob method is:
642 % unsigned char *DetachBlob(BlobInfo *blob_info)
644 % A description of each parameter follows:
646 % o blob_info: Specifies a pointer to a BlobInfo structure.
649 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
654 assert(blob_info != (BlobInfo *) NULL);
655 if (blob_info->debug != MagickFalse)
656 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
657 if (blob_info->mapped != MagickFalse)
658 (void) UnmapBlob(blob_info->data,blob_info->length);
659 blob_info->mapped=MagickFalse;
662 blob_info->eof=MagickFalse;
663 blob_info->exempt=MagickFalse;
664 blob_info->type=UndefinedStream;
665 blob_info->file=(FILE *) NULL;
666 data=blob_info->data;
667 blob_info->data=(unsigned char *) NULL;
668 blob_info->stream=(StreamHandler) NULL;
673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677 + D i s c a r d B l o b B y t e s %
681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
683 % DiscardBlobBytes() discards bytes in a blob.
685 % The format of the DiscardBlobBytes method is:
687 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
689 % A description of each parameter follows.
691 % o image: the image.
693 % o length: the number of bytes to skip.
697 static inline const unsigned char *ReadBlobStream(Image *image,
698 const size_t length,unsigned char *data,ssize_t *count)
700 assert(count != (ssize_t *) NULL);
701 assert(image->blob != (BlobInfo *) NULL);
702 if (image->blob->type != BlobStream)
704 *count=ReadBlob(image,length,data);
707 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
710 image->blob->eof=MagickTrue;
713 data=image->blob->data+image->blob->offset;
714 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
715 image->blob->offset));
716 image->blob->offset+=(*count);
717 if (*count != (ssize_t) length)
718 image->blob->eof=MagickTrue;
722 MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
723 const MagickSizeType length)
725 register MagickOffsetType
737 assert(image != (Image *) NULL);
738 assert(image->signature == MagickSignature);
740 for (i=0; i < (MagickOffsetType) length; i+=count)
742 quantum=(size_t) MagickMin(length-i,sizeof(buffer));
743 (void) ReadBlobStream(image,quantum,buffer,&count);
751 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759 + D u p l i c a t e s B l o b %
763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
765 % DuplicateBlob() duplicates a blob descriptor.
767 % The format of the DuplicateBlob method is:
769 % void DuplicateBlob(Image *image,const Image *duplicate)
771 % A description of each parameter follows:
773 % o image: the image.
775 % o duplicate: the duplicate image.
778 MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
780 assert(image != (Image *) NULL);
781 assert(image->signature == MagickSignature);
782 if (image->debug != MagickFalse)
783 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
784 assert(duplicate != (Image *) NULL);
785 assert(duplicate->signature == MagickSignature);
787 image->blob=ReferenceBlob(duplicate->blob);
791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801 % EOFBlob() returns a non-zero value when EOF has been detected reading from
804 % The format of the EOFBlob method is:
806 % int EOFBlob(const Image *image)
808 % A description of each parameter follows:
810 % o image: the image.
813 MagickExport int EOFBlob(const Image *image)
815 assert(image != (Image *) NULL);
816 assert(image->signature == MagickSignature);
817 if (image->debug != MagickFalse)
818 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
819 assert(image->blob != (BlobInfo *) NULL);
820 assert(image->blob->type != UndefinedStream);
821 switch (image->blob->type)
823 case UndefinedStream:
829 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
834 image->blob->eof=MagickFalse;
839 #if defined(MAGICKCORE_BZLIB_DELEGATE)
844 (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
845 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
851 image->blob->eof=MagickFalse;
857 return((int) image->blob->eof);
861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
865 + F i l e T o B l o b %
869 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871 % FileToBlob() returns the contents of a file as a buffer terminated with
872 % the '\0' character. The length of the buffer (not including the extra
873 % terminating '\0' character) is returned via the 'length' parameter. Free
874 % the buffer with RelinquishMagickMemory().
876 % The format of the FileToBlob method is:
878 % unsigned char *FileToBlob(const char *filename,const size_t extent,
879 % size_t *length,ExceptionInfo *exception)
881 % A description of each parameter follows:
883 % o blob: FileToBlob() returns the contents of a file as a blob. If
884 % an error occurs NULL is returned.
886 % o filename: the filename.
888 % o extent: The maximum length of the blob.
890 % o length: On return, this reflects the actual length of the blob.
892 % o exception: return any errors or warnings in this structure.
895 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
896 size_t *length,ExceptionInfo *exception)
916 assert(filename != (const char *) NULL);
917 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
918 assert(exception != (ExceptionInfo *) NULL);
921 if (LocaleCompare(filename,"-") != 0)
922 file=open(filename,O_RDONLY | O_BINARY);
925 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
926 return((unsigned char *) NULL);
928 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
930 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
939 Stream is not seekable.
941 quantum=(size_t) MagickMaxBufferExtent;
942 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
943 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
944 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=(size_t) MagickMin(i+count,extent);
983 *length=(size_t) MagickMin((MagickSizeType) 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) lseek(file,0,SEEK_SET);
1004 for (i=0; i < *length; i+=count)
1006 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1007 (MagickSizeType) SSIZE_MAX));
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=(size_t) MagickMin(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 formatted blob and its length. The magick member of the Image
1430 % structure determines the format of the returned blob (GIF, JPEG, PNG,
1431 % etc.). This method is the equivalent of WriteImage(), but writes the
1432 % formatted "file" to a memory buffer rather than to an actual file.
1434 % The format of the ImageToBlob method is:
1436 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1437 % size_t *length,ExceptionInfo *exception)
1439 % A description of each parameter follows:
1441 % o image_info: the image info.
1443 % o image: the image.
1445 % o length: This pointer to a size_t integer sets the initial length of the
1446 % blob. On return, it reflects the actual length of the blob.
1448 % o exception: return any errors or warnings in this structure.
1451 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1452 Image *image,size_t *length,ExceptionInfo *exception)
1466 assert(image_info != (const ImageInfo *) NULL);
1467 assert(image_info->signature == MagickSignature);
1468 if (image_info->debug != MagickFalse)
1469 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1470 image_info->filename);
1471 assert(image != (Image *) NULL);
1472 assert(image->signature == MagickSignature);
1473 assert(exception != (ExceptionInfo *) NULL);
1475 blob=(unsigned char *) NULL;
1476 blob_info=CloneImageInfo(image_info);
1477 blob_info->adjoin=MagickFalse;
1478 (void) SetImageInfo(blob_info,1,exception);
1479 if (*blob_info->magick != '\0')
1480 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1481 magick_info=GetMagickInfo(image->magick,exception);
1482 if (magick_info == (const MagickInfo *) NULL)
1484 (void) ThrowMagickException(exception,GetMagickModule(),
1485 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1489 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1490 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1493 Native blob support for this image format.
1495 blob_info->length=0;
1496 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1497 sizeof(unsigned char));
1498 if (blob_info->blob == (void *) NULL)
1499 (void) ThrowMagickException(exception,GetMagickModule(),
1500 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1503 (void) CloseBlob(image);
1504 image->blob->exempt=MagickTrue;
1505 *image->filename='\0';
1506 status=WriteImage(blob_info,image);
1507 if ((status == MagickFalse) || (image->blob->length == 0))
1508 InheritException(exception,&image->exception);
1511 *length=image->blob->length;
1512 blob=DetachBlob(image->blob);
1513 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1521 unique[MaxTextExtent];
1527 Write file to disk in blob image format.
1529 file=AcquireUniqueFileResource(unique);
1532 ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1533 image_info->filename);
1537 blob_info->file=fdopen(file,"wb");
1538 if (blob_info->file != (FILE *) NULL)
1540 (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1541 image->magick,unique);
1542 status=WriteImage(blob_info,image);
1543 (void) fclose(blob_info->file);
1544 if (status == MagickFalse)
1545 InheritException(exception,&image->exception);
1547 blob=FileToBlob(image->filename,~0UL,length,exception);
1549 (void) RelinquishUniqueFileResource(unique);
1552 blob_info=DestroyImageInfo(blob_info);
1557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1561 % I m a g e T o F i l e %
1565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1567 % ImageToFile() writes an image to a file. It returns MagickFalse if an error
1568 % occurs otherwise MagickTrue.
1570 % The format of the ImageToFile method is:
1572 % MagickBooleanType ImageToFile(Image *image,char *filename,
1573 % ExceptionInfo *exception)
1575 % A description of each parameter follows:
1577 % o image: the image.
1579 % o filename: Write the image to this file.
1581 % o exception: return any errors or warnings in this structure.
1584 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1585 ExceptionInfo *exception)
1590 register const unsigned char
1609 assert(image != (Image *) NULL);
1610 assert(image->signature == MagickSignature);
1611 assert(image->blob != (BlobInfo *) NULL);
1612 assert(image->blob->type != UndefinedStream);
1613 if (image->debug != MagickFalse)
1614 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1615 assert(filename != (const char *) NULL);
1616 if (*filename == '\0')
1617 file=AcquireUniqueFileResource(filename);
1619 if (LocaleCompare(filename,"-") == 0)
1620 file=fileno(stdout);
1622 file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1625 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1626 return(MagickFalse);
1628 quantum=(size_t) MagickMaxBufferExtent;
1629 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1630 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
1631 MagickMaxBufferExtent);
1632 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1633 if (buffer == (unsigned char *) NULL)
1636 (void) ThrowMagickException(exception,GetMagickModule(),
1637 ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1638 return(MagickFalse);
1641 p=ReadBlobStream(image,quantum,buffer,&count);
1642 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1644 length=(size_t) count;
1645 for (i=0; i < length; i+=count)
1647 count=write(file,p+i,(size_t) (length-i));
1658 if (LocaleCompare(filename,"-") != 0)
1660 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1661 if ((file == -1) || (i < length))
1663 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1664 return(MagickFalse);
1670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1674 % I m a g e s T o B l o b %
1678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1680 % ImagesToBlob() implements direct to memory image formats. It returns the
1681 % image sequence as a blob and its length. The magick member of the ImageInfo
1682 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1684 % Note, some image formats do not permit multiple images to the same image
1685 % stream (e.g. JPEG). in this instance, just the first image of the
1686 % sequence is returned as a blob.
1688 % The format of the ImagesToBlob method is:
1690 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1691 % size_t *length,ExceptionInfo *exception)
1693 % A description of each parameter follows:
1695 % o image_info: the image info.
1697 % o images: the image list.
1699 % o length: This pointer to a size_t integer sets the initial length of the
1700 % blob. On return, it reflects the actual length of the blob.
1702 % o exception: return any errors or warnings in this structure.
1705 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1706 Image *images,size_t *length,ExceptionInfo *exception)
1720 assert(image_info != (const ImageInfo *) NULL);
1721 assert(image_info->signature == MagickSignature);
1722 if (image_info->debug != MagickFalse)
1723 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1724 image_info->filename);
1725 assert(images != (Image *) NULL);
1726 assert(images->signature == MagickSignature);
1727 assert(exception != (ExceptionInfo *) NULL);
1729 blob=(unsigned char *) NULL;
1730 blob_info=CloneImageInfo(image_info);
1731 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1733 if (*blob_info->magick != '\0')
1734 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1735 if (blob_info->adjoin == MagickFalse)
1737 blob_info=DestroyImageInfo(blob_info);
1738 return(ImageToBlob(image_info,images,length,exception));
1740 magick_info=GetMagickInfo(images->magick,exception);
1741 if (magick_info == (const MagickInfo *) NULL)
1743 (void) ThrowMagickException(exception,GetMagickModule(),
1744 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1748 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1749 if (GetMagickBlobSupport(magick_info) != MagickFalse)
1752 Native blob support for this images format.
1754 blob_info->length=0;
1755 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1756 sizeof(unsigned char));
1757 if (blob_info->blob == (void *) NULL)
1758 (void) ThrowMagickException(exception,GetMagickModule(),
1759 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1762 images->blob->exempt=MagickTrue;
1763 *images->filename='\0';
1764 status=WriteImages(blob_info,images,images->filename,exception);
1765 if ((status == MagickFalse) || (images->blob->length == 0))
1766 InheritException(exception,&images->exception);
1769 *length=images->blob->length;
1770 blob=DetachBlob(images->blob);
1771 blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1779 filename[MaxTextExtent],
1780 unique[MaxTextExtent];
1786 Write file to disk in blob images format.
1788 file=AcquireUniqueFileResource(unique);
1791 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1792 image_info->filename);
1796 blob_info->file=fdopen(file,"wb");
1797 if (blob_info->file != (FILE *) NULL)
1799 (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1800 images->magick,unique);
1801 status=WriteImages(blob_info,images,filename,exception);
1802 (void) fclose(blob_info->file);
1803 if (status == MagickFalse)
1804 InheritException(exception,&images->exception);
1806 blob=FileToBlob(images->filename,~0UL,length,exception);
1808 (void) RelinquishUniqueFileResource(unique);
1811 blob_info=DestroyImageInfo(blob_info);
1815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1819 % I n j e c t I m a g e B l o b %
1823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1825 % InjectImageBlob() injects the image with a copy of itself in the specified
1826 % format (e.g. inject JPEG into a PDF image).
1828 % The format of the InjectImageBlob method is:
1830 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1831 % Image *image,Image *inject_image,const char *format,
1832 % ExceptionInfo *exception)
1834 % A description of each parameter follows:
1836 % o image_info: the image info..
1838 % o image: the image.
1840 % o inject_image: inject into the image stream.
1842 % o format: the image format.
1844 % o exception: return any errors or warnings in this structure.
1847 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1848 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1851 filename[MaxTextExtent];
1884 Write inject image to a temporary file.
1886 assert(image_info != (ImageInfo *) NULL);
1887 assert(image_info->signature == MagickSignature);
1888 assert(image != (Image *) NULL);
1889 assert(image->signature == MagickSignature);
1890 if (image->debug != MagickFalse)
1891 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1892 assert(inject_image != (Image *) NULL);
1893 assert(inject_image->signature == MagickSignature);
1894 assert(exception != (ExceptionInfo *) NULL);
1895 unique_file=(FILE *) NULL;
1896 file=AcquireUniqueFileResource(filename);
1898 unique_file=fdopen(file,"wb");
1899 if ((file == -1) || (unique_file == (FILE *) NULL))
1901 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
1902 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1904 return(MagickFalse);
1906 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1907 if (byte_image == (Image *) NULL)
1909 (void) fclose(unique_file);
1910 (void) RelinquishUniqueFileResource(filename);
1911 return(MagickFalse);
1913 (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1915 DestroyBlob(byte_image);
1916 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1917 write_info=CloneImageInfo(image_info);
1918 SetImageInfoFile(write_info,unique_file);
1919 status=WriteImage(write_info,byte_image);
1920 write_info=DestroyImageInfo(write_info);
1921 byte_image=DestroyImage(byte_image);
1922 (void) fclose(unique_file);
1923 if (status == MagickFalse)
1925 (void) RelinquishUniqueFileResource(filename);
1926 return(MagickFalse);
1929 Inject into image stream.
1931 file=open(filename,O_RDONLY | O_BINARY);
1934 (void) RelinquishUniqueFileResource(filename);
1935 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1936 image_info->filename);
1937 return(MagickFalse);
1939 quantum=(size_t) MagickMaxBufferExtent;
1940 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1941 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1942 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1943 if (buffer == (unsigned char *) NULL)
1945 (void) RelinquishUniqueFileResource(filename);
1946 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1949 for (i=0; ; i+=count)
1951 count=(ssize_t) read(file,buffer,quantum);
1958 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1963 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1964 (void) RelinquishUniqueFileResource(filename);
1965 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1974 + I s B l o b E x e m p t %
1978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1980 % IsBlobExempt() returns true if the blob is exempt.
1982 % The format of the IsBlobExempt method is:
1984 % MagickBooleanType IsBlobExempt(const Image *image)
1986 % A description of each parameter follows:
1988 % o image: the image.
1991 MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1993 assert(image != (const Image *) NULL);
1994 assert(image->signature == MagickSignature);
1995 if (image->debug != MagickFalse)
1996 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1997 return(image->blob->exempt);
2001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005 + I s B l o b S e e k a b l e %
2009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2011 % IsBlobSeekable() returns true if the blob is seekable.
2013 % The format of the IsBlobSeekable method is:
2015 % MagickBooleanType IsBlobSeekable(const Image *image)
2017 % A description of each parameter follows:
2019 % o image: the image.
2022 MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2027 assert(image != (const Image *) NULL);
2028 assert(image->signature == MagickSignature);
2029 if (image->debug != MagickFalse)
2030 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2031 seekable=(image->blob->type == FileStream) ||
2032 (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2041 + I s B l o b T e m p o r a r y %
2045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2047 % IsBlobTemporary() returns true if the blob is temporary.
2049 % The format of the IsBlobTemporary method is:
2051 % MagickBooleanType IsBlobTemporary(const Image *image)
2053 % A description of each parameter follows:
2055 % o image: the image.
2058 MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2060 assert(image != (const Image *) NULL);
2061 assert(image->signature == MagickSignature);
2062 if (image->debug != MagickFalse)
2063 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2064 return(image->blob->temporary);
2068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2078 % MapBlob() creates a mapping from a file to a binary large object.
2080 % The format of the MapBlob method is:
2082 % unsigned char *MapBlob(int file,const MapMode mode,
2083 % const MagickOffsetType offset,const size_t length)
2085 % A description of each parameter follows:
2087 % o file: map this file descriptor.
2089 % o mode: ReadMode, WriteMode, or IOMode.
2091 % o offset: starting at this offset within the file.
2093 % o length: the length of the mapping is returned in this pointer.
2096 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2097 const MagickOffsetType offset,const size_t length)
2099 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2112 #if defined(MAP_ANONYMOUS)
2113 flags|=MAP_ANONYMOUS;
2115 return((unsigned char *) NULL);
2122 protection=PROT_READ;
2124 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2130 protection=PROT_WRITE;
2132 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2134 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2135 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2136 POSIX_MADV_WILLNEED);
2142 protection=PROT_READ | PROT_WRITE;
2144 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2149 if (map == (unsigned char *) MAP_FAILED)
2150 return((unsigned char *) NULL);
2157 return((unsigned char *) NULL);
2162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2166 + M S B O r d e r L o n g %
2170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2172 % MSBOrderLong() converts a least-significant byte first buffer of integers to
2173 % most-significant byte first.
2175 % The format of the MSBOrderLong method is:
2177 % void MSBOrderLong(unsigned char *buffer,const size_t length)
2179 % A description of each parameter follows.
2181 % o buffer: Specifies a pointer to a buffer of integers.
2183 % o length: Specifies the length of the buffer.
2186 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2191 register unsigned char
2195 assert(buffer != (unsigned char *) NULL);
2202 *buffer++=(unsigned char) c;
2206 *buffer++=(unsigned char) c;
2212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2216 + M S B O r d e r S h o r t %
2220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2222 % MSBOrderShort() converts a least-significant byte first buffer of integers
2223 % to most-significant byte first.
2225 % The format of the MSBOrderShort method is:
2227 % void MSBOrderShort(unsigned char *p,const size_t length)
2229 % A description of each parameter follows.
2231 % o p: Specifies a pointer to a buffer of integers.
2233 % o length: Specifies the length of the buffer.
2236 MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2241 register unsigned char
2244 assert(p != (unsigned char *) NULL);
2251 *p++=(unsigned char) c;
2256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2266 % OpenBlob() opens a file associated with the image. A file name of '-' sets
2267 % the file to stdin for type 'r' and stdout for type 'w'. If the filename
2268 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2269 % compressed for type 'w'. If the filename prefix is '|', it is piped to or
2270 % from a system command.
2272 % The format of the OpenBlob method is:
2274 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2275 % const BlobMode mode,ExceptionInfo *exception)
2277 % A description of each parameter follows:
2279 % o image_info: the image info.
2281 % o image: the image.
2283 % o mode: the mode for opening the file.
2286 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2287 Image *image,const BlobMode mode,ExceptionInfo *exception)
2290 extension[MaxTextExtent],
2291 filename[MaxTextExtent];
2302 assert(image_info != (ImageInfo *) NULL);
2303 assert(image_info->signature == MagickSignature);
2304 if (image_info->debug != MagickFalse)
2305 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2306 image_info->filename);
2307 assert(image != (Image *) NULL);
2308 assert(image->signature == MagickSignature);
2309 if (image_info->blob != (void *) NULL)
2311 if (image_info->stream != (StreamHandler) NULL)
2312 image->blob->stream=(StreamHandler) image_info->stream;
2313 AttachBlob(image->blob,image_info->blob,image_info->length);
2316 (void) DetachBlob(image->blob);
2319 default: type="r"; break;
2320 case ReadBlobMode: type="r"; break;
2321 case ReadBinaryBlobMode: type="rb"; break;
2322 case WriteBlobMode: type="w"; break;
2323 case WriteBinaryBlobMode: type="w+b"; break;
2324 case AppendBlobMode: type="a"; break;
2325 case AppendBinaryBlobMode: type="a+b"; break;
2328 image->blob->synchronize=image_info->synchronize;
2329 if (image_info->stream != (StreamHandler) NULL)
2331 image->blob->stream=(StreamHandler) image_info->stream;
2334 image->blob->type=FifoStream;
2342 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2343 rights=ReadPolicyRights;
2345 rights=WritePolicyRights;
2346 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2349 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2350 "NotAuthorized","`%s'",filename);
2351 return(MagickFalse);
2353 if ((LocaleCompare(filename,"-") == 0) ||
2354 ((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2356 image->blob->file=(*type == 'r') ? stdin : stdout;
2357 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2358 if (strchr(type,'b') != (char *) NULL)
2359 setmode(_fileno(image->blob->file),_O_BINARY);
2361 image->blob->type=StandardStream;
2362 image->blob->exempt=MagickTrue;
2365 if (LocaleNCompare(filename,"fd:",3) == 0)
2368 mode[MaxTextExtent];
2372 image->blob->file=fdopen(StringToLong(filename+3),mode);
2373 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2374 if (strchr(type,'b') != (char *) NULL)
2375 setmode(_fileno(image->blob->file),_O_BINARY);
2377 image->blob->type=StandardStream;
2378 image->blob->exempt=MagickTrue;
2381 #if defined(MAGICKCORE_HAVE_POPEN)
2382 if (*filename == '|')
2385 mode[MaxTextExtent];
2388 Pipe image to or from a system command.
2390 #if defined(SIGPIPE)
2392 (void) signal(SIGPIPE,SIG_IGN);
2396 image->blob->file=(FILE *) popen(filename+1,mode);
2397 if (image->blob->file == (FILE *) NULL)
2399 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2400 return(MagickFalse);
2402 image->blob->type=PipeStream;
2403 image->blob->exempt=MagickTrue;
2407 status=GetPathAttributes(filename,&image->blob->properties);
2408 #if defined(S_ISFIFO)
2409 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2411 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2412 if (image->blob->file == (FILE *) NULL)
2414 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2415 return(MagickFalse);
2417 image->blob->type=FileStream;
2418 image->blob->exempt=MagickTrue;
2422 GetPathComponent(image->filename,ExtensionPath,extension);
2425 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2426 if ((image_info->adjoin == MagickFalse) ||
2427 (strchr(filename,'%') != (char *) NULL))
2430 Form filename for multi-part images.
2432 (void) InterpretImageFilename(image_info,image,image->filename,(int)
2433 image->scene,filename);
2434 if ((LocaleCompare(filename,image->filename) == 0) &&
2435 ((GetPreviousImageInList(image) != (Image *) NULL) ||
2436 (GetNextImageInList(image) != (Image *) NULL)))
2439 path[MaxTextExtent];
2441 GetPathComponent(image->filename,RootPath,path);
2442 if (*extension == '\0')
2443 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2444 path,(double) image->scene);
2446 (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g.%s",
2447 path,(double) image->scene,extension);
2449 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
2450 #if defined(macintosh)
2451 SetApplicationType(filename,image_info->magick,'8BIM');
2455 if (image_info->file != (FILE *) NULL)
2457 image->blob->file=image_info->file;
2458 image->blob->type=FileStream;
2459 image->blob->exempt=MagickTrue;
2464 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2465 if (image->blob->file != (FILE *) NULL)
2473 image->blob->type=FileStream;
2474 #if defined(MAGICKCORE_HAVE_SETVBUF)
2475 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2477 (void) ResetMagickMemory(magick,0,sizeof(magick));
2478 count=fread(magick,1,sizeof(magick),image->blob->file);
2479 (void) rewind(image->blob->file);
2480 (void) LogMagickEvent(BlobEvent,GetMagickModule(),
2481 " read %.20g magic header bytes",(double) count);
2482 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2483 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2484 ((int) magick[2] == 0x08))
2486 (void) fclose(image->blob->file);
2487 image->blob->file=(FILE *) gzopen(filename,type);
2488 if (image->blob->file != (FILE *) NULL)
2489 image->blob->type=ZipStream;
2492 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2493 if (strncmp((char *) magick,"BZh",3) == 0)
2495 (void) fclose(image->blob->file);
2496 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2497 if (image->blob->file != (FILE *) NULL)
2498 image->blob->type=BZipStream;
2501 if (image->blob->type == FileStream)
2512 sans_exception=AcquireExceptionInfo();
2513 magick_info=GetMagickInfo(image_info->magick,sans_exception);
2514 sans_exception=DestroyExceptionInfo(sans_exception);
2515 properties=(&image->blob->properties);
2516 if ((magick_info != (const MagickInfo *) NULL) &&
2517 (GetMagickBlobSupport(magick_info) != MagickFalse) &&
2518 (properties->st_size <= MagickMaxBufferExtent))
2526 length=(size_t) properties->st_size;
2527 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2528 if (blob != (void *) NULL)
2531 Format supports blobs-- use memory-mapped I/O.
2533 if (image_info->file != (FILE *) NULL)
2534 image->blob->exempt=MagickFalse;
2537 (void) fclose(image->blob->file);
2538 image->blob->file=(FILE *) NULL;
2540 AttachBlob(image->blob,blob,length);
2541 image->blob->mapped=MagickTrue;
2548 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2549 if ((LocaleCompare(extension,"Z") == 0) ||
2550 (LocaleCompare(extension,"gz") == 0) ||
2551 (LocaleCompare(extension,"wmz") == 0) ||
2552 (LocaleCompare(extension,"svgz") == 0))
2554 if (mode == WriteBinaryBlobMode)
2556 image->blob->file=(FILE *) gzopen(filename,type);
2557 if (image->blob->file != (FILE *) NULL)
2558 image->blob->type=ZipStream;
2562 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2563 if (LocaleCompare(extension,".bz2") == 0)
2565 image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2566 if (image->blob->file != (FILE *) NULL)
2567 image->blob->type=BZipStream;
2572 image->blob->file=(FILE *) OpenMagickStream(filename,type);
2573 if (image->blob->file != (FILE *) NULL)
2575 image->blob->type=FileStream;
2576 #if defined(MAGICKCORE_HAVE_SETVBUF)
2577 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2582 image->blob->status=MagickFalse;
2583 if (image->blob->type != UndefinedStream)
2584 image->blob->size=GetBlobSize(image);
2587 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2588 return(MagickFalse);
2594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2604 % PingBlob() returns all the attributes of an image or image sequence except
2605 % for the pixels. It is much faster and consumes far less memory than
2606 % BlobToImage(). On failure, a NULL image is returned and exception
2607 % describes the reason for the failure.
2609 % The format of the PingBlob method is:
2611 % Image *PingBlob(const ImageInfo *image_info,const void *blob,
2612 % const size_t length,ExceptionInfo *exception)
2614 % A description of each parameter follows:
2616 % o image_info: the image info.
2618 % o blob: the address of a character stream in one of the image formats
2619 % understood by ImageMagick.
2621 % o length: This size_t integer reflects the length in bytes of the blob.
2623 % o exception: return any errors or warnings in this structure.
2627 #if defined(__cplusplus) || defined(c_plusplus)
2631 static size_t PingStream(const Image *magick_unused(image),
2632 const void *magick_unused(pixels),const size_t columns)
2637 #if defined(__cplusplus) || defined(c_plusplus)
2641 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2642 const size_t length,ExceptionInfo *exception)
2650 assert(image_info != (ImageInfo *) NULL);
2651 assert(image_info->signature == MagickSignature);
2652 if (image_info->debug != MagickFalse)
2653 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2654 image_info->filename);
2655 assert(exception != (ExceptionInfo *) NULL);
2656 if ((blob == (const void *) NULL) || (length == 0))
2658 (void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2659 "UnrecognizedImageFormat","`%s'",image_info->magick);
2660 return((Image *) NULL);
2662 ping_info=CloneImageInfo(image_info);
2663 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2664 if (ping_info->blob == (const void *) NULL)
2666 (void) ThrowMagickException(exception,GetMagickModule(),
2667 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2668 return((Image *) NULL);
2670 (void) memcpy(ping_info->blob,blob,length);
2671 ping_info->length=length;
2672 ping_info->ping=MagickTrue;
2673 image=ReadStream(ping_info,&PingStream,exception);
2674 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2675 ping_info=DestroyImageInfo(ping_info);
2680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2690 % ReadBlob() reads data from the blob or image file and returns it. It
2691 % returns the number of bytes read.
2693 % The format of the ReadBlob method is:
2695 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2697 % A description of each parameter follows:
2699 % o image: the image.
2701 % o length: Specifies an integer representing the number of bytes to read
2704 % o data: Specifies an area to place the information requested from the
2708 MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2709 unsigned char *data)
2714 register unsigned char
2720 assert(image != (Image *) NULL);
2721 assert(image->signature == MagickSignature);
2722 assert(image->blob != (BlobInfo *) NULL);
2723 assert(image->blob->type != UndefinedStream);
2726 assert(data != (void *) NULL);
2729 switch (image->blob->type)
2731 case UndefinedStream:
2734 case StandardStream:
2741 count=(ssize_t) fread(q,1,length,image->blob->file);
2746 c=getc(image->blob->file);
2749 *q++=(unsigned char) c;
2754 c=getc(image->blob->file);
2757 *q++=(unsigned char) c;
2767 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2772 count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2777 c=gzgetc(image->blob->file);
2780 *q++=(unsigned char) c;
2785 c=gzgetc(image->blob->file);
2788 *q++=(unsigned char) c;
2799 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2800 count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2808 register const unsigned char
2811 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2813 image->blob->eof=MagickTrue;
2816 p=image->blob->data+image->blob->offset;
2817 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2818 image->blob->offset+=count;
2819 if (count != (ssize_t) length)
2820 image->blob->eof=MagickTrue;
2821 (void) memcpy(q,p,(size_t) count);
2829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2833 + R e a d B l o b B y t e %
2837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2839 % ReadBlobByte() reads a single byte from the image file and returns it.
2841 % The format of the ReadBlobByte method is:
2843 % int ReadBlobByte(Image *image)
2845 % A description of each parameter follows.
2847 % o image: the image.
2850 MagickExport int ReadBlobByte(Image *image)
2852 register const unsigned char
2861 assert(image != (Image *) NULL);
2862 assert(image->signature == MagickSignature);
2863 p=ReadBlobStream(image,1,buffer,&count);
2870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2874 + R e a d B l o b D o u b l e %
2878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2880 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2881 % specified by the endian member of the image structure.
2883 % The format of the ReadBlobDouble method is:
2885 % double ReadBlobDouble(Image *image)
2887 % A description of each parameter follows.
2889 % o image: the image.
2892 MagickExport double ReadBlobDouble(Image *image)
2903 quantum.double_value=0.0;
2904 quantum.unsigned_value=ReadBlobLongLong(image);
2905 return(quantum.double_value);
2909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2913 + R e a d B l o b F l o a t %
2917 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2919 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2920 % specified by the endian member of the image structure.
2922 % The format of the ReadBlobFloat method is:
2924 % float ReadBlobFloat(Image *image)
2926 % A description of each parameter follows.
2928 % o image: the image.
2931 MagickExport float ReadBlobFloat(Image *image)
2942 quantum.float_value=0.0;
2943 quantum.unsigned_value=ReadBlobLong(image);
2944 return(quantum.float_value);
2948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2952 + R e a d B l o b L o n g %
2956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2958 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2959 % specified by the endian member of the image structure.
2961 % The format of the ReadBlobLong method is:
2963 % unsigned int ReadBlobLong(Image *image)
2965 % A description of each parameter follows.
2967 % o image: the image.
2970 MagickExport unsigned int ReadBlobLong(Image *image)
2972 register const unsigned char
2984 assert(image != (Image *) NULL);
2985 assert(image->signature == MagickSignature);
2987 p=ReadBlobStream(image,4,buffer,&count);
2990 if (image->endian == LSBEndian)
2992 value=(unsigned int) (*p++);
2993 value|=((unsigned int) (*p++)) << 8;
2994 value|=((unsigned int) (*p++)) << 16;
2995 value|=((unsigned int) (*p++)) << 24;
2998 value=((unsigned int) (*p++)) << 24;
2999 value|=((unsigned int) (*p++)) << 16;
3000 value|=((unsigned int) (*p++)) << 8;
3001 value|=((unsigned int) (*p++));
3006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3010 + R e a d B l o b L o n g L o n g %
3014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3016 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3017 % byte-order specified by the endian member of the image structure.
3019 % The format of the ReadBlobLongLong method is:
3021 % MagickSizeType ReadBlobLongLong(Image *image)
3023 % A description of each parameter follows.
3025 % o image: the image.
3028 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3033 register const unsigned char
3042 assert(image != (Image *) NULL);
3043 assert(image->signature == MagickSignature);
3045 p=ReadBlobStream(image,8,buffer,&count);
3047 return(MagickULLConstant(0));
3048 if (image->endian == LSBEndian)
3050 value=(MagickSizeType) (*p++);
3051 value|=((MagickSizeType) (*p++)) << 8;
3052 value|=((MagickSizeType) (*p++)) << 16;
3053 value|=((MagickSizeType) (*p++)) << 24;
3054 value|=((MagickSizeType) (*p++)) << 32;
3055 value|=((MagickSizeType) (*p++)) << 40;
3056 value|=((MagickSizeType) (*p++)) << 48;
3057 value|=((MagickSizeType) (*p++)) << 56;
3058 return(value & MagickULLConstant(0xffffffffffffffff));
3060 value=((MagickSizeType) (*p++)) << 56;
3061 value|=((MagickSizeType) (*p++)) << 48;
3062 value|=((MagickSizeType) (*p++)) << 40;
3063 value|=((MagickSizeType) (*p++)) << 32;
3064 value|=((MagickSizeType) (*p++)) << 24;
3065 value|=((MagickSizeType) (*p++)) << 16;
3066 value|=((MagickSizeType) (*p++)) << 8;
3067 value|=((MagickSizeType) (*p++));
3068 return(value & MagickULLConstant(0xffffffffffffffff));
3072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3076 + R e a d B l o b S h o r t %
3080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3082 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3083 % specified by the endian member of the image structure.
3085 % The format of the ReadBlobShort method is:
3087 % unsigned short ReadBlobShort(Image *image)
3089 % A description of each parameter follows.
3091 % o image: the image.
3094 MagickExport unsigned short ReadBlobShort(Image *image)
3096 register const unsigned char
3099 register unsigned int
3108 assert(image != (Image *) NULL);
3109 assert(image->signature == MagickSignature);
3111 p=ReadBlobStream(image,2,buffer,&count);
3113 return((unsigned short) 0U);
3114 if (image->endian == LSBEndian)
3116 value=(unsigned int) (*p++);
3117 value|=((unsigned int) (*p++)) << 8;
3118 return((unsigned short) (value & 0xffff));
3120 value=(unsigned int) ((*p++) << 8);
3121 value|=(unsigned int) (*p++);
3122 return((unsigned short) (value & 0xffff));
3126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3130 + R e a d B l o b L S B L o n g %
3134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3136 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3137 % least-significant byte first order.
3139 % The format of the ReadBlobLSBLong method is:
3141 % unsigned int ReadBlobLSBLong(Image *image)
3143 % A description of each parameter follows.
3145 % o image: the image.
3148 MagickExport unsigned int ReadBlobLSBLong(Image *image)
3150 register const unsigned char
3153 register unsigned int
3162 assert(image != (Image *) NULL);
3163 assert(image->signature == MagickSignature);
3165 p=ReadBlobStream(image,4,buffer,&count);
3168 value=(unsigned int) (*p++);
3169 value|=((unsigned int) (*p++)) << 8;
3170 value|=((unsigned int) (*p++)) << 16;
3171 value|=((unsigned int) (*p++)) << 24;
3176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3180 + R e a d B l o b L S B S h o r t %
3184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3186 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3187 % least-significant byte first order.
3189 % The format of the ReadBlobLSBShort method is:
3191 % unsigned short ReadBlobLSBShort(Image *image)
3193 % A description of each parameter follows.
3195 % o image: the image.
3198 MagickExport unsigned short ReadBlobLSBShort(Image *image)
3200 register const unsigned char
3203 register unsigned int
3212 assert(image != (Image *) NULL);
3213 assert(image->signature == MagickSignature);
3215 p=ReadBlobStream(image,2,buffer,&count);
3217 return((unsigned short) 0U);
3218 value=(unsigned int) (*p++);
3219 value|=((unsigned int) ((*p++)) << 8);
3220 return((unsigned short) (value & 0xffff));
3224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3228 + R e a d B l o b M S B L o n g %
3232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3234 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3235 % most-significant byte first order.
3237 % The format of the ReadBlobMSBLong method is:
3239 % unsigned int ReadBlobMSBLong(Image *image)
3241 % A description of each parameter follows.
3243 % o image: the image.
3246 MagickExport unsigned int ReadBlobMSBLong(Image *image)
3248 register const unsigned char
3251 register unsigned int
3260 assert(image != (Image *) NULL);
3261 assert(image->signature == MagickSignature);
3263 p=ReadBlobStream(image,4,buffer,&count);
3266 value=((unsigned int) (*p++) << 24);
3267 value|=((unsigned int) (*p++) << 16);
3268 value|=((unsigned int) (*p++) << 8);
3269 value|=(unsigned int) (*p++);
3274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3278 + R e a d B l o b M S B L o n g L o n g %
3282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3284 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3285 % most-significant byte first order.
3287 % The format of the ReadBlobMSBLongLong method is:
3289 % unsigned int ReadBlobMSBLongLong(Image *image)
3291 % A description of each parameter follows.
3293 % o image: the image.
3296 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3298 register const unsigned char
3301 register MagickSizeType
3310 assert(image != (Image *) NULL);
3311 assert(image->signature == MagickSignature);
3313 p=ReadBlobStream(image,8,buffer,&count);
3315 return(MagickULLConstant(0));
3316 value=((MagickSizeType) (*p++)) << 56;
3317 value|=((MagickSizeType) (*p++)) << 48;
3318 value|=((MagickSizeType) (*p++)) << 40;
3319 value|=((MagickSizeType) (*p++)) << 32;
3320 value|=((MagickSizeType) (*p++)) << 24;
3321 value|=((MagickSizeType) (*p++)) << 16;
3322 value|=((MagickSizeType) (*p++)) << 8;
3323 value|=((MagickSizeType) (*p++));
3324 return(value & MagickULLConstant(0xffffffffffffffff));
3328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3332 + R e a d B l o b M S B S h o r t %
3336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3338 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3339 % most-significant byte first order.
3341 % The format of the ReadBlobMSBShort method is:
3343 % unsigned short ReadBlobMSBShort(Image *image)
3345 % A description of each parameter follows.
3347 % o image: the image.
3350 MagickExport unsigned short ReadBlobMSBShort(Image *image)
3352 register const unsigned char
3355 register unsigned int
3364 assert(image != (Image *) NULL);
3365 assert(image->signature == MagickSignature);
3367 p=ReadBlobStream(image,2,buffer,&count);
3369 return((unsigned short) 0U);
3370 value=(unsigned int) ((*p++) << 8);
3371 value|=(unsigned int) (*p++);
3372 return((unsigned short) (value & 0xffff));
3376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3380 + R e a d B l o b S t r i n g %
3384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3386 % ReadBlobString() reads characters from a blob or file until a newline
3387 % character is read or an end-of-file condition is encountered.
3389 % The format of the ReadBlobString method is:
3391 % char *ReadBlobString(Image *image,char *string)
3393 % A description of each parameter follows:
3395 % o image: the image.
3397 % o string: the address of a character buffer.
3400 MagickExport char *ReadBlobString(Image *image,char *string)
3402 register const unsigned char
3414 assert(image != (Image *) NULL);
3415 assert(image->signature == MagickSignature);
3416 for (i=0; i < (MaxTextExtent-1L); i++)
3418 p=ReadBlobStream(image,1,buffer,&count);
3422 return((char *) NULL);
3425 string[i]=(char) (*p);
3426 if ((string[i] == '\r') || (string[i] == '\n'))
3429 if (string[i] == '\r')
3430 (void) ReadBlobStream(image,1,buffer,&count);
3436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3440 + R e f e r e n c e B l o b %
3444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3446 % ReferenceBlob() increments the reference count associated with the pixel
3447 % blob returning a pointer to the blob.
3449 % The format of the ReferenceBlob method is:
3451 % BlobInfo ReferenceBlob(BlobInfo *blob_info)
3453 % A description of each parameter follows:
3455 % o blob_info: the blob_info.
3458 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3460 assert(blob != (BlobInfo *) NULL);
3461 assert(blob->signature == MagickSignature);
3462 if (blob->debug != MagickFalse)
3463 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3464 LockSemaphoreInfo(blob->semaphore);
3465 blob->reference_count++;
3466 UnlockSemaphoreInfo(blob->semaphore);
3471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3481 % SeekBlob() sets the offset in bytes from the beginning of a blob or file
3482 % and returns the resulting offset.
3484 % The format of the SeekBlob method is:
3486 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3489 % A description of each parameter follows:
3491 % o image: the image.
3493 % o offset: Specifies an integer representing the offset in bytes.
3495 % o whence: Specifies an integer representing how the offset is
3496 % treated relative to the beginning of the blob as follows:
3498 % SEEK_SET Set position equal to offset bytes.
3499 % SEEK_CUR Set position to current location plus offset.
3500 % SEEK_END Set position to EOF plus offset.
3503 MagickExport MagickOffsetType SeekBlob(Image *image,
3504 const MagickOffsetType offset,const int whence)
3506 assert(image != (Image *) NULL);
3507 assert(image->signature == MagickSignature);
3508 if (image->debug != MagickFalse)
3509 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3510 assert(image->blob != (BlobInfo *) NULL);
3511 assert(image->blob->type != UndefinedStream);
3512 switch (image->blob->type)
3514 case UndefinedStream:
3518 if (fseek(image->blob->file,offset,whence) < 0)
3520 image->blob->offset=TellBlob(image);
3523 case StandardStream:
3527 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3528 if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3531 image->blob->offset=TellBlob(image);
3547 image->blob->offset=offset;
3552 if ((image->blob->offset+offset) < 0)
3554 image->blob->offset+=offset;
3559 if (((MagickOffsetType) image->blob->length+offset) < 0)
3561 image->blob->offset=image->blob->length+offset;
3565 if (image->blob->offset <= (MagickOffsetType)
3566 ((off_t) image->blob->length))
3567 image->blob->eof=MagickFalse;
3569 if (image->blob->mapped != MagickFalse)
3573 image->blob->extent=(size_t) (image->blob->offset+
3574 image->blob->quantum);
3575 image->blob->data=(unsigned char *) ResizeQuantumMemory(
3576 image->blob->data,image->blob->extent+1,
3577 sizeof(*image->blob->data));
3578 (void) SyncBlob(image);
3579 if (image->blob->data == (unsigned char *) NULL)
3581 (void) DetachBlob(image->blob);
3588 return(image->blob->offset);
3592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3596 + S e t B l o b E x e m p t %
3600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3602 % SetBlobExempt() sets the blob exempt status.
3604 % The format of the SetBlobExempt method is:
3606 % MagickBooleanType SetBlobExempt(const Image *image,
3607 % const MagickBooleanType exempt)
3609 % A description of each parameter follows:
3611 % o image: the image.
3613 % o exempt: Set to true if this blob is exempt from being closed.
3616 MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3618 assert(image != (const Image *) NULL);
3619 assert(image->signature == MagickSignature);
3620 if (image->debug != MagickFalse)
3621 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3622 image->blob->exempt=exempt;
3626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3630 + S e t B l o b E x t e n t %
3634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3636 % SetBlobExtent() ensures enough space is allocated for the blob. If the
3637 % method is successful, subsequent writes to bytes in the specified range are
3638 % guaranteed not to fail.
3640 % The format of the SetBlobExtent method is:
3642 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3644 % A description of each parameter follows:
3646 % o image: the image.
3648 % o extent: the blob maximum extent.
3651 MagickExport MagickBooleanType SetBlobExtent(Image *image,
3652 const MagickSizeType extent)
3654 assert(image != (Image *) NULL);
3655 assert(image->signature == MagickSignature);
3656 if (image->debug != MagickFalse)
3657 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3658 assert(image->blob != (BlobInfo *) NULL);
3659 assert(image->blob->type != UndefinedStream);
3660 switch (image->blob->type)
3662 case UndefinedStream:
3666 if (extent != (MagickSizeType) ((off_t) extent))
3667 return(MagickFalse);
3668 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3669 return(MagickFalse);
3678 offset=TellBlob(image);
3679 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3680 (off_t) (extent-offset));
3682 return(MagickFalse);
3687 case StandardStream:
3690 return(MagickFalse);
3692 return(MagickFalse);
3694 return(MagickFalse);
3697 if (image->blob->mapped != MagickFalse)
3699 if (image->blob->file == (FILE *) NULL)
3700 return(MagickFalse);
3701 (void) UnmapBlob(image->blob->data,image->blob->length);
3702 #if !defined(MAGICKCORE_POSIX_FALLOCATE)
3703 return(MagickFalse);
3712 offset=TellBlob(image);
3713 status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3714 (off_t) (extent-offset));
3716 return(MagickFalse);
3718 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3719 WriteMode,0,(size_t) extent);
3720 image->blob->extent=(size_t) extent;
3721 image->blob->length=(size_t) extent;
3722 (void) SyncBlob(image);
3726 if (extent != (MagickSizeType) ((size_t) extent))
3727 return(MagickFalse);
3728 image->blob->extent=(size_t) extent;
3729 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3730 image->blob->extent+1,sizeof(*image->blob->data));
3731 (void) SyncBlob(image);
3732 if (image->blob->data == (unsigned char *) NULL)
3734 (void) DetachBlob(image->blob);
3735 return(MagickFalse);
3744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3752 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3754 % SyncBlob() flushes the datastream if it is a file or synchronizes the data
3755 % attributes if it is an blob.
3757 % The format of the SyncBlob method is:
3759 % int SyncBlob(Image *image)
3761 % A description of each parameter follows:
3763 % o image: the image.
3766 static int SyncBlob(Image *image)
3771 assert(image != (Image *) NULL);
3772 assert(image->signature == MagickSignature);
3773 if (image->debug != MagickFalse)
3774 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3775 assert(image->blob != (BlobInfo *) NULL);
3776 assert(image->blob->type != UndefinedStream);
3778 switch (image->blob->type)
3780 case UndefinedStream:
3783 case StandardStream:
3786 status=fflush(image->blob->file);
3791 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3792 status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3798 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3799 status=BZ2_bzflush((BZFILE *) image->blob->file);
3807 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3808 if (image->blob->mapped != MagickFalse)
3809 status=msync(image->blob->data,image->blob->length,MS_SYNC);
3818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3828 % TellBlob() obtains the current value of the blob or file position.
3830 % The format of the TellBlob method is:
3832 % MagickOffsetType TellBlob(const Image *image)
3834 % A description of each parameter follows:
3836 % o image: the image.
3839 MagickExport MagickOffsetType TellBlob(const Image *image)
3844 assert(image != (Image *) NULL);
3845 assert(image->signature == MagickSignature);
3846 if (image->debug != MagickFalse)
3847 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3848 assert(image->blob != (BlobInfo *) NULL);
3849 assert(image->blob->type != UndefinedStream);
3851 switch (image->blob->type)
3853 case UndefinedStream:
3857 offset=ftell(image->blob->file);
3860 case StandardStream:
3865 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3866 offset=(MagickOffsetType) gztell(image->blob->file);
3876 offset=image->blob->offset;
3884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3888 + U n m a p B l o b %
3892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3894 % UnmapBlob() deallocates the binary large object previously allocated with
3895 % the MapBlob method.
3897 % The format of the UnmapBlob method is:
3899 % MagickBooleanType UnmapBlob(void *map,const size_t length)
3901 % A description of each parameter follows:
3903 % o map: the address of the binary large object.
3905 % o length: the length of the binary large object.
3908 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3910 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3914 status=munmap(map,length);
3915 return(status == -1 ? MagickFalse : MagickTrue);
3919 return(MagickFalse);
3924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3928 + W r i t e B l o b %
3932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3934 % WriteBlob() writes data to a blob or image file. It returns the number of
3937 % The format of the WriteBlob method is:
3939 % ssize_t WriteBlob(Image *image,const size_t length,
3940 % const unsigned char *data)
3942 % A description of each parameter follows:
3944 % o image: the image.
3946 % o length: Specifies an integer representing the number of bytes to
3947 % write to the file.
3949 % o data: The address of the data to write to the blob or file.
3952 MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3953 const unsigned char *data)
3958 register const unsigned char
3964 assert(image != (Image *) NULL);
3965 assert(image->signature == MagickSignature);
3966 assert(data != (const unsigned char *) NULL);
3967 assert(image->blob != (BlobInfo *) NULL);
3968 assert(image->blob->type != UndefinedStream);
3973 switch (image->blob->type)
3975 case UndefinedStream:
3978 case StandardStream:
3985 count=(ssize_t) fwrite((const char *) data,1,length,
3991 c=putc((int) *p++,image->blob->file);
3998 c=putc((int) *p++,image->blob->file);
4010 #if defined(MAGICKCORE_ZLIB_DELEGATE)
4015 count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4016 (unsigned int) length);
4021 c=gzputc(image->blob->file,(int) *p++);
4028 c=gzputc(image->blob->file,(int) *p++);
4041 #if defined(MAGICKCORE_BZLIB_DELEGATE)
4042 count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4049 count=(ssize_t) image->blob->stream(image,data,length);
4054 register unsigned char
4057 if ((image->blob->offset+(MagickOffsetType) length) >=
4058 (MagickOffsetType) image->blob->extent)
4060 if (image->blob->mapped != MagickFalse)
4062 image->blob->quantum<<=1;
4063 image->blob->extent+=length+image->blob->quantum;
4064 image->blob->data=(unsigned char *) ResizeQuantumMemory(
4065 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4066 (void) SyncBlob(image);
4067 if (image->blob->data == (unsigned char *) NULL)
4069 (void) DetachBlob(image->blob);
4073 q=image->blob->data+image->blob->offset;
4074 (void) memcpy(q,p,length);
4075 image->blob->offset+=length;
4076 if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4077 image->blob->length=(size_t) image->blob->offset;
4078 count=(ssize_t) length;
4085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4089 + W r i t e B l o b B y t e %
4093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4095 % WriteBlobByte() write an integer to a blob. It returns the number of bytes
4096 % written (either 0 or 1);
4098 % The format of the WriteBlobByte method is:
4100 % ssize_t WriteBlobByte(Image *image,const unsigned char value)
4102 % A description of each parameter follows.
4104 % o image: the image.
4106 % o value: Specifies the value to write.
4109 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4111 assert(image != (Image *) NULL);
4112 assert(image->signature == MagickSignature);
4113 return(WriteBlobStream(image,1,&value));
4117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4121 + W r i t e B l o b F l o a t %
4125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4127 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4128 % specified by the endian member of the image structure.
4130 % The format of the WriteBlobFloat method is:
4132 % ssize_t WriteBlobFloat(Image *image,const float value)
4134 % A description of each parameter follows.
4136 % o image: the image.
4138 % o value: Specifies the value to write.
4141 MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4152 quantum.unsigned_value=0U;
4153 quantum.float_value=value;
4154 return(WriteBlobLong(image,quantum.unsigned_value));
4158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4162 + W r i t e B l o b L o n g %
4166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4168 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4169 % specified by the endian member of the image structure.
4171 % The format of the WriteBlobLong method is:
4173 % ssize_t WriteBlobLong(Image *image,const unsigned int value)
4175 % A description of each parameter follows.
4177 % o image: the image.
4179 % o value: Specifies the value to write.
4182 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4187 assert(image != (Image *) NULL);
4188 assert(image->signature == MagickSignature);
4189 if (image->endian == LSBEndian)
4191 buffer[0]=(unsigned char) value;
4192 buffer[1]=(unsigned char) (value >> 8);
4193 buffer[2]=(unsigned char) (value >> 16);
4194 buffer[3]=(unsigned char) (value >> 24);
4195 return(WriteBlobStream(image,4,buffer));
4197 buffer[0]=(unsigned char) (value >> 24);
4198 buffer[1]=(unsigned char) (value >> 16);
4199 buffer[2]=(unsigned char) (value >> 8);
4200 buffer[3]=(unsigned char) value;
4201 return(WriteBlobStream(image,4,buffer));
4205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4209 + W r i t e B l o b S h o r t %
4213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4215 % WriteBlobShort() writes a short value as a 16-bit quantity in the
4216 % byte-order specified by the endian member of the image structure.
4218 % The format of the WriteBlobShort method is:
4220 % ssize_t WriteBlobShort(Image *image,const unsigned short value)
4222 % A description of each parameter follows.
4224 % o image: the image.
4226 % o value: Specifies the value to write.
4229 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4234 assert(image != (Image *) NULL);
4235 assert(image->signature == MagickSignature);
4236 if (image->endian == LSBEndian)
4238 buffer[0]=(unsigned char) value;
4239 buffer[1]=(unsigned char) (value >> 8);
4240 return(WriteBlobStream(image,2,buffer));
4242 buffer[0]=(unsigned char) (value >> 8);
4243 buffer[1]=(unsigned char) value;
4244 return(WriteBlobStream(image,2,buffer));
4248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4252 + W r i t e B l o b L S B L o n g %
4256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4258 % WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4259 % least-significant byte first order.
4261 % The format of the WriteBlobLSBLong method is:
4263 % ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4265 % A description of each parameter follows.
4267 % o image: the image.
4269 % o value: Specifies the value to write.
4272 MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4277 assert(image != (Image *) NULL);
4278 assert(image->signature == MagickSignature);
4279 buffer[0]=(unsigned char) value;
4280 buffer[1]=(unsigned char) (value >> 8);
4281 buffer[2]=(unsigned char) (value >> 16);
4282 buffer[3]=(unsigned char) (value >> 24);
4283 return(WriteBlobStream(image,4,buffer));
4287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4291 + W r i t e B l o b L S B S h o r t %
4295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4297 % WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4298 % least-significant byte first order.
4300 % The format of the WriteBlobLSBShort method is:
4302 % ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4304 % A description of each parameter follows.
4306 % o image: the image.
4308 % o value: Specifies the value to write.
4311 MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4316 assert(image != (Image *) NULL);
4317 assert(image->signature == MagickSignature);
4318 buffer[0]=(unsigned char) value;
4319 buffer[1]=(unsigned char) (value >> 8);
4320 return(WriteBlobStream(image,2,buffer));
4324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4328 + W r i t e B l o b M S B L o n g %
4332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4334 % WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4335 % most-significant byte first order.
4337 % The format of the WriteBlobMSBLong method is:
4339 % ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4341 % A description of each parameter follows.
4343 % o value: Specifies the value to write.
4345 % o image: the image.
4348 MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4353 assert(image != (Image *) NULL);
4354 assert(image->signature == MagickSignature);
4355 buffer[0]=(unsigned char) (value >> 24);
4356 buffer[1]=(unsigned char) (value >> 16);
4357 buffer[2]=(unsigned char) (value >> 8);
4358 buffer[3]=(unsigned char) value;
4359 return(WriteBlobStream(image,4,buffer));
4363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4367 + W r i t e B l o b M S B L o n g L o n g %
4371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4373 % WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4374 % most-significant byte first order.
4376 % The format of the WriteBlobMSBLongLong method is:
4378 % ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4380 % A description of each parameter follows.
4382 % o value: Specifies the value to write.
4384 % o image: the image.
4387 MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4388 const MagickSizeType value)
4393 assert(image != (Image *) NULL);
4394 assert(image->signature == MagickSignature);
4395 buffer[0]=(unsigned char) (value >> 56);
4396 buffer[1]=(unsigned char) (value >> 48);
4397 buffer[2]=(unsigned char) (value >> 40);
4398 buffer[3]=(unsigned char) (value >> 32);
4399 buffer[4]=(unsigned char) (value >> 24);
4400 buffer[5]=(unsigned char) (value >> 16);
4401 buffer[6]=(unsigned char) (value >> 8);
4402 buffer[7]=(unsigned char) value;
4403 return(WriteBlobStream(image,8,buffer));
4407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4411 + W r i t e B l o b M S B S h o r t %
4415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4417 % WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4418 % most-significant byte first order.
4420 % The format of the WriteBlobMSBShort method is:
4422 % ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4424 % A description of each parameter follows.
4426 % o value: Specifies the value to write.
4428 % o file: Specifies the file to write the data to.
4431 MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4436 assert(image != (Image *) NULL);
4437 assert(image->signature == MagickSignature);
4438 buffer[0]=(unsigned char) (value >> 8);
4439 buffer[1]=(unsigned char) value;
4440 return(WriteBlobStream(image,2,buffer));
4444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4448 + W r i t e B l o b S t r i n g %
4452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4454 % WriteBlobString() write a string to a blob. It returns the number of
4455 % characters written.
4457 % The format of the WriteBlobString method is:
4459 % ssize_t WriteBlobString(Image *image,const char *string)
4461 % A description of each parameter follows.
4463 % o image: the image.
4465 % o string: Specifies the string to write.
4468 MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4470 assert(image != (Image *) NULL);
4471 assert(image->signature == MagickSignature);
4472 assert(string != (const char *) NULL);
4473 return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));