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