MagickCore 7.1.2
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
81 QuantumInfo
82 *quantum_info;
83
84 char
85 *map;
86
87 StorageType
88 storage_type;
89
90 unsigned char
91 *pixels;
92
93 RectangleInfo
94 extract_info;
95
96 ssize_t
97 y;
98
99 ExceptionInfo
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{
160 StreamInfo
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{
220 CacheInfo
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{
323 CacheInfo
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{
407 CacheInfo
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{
601 CacheInfo
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{
639 CacheInfo
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{
711 CacheInfo
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+=(size_t) 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{
888 CacheInfo
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+=(size_t) 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{
1013 CacheMethods
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
1221 RectangleInfo
1222 extract_info;
1223
1224 size_t
1225 length,
1226 packet_size;
1227
1228 ssize_t
1229 count;
1230
1231 StreamInfo
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 if (stream_info->quantum_info == (QuantumInfo *) NULL)
1325 stream_info->quantum_info=AcquireQuantumInfo(image_info,(Image *) NULL);
1326 if (stream_info->quantum_info == (QuantumInfo *) NULL)
1327 {
1328 read_info=DestroyImageInfo(read_info);
1329 return((Image *) NULL);
1330 }
1331 stream_info->exception=exception;
1332 read_info->client_data=(void *) stream_info;
1333 image=ReadStream(read_info,&WriteStreamImage,exception);
1334 read_info=DestroyImageInfo(read_info);
1335 stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
1336 stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
1337 if (stream_info->quantum_info == (QuantumInfo *) NULL)
1338 image=DestroyImage(image);
1339 return(image);
1340}
1341
1342/*
1343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1344% %
1345% %
1346% %
1347+ S t r e a m I m a g e P i x e l s %
1348% %
1349% %
1350% %
1351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1352%
1353% StreamImagePixels() extracts pixel data from an image and returns it in the
1354% stream_info->pixels structure in the format as defined by
1355% stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
1356%
1357% The format of the StreamImagePixels method is:
1358%
1359% MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1360% const Image *image,ExceptionInfo *exception)
1361%
1362% A description of each parameter follows:
1363%
1364% o stream_info: the stream info.
1365%
1366% o image: the image.
1367%
1368% o exception: return any errors or warnings in this structure.
1369%
1370*/
1371static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1372 const Image *image,ExceptionInfo *exception)
1373{
1374 QuantumInfo
1375 *quantum_info;
1376
1377 QuantumType
1378 *quantum_map;
1379
1380 const Quantum
1381 *p;
1382
1383 ssize_t
1384 i,
1385 x;
1386
1387 size_t
1388 length;
1389
1390 assert(stream_info != (StreamInfo *) NULL);
1391 assert(stream_info->signature == MagickCoreSignature);
1392 assert(image != (Image *) NULL);
1393 assert(image->signature == MagickCoreSignature);
1394 if (IsEventLogging() != MagickFalse)
1395 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1396 length=strlen(stream_info->map);
1397 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1398 if (quantum_map == (QuantumType *) NULL)
1399 {
1400 (void) ThrowMagickException(exception,GetMagickModule(),
1401 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1402 return(MagickFalse);
1403 }
1404 (void) memset(quantum_map,0,length*sizeof(*quantum_map));
1405 for (i=0; i < (ssize_t) length; i++)
1406 {
1407 switch (stream_info->map[i])
1408 {
1409 case 'A':
1410 case 'a':
1411 {
1412 quantum_map[i]=AlphaQuantum;
1413 break;
1414 }
1415 case 'B':
1416 case 'b':
1417 {
1418 quantum_map[i]=BlueQuantum;
1419 break;
1420 }
1421 case 'C':
1422 case 'c':
1423 {
1424 quantum_map[i]=CyanQuantum;
1425 if (image->colorspace == CMYKColorspace)
1426 break;
1427 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1428 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1429 "ColorSeparatedImageRequired","`%s'",stream_info->map);
1430 return(MagickFalse);
1431 }
1432 case 'g':
1433 case 'G':
1434 {
1435 quantum_map[i]=GreenQuantum;
1436 break;
1437 }
1438 case 'I':
1439 case 'i':
1440 {
1441 quantum_map[i]=IndexQuantum;
1442 break;
1443 }
1444 case 'K':
1445 case 'k':
1446 {
1447 quantum_map[i]=BlackQuantum;
1448 if (image->colorspace == CMYKColorspace)
1449 break;
1450 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1451 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1452 "ColorSeparatedImageRequired","`%s'",stream_info->map);
1453 return(MagickFalse);
1454 }
1455 case 'M':
1456 case 'm':
1457 {
1458 quantum_map[i]=MagentaQuantum;
1459 if (image->colorspace == CMYKColorspace)
1460 break;
1461 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1462 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1463 "ColorSeparatedImageRequired","`%s'",stream_info->map);
1464 return(MagickFalse);
1465 }
1466 case 'o':
1467 case 'O':
1468 {
1469 quantum_map[i]=OpacityQuantum;
1470 break;
1471 }
1472 case 'P':
1473 case 'p':
1474 {
1475 quantum_map[i]=UndefinedQuantum;
1476 break;
1477 }
1478 case 'R':
1479 case 'r':
1480 {
1481 quantum_map[i]=RedQuantum;
1482 break;
1483 }
1484 case 'Y':
1485 case 'y':
1486 {
1487 quantum_map[i]=YellowQuantum;
1488 if (image->colorspace == CMYKColorspace)
1489 break;
1490 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1491 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1492 "ColorSeparatedImageRequired","`%s'",stream_info->map);
1493 return(MagickFalse);
1494 }
1495 default:
1496 {
1497 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1498 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1499 "UnrecognizedPixelMap","`%s'",stream_info->map);
1500 return(MagickFalse);
1501 }
1502 }
1503 }
1504 quantum_info=stream_info->quantum_info;
1505 switch (stream_info->storage_type)
1506 {
1507 case CharPixel:
1508 {
1509 unsigned char
1510 *q;
1511
1512 q=(unsigned char *) stream_info->pixels;
1513 if (LocaleCompare(stream_info->map,"BGR") == 0)
1514 {
1515 p=GetAuthenticPixelQueue(image);
1516 if (p == (const Quantum *) NULL)
1517 break;
1518 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1519 {
1520 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1521 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1522 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1523 p+=(ptrdiff_t) GetPixelChannels(image);
1524 }
1525 break;
1526 }
1527 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1528 {
1529 p=GetAuthenticPixelQueue(image);
1530 if (p == (const Quantum *) NULL)
1531 break;
1532 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1533 {
1534 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1535 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1536 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1537 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1538 p+=(ptrdiff_t) GetPixelChannels(image);
1539 }
1540 break;
1541 }
1542 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1543 {
1544 p=GetAuthenticPixelQueue(image);
1545 if (p == (const Quantum *) NULL)
1546 break;
1547 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1548 {
1549 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1550 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1551 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1552 *q++=ScaleQuantumToChar((Quantum) 0);
1553 p+=(ptrdiff_t) GetPixelChannels(image);
1554 }
1555 break;
1556 }
1557 if (LocaleCompare(stream_info->map,"I") == 0)
1558 {
1559 p=GetAuthenticPixelQueue(image);
1560 if (p == (const Quantum *) NULL)
1561 break;
1562 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1563 {
1564 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
1565 p+=(ptrdiff_t) GetPixelChannels(image);
1566 }
1567 break;
1568 }
1569 if (LocaleCompare(stream_info->map,"RGB") == 0)
1570 {
1571 p=GetAuthenticPixelQueue(image);
1572 if (p == (const Quantum *) NULL)
1573 break;
1574 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1575 {
1576 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1577 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1578 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1579 p+=(ptrdiff_t) GetPixelChannels(image);
1580 }
1581 break;
1582 }
1583 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1584 {
1585 p=GetAuthenticPixelQueue(image);
1586 if (p == (const Quantum *) NULL)
1587 break;
1588 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1589 {
1590 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1591 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1592 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1593 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1594 p+=(ptrdiff_t) GetPixelChannels(image);
1595 }
1596 break;
1597 }
1598 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1599 {
1600 p=GetAuthenticPixelQueue(image);
1601 if (p == (const Quantum *) NULL)
1602 break;
1603 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1604 {
1605 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1606 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1607 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1608 *q++=ScaleQuantumToChar((Quantum) 0);
1609 p+=(ptrdiff_t) GetPixelChannels(image);
1610 }
1611 break;
1612 }
1613 p=GetAuthenticPixelQueue(image);
1614 if (p == (const Quantum *) NULL)
1615 break;
1616 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1617 {
1618 for (i=0; i < (ssize_t) length; i++)
1619 {
1620 *q=0;
1621 switch (quantum_map[i])
1622 {
1623 case RedQuantum:
1624 case CyanQuantum:
1625 {
1626 *q=ScaleQuantumToChar(GetPixelRed(image,p));
1627 break;
1628 }
1629 case GreenQuantum:
1630 case MagentaQuantum:
1631 {
1632 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
1633 break;
1634 }
1635 case BlueQuantum:
1636 case YellowQuantum:
1637 {
1638 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
1639 break;
1640 }
1641 case AlphaQuantum:
1642 {
1643 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
1644 break;
1645 }
1646 case OpacityQuantum:
1647 {
1648 *q=ScaleQuantumToChar(GetPixelOpacity(image,p));
1649 break;
1650 }
1651 case BlackQuantum:
1652 {
1653 if (image->colorspace == CMYKColorspace)
1654 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
1655 break;
1656 }
1657 case IndexQuantum:
1658 {
1659 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
1660 break;
1661 }
1662 default:
1663 break;
1664 }
1665 q++;
1666 }
1667 p+=(ptrdiff_t) GetPixelChannels(image);
1668 }
1669 break;
1670 }
1671 case DoublePixel:
1672 {
1673 double
1674 *q;
1675
1676 q=(double *) stream_info->pixels;
1677 if (LocaleCompare(stream_info->map,"BGR") == 0)
1678 {
1679 p=GetAuthenticPixelQueue(image);
1680 if (p == (const Quantum *) NULL)
1681 break;
1682 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1683 {
1684 *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1685 quantum_info->scale+quantum_info->minimum);
1686 *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1687 quantum_info->scale+quantum_info->minimum);
1688 *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1689 quantum_info->scale+quantum_info->minimum);
1690 p+=(ptrdiff_t) GetPixelChannels(image);
1691 }
1692 break;
1693 }
1694 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1695 {
1696 p=GetAuthenticPixelQueue(image);
1697 if (p == (const Quantum *) NULL)
1698 break;
1699 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1700 {
1701 *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1702 quantum_info->scale+quantum_info->minimum);
1703 *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1704 quantum_info->scale+quantum_info->minimum);
1705 *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1706 quantum_info->scale+quantum_info->minimum);
1707 *q++=(double) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1708 quantum_info->scale+quantum_info->minimum);
1709 p+=(ptrdiff_t) GetPixelChannels(image);
1710 }
1711 break;
1712 }
1713 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1714 {
1715 p=GetAuthenticPixelQueue(image);
1716 if (p == (const Quantum *) NULL)
1717 break;
1718 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1719 {
1720 *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1721 quantum_info->scale+quantum_info->minimum);
1722 *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1723 quantum_info->scale+quantum_info->minimum);
1724 *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1725 quantum_info->scale+quantum_info->minimum);
1726 *q++=0.0;
1727 p+=(ptrdiff_t) GetPixelChannels(image);
1728 }
1729 break;
1730 }
1731 if (LocaleCompare(stream_info->map,"I") == 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) GetPixelIntensity(image,p))*
1739 quantum_info->scale+quantum_info->minimum);
1740 p+=(ptrdiff_t) GetPixelChannels(image);
1741 }
1742 break;
1743 }
1744 if (LocaleCompare(stream_info->map,"RGB") == 0)
1745 {
1746 p=GetAuthenticPixelQueue(image);
1747 if (p == (const Quantum *) NULL)
1748 break;
1749 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1750 {
1751 *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1752 quantum_info->scale+quantum_info->minimum);
1753 *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1754 quantum_info->scale+quantum_info->minimum);
1755 *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1756 quantum_info->scale+quantum_info->minimum);
1757 p+=(ptrdiff_t) GetPixelChannels(image);
1758 }
1759 break;
1760 }
1761 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1762 {
1763 p=GetAuthenticPixelQueue(image);
1764 if (p == (const Quantum *) NULL)
1765 break;
1766 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1767 {
1768 *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1769 quantum_info->scale+quantum_info->minimum);
1770 *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1771 quantum_info->scale+quantum_info->minimum);
1772 *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1773 quantum_info->scale+quantum_info->minimum);
1774 *q++=(double) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1775 quantum_info->scale+quantum_info->minimum);
1776 p+=(ptrdiff_t) GetPixelChannels(image);
1777 }
1778 break;
1779 }
1780 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1781 {
1782 p=GetAuthenticPixelQueue(image);
1783 if (p == (const Quantum *) NULL)
1784 break;
1785 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1786 {
1787 *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1788 quantum_info->scale+quantum_info->minimum);
1789 *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1790 quantum_info->scale+quantum_info->minimum);
1791 *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1792 quantum_info->scale+quantum_info->minimum);
1793 *q++=0.0;
1794 p+=(ptrdiff_t) GetPixelChannels(image);
1795 }
1796 break;
1797 }
1798 p=GetAuthenticPixelQueue(image);
1799 if (p == (const Quantum *) NULL)
1800 break;
1801 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1802 {
1803 for (i=0; i < (ssize_t) length; i++)
1804 {
1805 *q=0;
1806 switch (quantum_map[i])
1807 {
1808 case RedQuantum:
1809 case CyanQuantum:
1810 {
1811 *q=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1812 quantum_info->scale+quantum_info->minimum);
1813 break;
1814 }
1815 case GreenQuantum:
1816 case MagentaQuantum:
1817 {
1818 *q=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1819 quantum_info->scale+quantum_info->minimum);
1820 break;
1821 }
1822 case BlueQuantum:
1823 case YellowQuantum:
1824 {
1825 *q=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1826 quantum_info->scale+quantum_info->minimum);
1827 break;
1828 }
1829 case AlphaQuantum:
1830 {
1831 *q=(double) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1832 quantum_info->scale+quantum_info->minimum);
1833 break;
1834 }
1835 case OpacityQuantum:
1836 {
1837 *q=(double) ((QuantumScale*(double) GetPixelOpacity(image,p))*
1838 quantum_info->scale+quantum_info->minimum);
1839 break;
1840 }
1841 case BlackQuantum:
1842 {
1843 if (image->colorspace == CMYKColorspace)
1844 *q=(double) ((QuantumScale*(double) GetPixelBlack(image,p))*
1845 quantum_info->scale+quantum_info->minimum);
1846 break;
1847 }
1848 case IndexQuantum:
1849 {
1850 *q=(double) ((QuantumScale*(double) GetPixelIntensity(image,p))*
1851 quantum_info->scale+quantum_info->minimum);
1852 break;
1853 }
1854 default:
1855 *q=0;
1856 }
1857 q++;
1858 }
1859 p+=(ptrdiff_t) GetPixelChannels(image);
1860 }
1861 break;
1862 }
1863 case FloatPixel:
1864 {
1865 float
1866 *q;
1867
1868 q=(float *) stream_info->pixels;
1869 if (LocaleCompare(stream_info->map,"BGR") == 0)
1870 {
1871 p=GetAuthenticPixelQueue(image);
1872 if (p == (const Quantum *) NULL)
1873 break;
1874 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1875 {
1876 *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1877 quantum_info->scale+quantum_info->minimum);
1878 *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1879 quantum_info->scale+quantum_info->minimum);
1880 *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1881 quantum_info->scale+quantum_info->minimum);
1882 p+=(ptrdiff_t) GetPixelChannels(image);
1883 }
1884 break;
1885 }
1886 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1887 {
1888 p=GetAuthenticPixelQueue(image);
1889 if (p == (const Quantum *) NULL)
1890 break;
1891 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1892 {
1893 *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1894 quantum_info->scale+quantum_info->minimum);
1895 *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1896 quantum_info->scale+quantum_info->minimum);
1897 *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1898 quantum_info->scale+quantum_info->minimum);
1899 *q++=(float) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1900 quantum_info->scale+quantum_info->minimum);
1901 p+=(ptrdiff_t) GetPixelChannels(image);
1902 }
1903 break;
1904 }
1905 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1906 {
1907 p=GetAuthenticPixelQueue(image);
1908 if (p == (const Quantum *) NULL)
1909 break;
1910 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1911 {
1912 *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1913 quantum_info->scale+quantum_info->minimum);
1914 *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1915 quantum_info->scale+quantum_info->minimum);
1916 *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1917 quantum_info->scale+quantum_info->minimum);
1918 *q++=0.0;
1919 p+=(ptrdiff_t) GetPixelChannels(image);
1920 }
1921 break;
1922 }
1923 if (LocaleCompare(stream_info->map,"I") == 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) GetPixelIntensity(image,p))*
1931 quantum_info->scale+quantum_info->minimum);
1932 p+=(ptrdiff_t) GetPixelChannels(image);
1933 }
1934 break;
1935 }
1936 if (LocaleCompare(stream_info->map,"RGB") == 0)
1937 {
1938 p=GetAuthenticPixelQueue(image);
1939 if (p == (const Quantum *) NULL)
1940 break;
1941 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1942 {
1943 *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1944 quantum_info->scale+quantum_info->minimum);
1945 *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1946 quantum_info->scale+quantum_info->minimum);
1947 *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1948 quantum_info->scale+quantum_info->minimum);
1949 p+=(ptrdiff_t) GetPixelChannels(image);
1950 }
1951 break;
1952 }
1953 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1954 {
1955 p=GetAuthenticPixelQueue(image);
1956 if (p == (const Quantum *) NULL)
1957 break;
1958 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1959 {
1960 *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1961 quantum_info->scale+quantum_info->minimum);
1962 *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1963 quantum_info->scale+quantum_info->minimum);
1964 *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1965 quantum_info->scale+quantum_info->minimum);
1966 *q++=(float) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1967 quantum_info->scale+quantum_info->minimum);
1968 p+=(ptrdiff_t) GetPixelChannels(image);
1969 }
1970 break;
1971 }
1972 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1973 {
1974 p=GetAuthenticPixelQueue(image);
1975 if (p == (const Quantum *) NULL)
1976 break;
1977 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1978 {
1979 *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1980 quantum_info->scale+quantum_info->minimum);
1981 *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1982 quantum_info->scale+quantum_info->minimum);
1983 *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1984 quantum_info->scale+quantum_info->minimum);
1985 *q++=0.0;
1986 p+=(ptrdiff_t) GetPixelChannels(image);
1987 }
1988 break;
1989 }
1990 p=GetAuthenticPixelQueue(image);
1991 if (p == (const Quantum *) NULL)
1992 break;
1993 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1994 {
1995 for (i=0; i < (ssize_t) length; i++)
1996 {
1997 *q=0;
1998 switch (quantum_map[i])
1999 {
2000 case RedQuantum:
2001 case CyanQuantum:
2002 {
2003 *q=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
2004 quantum_info->scale+quantum_info->minimum);
2005 break;
2006 }
2007 case GreenQuantum:
2008 case MagentaQuantum:
2009 {
2010 *q=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
2011 quantum_info->scale+quantum_info->minimum);
2012 break;
2013 }
2014 case BlueQuantum:
2015 case YellowQuantum:
2016 {
2017 *q=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
2018 quantum_info->scale+quantum_info->minimum);
2019 break;
2020 }
2021 case AlphaQuantum:
2022 {
2023 *q=(float) ((QuantumScale*(double) GetPixelAlpha(image,p))*
2024 quantum_info->scale+quantum_info->minimum);
2025 break;
2026 }
2027 case OpacityQuantum:
2028 {
2029 *q=(float) ((QuantumScale*(double) GetPixelOpacity(image,p))*
2030 quantum_info->scale+quantum_info->minimum);
2031 break;
2032 }
2033 case BlackQuantum:
2034 {
2035 if (image->colorspace == CMYKColorspace)
2036 *q=(float) ((QuantumScale*(double) GetPixelBlack(image,p))*
2037 quantum_info->scale+quantum_info->minimum);
2038 break;
2039 }
2040 case IndexQuantum:
2041 {
2042 *q=(float) ((QuantumScale*(double) GetPixelIntensity(image,p))*
2043 quantum_info->scale+quantum_info->minimum);
2044 break;
2045 }
2046 default:
2047 *q=0;
2048 }
2049 q++;
2050 }
2051 p+=(ptrdiff_t) GetPixelChannels(image);
2052 }
2053 break;
2054 }
2055 case LongPixel:
2056 {
2057 unsigned int
2058 *q;
2059
2060 q=(unsigned int *) stream_info->pixels;
2061 if (LocaleCompare(stream_info->map,"BGR") == 0)
2062 {
2063 p=GetAuthenticPixelQueue(image);
2064 if (p == (const Quantum *) NULL)
2065 break;
2066 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2067 {
2068 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2069 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2070 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2071 p+=(ptrdiff_t) GetPixelChannels(image);
2072 }
2073 break;
2074 }
2075 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2076 {
2077 p=GetAuthenticPixelQueue(image);
2078 if (p == (const Quantum *) NULL)
2079 break;
2080 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2081 {
2082 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2083 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2084 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2085 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
2086 p+=(ptrdiff_t) GetPixelChannels(image);
2087 }
2088 break;
2089 }
2090 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2091 {
2092 p=GetAuthenticPixelQueue(image);
2093 if (p == (const Quantum *) NULL)
2094 break;
2095 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2096 {
2097 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2098 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2099 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2100 *q++=0;
2101 p+=(ptrdiff_t) GetPixelChannels(image);
2102 }
2103 break;
2104 }
2105 if (LocaleCompare(stream_info->map,"I") == 0)
2106 {
2107 p=GetAuthenticPixelQueue(image);
2108 if (p == (const Quantum *) NULL)
2109 break;
2110 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2111 {
2112 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
2113 p+=(ptrdiff_t) GetPixelChannels(image);
2114 }
2115 break;
2116 }
2117 if (LocaleCompare(stream_info->map,"RGB") == 0)
2118 {
2119 p=GetAuthenticPixelQueue(image);
2120 if (p == (const Quantum *) NULL)
2121 break;
2122 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2123 {
2124 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2125 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2126 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2127 p+=(ptrdiff_t) GetPixelChannels(image);
2128 }
2129 break;
2130 }
2131 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2132 {
2133 p=GetAuthenticPixelQueue(image);
2134 if (p == (const Quantum *) NULL)
2135 break;
2136 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2137 {
2138 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2139 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2140 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2141 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
2142 p+=(ptrdiff_t) GetPixelChannels(image);
2143 }
2144 break;
2145 }
2146 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2147 {
2148 p=GetAuthenticPixelQueue(image);
2149 if (p == (const Quantum *) NULL)
2150 break;
2151 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2152 {
2153 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2154 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2155 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2156 *q++=0;
2157 p+=(ptrdiff_t) GetPixelChannels(image);
2158 }
2159 break;
2160 }
2161 p=GetAuthenticPixelQueue(image);
2162 if (p == (const Quantum *) NULL)
2163 break;
2164 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2165 {
2166 for (i=0; i < (ssize_t) length; i++)
2167 {
2168 *q=0;
2169 switch (quantum_map[i])
2170 {
2171 case RedQuantum:
2172 case CyanQuantum:
2173 {
2174 *q=ScaleQuantumToLong(GetPixelRed(image,p));
2175 break;
2176 }
2177 case GreenQuantum:
2178 case MagentaQuantum:
2179 {
2180 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
2181 break;
2182 }
2183 case BlueQuantum:
2184 case YellowQuantum:
2185 {
2186 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
2187 break;
2188 }
2189 case AlphaQuantum:
2190 {
2191 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
2192 break;
2193 }
2194 case OpacityQuantum:
2195 {
2196 *q=ScaleQuantumToLong(GetPixelOpacity(image,p));
2197 break;
2198 }
2199 case BlackQuantum:
2200 {
2201 if (image->colorspace == CMYKColorspace)
2202 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
2203 break;
2204 }
2205 case IndexQuantum:
2206 {
2207 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
2208 break;
2209 }
2210 default:
2211 break;
2212 }
2213 q++;
2214 }
2215 p+=(ptrdiff_t) GetPixelChannels(image);
2216 }
2217 break;
2218 }
2219 case LongLongPixel:
2220 {
2221 MagickSizeType
2222 *q;
2223
2224 q=(MagickSizeType *) stream_info->pixels;
2225 if (LocaleCompare(stream_info->map,"BGR") == 0)
2226 {
2227 p=GetAuthenticPixelQueue(image);
2228 if (p == (const Quantum *) NULL)
2229 break;
2230 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2231 {
2232 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2233 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2234 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2235 p+=(ptrdiff_t) GetPixelChannels(image);
2236 }
2237 break;
2238 }
2239 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2240 {
2241 p=GetAuthenticPixelQueue(image);
2242 if (p == (const Quantum *) NULL)
2243 break;
2244 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2245 {
2246 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2247 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2248 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2249 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2250 p+=(ptrdiff_t) GetPixelChannels(image);
2251 }
2252 break;
2253 }
2254 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2255 {
2256 p=GetAuthenticPixelQueue(image);
2257 if (p == (const Quantum *) NULL)
2258 break;
2259 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2260 {
2261 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2262 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2263 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2264 *q++=0U;
2265 p+=(ptrdiff_t) GetPixelChannels(image);
2266 }
2267 break;
2268 }
2269 if (LocaleCompare(stream_info->map,"I") == 0)
2270 {
2271 p=GetAuthenticPixelQueue(image);
2272 if (p == (const Quantum *) NULL)
2273 break;
2274 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2275 {
2276 *q++=ScaleQuantumToLongLong(ClampToQuantum(
2277 GetPixelIntensity(image,p)));
2278 p+=(ptrdiff_t) GetPixelChannels(image);
2279 }
2280 break;
2281 }
2282 if (LocaleCompare(stream_info->map,"RGB") == 0)
2283 {
2284 p=GetAuthenticPixelQueue(image);
2285 if (p == (const Quantum *) NULL)
2286 break;
2287 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2288 {
2289 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2290 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2291 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2292 p+=(ptrdiff_t) GetPixelChannels(image);
2293 }
2294 break;
2295 }
2296 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2297 {
2298 p=GetAuthenticPixelQueue(image);
2299 if (p == (const Quantum *) NULL)
2300 break;
2301 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2302 {
2303 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2304 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2305 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2306 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2307 p+=(ptrdiff_t) GetPixelChannels(image);
2308 }
2309 break;
2310 }
2311 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2312 {
2313 p=GetAuthenticPixelQueue(image);
2314 if (p == (const Quantum *) NULL)
2315 break;
2316 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2317 {
2318 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2319 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2320 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2321 *q++=0U;
2322 p+=(ptrdiff_t) GetPixelChannels(image);
2323 }
2324 break;
2325 }
2326 p=GetAuthenticPixelQueue(image);
2327 if (p == (const Quantum *) NULL)
2328 break;
2329 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2330 {
2331 for (i=0; i < (ssize_t) length; i++)
2332 {
2333 *q=0;
2334 switch (quantum_map[i])
2335 {
2336 case RedQuantum:
2337 case CyanQuantum:
2338 {
2339 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
2340 break;
2341 }
2342 case GreenQuantum:
2343 case MagentaQuantum:
2344 {
2345 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2346 break;
2347 }
2348 case BlueQuantum:
2349 case YellowQuantum:
2350 {
2351 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2352 break;
2353 }
2354 case AlphaQuantum:
2355 {
2356 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2357 break;
2358 }
2359 case OpacityQuantum:
2360 {
2361 *q=ScaleQuantumToLongLong(GetPixelOpacity(image,p));
2362 break;
2363 }
2364 case BlackQuantum:
2365 {
2366 if (image->colorspace == CMYKColorspace)
2367 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
2368 break;
2369 }
2370 case IndexQuantum:
2371 {
2372 *q=ScaleQuantumToLongLong(ClampToQuantum(
2373 GetPixelIntensity(image,p)));
2374 break;
2375 }
2376 default:
2377 *q=0;
2378 }
2379 q++;
2380 }
2381 p+=(ptrdiff_t) GetPixelChannels(image);
2382 }
2383 break;
2384 }
2385 case QuantumPixel:
2386 {
2387 Quantum
2388 *q;
2389
2390 q=(Quantum *) stream_info->pixels;
2391 if (LocaleCompare(stream_info->map,"BGR") == 0)
2392 {
2393 p=GetAuthenticPixelQueue(image);
2394 if (p == (const Quantum *) NULL)
2395 break;
2396 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2397 {
2398 *q++=GetPixelBlue(image,p);
2399 *q++=GetPixelGreen(image,p);
2400 *q++=GetPixelRed(image,p);
2401 p+=(ptrdiff_t) GetPixelChannels(image);
2402 }
2403 break;
2404 }
2405 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2406 {
2407 p=GetAuthenticPixelQueue(image);
2408 if (p == (const Quantum *) NULL)
2409 break;
2410 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2411 {
2412 *q++=GetPixelBlue(image,p);
2413 *q++=GetPixelGreen(image,p);
2414 *q++=GetPixelRed(image,p);
2415 *q++=GetPixelAlpha(image,p);
2416 p+=(ptrdiff_t) GetPixelChannels(image);
2417 }
2418 break;
2419 }
2420 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2421 {
2422 p=GetAuthenticPixelQueue(image);
2423 if (p == (const Quantum *) NULL)
2424 break;
2425 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2426 {
2427 *q++=GetPixelBlue(image,p);
2428 *q++=GetPixelGreen(image,p);
2429 *q++=GetPixelRed(image,p);
2430 *q++=(Quantum) 0;
2431 p+=(ptrdiff_t) GetPixelChannels(image);
2432 }
2433 break;
2434 }
2435 if (LocaleCompare(stream_info->map,"I") == 0)
2436 {
2437 p=GetAuthenticPixelQueue(image);
2438 if (p == (const Quantum *) NULL)
2439 break;
2440 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2441 {
2442 *q++=ClampToQuantum(GetPixelIntensity(image,p));
2443 p+=(ptrdiff_t) GetPixelChannels(image);
2444 }
2445 break;
2446 }
2447 if (LocaleCompare(stream_info->map,"RGB") == 0)
2448 {
2449 p=GetAuthenticPixelQueue(image);
2450 if (p == (const Quantum *) NULL)
2451 break;
2452 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2453 {
2454 *q++=GetPixelRed(image,p);
2455 *q++=GetPixelGreen(image,p);
2456 *q++=GetPixelBlue(image,p);
2457 p+=(ptrdiff_t) GetPixelChannels(image);
2458 }
2459 break;
2460 }
2461 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2462 {
2463 p=GetAuthenticPixelQueue(image);
2464 if (p == (const Quantum *) NULL)
2465 break;
2466 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2467 {
2468 *q++=GetPixelRed(image,p);
2469 *q++=GetPixelGreen(image,p);
2470 *q++=GetPixelBlue(image,p);
2471 *q++=GetPixelAlpha(image,p);
2472 p+=(ptrdiff_t) GetPixelChannels(image);
2473 }
2474 break;
2475 }
2476 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2477 {
2478 p=GetAuthenticPixelQueue(image);
2479 if (p == (const Quantum *) NULL)
2480 break;
2481 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2482 {
2483 *q++=GetPixelRed(image,p);
2484 *q++=GetPixelGreen(image,p);
2485 *q++=GetPixelBlue(image,p);
2486 *q++=(Quantum) 0;
2487 p+=(ptrdiff_t) GetPixelChannels(image);
2488 }
2489 break;
2490 }
2491 p=GetAuthenticPixelQueue(image);
2492 if (p == (const Quantum *) NULL)
2493 break;
2494 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2495 {
2496 for (i=0; i < (ssize_t) length; i++)
2497 {
2498 *q=(Quantum) 0;
2499 switch (quantum_map[i])
2500 {
2501 case RedQuantum:
2502 case CyanQuantum:
2503 {
2504 *q=GetPixelRed(image,p);
2505 break;
2506 }
2507 case GreenQuantum:
2508 case MagentaQuantum:
2509 {
2510 *q=GetPixelGreen(image,p);
2511 break;
2512 }
2513 case BlueQuantum:
2514 case YellowQuantum:
2515 {
2516 *q=GetPixelBlue(image,p);
2517 break;
2518 }
2519 case AlphaQuantum:
2520 {
2521 *q=GetPixelAlpha(image,p);
2522 break;
2523 }
2524 case OpacityQuantum:
2525 {
2526 *q=GetPixelOpacity(image,p);
2527 break;
2528 }
2529 case BlackQuantum:
2530 {
2531 if (image->colorspace == CMYKColorspace)
2532 *q=GetPixelBlack(image,p);
2533 break;
2534 }
2535 case IndexQuantum:
2536 {
2537 *q=ClampToQuantum(GetPixelIntensity(image,p));
2538 break;
2539 }
2540 default:
2541 *q=(Quantum) 0;
2542 }
2543 q++;
2544 }
2545 p+=(ptrdiff_t) GetPixelChannels(image);
2546 }
2547 break;
2548 }
2549 case ShortPixel:
2550 {
2551 unsigned short
2552 *q;
2553
2554 q=(unsigned short *) stream_info->pixels;
2555 if (LocaleCompare(stream_info->map,"BGR") == 0)
2556 {
2557 p=GetAuthenticPixelQueue(image);
2558 if (p == (const Quantum *) NULL)
2559 break;
2560 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2561 {
2562 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2563 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2564 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2565 p+=(ptrdiff_t) GetPixelChannels(image);
2566 }
2567 break;
2568 }
2569 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2570 {
2571 p=GetAuthenticPixelQueue(image);
2572 if (p == (const Quantum *) NULL)
2573 break;
2574 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2575 {
2576 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2577 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2578 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2579 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
2580 p+=(ptrdiff_t) GetPixelChannels(image);
2581 }
2582 break;
2583 }
2584 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2585 {
2586 p=GetAuthenticPixelQueue(image);
2587 if (p == (const Quantum *) NULL)
2588 break;
2589 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2590 {
2591 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2592 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2593 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2594 *q++=0;
2595 p+=(ptrdiff_t) GetPixelChannels(image);
2596 }
2597 break;
2598 }
2599 if (LocaleCompare(stream_info->map,"I") == 0)
2600 {
2601 p=GetAuthenticPixelQueue(image);
2602 if (p == (const Quantum *) NULL)
2603 break;
2604 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2605 {
2606 *q++=ScaleQuantumToShort(ClampToQuantum(
2607 GetPixelIntensity(image,p)));
2608 p+=(ptrdiff_t) GetPixelChannels(image);
2609 }
2610 break;
2611 }
2612 if (LocaleCompare(stream_info->map,"RGB") == 0)
2613 {
2614 p=GetAuthenticPixelQueue(image);
2615 if (p == (const Quantum *) NULL)
2616 break;
2617 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2618 {
2619 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2620 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2621 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2622 p+=(ptrdiff_t) GetPixelChannels(image);
2623 }
2624 break;
2625 }
2626 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2627 {
2628 p=GetAuthenticPixelQueue(image);
2629 if (p == (const Quantum *) NULL)
2630 break;
2631 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2632 {
2633 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2634 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2635 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2636 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
2637 p+=(ptrdiff_t) GetPixelChannels(image);
2638 }
2639 break;
2640 }
2641 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2642 {
2643 p=GetAuthenticPixelQueue(image);
2644 if (p == (const Quantum *) NULL)
2645 break;
2646 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2647 {
2648 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2649 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2650 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2651 *q++=0;
2652 p+=(ptrdiff_t) GetPixelChannels(image);
2653 }
2654 break;
2655 }
2656 p=GetAuthenticPixelQueue(image);
2657 if (p == (const Quantum *) NULL)
2658 break;
2659 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2660 {
2661 for (i=0; i < (ssize_t) length; i++)
2662 {
2663 *q=0;
2664 switch (quantum_map[i])
2665 {
2666 case RedQuantum:
2667 case CyanQuantum:
2668 {
2669 *q=ScaleQuantumToShort(GetPixelRed(image,p));
2670 break;
2671 }
2672 case GreenQuantum:
2673 case MagentaQuantum:
2674 {
2675 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
2676 break;
2677 }
2678 case BlueQuantum:
2679 case YellowQuantum:
2680 {
2681 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
2682 break;
2683 }
2684 case AlphaQuantum:
2685 {
2686 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
2687 break;
2688 }
2689 case OpacityQuantum:
2690 {
2691 *q=ScaleQuantumToShort(GetPixelOpacity(image,p));
2692 break;
2693 }
2694 case BlackQuantum:
2695 {
2696 if (image->colorspace == CMYKColorspace)
2697 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
2698 break;
2699 }
2700 case IndexQuantum:
2701 {
2702 *q=ScaleQuantumToShort(ClampToQuantum(
2703 GetPixelIntensity(image,p)));
2704 break;
2705 }
2706 default:
2707 break;
2708 }
2709 q++;
2710 }
2711 p+=(ptrdiff_t) GetPixelChannels(image);
2712 }
2713 break;
2714 }
2715 default:
2716 {
2717 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2718 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2719 "UnrecognizedPixelMap","`%s'",stream_info->map);
2720 break;
2721 }
2722 }
2723 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2724 return(MagickTrue);
2725}
2726
2727/*
2728%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2729% %
2730% %
2731% %
2732+ 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 %
2733% %
2734% %
2735% %
2736%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2737%
2738% SyncAuthenticPixelsStream() calls the user supplied callback method with
2739% the latest stream of pixels.
2740%
2741% The format of the SyncAuthenticPixelsStream method is:
2742%
2743% MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2744% ExceptionInfo *exception)
2745%
2746% A description of each parameter follows:
2747%
2748% o image: the image.
2749%
2750% o exception: return any errors or warnings in this structure.
2751%
2752*/
2753static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2754 ExceptionInfo *exception)
2755{
2756 CacheInfo
2757 *cache_info;
2758
2759 size_t
2760 length;
2761
2762 StreamHandler
2763 stream_handler;
2764
2765 assert(image != (Image *) NULL);
2766 assert(image->signature == MagickCoreSignature);
2767 if (IsEventLogging() != MagickFalse)
2768 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2769 cache_info=(CacheInfo *) image->cache;
2770 assert(cache_info->signature == MagickCoreSignature);
2771 stream_handler=GetBlobStreamHandler(image);
2772 if (stream_handler == (StreamHandler) NULL)
2773 {
2774 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
2775 "NoStreamHandlerIsDefined","`%s'",image->filename);
2776 return(MagickFalse);
2777 }
2778 length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
2779 return(length == cache_info->columns ? MagickTrue : MagickFalse);
2780}
2781
2782/*
2783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2784% %
2785% %
2786% %
2787% W r i t e S t r e a m %
2788% %
2789% %
2790% %
2791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2792%
2793% WriteStream() makes the image pixels available to a user supplied callback
2794% method immediately upon writing pixel data with the WriteImage() method.
2795%
2796% The format of the WriteStream() method is:
2797%
2798% MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
2799% StreamHandler stream,ExceptionInfo *exception)
2800%
2801% A description of each parameter follows:
2802%
2803% o image_info: the image info.
2804%
2805% o stream: A callback method.
2806%
2807% o exception: return any errors or warnings in this structure.
2808%
2809*/
2810MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
2811 Image *image,StreamHandler stream,ExceptionInfo *exception)
2812{
2813 ImageInfo
2814 *write_info;
2815
2816 MagickBooleanType
2817 status;
2818
2819 assert(image_info != (ImageInfo *) NULL);
2820 assert(image_info->signature == MagickCoreSignature);
2821 if (IsEventLogging() != MagickFalse)
2822 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2823 image_info->filename);
2824 assert(image != (Image *) NULL);
2825 assert(image->signature == MagickCoreSignature);
2826 write_info=CloneImageInfo(image_info);
2827 *write_info->magick='\0';
2828 write_info->stream=stream;
2829 status=WriteImage(write_info,image,exception);
2830 write_info=DestroyImageInfo(write_info);
2831 return(status);
2832}