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