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