| /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                         BBBB   L       OOO   BBBB                           % | 
 | %                         B   B  L      O   O  B   B                          % | 
 | %                         BBBB   L      O   O  BBBB                           % | 
 | %                         B   B  L      O   O  B   B                          % | 
 | %                         BBBB   LLLLL   OOO   BBBB                           % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                     MagickCore Binary Large OBjectS Methods                 % | 
 | %                                                                             % | 
 | %                              Software Design                                % | 
 | %                                John Cristy                                  % | 
 | %                                 July 1999                                   % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      % | 
 | %  dedicated to making software imaging solutions freely available.           % | 
 | %                                                                             % | 
 | %  You may not use this file except in compliance with the License.  You may  % | 
 | %  obtain a copy of the License at                                            % | 
 | %                                                                             % | 
 | %    http://www.imagemagick.org/script/license.php                            % | 
 | %                                                                             % | 
 | %  Unless required by applicable law or agreed to in writing, software        % | 
 | %  distributed under the License is distributed on an "AS IS" BASIS,          % | 
 | %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   % | 
 | %  See the License for the specific language governing permissions and        % | 
 | %  limitations under the License.                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | % | 
 | % | 
 | */ | 
 |  | 
 | /* | 
 |   Include declarations. | 
 | */ | 
 | #include "MagickCore/studio.h" | 
 | #include "MagickCore/blob.h" | 
 | #include "MagickCore/blob-private.h" | 
 | #include "MagickCore/cache.h" | 
 | #include "MagickCore/client.h" | 
 | #include "MagickCore/constitute.h" | 
 | #include "MagickCore/delegate.h" | 
 | #include "MagickCore/exception.h" | 
 | #include "MagickCore/exception-private.h" | 
 | #include "MagickCore/image-private.h" | 
 | #include "MagickCore/list.h" | 
 | #include "MagickCore/locale_.h" | 
 | #include "MagickCore/log.h" | 
 | #include "MagickCore/magick.h" | 
 | #include "MagickCore/memory_.h" | 
 | #include "MagickCore/policy.h" | 
 | #include "MagickCore/resource_.h" | 
 | #include "MagickCore/semaphore.h" | 
 | #include "MagickCore/string_.h" | 
 | #include "MagickCore/string-private.h" | 
 | #include "MagickCore/token.h" | 
 | #include "MagickCore/utility.h" | 
 | #include "MagickCore/utility-private.h" | 
 | #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT) | 
 | # include <sys/mman.h> | 
 | #endif | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 | #include "zlib.h" | 
 | #endif | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 | #include "bzlib.h" | 
 | #endif | 
 |  | 
 | /* | 
 |   Define declarations. | 
 | */ | 
 | #define MagickMaxBlobExtent  65541 | 
 | #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) | 
 | # define MAP_ANONYMOUS  MAP_ANON | 
 | #endif | 
 | #if !defined(MAP_FAILED) | 
 | #define MAP_FAILED  ((void *) -1) | 
 | #endif | 
 | #if !defined(MS_SYNC) | 
 | #define MS_SYNC  0x04 | 
 | #endif | 
 | #if defined(__OS2__) | 
 | #include <io.h> | 
 | #define _O_BINARY O_BINARY | 
 | #endif | 
 |  | 
 | /* | 
 |   Typedef declarations. | 
 | */ | 
 | struct _BlobInfo | 
 | { | 
 |   size_t | 
 |     length, | 
 |     extent, | 
 |     quantum; | 
 |  | 
 |   MagickBooleanType | 
 |     mapped, | 
 |     eof; | 
 |  | 
 |   MagickOffsetType | 
 |     offset; | 
 |  | 
 |   MagickSizeType | 
 |     size; | 
 |  | 
 |   MagickBooleanType | 
 |     exempt, | 
 |     synchronize, | 
 |     status, | 
 |     temporary; | 
 |  | 
 |   StreamType | 
 |     type; | 
 |  | 
 |   FILE | 
 |     *file; | 
 |  | 
 |   struct stat | 
 |     properties; | 
 |  | 
 |   StreamHandler | 
 |     stream; | 
 |  | 
 |   unsigned char | 
 |     *data; | 
 |  | 
 |   MagickBooleanType | 
 |     debug; | 
 |  | 
 |   SemaphoreInfo | 
 |     *semaphore; | 
 |  | 
 |   ssize_t | 
 |     reference_count; | 
 |  | 
 |   size_t | 
 |     signature; | 
 | }; | 
 |  | 
 | /* | 
 |   Forward declarations. | 
 | */ | 
 | static int | 
 |   SyncBlob(Image *); | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   A t t a c h B l o b                                                       % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  AttachBlob() attaches a blob to the BlobInfo structure. | 
 | % | 
 | %  The format of the AttachBlob method is: | 
 | % | 
 | %      void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o blob_info: Specifies a pointer to a BlobInfo structure. | 
 | % | 
 | %    o blob: the address of a character stream in one of the image formats | 
 | %      understood by ImageMagick. | 
 | % | 
 | %    o length: This size_t integer reflects the length in bytes of the blob. | 
 | % | 
 | */ | 
 | MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob, | 
 |   const size_t length) | 
 | { | 
 |   assert(blob_info != (BlobInfo *) NULL); | 
 |   if (blob_info->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); | 
 |   blob_info->length=length; | 
 |   blob_info->extent=length; | 
 |   blob_info->quantum=(size_t) MagickMaxBlobExtent; | 
 |   blob_info->offset=0; | 
 |   blob_info->type=BlobStream; | 
 |   blob_info->file=(FILE *) NULL; | 
 |   blob_info->data=(unsigned char *) blob; | 
 |   blob_info->mapped=MagickFalse; | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   B l o b T o F i l e                                                       % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  BlobToFile() writes a blob to a file.  It returns MagickFalse if an error | 
 | %  occurs otherwise MagickTrue. | 
 | % | 
 | %  The format of the BlobToFile method is: | 
 | % | 
 | %       MagickBooleanType BlobToFile(char *filename,const void *blob, | 
 | %         const size_t length,ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o filename: Write the blob to this file. | 
 | % | 
 | %    o blob: the address of a blob. | 
 | % | 
 | %    o length: This length in bytes of the blob. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 |  | 
 | static inline MagickSizeType MagickMin(const MagickSizeType x, | 
 |   const MagickSizeType y) | 
 | { | 
 |   if (x < y) | 
 |     return(x); | 
 |   return(y); | 
 | } | 
 |  | 
 | MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob, | 
 |   const size_t length,ExceptionInfo *exception) | 
 | { | 
 |   int | 
 |     file; | 
 |  | 
 |   register size_t | 
 |     i; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   assert(filename != (const char *) NULL); | 
 |   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); | 
 |   assert(blob != (const void *) NULL); | 
 |   if (*filename == '\0') | 
 |     file=AcquireUniqueFileResource(filename); | 
 |   else | 
 |     file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE); | 
 |   if (file == -1) | 
 |     { | 
 |       ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   for (i=0; i < length; i+=count) | 
 |   { | 
 |     count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length- | 
 |       i,(MagickSizeType) SSIZE_MAX)); | 
 |     if (count <= 0) | 
 |       { | 
 |         count=0; | 
 |         if (errno != EINTR) | 
 |           break; | 
 |       } | 
 |   } | 
 |   file=close(file); | 
 |   if ((file == -1) || (i < length)) | 
 |     { | 
 |       ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   return(MagickTrue); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   B l o b T o I m a g e                                                     % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  BlobToImage() implements direct to memory image formats.  It returns the | 
 | %  blob as an image. | 
 | % | 
 | %  The format of the BlobToImage method is: | 
 | % | 
 | %      Image *BlobToImage(const ImageInfo *image_info,const void *blob, | 
 | %        const size_t length,ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image_info: the image info. | 
 | % | 
 | %    o blob: the address of a character stream in one of the image formats | 
 | %      understood by ImageMagick. | 
 | % | 
 | %    o length: This size_t integer reflects the length in bytes of the blob. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 | MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob, | 
 |   const size_t length,ExceptionInfo *exception) | 
 | { | 
 |   const MagickInfo | 
 |     *magick_info; | 
 |  | 
 |   Image | 
 |     *image; | 
 |  | 
 |   ImageInfo | 
 |     *blob_info, | 
 |     *clone_info; | 
 |  | 
 |   MagickBooleanType | 
 |     status; | 
 |  | 
 |   assert(image_info != (ImageInfo *) NULL); | 
 |   assert(image_info->signature == MagickSignature); | 
 |   if (image_info->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", | 
 |       image_info->filename); | 
 |   assert(exception != (ExceptionInfo *) NULL); | 
 |   if ((blob == (const void *) NULL) || (length == 0)) | 
 |     { | 
 |       (void) ThrowMagickException(exception,GetMagickModule(),BlobError, | 
 |         "ZeroLengthBlobNotPermitted","`%s'",image_info->filename); | 
 |       return((Image *) NULL); | 
 |     } | 
 |   blob_info=CloneImageInfo(image_info); | 
 |   blob_info->blob=(void *) blob; | 
 |   blob_info->length=length; | 
 |   if (*blob_info->magick == '\0') | 
 |     (void) SetImageInfo(blob_info,0,exception); | 
 |   magick_info=GetMagickInfo(blob_info->magick,exception); | 
 |   if (magick_info == (const MagickInfo *) NULL) | 
 |     { | 
 |       blob_info=DestroyImageInfo(blob_info); | 
 |       (void) ThrowMagickException(exception,GetMagickModule(), | 
 |         MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", | 
 |         image_info->filename); | 
 |       return((Image *) NULL); | 
 |     } | 
 |   if (GetMagickBlobSupport(magick_info) != MagickFalse) | 
 |     { | 
 |       /* | 
 |         Native blob support for this image format. | 
 |       */ | 
 |       (void) CopyMagickString(blob_info->filename,image_info->filename, | 
 |         MaxTextExtent); | 
 |       (void) CopyMagickString(blob_info->magick,image_info->magick, | 
 |         MaxTextExtent); | 
 |       image=ReadImage(blob_info,exception); | 
 |       if (image != (Image *) NULL) | 
 |         (void) DetachBlob(image->blob); | 
 |       blob_info=DestroyImageInfo(blob_info); | 
 |       return(image); | 
 |     } | 
 |   /* | 
 |     Write blob to a temporary file on disk. | 
 |   */ | 
 |   blob_info->blob=(void *) NULL; | 
 |   blob_info->length=0; | 
 |   *blob_info->filename='\0'; | 
 |   status=BlobToFile(blob_info->filename,blob,length,exception); | 
 |   if (status == MagickFalse) | 
 |     { | 
 |       (void) RelinquishUniqueFileResource(blob_info->filename); | 
 |       blob_info=DestroyImageInfo(blob_info); | 
 |       return((Image *) NULL); | 
 |     } | 
 |   clone_info=CloneImageInfo(blob_info); | 
 |   (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s", | 
 |     blob_info->magick,blob_info->filename); | 
 |   image=ReadImage(clone_info,exception); | 
 |   clone_info=DestroyImageInfo(clone_info); | 
 |   (void) RelinquishUniqueFileResource(blob_info->filename); | 
 |   blob_info=DestroyImageInfo(blob_info); | 
 |   return(image); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   C l o n e B l o b I n f o                                                 % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  CloneBlobInfo() makes a duplicate of the given blob info structure, or if | 
 | %  blob info is NULL, a new one. | 
 | % | 
 | %  The format of the CloneBlobInfo method is: | 
 | % | 
 | %      BlobInfo *CloneBlobInfo(const BlobInfo *blob_info) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o blob_info: the blob info. | 
 | % | 
 | */ | 
 | MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info) | 
 | { | 
 |   BlobInfo | 
 |     *clone_info; | 
 |  | 
 |   clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info)); | 
 |   if (clone_info == (BlobInfo *) NULL) | 
 |     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); | 
 |   GetBlobInfo(clone_info); | 
 |   if (blob_info == (BlobInfo *) NULL) | 
 |     return(clone_info); | 
 |   clone_info->length=blob_info->length; | 
 |   clone_info->extent=blob_info->extent; | 
 |   clone_info->synchronize=blob_info->synchronize; | 
 |   clone_info->quantum=blob_info->quantum; | 
 |   clone_info->mapped=blob_info->mapped; | 
 |   clone_info->eof=blob_info->eof; | 
 |   clone_info->offset=blob_info->offset; | 
 |   clone_info->size=blob_info->size; | 
 |   clone_info->exempt=blob_info->exempt; | 
 |   clone_info->status=blob_info->status; | 
 |   clone_info->temporary=blob_info->temporary; | 
 |   clone_info->type=blob_info->type; | 
 |   clone_info->file=blob_info->file; | 
 |   clone_info->properties=blob_info->properties; | 
 |   clone_info->stream=blob_info->stream; | 
 |   clone_info->data=blob_info->data; | 
 |   clone_info->debug=IsEventLogging(); | 
 |   clone_info->reference_count=1; | 
 |   return(clone_info); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   C l o s e B l o b                                                         % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  CloseBlob() closes a stream associated with the image. | 
 | % | 
 | %  The format of the CloseBlob method is: | 
 | % | 
 | %      MagickBooleanType CloseBlob(Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport MagickBooleanType CloseBlob(Image *image) | 
 | { | 
 |   int | 
 |     status; | 
 |  | 
 |   /* | 
 |     Close image file. | 
 |   */ | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   if (image->blob->type == UndefinedStream) | 
 |     return(MagickTrue); | 
 |   if (image->blob->synchronize != MagickFalse) | 
 |     SyncBlob(image); | 
 |   image->blob->size=GetBlobSize(image); | 
 |   image->extent=image->blob->size; | 
 |   image->blob->eof=MagickFalse; | 
 |   if (image->blob->exempt != MagickFalse) | 
 |     { | 
 |       image->blob->type=UndefinedStream; | 
 |       return(MagickTrue); | 
 |     } | 
 |   status=0; | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |     { | 
 |       status=ferror(image->blob->file); | 
 |       break; | 
 |     } | 
 |     case ZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |       (void) gzerror(image->blob->file,&status); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case BZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 |       (void) BZ2_bzerror((BZFILE *) image->blob->file,&status); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case FifoStream: | 
 |     case BlobStream: | 
 |       break; | 
 |   } | 
 |   image->blob->status=status < 0 ? MagickTrue : MagickFalse; | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     case StandardStream: | 
 |     { | 
 |       if (image->blob->synchronize != MagickFalse) | 
 |         { | 
 |           status=fflush(image->blob->file); | 
 |           status=fsync(fileno(image->blob->file)); | 
 |         } | 
 |       status=fclose(image->blob->file); | 
 |       break; | 
 |     } | 
 |     case PipeStream: | 
 |     { | 
 | #if defined(MAGICKCORE_HAVE_PCLOSE) | 
 |       status=pclose(image->blob->file); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case ZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |       status=gzclose(image->blob->file); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case BZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 |       BZ2_bzclose((BZFILE *) image->blob->file); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case FifoStream: | 
 |       break; | 
 |     case BlobStream: | 
 |     { | 
 |       if (image->blob->file != (FILE *) NULL) | 
 |         { | 
 |           if (image->blob->synchronize != MagickFalse) | 
 |             (void) fsync(fileno(image->blob->file)); | 
 |           status=fclose(image->blob->file); | 
 |         } | 
 |       break; | 
 |     } | 
 |   } | 
 |   (void) DetachBlob(image->blob); | 
 |   image->blob->status=status < 0 ? MagickTrue : MagickFalse; | 
 |   return(image->blob->status); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   D e s t r o y B l o b                                                     % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  DestroyBlob() deallocates memory associated with a blob. | 
 | % | 
 | %  The format of the DestroyBlob method is: | 
 | % | 
 | %      void DestroyBlob(Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport void DestroyBlob(Image *image) | 
 | { | 
 |   MagickBooleanType | 
 |     destroy; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->signature == MagickSignature); | 
 |   destroy=MagickFalse; | 
 |   LockSemaphoreInfo(image->blob->semaphore); | 
 |   image->blob->reference_count--; | 
 |   assert(image->blob->reference_count >= 0); | 
 |   if (image->blob->reference_count == 0) | 
 |     destroy=MagickTrue; | 
 |   UnlockSemaphoreInfo(image->blob->semaphore); | 
 |   if (destroy == MagickFalse) | 
 |     return; | 
 |   (void) CloseBlob(image); | 
 |   if (image->blob->mapped != MagickFalse) | 
 |     (void) UnmapBlob(image->blob->data,image->blob->length); | 
 |   if (image->blob->semaphore != (SemaphoreInfo *) NULL) | 
 |     DestroySemaphoreInfo(&image->blob->semaphore); | 
 |   image->blob->signature=(~MagickSignature); | 
 |   image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   D e t a c h B l o b                                                       % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  DetachBlob() detaches a blob from the BlobInfo structure. | 
 | % | 
 | %  The format of the DetachBlob method is: | 
 | % | 
 | %      unsigned char *DetachBlob(BlobInfo *blob_info) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o blob_info: Specifies a pointer to a BlobInfo structure. | 
 | % | 
 | */ | 
 | MagickExport unsigned char *DetachBlob(BlobInfo *blob_info) | 
 | { | 
 |   unsigned char | 
 |     *data; | 
 |  | 
 |   assert(blob_info != (BlobInfo *) NULL); | 
 |   if (blob_info->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); | 
 |   if (blob_info->mapped != MagickFalse) | 
 |     (void) UnmapBlob(blob_info->data,blob_info->length); | 
 |   blob_info->mapped=MagickFalse; | 
 |   blob_info->length=0; | 
 |   blob_info->offset=0; | 
 |   blob_info->eof=MagickFalse; | 
 |   blob_info->exempt=MagickFalse; | 
 |   blob_info->type=UndefinedStream; | 
 |   blob_info->file=(FILE *) NULL; | 
 |   data=blob_info->data; | 
 |   blob_info->data=(unsigned char *) NULL; | 
 |   blob_info->stream=(StreamHandler) NULL; | 
 |   return(data); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  D i s c a r d B l o b B y t e s                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  DiscardBlobBytes() discards bytes in a blob. | 
 | % | 
 | %  The format of the DiscardBlobBytes method is: | 
 | % | 
 | %      MagickBooleanType DiscardBlobBytes(Image *image,const size_t length) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o length:  the number of bytes to skip. | 
 | % | 
 | */ | 
 |  | 
 | static inline const unsigned char *ReadBlobStream(Image *image, | 
 |   const size_t length,unsigned char *data,ssize_t *count) | 
 | { | 
 |   assert(count != (ssize_t *) NULL); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   if (image->blob->type != BlobStream) | 
 |     { | 
 |       *count=ReadBlob(image,length,data); | 
 |       return(data); | 
 |     } | 
 |   if (image->blob->offset >= (MagickOffsetType) image->blob->length) | 
 |     { | 
 |       *count=0; | 
 |       image->blob->eof=MagickTrue; | 
 |       return(data); | 
 |     } | 
 |   data=image->blob->data+image->blob->offset; | 
 |   *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length- | 
 |     image->blob->offset)); | 
 |   image->blob->offset+=(*count); | 
 |   if (*count != (ssize_t) length) | 
 |     image->blob->eof=MagickTrue; | 
 |   return(data); | 
 | } | 
 |  | 
 | MagickExport MagickBooleanType DiscardBlobBytes(Image *image, | 
 |   const MagickSizeType length) | 
 | { | 
 |   register MagickOffsetType | 
 |     i; | 
 |  | 
 |   size_t | 
 |     quantum; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[16384]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   count=0; | 
 |   for (i=0; i < (MagickOffsetType) length; i+=count) | 
 |   { | 
 |     quantum=(size_t) MagickMin(length-i,sizeof(buffer)); | 
 |     (void) ReadBlobStream(image,quantum,buffer,&count); | 
 |     if (count <= 0) | 
 |       { | 
 |         count=0; | 
 |         if (errno != EINTR) | 
 |           break; | 
 |       } | 
 |   } | 
 |   return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   D u p l i c a t e s B l o b                                               % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  DuplicateBlob() duplicates a blob descriptor. | 
 | % | 
 | %  The format of the DuplicateBlob method is: | 
 | % | 
 | %      void DuplicateBlob(Image *image,const Image *duplicate) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o duplicate: the duplicate image. | 
 | % | 
 | */ | 
 | MagickExport void DuplicateBlob(Image *image,const Image *duplicate) | 
 | { | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(duplicate != (Image *) NULL); | 
 |   assert(duplicate->signature == MagickSignature); | 
 |   DestroyBlob(image); | 
 |   image->blob=ReferenceBlob(duplicate->blob); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  E O F B l o b                                                              % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  EOFBlob() returns a non-zero value when EOF has been detected reading from | 
 | %  a blob or file. | 
 | % | 
 | %  The format of the EOFBlob method is: | 
 | % | 
 | %      int EOFBlob(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport int EOFBlob(const Image *image) | 
 | { | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |     { | 
 |       image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse; | 
 |       break; | 
 |     } | 
 |     case ZipStream: | 
 |     { | 
 |       image->blob->eof=MagickFalse; | 
 |       break; | 
 |     } | 
 |     case BZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 |       int | 
 |         status; | 
 |  | 
 |       status=0; | 
 |       (void) BZ2_bzerror((BZFILE *) image->blob->file,&status); | 
 |       image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse; | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case FifoStream: | 
 |     { | 
 |       image->blob->eof=MagickFalse; | 
 |       break; | 
 |     } | 
 |     case BlobStream: | 
 |       break; | 
 |   } | 
 |   return((int) image->blob->eof); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   F i l e T o B l o b                                                       % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  FileToBlob() returns the contents of a file as a buffer terminated with | 
 | %  the '\0' character.  The length of the buffer (not including the extra | 
 | %  terminating '\0' character) is returned via the 'length' parameter.  Free | 
 | %  the buffer with RelinquishMagickMemory(). | 
 | % | 
 | %  The format of the FileToBlob method is: | 
 | % | 
 | %      unsigned char *FileToBlob(const char *filename,const size_t extent, | 
 | %        size_t *length,ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o blob:  FileToBlob() returns the contents of a file as a blob.  If | 
 | %      an error occurs NULL is returned. | 
 | % | 
 | %    o filename: the filename. | 
 | % | 
 | %    o extent:  The maximum length of the blob. | 
 | % | 
 | %    o length: On return, this reflects the actual length of the blob. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 | MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent, | 
 |   size_t *length,ExceptionInfo *exception) | 
 | { | 
 |   int | 
 |     file; | 
 |  | 
 |   MagickOffsetType | 
 |     offset; | 
 |  | 
 |   register size_t | 
 |     i; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     *blob; | 
 |  | 
 |   void | 
 |     *map; | 
 |  | 
 |   assert(filename != (const char *) NULL); | 
 |   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); | 
 |   assert(exception != (ExceptionInfo *) NULL); | 
 |   *length=0; | 
 |   file=fileno(stdin); | 
 |   if (LocaleCompare(filename,"-") != 0) | 
 |     file=open_utf8(filename,O_RDONLY | O_BINARY,0); | 
 |   if (file == -1) | 
 |     { | 
 |       ThrowFileException(exception,BlobError,"UnableToOpenFile",filename); | 
 |       return((unsigned char *) NULL); | 
 |     } | 
 |   offset=(MagickOffsetType) lseek(file,0,SEEK_END); | 
 |   count=0; | 
 |   if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset))) | 
 |     { | 
 |       size_t | 
 |         quantum; | 
 |  | 
 |       struct stat | 
 |         file_info; | 
 |  | 
 |       /* | 
 |         Stream is not seekable. | 
 |       */ | 
 |       quantum=(size_t) MagickMaxBufferExtent; | 
 |       if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0)) | 
 |         quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size, | 
 |           MagickMaxBufferExtent); | 
 |       blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob)); | 
 |       for (i=0; blob != (unsigned char *) NULL; i+=count) | 
 |       { | 
 |         count=(ssize_t) read(file,blob+i,quantum); | 
 |         if (count <= 0) | 
 |           { | 
 |             count=0; | 
 |             if (errno != EINTR) | 
 |               break; | 
 |           } | 
 |         if (~(1UL*i) < (quantum+1)) | 
 |           { | 
 |             blob=(unsigned char *) RelinquishMagickMemory(blob); | 
 |             break; | 
 |           } | 
 |         blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1, | 
 |           sizeof(*blob)); | 
 |         if ((size_t) (i+count) >= extent) | 
 |           break; | 
 |       } | 
 |       if (LocaleCompare(filename,"-") != 0) | 
 |         file=close(file); | 
 |       if (blob == (unsigned char *) NULL) | 
 |         { | 
 |           (void) ThrowMagickException(exception,GetMagickModule(), | 
 |             ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); | 
 |           return((unsigned char *) NULL); | 
 |         } | 
 |       if (file == -1) | 
 |         { | 
 |           blob=(unsigned char *) RelinquishMagickMemory(blob); | 
 |           ThrowFileException(exception,BlobError,"UnableToReadBlob",filename); | 
 |           return((unsigned char *) NULL); | 
 |         } | 
 |       *length=(size_t) MagickMin(i+count,extent); | 
 |       blob[*length]='\0'; | 
 |       return(blob); | 
 |     } | 
 |   *length=(size_t) MagickMin((MagickSizeType) offset,extent); | 
 |   blob=(unsigned char *) NULL; | 
 |   if (~(*length) >= (MaxTextExtent-1)) | 
 |     blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent, | 
 |       sizeof(*blob)); | 
 |   if (blob == (unsigned char *) NULL) | 
 |     { | 
 |       file=close(file); | 
 |       (void) ThrowMagickException(exception,GetMagickModule(), | 
 |         ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); | 
 |       return((unsigned char *) NULL); | 
 |     } | 
 |   map=MapBlob(file,ReadMode,0,*length); | 
 |   if (map != (unsigned char *) NULL) | 
 |     { | 
 |       (void) memcpy(blob,map,*length); | 
 |       (void) UnmapBlob(map,*length); | 
 |     } | 
 |   else | 
 |     { | 
 |       (void) lseek(file,0,SEEK_SET); | 
 |       for (i=0; i < *length; i+=count) | 
 |       { | 
 |         count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i, | 
 |           (MagickSizeType) SSIZE_MAX)); | 
 |         if (count <= 0) | 
 |           { | 
 |             count=0; | 
 |             if (errno != EINTR) | 
 |               break; | 
 |           } | 
 |       } | 
 |       if (i < *length) | 
 |         { | 
 |           file=close(file)-1; | 
 |           blob=(unsigned char *) RelinquishMagickMemory(blob); | 
 |           ThrowFileException(exception,BlobError,"UnableToReadBlob",filename); | 
 |           return((unsigned char *) NULL); | 
 |         } | 
 |     } | 
 |   blob[*length]='\0'; | 
 |   if (LocaleCompare(filename,"-") != 0) | 
 |     file=close(file); | 
 |   if (file == -1) | 
 |     { | 
 |       blob=(unsigned char *) RelinquishMagickMemory(blob); | 
 |       ThrowFileException(exception,BlobError,"UnableToReadBlob",filename); | 
 |     } | 
 |   return(blob); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   F i l e T o I m a g e                                                     % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  FileToImage() write the contents of a file to an image. | 
 | % | 
 | %  The format of the FileToImage method is: | 
 | % | 
 | %      MagickBooleanType FileToImage(Image *,const char *filename) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o filename: the filename. | 
 | % | 
 | */ | 
 |  | 
 | static inline ssize_t WriteBlobStream(Image *image,const size_t length, | 
 |   const unsigned char *data) | 
 | { | 
 |   MagickSizeType | 
 |     extent; | 
 |  | 
 |   register unsigned char | 
 |     *q; | 
 |  | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   if (image->blob->type != BlobStream) | 
 |     return(WriteBlob(image,length,data)); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   assert(data != (void *) NULL); | 
 |   extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length); | 
 |   if (extent >= image->blob->extent) | 
 |     { | 
 |       image->blob->quantum<<=1; | 
 |       extent=image->blob->extent+image->blob->quantum+length; | 
 |       if (SetBlobExtent(image,extent) == MagickFalse) | 
 |         return(0); | 
 |     } | 
 |   q=image->blob->data+image->blob->offset; | 
 |   (void) memcpy(q,data,length); | 
 |   image->blob->offset+=length; | 
 |   if (image->blob->offset >= (MagickOffsetType) image->blob->length) | 
 |     image->blob->length=(size_t) image->blob->offset; | 
 |   return((ssize_t) length); | 
 | } | 
 |  | 
 | MagickExport MagickBooleanType FileToImage(Image *image,const char *filename, | 
 |   ExceptionInfo *exception) | 
 | { | 
 |   int | 
 |     file; | 
 |  | 
 |   size_t | 
 |     length, | 
 |     quantum; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   struct stat | 
 |     file_info; | 
 |  | 
 |   unsigned char | 
 |     *blob; | 
 |  | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   assert(filename != (const char *) NULL); | 
 |   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); | 
 |   file=open_utf8(filename,O_RDONLY | O_BINARY,0); | 
 |   if (file == -1) | 
 |     { | 
 |       ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   quantum=(size_t) MagickMaxBufferExtent; | 
 |   if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0)) | 
 |     quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent); | 
 |   blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob)); | 
 |   if (blob == (unsigned char *) NULL) | 
 |     { | 
 |       ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed", | 
 |         filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   for ( ; ; ) | 
 |   { | 
 |     count=(ssize_t) read(file,blob,quantum); | 
 |     if (count <= 0) | 
 |       { | 
 |         count=0; | 
 |         if (errno != EINTR) | 
 |           break; | 
 |       } | 
 |     length=(size_t) count; | 
 |     count=WriteBlobStream(image,length,blob); | 
 |     if (count != (ssize_t) length) | 
 |       { | 
 |         ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); | 
 |         break; | 
 |       } | 
 |   } | 
 |   file=close(file); | 
 |   if (file == -1) | 
 |     ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); | 
 |   blob=(unsigned char *) RelinquishMagickMemory(blob); | 
 |   return(MagickTrue); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   G e t B l o b E r r o r                                                   % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  GetBlobError() returns MagickTrue if the blob associated with the specified | 
 | %  image encountered an error. | 
 | % | 
 | %  The format of the GetBlobError method is: | 
 | % | 
 | %       MagickBooleanType GetBlobError(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickPrivate MagickBooleanType GetBlobError(const Image *image) | 
 | { | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   return(image->blob->status); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   G e t B l o b F i l e H a n d l e                                         % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  GetBlobFileHandle() returns the file handle associated with the image blob. | 
 | % | 
 | %  The format of the GetBlobFile method is: | 
 | % | 
 | %      FILE *GetBlobFileHandle(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport FILE *GetBlobFileHandle(const Image *image) | 
 | { | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   return(image->blob->file); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   G e t B l o b I n f o                                                     % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  GetBlobInfo() initializes the BlobInfo structure. | 
 | % | 
 | %  The format of the GetBlobInfo method is: | 
 | % | 
 | %      void GetBlobInfo(BlobInfo *blob_info) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o blob_info: Specifies a pointer to a BlobInfo structure. | 
 | % | 
 | */ | 
 | MagickPrivate void GetBlobInfo(BlobInfo *blob_info) | 
 | { | 
 |   assert(blob_info != (BlobInfo *) NULL); | 
 |   (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info)); | 
 |   blob_info->type=UndefinedStream; | 
 |   blob_info->quantum=(size_t) MagickMaxBlobExtent; | 
 |   blob_info->properties.st_mtime=time((time_t *) NULL); | 
 |   blob_info->properties.st_ctime=time((time_t *) NULL); | 
 |   blob_info->debug=IsEventLogging(); | 
 |   blob_info->reference_count=1; | 
 |   blob_info->semaphore=AllocateSemaphoreInfo(); | 
 |   blob_info->signature=MagickSignature; | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %  G e t B l o b P r o p e r t i e s                                          % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  GetBlobProperties() returns information about an image blob. | 
 | % | 
 | %  The format of the GetBlobProperties method is: | 
 | % | 
 | %      const struct stat *GetBlobProperties(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickPrivate const struct stat *GetBlobProperties(const Image *image) | 
 | { | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   return(&image->blob->properties); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  G e t B l o b S i z e                                                      % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  GetBlobSize() returns the current length of the image file or blob; zero is | 
 | %  returned if the size cannot be determined. | 
 | % | 
 | %  The format of the GetBlobSize method is: | 
 | % | 
 | %      MagickSizeType GetBlobSize(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport MagickSizeType GetBlobSize(const Image *image) | 
 | { | 
 |   MagickSizeType | 
 |     extent; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   extent=0; | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |     { | 
 |       extent=image->blob->size; | 
 |       break; | 
 |     } | 
 |     case FileStream: | 
 |     { | 
 |       if (fstat(fileno(image->blob->file),&image->blob->properties) == 0) | 
 |         extent=(MagickSizeType) image->blob->properties.st_size; | 
 |       break; | 
 |     } | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |     { | 
 |       extent=image->blob->size; | 
 |       break; | 
 |     } | 
 |     case ZipStream: | 
 |     case BZipStream: | 
 |     { | 
 |       MagickBooleanType | 
 |         status; | 
 |  | 
 |       status=GetPathAttributes(image->filename,&image->blob->properties); | 
 |       if (status != MagickFalse) | 
 |         extent=(MagickSizeType) image->blob->properties.st_size; | 
 |       break; | 
 |     } | 
 |     case FifoStream: | 
 |       break; | 
 |     case BlobStream: | 
 |     { | 
 |       extent=(MagickSizeType) image->blob->length; | 
 |       break; | 
 |     } | 
 |   } | 
 |   return(extent); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   G e t B l o b S t r e a m D a t a                                         % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  GetBlobStreamData() returns the stream data for the image. | 
 | % | 
 | %  The format of the GetBlobStreamData method is: | 
 | % | 
 | %      unsigned char *GetBlobStreamData(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport unsigned char *GetBlobStreamData(const Image *image) | 
 | { | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   return(image->blob->data); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   G e t B l o b S t r e a m H a n d l e r                                   % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  GetBlobStreamHandler() returns the stream handler for the image. | 
 | % | 
 | %  The format of the GetBlobStreamHandler method is: | 
 | % | 
 | %      StreamHandler GetBlobStreamHandler(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image) | 
 | { | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   return(image->blob->stream); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   I m a g e T o B l o b                                                     % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ImageToBlob() implements direct to memory image formats.  It returns the | 
 | %  image as a formatted blob and its length.  The magick member of the Image | 
 | %  structure determines the format of the returned blob (GIF, JPEG, PNG, | 
 | %  etc.).  This method is the equivalent of WriteImage(), but writes the | 
 | %  formatted "file" to a memory buffer rather than to an actual file. | 
 | % | 
 | %  The format of the ImageToBlob method is: | 
 | % | 
 | %      unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image, | 
 | %        size_t *length,ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image_info: the image info. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o length: This pointer to a size_t integer sets the initial length of the | 
 | %      blob.  On return, it reflects the actual length of the blob. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 | MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info, | 
 |   Image *image,size_t *length,ExceptionInfo *exception) | 
 | { | 
 |   const MagickInfo | 
 |     *magick_info; | 
 |  | 
 |   ImageInfo | 
 |     *blob_info; | 
 |  | 
 |   MagickBooleanType | 
 |     status; | 
 |  | 
 |   unsigned char | 
 |     *blob; | 
 |  | 
 |   assert(image_info != (const ImageInfo *) NULL); | 
 |   assert(image_info->signature == MagickSignature); | 
 |   if (image_info->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", | 
 |       image_info->filename); | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   assert(exception != (ExceptionInfo *) NULL); | 
 |   *length=0; | 
 |   blob=(unsigned char *) NULL; | 
 |   blob_info=CloneImageInfo(image_info); | 
 |   blob_info->adjoin=MagickFalse; | 
 |   (void) SetImageInfo(blob_info,1,exception); | 
 |   if (*blob_info->magick != '\0') | 
 |     (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent); | 
 |   magick_info=GetMagickInfo(image->magick,exception); | 
 |   if (magick_info == (const MagickInfo *) NULL) | 
 |     { | 
 |       (void) ThrowMagickException(exception,GetMagickModule(), | 
 |         MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", | 
 |         image->filename); | 
 |       return(blob); | 
 |     } | 
 |   (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent); | 
 |   if (GetMagickBlobSupport(magick_info) != MagickFalse) | 
 |     { | 
 |       /* | 
 |         Native blob support for this image format. | 
 |       */ | 
 |       blob_info->length=0; | 
 |       blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent, | 
 |         sizeof(unsigned char)); | 
 |       if (blob_info->blob == (void *) NULL) | 
 |         (void) ThrowMagickException(exception,GetMagickModule(), | 
 |           ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); | 
 |       else | 
 |         { | 
 |           (void) CloseBlob(image); | 
 |           image->blob->exempt=MagickTrue; | 
 |           *image->filename='\0'; | 
 |           status=WriteImage(blob_info,image,exception); | 
 |           if ((status != MagickFalse) && (image->blob->length != 0)) | 
 |             { | 
 |               *length=image->blob->length; | 
 |               blob=DetachBlob(image->blob); | 
 |               blob=(unsigned char *) ResizeQuantumMemory(blob,*length, | 
 |                 sizeof(*blob)); | 
 |             } | 
 |         } | 
 |     } | 
 |   else | 
 |     { | 
 |       char | 
 |         unique[MaxTextExtent]; | 
 |  | 
 |       int | 
 |         file; | 
 |  | 
 |       /* | 
 |         Write file to disk in blob image format. | 
 |       */ | 
 |       file=AcquireUniqueFileResource(unique); | 
 |       if (file == -1) | 
 |         { | 
 |           ThrowFileException(exception,BlobError,"UnableToWriteBlob", | 
 |             image_info->filename); | 
 |         } | 
 |       else | 
 |         { | 
 |           blob_info->file=fdopen(file,"wb"); | 
 |           if (blob_info->file != (FILE *) NULL) | 
 |             { | 
 |               (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s", | 
 |                 image->magick,unique); | 
 |               status=WriteImage(blob_info,image,exception); | 
 |               (void) fclose(blob_info->file); | 
 |               if (status != MagickFalse) | 
 |                 blob=FileToBlob(image->filename,~0UL,length,exception); | 
 |             } | 
 |           (void) RelinquishUniqueFileResource(unique); | 
 |         } | 
 |     } | 
 |   blob_info=DestroyImageInfo(blob_info); | 
 |   return(blob); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   I m a g e T o F i l e                                                     % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ImageToFile() writes an image to a file.  It returns MagickFalse if an error | 
 | %  occurs otherwise MagickTrue. | 
 | % | 
 | %  The format of the ImageToFile method is: | 
 | % | 
 | %       MagickBooleanType ImageToFile(Image *image,char *filename, | 
 | %         ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o filename: Write the image to this file. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 | MagickExport MagickBooleanType ImageToFile(Image *image,char *filename, | 
 |   ExceptionInfo *exception) | 
 | { | 
 |   int | 
 |     file; | 
 |  | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   register size_t | 
 |     i; | 
 |  | 
 |   size_t | 
 |     length, | 
 |     quantum; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   struct stat | 
 |     file_info; | 
 |  | 
 |   unsigned char | 
 |     *buffer; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); | 
 |   assert(filename != (const char *) NULL); | 
 |   if (*filename == '\0') | 
 |     file=AcquireUniqueFileResource(filename); | 
 |   else | 
 |     if (LocaleCompare(filename,"-") == 0) | 
 |       file=fileno(stdout); | 
 |     else | 
 |       file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE); | 
 |   if (file == -1) | 
 |     { | 
 |       ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   quantum=(size_t) MagickMaxBufferExtent; | 
 |   if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0)) | 
 |     quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size, | 
 |       MagickMaxBufferExtent); | 
 |   buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer)); | 
 |   if (buffer == (unsigned char *) NULL) | 
 |     { | 
 |       file=close(file)-1; | 
 |       (void) ThrowMagickException(exception,GetMagickModule(), | 
 |         ResourceLimitError,"MemoryAllocationError","`%s'",filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   length=0; | 
 |   p=ReadBlobStream(image,quantum,buffer,&count); | 
 |   for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count)) | 
 |   { | 
 |     length=(size_t) count; | 
 |     for (i=0; i < length; i+=count) | 
 |     { | 
 |       count=write(file,p+i,(size_t) (length-i)); | 
 |       if (count <= 0) | 
 |         { | 
 |           count=0; | 
 |           if (errno != EINTR) | 
 |             break; | 
 |         } | 
 |     } | 
 |     if (i < length) | 
 |       break; | 
 |   } | 
 |   if (LocaleCompare(filename,"-") != 0) | 
 |     file=close(file); | 
 |   buffer=(unsigned char *) RelinquishMagickMemory(buffer); | 
 |   if ((file == -1) || (i < length)) | 
 |     { | 
 |       ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   return(MagickTrue); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   I m a g e s T o B l o b                                                   % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ImagesToBlob() implements direct to memory image formats.  It returns the | 
 | %  image sequence as a blob and its length.  The magick member of the ImageInfo | 
 | %  structure determines the format of the returned blob (GIF, JPEG,  PNG, etc.) | 
 | % | 
 | %  Note, some image formats do not permit multiple images to the same image | 
 | %  stream (e.g. JPEG).  in this instance, just the first image of the | 
 | %  sequence is returned as a blob. | 
 | % | 
 | %  The format of the ImagesToBlob method is: | 
 | % | 
 | %      unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images, | 
 | %        size_t *length,ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image_info: the image info. | 
 | % | 
 | %    o images: the image list. | 
 | % | 
 | %    o length: This pointer to a size_t integer sets the initial length of the | 
 | %      blob.  On return, it reflects the actual length of the blob. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 | MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info, | 
 |   Image *images,size_t *length,ExceptionInfo *exception) | 
 | { | 
 |   const MagickInfo | 
 |     *magick_info; | 
 |  | 
 |   ImageInfo | 
 |     *blob_info; | 
 |  | 
 |   MagickBooleanType | 
 |     status; | 
 |  | 
 |   unsigned char | 
 |     *blob; | 
 |  | 
 |   assert(image_info != (const ImageInfo *) NULL); | 
 |   assert(image_info->signature == MagickSignature); | 
 |   if (image_info->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", | 
 |       image_info->filename); | 
 |   assert(images != (Image *) NULL); | 
 |   assert(images->signature == MagickSignature); | 
 |   assert(exception != (ExceptionInfo *) NULL); | 
 |   *length=0; | 
 |   blob=(unsigned char *) NULL; | 
 |   blob_info=CloneImageInfo(image_info); | 
 |   (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images), | 
 |     exception); | 
 |   if (*blob_info->magick != '\0') | 
 |     (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent); | 
 |   if (blob_info->adjoin == MagickFalse) | 
 |     { | 
 |       blob_info=DestroyImageInfo(blob_info); | 
 |       return(ImageToBlob(image_info,images,length,exception)); | 
 |     } | 
 |   magick_info=GetMagickInfo(images->magick,exception); | 
 |   if (magick_info == (const MagickInfo *) NULL) | 
 |     { | 
 |       (void) ThrowMagickException(exception,GetMagickModule(), | 
 |         MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", | 
 |         images->filename); | 
 |       return(blob); | 
 |     } | 
 |   (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent); | 
 |   if (GetMagickBlobSupport(magick_info) != MagickFalse) | 
 |     { | 
 |       /* | 
 |         Native blob support for this images format. | 
 |       */ | 
 |       blob_info->length=0; | 
 |       blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent, | 
 |         sizeof(unsigned char)); | 
 |       if (blob_info->blob == (void *) NULL) | 
 |         (void) ThrowMagickException(exception,GetMagickModule(), | 
 |           ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename); | 
 |       else | 
 |         { | 
 |           images->blob->exempt=MagickTrue; | 
 |           *images->filename='\0'; | 
 |           status=WriteImages(blob_info,images,images->filename,exception); | 
 |           if ((status != MagickFalse) && (images->blob->length != 0)) | 
 |             { | 
 |               *length=images->blob->length; | 
 |               blob=DetachBlob(images->blob); | 
 |               blob=(unsigned char *) ResizeQuantumMemory(blob,*length, | 
 |                 sizeof(*blob)); | 
 |             } | 
 |         } | 
 |     } | 
 |   else | 
 |     { | 
 |       char | 
 |         filename[MaxTextExtent], | 
 |         unique[MaxTextExtent]; | 
 |  | 
 |       int | 
 |         file; | 
 |  | 
 |       /* | 
 |         Write file to disk in blob images format. | 
 |       */ | 
 |       file=AcquireUniqueFileResource(unique); | 
 |       if (file == -1) | 
 |         { | 
 |           ThrowFileException(exception,FileOpenError,"UnableToWriteBlob", | 
 |             image_info->filename); | 
 |         } | 
 |       else | 
 |         { | 
 |           blob_info->file=fdopen(file,"wb"); | 
 |           if (blob_info->file != (FILE *) NULL) | 
 |             { | 
 |               (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s", | 
 |                 images->magick,unique); | 
 |               status=WriteImages(blob_info,images,filename,exception); | 
 |               (void) fclose(blob_info->file); | 
 |               if (status != MagickFalse) | 
 |                 blob=FileToBlob(images->filename,~0UL,length,exception); | 
 |             } | 
 |           (void) RelinquishUniqueFileResource(unique); | 
 |         } | 
 |     } | 
 |   blob_info=DestroyImageInfo(blob_info); | 
 |   return(blob); | 
 | } | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   I n j e c t I m a g e B l o b                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  InjectImageBlob() injects the image with a copy of itself in the specified | 
 | %  format (e.g. inject JPEG into a PDF image). | 
 | % | 
 | %  The format of the InjectImageBlob method is: | 
 | % | 
 | %      MagickBooleanType InjectImageBlob(const ImageInfo *image_info, | 
 | %        Image *image,Image *inject_image,const char *format, | 
 | %        ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image_info: the image info.. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o inject_image: inject into the image stream. | 
 | % | 
 | %    o format: the image format. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 | MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info, | 
 |   Image *image,Image *inject_image,const char *format,ExceptionInfo *exception) | 
 | { | 
 |   char | 
 |     filename[MaxTextExtent]; | 
 |  | 
 |   FILE | 
 |     *unique_file; | 
 |  | 
 |   Image | 
 |     *byte_image; | 
 |  | 
 |   ImageInfo | 
 |     *write_info; | 
 |  | 
 |   int | 
 |     file; | 
 |  | 
 |   MagickBooleanType | 
 |     status; | 
 |  | 
 |   register ssize_t | 
 |     i; | 
 |  | 
 |   size_t | 
 |     quantum; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   struct stat | 
 |     file_info; | 
 |  | 
 |   unsigned char | 
 |     *buffer; | 
 |  | 
 |   /* | 
 |     Write inject image to a temporary file. | 
 |   */ | 
 |   assert(image_info != (ImageInfo *) NULL); | 
 |   assert(image_info->signature == MagickSignature); | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(inject_image != (Image *) NULL); | 
 |   assert(inject_image->signature == MagickSignature); | 
 |   assert(exception != (ExceptionInfo *) NULL); | 
 |   unique_file=(FILE *) NULL; | 
 |   file=AcquireUniqueFileResource(filename); | 
 |   if (file != -1) | 
 |     unique_file=fdopen(file,"wb"); | 
 |   if ((file == -1) || (unique_file == (FILE *) NULL)) | 
 |     { | 
 |       (void) CopyMagickString(image->filename,filename,MaxTextExtent); | 
 |       ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile", | 
 |         image->filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   byte_image=CloneImage(inject_image,0,0,MagickFalse,exception); | 
 |   if (byte_image == (Image *) NULL) | 
 |     { | 
 |       (void) fclose(unique_file); | 
 |       (void) RelinquishUniqueFileResource(filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format, | 
 |     filename); | 
 |   DestroyBlob(byte_image); | 
 |   byte_image->blob=CloneBlobInfo((BlobInfo *) NULL); | 
 |   write_info=CloneImageInfo(image_info); | 
 |   SetImageInfoFile(write_info,unique_file); | 
 |   status=WriteImage(write_info,byte_image,exception); | 
 |   write_info=DestroyImageInfo(write_info); | 
 |   byte_image=DestroyImage(byte_image); | 
 |   (void) fclose(unique_file); | 
 |   if (status == MagickFalse) | 
 |     { | 
 |       (void) RelinquishUniqueFileResource(filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   /* | 
 |     Inject into image stream. | 
 |   */ | 
 |   file=open_utf8(filename,O_RDONLY | O_BINARY,0); | 
 |   if (file == -1) | 
 |     { | 
 |       (void) RelinquishUniqueFileResource(filename); | 
 |       ThrowFileException(exception,FileOpenError,"UnableToOpenFile", | 
 |         image_info->filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   quantum=(size_t) MagickMaxBufferExtent; | 
 |   if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0)) | 
 |     quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent); | 
 |   buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer)); | 
 |   if (buffer == (unsigned char *) NULL) | 
 |     { | 
 |       (void) RelinquishUniqueFileResource(filename); | 
 |       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", | 
 |         image->filename); | 
 |     } | 
 |   for (i=0; ; i+=count) | 
 |   { | 
 |     count=(ssize_t) read(file,buffer,quantum); | 
 |     if (count <= 0) | 
 |       { | 
 |         count=0; | 
 |         if (errno != EINTR) | 
 |           break; | 
 |       } | 
 |     status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue : | 
 |       MagickFalse; | 
 |   } | 
 |   file=close(file); | 
 |   if (file == -1) | 
 |     ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename); | 
 |   (void) RelinquishUniqueFileResource(filename); | 
 |   buffer=(unsigned char *) RelinquishMagickMemory(buffer); | 
 |   return(status); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   I s B l o b E x e m p t                                                   % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  IsBlobExempt() returns true if the blob is exempt. | 
 | % | 
 | %  The format of the IsBlobExempt method is: | 
 | % | 
 | %       MagickBooleanType IsBlobExempt(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickPrivate MagickBooleanType IsBlobExempt(const Image *image) | 
 | { | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   return(image->blob->exempt); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   I s B l o b S e e k a b l e                                               % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  IsBlobSeekable() returns true if the blob is seekable. | 
 | % | 
 | %  The format of the IsBlobSeekable method is: | 
 | % | 
 | %       MagickBooleanType IsBlobSeekable(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image) | 
 | { | 
 |   MagickBooleanType | 
 |     seekable; | 
 |  | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   seekable=(image->blob->type == FileStream) || | 
 |     (image->blob->type == BlobStream) ? MagickTrue : MagickFalse; | 
 |   return(seekable); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   I s B l o b T e m p o r a r y                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  IsBlobTemporary() returns true if the blob is temporary. | 
 | % | 
 | %  The format of the IsBlobTemporary method is: | 
 | % | 
 | %       MagickBooleanType IsBlobTemporary(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image) | 
 | { | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   return(image->blob->temporary); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  M a p B l o b                                                              % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  MapBlob() creates a mapping from a file to a binary large object. | 
 | % | 
 | %  The format of the MapBlob method is: | 
 | % | 
 | %      unsigned char *MapBlob(int file,const MapMode mode, | 
 | %        const MagickOffsetType offset,const size_t length) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o file: map this file descriptor. | 
 | % | 
 | %    o mode: ReadMode, WriteMode, or IOMode. | 
 | % | 
 | %    o offset: starting at this offset within the file. | 
 | % | 
 | %    o length: the length of the mapping is returned in this pointer. | 
 | % | 
 | */ | 
 | MagickExport unsigned char *MapBlob(int file,const MapMode mode, | 
 |   const MagickOffsetType offset,const size_t length) | 
 | { | 
 | #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) | 
 |   int | 
 |     flags, | 
 |     protection; | 
 |  | 
 |   unsigned char | 
 |     *map; | 
 |  | 
 |   /* | 
 |     Map file. | 
 |   */ | 
 |   flags=0; | 
 |   if (file == -1) | 
 | #if defined(MAP_ANONYMOUS) | 
 |     flags|=MAP_ANONYMOUS; | 
 | #else | 
 |     return((unsigned char *) NULL); | 
 | #endif | 
 |   switch (mode) | 
 |   { | 
 |     case ReadMode: | 
 |     default: | 
 |     { | 
 |       protection=PROT_READ; | 
 |       flags|=MAP_PRIVATE; | 
 |       map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file, | 
 |         (off_t) offset); | 
 |       break; | 
 |     } | 
 |     case WriteMode: | 
 |     { | 
 |       protection=PROT_WRITE; | 
 |       flags|=MAP_SHARED; | 
 |       map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file, | 
 |         (off_t) offset); | 
 | #if defined(MAGICKCORE_HAVE_POSIX_MADVISE) | 
 |       (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL | | 
 |         POSIX_MADV_WILLNEED); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case IOMode: | 
 |     { | 
 |       protection=PROT_READ | PROT_WRITE; | 
 |       flags|=MAP_SHARED; | 
 |       map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file, | 
 |         (off_t) offset); | 
 |       break; | 
 |     } | 
 |   } | 
 |   if (map == (unsigned char *) MAP_FAILED) | 
 |     return((unsigned char *) NULL); | 
 |   return(map); | 
 | #else | 
 |   (void) file; | 
 |   (void) mode; | 
 |   (void) offset; | 
 |   (void) length; | 
 |   return((unsigned char *) NULL); | 
 | #endif | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  M S B O r d e r L o n g                                                    % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  MSBOrderLong() converts a least-significant byte first buffer of integers to | 
 | %  most-significant byte first. | 
 | % | 
 | %  The format of the MSBOrderLong method is: | 
 | % | 
 | %      void MSBOrderLong(unsigned char *buffer,const size_t length) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %   o  buffer:  Specifies a pointer to a buffer of integers. | 
 | % | 
 | %   o  length:  Specifies the length of the buffer. | 
 | % | 
 | */ | 
 | MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length) | 
 | { | 
 |   int | 
 |     c; | 
 |  | 
 |   register unsigned char | 
 |     *p, | 
 |     *q; | 
 |  | 
 |   assert(buffer != (unsigned char *) NULL); | 
 |   q=buffer+length; | 
 |   while (buffer < q) | 
 |   { | 
 |     p=buffer+3; | 
 |     c=(int) (*p); | 
 |     *p=(*buffer); | 
 |     *buffer++=(unsigned char) c; | 
 |     p=buffer+1; | 
 |     c=(int) (*p); | 
 |     *p=(*buffer); | 
 |     *buffer++=(unsigned char) c; | 
 |     buffer+=2; | 
 |   } | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  M S B O r d e r S h o r t                                                  % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  MSBOrderShort() converts a least-significant byte first buffer of integers | 
 | %  to most-significant byte first. | 
 | % | 
 | %  The format of the MSBOrderShort method is: | 
 | % | 
 | %      void MSBOrderShort(unsigned char *p,const size_t length) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %   o  p:  Specifies a pointer to a buffer of integers. | 
 | % | 
 | %   o  length:  Specifies the length of the buffer. | 
 | % | 
 | */ | 
 | MagickExport void MSBOrderShort(unsigned char *p,const size_t length) | 
 | { | 
 |   int | 
 |     c; | 
 |  | 
 |   register unsigned char | 
 |     *q; | 
 |  | 
 |   assert(p != (unsigned char *) NULL); | 
 |   q=p+length; | 
 |   while (p < q) | 
 |   { | 
 |     c=(int) (*p); | 
 |     *p=(*(p+1)); | 
 |     p++; | 
 |     *p++=(unsigned char) c; | 
 |   } | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   O p e n B l o b                                                           % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  OpenBlob() opens a file associated with the image.  A file name of '-' sets | 
 | %  the file to stdin for type 'r' and stdout for type 'w'.  If the filename | 
 | %  suffix is '.gz' or '.Z', the image is decompressed for type 'r' and | 
 | %  compressed for type 'w'.  If the filename prefix is '|', it is piped to or | 
 | %  from a system command. | 
 | % | 
 | %  The format of the OpenBlob method is: | 
 | % | 
 | %       MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image, | 
 | %        const BlobMode mode,ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image_info: the image info. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o mode: the mode for opening the file. | 
 | % | 
 | */ | 
 | MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info, | 
 |   Image *image,const BlobMode mode,ExceptionInfo *exception) | 
 | { | 
 |   char | 
 |     extension[MaxTextExtent], | 
 |     filename[MaxTextExtent]; | 
 |  | 
 |   const char | 
 |     *type; | 
 |  | 
 |   MagickBooleanType | 
 |     status; | 
 |  | 
 |   PolicyRights | 
 |     rights; | 
 |  | 
 |   assert(image_info != (ImageInfo *) NULL); | 
 |   assert(image_info->signature == MagickSignature); | 
 |   if (image_info->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", | 
 |       image_info->filename); | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image_info->blob != (void *) NULL) | 
 |     { | 
 |       if (image_info->stream != (StreamHandler) NULL) | 
 |         image->blob->stream=(StreamHandler) image_info->stream; | 
 |       AttachBlob(image->blob,image_info->blob,image_info->length); | 
 |       return(MagickTrue); | 
 |     } | 
 |   (void) DetachBlob(image->blob); | 
 |   switch (mode) | 
 |   { | 
 |     default: type="r"; break; | 
 |     case ReadBlobMode: type="r"; break; | 
 |     case ReadBinaryBlobMode: type="rb"; break; | 
 |     case WriteBlobMode: type="w"; break; | 
 |     case WriteBinaryBlobMode: type="w+b"; break; | 
 |     case AppendBlobMode: type="a"; break; | 
 |     case AppendBinaryBlobMode: type="a+b"; break; | 
 |   } | 
 |   if (*type != 'r') | 
 |     image->blob->synchronize=image_info->synchronize; | 
 |   if (image_info->stream != (StreamHandler) NULL) | 
 |     { | 
 |       image->blob->stream=(StreamHandler) image_info->stream; | 
 |       if (*type == 'w') | 
 |         { | 
 |           image->blob->type=FifoStream; | 
 |           return(MagickTrue); | 
 |         } | 
 |     } | 
 |   /* | 
 |     Open image file. | 
 |   */ | 
 |   *filename='\0'; | 
 |   (void) CopyMagickString(filename,image->filename,MaxTextExtent); | 
 |   rights=ReadPolicyRights; | 
 |   if (*type == 'w') | 
 |     rights=WritePolicyRights; | 
 |   if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse) | 
 |     { | 
 |       errno=EPERM; | 
 |       (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, | 
 |         "NotAuthorized","`%s'",filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   if ((LocaleCompare(filename,"-") == 0) || | 
 |       ((*filename == '\0') && (image_info->file == (FILE *) NULL))) | 
 |     { | 
 |       image->blob->file=(*type == 'r') ? stdin : stdout; | 
 | #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) | 
 |       if (strchr(type,'b') != (char *) NULL) | 
 |         setmode(_fileno(image->blob->file),_O_BINARY); | 
 | #endif | 
 |       image->blob->type=StandardStream; | 
 |       image->blob->exempt=MagickTrue; | 
 |       return(MagickTrue); | 
 |     } | 
 |   if (LocaleNCompare(filename,"fd:",3) == 0) | 
 |     { | 
 |       char | 
 |         mode[MaxTextExtent]; | 
 |  | 
 |       *mode=(*type); | 
 |       mode[1]='\0'; | 
 |       image->blob->file=fdopen(StringToLong(filename+3),mode); | 
 | #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) | 
 |       if (strchr(type,'b') != (char *) NULL) | 
 |         setmode(_fileno(image->blob->file),_O_BINARY); | 
 | #endif | 
 |       image->blob->type=StandardStream; | 
 |       image->blob->exempt=MagickTrue; | 
 |       return(MagickTrue); | 
 |     } | 
 | #if defined(MAGICKCORE_HAVE_POPEN) | 
 |   if (*filename == '|') | 
 |     { | 
 |       char | 
 |         mode[MaxTextExtent]; | 
 |  | 
 |       /* | 
 |         Pipe image to or from a system command. | 
 |       */ | 
 | #if defined(SIGPIPE) | 
 |       if (*type == 'w') | 
 |         (void) signal(SIGPIPE,SIG_IGN); | 
 | #endif | 
 |       *mode=(*type); | 
 |       mode[1]='\0'; | 
 |       image->blob->file=(FILE *) popen_utf8(filename+1,mode); | 
 |       if (image->blob->file == (FILE *) NULL) | 
 |         { | 
 |           ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename); | 
 |           return(MagickFalse); | 
 |         } | 
 |       image->blob->type=PipeStream; | 
 |       image->blob->exempt=MagickTrue; | 
 |       return(MagickTrue); | 
 |     } | 
 | #endif | 
 |   status=GetPathAttributes(filename,&image->blob->properties); | 
 | #if defined(S_ISFIFO) | 
 |   if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode)) | 
 |     { | 
 |       image->blob->file=(FILE *) fopen_utf8(filename,type); | 
 |       if (image->blob->file == (FILE *) NULL) | 
 |         { | 
 |           ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename); | 
 |           return(MagickFalse); | 
 |         } | 
 |       image->blob->type=FileStream; | 
 |       image->blob->exempt=MagickTrue; | 
 |       return(MagickTrue); | 
 |     } | 
 | #endif | 
 |   GetPathComponent(image->filename,ExtensionPath,extension); | 
 |   if (*type == 'w') | 
 |     { | 
 |       (void) CopyMagickString(filename,image->filename,MaxTextExtent); | 
 |       if ((image_info->adjoin == MagickFalse) || | 
 |           (strchr(filename,'%') != (char *) NULL)) | 
 |         { | 
 |           /* | 
 |             Form filename for multi-part images. | 
 |           */ | 
 |           (void) InterpretImageFilename(image_info,image,image->filename,(int) | 
 |             image->scene,filename,exception); | 
 |           if ((LocaleCompare(filename,image->filename) == 0) && | 
 |               ((GetPreviousImageInList(image) != (Image *) NULL) || | 
 |                (GetNextImageInList(image) != (Image *) NULL))) | 
 |             { | 
 |               char | 
 |                 path[MaxTextExtent]; | 
 |  | 
 |               GetPathComponent(image->filename,RootPath,path); | 
 |               if (*extension == '\0') | 
 |                 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g", | 
 |                   path,(double) image->scene); | 
 |               else | 
 |                 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s", | 
 |                   path,(double) image->scene,extension); | 
 |             } | 
 |           (void) CopyMagickString(image->filename,filename,MaxTextExtent); | 
 | #if defined(macintosh) | 
 |           SetApplicationType(filename,image_info->magick,'8BIM'); | 
 | #endif | 
 |         } | 
 |     } | 
 |   if (image_info->file != (FILE *) NULL) | 
 |     { | 
 |       image->blob->file=image_info->file; | 
 |       image->blob->type=FileStream; | 
 |       image->blob->exempt=MagickTrue; | 
 |     } | 
 |   else | 
 |     if (*type == 'r') | 
 |       { | 
 |         image->blob->file=(FILE *) fopen_utf8(filename,type); | 
 |         if (image->blob->file != (FILE *) NULL) | 
 |           { | 
 |             size_t | 
 |               count; | 
 |  | 
 |             unsigned char | 
 |               magick[3]; | 
 |  | 
 |             image->blob->type=FileStream; | 
 | #if defined(MAGICKCORE_HAVE_SETVBUF) | 
 |             (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384); | 
 | #endif | 
 |             (void) ResetMagickMemory(magick,0,sizeof(magick)); | 
 |             count=fread(magick,1,sizeof(magick),image->blob->file); | 
 |             (void) rewind(image->blob->file); | 
 |             (void) LogMagickEvent(BlobEvent,GetMagickModule(), | 
 |                "  read %.20g magic header bytes",(double) count); | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |             if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) && | 
 |                 ((int) magick[2] == 0x08)) | 
 |               { | 
 |                 (void) fclose(image->blob->file); | 
 |                 image->blob->file=(FILE *) gzopen(filename,type); | 
 |                 if (image->blob->file != (FILE *) NULL) | 
 |                   image->blob->type=ZipStream; | 
 |                } | 
 | #endif | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 |             if (strncmp((char *) magick,"BZh",3) == 0) | 
 |               { | 
 |                 (void) fclose(image->blob->file); | 
 |                 image->blob->file=(FILE *) BZ2_bzopen(filename,type); | 
 |                 if (image->blob->file != (FILE *) NULL) | 
 |                   image->blob->type=BZipStream; | 
 |               } | 
 | #endif | 
 |             if (image->blob->type == FileStream) | 
 |               { | 
 |                 const MagickInfo | 
 |                   *magick_info; | 
 |  | 
 |                 ExceptionInfo | 
 |                   *sans_exception; | 
 |  | 
 |                 struct stat | 
 |                   *properties; | 
 |  | 
 |                 sans_exception=AcquireExceptionInfo(); | 
 |                 magick_info=GetMagickInfo(image_info->magick,sans_exception); | 
 |                 sans_exception=DestroyExceptionInfo(sans_exception); | 
 |                 properties=(&image->blob->properties); | 
 |                 if ((magick_info != (const MagickInfo *) NULL) && | 
 |                     (GetMagickBlobSupport(magick_info) != MagickFalse) && | 
 |                     (properties->st_size <= MagickMaxBufferExtent)) | 
 |                   { | 
 |                     size_t | 
 |                       length; | 
 |  | 
 |                     void | 
 |                       *blob; | 
 |  | 
 |                     length=(size_t) properties->st_size; | 
 |                     blob=MapBlob(fileno(image->blob->file),ReadMode,0,length); | 
 |                     if (blob != (void *) NULL) | 
 |                       { | 
 |                         /* | 
 |                           Format supports blobs-- use memory-mapped I/O. | 
 |                         */ | 
 |                         if (image_info->file != (FILE *) NULL) | 
 |                           image->blob->exempt=MagickFalse; | 
 |                         else | 
 |                           { | 
 |                             (void) fclose(image->blob->file); | 
 |                             image->blob->file=(FILE *) NULL; | 
 |                           } | 
 |                         AttachBlob(image->blob,blob,length); | 
 |                         image->blob->mapped=MagickTrue; | 
 |                       } | 
 |                   } | 
 |               } | 
 |           } | 
 |         } | 
 |       else | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |         if ((LocaleCompare(extension,"Z") == 0) || | 
 |             (LocaleCompare(extension,"gz") == 0) || | 
 |             (LocaleCompare(extension,"wmz") == 0) || | 
 |             (LocaleCompare(extension,"svgz") == 0)) | 
 |           { | 
 |             if (mode == WriteBinaryBlobMode) | 
 |               type="wb"; | 
 |             image->blob->file=(FILE *) gzopen(filename,type); | 
 |             if (image->blob->file != (FILE *) NULL) | 
 |               image->blob->type=ZipStream; | 
 |           } | 
 |         else | 
 | #endif | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 |           if (LocaleCompare(extension,".bz2") == 0) | 
 |             { | 
 |               image->blob->file=(FILE *) BZ2_bzopen(filename,type); | 
 |               if (image->blob->file != (FILE *) NULL) | 
 |                 image->blob->type=BZipStream; | 
 |             } | 
 |           else | 
 | #endif | 
 |             { | 
 |               image->blob->file=(FILE *) fopen_utf8(filename,type); | 
 |               if (image->blob->file != (FILE *) NULL) | 
 |                 { | 
 |                   image->blob->type=FileStream; | 
 | #if defined(MAGICKCORE_HAVE_SETVBUF) | 
 |                   (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF, | 
 |                     16384); | 
 | #endif | 
 |                 } | 
 |        } | 
 |   image->blob->status=MagickFalse; | 
 |   if (image->blob->type != UndefinedStream) | 
 |     image->blob->size=GetBlobSize(image); | 
 |   else | 
 |     { | 
 |       ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename); | 
 |       return(MagickFalse); | 
 |     } | 
 |   return(MagickTrue); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   P i n g B l o b                                                           % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  PingBlob() returns all the attributes of an image or image sequence except | 
 | %  for the pixels.  It is much faster and consumes far less memory than | 
 | %  BlobToImage().  On failure, a NULL image is returned and exception | 
 | %  describes the reason for the failure. | 
 | % | 
 | %  The format of the PingBlob method is: | 
 | % | 
 | %      Image *PingBlob(const ImageInfo *image_info,const void *blob, | 
 | %        const size_t length,ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image_info: the image info. | 
 | % | 
 | %    o blob: the address of a character stream in one of the image formats | 
 | %      understood by ImageMagick. | 
 | % | 
 | %    o length: This size_t integer reflects the length in bytes of the blob. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 |  | 
 | #if defined(__cplusplus) || defined(c_plusplus) | 
 | extern "C" { | 
 | #endif | 
 |  | 
 | static size_t PingStream(const Image *magick_unused(image), | 
 |   const void *magick_unused(pixels),const size_t columns) | 
 | { | 
 |   return(columns); | 
 | } | 
 |  | 
 | #if defined(__cplusplus) || defined(c_plusplus) | 
 | } | 
 | #endif | 
 |  | 
 | MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob, | 
 |   const size_t length,ExceptionInfo *exception) | 
 | { | 
 |   Image | 
 |     *image; | 
 |  | 
 |   ImageInfo | 
 |     *ping_info; | 
 |  | 
 |   assert(image_info != (ImageInfo *) NULL); | 
 |   assert(image_info->signature == MagickSignature); | 
 |   if (image_info->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", | 
 |       image_info->filename); | 
 |   assert(exception != (ExceptionInfo *) NULL); | 
 |   if ((blob == (const void *) NULL) || (length == 0)) | 
 |     { | 
 |       (void) ThrowMagickException(exception,GetMagickModule(),BlobError, | 
 |         "UnrecognizedImageFormat","`%s'",image_info->magick); | 
 |       return((Image *) NULL); | 
 |     } | 
 |   ping_info=CloneImageInfo(image_info); | 
 |   ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char)); | 
 |   if (ping_info->blob == (const void *) NULL) | 
 |     { | 
 |       (void) ThrowMagickException(exception,GetMagickModule(), | 
 |         ResourceLimitFatalError,"MemoryAllocationFailed","`%s'",""); | 
 |       return((Image *) NULL); | 
 |     } | 
 |   (void) memcpy(ping_info->blob,blob,length); | 
 |   ping_info->length=length; | 
 |   ping_info->ping=MagickTrue; | 
 |   image=ReadStream(ping_info,&PingStream,exception); | 
 |   ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob); | 
 |   ping_info=DestroyImageInfo(ping_info); | 
 |   return(image); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b                                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlob() reads data from the blob or image file and returns it.  It | 
 | %  returns the number of bytes read. | 
 | % | 
 | %  The format of the ReadBlob method is: | 
 | % | 
 | %      ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o length:  Specifies an integer representing the number of bytes to read | 
 | %      from the file. | 
 | % | 
 | %    o data:  Specifies an area to place the information requested from the | 
 | %      file. | 
 | % | 
 | */ | 
 | MagickExport ssize_t ReadBlob(Image *image,const size_t length, | 
 |   unsigned char *data) | 
 | { | 
 |   int | 
 |     c; | 
 |  | 
 |   register unsigned char | 
 |     *q; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   if (length == 0) | 
 |     return(0); | 
 |   assert(data != (void *) NULL); | 
 |   count=0; | 
 |   q=data; | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |     { | 
 |       switch (length) | 
 |       { | 
 |         default: | 
 |         { | 
 |           count=(ssize_t) fread(q,1,length,image->blob->file); | 
 |           break; | 
 |         } | 
 |         case 2: | 
 |         { | 
 |           c=getc(image->blob->file); | 
 |           if (c == EOF) | 
 |             break; | 
 |           *q++=(unsigned char) c; | 
 |           count++; | 
 |         } | 
 |         case 1: | 
 |         { | 
 |           c=getc(image->blob->file); | 
 |           if (c == EOF) | 
 |             break; | 
 |           *q++=(unsigned char) c; | 
 |           count++; | 
 |         } | 
 |         case 0: | 
 |           break; | 
 |       } | 
 |       break; | 
 |     } | 
 |     case ZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |       switch (length) | 
 |       { | 
 |         default: | 
 |         { | 
 |           count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length); | 
 |           break; | 
 |         } | 
 |         case 2: | 
 |         { | 
 |           c=gzgetc(image->blob->file); | 
 |           if (c == EOF) | 
 |             break; | 
 |           *q++=(unsigned char) c; | 
 |           count++; | 
 |         } | 
 |         case 1: | 
 |         { | 
 |           c=gzgetc(image->blob->file); | 
 |           if (c == EOF) | 
 |             break; | 
 |           *q++=(unsigned char) c; | 
 |           count++; | 
 |         } | 
 |         case 0: | 
 |           break; | 
 |       } | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case BZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 |       count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case FifoStream: | 
 |       break; | 
 |     case BlobStream: | 
 |     { | 
 |       register const unsigned char | 
 |         *p; | 
 |  | 
 |       if (image->blob->offset >= (MagickOffsetType) image->blob->length) | 
 |         { | 
 |           image->blob->eof=MagickTrue; | 
 |           break; | 
 |         } | 
 |       p=image->blob->data+image->blob->offset; | 
 |       count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset); | 
 |       image->blob->offset+=count; | 
 |       if (count != (ssize_t) length) | 
 |         image->blob->eof=MagickTrue; | 
 |       (void) memcpy(q,p,(size_t) count); | 
 |       break; | 
 |     } | 
 |   } | 
 |   return(count); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b B y t e                                                    % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobByte() reads a single byte from the image file and returns it. | 
 | % | 
 | %  The format of the ReadBlobByte method is: | 
 | % | 
 | %      int ReadBlobByte(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport int ReadBlobByte(Image *image) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[1]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   p=ReadBlobStream(image,1,buffer,&count); | 
 |   if (count != 1) | 
 |     return(EOF); | 
 |   return((int) (*p)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b D o u b l e                                                % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order | 
 | %  specified by the endian member of the image structure. | 
 | % | 
 | %  The format of the ReadBlobDouble method is: | 
 | % | 
 | %      double ReadBlobDouble(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport double ReadBlobDouble(Image *image) | 
 | { | 
 |   union | 
 |   { | 
 |     MagickSizeType | 
 |       unsigned_value; | 
 |  | 
 |     double | 
 |       double_value; | 
 |   } quantum; | 
 |  | 
 |   quantum.double_value=0.0; | 
 |   quantum.unsigned_value=ReadBlobLongLong(image); | 
 |   return(quantum.double_value); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b F l o a t                                                  % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order | 
 | %  specified by the endian member of the image structure. | 
 | % | 
 | %  The format of the ReadBlobFloat method is: | 
 | % | 
 | %      float ReadBlobFloat(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport float ReadBlobFloat(Image *image) | 
 | { | 
 |   union | 
 |   { | 
 |     unsigned int | 
 |       unsigned_value; | 
 |  | 
 |     float | 
 |       float_value; | 
 |   } quantum; | 
 |  | 
 |   quantum.float_value=0.0; | 
 |   quantum.unsigned_value=ReadBlobLong(image); | 
 |   return(quantum.float_value); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b L o n g                                                    % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order | 
 | %  specified by the endian member of the image structure. | 
 | % | 
 | %  The format of the ReadBlobLong method is: | 
 | % | 
 | %      unsigned int ReadBlobLong(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport unsigned int ReadBlobLong(Image *image) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[4]; | 
 |  | 
 |   unsigned int | 
 |     value; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   *buffer='\0'; | 
 |   p=ReadBlobStream(image,4,buffer,&count); | 
 |   if (count != 4) | 
 |     return(0UL); | 
 |   if (image->endian == LSBEndian) | 
 |     { | 
 |       value=(unsigned int) (*p++); | 
 |       value|=((unsigned int) (*p++)) << 8; | 
 |       value|=((unsigned int) (*p++)) << 16; | 
 |       value|=((unsigned int) (*p++)) << 24; | 
 |       return(value); | 
 |     } | 
 |   value=((unsigned int) (*p++)) << 24; | 
 |   value|=((unsigned int) (*p++)) << 16; | 
 |   value|=((unsigned int) (*p++)) << 8; | 
 |   value|=((unsigned int) (*p++)); | 
 |   return(value); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b L o n g L o n g                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobLongLong() reads a long long value as a 64-bit quantity in the | 
 | %  byte-order specified by the endian member of the image structure. | 
 | % | 
 | %  The format of the ReadBlobLongLong method is: | 
 | % | 
 | %      MagickSizeType ReadBlobLongLong(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport MagickSizeType ReadBlobLongLong(Image *image) | 
 | { | 
 |   MagickSizeType | 
 |     value; | 
 |  | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[8]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   *buffer='\0'; | 
 |   p=ReadBlobStream(image,8,buffer,&count); | 
 |   if (count != 8) | 
 |     return(MagickULLConstant(0)); | 
 |   if (image->endian == LSBEndian) | 
 |     { | 
 |       value=(MagickSizeType) (*p++); | 
 |       value|=((MagickSizeType) (*p++)) << 8; | 
 |       value|=((MagickSizeType) (*p++)) << 16; | 
 |       value|=((MagickSizeType) (*p++)) << 24; | 
 |       value|=((MagickSizeType) (*p++)) << 32; | 
 |       value|=((MagickSizeType) (*p++)) << 40; | 
 |       value|=((MagickSizeType) (*p++)) << 48; | 
 |       value|=((MagickSizeType) (*p++)) << 56; | 
 |       return(value & MagickULLConstant(0xffffffffffffffff)); | 
 |     } | 
 |   value=((MagickSizeType) (*p++)) << 56; | 
 |   value|=((MagickSizeType) (*p++)) << 48; | 
 |   value|=((MagickSizeType) (*p++)) << 40; | 
 |   value|=((MagickSizeType) (*p++)) << 32; | 
 |   value|=((MagickSizeType) (*p++)) << 24; | 
 |   value|=((MagickSizeType) (*p++)) << 16; | 
 |   value|=((MagickSizeType) (*p++)) << 8; | 
 |   value|=((MagickSizeType) (*p++)); | 
 |   return(value & MagickULLConstant(0xffffffffffffffff)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b S h o r t                                                  % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order | 
 | %  specified by the endian member of the image structure. | 
 | % | 
 | %  The format of the ReadBlobShort method is: | 
 | % | 
 | %      unsigned short ReadBlobShort(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport unsigned short ReadBlobShort(Image *image) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   register unsigned int | 
 |     value; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[2]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   *buffer='\0'; | 
 |   p=ReadBlobStream(image,2,buffer,&count); | 
 |   if (count != 2) | 
 |     return((unsigned short) 0U); | 
 |   if (image->endian == LSBEndian) | 
 |     { | 
 |       value=(unsigned int) (*p++); | 
 |       value|=((unsigned int) (*p++)) << 8; | 
 |       return((unsigned short) (value & 0xffff)); | 
 |     } | 
 |   value=(unsigned int) ((*p++) << 8); | 
 |   value|=(unsigned int) (*p++); | 
 |   return((unsigned short) (value & 0xffff)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b L S B L o n g                                              % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in | 
 | %  least-significant byte first order. | 
 | % | 
 | %  The format of the ReadBlobLSBLong method is: | 
 | % | 
 | %      unsigned int ReadBlobLSBLong(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport unsigned int ReadBlobLSBLong(Image *image) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   register unsigned int | 
 |     value; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[4]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   *buffer='\0'; | 
 |   p=ReadBlobStream(image,4,buffer,&count); | 
 |   if (count != 4) | 
 |     return(0U); | 
 |   value=(unsigned int) (*p++); | 
 |   value|=((unsigned int) (*p++)) << 8; | 
 |   value|=((unsigned int) (*p++)) << 16; | 
 |   value|=((unsigned int) (*p++)) << 24; | 
 |   return(value); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b L S B S h o r t                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobLSBShort() reads a short value as a 16-bit quantity in | 
 | %  least-significant byte first order. | 
 | % | 
 | %  The format of the ReadBlobLSBShort method is: | 
 | % | 
 | %      unsigned short ReadBlobLSBShort(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport unsigned short ReadBlobLSBShort(Image *image) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   register unsigned int | 
 |     value; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[2]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   *buffer='\0'; | 
 |   p=ReadBlobStream(image,2,buffer,&count); | 
 |   if (count != 2) | 
 |     return((unsigned short) 0U); | 
 |   value=(unsigned int) (*p++); | 
 |   value|=((unsigned int) ((*p++)) << 8); | 
 |   return((unsigned short) (value & 0xffff)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b M S B L o n g                                              % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in | 
 | %  most-significant byte first order. | 
 | % | 
 | %  The format of the ReadBlobMSBLong method is: | 
 | % | 
 | %      unsigned int ReadBlobMSBLong(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport unsigned int ReadBlobMSBLong(Image *image) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   register unsigned int | 
 |     value; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[4]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   *buffer='\0'; | 
 |   p=ReadBlobStream(image,4,buffer,&count); | 
 |   if (count != 4) | 
 |     return(0UL); | 
 |   value=((unsigned int) (*p++) << 24); | 
 |   value|=((unsigned int) (*p++) << 16); | 
 |   value|=((unsigned int) (*p++) << 8); | 
 |   value|=(unsigned int) (*p++); | 
 |   return(value); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b M S B L o n g L o n g                                      % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in | 
 | %  most-significant byte first order. | 
 | % | 
 | %  The format of the ReadBlobMSBLongLong method is: | 
 | % | 
 | %      unsigned int ReadBlobMSBLongLong(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   register MagickSizeType | 
 |     value; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[8]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   *buffer='\0'; | 
 |   p=ReadBlobStream(image,8,buffer,&count); | 
 |   if (count != 8) | 
 |     return(MagickULLConstant(0)); | 
 |   value=((MagickSizeType) (*p++)) << 56; | 
 |   value|=((MagickSizeType) (*p++)) << 48; | 
 |   value|=((MagickSizeType) (*p++)) << 40; | 
 |   value|=((MagickSizeType) (*p++)) << 32; | 
 |   value|=((MagickSizeType) (*p++)) << 24; | 
 |   value|=((MagickSizeType) (*p++)) << 16; | 
 |   value|=((MagickSizeType) (*p++)) << 8; | 
 |   value|=((MagickSizeType) (*p++)); | 
 |   return(value & MagickULLConstant(0xffffffffffffffff)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  R e a d B l o b M S B S h o r t                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobMSBShort() reads a short value as a 16-bit quantity in | 
 | %  most-significant byte first order. | 
 | % | 
 | %  The format of the ReadBlobMSBShort method is: | 
 | % | 
 | %      unsigned short ReadBlobMSBShort(Image *image) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport unsigned short ReadBlobMSBShort(Image *image) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   register unsigned int | 
 |     value; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[2]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   *buffer='\0'; | 
 |   p=ReadBlobStream(image,2,buffer,&count); | 
 |   if (count != 2) | 
 |     return((unsigned short) 0U); | 
 |   value=(unsigned int) ((*p++) << 8); | 
 |   value|=(unsigned int) (*p++); | 
 |   return((unsigned short) (value & 0xffff)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   R e a d B l o b S t r i n g                                               % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadBlobString() reads characters from a blob or file until a newline | 
 | %  character is read or an end-of-file condition is encountered. | 
 | % | 
 | %  The format of the ReadBlobString method is: | 
 | % | 
 | %      char *ReadBlobString(Image *image,char *string) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o string: the address of a character buffer. | 
 | % | 
 | */ | 
 | MagickExport char *ReadBlobString(Image *image,char *string) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   register ssize_t | 
 |     i; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   unsigned char | 
 |     buffer[1]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   for (i=0; i < (MaxTextExtent-1L); i++) | 
 |   { | 
 |     p=ReadBlobStream(image,1,buffer,&count); | 
 |     if (count != 1) | 
 |       { | 
 |         if (i == 0) | 
 |           return((char *) NULL); | 
 |         break; | 
 |       } | 
 |     string[i]=(char) (*p); | 
 |     if ((string[i] == '\r') || (string[i] == '\n')) | 
 |       break; | 
 |   } | 
 |   if (string[i] == '\r') | 
 |     (void) ReadBlobStream(image,1,buffer,&count); | 
 |   string[i]='\0'; | 
 |   return(string); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   R e f e r e n c e B l o b                                                 % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReferenceBlob() increments the reference count associated with the pixel | 
 | %  blob returning a pointer to the blob. | 
 | % | 
 | %  The format of the ReferenceBlob method is: | 
 | % | 
 | %      BlobInfo ReferenceBlob(BlobInfo *blob_info) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o blob_info: the blob_info. | 
 | % | 
 | */ | 
 | MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob) | 
 | { | 
 |   assert(blob != (BlobInfo *) NULL); | 
 |   assert(blob->signature == MagickSignature); | 
 |   if (blob->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); | 
 |   LockSemaphoreInfo(blob->semaphore); | 
 |   blob->reference_count++; | 
 |   UnlockSemaphoreInfo(blob->semaphore); | 
 |   return(blob); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  S e e k B l o b                                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  SeekBlob() sets the offset in bytes from the beginning of a blob or file | 
 | %  and returns the resulting offset. | 
 | % | 
 | %  The format of the SeekBlob method is: | 
 | % | 
 | %      MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset, | 
 | %        const int whence) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o offset:  Specifies an integer representing the offset in bytes. | 
 | % | 
 | %    o whence:  Specifies an integer representing how the offset is | 
 | %      treated relative to the beginning of the blob as follows: | 
 | % | 
 | %        SEEK_SET  Set position equal to offset bytes. | 
 | %        SEEK_CUR  Set position to current location plus offset. | 
 | %        SEEK_END  Set position to EOF plus offset. | 
 | % | 
 | */ | 
 | MagickExport MagickOffsetType SeekBlob(Image *image, | 
 |   const MagickOffsetType offset,const int whence) | 
 | { | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     { | 
 |       if (fseek(image->blob->file,offset,whence) < 0) | 
 |         return(-1); | 
 |       image->blob->offset=TellBlob(image); | 
 |       break; | 
 |     } | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |     case ZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |       if (gzseek(image->blob->file,(off_t) offset,whence) < 0) | 
 |         return(-1); | 
 | #endif | 
 |       image->blob->offset=TellBlob(image); | 
 |       break; | 
 |     } | 
 |     case BZipStream: | 
 |       return(-1); | 
 |     case FifoStream: | 
 |       return(-1); | 
 |     case BlobStream: | 
 |     { | 
 |       switch (whence) | 
 |       { | 
 |         case SEEK_SET: | 
 |         default: | 
 |         { | 
 |           if (offset < 0) | 
 |             return(-1); | 
 |           image->blob->offset=offset; | 
 |           break; | 
 |         } | 
 |         case SEEK_CUR: | 
 |         { | 
 |           if ((image->blob->offset+offset) < 0) | 
 |             return(-1); | 
 |           image->blob->offset+=offset; | 
 |           break; | 
 |         } | 
 |         case SEEK_END: | 
 |         { | 
 |           if (((MagickOffsetType) image->blob->length+offset) < 0) | 
 |             return(-1); | 
 |           image->blob->offset=image->blob->length+offset; | 
 |           break; | 
 |         } | 
 |       } | 
 |       if (image->blob->offset <= (MagickOffsetType) | 
 |           ((off_t) image->blob->length)) | 
 |         image->blob->eof=MagickFalse; | 
 |       else | 
 |         if (image->blob->mapped != MagickFalse) | 
 |           return(-1); | 
 |         else | 
 |           { | 
 |             image->blob->extent=(size_t) (image->blob->offset+ | 
 |               image->blob->quantum); | 
 |             image->blob->data=(unsigned char *) ResizeQuantumMemory( | 
 |               image->blob->data,image->blob->extent+1, | 
 |               sizeof(*image->blob->data)); | 
 |             (void) SyncBlob(image); | 
 |             if (image->blob->data == (unsigned char *) NULL) | 
 |               { | 
 |                 (void) DetachBlob(image->blob); | 
 |                 return(-1); | 
 |               } | 
 |           } | 
 |       break; | 
 |     } | 
 |   } | 
 |   return(image->blob->offset); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   S e t B l o b E x e m p t                                                 % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  SetBlobExempt() sets the blob exempt status. | 
 | % | 
 | %  The format of the SetBlobExempt method is: | 
 | % | 
 | %      MagickBooleanType SetBlobExempt(const Image *image, | 
 | %        const MagickBooleanType exempt) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o exempt: Set to true if this blob is exempt from being closed. | 
 | % | 
 | */ | 
 | MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt) | 
 | { | 
 |   assert(image != (const Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   image->blob->exempt=exempt; | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  S e t B l o b E x t e n t                                                  % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  SetBlobExtent() ensures enough space is allocated for the blob.  If the | 
 | %  method is successful, subsequent writes to bytes in the specified range are | 
 | %  guaranteed not to fail. | 
 | % | 
 | %  The format of the SetBlobExtent method is: | 
 | % | 
 | %      MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o extent:  the blob maximum extent. | 
 | % | 
 | */ | 
 | MagickPrivate MagickBooleanType SetBlobExtent(Image *image, | 
 |   const MagickSizeType extent) | 
 | { | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     { | 
 |       if (extent != (MagickSizeType) ((off_t) extent)) | 
 |         return(MagickFalse); | 
 | #if !defined(MAGICKCORE_POSIX_FALLOCATE) | 
 |         return(MagickFalse); | 
 | #else | 
 |       { | 
 |         int | 
 |           status; | 
 |  | 
 |         MagickOffsetType | 
 |           offset; | 
 |  | 
 |         offset=TellBlob(image); | 
 |         status=posix_fallocate(fileno(image->blob->file),(off_t) offset, | 
 |           (off_t) (extent-offset)); | 
 |         if (status != 0) | 
 |           return(MagickFalse); | 
 |       } | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |     case ZipStream: | 
 |       return(MagickFalse); | 
 |     case BZipStream: | 
 |       return(MagickFalse); | 
 |     case FifoStream: | 
 |       return(MagickFalse); | 
 |     case BlobStream: | 
 |     { | 
 |       if (image->blob->mapped != MagickFalse) | 
 |         { | 
 |           if (image->blob->file == (FILE *) NULL) | 
 |             return(MagickFalse); | 
 |           (void) UnmapBlob(image->blob->data,image->blob->length); | 
 | #if !defined(MAGICKCORE_POSIX_FALLOCATE) | 
 |           return(MagickFalse); | 
 | #else | 
 |           { | 
 |             int | 
 |               status; | 
 |  | 
 |             MagickOffsetType | 
 |               offset; | 
 |  | 
 |             offset=TellBlob(image); | 
 |             status=posix_fallocate(fileno(image->blob->file),(off_t) offset, | 
 |               (off_t) (extent-offset)); | 
 |             if (status != 0) | 
 |               return(MagickFalse); | 
 |           } | 
 |           image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file), | 
 |             WriteMode,0,(size_t) extent); | 
 |           image->blob->extent=(size_t) extent; | 
 |           image->blob->length=(size_t) extent; | 
 |           (void) SyncBlob(image); | 
 |           break; | 
 | #endif | 
 |         } | 
 |       if (extent != (MagickSizeType) ((size_t) extent)) | 
 |         return(MagickFalse); | 
 |       image->blob->extent=(size_t) extent; | 
 |       image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data, | 
 |         image->blob->extent+1,sizeof(*image->blob->data)); | 
 |       (void) SyncBlob(image); | 
 |       if (image->blob->data == (unsigned char *) NULL) | 
 |         { | 
 |           (void) DetachBlob(image->blob); | 
 |           return(MagickFalse); | 
 |         } | 
 |       break; | 
 |     } | 
 |   } | 
 |   return(MagickTrue); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  S y n c B l o b                                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  SyncBlob() flushes the datastream if it is a file or synchronizes the data | 
 | %  attributes if it is an blob. | 
 | % | 
 | %  The format of the SyncBlob method is: | 
 | % | 
 | %      int SyncBlob(Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | static int SyncBlob(Image *image) | 
 | { | 
 |   int | 
 |     status; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   status=0; | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |     { | 
 |       status=fflush(image->blob->file); | 
 |       break; | 
 |     } | 
 |     case ZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |       status=gzflush(image->blob->file,Z_SYNC_FLUSH); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case BZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 |       status=BZ2_bzflush((BZFILE *) image->blob->file); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case FifoStream: | 
 |       break; | 
 |     case BlobStream: | 
 |     { | 
 | #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) | 
 |       if (image->blob->mapped != MagickFalse) | 
 |         status=msync(image->blob->data,image->blob->length,MS_SYNC); | 
 | #endif | 
 |       break; | 
 |     } | 
 |   } | 
 |   return(status); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  T e l l B l o b                                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  TellBlob() obtains the current value of the blob or file position. | 
 | % | 
 | %  The format of the TellBlob method is: | 
 | % | 
 | %      MagickOffsetType TellBlob(const Image *image) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport MagickOffsetType TellBlob(const Image *image) | 
 | { | 
 |   MagickOffsetType | 
 |     offset; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->debug != MagickFalse) | 
 |     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   offset=(-1); | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     { | 
 |       offset=ftell(image->blob->file); | 
 |       break; | 
 |     } | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |       break; | 
 |     case ZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |       offset=(MagickOffsetType) gztell(image->blob->file); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case BZipStream: | 
 |       break; | 
 |     case FifoStream: | 
 |       break; | 
 |     case BlobStream: | 
 |     { | 
 |       offset=image->blob->offset; | 
 |       break; | 
 |     } | 
 |   } | 
 |   return(offset); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  U n m a p B l o b                                                          % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  UnmapBlob() deallocates the binary large object previously allocated with | 
 | %  the MapBlob method. | 
 | % | 
 | %  The format of the UnmapBlob method is: | 
 | % | 
 | %       MagickBooleanType UnmapBlob(void *map,const size_t length) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o map: the address  of the binary large object. | 
 | % | 
 | %    o length: the length of the binary large object. | 
 | % | 
 | */ | 
 | MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length) | 
 | { | 
 | #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) | 
 |   int | 
 |     status; | 
 |  | 
 |   status=munmap(map,length); | 
 |   return(status == -1 ? MagickFalse : MagickTrue); | 
 | #else | 
 |   (void) map; | 
 |   (void) length; | 
 |   return(MagickFalse); | 
 | #endif | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b                                                          % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlob() writes data to a blob or image file.  It returns the number of | 
 | %  bytes written. | 
 | % | 
 | %  The format of the WriteBlob method is: | 
 | % | 
 | %      ssize_t WriteBlob(Image *image,const size_t length, | 
 | %        const unsigned char *data) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o length:  Specifies an integer representing the number of bytes to | 
 | %      write to the file. | 
 | % | 
 | %    o data:  The address of the data to write to the blob or file. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlob(Image *image,const size_t length, | 
 |   const unsigned char *data) | 
 | { | 
 |   int | 
 |     c; | 
 |  | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   ssize_t | 
 |     count; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   assert(data != (const unsigned char *) NULL); | 
 |   assert(image->blob != (BlobInfo *) NULL); | 
 |   assert(image->blob->type != UndefinedStream); | 
 |   if (length == 0) | 
 |     return(0); | 
 |   count=0; | 
 |   p=data; | 
 |   switch (image->blob->type) | 
 |   { | 
 |     case UndefinedStream: | 
 |       break; | 
 |     case FileStream: | 
 |     case StandardStream: | 
 |     case PipeStream: | 
 |     { | 
 |       switch (length) | 
 |       { | 
 |         default: | 
 |         { | 
 |           count=(ssize_t) fwrite((const char *) data,1,length, | 
 |             image->blob->file); | 
 |           break; | 
 |         } | 
 |         case 2: | 
 |         { | 
 |           c=putc((int) *p++,image->blob->file); | 
 |           if (c == EOF) | 
 |             break; | 
 |           count++; | 
 |         } | 
 |         case 1: | 
 |         { | 
 |           c=putc((int) *p++,image->blob->file); | 
 |           if (c == EOF) | 
 |             break; | 
 |           count++; | 
 |         } | 
 |         case 0: | 
 |           break; | 
 |       } | 
 |       break; | 
 |     } | 
 |     case ZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_ZLIB_DELEGATE) | 
 |       switch (length) | 
 |       { | 
 |         default: | 
 |         { | 
 |           count=(ssize_t) gzwrite(image->blob->file,(void *) data, | 
 |             (unsigned int) length); | 
 |           break; | 
 |         } | 
 |         case 2: | 
 |         { | 
 |           c=gzputc(image->blob->file,(int) *p++); | 
 |           if (c == EOF) | 
 |             break; | 
 |           count++; | 
 |         } | 
 |         case 1: | 
 |         { | 
 |           c=gzputc(image->blob->file,(int) *p++); | 
 |           if (c == EOF) | 
 |             break; | 
 |           count++; | 
 |         } | 
 |         case 0: | 
 |           break; | 
 |       } | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case BZipStream: | 
 |     { | 
 | #if defined(MAGICKCORE_BZLIB_DELEGATE) | 
 |       count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data, | 
 |         (int) length); | 
 | #endif | 
 |       break; | 
 |     } | 
 |     case FifoStream: | 
 |     { | 
 |       count=(ssize_t) image->blob->stream(image,data,length); | 
 |       break; | 
 |     } | 
 |     case BlobStream: | 
 |     { | 
 |       register unsigned char | 
 |         *q; | 
 |  | 
 |       if ((image->blob->offset+(MagickOffsetType) length) >= | 
 |           (MagickOffsetType) image->blob->extent) | 
 |         { | 
 |           if (image->blob->mapped != MagickFalse) | 
 |             return(0); | 
 |           image->blob->quantum<<=1; | 
 |           image->blob->extent+=length+image->blob->quantum; | 
 |           image->blob->data=(unsigned char *) ResizeQuantumMemory( | 
 |             image->blob->data,image->blob->extent+1,sizeof(*image->blob->data)); | 
 |           (void) SyncBlob(image); | 
 |           if (image->blob->data == (unsigned char *) NULL) | 
 |             { | 
 |               (void) DetachBlob(image->blob); | 
 |               return(0); | 
 |             } | 
 |         } | 
 |       q=image->blob->data+image->blob->offset; | 
 |       (void) memcpy(q,p,length); | 
 |       image->blob->offset+=length; | 
 |       if (image->blob->offset >= (MagickOffsetType) image->blob->length) | 
 |         image->blob->length=(size_t) image->blob->offset; | 
 |       count=(ssize_t) length; | 
 |     } | 
 |   } | 
 |   return(count); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b B y t e                                                  % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobByte() write an integer to a blob.  It returns the number of bytes | 
 | %  written (either 0 or 1); | 
 | % | 
 | %  The format of the WriteBlobByte method is: | 
 | % | 
 | %      ssize_t WriteBlobByte(Image *image,const unsigned char value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o value: Specifies the value to write. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value) | 
 | { | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   return(WriteBlobStream(image,1,&value)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b F l o a t                                                % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order | 
 | %  specified by the endian member of the image structure. | 
 | % | 
 | %  The format of the WriteBlobFloat method is: | 
 | % | 
 | %      ssize_t WriteBlobFloat(Image *image,const float value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o value: Specifies the value to write. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobFloat(Image *image,const float value) | 
 | { | 
 |   union | 
 |   { | 
 |     unsigned int | 
 |       unsigned_value; | 
 |  | 
 |     float | 
 |       float_value; | 
 |   } quantum; | 
 |  | 
 |   quantum.unsigned_value=0U; | 
 |   quantum.float_value=value; | 
 |   return(WriteBlobLong(image,quantum.unsigned_value)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b L o n g                                                  % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order | 
 | %  specified by the endian member of the image structure. | 
 | % | 
 | %  The format of the WriteBlobLong method is: | 
 | % | 
 | %      ssize_t WriteBlobLong(Image *image,const unsigned int value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o value: Specifies the value to write. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value) | 
 | { | 
 |   unsigned char | 
 |     buffer[4]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->endian == LSBEndian) | 
 |     { | 
 |       buffer[0]=(unsigned char) value; | 
 |       buffer[1]=(unsigned char) (value >> 8); | 
 |       buffer[2]=(unsigned char) (value >> 16); | 
 |       buffer[3]=(unsigned char) (value >> 24); | 
 |       return(WriteBlobStream(image,4,buffer)); | 
 |     } | 
 |   buffer[0]=(unsigned char) (value >> 24); | 
 |   buffer[1]=(unsigned char) (value >> 16); | 
 |   buffer[2]=(unsigned char) (value >> 8); | 
 |   buffer[3]=(unsigned char) value; | 
 |   return(WriteBlobStream(image,4,buffer)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   W r i t e B l o b S h o r t                                               % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobShort() writes a short value as a 16-bit quantity in the | 
 | %  byte-order specified by the endian member of the image structure. | 
 | % | 
 | %  The format of the WriteBlobShort method is: | 
 | % | 
 | %      ssize_t WriteBlobShort(Image *image,const unsigned short value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o value:  Specifies the value to write. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value) | 
 | { | 
 |   unsigned char | 
 |     buffer[2]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   if (image->endian == LSBEndian) | 
 |     { | 
 |       buffer[0]=(unsigned char) value; | 
 |       buffer[1]=(unsigned char) (value >> 8); | 
 |       return(WriteBlobStream(image,2,buffer)); | 
 |     } | 
 |   buffer[0]=(unsigned char) (value >> 8); | 
 |   buffer[1]=(unsigned char) value; | 
 |   return(WriteBlobStream(image,2,buffer)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b L S B L o n g                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in | 
 | %  least-significant byte first order. | 
 | % | 
 | %  The format of the WriteBlobLSBLong method is: | 
 | % | 
 | %      ssize_t WriteBlobLSBLong(Image *image,const unsigned int value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o value: Specifies the value to write. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value) | 
 | { | 
 |   unsigned char | 
 |     buffer[4]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   buffer[0]=(unsigned char) value; | 
 |   buffer[1]=(unsigned char) (value >> 8); | 
 |   buffer[2]=(unsigned char) (value >> 16); | 
 |   buffer[3]=(unsigned char) (value >> 24); | 
 |   return(WriteBlobStream(image,4,buffer)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +   W r i t e B l o b L S B S h o r t                                         % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in | 
 | %  least-significant byte first order. | 
 | % | 
 | %  The format of the WriteBlobLSBShort method is: | 
 | % | 
 | %      ssize_t WriteBlobLSBShort(Image *image,const unsigned short value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o value:  Specifies the value to write. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value) | 
 | { | 
 |   unsigned char | 
 |     buffer[2]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   buffer[0]=(unsigned char) value; | 
 |   buffer[1]=(unsigned char) (value >> 8); | 
 |   return(WriteBlobStream(image,2,buffer)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b M S B L o n g                                            % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in | 
 | %  most-significant byte first order. | 
 | % | 
 | %  The format of the WriteBlobMSBLong method is: | 
 | % | 
 | %      ssize_t WriteBlobMSBLong(Image *image,const unsigned int value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o value:  Specifies the value to write. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value) | 
 | { | 
 |   unsigned char | 
 |     buffer[4]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   buffer[0]=(unsigned char) (value >> 24); | 
 |   buffer[1]=(unsigned char) (value >> 16); | 
 |   buffer[2]=(unsigned char) (value >> 8); | 
 |   buffer[3]=(unsigned char) value; | 
 |   return(WriteBlobStream(image,4,buffer)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b M S B L o n g L o n g                                    % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in | 
 | %  most-significant byte first order. | 
 | % | 
 | %  The format of the WriteBlobMSBLongLong method is: | 
 | % | 
 | %      ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o value:  Specifies the value to write. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobMSBLongLong(Image *image, | 
 |   const MagickSizeType value) | 
 | { | 
 |   unsigned char | 
 |     buffer[8]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   buffer[0]=(unsigned char) (value >> 56); | 
 |   buffer[1]=(unsigned char) (value >> 48); | 
 |   buffer[2]=(unsigned char) (value >> 40); | 
 |   buffer[3]=(unsigned char) (value >> 32); | 
 |   buffer[4]=(unsigned char) (value >> 24); | 
 |   buffer[5]=(unsigned char) (value >> 16); | 
 |   buffer[6]=(unsigned char) (value >> 8); | 
 |   buffer[7]=(unsigned char) value; | 
 |   return(WriteBlobStream(image,8,buffer)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b M S B S h o r t                                          % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in | 
 | %  most-significant byte first order. | 
 | % | 
 | %  The format of the WriteBlobMSBShort method is: | 
 | % | 
 | %      ssize_t WriteBlobMSBShort(Image *image,const unsigned short value) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %   o  value:  Specifies the value to write. | 
 | % | 
 | %   o  file:  Specifies the file to write the data to. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value) | 
 | { | 
 |   unsigned char | 
 |     buffer[2]; | 
 |  | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   buffer[0]=(unsigned char) (value >> 8); | 
 |   buffer[1]=(unsigned char) value; | 
 |   return(WriteBlobStream(image,2,buffer)); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | +  W r i t e B l o b S t r i n g                                              % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  WriteBlobString() write a string to a blob.  It returns the number of | 
 | %  characters written. | 
 | % | 
 | %  The format of the WriteBlobString method is: | 
 | % | 
 | %      ssize_t WriteBlobString(Image *image,const char *string) | 
 | % | 
 | %  A description of each parameter follows. | 
 | % | 
 | %    o image: the image. | 
 | % | 
 | %    o string: Specifies the string to write. | 
 | % | 
 | */ | 
 | MagickExport ssize_t WriteBlobString(Image *image,const char *string) | 
 | { | 
 |   assert(image != (Image *) NULL); | 
 |   assert(image->signature == MagickSignature); | 
 |   assert(string != (const char *) NULL); | 
 |   return(WriteBlobStream(image,strlen(string),(const unsigned char *) string)); | 
 | } |