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