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