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