Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                  SSSSS  TTTTT  RRRR   EEEEE   AAA   M   M                   %
      7 %                  SS       T    R   R  E      A   A  MM MM                   %
      8 %                   SSS     T    RRRR   EEE    AAAAA  M M M                   %
      9 %                     SS    T    R R    E      A   A  M   M                   %
     10 %                  SSSSS    T    R  R   EEEEE  A   A  M   M                   %
     11 %                                                                             %
     12 %                                                                             %
     13 %                       MagickCore Pixel Stream Methods                       %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                                 March 2000                                  %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     21 %  dedicated to making software imaging solutions freely available.           %
     22 %                                                                             %
     23 %  You may not use this file except in compliance with the License.  You may  %
     24 %  obtain a copy of the License at                                            %
     25 %                                                                             %
     26 %    http://www.imagemagick.org/script/license.php                            %
     27 %                                                                             %
     28 %  Unless required by applicable law or agreed to in writing, software        %
     29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     31 %  See the License for the specific language governing permissions and        %
     32 %  limitations under the License.                                             %
     33 %                                                                             %
     34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     35 %
     36 %
     37 %
     38 */
     39 
     40 /*
     42   Include declarations.
     43 */
     44 #include "MagickCore/studio.h"
     45 #include "MagickCore/blob.h"
     46 #include "MagickCore/blob-private.h"
     47 #include "MagickCore/cache.h"
     48 #include "MagickCore/cache-private.h"
     49 #include "MagickCore/color-private.h"
     50 #include "MagickCore/composite-private.h"
     51 #include "MagickCore/constitute.h"
     52 #include "MagickCore/exception.h"
     53 #include "MagickCore/exception-private.h"
     54 #include "MagickCore/geometry.h"
     55 #include "MagickCore/memory_.h"
     56 #include "MagickCore/memory-private.h"
     57 #include "MagickCore/pixel.h"
     58 #include "MagickCore/pixel-accessor.h"
     59 #include "MagickCore/quantum.h"
     60 #include "MagickCore/quantum-private.h"
     61 #include "MagickCore/semaphore.h"
     62 #include "MagickCore/stream.h"
     63 #include "MagickCore/stream-private.h"
     64 #include "MagickCore/string_.h"
     65 
     66 /*
     68   Typedef declaractions.
     69 */
     70 struct _StreamInfo
     71 {
     72   const ImageInfo
     73     *image_info;
     74 
     75   const Image
     76     *image;
     77 
     78   Image
     79     *stream;
     80 
     81   QuantumInfo
     82     *quantum_info;
     83 
     84   char
     85     *map;
     86 
     87   StorageType
     88     storage_type;
     89 
     90   unsigned char
     91     *pixels;
     92 
     93   RectangleInfo
     94     extract_info;
     95 
     96   ssize_t
     97     y;
     98 
     99   ExceptionInfo
    100     *exception;
    101 
    102   const void
    103     *client_data;
    104 
    105   size_t
    106     signature;
    107 };
    108 
    109 /*
    111   Declare pixel cache interfaces.
    112 */
    113 #if defined(__cplusplus) || defined(c_plusplus)
    114 extern "C" {
    115 #endif
    116 
    117 static const Quantum
    118   *GetVirtualPixelStream(const Image *,const VirtualPixelMethod,const ssize_t,
    119     const ssize_t,const size_t,const size_t,ExceptionInfo *);
    120 
    121 static MagickBooleanType
    122   StreamImagePixels(const StreamInfo *,const Image *,ExceptionInfo *),
    123   SyncAuthenticPixelsStream(Image *,ExceptionInfo *);
    124 
    125 static Quantum
    126   *QueueAuthenticPixelsStream(Image *,const ssize_t,const ssize_t,const size_t,
    127     const size_t,ExceptionInfo *);
    128 
    129 #if defined(__cplusplus) || defined(c_plusplus)
    130 }
    131 #endif
    132 
    133 /*
    135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    136 %                                                                             %
    137 %                                                                             %
    138 %                                                                             %
    139 +   A c q u i r e S t r e a m I n f o                                         %
    140 %                                                                             %
    141 %                                                                             %
    142 %                                                                             %
    143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    144 %
    145 %  AcquireStreamInfo() allocates the StreamInfo structure.
    146 %
    147 %  The format of the AcquireStreamInfo method is:
    148 %
    149 %      StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
    150 %        ExceptionInfo *exception)
    151 %
    152 %  A description of each parameter follows:
    153 %
    154 %    o image_info: the image info.
    155 %
    156 %    o exception: return any errors or warnings in this structure.
    157 %
    158 */
    159 MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
    160   ExceptionInfo *exception)
    161 {
    162   StreamInfo
    163     *stream_info;
    164 
    165   stream_info=(StreamInfo *) AcquireMagickMemory(sizeof(*stream_info));
    166   if (stream_info == (StreamInfo *) NULL)
    167     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
    168   (void) ResetMagickMemory(stream_info,0,sizeof(*stream_info));
    169   stream_info->pixels=(unsigned char *) MagickAssumeAligned(
    170     AcquireAlignedMemory(1,sizeof(*stream_info->pixels)));
    171   if (stream_info->pixels == (unsigned char *) NULL)
    172     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
    173   stream_info->map=ConstantString("RGB");
    174   stream_info->storage_type=CharPixel;
    175   stream_info->stream=AcquireImage(image_info,exception);
    176   stream_info->signature=MagickCoreSignature;
    177   return(stream_info);
    178 }
    179 
    180 /*
    182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    183 %                                                                             %
    184 %                                                                             %
    185 %                                                                             %
    186 +   D e s t r o y P i x e l S t r e a m                                       %
    187 %                                                                             %
    188 %                                                                             %
    189 %                                                                             %
    190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    191 %
    192 %  DestroyPixelStream() deallocates memory associated with the pixel stream.
    193 %
    194 %  The format of the DestroyPixelStream() method is:
    195 %
    196 %      void DestroyPixelStream(Image *image)
    197 %
    198 %  A description of each parameter follows:
    199 %
    200 %    o image: the image.
    201 %
    202 */
    203 
    204 static inline void RelinquishStreamPixels(CacheInfo *cache_info)
    205 {
    206   assert(cache_info != (CacheInfo *) NULL);
    207   if (cache_info->mapped == MagickFalse)
    208     (void) RelinquishAlignedMemory(cache_info->pixels);
    209   else
    210     (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
    211   cache_info->pixels=(Quantum *) NULL;
    212   cache_info->metacontent=(void *) NULL;
    213   cache_info->length=0;
    214   cache_info->mapped=MagickFalse;
    215 }
    216 
    217 static void DestroyPixelStream(Image *image)
    218 {
    219   CacheInfo
    220     *cache_info;
    221 
    222   MagickBooleanType
    223     destroy;
    224 
    225   assert(image != (Image *) NULL);
    226   assert(image->signature == MagickCoreSignature);
    227   if (image->debug != MagickFalse)
    228     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    229   cache_info=(CacheInfo *) image->cache;
    230   assert(cache_info->signature == MagickCoreSignature);
    231   destroy=MagickFalse;
    232   LockSemaphoreInfo(cache_info->semaphore);
    233   cache_info->reference_count--;
    234   if (cache_info->reference_count == 0)
    235     destroy=MagickTrue;
    236   UnlockSemaphoreInfo(cache_info->semaphore);
    237   if (destroy == MagickFalse)
    238     return;
    239   RelinquishStreamPixels(cache_info);
    240   if (cache_info->nexus_info != (NexusInfo **) NULL)
    241     cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
    242       cache_info->number_threads);
    243   if (cache_info->file_semaphore != (SemaphoreInfo *) NULL)
    244     RelinquishSemaphoreInfo(&cache_info->file_semaphore);
    245   if (cache_info->semaphore != (SemaphoreInfo *) NULL)
    246     RelinquishSemaphoreInfo(&cache_info->semaphore);
    247   cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
    248 }
    249 
    250 /*
    252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    253 %                                                                             %
    254 %                                                                             %
    255 %                                                                             %
    256 +   D e s t r o y S t r e a m I n f o                                         %
    257 %                                                                             %
    258 %                                                                             %
    259 %                                                                             %
    260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    261 %
    262 %  DestroyStreamInfo() destroys memory associated with the StreamInfo
    263 %  structure.
    264 %
    265 %  The format of the DestroyStreamInfo method is:
    266 %
    267 %      StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
    268 %
    269 %  A description of each parameter follows:
    270 %
    271 %    o stream_info: the stream info.
    272 %
    273 */
    274 MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
    275 {
    276   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
    277   assert(stream_info != (StreamInfo *) NULL);
    278   assert(stream_info->signature == MagickCoreSignature);
    279   if (stream_info->map != (char *) NULL)
    280     stream_info->map=DestroyString(stream_info->map);
    281   if (stream_info->pixels != (unsigned char *) NULL)
    282     stream_info->pixels=(unsigned char *) RelinquishAlignedMemory(
    283       stream_info->pixels);
    284   if (stream_info->stream != (Image *) NULL)
    285     {
    286       (void) CloseBlob(stream_info->stream);
    287       stream_info->stream=DestroyImage(stream_info->stream);
    288     }
    289   if (stream_info->quantum_info != (QuantumInfo *) NULL)
    290     stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
    291   stream_info->signature=(~MagickCoreSignature);
    292   stream_info=(StreamInfo *) RelinquishMagickMemory(stream_info);
    293   return(stream_info);
    294 }
    295 
    296 /*
    298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    299 %                                                                             %
    300 %                                                                             %
    301 %                                                                             %
    302 +   G e t A u t h e n t i c M e t a c o n t e n t F r o m S t r e a m         %
    303 %                                                                             %
    304 %                                                                             %
    305 %                                                                             %
    306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    307 %
    308 %  GetAuthenticMetacontentFromStream() returns the metacontent corresponding
    309 %  with the last call to QueueAuthenticPixelsStream() or
    310 %  GetAuthenticPixelsStream().
    311 %
    312 %  The format of the GetAuthenticMetacontentFromStream() method is:
    313 %
    314 %      void *GetAuthenticMetacontentFromStream(const Image *image)
    315 %
    316 %  A description of each parameter follows:
    317 %
    318 %    o image: the image.
    319 %
    320 */
    321 static void *GetAuthenticMetacontentFromStream(const Image *image)
    322 {
    323   CacheInfo
    324     *cache_info;
    325 
    326   assert(image != (Image *) NULL);
    327   assert(image->signature == MagickCoreSignature);
    328   if (image->debug != MagickFalse)
    329     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    330   cache_info=(CacheInfo *) image->cache;
    331   assert(cache_info->signature == MagickCoreSignature);
    332   return(cache_info->metacontent);
    333 }
    334 
    335 /*
    337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    338 %                                                                             %
    339 %                                                                             %
    340 %                                                                             %
    341 +   G e t A u t h e n t i c P i x e l S t r e a m                             %
    342 %                                                                             %
    343 %                                                                             %
    344 %                                                                             %
    345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    346 %
    347 %  GetAuthenticPixelsStream() gets pixels from the in-memory or disk pixel
    348 %  cache as defined by the geometry parameters.   A pointer to the pixels is
    349 %  returned if the pixels are transferred, otherwise a NULL is returned.  For
    350 %  streams this method is a no-op.
    351 %
    352 %  The format of the GetAuthenticPixelsStream() method is:
    353 %
    354 %      Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
    355 %        const ssize_t y,const size_t columns,const size_t rows,
    356 %        ExceptionInfo *exception)
    357 %
    358 %  A description of each parameter follows:
    359 %
    360 %    o image: the image.
    361 %
    362 %    o x,y,columns,rows:  These values define the perimeter of a region of
    363 %      pixels.
    364 %
    365 %    o exception: return any errors or warnings in this structure.
    366 %
    367 */
    368 static Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
    369   const ssize_t y,const size_t columns,const size_t rows,
    370   ExceptionInfo *exception)
    371 {
    372   Quantum
    373     *pixels;
    374 
    375   assert(image != (Image *) NULL);
    376   assert(image->signature == MagickCoreSignature);
    377   if (image->debug != MagickFalse)
    378     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    379   pixels=QueueAuthenticPixelsStream(image,x,y,columns,rows,exception);
    380   return(pixels);
    381 }
    382 
    383 /*
    385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    386 %                                                                             %
    387 %                                                                             %
    388 %                                                                             %
    389 +   G e t A u t h e n t i c P i x e l F r o m S t e a m                       %
    390 %                                                                             %
    391 %                                                                             %
    392 %                                                                             %
    393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    394 %
    395 %  GetAuthenticPixelsFromStream() returns the pixels associated with the last
    396 %  call to QueueAuthenticPixelsStream() or GetAuthenticPixelsStream().
    397 %
    398 %  The format of the GetAuthenticPixelsFromStream() method is:
    399 %
    400 %      Quantum *GetAuthenticPixelsFromStream(const Image image)
    401 %
    402 %  A description of each parameter follows:
    403 %
    404 %    o image: the image.
    405 %
    406 */
    407 static Quantum *GetAuthenticPixelsFromStream(const Image *image)
    408 {
    409   CacheInfo
    410     *cache_info;
    411 
    412   assert(image != (Image *) NULL);
    413   assert(image->signature == MagickCoreSignature);
    414   if (image->debug != MagickFalse)
    415     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    416   cache_info=(CacheInfo *) image->cache;
    417   assert(cache_info->signature == MagickCoreSignature);
    418   return(cache_info->pixels);
    419 }
    420 
    421 /*
    423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    424 %                                                                             %
    425 %                                                                             %
    426 %                                                                             %
    427 +   G e t O n e A u t h e n t i c P i x e l F r o m S t r e a m               %
    428 %                                                                             %
    429 %                                                                             %
    430 %                                                                             %
    431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    432 %
    433 %  GetOneAuthenticPixelFromStream() returns a single pixel at the specified
    434 %  (x,y) location.  The image background color is returned if an error occurs.
    435 %
    436 %  The format of the GetOneAuthenticPixelFromStream() method is:
    437 %
    438 %      MagickBooleanType GetOneAuthenticPixelFromStream(const Image image,
    439 %        const ssize_t x,const ssize_t y,Quantum *pixel,
    440 %        ExceptionInfo *exception)
    441 %
    442 %  A description of each parameter follows:
    443 %
    444 %    o image: the image.
    445 %
    446 %    o pixel: return a pixel at the specified (x,y) location.
    447 %
    448 %    o x,y:  These values define the location of the pixel to return.
    449 %
    450 %    o exception: return any errors or warnings in this structure.
    451 %
    452 */
    453 static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
    454   const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
    455 {
    456   register Quantum
    457     *p;
    458 
    459   register ssize_t
    460     i;
    461 
    462   assert(image != (Image *) NULL);
    463   assert(image->signature == MagickCoreSignature);
    464   (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
    465   p=GetAuthenticPixelsStream(image,x,y,1,1,exception);
    466   if (p == (Quantum *) NULL)
    467     {
    468       pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
    469       pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
    470       pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
    471       pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
    472       pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
    473       return(MagickFalse);
    474     }
    475   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
    476   {
    477     PixelChannel channel=GetPixelChannelChannel(image,i);
    478     pixel[channel]=p[i];
    479   }
    480   return(MagickTrue);
    481 }
    482 
    483 /*
    485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    486 %                                                                             %
    487 %                                                                             %
    488 %                                                                             %
    489 +   G e t O n e V i r t u a l P i x e l F r o m S t r e a m                   %
    490 %                                                                             %
    491 %                                                                             %
    492 %                                                                             %
    493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    494 %
    495 %  GetOneVirtualPixelFromStream() returns a single pixel at the specified
    496 %  (x.y) location.  The image background color is returned if an error occurs.
    497 %
    498 %  The format of the GetOneVirtualPixelFromStream() method is:
    499 %
    500 %      MagickBooleanType GetOneVirtualPixelFromStream(const Image image,
    501 %        const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
    502 %        const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
    503 %
    504 %  A description of each parameter follows:
    505 %
    506 %    o image: the image.
    507 %
    508 %    o virtual_pixel_method: the virtual pixel method.
    509 %
    510 %    o x,y:  These values define the location of the pixel to return.
    511 %
    512 %    o pixel: return a pixel at the specified (x,y) location.
    513 %
    514 %    o exception: return any errors or warnings in this structure.
    515 %
    516 */
    517 static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
    518   const VirtualPixelMethod virtual_pixel_method,const ssize_t x,const ssize_t y,
    519   Quantum *pixel,ExceptionInfo *exception)
    520 {
    521   const Quantum
    522     *p;
    523 
    524   register ssize_t
    525     i;
    526 
    527   assert(image != (Image *) NULL);
    528   assert(image->signature == MagickCoreSignature);
    529   (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
    530   p=GetVirtualPixelStream(image,virtual_pixel_method,x,y,1,1,exception);
    531   if (p == (const Quantum *) NULL)
    532     {
    533       pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
    534       pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
    535       pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
    536       pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
    537       pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
    538       return(MagickFalse);
    539     }
    540   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
    541   {
    542     PixelChannel channel=GetPixelChannelChannel(image,i);
    543     pixel[channel]=p[i];
    544   }
    545   return(MagickTrue);
    546 }
    547 
    548 /*
    550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    551 %                                                                             %
    552 %                                                                             %
    553 %                                                                             %
    554 +   G e t S t r e a m I n f o C l i e n t D a t a                             %
    555 %                                                                             %
    556 %                                                                             %
    557 %                                                                             %
    558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    559 %
    560 %  GetStreamInfoClientData() gets the stream info client data.
    561 %
    562 %  The format of the GetStreamInfoClientData method is:
    563 %
    564 %      const void *GetStreamInfoClientData(StreamInfo *stream_info)
    565 %
    566 %  A description of each parameter follows:
    567 %
    568 %    o stream_info: the stream info.
    569 %
    570 */
    571 MagickPrivate const void *GetStreamInfoClientData(StreamInfo *stream_info)
    572 {
    573   assert(stream_info != (StreamInfo *) NULL);
    574   assert(stream_info->signature == MagickCoreSignature);
    575   return(stream_info->client_data);
    576 }
    577 
    578 /*
    580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    581 %                                                                             %
    582 %                                                                             %
    583 %                                                                             %
    584 +   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                      %
    585 %                                                                             %
    586 %                                                                             %
    587 %                                                                             %
    588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    589 %
    590 %  GetVirtualPixelsStream() returns the pixels associated with the last
    591 %  call to QueueAuthenticPixelsStream() or GetVirtualPixelStream().
    592 %
    593 %  The format of the GetVirtualPixelsStream() method is:
    594 %
    595 %      const Quantum *GetVirtualPixelsStream(const Image *image)
    596 %
    597 %  A description of each parameter follows:
    598 %
    599 %    o pixels: return the pixels associated corresponding with the last call to
    600 %      QueueAuthenticPixelsStream() or GetVirtualPixelStream().
    601 %
    602 %    o image: the image.
    603 %
    604 */
    605 static const Quantum *GetVirtualPixelsStream(const Image *image)
    606 {
    607   CacheInfo
    608     *cache_info;
    609 
    610   assert(image != (Image *) NULL);
    611   assert(image->signature == MagickCoreSignature);
    612   if (image->debug != MagickFalse)
    613     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    614   cache_info=(CacheInfo *) image->cache;
    615   assert(cache_info->signature == MagickCoreSignature);
    616   return(cache_info->pixels);
    617 }
    618 
    619 /*
    621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    622 %                                                                             %
    623 %                                                                             %
    624 %                                                                             %
    625 +   G e t V i r t u a l I n d e x e s F r o m S t r e a m                     %
    626 %                                                                             %
    627 %                                                                             %
    628 %                                                                             %
    629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    630 %
    631 %  GetVirtualMetacontentFromStream() returns the associated pixel channels
    632 %  corresponding with the last call to QueueAuthenticPixelsStream() or
    633 %  GetVirtualPixelStream().
    634 %
    635 %  The format of the GetVirtualMetacontentFromStream() method is:
    636 %
    637 %      const void *GetVirtualMetacontentFromStream(const Image *image)
    638 %
    639 %  A description of each parameter follows:
    640 %
    641 %    o image: the image.
    642 %
    643 */
    644 static const void *GetVirtualMetacontentFromStream(const Image *image)
    645 {
    646   CacheInfo
    647     *cache_info;
    648 
    649   assert(image != (Image *) NULL);
    650   assert(image->signature == MagickCoreSignature);
    651   if (image->debug != MagickFalse)
    652     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    653   cache_info=(CacheInfo *) image->cache;
    654   assert(cache_info->signature == MagickCoreSignature);
    655   return(cache_info->metacontent);
    656 }
    657 
    658 /*
    660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    661 %                                                                             %
    662 %                                                                             %
    663 %                                                                             %
    664 +   G e t V i r t u a l P i x e l S t r e a m                                 %
    665 %                                                                             %
    666 %                                                                             %
    667 %                                                                             %
    668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    669 %
    670 %  GetVirtualPixelStream() gets pixels from the in-memory or disk pixel cache as
    671 %  defined by the geometry parameters.   A pointer to the pixels is returned if
    672 %  the pixels are transferred, otherwise a NULL is returned.  For streams this
    673 %  method is a no-op.
    674 %
    675 %  The format of the GetVirtualPixelStream() method is:
    676 %
    677 %      const Quantum *GetVirtualPixelStream(const Image *image,
    678 %        const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
    679 %        const ssize_t y,const size_t columns,const size_t rows,
    680 %        ExceptionInfo *exception)
    681 %
    682 %  A description of each parameter follows:
    683 %
    684 %    o image: the image.
    685 %
    686 %    o virtual_pixel_method: the virtual pixel method.
    687 %
    688 %    o x,y,columns,rows:  These values define the perimeter of a region of
    689 %      pixels.
    690 %
    691 %    o exception: return any errors or warnings in this structure.
    692 %
    693 */
    694 
    695 static inline MagickBooleanType AcquireStreamPixels(CacheInfo *cache_info,
    696   ExceptionInfo *exception)
    697 {
    698   if (cache_info->length != (MagickSizeType) ((size_t) cache_info->length))
    699     return(MagickFalse);
    700   cache_info->mapped=MagickFalse;
    701   cache_info->pixels=(Quantum *) AcquireAlignedMemory(1,(size_t)
    702     cache_info->length);
    703   if (cache_info->pixels == (Quantum *) NULL)
    704     {
    705       cache_info->mapped=MagickTrue;
    706       cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
    707         cache_info->length);
    708     }
    709   if (cache_info->pixels == (Quantum *) NULL)
    710     {
    711       (void) ThrowMagickException(exception,GetMagickModule(),
    712         ResourceLimitError,"MemoryAllocationFailed","`%s'",
    713         cache_info->filename);
    714       return(MagickFalse);
    715     }
    716   return(MagickTrue);
    717 }
    718 
    719 static const Quantum *GetVirtualPixelStream(const Image *image,
    720   const VirtualPixelMethod magick_unused(virtual_pixel_method),const ssize_t x,
    721   const ssize_t y,const size_t columns,const size_t rows,
    722   ExceptionInfo *exception)
    723 {
    724   CacheInfo
    725     *cache_info;
    726 
    727   MagickBooleanType
    728     status;
    729 
    730   MagickSizeType
    731     number_pixels;
    732 
    733   size_t
    734     length;
    735 
    736   magick_unreferenced(virtual_pixel_method);
    737 
    738   /*
    739     Validate pixel cache geometry.
    740   */
    741   assert(image != (const Image *) NULL);
    742   assert(image->signature == MagickCoreSignature);
    743   if (image->debug != MagickFalse)
    744     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    745   if ((x < 0) || (y < 0) ||
    746       ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
    747       ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
    748       (columns == 0) || (rows == 0))
    749     {
    750       (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
    751         "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
    752       return((Quantum *) NULL);
    753     }
    754   cache_info=(CacheInfo *) image->cache;
    755   assert(cache_info->signature == MagickCoreSignature);
    756   /*
    757     Pixels are stored in a temporary buffer until they are synced to the cache.
    758   */
    759   number_pixels=(MagickSizeType) columns*rows;
    760   length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
    761   if (cache_info->number_channels == 0)
    762     length=number_pixels*sizeof(Quantum);
    763   if (cache_info->metacontent_extent != 0)
    764     length+=number_pixels*cache_info->metacontent_extent;
    765   if (cache_info->pixels == (Quantum *) NULL)
    766     {
    767       cache_info->length=length;
    768       status=AcquireStreamPixels(cache_info,exception);
    769       if (status == MagickFalse)
    770         {
    771           cache_info->length=0;
    772           return((Quantum *) NULL);
    773         }
    774     }
    775   else
    776     if (cache_info->length < length)
    777       {
    778         RelinquishStreamPixels(cache_info);
    779         cache_info->length=length;
    780         status=AcquireStreamPixels(cache_info,exception);
    781         if (status == MagickFalse)
    782           {
    783             cache_info->length=0;
    784             return((Quantum *) NULL);
    785           }
    786       }
    787   cache_info->metacontent=(void *) NULL;
    788   if (cache_info->metacontent_extent != 0)
    789     cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
    790       cache_info->number_channels);
    791   return(cache_info->pixels);
    792 }
    793 
    794 /*
    796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    797 %                                                                             %
    798 %                                                                             %
    799 %                                                                             %
    800 +   O p e n S t r e a m                                                       %
    801 %                                                                             %
    802 %                                                                             %
    803 %                                                                             %
    804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    805 %
    806 %  OpenStream() opens a stream for writing by the StreamImage() method.
    807 %
    808 %  The format of the OpenStream method is:
    809 %
    810 %       MagickBooleanType OpenStream(const ImageInfo *image_info,
    811 %        StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
    812 %
    813 %  A description of each parameter follows:
    814 %
    815 %    o image_info: the image info.
    816 %
    817 %    o stream_info: the stream info.
    818 %
    819 %    o filename: the stream filename.
    820 %
    821 %    o exception: return any errors or warnings in this structure.
    822 %
    823 */
    824 MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
    825   StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
    826 {
    827   MagickBooleanType
    828     status;
    829 
    830   (void) CopyMagickString(stream_info->stream->filename,filename,MagickPathExtent);
    831   status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
    832   return(status);
    833 }
    834 
    835 /*
    837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    838 %                                                                             %
    839 %                                                                             %
    840 %                                                                             %
    841 +   Q u e u e A u t h e n t i c P i x e l s S t r e a m                       %
    842 %                                                                             %
    843 %                                                                             %
    844 %                                                                             %
    845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    846 %
    847 %  QueueAuthenticPixelsStream() allocates an area to store image pixels as
    848 %  defined by the region rectangle and returns a pointer to the area.  This
    849 %  area is subsequently transferred from the pixel cache with method
    850 %  SyncAuthenticPixelsStream().  A pointer to the pixels is returned if the
    851 %  pixels are transferred, otherwise a NULL is returned.
    852 %
    853 %  The format of the QueueAuthenticPixelsStream() method is:
    854 %
    855 %      Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
    856 %        const ssize_t y,const size_t columns,const size_t rows,
    857 %        ExceptionInfo *exception)
    858 %
    859 %  A description of each parameter follows:
    860 %
    861 %    o image: the image.
    862 %
    863 %    o x,y,columns,rows:  These values define the perimeter of a region of
    864 %      pixels.
    865 %
    866 */
    867 static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
    868   const ssize_t y,const size_t columns,const size_t rows,
    869   ExceptionInfo *exception)
    870 {
    871   CacheInfo
    872     *cache_info;
    873 
    874   MagickBooleanType
    875     status;
    876 
    877   MagickSizeType
    878     number_pixels;
    879 
    880   size_t
    881     length;
    882 
    883   StreamHandler
    884     stream_handler;
    885 
    886   /*
    887     Validate pixel cache geometry.
    888   */
    889   assert(image != (Image *) NULL);
    890   if ((x < 0) || (y < 0) ||
    891       ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
    892       ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
    893       (columns == 0) || (rows == 0))
    894     {
    895       (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
    896         "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
    897       return((Quantum *) NULL);
    898     }
    899   stream_handler=GetBlobStreamHandler(image);
    900   if (stream_handler == (StreamHandler) NULL)
    901     {
    902       (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
    903         "NoStreamHandlerIsDefined","`%s'",image->filename);
    904       return((Quantum *) NULL);
    905     }
    906   cache_info=(CacheInfo *) image->cache;
    907   assert(cache_info->signature == MagickCoreSignature);
    908   if ((image->storage_class != GetPixelCacheStorageClass(image->cache)) ||
    909       (image->colorspace != GetPixelCacheColorspace(image->cache)))
    910     {
    911       if (GetPixelCacheStorageClass(image->cache) == UndefinedClass)
    912         (void) stream_handler(image,(const void *) NULL,(size_t)
    913           cache_info->columns);
    914       cache_info->storage_class=image->storage_class;
    915       cache_info->colorspace=image->colorspace;
    916       cache_info->columns=image->columns;
    917       cache_info->rows=image->rows;
    918       image->cache=cache_info;
    919     }
    920   /*
    921     Pixels are stored in a temporary buffer until they are synced to the cache.
    922   */
    923   cache_info->columns=columns;
    924   cache_info->rows=rows;
    925   number_pixels=(MagickSizeType) columns*rows;
    926   length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
    927   if (cache_info->number_channels == 0)
    928     length=number_pixels*sizeof(Quantum);
    929   if (cache_info->metacontent_extent != 0)
    930     length+=number_pixels*cache_info->metacontent_extent;
    931   if (cache_info->pixels == (Quantum *) NULL)
    932     {
    933       cache_info->length=length;
    934       status=AcquireStreamPixels(cache_info,exception);
    935       if (status == MagickFalse)
    936         {
    937           cache_info->length=0;
    938           return((Quantum *) NULL);
    939         }
    940     }
    941   else
    942     if (cache_info->length < length)
    943       {
    944         RelinquishStreamPixels(cache_info);
    945         cache_info->length=length;
    946         status=AcquireStreamPixels(cache_info,exception);
    947         if (status == MagickFalse)
    948           {
    949             cache_info->length=0;
    950             return((Quantum *) NULL);
    951           }
    952       }
    953   cache_info->metacontent=(void *) NULL;
    954   if (cache_info->metacontent_extent != 0)
    955     cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
    956       cache_info->number_channels);
    957   return(cache_info->pixels);
    958 }
    959 
    960 /*
    962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    963 %                                                                             %
    964 %                                                                             %
    965 %                                                                             %
    966 %   R e a d S t r e a m                                                       %
    967 %                                                                             %
    968 %                                                                             %
    969 %                                                                             %
    970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    971 %
    972 %  ReadStream() makes the image pixels available to a user supplied callback
    973 %  method immediately upon reading a scanline with the ReadImage() method.
    974 %
    975 %  The format of the ReadStream() method is:
    976 %
    977 %      Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
    978 %        ExceptionInfo *exception)
    979 %
    980 %  A description of each parameter follows:
    981 %
    982 %    o image_info: the image info.
    983 %
    984 %    o stream: a callback method.
    985 %
    986 %    o exception: return any errors or warnings in this structure.
    987 %
    988 */
    989 MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
    990   ExceptionInfo *exception)
    991 {
    992   CacheMethods
    993     cache_methods;
    994 
    995   Image
    996     *image;
    997 
    998   ImageInfo
    999     *read_info;
   1000 
   1001   /*
   1002     Stream image pixels.
   1003   */
   1004   assert(image_info != (ImageInfo *) NULL);
   1005   assert(image_info->signature == MagickCoreSignature);
   1006   if (image_info->debug != MagickFalse)
   1007     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   1008       image_info->filename);
   1009   assert(exception != (ExceptionInfo *) NULL);
   1010   assert(exception->signature == MagickCoreSignature);
   1011   read_info=CloneImageInfo(image_info);
   1012   read_info->cache=AcquirePixelCache(0);
   1013   GetPixelCacheMethods(&cache_methods);
   1014   cache_methods.get_virtual_pixel_handler=GetVirtualPixelStream;
   1015   cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
   1016   cache_methods.get_virtual_metacontent_from_handler=
   1017     GetVirtualMetacontentFromStream;
   1018   cache_methods.get_authentic_pixels_handler=GetAuthenticPixelsStream;
   1019   cache_methods.queue_authentic_pixels_handler=QueueAuthenticPixelsStream;
   1020   cache_methods.sync_authentic_pixels_handler=SyncAuthenticPixelsStream;
   1021   cache_methods.get_authentic_pixels_from_handler=GetAuthenticPixelsFromStream;
   1022   cache_methods.get_authentic_metacontent_from_handler=
   1023     GetAuthenticMetacontentFromStream;
   1024   cache_methods.get_one_virtual_pixel_from_handler=GetOneVirtualPixelFromStream;
   1025   cache_methods.get_one_authentic_pixel_from_handler=
   1026     GetOneAuthenticPixelFromStream;
   1027   cache_methods.destroy_pixel_handler=DestroyPixelStream;
   1028   SetPixelCacheMethods(read_info->cache,&cache_methods);
   1029   read_info->stream=stream;
   1030   image=ReadImage(read_info,exception);
   1031   if (image != (Image *) NULL)
   1032     InitializePixelChannelMap(image);
   1033   read_info=DestroyImageInfo(read_info);
   1034   return(image);
   1035 }
   1036 
   1037 /*
   1039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1040 %                                                                             %
   1041 %                                                                             %
   1042 %                                                                             %
   1043 +   S e t S t r e a m I n f o C l i e n t D a t a                             %
   1044 %                                                                             %
   1045 %                                                                             %
   1046 %                                                                             %
   1047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1048 %
   1049 %  SetStreamInfoClientData() sets the stream info client data.
   1050 %
   1051 %  The format of the SetStreamInfoClientData method is:
   1052 %
   1053 %      void SetStreamInfoClientData(StreamInfo *stream_info,
   1054 %        const void *client_data)
   1055 %
   1056 %  A description of each parameter follows:
   1057 %
   1058 %    o stream_info: the stream info.
   1059 %
   1060 %    o client_data: the client data.
   1061 %
   1062 */
   1063 MagickPrivate void SetStreamInfoClientData(StreamInfo *stream_info,
   1064   const void *client_data)
   1065 {
   1066   assert(stream_info != (StreamInfo *) NULL);
   1067   assert(stream_info->signature == MagickCoreSignature);
   1068   stream_info->client_data=client_data;
   1069 }
   1070 
   1071 /*
   1073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1074 %                                                                             %
   1075 %                                                                             %
   1076 %                                                                             %
   1077 +   S e t S t r e a m I n f o M a p                                           %
   1078 %                                                                             %
   1079 %                                                                             %
   1080 %                                                                             %
   1081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1082 %
   1083 %  SetStreamInfoMap() sets the stream info map member.
   1084 %
   1085 %  The format of the SetStreamInfoMap method is:
   1086 %
   1087 %      void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
   1088 %
   1089 %  A description of each parameter follows:
   1090 %
   1091 %    o stream_info: the stream info.
   1092 %
   1093 %    o map: the map.
   1094 %
   1095 */
   1096 MagickExport void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
   1097 {
   1098   assert(stream_info != (StreamInfo *) NULL);
   1099   assert(stream_info->signature == MagickCoreSignature);
   1100   (void) CloneString(&stream_info->map,map);
   1101 }
   1102 
   1103 /*
   1105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1106 %                                                                             %
   1107 %                                                                             %
   1108 %                                                                             %
   1109 +   S e t S t r e a m I n f o S t o r a g e T y p e                           %
   1110 %                                                                             %
   1111 %                                                                             %
   1112 %                                                                             %
   1113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1114 %
   1115 %  SetStreamInfoStorageType() sets the stream info storage type member.
   1116 %
   1117 %  The format of the SetStreamInfoStorageType method is:
   1118 %
   1119 %      void SetStreamInfoStorageType(StreamInfo *stream_info,
   1120 %        const StoreageType *storage_type)
   1121 %
   1122 %  A description of each parameter follows:
   1123 %
   1124 %    o stream_info: the stream info.
   1125 %
   1126 %    o storage_type: the storage type.
   1127 %
   1128 */
   1129 MagickExport void SetStreamInfoStorageType(StreamInfo *stream_info,
   1130   const StorageType storage_type)
   1131 {
   1132   assert(stream_info != (StreamInfo *) NULL);
   1133   assert(stream_info->signature == MagickCoreSignature);
   1134   stream_info->storage_type=storage_type;
   1135 }
   1136 
   1137 /*
   1139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1140 %                                                                             %
   1141 %                                                                             %
   1142 %                                                                             %
   1143 +   S t r e a m I m a g e                                                     %
   1144 %                                                                             %
   1145 %                                                                             %
   1146 %                                                                             %
   1147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1148 %
   1149 %  StreamImage() streams pixels from an image and writes them in a user
   1150 %  defined format and storage type (e.g. RGBA as 8-bit unsigned char).
   1151 %
   1152 %  The format of the StreamImage() method is:
   1153 %
   1154 %      Image *StreamImage(const ImageInfo *image_info,
   1155 %        StreamInfo *stream_info,ExceptionInfo *exception)
   1156 %
   1157 %  A description of each parameter follows:
   1158 %
   1159 %    o image_info: the image info.
   1160 %
   1161 %    o stream_info: the stream info.
   1162 %
   1163 %    o exception: return any errors or warnings in this structure.
   1164 %
   1165 */
   1166 
   1167 #if defined(__cplusplus) || defined(c_plusplus)
   1168 extern "C" {
   1169 #endif
   1170 
   1171 static size_t WriteStreamImage(const Image *image,const void *pixels,
   1172   const size_t columns)
   1173 {
   1174   CacheInfo
   1175     *cache_info;
   1176 
   1177   RectangleInfo
   1178     extract_info;
   1179 
   1180   size_t
   1181     length,
   1182     packet_size;
   1183 
   1184   ssize_t
   1185     count;
   1186 
   1187   StreamInfo
   1188     *stream_info;
   1189 
   1190   (void) pixels;
   1191   stream_info=(StreamInfo *) image->client_data;
   1192   switch (stream_info->storage_type)
   1193   {
   1194     default: packet_size=sizeof(unsigned char); break;
   1195     case CharPixel: packet_size=sizeof(unsigned char); break;
   1196     case DoublePixel: packet_size=sizeof(double); break;
   1197     case FloatPixel: packet_size=sizeof(float); break;
   1198     case LongPixel: packet_size=sizeof(unsigned int); break;
   1199     case LongLongPixel: packet_size=sizeof(MagickSizeType); break;
   1200     case QuantumPixel: packet_size=sizeof(Quantum); break;
   1201     case ShortPixel: packet_size=sizeof(unsigned short); break;
   1202   }
   1203   cache_info=(CacheInfo *) image->cache;
   1204   assert(cache_info->signature == MagickCoreSignature);
   1205   packet_size*=strlen(stream_info->map);
   1206   length=packet_size*cache_info->columns*cache_info->rows;
   1207   if (image != stream_info->image)
   1208     {
   1209       ImageInfo
   1210         *write_info;
   1211 
   1212       /*
   1213         Prepare stream for writing.
   1214       */
   1215       (void) RelinquishAlignedMemory(stream_info->pixels);
   1216       stream_info->pixels=(unsigned char *) AcquireAlignedMemory(1,length);
   1217       if (stream_info->pixels == (unsigned char *) NULL)
   1218         return(0);
   1219       (void) ResetMagickMemory(stream_info->pixels,0,length);
   1220       stream_info->image=image;
   1221       write_info=CloneImageInfo(stream_info->image_info);
   1222       (void) SetImageInfo(write_info,1,stream_info->exception);
   1223       if (write_info->extract != (char *) NULL)
   1224         (void) ParseAbsoluteGeometry(write_info->extract,
   1225           &stream_info->extract_info);
   1226       stream_info->y=0;
   1227       write_info=DestroyImageInfo(write_info);
   1228     }
   1229   extract_info=stream_info->extract_info;
   1230   if ((extract_info.width == 0) || (extract_info.height == 0))
   1231     {
   1232       /*
   1233         Write all pixels to stream.
   1234       */
   1235       (void) StreamImagePixels(stream_info,image,stream_info->exception);
   1236       count=WriteBlob(stream_info->stream,length,stream_info->pixels);
   1237       stream_info->y++;
   1238       return(count == 0 ? 0 : columns);
   1239     }
   1240   if ((stream_info->y < extract_info.y) ||
   1241       (stream_info->y >= (ssize_t) (extract_info.y+extract_info.height)))
   1242     {
   1243       stream_info->y++;
   1244       return(columns);
   1245     }
   1246   /*
   1247     Write a portion of the pixel row to the stream.
   1248   */
   1249   (void) StreamImagePixels(stream_info,image,stream_info->exception);
   1250   length=packet_size*extract_info.width;
   1251   count=WriteBlob(stream_info->stream,length,stream_info->pixels+packet_size*
   1252     extract_info.x);
   1253   stream_info->y++;
   1254   return(count == 0 ? 0 : columns);
   1255 }
   1256 
   1257 #if defined(__cplusplus) || defined(c_plusplus)
   1258 }
   1259 #endif
   1260 
   1261 MagickExport Image *StreamImage(const ImageInfo *image_info,
   1262   StreamInfo *stream_info,ExceptionInfo *exception)
   1263 {
   1264   Image
   1265     *image;
   1266 
   1267   ImageInfo
   1268     *read_info;
   1269 
   1270   assert(image_info != (const ImageInfo *) NULL);
   1271   assert(image_info->signature == MagickCoreSignature);
   1272   if (image_info->debug != MagickFalse)
   1273     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   1274       image_info->filename);
   1275   assert(stream_info != (StreamInfo *) NULL);
   1276   assert(stream_info->signature == MagickCoreSignature);
   1277   assert(exception != (ExceptionInfo *) NULL);
   1278   read_info=CloneImageInfo(image_info);
   1279   stream_info->image_info=image_info;
   1280   stream_info->quantum_info=AcquireQuantumInfo(image_info,(Image *) NULL);
   1281   stream_info->exception=exception;
   1282   read_info->client_data=(void *) stream_info;
   1283   image=ReadStream(read_info,&WriteStreamImage,exception);
   1284   read_info=DestroyImageInfo(read_info);
   1285   stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
   1286   stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
   1287   if (stream_info->quantum_info == (QuantumInfo *) NULL)
   1288     image=DestroyImage(image);
   1289   return(image);
   1290 }
   1291 
   1292 /*
   1294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1295 %                                                                             %
   1296 %                                                                             %
   1297 %                                                                             %
   1298 +   S t r e a m I m a g e P i x e l s                                         %
   1299 %                                                                             %
   1300 %                                                                             %
   1301 %                                                                             %
   1302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1303 %
   1304 %  StreamImagePixels() extracts pixel data from an image and returns it in the
   1305 %  stream_info->pixels structure in the format as defined by
   1306 %  stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
   1307 %
   1308 %  The format of the StreamImagePixels method is:
   1309 %
   1310 %      MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
   1311 %        const Image *image,ExceptionInfo *exception)
   1312 %
   1313 %  A description of each parameter follows:
   1314 %
   1315 %    o stream_info: the stream info.
   1316 %
   1317 %    o image: the image.
   1318 %
   1319 %    o exception: return any errors or warnings in this structure.
   1320 %
   1321 */
   1322 static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
   1323   const Image *image,ExceptionInfo *exception)
   1324 {
   1325   QuantumInfo
   1326     *quantum_info;
   1327 
   1328   QuantumType
   1329     *quantum_map;
   1330 
   1331   register const Quantum
   1332     *p;
   1333 
   1334   register ssize_t
   1335     i,
   1336     x;
   1337 
   1338   size_t
   1339     length;
   1340 
   1341   assert(stream_info != (StreamInfo *) NULL);
   1342   assert(stream_info->signature == MagickCoreSignature);
   1343   assert(image != (Image *) NULL);
   1344   assert(image->signature == MagickCoreSignature);
   1345   if (image->debug != MagickFalse)
   1346     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   1347   length=strlen(stream_info->map);
   1348   quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
   1349   if (quantum_map == (QuantumType *) NULL)
   1350     {
   1351       (void) ThrowMagickException(exception,GetMagickModule(),
   1352         ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
   1353       return(MagickFalse);
   1354     }
   1355   for (i=0; i < (ssize_t) length; i++)
   1356   {
   1357     switch (stream_info->map[i])
   1358     {
   1359       case 'A':
   1360       case 'a':
   1361       {
   1362         quantum_map[i]=AlphaQuantum;
   1363         break;
   1364       }
   1365       case 'B':
   1366       case 'b':
   1367       {
   1368         quantum_map[i]=BlueQuantum;
   1369         break;
   1370       }
   1371       case 'C':
   1372       case 'c':
   1373       {
   1374         quantum_map[i]=CyanQuantum;
   1375         if (image->colorspace == CMYKColorspace)
   1376           break;
   1377         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
   1378         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
   1379           "ColorSeparatedImageRequired","`%s'",stream_info->map);
   1380         return(MagickFalse);
   1381       }
   1382       case 'g':
   1383       case 'G':
   1384       {
   1385         quantum_map[i]=GreenQuantum;
   1386         break;
   1387       }
   1388       case 'I':
   1389       case 'i':
   1390       {
   1391         quantum_map[i]=IndexQuantum;
   1392         break;
   1393       }
   1394       case 'K':
   1395       case 'k':
   1396       {
   1397         quantum_map[i]=BlackQuantum;
   1398         if (image->colorspace == CMYKColorspace)
   1399           break;
   1400         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
   1401         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
   1402           "ColorSeparatedImageRequired","`%s'",stream_info->map);
   1403         return(MagickFalse);
   1404       }
   1405       case 'M':
   1406       case 'm':
   1407       {
   1408         quantum_map[i]=MagentaQuantum;
   1409         if (image->colorspace == CMYKColorspace)
   1410           break;
   1411         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
   1412         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
   1413           "ColorSeparatedImageRequired","`%s'",stream_info->map);
   1414         return(MagickFalse);
   1415       }
   1416       case 'o':
   1417       case 'O':
   1418       {
   1419         quantum_map[i]=OpacityQuantum;
   1420         break;
   1421       }
   1422       case 'P':
   1423       case 'p':
   1424       {
   1425         quantum_map[i]=UndefinedQuantum;
   1426         break;
   1427       }
   1428       case 'R':
   1429       case 'r':
   1430       {
   1431         quantum_map[i]=RedQuantum;
   1432         break;
   1433       }
   1434       case 'Y':
   1435       case 'y':
   1436       {
   1437         quantum_map[i]=YellowQuantum;
   1438         if (image->colorspace == CMYKColorspace)
   1439           break;
   1440         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
   1441         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
   1442           "ColorSeparatedImageRequired","`%s'",stream_info->map);
   1443         return(MagickFalse);
   1444       }
   1445       default:
   1446       {
   1447         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
   1448         (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
   1449           "UnrecognizedPixelMap","`%s'",stream_info->map);
   1450         return(MagickFalse);
   1451       }
   1452     }
   1453   }
   1454   quantum_info=stream_info->quantum_info;
   1455   switch (stream_info->storage_type)
   1456   {
   1457     case CharPixel:
   1458     {
   1459       register unsigned char
   1460         *q;
   1461 
   1462       q=(unsigned char *) stream_info->pixels;
   1463       if (LocaleCompare(stream_info->map,"BGR") == 0)
   1464         {
   1465           p=GetAuthenticPixelQueue(image);
   1466           if (p == (const Quantum *) NULL)
   1467             break;
   1468           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1469           {
   1470             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1471             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1472             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1473             p++;
   1474           }
   1475           break;
   1476         }
   1477       if (LocaleCompare(stream_info->map,"BGRA") == 0)
   1478         {
   1479           p=GetAuthenticPixelQueue(image);
   1480           if (p == (const Quantum *) NULL)
   1481             break;
   1482           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1483           {
   1484             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1485             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1486             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1487             *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
   1488             p++;
   1489           }
   1490           break;
   1491         }
   1492       if (LocaleCompare(stream_info->map,"BGRP") == 0)
   1493         {
   1494           p=GetAuthenticPixelQueue(image);
   1495           if (p == (const Quantum *) NULL)
   1496             break;
   1497           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1498           {
   1499             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1500             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1501             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1502             *q++=ScaleQuantumToChar((Quantum) 0);
   1503             p++;
   1504           }
   1505           break;
   1506         }
   1507       if (LocaleCompare(stream_info->map,"I") == 0)
   1508         {
   1509           p=GetAuthenticPixelQueue(image);
   1510           if (p == (const Quantum *) NULL)
   1511             break;
   1512           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1513           {
   1514             *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
   1515             p++;
   1516           }
   1517           break;
   1518         }
   1519       if (LocaleCompare(stream_info->map,"RGB") == 0)
   1520         {
   1521           p=GetAuthenticPixelQueue(image);
   1522           if (p == (const Quantum *) NULL)
   1523             break;
   1524           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1525           {
   1526             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1527             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1528             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1529             p++;
   1530           }
   1531           break;
   1532         }
   1533       if (LocaleCompare(stream_info->map,"RGBA") == 0)
   1534         {
   1535           p=GetAuthenticPixelQueue(image);
   1536           if (p == (const Quantum *) NULL)
   1537             break;
   1538           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1539           {
   1540             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1541             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1542             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1543             *q++=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
   1544             p++;
   1545           }
   1546           break;
   1547         }
   1548       if (LocaleCompare(stream_info->map,"RGBP") == 0)
   1549         {
   1550           p=GetAuthenticPixelQueue(image);
   1551           if (p == (const Quantum *) NULL)
   1552             break;
   1553           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1554           {
   1555             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1556             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1557             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1558             *q++=ScaleQuantumToChar((Quantum) 0);
   1559             p++;
   1560           }
   1561           break;
   1562         }
   1563       p=GetAuthenticPixelQueue(image);
   1564       if (p == (const Quantum *) NULL)
   1565         break;
   1566       for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1567       {
   1568         for (i=0; i < (ssize_t) length; i++)
   1569         {
   1570           *q=0;
   1571           switch (quantum_map[i])
   1572           {
   1573             case RedQuantum:
   1574             case CyanQuantum:
   1575             {
   1576               *q=ScaleQuantumToChar(GetPixelRed(image,p));
   1577               break;
   1578             }
   1579             case GreenQuantum:
   1580             case MagentaQuantum:
   1581             {
   1582               *q=ScaleQuantumToChar(GetPixelGreen(image,p));
   1583               break;
   1584             }
   1585             case BlueQuantum:
   1586             case YellowQuantum:
   1587             {
   1588               *q=ScaleQuantumToChar(GetPixelBlue(image,p));
   1589               break;
   1590             }
   1591             case AlphaQuantum:
   1592             {
   1593               *q=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
   1594               break;
   1595             }
   1596             case OpacityQuantum:
   1597             {
   1598               *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
   1599               break;
   1600             }
   1601             case BlackQuantum:
   1602             {
   1603               if (image->colorspace == CMYKColorspace)
   1604                 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
   1605               break;
   1606             }
   1607             case IndexQuantum:
   1608             {
   1609               *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
   1610               break;
   1611             }
   1612             default:
   1613               break;
   1614           }
   1615           q++;
   1616         }
   1617         p++;
   1618       }
   1619       break;
   1620     }
   1621     case DoublePixel:
   1622     {
   1623       register double
   1624         *q;
   1625 
   1626       q=(double *) stream_info->pixels;
   1627       if (LocaleCompare(stream_info->map,"BGR") == 0)
   1628         {
   1629           p=GetAuthenticPixelQueue(image);
   1630           if (p == (const Quantum *) NULL)
   1631             break;
   1632           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1633           {
   1634             *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
   1635               quantum_info->scale+quantum_info->minimum);
   1636             *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
   1637               quantum_info->scale+quantum_info->minimum);
   1638             *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
   1639               quantum_info->scale+quantum_info->minimum);
   1640             p++;
   1641           }
   1642           break;
   1643         }
   1644       if (LocaleCompare(stream_info->map,"BGRA") == 0)
   1645         {
   1646           p=GetAuthenticPixelQueue(image);
   1647           if (p == (const Quantum *) NULL)
   1648             break;
   1649           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1650           {
   1651             *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
   1652               quantum_info->scale+quantum_info->minimum);
   1653             *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
   1654               quantum_info->scale+quantum_info->minimum);
   1655             *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
   1656               quantum_info->scale+quantum_info->minimum);
   1657             *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
   1658               quantum_info->scale+quantum_info->minimum);
   1659             p++;
   1660           }
   1661           break;
   1662         }
   1663       if (LocaleCompare(stream_info->map,"BGRP") == 0)
   1664         {
   1665           p=GetAuthenticPixelQueue(image);
   1666           if (p == (const Quantum *) NULL)
   1667             break;
   1668           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1669           {
   1670             *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
   1671               quantum_info->scale+quantum_info->minimum);
   1672             *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
   1673               quantum_info->scale+quantum_info->minimum);
   1674             *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
   1675               quantum_info->scale+quantum_info->minimum);
   1676             *q++=0.0;
   1677             p++;
   1678           }
   1679           break;
   1680         }
   1681       if (LocaleCompare(stream_info->map,"I") == 0)
   1682         {
   1683           p=GetAuthenticPixelQueue(image);
   1684           if (p == (const Quantum *) NULL)
   1685             break;
   1686           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1687           {
   1688             *q++=(double) ((QuantumScale*GetPixelIntensity(image,p))*
   1689               quantum_info->scale+quantum_info->minimum);
   1690             p++;
   1691           }
   1692           break;
   1693         }
   1694       if (LocaleCompare(stream_info->map,"RGB") == 0)
   1695         {
   1696           p=GetAuthenticPixelQueue(image);
   1697           if (p == (const Quantum *) NULL)
   1698             break;
   1699           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1700           {
   1701             *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
   1702               quantum_info->scale+quantum_info->minimum);
   1703             *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
   1704               quantum_info->scale+quantum_info->minimum);
   1705             *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
   1706               quantum_info->scale+quantum_info->minimum);
   1707             p++;
   1708           }
   1709           break;
   1710         }
   1711       if (LocaleCompare(stream_info->map,"RGBA") == 0)
   1712         {
   1713           p=GetAuthenticPixelQueue(image);
   1714           if (p == (const Quantum *) NULL)
   1715             break;
   1716           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1717           {
   1718             *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
   1719               quantum_info->scale+quantum_info->minimum);
   1720             *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
   1721               quantum_info->scale+quantum_info->minimum);
   1722             *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
   1723               quantum_info->scale+quantum_info->minimum);
   1724             *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
   1725               quantum_info->scale+quantum_info->minimum);
   1726             p++;
   1727           }
   1728           break;
   1729         }
   1730       if (LocaleCompare(stream_info->map,"RGBP") == 0)
   1731         {
   1732           p=GetAuthenticPixelQueue(image);
   1733           if (p == (const Quantum *) NULL)
   1734             break;
   1735           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1736           {
   1737             *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
   1738               quantum_info->scale+quantum_info->minimum);
   1739             *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
   1740               quantum_info->scale+quantum_info->minimum);
   1741             *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
   1742               quantum_info->scale+quantum_info->minimum);
   1743             *q++=0.0;
   1744             p++;
   1745           }
   1746           break;
   1747         }
   1748       p=GetAuthenticPixelQueue(image);
   1749       if (p == (const Quantum *) NULL)
   1750         break;
   1751       for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1752       {
   1753         for (i=0; i < (ssize_t) length; i++)
   1754         {
   1755           *q=0;
   1756           switch (quantum_map[i])
   1757           {
   1758             case RedQuantum:
   1759             case CyanQuantum:
   1760             {
   1761               *q=(double) ((QuantumScale*GetPixelRed(image,p))*
   1762                 quantum_info->scale+quantum_info->minimum);
   1763               break;
   1764             }
   1765             case GreenQuantum:
   1766             case MagentaQuantum:
   1767             {
   1768               *q=(double) ((QuantumScale*GetPixelGreen(image,p))*
   1769                 quantum_info->scale+quantum_info->minimum);
   1770               break;
   1771             }
   1772             case BlueQuantum:
   1773             case YellowQuantum:
   1774             {
   1775               *q=(double) ((QuantumScale*GetPixelBlue(image,p))*
   1776                 quantum_info->scale+quantum_info->minimum);
   1777               break;
   1778             }
   1779             case AlphaQuantum:
   1780             {
   1781               *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
   1782                 quantum_info->scale+quantum_info->minimum);
   1783               break;
   1784             }
   1785             case OpacityQuantum:
   1786             {
   1787               *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
   1788                 quantum_info->scale+quantum_info->minimum);
   1789               break;
   1790             }
   1791             case BlackQuantum:
   1792             {
   1793               if (image->colorspace == CMYKColorspace)
   1794                 *q=(double) ((QuantumScale*GetPixelBlack(image,p))*
   1795                   quantum_info->scale+quantum_info->minimum);
   1796               break;
   1797             }
   1798             case IndexQuantum:
   1799             {
   1800               *q=(double) ((QuantumScale*GetPixelIntensity(image,p))*
   1801                 quantum_info->scale+quantum_info->minimum);
   1802               break;
   1803             }
   1804             default:
   1805               *q=0;
   1806           }
   1807           q++;
   1808         }
   1809         p++;
   1810       }
   1811       break;
   1812     }
   1813     case FloatPixel:
   1814     {
   1815       register float
   1816         *q;
   1817 
   1818       q=(float *) stream_info->pixels;
   1819       if (LocaleCompare(stream_info->map,"BGR") == 0)
   1820         {
   1821           p=GetAuthenticPixelQueue(image);
   1822           if (p == (const Quantum *) NULL)
   1823             break;
   1824           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1825           {
   1826             *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
   1827               quantum_info->scale+quantum_info->minimum);
   1828             *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
   1829               quantum_info->scale+quantum_info->minimum);
   1830             *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
   1831               quantum_info->scale+quantum_info->minimum);
   1832             p++;
   1833           }
   1834           break;
   1835         }
   1836       if (LocaleCompare(stream_info->map,"BGRA") == 0)
   1837         {
   1838           p=GetAuthenticPixelQueue(image);
   1839           if (p == (const Quantum *) NULL)
   1840             break;
   1841           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1842           {
   1843             *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
   1844               quantum_info->scale+quantum_info->minimum);
   1845             *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
   1846               quantum_info->scale+quantum_info->minimum);
   1847             *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
   1848               quantum_info->scale+quantum_info->minimum);
   1849             *q++=(float) ((QuantumScale*(Quantum) (GetPixelAlpha(image,p)))*
   1850               quantum_info->scale+quantum_info->minimum);
   1851             p++;
   1852           }
   1853           break;
   1854         }
   1855       if (LocaleCompare(stream_info->map,"BGRP") == 0)
   1856         {
   1857           p=GetAuthenticPixelQueue(image);
   1858           if (p == (const Quantum *) NULL)
   1859             break;
   1860           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1861           {
   1862             *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
   1863               quantum_info->scale+quantum_info->minimum);
   1864             *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
   1865               quantum_info->scale+quantum_info->minimum);
   1866             *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
   1867               quantum_info->scale+quantum_info->minimum);
   1868             *q++=0.0;
   1869             p++;
   1870           }
   1871           break;
   1872         }
   1873       if (LocaleCompare(stream_info->map,"I") == 0)
   1874         {
   1875           p=GetAuthenticPixelQueue(image);
   1876           if (p == (const Quantum *) NULL)
   1877             break;
   1878           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1879           {
   1880             *q++=(float) ((QuantumScale*GetPixelIntensity(image,p))*
   1881               quantum_info->scale+quantum_info->minimum);
   1882             p++;
   1883           }
   1884           break;
   1885         }
   1886       if (LocaleCompare(stream_info->map,"RGB") == 0)
   1887         {
   1888           p=GetAuthenticPixelQueue(image);
   1889           if (p == (const Quantum *) NULL)
   1890             break;
   1891           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1892           {
   1893             *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
   1894               quantum_info->scale+quantum_info->minimum);
   1895             *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
   1896               quantum_info->scale+quantum_info->minimum);
   1897             *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
   1898               quantum_info->scale+quantum_info->minimum);
   1899             p++;
   1900           }
   1901           break;
   1902         }
   1903       if (LocaleCompare(stream_info->map,"RGBA") == 0)
   1904         {
   1905           p=GetAuthenticPixelQueue(image);
   1906           if (p == (const Quantum *) NULL)
   1907             break;
   1908           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1909           {
   1910             *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
   1911               quantum_info->scale+quantum_info->minimum);
   1912             *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
   1913               quantum_info->scale+quantum_info->minimum);
   1914             *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
   1915               quantum_info->scale+quantum_info->minimum);
   1916             *q++=(float) ((QuantumScale*GetPixelAlpha(image,p))*
   1917               quantum_info->scale+quantum_info->minimum);
   1918             p++;
   1919           }
   1920           break;
   1921         }
   1922       if (LocaleCompare(stream_info->map,"RGBP") == 0)
   1923         {
   1924           p=GetAuthenticPixelQueue(image);
   1925           if (p == (const Quantum *) NULL)
   1926             break;
   1927           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1928           {
   1929             *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
   1930               quantum_info->scale+quantum_info->minimum);
   1931             *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
   1932               quantum_info->scale+quantum_info->minimum);
   1933             *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
   1934               quantum_info->scale+quantum_info->minimum);
   1935             *q++=0.0;
   1936             p++;
   1937           }
   1938           break;
   1939         }
   1940       p=GetAuthenticPixelQueue(image);
   1941       if (p == (const Quantum *) NULL)
   1942         break;
   1943       for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   1944       {
   1945         for (i=0; i < (ssize_t) length; i++)
   1946         {
   1947           *q=0;
   1948           switch (quantum_map[i])
   1949           {
   1950             case RedQuantum:
   1951             case CyanQuantum:
   1952             {
   1953               *q=(float) ((QuantumScale*GetPixelRed(image,p))*
   1954                 quantum_info->scale+quantum_info->minimum);
   1955               break;
   1956             }
   1957             case GreenQuantum:
   1958             case MagentaQuantum:
   1959             {
   1960               *q=(float) ((QuantumScale*GetPixelGreen(image,p))*
   1961                 quantum_info->scale+quantum_info->minimum);
   1962               break;
   1963             }
   1964             case BlueQuantum:
   1965             case YellowQuantum:
   1966             {
   1967               *q=(float) ((QuantumScale*GetPixelBlue(image,p))*
   1968                 quantum_info->scale+quantum_info->minimum);
   1969               break;
   1970             }
   1971             case AlphaQuantum:
   1972             {
   1973               *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
   1974                 quantum_info->scale+quantum_info->minimum);
   1975               break;
   1976             }
   1977             case OpacityQuantum:
   1978             {
   1979               *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
   1980                 quantum_info->scale+quantum_info->minimum);
   1981               break;
   1982             }
   1983             case BlackQuantum:
   1984             {
   1985               if (image->colorspace == CMYKColorspace)
   1986                 *q=(float) ((QuantumScale*GetPixelBlack(image,p))*
   1987                   quantum_info->scale+quantum_info->minimum);
   1988               break;
   1989             }
   1990             case IndexQuantum:
   1991             {
   1992               *q=(float) ((QuantumScale*GetPixelIntensity(image,p))*
   1993                 quantum_info->scale+quantum_info->minimum);
   1994               break;
   1995             }
   1996             default:
   1997               *q=0;
   1998           }
   1999           q++;
   2000         }
   2001         p++;
   2002       }
   2003       break;
   2004     }
   2005     case LongPixel:
   2006     {
   2007       register unsigned int
   2008         *q;
   2009 
   2010       q=(unsigned int *) stream_info->pixels;
   2011       if (LocaleCompare(stream_info->map,"BGR") == 0)
   2012         {
   2013           p=GetAuthenticPixelQueue(image);
   2014           if (p == (const Quantum *) NULL)
   2015             break;
   2016           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2017           {
   2018             *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
   2019             *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
   2020             *q++=ScaleQuantumToLong(GetPixelRed(image,p));
   2021             p++;
   2022           }
   2023           break;
   2024         }
   2025       if (LocaleCompare(stream_info->map,"BGRA") == 0)
   2026         {
   2027           p=GetAuthenticPixelQueue(image);
   2028           if (p == (const Quantum *) NULL)
   2029             break;
   2030           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2031           {
   2032             *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
   2033             *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
   2034             *q++=ScaleQuantumToLong(GetPixelRed(image,p));
   2035             *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
   2036             p++;
   2037           }
   2038           break;
   2039         }
   2040       if (LocaleCompare(stream_info->map,"BGRP") == 0)
   2041         {
   2042           p=GetAuthenticPixelQueue(image);
   2043           if (p == (const Quantum *) NULL)
   2044             break;
   2045           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2046           {
   2047             *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
   2048             *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
   2049             *q++=ScaleQuantumToLong(GetPixelRed(image,p));
   2050             *q++=0;
   2051             p++;
   2052           }
   2053           break;
   2054         }
   2055       if (LocaleCompare(stream_info->map,"I") == 0)
   2056         {
   2057           p=GetAuthenticPixelQueue(image);
   2058           if (p == (const Quantum *) NULL)
   2059             break;
   2060           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2061           {
   2062             *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
   2063             p++;
   2064           }
   2065           break;
   2066         }
   2067       if (LocaleCompare(stream_info->map,"RGB") == 0)
   2068         {
   2069           p=GetAuthenticPixelQueue(image);
   2070           if (p == (const Quantum *) NULL)
   2071             break;
   2072           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2073           {
   2074             *q++=ScaleQuantumToLong(GetPixelRed(image,p));
   2075             *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
   2076             *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
   2077             p++;
   2078           }
   2079           break;
   2080         }
   2081       if (LocaleCompare(stream_info->map,"RGBA") == 0)
   2082         {
   2083           p=GetAuthenticPixelQueue(image);
   2084           if (p == (const Quantum *) NULL)
   2085             break;
   2086           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2087           {
   2088             *q++=ScaleQuantumToLong(GetPixelRed(image,p));
   2089             *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
   2090             *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
   2091             *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
   2092             p++;
   2093           }
   2094           break;
   2095         }
   2096       if (LocaleCompare(stream_info->map,"RGBP") == 0)
   2097         {
   2098           p=GetAuthenticPixelQueue(image);
   2099           if (p == (const Quantum *) NULL)
   2100             break;
   2101           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2102           {
   2103             *q++=ScaleQuantumToLong(GetPixelRed(image,p));
   2104             *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
   2105             *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
   2106             *q++=0;
   2107             p++;
   2108           }
   2109           break;
   2110         }
   2111       p=GetAuthenticPixelQueue(image);
   2112       if (p == (const Quantum *) NULL)
   2113         break;
   2114       for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2115       {
   2116         for (i=0; i < (ssize_t) length; i++)
   2117         {
   2118           *q=0;
   2119           switch (quantum_map[i])
   2120           {
   2121             case RedQuantum:
   2122             case CyanQuantum:
   2123             {
   2124               *q=ScaleQuantumToLong(GetPixelRed(image,p));
   2125               break;
   2126             }
   2127             case GreenQuantum:
   2128             case MagentaQuantum:
   2129             {
   2130               *q=ScaleQuantumToLong(GetPixelGreen(image,p));
   2131               break;
   2132             }
   2133             case BlueQuantum:
   2134             case YellowQuantum:
   2135             {
   2136               *q=ScaleQuantumToLong(GetPixelBlue(image,p));
   2137               break;
   2138             }
   2139             case AlphaQuantum:
   2140             {
   2141               *q=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
   2142               break;
   2143             }
   2144             case OpacityQuantum:
   2145             {
   2146               *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
   2147               break;
   2148             }
   2149             case BlackQuantum:
   2150             {
   2151               if (image->colorspace == CMYKColorspace)
   2152                 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
   2153               break;
   2154             }
   2155             case IndexQuantum:
   2156             {
   2157               *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
   2158               break;
   2159             }
   2160             default:
   2161               break;
   2162           }
   2163           q++;
   2164         }
   2165         p++;
   2166       }
   2167       break;
   2168     }
   2169     case LongLongPixel:
   2170     {
   2171       register MagickSizeType
   2172         *q;
   2173 
   2174       q=(MagickSizeType *) stream_info->pixels;
   2175       if (LocaleCompare(stream_info->map,"BGR") == 0)
   2176         {
   2177           p=GetAuthenticPixelQueue(image);
   2178           if (p == (const Quantum *) NULL)
   2179             break;
   2180           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2181           {
   2182             *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
   2183             *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
   2184             *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
   2185             p++;
   2186           }
   2187           break;
   2188         }
   2189       if (LocaleCompare(stream_info->map,"BGRA") == 0)
   2190         {
   2191           p=GetAuthenticPixelQueue(image);
   2192           if (p == (const Quantum *) NULL)
   2193             break;
   2194           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2195           {
   2196             *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
   2197             *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
   2198             *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
   2199             *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
   2200             p++;
   2201           }
   2202           break;
   2203         }
   2204       if (LocaleCompare(stream_info->map,"BGRP") == 0)
   2205         {
   2206           p=GetAuthenticPixelQueue(image);
   2207           if (p == (const Quantum *) NULL)
   2208             break;
   2209           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2210           {
   2211             *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
   2212             *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
   2213             *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
   2214             *q++=0U;
   2215             p++;
   2216           }
   2217           break;
   2218         }
   2219       if (LocaleCompare(stream_info->map,"I") == 0)
   2220         {
   2221           p=GetAuthenticPixelQueue(image);
   2222           if (p == (const Quantum *) NULL)
   2223             break;
   2224           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2225           {
   2226             *q++=ScaleQuantumToLongLong(ClampToQuantum(
   2227               GetPixelIntensity(image,p)));
   2228             p++;
   2229           }
   2230           break;
   2231         }
   2232       if (LocaleCompare(stream_info->map,"RGB") == 0)
   2233         {
   2234           p=GetAuthenticPixelQueue(image);
   2235           if (p == (const Quantum *) NULL)
   2236             break;
   2237           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2238           {
   2239             *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
   2240             *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
   2241             *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
   2242             p++;
   2243           }
   2244           break;
   2245         }
   2246       if (LocaleCompare(stream_info->map,"RGBA") == 0)
   2247         {
   2248           p=GetAuthenticPixelQueue(image);
   2249           if (p == (const Quantum *) NULL)
   2250             break;
   2251           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2252           {
   2253             *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
   2254             *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
   2255             *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
   2256             *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
   2257             p++;
   2258           }
   2259           break;
   2260         }
   2261       if (LocaleCompare(stream_info->map,"RGBP") == 0)
   2262         {
   2263           p=GetAuthenticPixelQueue(image);
   2264           if (p == (const Quantum *) NULL)
   2265             break;
   2266           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2267           {
   2268             *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
   2269             *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
   2270             *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
   2271             *q++=0U;
   2272             p++;
   2273           }
   2274           break;
   2275         }
   2276       p=GetAuthenticPixelQueue(image);
   2277       if (p == (const Quantum *) NULL)
   2278         break;
   2279       for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2280       {
   2281         for (i=0; i < (ssize_t) length; i++)
   2282         {
   2283           *q=0;
   2284           switch (quantum_map[i])
   2285           {
   2286             case RedQuantum:
   2287             case CyanQuantum:
   2288             {
   2289               *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
   2290               break;
   2291             }
   2292             case GreenQuantum:
   2293             case MagentaQuantum:
   2294             {
   2295               *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
   2296               break;
   2297             }
   2298             case BlueQuantum:
   2299             case YellowQuantum:
   2300             {
   2301               *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
   2302               break;
   2303             }
   2304             case AlphaQuantum:
   2305             {
   2306               *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
   2307               break;
   2308             }
   2309             case OpacityQuantum:
   2310             {
   2311               *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
   2312               break;
   2313             }
   2314             case BlackQuantum:
   2315             {
   2316               if (image->colorspace == CMYKColorspace)
   2317                 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
   2318               break;
   2319             }
   2320             case IndexQuantum:
   2321             {
   2322               *q=ScaleQuantumToLongLong(ClampToQuantum(
   2323                 GetPixelIntensity(image,p)));
   2324               break;
   2325             }
   2326             default:
   2327               *q=0;
   2328           }
   2329           q++;
   2330         }
   2331         p++;
   2332       }
   2333       break;
   2334     }
   2335     case QuantumPixel:
   2336     {
   2337       register Quantum
   2338         *q;
   2339 
   2340       q=(Quantum *) stream_info->pixels;
   2341       if (LocaleCompare(stream_info->map,"BGR") == 0)
   2342         {
   2343           p=GetAuthenticPixelQueue(image);
   2344           if (p == (const Quantum *) NULL)
   2345             break;
   2346           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2347           {
   2348             *q++=GetPixelBlue(image,p);
   2349             *q++=GetPixelGreen(image,p);
   2350             *q++=GetPixelRed(image,p);
   2351             p++;
   2352           }
   2353           break;
   2354         }
   2355       if (LocaleCompare(stream_info->map,"BGRA") == 0)
   2356         {
   2357           p=GetAuthenticPixelQueue(image);
   2358           if (p == (const Quantum *) NULL)
   2359             break;
   2360           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2361           {
   2362             *q++=GetPixelBlue(image,p);
   2363             *q++=GetPixelGreen(image,p);
   2364             *q++=GetPixelRed(image,p);
   2365             *q++=GetPixelAlpha(image,p);
   2366             p++;
   2367           }
   2368           break;
   2369         }
   2370       if (LocaleCompare(stream_info->map,"BGRP") == 0)
   2371         {
   2372           p=GetAuthenticPixelQueue(image);
   2373           if (p == (const Quantum *) NULL)
   2374             break;
   2375           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2376           {
   2377             *q++=GetPixelBlue(image,p);
   2378             *q++=GetPixelGreen(image,p);
   2379             *q++=GetPixelRed(image,p);
   2380             *q++=0;
   2381             p++;
   2382           }
   2383           break;
   2384         }
   2385       if (LocaleCompare(stream_info->map,"I") == 0)
   2386         {
   2387           p=GetAuthenticPixelQueue(image);
   2388           if (p == (const Quantum *) NULL)
   2389             break;
   2390           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2391           {
   2392             *q++=ClampToQuantum(GetPixelIntensity(image,p));
   2393             p++;
   2394           }
   2395           break;
   2396         }
   2397       if (LocaleCompare(stream_info->map,"RGB") == 0)
   2398         {
   2399           p=GetAuthenticPixelQueue(image);
   2400           if (p == (const Quantum *) NULL)
   2401             break;
   2402           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2403           {
   2404             *q++=GetPixelRed(image,p);
   2405             *q++=GetPixelGreen(image,p);
   2406             *q++=GetPixelBlue(image,p);
   2407             p++;
   2408           }
   2409           break;
   2410         }
   2411       if (LocaleCompare(stream_info->map,"RGBA") == 0)
   2412         {
   2413           p=GetAuthenticPixelQueue(image);
   2414           if (p == (const Quantum *) NULL)
   2415             break;
   2416           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2417           {
   2418             *q++=GetPixelRed(image,p);
   2419             *q++=GetPixelGreen(image,p);
   2420             *q++=GetPixelBlue(image,p);
   2421             *q++=GetPixelAlpha(image,p);
   2422             p++;
   2423           }
   2424           break;
   2425         }
   2426       if (LocaleCompare(stream_info->map,"RGBP") == 0)
   2427         {
   2428           p=GetAuthenticPixelQueue(image);
   2429           if (p == (const Quantum *) NULL)
   2430             break;
   2431           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2432           {
   2433             *q++=GetPixelRed(image,p);
   2434             *q++=GetPixelGreen(image,p);
   2435             *q++=GetPixelBlue(image,p);
   2436             *q++=0U;
   2437             p++;
   2438           }
   2439           break;
   2440         }
   2441       p=GetAuthenticPixelQueue(image);
   2442       if (p == (const Quantum *) NULL)
   2443         break;
   2444       for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2445       {
   2446         for (i=0; i < (ssize_t) length; i++)
   2447         {
   2448           *q=(Quantum) 0;
   2449           switch (quantum_map[i])
   2450           {
   2451             case RedQuantum:
   2452             case CyanQuantum:
   2453             {
   2454               *q=GetPixelRed(image,p);
   2455               break;
   2456             }
   2457             case GreenQuantum:
   2458             case MagentaQuantum:
   2459             {
   2460               *q=GetPixelGreen(image,p);
   2461               break;
   2462             }
   2463             case BlueQuantum:
   2464             case YellowQuantum:
   2465             {
   2466               *q=GetPixelBlue(image,p);
   2467               break;
   2468             }
   2469             case AlphaQuantum:
   2470             {
   2471               *q=(Quantum) (GetPixelAlpha(image,p));
   2472               break;
   2473             }
   2474             case OpacityQuantum:
   2475             {
   2476               *q=GetPixelAlpha(image,p);
   2477               break;
   2478             }
   2479             case BlackQuantum:
   2480             {
   2481               if (image->colorspace == CMYKColorspace)
   2482                 *q=GetPixelBlack(image,p);
   2483               break;
   2484             }
   2485             case IndexQuantum:
   2486             {
   2487               *q=ClampToQuantum(GetPixelIntensity(image,p));
   2488               break;
   2489             }
   2490             default:
   2491               *q=0;
   2492           }
   2493           q++;
   2494         }
   2495         p++;
   2496       }
   2497       break;
   2498     }
   2499     case ShortPixel:
   2500     {
   2501       register unsigned short
   2502         *q;
   2503 
   2504       q=(unsigned short *) stream_info->pixels;
   2505       if (LocaleCompare(stream_info->map,"BGR") == 0)
   2506         {
   2507           p=GetAuthenticPixelQueue(image);
   2508           if (p == (const Quantum *) NULL)
   2509             break;
   2510           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2511           {
   2512             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
   2513             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
   2514             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
   2515             p++;
   2516           }
   2517           break;
   2518         }
   2519       if (LocaleCompare(stream_info->map,"BGRA") == 0)
   2520         {
   2521           p=GetAuthenticPixelQueue(image);
   2522           if (p == (const Quantum *) NULL)
   2523             break;
   2524           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2525           {
   2526             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
   2527             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
   2528             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
   2529             *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
   2530             p++;
   2531           }
   2532           break;
   2533         }
   2534       if (LocaleCompare(stream_info->map,"BGRP") == 0)
   2535         {
   2536           p=GetAuthenticPixelQueue(image);
   2537             if (p == (const Quantum *) NULL)
   2538             break;
   2539           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2540           {
   2541             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
   2542             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
   2543             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
   2544             *q++=0;
   2545             p++;
   2546           }
   2547           break;
   2548         }
   2549       if (LocaleCompare(stream_info->map,"I") == 0)
   2550         {
   2551           p=GetAuthenticPixelQueue(image);
   2552           if (p == (const Quantum *) NULL)
   2553             break;
   2554           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2555           {
   2556             *q++=ScaleQuantumToShort(ClampToQuantum(
   2557               GetPixelIntensity(image,p)));
   2558             p++;
   2559           }
   2560           break;
   2561         }
   2562       if (LocaleCompare(stream_info->map,"RGB") == 0)
   2563         {
   2564           p=GetAuthenticPixelQueue(image);
   2565           if (p == (const Quantum *) NULL)
   2566             break;
   2567           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2568           {
   2569             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
   2570             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
   2571             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
   2572             p++;
   2573           }
   2574           break;
   2575         }
   2576       if (LocaleCompare(stream_info->map,"RGBA") == 0)
   2577         {
   2578           p=GetAuthenticPixelQueue(image);
   2579           if (p == (const Quantum *) NULL)
   2580             break;
   2581           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2582           {
   2583             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
   2584             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
   2585             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
   2586             *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
   2587             p++;
   2588           }
   2589           break;
   2590         }
   2591       if (LocaleCompare(stream_info->map,"RGBP") == 0)
   2592         {
   2593           p=GetAuthenticPixelQueue(image);
   2594           if (p == (const Quantum *) NULL)
   2595             break;
   2596           for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2597           {
   2598             *q++=ScaleQuantumToShort(GetPixelRed(image,p));
   2599             *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
   2600             *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
   2601             *q++=0;
   2602             p++;
   2603           }
   2604           break;
   2605         }
   2606       p=GetAuthenticPixelQueue(image);
   2607       if (p == (const Quantum *) NULL)
   2608         break;
   2609       for (x=0; x < (ssize_t) GetImageExtent(image); x++)
   2610       {
   2611         for (i=0; i < (ssize_t) length; i++)
   2612         {
   2613           *q=0;
   2614           switch (quantum_map[i])
   2615           {
   2616             case RedQuantum:
   2617             case CyanQuantum:
   2618             {
   2619               *q=ScaleQuantumToShort(GetPixelRed(image,p));
   2620               break;
   2621             }
   2622             case GreenQuantum:
   2623             case MagentaQuantum:
   2624             {
   2625               *q=ScaleQuantumToShort(GetPixelGreen(image,p));
   2626               break;
   2627             }
   2628             case BlueQuantum:
   2629             case YellowQuantum:
   2630             {
   2631               *q=ScaleQuantumToShort(GetPixelBlue(image,p));
   2632               break;
   2633             }
   2634             case AlphaQuantum:
   2635             {
   2636               *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
   2637               break;
   2638             }
   2639             case OpacityQuantum:
   2640             {
   2641               *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
   2642               break;
   2643             }
   2644             case BlackQuantum:
   2645             {
   2646               if (image->colorspace == CMYKColorspace)
   2647                 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
   2648               break;
   2649             }
   2650             case IndexQuantum:
   2651             {
   2652               *q=ScaleQuantumToShort(ClampToQuantum(
   2653                 GetPixelIntensity(image,p)));
   2654               break;
   2655             }
   2656             default:
   2657               break;
   2658           }
   2659           q++;
   2660         }
   2661         p++;
   2662       }
   2663       break;
   2664     }
   2665     default:
   2666     {
   2667       quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
   2668       (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
   2669         "UnrecognizedPixelMap","`%s'",stream_info->map);
   2670       break;
   2671     }
   2672   }
   2673   quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
   2674   return(MagickTrue);
   2675 }
   2676 
   2677 /*
   2679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2680 %                                                                             %
   2681 %                                                                             %
   2682 %                                                                             %
   2683 +   S y n c A u t h e n t i c P i x e l s S t r e a m                         %
   2684 %                                                                             %
   2685 %                                                                             %
   2686 %                                                                             %
   2687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2688 %
   2689 %  SyncAuthenticPixelsStream() calls the user supplied callback method with
   2690 %  the latest stream of pixels.
   2691 %
   2692 %  The format of the SyncAuthenticPixelsStream method is:
   2693 %
   2694 %      MagickBooleanType SyncAuthenticPixelsStream(Image *image,
   2695 %        ExceptionInfo *exception)
   2696 %
   2697 %  A description of each parameter follows:
   2698 %
   2699 %    o image: the image.
   2700 %
   2701 %    o exception: return any errors or warnings in this structure.
   2702 %
   2703 */
   2704 static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
   2705   ExceptionInfo *exception)
   2706 {
   2707   CacheInfo
   2708     *cache_info;
   2709 
   2710   size_t
   2711     length;
   2712 
   2713   StreamHandler
   2714     stream_handler;
   2715 
   2716   assert(image != (Image *) NULL);
   2717   assert(image->signature == MagickCoreSignature);
   2718   if (image->debug != MagickFalse)
   2719     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   2720   cache_info=(CacheInfo *) image->cache;
   2721   assert(cache_info->signature == MagickCoreSignature);
   2722   stream_handler=GetBlobStreamHandler(image);
   2723   if (stream_handler == (StreamHandler) NULL)
   2724     {
   2725       (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
   2726         "NoStreamHandlerIsDefined","`%s'",image->filename);
   2727       return(MagickFalse);
   2728     }
   2729   length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
   2730   return(length == cache_info->columns ? MagickTrue : MagickFalse);
   2731 }
   2732 
   2733 /*
   2735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2736 %                                                                             %
   2737 %                                                                             %
   2738 %                                                                             %
   2739 %   W r i t e S t r e a m                                                     %
   2740 %                                                                             %
   2741 %                                                                             %
   2742 %                                                                             %
   2743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2744 %
   2745 %  WriteStream() makes the image pixels available to a user supplied callback
   2746 %  method immediately upon writing pixel data with the WriteImage() method.
   2747 %
   2748 %  The format of the WriteStream() method is:
   2749 %
   2750 %      MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
   2751 %        StreamHandler stream,ExceptionInfo *exception)
   2752 %
   2753 %  A description of each parameter follows:
   2754 %
   2755 %    o image_info: the image info.
   2756 %
   2757 %    o stream: A callback method.
   2758 %
   2759 %    o exception: return any errors or warnings in this structure.
   2760 %
   2761 */
   2762 MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
   2763   Image *image,StreamHandler stream,ExceptionInfo *exception)
   2764 {
   2765   ImageInfo
   2766     *write_info;
   2767 
   2768   MagickBooleanType
   2769     status;
   2770 
   2771   assert(image_info != (ImageInfo *) NULL);
   2772   assert(image_info->signature == MagickCoreSignature);
   2773   if (image_info->debug != MagickFalse)
   2774     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   2775       image_info->filename);
   2776   assert(image != (Image *) NULL);
   2777   assert(image->signature == MagickCoreSignature);
   2778   write_info=CloneImageInfo(image_info);
   2779   *write_info->magick='\0';
   2780   write_info->stream=stream;
   2781   status=WriteImage(write_info,image,exception);
   2782   write_info=DestroyImageInfo(write_info);
   2783   return(status);
   2784 }
   2785