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