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