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