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