]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/stream.c
https://github.com/ImageMagick/ImageMagick/issues/1279
[imagemagick] / MagickCore / stream.c
index 2e75164ff7dff68d1b655ae6a8be2e742f16f20c..b55f95900a3168b0e808805961158582d0464edb 100644 (file)
 %                       MagickCore Pixel Stream Methods                       %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 March 2000                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2018 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                            %
+%    https://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,          %
 #include "MagickCore/exception-private.h"
 #include "MagickCore/geometry.h"
 #include "MagickCore/memory_.h"
+#include "MagickCore/memory-private.h"
 #include "MagickCore/pixel.h"
 #include "MagickCore/pixel-accessor.h"
+#include "MagickCore/policy.h"
 #include "MagickCore/quantum.h"
 #include "MagickCore/quantum-private.h"
 #include "MagickCore/semaphore.h"
@@ -126,6 +128,9 @@ static Quantum
 }
 #endif
 \f
+static ssize_t
+  cache_anonymous_memory = (-1);
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -141,30 +146,32 @@ static Quantum
 %
 %  The format of the AcquireStreamInfo method is:
 %
-%      StreamInfo *AcquireStreamInfo(const ImageInfo *image_info)
+%      StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
+%        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
 %    o image_info: the image info.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
-MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info)
+MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
+  ExceptionInfo *exception)
 {
   StreamInfo
     *stream_info;
 
-  stream_info=(StreamInfo *) AcquireMagickMemory(sizeof(*stream_info));
-  if (stream_info == (StreamInfo *) NULL)
-    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
-  (void) ResetMagickMemory(stream_info,0,sizeof(*stream_info));
-  stream_info->pixels=(unsigned char *) AcquireMagickMemory(
-    sizeof(*stream_info->pixels));
+  stream_info=(StreamInfo *) AcquireCriticalMemory(sizeof(*stream_info));
+  (void) memset(stream_info,0,sizeof(*stream_info));
+  stream_info->pixels=(unsigned char *) MagickAssumeAligned(
+    AcquireAlignedMemory(1,sizeof(*stream_info->pixels)));
   if (stream_info->pixels == (unsigned char *) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   stream_info->map=ConstantString("RGB");
   stream_info->storage_type=CharPixel;
-  stream_info->stream=AcquireImage(image_info);
-  stream_info->signature=MagickSignature;
+  stream_info->stream=AcquireImage(image_info,exception);
+  stream_info->signature=MagickCoreSignature;
   return(stream_info);
 }
 \f
@@ -195,7 +202,7 @@ static inline void RelinquishStreamPixels(CacheInfo *cache_info)
 {
   assert(cache_info != (CacheInfo *) NULL);
   if (cache_info->mapped == MagickFalse)
-    (void) RelinquishMagickMemory(cache_info->pixels);
+    (void) RelinquishAlignedMemory(cache_info->pixels);
   else
     (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
   cache_info->pixels=(Quantum *) NULL;
@@ -213,11 +220,11 @@ static void DestroyPixelStream(Image *image)
     destroy;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   destroy=MagickFalse;
   LockSemaphoreInfo(cache_info->semaphore);
   cache_info->reference_count--;
@@ -230,10 +237,10 @@ static void DestroyPixelStream(Image *image)
   if (cache_info->nexus_info != (NexusInfo **) NULL)
     cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
       cache_info->number_threads);
-  if (cache_info->disk_semaphore != (SemaphoreInfo *) NULL)
-    DestroySemaphoreInfo(&cache_info->disk_semaphore);
+  if (cache_info->file_semaphore != (SemaphoreInfo *) NULL)
+    RelinquishSemaphoreInfo(&cache_info->file_semaphore);
   if (cache_info->semaphore != (SemaphoreInfo *) NULL)
-    DestroySemaphoreInfo(&cache_info->semaphore);
+    RelinquishSemaphoreInfo(&cache_info->semaphore);
   cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
 }
 \f
@@ -264,11 +271,11 @@ MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
 {
   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   assert(stream_info != (StreamInfo *) NULL);
-  assert(stream_info->signature == MagickSignature);
+  assert(stream_info->signature == MagickCoreSignature);
   if (stream_info->map != (char *) NULL)
     stream_info->map=DestroyString(stream_info->map);
   if (stream_info->pixels != (unsigned char *) NULL)
-    stream_info->pixels=(unsigned char *) RelinquishMagickMemory(
+    stream_info->pixels=(unsigned char *) RelinquishAlignedMemory(
       stream_info->pixels);
   if (stream_info->stream != (Image *) NULL)
     {
@@ -277,7 +284,7 @@ MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
     }
   if (stream_info->quantum_info != (QuantumInfo *) NULL)
     stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
-  stream_info->signature=(~MagickSignature);
+  stream_info->signature=(~MagickCoreSignature);
   stream_info=(StreamInfo *) RelinquishMagickMemory(stream_info);
   return(stream_info);
 }
@@ -312,11 +319,11 @@ static void *GetAuthenticMetacontentFromStream(const Image *image)
     *cache_info;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   return(cache_info->metacontent);
 }
 \f
@@ -360,7 +367,7 @@ static Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
     *pixels;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   pixels=QueueAuthenticPixelsStream(image,x,y,columns,rows,exception);
@@ -396,11 +403,11 @@ static Quantum *GetAuthenticPixelsFromStream(const Image *image)
     *cache_info;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   return(cache_info->pixels);
 }
 \f
@@ -421,7 +428,7 @@ static Quantum *GetAuthenticPixelsFromStream(const Image *image)
 %  The format of the GetOneAuthenticPixelFromStream() method is:
 %
 %      MagickBooleanType GetOneAuthenticPixelFromStream(const Image image,
-%        const ssize_t x,const ssize_t y,PixelPacket *pixel,
+%        const ssize_t x,const ssize_t y,Quantum *pixel,
 %        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -436,18 +443,32 @@ static Quantum *GetAuthenticPixelsFromStream(const Image *image)
 %
 */
 static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
-  const ssize_t x,const ssize_t y,PixelPacket *pixel,ExceptionInfo *exception)
+  const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
 {
   register Quantum
-    *q;
+    *p;
+
+  register ssize_t
+    i;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
-  *pixel=image->background_color;
-  q=GetAuthenticPixelsStream(image,x,y,1,1,exception);
-  if (q != (Quantum *) NULL)
-    return(MagickFalse);
-  GetPixelPacket(image,q,pixel);
+  assert(image->signature == MagickCoreSignature);
+  (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
+  p=GetAuthenticPixelsStream(image,x,y,1,1,exception);
+  if (p == (Quantum *) NULL)
+    {
+      pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
+      pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
+      pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
+      pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
+      pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
+      return(MagickFalse);
+    }
+  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+  {
+    PixelChannel channel = GetPixelChannelChannel(image,i);
+    pixel[channel]=p[i];
+  }
   return(MagickTrue);
 }
 \f
@@ -469,7 +490,7 @@ static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
 %
 %      MagickBooleanType GetOneVirtualPixelFromStream(const Image image,
 %        const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
-%        const ssize_t y,PixelPacket *pixel,ExceptionInfo *exception)
+%        const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -486,20 +507,32 @@ static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
 */
 static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
   const VirtualPixelMethod virtual_pixel_method,const ssize_t x,const ssize_t y,
-  PixelPacket *pixel,ExceptionInfo *exception)
+  Quantum *pixel,ExceptionInfo *exception)
 {
   const Quantum
     *p;
 
+  register ssize_t
+    i;
+
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
-  *pixel=image->background_color;
+  assert(image->signature == MagickCoreSignature);
+  (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
   p=GetVirtualPixelStream(image,virtual_pixel_method,x,y,1,1,exception);
   if (p == (const Quantum *) NULL)
-    return(MagickFalse);
-  GetPixelPacket(image,p,pixel);
-  if (image->colorspace == CMYKColorspace)
-    pixel->black=GetPixelBlack(image,p);
+    {
+      pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
+      pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
+      pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
+      pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
+      pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
+      return(MagickFalse);
+    }
+  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+  {
+    PixelChannel channel = GetPixelChannelChannel(image,i);
+    pixel[channel]=p[i];
+  }
   return(MagickTrue);
 }
 \f
@@ -528,7 +561,7 @@ static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
 MagickPrivate const void *GetStreamInfoClientData(StreamInfo *stream_info)
 {
   assert(stream_info != (StreamInfo *) NULL);
-  assert(stream_info->signature == MagickSignature);
+  assert(stream_info->signature == MagickCoreSignature);
   return(stream_info->client_data);
 }
 \f
@@ -537,14 +570,14 @@ MagickPrivate const void *GetStreamInfoClientData(StreamInfo *stream_info)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   G e t  V i r t u a l P i x e l s F r o m S t r e a m                      %
++   G e t V i r t u a l P i x e l s F r o m S t r e a m                       %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  GetVirtualPixelsStream() returns the pixels associated with the last
-%  call to QueueAuthenticPixelsStream() or GetVirtualPixelStream().
+%  GetVirtualPixelsStream() returns the pixels associated with the last call to
+%  QueueAuthenticPixelsStream() or GetVirtualPixelStream().
 %
 %  The format of the GetVirtualPixelsStream() method is:
 %
@@ -564,11 +597,11 @@ static const Quantum *GetVirtualPixelsStream(const Image *image)
     *cache_info;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   return(cache_info->pixels);
 }
 \f
@@ -583,8 +616,8 @@ static const Quantum *GetVirtualPixelsStream(const Image *image)
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  GetVirtualMetacontentFromStream() returns the associated pixel 
-%  channels corresponding with the last call to QueueAuthenticPixelsStream() or
+%  GetVirtualMetacontentFromStream() returns the associated pixel channels
+%  corresponding with the last call to QueueAuthenticPixelsStream() or
 %  GetVirtualPixelStream().
 %
 %  The format of the GetVirtualMetacontentFromStream() method is:
@@ -596,18 +629,17 @@ static const Quantum *GetVirtualPixelsStream(const Image *image)
 %    o image: the image.
 %
 */
-static const void *GetVirtualMetacontentFromStream(
-  const Image *image)
+static const void *GetVirtualMetacontentFromStream(const Image *image)
 {
   CacheInfo
     *cache_info;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   return(cache_info->metacontent);
 }
 \f
@@ -652,15 +684,43 @@ static inline MagickBooleanType AcquireStreamPixels(CacheInfo *cache_info,
 {
   if (cache_info->length != (MagickSizeType) ((size_t) cache_info->length))
     return(MagickFalse);
-  cache_info->mapped=MagickFalse;
-  cache_info->pixels=(Quantum *) AcquireMagickMemory((size_t)
-    cache_info->length);
-  if (cache_info->pixels == (Quantum *) NULL)
+  if (cache_anonymous_memory < 0)
     {
-      cache_info->mapped=MagickTrue;
-      cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
-        cache_info->length);
+      char
+        *value;
+
+      /*
+        Does the security policy require anonymous mapping for pixel cache?
+      */
+      cache_anonymous_memory=0;
+      value=GetPolicyValue("pixel-cache-memory");
+      if (value == (char *) NULL)
+        value=GetPolicyValue("cache:memory-map");
+      if (LocaleCompare(value,"anonymous") == 0)
+        {
+#if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS)
+          cache_anonymous_memory=1;
+#else
+          (void) ThrowMagickException(exception,GetMagickModule(),
+            MissingDelegateError,"DelegateLibrarySupportNotBuiltIn",
+            "'%s' (policy requires anonymous memory mapping)",
+            cache_info->filename);
+#endif
+        }
+      value=DestroyString(value);
     }
+   if (cache_anonymous_memory <= 0)
+     {
+       cache_info->mapped=MagickFalse;
+       cache_info->pixels=(Quantum *) MagickAssumeAligned(
+         AcquireAlignedMemory(1,(size_t) cache_info->length));
+     }
+   else
+     {
+       cache_info->mapped=MagickTrue;
+       cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
+         cache_info->length);
+     }
   if (cache_info->pixels == (Quantum *) NULL)
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
@@ -688,11 +748,13 @@ static const Quantum *GetVirtualPixelStream(const Image *image,
   size_t
     length;
 
+  magick_unreferenced(virtual_pixel_method);
+
   /*
     Validate pixel cache geometry.
   */
   assert(image != (const Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   if ((x < 0) || (y < 0) ||
@@ -705,12 +767,14 @@ static const Quantum *GetVirtualPixelStream(const Image *image,
       return((Quantum *) NULL);
     }
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   /*
     Pixels are stored in a temporary buffer until they are synced to the cache.
   */
   number_pixels=(MagickSizeType) columns*rows;
   length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
+  if (cache_info->number_channels == 0)
+    length=(size_t) number_pixels*sizeof(Quantum);
   if (cache_info->metacontent_extent != 0)
     length+=number_pixels*cache_info->metacontent_extent;
   if (cache_info->pixels == (Quantum *) NULL)
@@ -724,7 +788,7 @@ static const Quantum *GetVirtualPixelStream(const Image *image,
         }
     }
   else
-    if (cache_info->length != length)
+    if (cache_info->length < length)
       {
         RelinquishStreamPixels(cache_info);
         cache_info->length=length;
@@ -777,7 +841,8 @@ MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
   MagickBooleanType
     status;
 
-  (void) CopyMagickString(stream_info->stream->filename,filename,MaxTextExtent);
+  (void) CopyMagickString(stream_info->stream->filename,filename,
+    MagickPathExtent);
   status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
   return(status);
 }
@@ -820,6 +885,9 @@ static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
   CacheInfo
     *cache_info;
 
+  MagickBooleanType
+    status;
+
   MagickSizeType
     number_pixels;
 
@@ -850,7 +918,7 @@ static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
       return((Quantum *) NULL);
     }
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   if ((image->storage_class != GetPixelCacheStorageClass(image->cache)) ||
       (image->colorspace != GetPixelCacheColorspace(image->cache)))
     {
@@ -870,22 +938,32 @@ static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
   cache_info->rows=rows;
   number_pixels=(MagickSizeType) columns*rows;
   length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
+  if (cache_info->number_channels == 0)
+    length=(size_t) number_pixels*sizeof(Quantum);
   if (cache_info->metacontent_extent != 0)
     length+=number_pixels*cache_info->metacontent_extent;
   if (cache_info->pixels == (Quantum *) NULL)
     {
-      cache_info->pixels=(Quantum *) AcquireMagickMemory(length);
-      cache_info->length=(MagickSizeType) length;
+      cache_info->length=length;
+      status=AcquireStreamPixels(cache_info,exception);
+      if (status == MagickFalse)
+        {
+          cache_info->length=0;
+          return((Quantum *) NULL);
+        }
     }
   else
-    if (cache_info->length < (MagickSizeType) length)
+    if (cache_info->length < length)
       {
-        cache_info->pixels=(Quantum *) ResizeMagickMemory(
-          cache_info->pixels,length);
-        cache_info->length=(MagickSizeType) length;
+        RelinquishStreamPixels(cache_info);
+        cache_info->length=length;
+        status=AcquireStreamPixels(cache_info,exception);
+        if (status == MagickFalse)
+          {
+            cache_info->length=0;
+            return((Quantum *) NULL);
+          }
       }
-  if (cache_info->pixels == (void *) NULL)
-    return((Quantum *) NULL);
   cache_info->metacontent=(void *) NULL;
   if (cache_info->metacontent_extent != 0)
     cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
@@ -937,19 +1015,19 @@ MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
     Stream image pixels.
   */
   assert(image_info != (ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
+  assert(image_info->signature == MagickCoreSignature);
   if (image_info->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
       image_info->filename);
   assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
+  assert(exception->signature == MagickCoreSignature);
   read_info=CloneImageInfo(image_info);
   read_info->cache=AcquirePixelCache(0);
   GetPixelCacheMethods(&cache_methods);
   cache_methods.get_virtual_pixel_handler=GetVirtualPixelStream;
+  cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
   cache_methods.get_virtual_metacontent_from_handler=
     GetVirtualMetacontentFromStream;
-  cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
   cache_methods.get_authentic_pixels_handler=GetAuthenticPixelsStream;
   cache_methods.queue_authentic_pixels_handler=QueueAuthenticPixelsStream;
   cache_methods.sync_authentic_pixels_handler=SyncAuthenticPixelsStream;
@@ -963,6 +1041,11 @@ MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
   SetPixelCacheMethods(read_info->cache,&cache_methods);
   read_info->stream=stream;
   image=ReadImage(read_info,exception);
+  if (image != (Image *) NULL)
+    {
+      InitializePixelChannelMap(image);
+      ResetPixelCacheChannels(image);
+    }
   read_info=DestroyImageInfo(read_info);
   return(image);
 }
@@ -972,6 +1055,29 @@ MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
 %                                                                             %
 %                                                                             %
 %                                                                             %
++   R e s e t S t r e a m A n o n y m o u s M e m o r y                       %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ResetStreamAnonymousMemory() resets the anonymous_memory value.
+%
+%  The format of the ResetStreamAnonymousMemory method is:
+%
+%      void ResetStreamAnonymousMemory(void)
+%
+*/
+MagickPrivate void ResetStreamAnonymousMemory(void)
+{
+  cache_anonymous_memory=0;
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 +   S e t S t r e a m I n f o C l i e n t D a t a                             %
 %                                                                             %
 %                                                                             %
@@ -996,7 +1102,7 @@ MagickPrivate void SetStreamInfoClientData(StreamInfo *stream_info,
   const void *client_data)
 {
   assert(stream_info != (StreamInfo *) NULL);
-  assert(stream_info->signature == MagickSignature);
+  assert(stream_info->signature == MagickCoreSignature);
   stream_info->client_data=client_data;
 }
 \f
@@ -1027,7 +1133,7 @@ MagickPrivate void SetStreamInfoClientData(StreamInfo *stream_info,
 MagickExport void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
 {
   assert(stream_info != (StreamInfo *) NULL);
-  assert(stream_info->signature == MagickSignature);
+  assert(stream_info->signature == MagickCoreSignature);
   (void) CloneString(&stream_info->map,map);
 }
 \f
@@ -1060,7 +1166,7 @@ MagickExport void SetStreamInfoStorageType(StreamInfo *stream_info,
   const StorageType storage_type)
 {
   assert(stream_info != (StreamInfo *) NULL);
-  assert(stream_info->signature == MagickSignature);
+  assert(stream_info->signature == MagickCoreSignature);
   stream_info->storage_type=storage_type;
 }
 \f
@@ -1120,17 +1226,17 @@ static size_t WriteStreamImage(const Image *image,const void *pixels,
   stream_info=(StreamInfo *) image->client_data;
   switch (stream_info->storage_type)
   {
-    default: packet_size=sizeof(char); break;
-    case CharPixel: packet_size=sizeof(char); break;
+    default: packet_size=sizeof(unsigned char); break;
+    case CharPixel: packet_size=sizeof(unsigned char); break;
     case DoublePixel: packet_size=sizeof(double); break;
     case FloatPixel: packet_size=sizeof(float); break;
-    case IntegerPixel: packet_size=sizeof(int); break;
-    case LongPixel: packet_size=sizeof(ssize_t); break;
+    case LongPixel: packet_size=sizeof(unsigned int); break;
+    case LongLongPixel: packet_size=sizeof(MagickSizeType); break;
     case QuantumPixel: packet_size=sizeof(Quantum); break;
     case ShortPixel: packet_size=sizeof(unsigned short); break;
   }
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   packet_size*=strlen(stream_info->map);
   length=packet_size*cache_info->columns*cache_info->rows;
   if (image != stream_info->image)
@@ -1141,10 +1247,11 @@ static size_t WriteStreamImage(const Image *image,const void *pixels,
       /*
         Prepare stream for writing.
       */
-      stream_info->pixels=(unsigned char *) ResizeQuantumMemory(
-        stream_info->pixels,length,sizeof(*stream_info->pixels));
+      (void) RelinquishAlignedMemory(stream_info->pixels);
+      stream_info->pixels=(unsigned char *) AcquireAlignedMemory(1,length);
       if (stream_info->pixels == (unsigned char *) NULL)
         return(0);
+      (void) memset(stream_info->pixels,0,length);
       stream_info->image=image;
       write_info=CloneImageInfo(stream_info->image_info);
       (void) SetImageInfo(write_info,1,stream_info->exception);
@@ -1196,19 +1303,26 @@ MagickExport Image *StreamImage(const ImageInfo *image_info,
     *read_info;
 
   assert(image_info != (const ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
+  assert(image_info->signature == MagickCoreSignature);
   if (image_info->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
       image_info->filename);
   assert(stream_info != (StreamInfo *) NULL);
-  assert(stream_info->signature == MagickSignature);
+  assert(stream_info->signature == MagickCoreSignature);
   assert(exception != (ExceptionInfo *) NULL);
   read_info=CloneImageInfo(image_info);
   stream_info->image_info=image_info;
+  stream_info->quantum_info=AcquireQuantumInfo(image_info,(Image *) NULL);
+  if (stream_info->quantum_info == (QuantumInfo *) NULL)
+    {
+      read_info=DestroyImageInfo(read_info);
+      return((Image *) NULL);
+    }
   stream_info->exception=exception;
   read_info->client_data=(void *) stream_info;
   image=ReadStream(read_info,&WriteStreamImage,exception);
   read_info=DestroyImageInfo(read_info);
+  stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
   stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
   if (stream_info->quantum_info == (QuantumInfo *) NULL)
     image=DestroyImage(image);
@@ -1264,9 +1378,9 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
     length;
 
   assert(stream_info != (StreamInfo *) NULL);
-  assert(stream_info->signature == MagickSignature);
+  assert(stream_info->signature == MagickCoreSignature);
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   length=strlen(stream_info->map);
@@ -1277,6 +1391,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
         ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
       return(MagickFalse);
     }
+  (void) memset(quantum_map,0,length*sizeof(*quantum_map));
   for (i=0; i < (ssize_t) length; i++)
   {
     switch (stream_info->map[i])
@@ -1395,7 +1510,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1410,7 +1525,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
             *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1418,14 +1533,14 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
         {
           p=GetAuthenticPixelQueue(image);
           if (p == (const Quantum *) NULL)
-              break;
+            break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
             *q++=ScaleQuantumToChar((Quantum) 0);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1436,8 +1551,8 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
-            p++;
+            *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1451,7 +1566,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1466,7 +1581,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
             *q++=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1481,7 +1596,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
             *q++=ScaleQuantumToChar((Quantum) 0);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1531,7 +1646,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             }
             case IndexQuantum:
             {
-              *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
+              *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
               break;
             }
             default:
@@ -1539,7 +1654,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
           }
           q++;
         }
-        p++;
+        p+=GetPixelChannels(image);
       }
       break;
     }
@@ -1562,7 +1677,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
               quantum_info->scale+quantum_info->minimum);
             *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1581,7 +1696,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
               quantum_info->scale+quantum_info->minimum);
             *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1599,7 +1714,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
               quantum_info->scale+quantum_info->minimum);
             *q++=0.0;
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1612,7 +1727,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
           {
             *q++=(double) ((QuantumScale*GetPixelIntensity(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1629,7 +1744,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
               quantum_info->scale+quantum_info->minimum);
             *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1648,7 +1763,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
               quantum_info->scale+quantum_info->minimum);
             *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1666,7 +1781,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
               quantum_info->scale+quantum_info->minimum);
             *q++=0.0;
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1731,7 +1846,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
           }
           q++;
         }
-        p++;
+        p+=GetPixelChannels(image);
       }
       break;
     }
@@ -1754,7 +1869,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
               quantum_info->scale+quantum_info->minimum);
             *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1773,7 +1888,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
               quantum_info->scale+quantum_info->minimum);
             *q++=(float) ((QuantumScale*(Quantum) (GetPixelAlpha(image,p)))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1791,7 +1906,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
               quantum_info->scale+quantum_info->minimum);
             *q++=0.0;
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1804,7 +1919,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
           {
             *q++=(float) ((QuantumScale*GetPixelIntensity(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1821,7 +1936,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
               quantum_info->scale+quantum_info->minimum);
             *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1840,7 +1955,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
               quantum_info->scale+quantum_info->minimum);
             *q++=(float) ((QuantumScale*GetPixelAlpha(image,p))*
               quantum_info->scale+quantum_info->minimum);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1858,7 +1973,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
               quantum_info->scale+quantum_info->minimum);
             *q++=0.0;
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1923,11 +2038,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
           }
           q++;
         }
-        p++;
+        p+=GetPixelChannels(image);
       }
       break;
     }
-    case IntegerPixel:
+    case LongPixel:
     {
       register unsigned int
         *q;
@@ -1940,10 +2055,10 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
-            p++;
+            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
+            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1954,11 +2069,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
-            p++;
+            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
+            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
+            *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1969,11 +2084,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=0U;
-            p++;
+            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
+            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
+            *q++=0;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1984,9 +2099,8 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=(unsigned int) ScaleQuantumToLong(
-              GetPixelIntensity(image,p));
-            p++;
+            *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -1997,10 +2111,10 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
-            p++;
+            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
+            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2011,12 +2125,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong((Quantum)
-              (GetPixelAlpha(image,p)));
-            p++;
+            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
+            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
+            *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2027,11 +2140,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=0U;
-            p++;
+            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
+            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
+            *q++=0;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2048,58 +2161,57 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             case RedQuantum:
             case CyanQuantum:
             {
-              *q=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
+              *q=ScaleQuantumToLong(GetPixelRed(image,p));
               break;
             }
             case GreenQuantum:
             case MagentaQuantum:
             {
-              *q=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
+              *q=ScaleQuantumToLong(GetPixelGreen(image,p));
               break;
             }
             case BlueQuantum:
             case YellowQuantum:
             {
-              *q=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
+              *q=ScaleQuantumToLong(GetPixelBlue(image,p));
               break;
             }
             case AlphaQuantum:
             {
-              *q=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
+              *q=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
               break;
             }
             case OpacityQuantum:
             {
-              *q=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
+              *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
               break;
             }
             case BlackQuantum:
             {
               if (image->colorspace == CMYKColorspace)
-                *q=(unsigned int) ScaleQuantumToLong(GetPixelBlack(image,p));
+                *q=ScaleQuantumToLong(GetPixelBlack(image,p));
               break;
             }
             case IndexQuantum:
             {
-              *q=(unsigned int)
-                ScaleQuantumToLong(GetPixelIntensity(image,p));
+              *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
               break;
             }
             default:
-              *q=0;
+              break;
           }
           q++;
         }
-        p++;
+        p+=GetPixelChannels(image);
       }
       break;
     }
-    case LongPixel:
+    case LongLongPixel:
     {
-      register size_t
+      register MagickSizeType
         *q;
 
-      q=(size_t *) stream_info->pixels;
+      q=(MagickSizeType *) stream_info->pixels;
       if (LocaleCompare(stream_info->map,"BGR") == 0)
         {
           p=GetAuthenticPixelQueue(image);
@@ -2107,10 +2219,10 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
-            p++;
+            *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2121,11 +2233,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
-            p++;
+            *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2136,11 +2248,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=0;
-            p++;
+            *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
+            *q++=0U;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2151,8 +2263,9 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToLong(GetPixelIntensity(image,p));
-            p++;
+            *q++=ScaleQuantumToLongLong(ClampToQuantum(
+              GetPixelIntensity(image,p)));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2163,10 +2276,10 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
-            p++;
+            *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2177,11 +2290,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
-            p++;
+            *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2192,11 +2305,11 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToLong(GetPixelRed(image,p));
-            *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
-            *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
-            *q++=0;
-            p++;
+            *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
+            *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
+            *q++=0U;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2213,48 +2326,49 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             case RedQuantum:
             case CyanQuantum:
             {
-              *q=ScaleQuantumToLong(GetPixelRed(image,p));
+              *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
               break;
             }
             case GreenQuantum:
             case MagentaQuantum:
             {
-              *q=ScaleQuantumToLong(GetPixelGreen(image,p));
+              *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
               break;
             }
             case BlueQuantum:
             case YellowQuantum:
             {
-              *q=ScaleQuantumToLong(GetPixelBlue(image,p));
+              *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
               break;
             }
             case AlphaQuantum:
             {
-              *q=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
+              *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
               break;
             }
             case OpacityQuantum:
             {
-              *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
+              *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
               break;
             }
             case BlackQuantum:
             {
               if (image->colorspace == CMYKColorspace)
-                *q=ScaleQuantumToLong(GetPixelBlack(image,p));
+                *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
               break;
             }
             case IndexQuantum:
             {
-              *q=ScaleQuantumToLong(GetPixelIntensity(image,p));
+              *q=ScaleQuantumToLongLong(ClampToQuantum(
+                GetPixelIntensity(image,p)));
               break;
             }
             default:
-              break;
+              *q=0;
           }
           q++;
         }
-        p++;
+        p+=GetPixelChannels(image);
       }
       break;
     }
@@ -2274,7 +2388,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=GetPixelBlue(image,p);
             *q++=GetPixelGreen(image,p);
             *q++=GetPixelRed(image,p);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2288,8 +2402,8 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=GetPixelBlue(image,p);
             *q++=GetPixelGreen(image,p);
             *q++=GetPixelRed(image,p);
-            *q++=(Quantum) (GetPixelAlpha(image,p));
-            p++;
+            *q++=GetPixelAlpha(image,p);
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2304,7 +2418,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=GetPixelGreen(image,p);
             *q++=GetPixelRed(image,p);
             *q++=0;
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2315,8 +2429,8 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=GetPixelIntensity(image,p);
-            p++;
+            *q++=ClampToQuantum(GetPixelIntensity(image,p));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2330,7 +2444,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=GetPixelRed(image,p);
             *q++=GetPixelGreen(image,p);
             *q++=GetPixelBlue(image,p);
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2344,8 +2458,8 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=GetPixelRed(image,p);
             *q++=GetPixelGreen(image,p);
             *q++=GetPixelBlue(image,p);
-            *q++=(Quantum) (GetPixelAlpha(image,p));
-            p++;
+            *q++=GetPixelAlpha(image,p);
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2360,7 +2474,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=GetPixelGreen(image,p);
             *q++=GetPixelBlue(image,p);
             *q++=0U;
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2410,7 +2524,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             }
             case IndexQuantum:
             {
-              *q=(GetPixelIntensity(image,p));
+              *q=ClampToQuantum(GetPixelIntensity(image,p));
               break;
             }
             default:
@@ -2418,7 +2532,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
           }
           q++;
         }
-        p++;
+        p+=GetPixelChannels(image);
       }
       break;
     }
@@ -2438,7 +2552,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2453,7 +2567,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
             *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2468,7 +2582,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
             *q++=0;
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2479,8 +2593,9 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             break;
           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
           {
-            *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
-            p++;
+            *q++=ScaleQuantumToShort(ClampToQuantum(
+              GetPixelIntensity(image,p)));
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2494,7 +2609,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2509,7 +2624,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
             *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2524,7 +2639,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
             *q++=0;
-            p++;
+            p+=GetPixelChannels(image);
           }
           break;
         }
@@ -2574,7 +2689,8 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
             }
             case IndexQuantum:
             {
-              *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
+              *q=ScaleQuantumToShort(ClampToQuantum(
+                GetPixelIntensity(image,p)));
               break;
             }
             default:
@@ -2582,7 +2698,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
           }
           q++;
         }
-        p++;
+        p+=GetPixelChannels(image);
       }
       break;
     }
@@ -2637,11 +2753,11 @@ static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
     stream_handler;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   cache_info=(CacheInfo *) image->cache;
-  assert(cache_info->signature == MagickSignature);
+  assert(cache_info->signature == MagickCoreSignature);
   stream_handler=GetBlobStreamHandler(image);
   if (stream_handler == (StreamHandler) NULL)
     {
@@ -2670,7 +2786,7 @@ static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
 %  The format of the WriteStream() method is:
 %
 %      MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
-%        StreamHandler stream)
+%        StreamHandler stream,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -2678,9 +2794,11 @@ static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
 %
 %    o stream: A callback method.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
 MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
-  Image *image,StreamHandler stream)
+  Image *image,StreamHandler stream,ExceptionInfo *exception)
 {
   ImageInfo
     *write_info;
@@ -2689,15 +2807,16 @@ MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
     status;
 
   assert(image_info != (ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
+  assert(image_info->signature == MagickCoreSignature);
   if (image_info->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
       image_info->filename);
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   write_info=CloneImageInfo(image_info);
+  *write_info->magick='\0';
   write_info->stream=stream;
-  status=WriteImage(write_info,image,&image->exception);
+  status=WriteImage(write_info,image,exception);
   write_info=DestroyImageInfo(write_info);
   return(status);
 }