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