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