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