blob: 1d5b472a45ba3a4619f8ca1527ce6fb1a3f2e61c [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% John Cristy %
17% March 2000 %
18% %
19% %
cristy16af1cb2009-12-11 21:38:29 +000020% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37%
38*/
39
40/*
41 Include declarations.
42*/
43#include "magick/studio.h"
44#include "magick/blob.h"
45#include "magick/blob-private.h"
46#include "magick/cache.h"
47#include "magick/cache-private.h"
48#include "magick/color-private.h"
49#include "magick/composite-private.h"
50#include "magick/constitute.h"
51#include "magick/exception.h"
52#include "magick/exception-private.h"
53#include "magick/geometry.h"
54#include "magick/memory_.h"
cristy46f08202010-01-10 04:04:21 +000055#include "magick/pixel.h"
cristy3ed852e2009-09-05 21:47:34 +000056#include "magick/quantum.h"
57#include "magick/quantum-private.h"
58#include "magick/semaphore.h"
59#include "magick/stream.h"
60#include "magick/stream-private.h"
61#include "magick/string_.h"
62
63/*
64 Typedef declaractions.
65*/
66struct _StreamInfo
67{
68 const ImageInfo
69 *image_info;
70
71 const Image
72 *image;
73
74 Image
75 *stream;
76
77 QuantumInfo
78 *quantum_info;
79
80 char
81 *map;
82
83 StorageType
84 storage_type;
85
86 unsigned char
87 *pixels;
88
89 RectangleInfo
90 extract_info;
91
cristybb503372010-05-27 20:51:26 +000092 ssize_t
cristy3ed852e2009-09-05 21:47:34 +000093 y;
94
95 ExceptionInfo
96 *exception;
97
98 const void
99 *client_data;
100
cristybb503372010-05-27 20:51:26 +0000101 size_t
cristy3ed852e2009-09-05 21:47:34 +0000102 signature;
103};
104
105/*
106 Declare pixel cache interfaces.
107*/
108#if defined(__cplusplus) || defined(c_plusplus)
109extern "C" {
110#endif
111
112static const PixelPacket
cristybb503372010-05-27 20:51:26 +0000113 *GetVirtualPixelStream(const Image *,const VirtualPixelMethod,const ssize_t,
114 const ssize_t,const size_t,const size_t,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000115
116static MagickBooleanType
117 StreamImagePixels(const StreamInfo *,const Image *,ExceptionInfo *),
118 SyncAuthenticPixelsStream(Image *,ExceptionInfo *);
119
120static PixelPacket
cristybb503372010-05-27 20:51:26 +0000121 *QueueAuthenticPixelsStream(Image *,const ssize_t,const ssize_t,const size_t,
122 const size_t,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000123
124#if defined(__cplusplus) || defined(c_plusplus)
125}
126#endif
127
128/*
129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130% %
131% %
132% %
133+ A c q u i r e S t r e a m I n f o %
134% %
135% %
136% %
137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138%
139% AcquireStreamInfo() allocates the StreamInfo structure.
140%
141% The format of the AcquireStreamInfo method is:
142%
143% StreamInfo *AcquireStreamInfo(const ImageInfo *image_info)
144%
145% A description of each parameter follows:
146%
147% o image_info: the image info.
148%
149*/
150MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info)
151{
152 StreamInfo
153 *stream_info;
154
cristy90823212009-12-12 20:48:33 +0000155 stream_info=(StreamInfo *) AcquireAlignedMemory(1,sizeof(*stream_info));
cristy3ed852e2009-09-05 21:47:34 +0000156 if (stream_info == (StreamInfo *) NULL)
157 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
158 (void) ResetMagickMemory(stream_info,0,sizeof(*stream_info));
159 stream_info->pixels=(unsigned char *) AcquireMagickMemory(
160 sizeof(*stream_info->pixels));
161 if (stream_info->pixels == (unsigned char *) NULL)
162 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
163 stream_info->map=ConstantString("RGB");
164 stream_info->storage_type=CharPixel;
165 stream_info->stream=AcquireImage(image_info);
166 stream_info->signature=MagickSignature;
167 return(stream_info);
168}
169
170/*
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172% %
173% %
174% %
175+ D e s t r o y P i x e l S t r e a m %
176% %
177% %
178% %
179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180%
181% DestroyPixelStream() deallocates memory associated with the pixel stream.
182%
183% The format of the DestroyPixelStream() method is:
184%
185% void DestroyPixelStream(Image *image)
186%
187% A description of each parameter follows:
188%
189% o image: the image.
190%
191*/
192
193static inline void RelinquishStreamPixels(CacheInfo *cache_info)
194{
195 assert(cache_info != (CacheInfo *) NULL);
196 if (cache_info->mapped == MagickFalse)
197 (void) RelinquishMagickMemory(cache_info->pixels);
198 else
199 (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
200 cache_info->pixels=(PixelPacket *) NULL;
201 cache_info->indexes=(IndexPacket *) NULL;
202 cache_info->length=0;
203 cache_info->mapped=MagickFalse;
204}
205
206static void DestroyPixelStream(Image *image)
207{
208 CacheInfo
209 *cache_info;
210
211 MagickBooleanType
212 destroy;
213
214 assert(image != (Image *) NULL);
215 assert(image->signature == MagickSignature);
216 if (image->debug != MagickFalse)
217 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
218 cache_info=(CacheInfo *) image->cache;
219 assert(cache_info->signature == MagickSignature);
220 destroy=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000221 LockSemaphoreInfo(cache_info->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000222 cache_info->reference_count--;
223 if (cache_info->reference_count == 0)
224 destroy=MagickTrue;
cristyf84a1932010-01-03 18:00:18 +0000225 UnlockSemaphoreInfo(cache_info->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000226 if (destroy == MagickFalse)
227 return;
228 RelinquishStreamPixels(cache_info);
229 if (cache_info->nexus_info != (NexusInfo **) NULL)
230 cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
231 cache_info->number_threads);
232 if (cache_info->disk_semaphore != (SemaphoreInfo *) NULL)
233 DestroySemaphoreInfo(&cache_info->disk_semaphore);
234 if (cache_info->semaphore != (SemaphoreInfo *) NULL)
235 DestroySemaphoreInfo(&cache_info->semaphore);
236 cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
237}
238
239/*
240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241% %
242% %
243% %
244+ D e s t r o y S t r e a m I n f o %
245% %
246% %
247% %
248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249%
250% DestroyStreamInfo() destroys memory associated with the StreamInfo
251% structure.
252%
253% The format of the DestroyStreamInfo method is:
254%
255% StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
256%
257% A description of each parameter follows:
258%
259% o stream_info: the stream info.
260%
261*/
262MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
263{
264 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
265 assert(stream_info != (StreamInfo *) NULL);
266 assert(stream_info->signature == MagickSignature);
267 if (stream_info->map != (char *) NULL)
268 stream_info->map=DestroyString(stream_info->map);
269 if (stream_info->pixels != (unsigned char *) NULL)
270 stream_info->pixels=(unsigned char *) RelinquishMagickMemory(
271 stream_info->pixels);
272 if (stream_info->stream != (Image *) NULL)
273 {
274 (void) CloseBlob(stream_info->stream);
275 stream_info->stream=DestroyImage(stream_info->stream);
276 }
277 if (stream_info->quantum_info != (QuantumInfo *) NULL)
278 stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
279 stream_info->signature=(~MagickSignature);
280 stream_info=(StreamInfo *) RelinquishMagickMemory(stream_info);
281 return(stream_info);
282}
283
284/*
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286% %
287% %
288% %
289+ G e t A u t h e n t i c I n d e x e s F r o m S t r e a m %
290% %
291% %
292% %
293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294%
295% GetAuthenticIndexesFromStream() returns the indexes associated with the
296% last call to QueueAuthenticPixelsStream() or GetAuthenticPixelsStream().
297%
298% The format of the GetAuthenticIndexesFromStream() method is:
299%
300% IndexPacket *GetAuthenticIndexesFromStream(const Image *image)
301%
302% A description of each parameter follows:
303%
304% o image: the image.
305%
306*/
307static IndexPacket *GetAuthenticIndexesFromStream(const Image *image)
308{
309 CacheInfo
310 *cache_info;
311
312 assert(image != (Image *) NULL);
313 assert(image->signature == MagickSignature);
314 if (image->debug != MagickFalse)
315 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
316 cache_info=(CacheInfo *) image->cache;
317 assert(cache_info->signature == MagickSignature);
318 return(cache_info->indexes);
319}
320
321/*
322%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323% %
324% %
325% %
326+ G e t A u t h e n t i c P i x e l S t r e a m %
327% %
328% %
329% %
330%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
331%
332% GetAuthenticPixelsStream() gets pixels from the in-memory or disk pixel
333% cache as defined by the geometry parameters. A pointer to the pixels is
334% returned if the pixels are transferred, otherwise a NULL is returned. For
335% streams this method is a no-op.
336%
337% The format of the GetAuthenticPixelsStream() method is:
338%
cristybb503372010-05-27 20:51:26 +0000339% PixelPacket *GetAuthenticPixelsStream(Image *image,const ssize_t x,
340% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000341% ExceptionInfo *exception)
342%
343% A description of each parameter follows:
344%
345% o image: the image.
346%
347% o x,y,columns,rows: These values define the perimeter of a region of
348% pixels.
349%
350% o exception: return any errors or warnings in this structure.
351%
352*/
cristybb503372010-05-27 20:51:26 +0000353static PixelPacket *GetAuthenticPixelsStream(Image *image,const ssize_t x,
354 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000355 ExceptionInfo *exception)
356{
357 PixelPacket
358 *pixels;
359
360 assert(image != (Image *) NULL);
361 assert(image->signature == MagickSignature);
362 if (image->debug != MagickFalse)
363 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
364 pixels=QueueAuthenticPixelsStream(image,x,y,columns,rows,exception);
365 return(pixels);
366}
367
368/*
369%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370% %
371% %
372% %
373+ 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 %
374% %
375% %
376% %
377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378%
379% GetAuthenticPixelsFromStream() returns the pixels associated with the last
380% call to QueueAuthenticPixelsStream() or GetAuthenticPixelsStream().
381%
382% The format of the GetAuthenticPixelsFromStream() method is:
383%
384% PixelPacket *GetAuthenticPixelsFromStream(const Image image)
385%
386% A description of each parameter follows:
387%
388% o image: the image.
389%
390*/
391static PixelPacket *GetAuthenticPixelsFromStream(const Image *image)
392{
393 CacheInfo
394 *cache_info;
395
396 assert(image != (Image *) NULL);
397 assert(image->signature == MagickSignature);
398 if (image->debug != MagickFalse)
399 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
400 cache_info=(CacheInfo *) image->cache;
401 assert(cache_info->signature == MagickSignature);
402 return(cache_info->pixels);
403}
404
405/*
406%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
407% %
408% %
409% %
410+ 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 %
411% %
412% %
413% %
414%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415%
416% GetOneAuthenticPixelFromStream() returns a single pixel at the specified
417% (x,y) location. The image background color is returned if an error occurs.
418%
419% The format of the GetOneAuthenticPixelFromStream() method is:
420%
421% MagickBooleanType GetOneAuthenticPixelFromStream(const Image image,
cristybb503372010-05-27 20:51:26 +0000422% const ssize_t x,const ssize_t y,PixelPacket *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000423%
424% A description of each parameter follows:
425%
426% o image: the image.
427%
428% o pixel: return a pixel at the specified (x,y) location.
429%
430% o x,y: These values define the location of the pixel to return.
431%
432% o exception: return any errors or warnings in this structure.
433%
434*/
435static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
cristybb503372010-05-27 20:51:26 +0000436 const ssize_t x,const ssize_t y,PixelPacket *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000437{
438 register PixelPacket
439 *pixels;
440
441 assert(image != (Image *) NULL);
442 assert(image->signature == MagickSignature);
443 *pixel=image->background_color;
444 pixels=GetAuthenticPixelsStream(image,x,y,1,1,exception);
445 if (pixels != (PixelPacket *) NULL)
446 return(MagickFalse);
447 *pixel=(*pixels);
448 return(MagickTrue);
449}
450
451/*
452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453% %
454% %
455% %
456+ 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 %
457% %
458% %
459% %
460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461%
462% GetOneVirtualPixelFromStream() returns a single pixel at the specified
463% (x.y) location. The image background color is returned if an error occurs.
464%
465% The format of the GetOneVirtualPixelFromStream() method is:
466%
467% MagickBooleanType GetOneVirtualPixelFromStream(const Image image,
cristybb503372010-05-27 20:51:26 +0000468% const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
469% const ssize_t y,PixelPacket *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000470%
471% A description of each parameter follows:
472%
473% o image: the image.
474%
475% o virtual_pixel_method: the virtual pixel method.
476%
477% o x,y: These values define the location of the pixel to return.
478%
479% o pixel: return a pixel at the specified (x,y) location.
480%
481% o exception: return any errors or warnings in this structure.
482%
483*/
484static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000485 const VirtualPixelMethod virtual_pixel_method,const ssize_t x,const ssize_t y,
cristy3ed852e2009-09-05 21:47:34 +0000486 PixelPacket *pixel,ExceptionInfo *exception)
487{
488 const PixelPacket
489 *pixels;
490
491 assert(image != (Image *) NULL);
492 assert(image->signature == MagickSignature);
493 *pixel=image->background_color;
494 pixels=GetVirtualPixelStream(image,virtual_pixel_method,x,y,1,1,exception);
495 if (pixels != (const PixelPacket *) NULL)
496 return(MagickFalse);
497 *pixel=(*pixels);
498 return(MagickTrue);
499}
500
501/*
502%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503% %
504% %
505% %
506+ G e t S t r e a m I n f o C l i e n t D a t a %
507% %
508% %
509% %
510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511%
512% GetStreamInfoClientData() gets the stream info client data.
513%
514% The format of the SetStreamInfoClientData method is:
515%
516% const void *GetStreamInfoClientData(StreamInfo *stream_info)
517%
518% A description of each parameter follows:
519%
520% o stream_info: the stream info.
521%
522*/
523MagickExport const void *GetStreamInfoClientData(StreamInfo *stream_info)
524{
525 assert(stream_info != (StreamInfo *) NULL);
526 assert(stream_info->signature == MagickSignature);
527 return(stream_info->client_data);
528}
529
530/*
531%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
532% %
533% %
534% %
535+ 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 %
536% %
537% %
538% %
539%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
540%
541% GetVirtualPixelsStream() returns the pixels associated with the last
542% call to QueueAuthenticPixelsStream() or GetVirtualPixelStream().
543%
544% The format of the GetVirtualPixelsStream() method is:
545%
546% const IndexPacket *GetVirtualPixelsStream(const Image *image)
547%
548% A description of each parameter follows:
549%
550% o pixels: return the pixels associated with the last call to
551% QueueAuthenticPixelsStream() or GetVirtualPixelStream().
552%
553% o image: the image.
554%
555*/
556static const PixelPacket *GetVirtualPixelsStream(const Image *image)
557{
558 CacheInfo
559 *cache_info;
560
561 assert(image != (Image *) NULL);
562 assert(image->signature == MagickSignature);
563 if (image->debug != MagickFalse)
564 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
565 cache_info=(CacheInfo *) image->cache;
566 assert(cache_info->signature == MagickSignature);
567 return(cache_info->pixels);
568}
569
570/*
571%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572% %
573% %
574% %
575+ 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 %
576% %
577% %
578% %
579%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
580%
581% GetVirtualIndexesFromStream() returns the indexes associated with the last
582% call to QueueAuthenticPixelsStream() or GetVirtualPixelStream().
583%
584% The format of the GetVirtualIndexesFromStream() method is:
585%
586% const IndexPacket *GetVirtualIndexesFromStream(const Image *image)
587%
588% A description of each parameter follows:
589%
590% o image: the image.
591%
592*/
593static const IndexPacket *GetVirtualIndexesFromStream(const Image *image)
594{
595 CacheInfo
596 *cache_info;
597
598 assert(image != (Image *) NULL);
599 assert(image->signature == MagickSignature);
600 if (image->debug != MagickFalse)
601 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
602 cache_info=(CacheInfo *) image->cache;
603 assert(cache_info->signature == MagickSignature);
604 return(cache_info->indexes);
605}
606
607/*
608%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
609% %
610% %
611% %
612+ G e t V i r t u a l P i x e l S t r e a m %
613% %
614% %
615% %
616%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617%
618% GetVirtualPixelStream() gets pixels from the in-memory or disk pixel cache as
619% defined by the geometry parameters. A pointer to the pixels is returned if
620% the pixels are transferred, otherwise a NULL is returned. For streams this
621% method is a no-op.
622%
623% The format of the GetVirtualPixelStream() method is:
624%
625% const PixelPacket *GetVirtualPixelStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000626% const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
627% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000628% ExceptionInfo *exception)
629%
630% A description of each parameter follows:
631%
632% o image: the image.
633%
634% o virtual_pixel_method: the virtual pixel method.
635%
636% o x,y,columns,rows: These values define the perimeter of a region of
637% pixels.
638%
639% o exception: return any errors or warnings in this structure.
640%
641*/
642
643static inline MagickBooleanType AcquireStreamPixels(CacheInfo *cache_info,
644 ExceptionInfo *exception)
645{
646 if (cache_info->length != (MagickSizeType) ((size_t) cache_info->length))
647 return(MagickFalse);
648 cache_info->mapped=MagickFalse;
649 cache_info->pixels=(PixelPacket *) AcquireMagickMemory((size_t)
650 cache_info->length);
651 if (cache_info->pixels == (PixelPacket *) NULL)
652 {
653 cache_info->mapped=MagickTrue;
654 cache_info->pixels=(PixelPacket *) MapBlob(-1,IOMode,0,(size_t)
655 cache_info->length);
656 }
657 if (cache_info->pixels == (PixelPacket *) NULL)
658 {
659 (void) ThrowMagickException(exception,GetMagickModule(),
660 ResourceLimitError,"MemoryAllocationFailed","`%s'",
661 cache_info->filename);
662 return(MagickFalse);
663 }
664 return(MagickTrue);
665}
666
667static const PixelPacket *GetVirtualPixelStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000668 const VirtualPixelMethod magick_unused(virtual_pixel_method),const ssize_t x,
669 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000670 ExceptionInfo *exception)
671{
672 CacheInfo
673 *cache_info;
674
675 MagickBooleanType
676 status;
677
678 MagickSizeType
679 number_pixels;
680
681 size_t
682 length;
683
684 /*
685 Validate pixel cache geometry.
686 */
687 assert(image != (const Image *) NULL);
688 assert(image->signature == MagickSignature);
689 if (image->debug != MagickFalse)
690 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy5dd71882010-08-01 20:53:13 +0000691 if ((x < 0) || (y < 0) ||
692 ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
693 ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
694 (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000695 {
696 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
697 "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
698 return((PixelPacket *) NULL);
699 }
700 cache_info=(CacheInfo *) image->cache;
701 assert(cache_info->signature == MagickSignature);
702 /*
703 Pixels are stored in a temporary buffer until they are synced to the cache.
704 */
705 number_pixels=(MagickSizeType) columns*rows;
706 length=(size_t) number_pixels*sizeof(PixelPacket);
707 if ((image->storage_class == PseudoClass) ||
708 (image->colorspace == CMYKColorspace))
709 length+=number_pixels*sizeof(IndexPacket);
710 if (cache_info->pixels == (PixelPacket *) NULL)
711 {
712 cache_info->length=length;
713 status=AcquireStreamPixels(cache_info,exception);
714 if (status == MagickFalse)
715 return((PixelPacket *) NULL);
716 }
717 else
718 if (cache_info->length != length)
719 {
720 RelinquishStreamPixels(cache_info);
721 cache_info->length=length;
722 status=AcquireStreamPixels(cache_info,exception);
723 if (status == MagickFalse)
724 return((PixelPacket *) NULL);
725 }
726 cache_info->indexes=(IndexPacket *) NULL;
727 if ((image->storage_class == PseudoClass) ||
728 (image->colorspace == CMYKColorspace))
729 cache_info->indexes=(IndexPacket *) (cache_info->pixels+number_pixels);
730 return(cache_info->pixels);
731}
732
733/*
734%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735% %
736% %
737% %
738+ O p e n S t r e a m %
739% %
740% %
741% %
742%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
743%
744% OpenStream() opens a stream for writing by the StreamImage() method.
745%
746% The format of the OpenStream method is:
747%
748% MagickBooleanType OpenStream(const ImageInfo *image_info,
749% StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
750%
751% A description of each parameter follows:
752%
753% o image_info: the image info.
754%
755% o stream_info: the stream info.
756%
757% o filename: the stream filename.
758%
759% o exception: return any errors or warnings in this structure.
760%
761*/
762MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
763 StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
764{
765 MagickBooleanType
766 status;
767
768 (void) CopyMagickString(stream_info->stream->filename,filename,MaxTextExtent);
769 status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
770 return(status);
771}
772
773/*
774%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
775% %
776% %
777% %
778+ 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 %
779% %
780% %
781% %
782%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783%
784% QueueAuthenticPixelsStream() allocates an area to store image pixels as
785% defined by the region rectangle and returns a pointer to the area. This
786% area is subsequently transferred from the pixel cache with method
787% SyncAuthenticPixelsStream(). A pointer to the pixels is returned if the
788% pixels are transferred, otherwise a NULL is returned.
789%
790% The format of the QueueAuthenticPixelsStream() method is:
791%
cristybb503372010-05-27 20:51:26 +0000792% PixelPacket *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
793% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000794% ExceptionInfo *exception)
795%
796% A description of each parameter follows:
797%
798% o image: the image.
799%
800% o x,y,columns,rows: These values define the perimeter of a region of
801% pixels.
802%
803*/
cristybb503372010-05-27 20:51:26 +0000804static PixelPacket *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
805 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000806 ExceptionInfo *exception)
807{
808 CacheInfo
809 *cache_info;
810
811 MagickSizeType
812 number_pixels;
813
814 size_t
815 length;
816
817 StreamHandler
818 stream_handler;
819
820 /*
821 Validate pixel cache geometry.
822 */
823 assert(image != (Image *) NULL);
cristybb503372010-05-27 20:51:26 +0000824 if ((x < 0) || (y < 0) || ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
825 ((y+(ssize_t) rows) > (ssize_t) image->rows) || (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000826 {
827 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
828 "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
829 return((PixelPacket *) NULL);
830 }
831 stream_handler=GetBlobStreamHandler(image);
832 if (stream_handler == (StreamHandler) NULL)
833 {
834 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
835 "NoStreamHandlerIsDefined","`%s'",image->filename);
836 return((PixelPacket *) NULL);
837 }
838 cache_info=(CacheInfo *) image->cache;
839 assert(cache_info->signature == MagickSignature);
840 if ((image->storage_class != GetPixelCacheStorageClass(image->cache)) ||
841 (image->colorspace != GetPixelCacheColorspace(image->cache)))
842 {
843 if (GetPixelCacheStorageClass(image->cache) == UndefinedClass)
844 (void) stream_handler(image,(const void *) NULL,(size_t)
845 cache_info->columns);
846 cache_info->storage_class=image->storage_class;
847 cache_info->colorspace=image->colorspace;
848 cache_info->columns=image->columns;
849 cache_info->rows=image->rows;
850 image->cache=cache_info;
851 }
852 /*
853 Pixels are stored in a temporary buffer until they are synced to the cache.
854 */
855 cache_info->columns=columns;
856 cache_info->rows=rows;
857 number_pixels=(MagickSizeType) columns*rows;
858 length=(size_t) number_pixels*sizeof(PixelPacket);
859 if ((image->storage_class == PseudoClass) ||
860 (image->colorspace == CMYKColorspace))
861 length+=number_pixels*sizeof(IndexPacket);
862 if (cache_info->pixels == (PixelPacket *) NULL)
863 {
864 cache_info->pixels=(PixelPacket *) AcquireMagickMemory(length);
865 cache_info->length=(MagickSizeType) length;
866 }
867 else
868 if (cache_info->length < (MagickSizeType) length)
869 {
870 cache_info->pixels=(PixelPacket *) ResizeMagickMemory(
871 cache_info->pixels,length);
872 cache_info->length=(MagickSizeType) length;
873 }
874 if (cache_info->pixels == (void *) NULL)
875 return((PixelPacket *) NULL);
876 cache_info->indexes=(IndexPacket *) NULL;
877 if ((image->storage_class == PseudoClass) ||
878 (image->colorspace == CMYKColorspace))
879 cache_info->indexes=(IndexPacket *) (cache_info->pixels+number_pixels);
880 return(cache_info->pixels);
881}
882
883/*
884%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885% %
886% %
887% %
888% R e a d S t r e a m %
889% %
890% %
891% %
892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893%
894% ReadStream() makes the image pixels available to a user supplied callback
895% method immediately upon reading a scanline with the ReadImage() method.
896%
897% The format of the ReadStream() method is:
898%
899% Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
900% ExceptionInfo *exception)
901%
902% A description of each parameter follows:
903%
904% o image_info: the image info.
905%
906% o stream: a callback method.
907%
908% o exception: return any errors or warnings in this structure.
909%
910*/
911MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
912 ExceptionInfo *exception)
913{
914 CacheMethods
915 cache_methods;
916
917 Image
918 *image;
919
920 ImageInfo
921 *read_info;
922
923 /*
924 Stream image pixels.
925 */
926 assert(image_info != (ImageInfo *) NULL);
927 assert(image_info->signature == MagickSignature);
928 if (image_info->debug != MagickFalse)
929 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
930 image_info->filename);
931 assert(exception != (ExceptionInfo *) NULL);
932 assert(exception->signature == MagickSignature);
933 read_info=CloneImageInfo(image_info);
934 read_info->cache=AcquirePixelCache(0);
935 GetPixelCacheMethods(&cache_methods);
936 cache_methods.get_virtual_pixel_handler=GetVirtualPixelStream;
937 cache_methods.get_virtual_indexes_from_handler=GetVirtualIndexesFromStream;
938 cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
939 cache_methods.get_authentic_pixels_handler=GetAuthenticPixelsStream;
940 cache_methods.queue_authentic_pixels_handler=QueueAuthenticPixelsStream;
941 cache_methods.sync_authentic_pixels_handler=SyncAuthenticPixelsStream;
942 cache_methods.get_authentic_pixels_from_handler=GetAuthenticPixelsFromStream;
943 cache_methods.get_authentic_indexes_from_handler=
944 GetAuthenticIndexesFromStream;
945 cache_methods.get_one_virtual_pixel_from_handler=GetOneVirtualPixelFromStream;
946 cache_methods.get_one_authentic_pixel_from_handler=
947 GetOneAuthenticPixelFromStream;
948 cache_methods.destroy_pixel_handler=DestroyPixelStream;
949 SetPixelCacheMethods(read_info->cache,&cache_methods);
950 read_info->stream=stream;
951 image=ReadImage(read_info,exception);
952 read_info=DestroyImageInfo(read_info);
953 return(image);
954}
955
956/*
957%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
958% %
959% %
960% %
961+ S e t S t r e a m I n f o C l i e n t D a t a %
962% %
963% %
964% %
965%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966%
967% SetStreamInfoClientData() sets the stream info client data.
968%
969% The format of the SetStreamInfoClientData method is:
970%
971% void SetStreamInfoClientData(StreamInfo *stream_info,
972% const void *client_data)
973%
974% A description of each parameter follows:
975%
976% o stream_info: the stream info.
977%
978% o client_data: the client data.
979%
980*/
981MagickExport void SetStreamInfoClientData(StreamInfo *stream_info,
982 const void *client_data)
983{
984 assert(stream_info != (StreamInfo *) NULL);
985 assert(stream_info->signature == MagickSignature);
986 stream_info->client_data=client_data;
987}
988
989/*
990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991% %
992% %
993% %
994+ S e t S t r e a m I n f o M a p %
995% %
996% %
997% %
998%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
999%
1000% SetStreamInfoMap() sets the stream info map member.
1001%
1002% The format of the SetStreamInfoMap method is:
1003%
1004% void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1005%
1006% A description of each parameter follows:
1007%
1008% o stream_info: the stream info.
1009%
1010% o map: the map.
1011%
1012*/
1013MagickExport void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1014{
1015 assert(stream_info != (StreamInfo *) NULL);
1016 assert(stream_info->signature == MagickSignature);
1017 (void) CloneString(&stream_info->map,map);
1018}
1019
1020/*
1021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1022% %
1023% %
1024% %
1025+ S e t S t r e a m I n f o S t o r a g e T y p e %
1026% %
1027% %
1028% %
1029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030%
1031% SetStreamInfoStorageType() sets the stream info storage type member.
1032%
1033% The format of the SetStreamInfoStorageType method is:
1034%
1035% void SetStreamInfoStorageType(StreamInfo *stream_info,
1036% const StoreageType *storage_type)
1037%
1038% A description of each parameter follows:
1039%
1040% o stream_info: the stream info.
1041%
1042% o storage_type: the storage type.
1043%
1044*/
1045MagickExport void SetStreamInfoStorageType(StreamInfo *stream_info,
1046 const StorageType storage_type)
1047{
1048 assert(stream_info != (StreamInfo *) NULL);
1049 assert(stream_info->signature == MagickSignature);
1050 stream_info->storage_type=storage_type;
1051}
1052
1053/*
1054%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1055% %
1056% %
1057% %
1058+ S t r e a m I m a g e %
1059% %
1060% %
1061% %
1062%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1063%
1064% StreamImage() streams pixels from an image and writes them in a user
1065% defined format and storage type (e.g. RGBA as 8-bit unsigned char).
1066%
1067% The format of he wStreamImage() method is:
1068%
1069% Image *StreamImage(const ImageInfo *image_info,
1070% StreamInfo *stream_info,ExceptionInfo *exception)
1071%
1072% A description of each parameter follows:
1073%
1074% o image_info: the image info.
1075%
1076% o stream_info: the stream info.
1077%
1078% o exception: return any errors or warnings in this structure.
1079%
1080*/
1081
1082#if defined(__cplusplus) || defined(c_plusplus)
1083extern "C" {
1084#endif
1085
1086static size_t WriteStreamImage(const Image *image,const void *pixels,
1087 const size_t columns)
1088{
cristye3664f42010-05-14 00:59:57 +00001089 CacheInfo
1090 *cache_info;
1091
cristy3ed852e2009-09-05 21:47:34 +00001092 RectangleInfo
1093 extract_info;
1094
1095 size_t
1096 length,
1097 packet_size;
1098
1099 ssize_t
1100 count;
1101
1102 StreamInfo
1103 *stream_info;
1104
1105 stream_info=(StreamInfo *) image->client_data;
1106 switch (stream_info->storage_type)
1107 {
1108 default: packet_size=sizeof(char); break;
1109 case CharPixel: packet_size=sizeof(char); break;
1110 case DoublePixel: packet_size=sizeof(double); break;
1111 case FloatPixel: packet_size=sizeof(float); break;
1112 case IntegerPixel: packet_size=sizeof(int); break;
cristybb503372010-05-27 20:51:26 +00001113 case LongPixel: packet_size=sizeof(ssize_t); break;
cristy3ed852e2009-09-05 21:47:34 +00001114 case QuantumPixel: packet_size=sizeof(Quantum); break;
1115 case ShortPixel: packet_size=sizeof(unsigned short); break;
1116 }
cristye3664f42010-05-14 00:59:57 +00001117 cache_info=(CacheInfo *) image->cache;
1118 assert(cache_info->signature == MagickSignature);
cristy3ed852e2009-09-05 21:47:34 +00001119 packet_size*=strlen(stream_info->map);
cristye3664f42010-05-14 00:59:57 +00001120 length=packet_size*cache_info->columns*cache_info->rows;
cristy3ed852e2009-09-05 21:47:34 +00001121 if (image != stream_info->image)
1122 {
1123 ImageInfo
1124 *write_info;
1125
1126 /*
1127 Prepare stream for writing.
1128 */
1129 stream_info->pixels=(unsigned char *) ResizeQuantumMemory(
1130 stream_info->pixels,length,sizeof(*stream_info->pixels));
cristy5dd71882010-08-01 20:53:13 +00001131 if (stream_info->pixels == (unsigned char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001132 return(0);
1133 stream_info->image=image;
1134 write_info=CloneImageInfo(stream_info->image_info);
cristyd965a422010-03-03 17:47:35 +00001135 (void) SetImageInfo(write_info,1,stream_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001136 if (write_info->extract != (char *) NULL)
1137 (void) ParseAbsoluteGeometry(write_info->extract,
1138 &stream_info->extract_info);
1139 stream_info->y=0;
1140 write_info=DestroyImageInfo(write_info);
1141 }
1142 extract_info=stream_info->extract_info;
1143 if ((extract_info.width == 0) ||
1144 (extract_info.height == 0))
1145 {
1146 /*
1147 Write all pixels to stream.
1148 */
1149 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1150 count=WriteBlob(stream_info->stream,length,stream_info->pixels);
1151 stream_info->y++;
1152 return(count == 0 ? 0 : columns);
1153 }
1154 if ((stream_info->y < extract_info.y) ||
cristybb503372010-05-27 20:51:26 +00001155 (stream_info->y >= (ssize_t) (extract_info.y+extract_info.height)))
cristy3ed852e2009-09-05 21:47:34 +00001156 {
1157 stream_info->y++;
1158 return(columns);
1159 }
1160 /*
1161 Write a portion of the pixel row to the stream.
1162 */
1163 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1164 length=packet_size*extract_info.width;
cristy5dd71882010-08-01 20:53:13 +00001165 count=WriteBlob(stream_info->stream,length,stream_info->pixels+packet_size*
1166 extract_info.x);
cristy3ed852e2009-09-05 21:47:34 +00001167 stream_info->y++;
1168 return(count == 0 ? 0 : columns);
1169}
1170
1171#if defined(__cplusplus) || defined(c_plusplus)
1172}
1173#endif
1174
1175MagickExport Image *StreamImage(const ImageInfo *image_info,
1176 StreamInfo *stream_info,ExceptionInfo *exception)
1177{
1178 Image
1179 *image;
1180
1181 ImageInfo
1182 *read_info;
1183
1184 assert(image_info != (const ImageInfo *) NULL);
1185 assert(image_info->signature == MagickSignature);
1186 if (image_info->debug != MagickFalse)
1187 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1188 image_info->filename);
1189 assert(stream_info != (StreamInfo *) NULL);
1190 assert(stream_info->signature == MagickSignature);
1191 assert(exception != (ExceptionInfo *) NULL);
1192 read_info=CloneImageInfo(image_info);
1193 stream_info->image_info=image_info;
1194 stream_info->exception=exception;
1195 read_info->client_data=(void *) stream_info;
1196 image=ReadStream(read_info,&WriteStreamImage,exception);
1197 read_info=DestroyImageInfo(read_info);
1198 stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
1199 if (stream_info->quantum_info == (QuantumInfo *) NULL)
1200 image=DestroyImage(image);
1201 return(image);
1202}
1203
1204/*
1205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1206% %
1207% %
1208% %
1209+ S t r e a m I m a g e P i x e l s %
1210% %
1211% %
1212% %
1213%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1214%
1215% StreamImagePixels() extracts pixel data from an image and returns it in the
1216% stream_info->pixels structure in the format as defined by
1217% stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
1218%
1219% The format of the StreamImagePixels method is:
1220%
1221% MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1222% const Image *image,ExceptionInfo *exception)
1223%
1224% A description of each parameter follows:
1225%
1226% o stream_info: the stream info.
1227%
1228% o image: the image.
1229%
1230% o exception: return any errors or warnings in this structure.
1231%
1232*/
1233static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1234 const Image *image,ExceptionInfo *exception)
1235{
1236 QuantumInfo
1237 *quantum_info;
1238
1239 QuantumType
1240 *quantum_map;
1241
cristybb503372010-05-27 20:51:26 +00001242 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001243 i,
1244 x;
1245
1246 register const PixelPacket
1247 *p;
1248
1249 register IndexPacket
1250 *indexes;
1251
1252 size_t
1253 length;
1254
1255 assert(stream_info != (StreamInfo *) NULL);
1256 assert(stream_info->signature == MagickSignature);
1257 assert(image != (Image *) NULL);
1258 assert(image->signature == MagickSignature);
1259 if (image->debug != MagickFalse)
1260 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1261 length=strlen(stream_info->map);
1262 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1263 if (quantum_map == (QuantumType *) NULL)
1264 {
1265 (void) ThrowMagickException(exception,GetMagickModule(),
1266 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1267 return(MagickFalse);
1268 }
cristybb503372010-05-27 20:51:26 +00001269 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001270 {
1271 switch (stream_info->map[i])
1272 {
1273 case 'A':
1274 case 'a':
1275 {
1276 quantum_map[i]=AlphaQuantum;
1277 break;
1278 }
1279 case 'B':
1280 case 'b':
1281 {
1282 quantum_map[i]=BlueQuantum;
1283 break;
1284 }
1285 case 'C':
1286 case 'c':
1287 {
1288 quantum_map[i]=CyanQuantum;
1289 if (image->colorspace == CMYKColorspace)
1290 break;
1291 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1292 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1293 "ColorSeparatedImageRequired","`%s'",stream_info->map);
1294 return(MagickFalse);
1295 }
1296 case 'g':
1297 case 'G':
1298 {
1299 quantum_map[i]=GreenQuantum;
1300 break;
1301 }
1302 case 'I':
1303 case 'i':
1304 {
1305 quantum_map[i]=IndexQuantum;
1306 break;
1307 }
1308 case 'K':
1309 case 'k':
1310 {
1311 quantum_map[i]=BlackQuantum;
1312 if (image->colorspace == CMYKColorspace)
1313 break;
1314 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1315 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1316 "ColorSeparatedImageRequired","`%s'",stream_info->map);
1317 return(MagickFalse);
1318 }
1319 case 'M':
1320 case 'm':
1321 {
1322 quantum_map[i]=MagentaQuantum;
1323 if (image->colorspace == CMYKColorspace)
1324 break;
1325 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1326 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1327 "ColorSeparatedImageRequired","`%s'",stream_info->map);
1328 return(MagickFalse);
1329 }
1330 case 'o':
1331 case 'O':
1332 {
1333 quantum_map[i]=OpacityQuantum;
1334 break;
1335 }
1336 case 'P':
1337 case 'p':
1338 {
1339 quantum_map[i]=UndefinedQuantum;
1340 break;
1341 }
1342 case 'R':
1343 case 'r':
1344 {
1345 quantum_map[i]=RedQuantum;
1346 break;
1347 }
1348 case 'Y':
1349 case 'y':
1350 {
1351 quantum_map[i]=YellowQuantum;
1352 if (image->colorspace == CMYKColorspace)
1353 break;
1354 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1355 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1356 "ColorSeparatedImageRequired","`%s'",stream_info->map);
1357 return(MagickFalse);
1358 }
1359 default:
1360 {
1361 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1362 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1363 "UnrecognizedPixelMap","`%s'",stream_info->map);
1364 return(MagickFalse);
1365 }
1366 }
1367 }
1368 quantum_info=stream_info->quantum_info;
1369 switch (stream_info->storage_type)
1370 {
1371 case CharPixel:
1372 {
1373 register unsigned char
1374 *q;
1375
1376 q=(unsigned char *) stream_info->pixels;
1377 if (LocaleCompare(stream_info->map,"BGR") == 0)
1378 {
1379 p=GetAuthenticPixelQueue(image);
1380 if (p == (const PixelPacket *) NULL)
1381 break;
cristybb503372010-05-27 20:51:26 +00001382 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001383 {
cristyce70c172010-01-07 17:15:30 +00001384 *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
1385 *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1386 *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001387 p++;
1388 }
1389 break;
1390 }
1391 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1392 {
1393 p=GetAuthenticPixelQueue(image);
1394 if (p == (const PixelPacket *) NULL)
1395 break;
cristybb503372010-05-27 20:51:26 +00001396 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001397 {
cristyce70c172010-01-07 17:15:30 +00001398 *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
1399 *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1400 *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
cristy46f08202010-01-10 04:04:21 +00001401 *q++=ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00001402 p++;
1403 }
1404 break;
1405 }
1406 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1407 {
1408 p=GetAuthenticPixelQueue(image);
1409 if (p == (const PixelPacket *) NULL)
1410 break;
cristybb503372010-05-27 20:51:26 +00001411 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001412 {
cristyce70c172010-01-07 17:15:30 +00001413 *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
1414 *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1415 *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001416 *q++=ScaleQuantumToChar((Quantum) 0);
1417 p++;
1418 }
1419 break;
1420 }
1421 if (LocaleCompare(stream_info->map,"I") == 0)
1422 {
1423 p=GetAuthenticPixelQueue(image);
1424 if (p == (const PixelPacket *) NULL)
1425 break;
cristybb503372010-05-27 20:51:26 +00001426 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001427 {
1428 *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
1429 p++;
1430 }
1431 break;
1432 }
1433 if (LocaleCompare(stream_info->map,"RGB") == 0)
1434 {
1435 p=GetAuthenticPixelQueue(image);
1436 if (p == (const PixelPacket *) NULL)
1437 break;
cristybb503372010-05-27 20:51:26 +00001438 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001439 {
cristyce70c172010-01-07 17:15:30 +00001440 *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
1441 *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1442 *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001443 p++;
1444 }
1445 break;
1446 }
1447 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1448 {
1449 p=GetAuthenticPixelQueue(image);
1450 if (p == (const PixelPacket *) NULL)
1451 break;
cristybb503372010-05-27 20:51:26 +00001452 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001453 {
cristyce70c172010-01-07 17:15:30 +00001454 *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
1455 *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1456 *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
cristy46f08202010-01-10 04:04:21 +00001457 *q++=ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00001458 p++;
1459 }
1460 break;
1461 }
1462 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1463 {
1464 p=GetAuthenticPixelQueue(image);
1465 if (p == (const PixelPacket *) NULL)
1466 break;
cristybb503372010-05-27 20:51:26 +00001467 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001468 {
cristyce70c172010-01-07 17:15:30 +00001469 *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
1470 *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1471 *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001472 *q++=ScaleQuantumToChar((Quantum) 0);
1473 p++;
1474 }
1475 break;
1476 }
1477 p=GetAuthenticPixelQueue(image);
1478 if (p == (const PixelPacket *) NULL)
1479 break;
1480 indexes=GetAuthenticIndexQueue(image);
cristybb503372010-05-27 20:51:26 +00001481 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001482 {
cristybb503372010-05-27 20:51:26 +00001483 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001484 {
1485 *q=0;
1486 switch (quantum_map[i])
1487 {
1488 case RedQuantum:
1489 case CyanQuantum:
1490 {
cristyce70c172010-01-07 17:15:30 +00001491 *q=ScaleQuantumToChar(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001492 break;
1493 }
1494 case GreenQuantum:
1495 case MagentaQuantum:
1496 {
cristyce70c172010-01-07 17:15:30 +00001497 *q=ScaleQuantumToChar(GetGreenPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001498 break;
1499 }
1500 case BlueQuantum:
1501 case YellowQuantum:
1502 {
cristyce70c172010-01-07 17:15:30 +00001503 *q=ScaleQuantumToChar(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001504 break;
1505 }
1506 case AlphaQuantum:
1507 {
cristy46f08202010-01-10 04:04:21 +00001508 *q=ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00001509 break;
1510 }
1511 case OpacityQuantum:
1512 {
cristyce70c172010-01-07 17:15:30 +00001513 *q=ScaleQuantumToChar(GetOpacityPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001514 break;
1515 }
1516 case BlackQuantum:
1517 {
1518 if (image->colorspace == CMYKColorspace)
1519 *q=ScaleQuantumToChar(indexes[x]);
1520 break;
1521 }
1522 case IndexQuantum:
1523 {
1524 *q=ScaleQuantumToChar(PixelIntensityToQuantum(p));
1525 break;
1526 }
1527 default:
1528 break;
1529 }
1530 q++;
1531 }
1532 p++;
1533 }
1534 break;
1535 }
1536 case DoublePixel:
1537 {
1538 register double
1539 *q;
1540
1541 q=(double *) stream_info->pixels;
1542 if (LocaleCompare(stream_info->map,"BGR") == 0)
1543 {
1544 p=GetAuthenticPixelQueue(image);
1545 if (p == (const PixelPacket *) NULL)
1546 break;
cristybb503372010-05-27 20:51:26 +00001547 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001548 {
cristy46f08202010-01-10 04:04:21 +00001549 *q++=(double) ((QuantumScale*GetBluePixelComponent(p))*
1550 quantum_info->scale+quantum_info->minimum);
1551 *q++=(double) ((QuantumScale*GetGreenPixelComponent(p))*
1552 quantum_info->scale+quantum_info->minimum);
1553 *q++=(double) ((QuantumScale*GetRedPixelComponent(p))*
1554 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001555 p++;
1556 }
1557 break;
1558 }
1559 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1560 {
1561 p=GetAuthenticPixelQueue(image);
1562 if (p == (const PixelPacket *) NULL)
1563 break;
cristybb503372010-05-27 20:51:26 +00001564 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001565 {
cristy46f08202010-01-10 04:04:21 +00001566 *q++=(double) ((QuantumScale*GetBluePixelComponent(p))*
1567 quantum_info->scale+quantum_info->minimum);
1568 *q++=(double) ((QuantumScale*GetGreenPixelComponent(p))*
1569 quantum_info->scale+quantum_info->minimum);
1570 *q++=(double) ((QuantumScale*GetRedPixelComponent(p))*
1571 quantum_info->scale+quantum_info->minimum);
1572 *q++=(double) ((QuantumScale*GetAlphaPixelComponent(p))*
cristy3ed852e2009-09-05 21:47:34 +00001573 quantum_info->scale+quantum_info->minimum);
1574 p++;
1575 }
1576 break;
1577 }
1578 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1579 {
1580 p=GetAuthenticPixelQueue(image);
1581 if (p == (const PixelPacket *) NULL)
1582 break;
cristybb503372010-05-27 20:51:26 +00001583 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001584 {
cristy46f08202010-01-10 04:04:21 +00001585 *q++=(double) ((QuantumScale*GetBluePixelComponent(p))*
1586 quantum_info->scale+quantum_info->minimum);
1587 *q++=(double) ((QuantumScale*GetGreenPixelComponent(p))*
1588 quantum_info->scale+quantum_info->minimum);
1589 *q++=(double) ((QuantumScale*GetRedPixelComponent(p))*
1590 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001591 *q++=0.0;
1592 p++;
1593 }
1594 break;
1595 }
1596 if (LocaleCompare(stream_info->map,"I") == 0)
1597 {
1598 p=GetAuthenticPixelQueue(image);
1599 if (p == (const PixelPacket *) NULL)
1600 break;
cristybb503372010-05-27 20:51:26 +00001601 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001602 {
1603 *q++=(double) ((QuantumScale*PixelIntensityToQuantum(p))*
1604 quantum_info->scale+quantum_info->minimum);
1605 p++;
1606 }
1607 break;
1608 }
1609 if (LocaleCompare(stream_info->map,"RGB") == 0)
1610 {
1611 p=GetAuthenticPixelQueue(image);
1612 if (p == (const PixelPacket *) NULL)
1613 break;
cristybb503372010-05-27 20:51:26 +00001614 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001615 {
cristy46f08202010-01-10 04:04:21 +00001616 *q++=(double) ((QuantumScale*GetRedPixelComponent(p))*
1617 quantum_info->scale+quantum_info->minimum);
1618 *q++=(double) ((QuantumScale*GetGreenPixelComponent(p))*
1619 quantum_info->scale+quantum_info->minimum);
1620 *q++=(double) ((QuantumScale*GetBluePixelComponent(p))*
1621 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001622 p++;
1623 }
1624 break;
1625 }
1626 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1627 {
1628 p=GetAuthenticPixelQueue(image);
1629 if (p == (const PixelPacket *) NULL)
1630 break;
cristybb503372010-05-27 20:51:26 +00001631 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001632 {
cristy46f08202010-01-10 04:04:21 +00001633 *q++=(double) ((QuantumScale*GetRedPixelComponent(p))*
1634 quantum_info->scale+quantum_info->minimum);
1635 *q++=(double) ((QuantumScale*GetGreenPixelComponent(p))*
1636 quantum_info->scale+quantum_info->minimum);
1637 *q++=(double) ((QuantumScale*GetBluePixelComponent(p))*
1638 quantum_info->scale+quantum_info->minimum);
1639 *q++=(double) ((QuantumScale*GetAlphaPixelComponent(p))*
cristy3ed852e2009-09-05 21:47:34 +00001640 quantum_info->scale+quantum_info->minimum);
1641 p++;
1642 }
1643 break;
1644 }
1645 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1646 {
1647 p=GetAuthenticPixelQueue(image);
1648 if (p == (const PixelPacket *) NULL)
1649 break;
cristybb503372010-05-27 20:51:26 +00001650 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001651 {
cristy46f08202010-01-10 04:04:21 +00001652 *q++=(double) ((QuantumScale*GetRedPixelComponent(p))*
1653 quantum_info->scale+quantum_info->minimum);
1654 *q++=(double) ((QuantumScale*GetGreenPixelComponent(p))*
1655 quantum_info->scale+quantum_info->minimum);
1656 *q++=(double) ((QuantumScale*GetBluePixelComponent(p))*
1657 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001658 *q++=0.0;
1659 p++;
1660 }
1661 break;
1662 }
1663 p=GetAuthenticPixelQueue(image);
1664 if (p == (const PixelPacket *) NULL)
1665 break;
1666 indexes=GetAuthenticIndexQueue(image);
cristybb503372010-05-27 20:51:26 +00001667 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001668 {
cristybb503372010-05-27 20:51:26 +00001669 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001670 {
1671 *q=0;
1672 switch (quantum_map[i])
1673 {
1674 case RedQuantum:
1675 case CyanQuantum:
1676 {
cristy46f08202010-01-10 04:04:21 +00001677 *q=(double) ((QuantumScale*GetRedPixelComponent(p))*
1678 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001679 break;
1680 }
1681 case GreenQuantum:
1682 case MagentaQuantum:
1683 {
cristy46f08202010-01-10 04:04:21 +00001684 *q=(double) ((QuantumScale*GetGreenPixelComponent(p))*
1685 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001686 break;
1687 }
1688 case BlueQuantum:
1689 case YellowQuantum:
1690 {
cristy46f08202010-01-10 04:04:21 +00001691 *q=(double) ((QuantumScale*GetBluePixelComponent(p))*
1692 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001693 break;
1694 }
1695 case AlphaQuantum:
1696 {
cristy46f08202010-01-10 04:04:21 +00001697 *q=(double) ((QuantumScale*GetAlphaPixelComponent(p))*
1698 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001699 break;
1700 }
1701 case OpacityQuantum:
1702 {
cristy46f08202010-01-10 04:04:21 +00001703 *q=(double) ((QuantumScale*GetOpacityPixelComponent(p))*
1704 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001705 break;
1706 }
1707 case BlackQuantum:
1708 {
1709 if (image->colorspace == CMYKColorspace)
1710 *q=(double) ((QuantumScale*indexes[x])*quantum_info->scale+
1711 quantum_info->minimum);
1712 break;
1713 }
1714 case IndexQuantum:
1715 {
1716 *q=(double) ((QuantumScale*PixelIntensityToQuantum(p))*
1717 quantum_info->scale+quantum_info->minimum);
1718 break;
1719 }
1720 default:
1721 *q=0;
1722 }
1723 q++;
1724 }
1725 p++;
1726 }
1727 break;
1728 }
1729 case FloatPixel:
1730 {
1731 register float
1732 *q;
1733
1734 q=(float *) stream_info->pixels;
1735 if (LocaleCompare(stream_info->map,"BGR") == 0)
1736 {
1737 p=GetAuthenticPixelQueue(image);
1738 if (p == (const PixelPacket *) NULL)
1739 break;
cristybb503372010-05-27 20:51:26 +00001740 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001741 {
cristy46f08202010-01-10 04:04:21 +00001742 *q++=(float) ((QuantumScale*GetBluePixelComponent(p))*
1743 quantum_info->scale+quantum_info->minimum);
1744 *q++=(float) ((QuantumScale*GetGreenPixelComponent(p))*
1745 quantum_info->scale+quantum_info->minimum);
1746 *q++=(float) ((QuantumScale*GetRedPixelComponent(p))*
1747 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001748 p++;
1749 }
1750 break;
1751 }
1752 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1753 {
1754 p=GetAuthenticPixelQueue(image);
1755 if (p == (const PixelPacket *) NULL)
1756 break;
cristybb503372010-05-27 20:51:26 +00001757 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001758 {
cristy46f08202010-01-10 04:04:21 +00001759 *q++=(float) ((QuantumScale*GetBluePixelComponent(p))*
1760 quantum_info->scale+quantum_info->minimum);
1761 *q++=(float) ((QuantumScale*GetGreenPixelComponent(p))*
1762 quantum_info->scale+quantum_info->minimum);
1763 *q++=(float) ((QuantumScale*GetRedPixelComponent(p))*
1764 quantum_info->scale+quantum_info->minimum);
1765 *q++=(float) ((QuantumScale*(Quantum) (GetAlphaPixelComponent(p)))*
cristy3ed852e2009-09-05 21:47:34 +00001766 quantum_info->scale+quantum_info->minimum);
1767 p++;
1768 }
1769 break;
1770 }
1771 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1772 {
1773 p=GetAuthenticPixelQueue(image);
1774 if (p == (const PixelPacket *) NULL)
1775 break;
cristybb503372010-05-27 20:51:26 +00001776 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001777 {
cristy46f08202010-01-10 04:04:21 +00001778 *q++=(float) ((QuantumScale*GetBluePixelComponent(p))*
1779 quantum_info->scale+quantum_info->minimum);
1780 *q++=(float) ((QuantumScale*GetGreenPixelComponent(p))*
1781 quantum_info->scale+quantum_info->minimum);
1782 *q++=(float) ((QuantumScale*GetRedPixelComponent(p))*
1783 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001784 *q++=0.0;
1785 p++;
1786 }
1787 break;
1788 }
1789 if (LocaleCompare(stream_info->map,"I") == 0)
1790 {
1791 p=GetAuthenticPixelQueue(image);
1792 if (p == (const PixelPacket *) NULL)
1793 break;
cristybb503372010-05-27 20:51:26 +00001794 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001795 {
1796 *q++=(float) ((QuantumScale*PixelIntensityToQuantum(p))*
1797 quantum_info->scale+quantum_info->minimum);
1798 p++;
1799 }
1800 break;
1801 }
1802 if (LocaleCompare(stream_info->map,"RGB") == 0)
1803 {
1804 p=GetAuthenticPixelQueue(image);
1805 if (p == (const PixelPacket *) NULL)
1806 break;
cristybb503372010-05-27 20:51:26 +00001807 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001808 {
cristy46f08202010-01-10 04:04:21 +00001809 *q++=(float) ((QuantumScale*GetRedPixelComponent(p))*
1810 quantum_info->scale+quantum_info->minimum);
1811 *q++=(float) ((QuantumScale*GetGreenPixelComponent(p))*
1812 quantum_info->scale+quantum_info->minimum);
1813 *q++=(float) ((QuantumScale*GetBluePixelComponent(p))*
1814 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001815 p++;
1816 }
1817 break;
1818 }
1819 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1820 {
1821 p=GetAuthenticPixelQueue(image);
1822 if (p == (const PixelPacket *) NULL)
1823 break;
cristybb503372010-05-27 20:51:26 +00001824 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001825 {
cristy46f08202010-01-10 04:04:21 +00001826 *q++=(float) ((QuantumScale*GetRedPixelComponent(p))*
1827 quantum_info->scale+quantum_info->minimum);
1828 *q++=(float) ((QuantumScale*GetGreenPixelComponent(p))*
1829 quantum_info->scale+quantum_info->minimum);
1830 *q++=(float) ((QuantumScale*GetBluePixelComponent(p))*
1831 quantum_info->scale+quantum_info->minimum);
1832 *q++=(float) ((QuantumScale*GetAlphaPixelComponent(p))*
cristy3ed852e2009-09-05 21:47:34 +00001833 quantum_info->scale+quantum_info->minimum);
1834 p++;
1835 }
1836 break;
1837 }
1838 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1839 {
1840 p=GetAuthenticPixelQueue(image);
1841 if (p == (const PixelPacket *) NULL)
1842 break;
cristybb503372010-05-27 20:51:26 +00001843 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001844 {
cristy46f08202010-01-10 04:04:21 +00001845 *q++=(float) ((QuantumScale*GetRedPixelComponent(p))*
1846 quantum_info->scale+quantum_info->minimum);
1847 *q++=(float) ((QuantumScale*GetGreenPixelComponent(p))*
1848 quantum_info->scale+quantum_info->minimum);
1849 *q++=(float) ((QuantumScale*GetBluePixelComponent(p))*
1850 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001851 *q++=0.0;
1852 p++;
1853 }
1854 break;
1855 }
1856 p=GetAuthenticPixelQueue(image);
1857 if (p == (const PixelPacket *) NULL)
1858 break;
1859 indexes=GetAuthenticIndexQueue(image);
cristybb503372010-05-27 20:51:26 +00001860 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001861 {
cristybb503372010-05-27 20:51:26 +00001862 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001863 {
1864 *q=0;
1865 switch (quantum_map[i])
1866 {
1867 case RedQuantum:
1868 case CyanQuantum:
1869 {
cristy46f08202010-01-10 04:04:21 +00001870 *q=(float) ((QuantumScale*GetRedPixelComponent(p))*
1871 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001872 break;
1873 }
1874 case GreenQuantum:
1875 case MagentaQuantum:
1876 {
cristy46f08202010-01-10 04:04:21 +00001877 *q=(float) ((QuantumScale*GetGreenPixelComponent(p))*
1878 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001879 break;
1880 }
1881 case BlueQuantum:
1882 case YellowQuantum:
1883 {
cristy46f08202010-01-10 04:04:21 +00001884 *q=(float) ((QuantumScale*GetBluePixelComponent(p))*
1885 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001886 break;
1887 }
1888 case AlphaQuantum:
1889 {
cristy46f08202010-01-10 04:04:21 +00001890 *q=(float) ((QuantumScale*GetAlphaPixelComponent(p))*
1891 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001892 break;
1893 }
1894 case OpacityQuantum:
1895 {
cristy46f08202010-01-10 04:04:21 +00001896 *q=(float) ((QuantumScale*GetOpacityPixelComponent(p))*
1897 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001898 break;
1899 }
1900 case BlackQuantum:
1901 {
1902 if (image->colorspace == CMYKColorspace)
1903 *q=(float) ((QuantumScale*indexes[x])*quantum_info->scale+
1904 quantum_info->minimum);
1905 break;
1906 }
1907 case IndexQuantum:
1908 {
1909 *q=(float) ((QuantumScale*PixelIntensityToQuantum(p))*
1910 quantum_info->scale+quantum_info->minimum);
1911 break;
1912 }
1913 default:
1914 *q=0;
1915 }
1916 q++;
1917 }
1918 p++;
1919 }
1920 break;
1921 }
1922 case IntegerPixel:
1923 {
1924 register unsigned int
1925 *q;
1926
1927 q=(unsigned int *) stream_info->pixels;
1928 if (LocaleCompare(stream_info->map,"BGR") == 0)
1929 {
1930 p=GetAuthenticPixelQueue(image);
1931 if (p == (const PixelPacket *) NULL)
1932 break;
cristybb503372010-05-27 20:51:26 +00001933 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001934 {
cristyce70c172010-01-07 17:15:30 +00001935 *q++=(unsigned int) ScaleQuantumToLong(GetBluePixelComponent(p));
1936 *q++=(unsigned int) ScaleQuantumToLong(GetGreenPixelComponent(p));
1937 *q++=(unsigned int) ScaleQuantumToLong(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001938 p++;
1939 }
1940 break;
1941 }
1942 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1943 {
1944 p=GetAuthenticPixelQueue(image);
1945 if (p == (const PixelPacket *) NULL)
1946 break;
cristybb503372010-05-27 20:51:26 +00001947 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001948 {
cristyce70c172010-01-07 17:15:30 +00001949 *q++=(unsigned int) ScaleQuantumToLong(GetBluePixelComponent(p));
1950 *q++=(unsigned int) ScaleQuantumToLong(GetGreenPixelComponent(p));
1951 *q++=(unsigned int) ScaleQuantumToLong(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001952 *q++=(unsigned int) ScaleQuantumToLong((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00001953 GetOpacityPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00001954 p++;
1955 }
1956 break;
1957 }
1958 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1959 {
1960 p=GetAuthenticPixelQueue(image);
1961 if (p == (const PixelPacket *) NULL)
1962 break;
cristybb503372010-05-27 20:51:26 +00001963 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001964 {
cristyce70c172010-01-07 17:15:30 +00001965 *q++=(unsigned int) ScaleQuantumToLong(GetBluePixelComponent(p));
1966 *q++=(unsigned int) ScaleQuantumToLong(GetGreenPixelComponent(p));
1967 *q++=(unsigned int) ScaleQuantumToLong(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001968 *q++=0U;
1969 p++;
1970 }
1971 break;
1972 }
1973 if (LocaleCompare(stream_info->map,"I") == 0)
1974 {
1975 p=GetAuthenticPixelQueue(image);
1976 if (p == (const PixelPacket *) NULL)
1977 break;
cristybb503372010-05-27 20:51:26 +00001978 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001979 {
1980 *q++=(unsigned int) ScaleQuantumToLong(
1981 PixelIntensityToQuantum(p));
1982 p++;
1983 }
1984 break;
1985 }
1986 if (LocaleCompare(stream_info->map,"RGB") == 0)
1987 {
1988 p=GetAuthenticPixelQueue(image);
1989 if (p == (const PixelPacket *) NULL)
1990 break;
cristybb503372010-05-27 20:51:26 +00001991 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001992 {
cristyce70c172010-01-07 17:15:30 +00001993 *q++=(unsigned int) ScaleQuantumToLong(GetRedPixelComponent(p));
1994 *q++=(unsigned int) ScaleQuantumToLong(GetGreenPixelComponent(p));
1995 *q++=(unsigned int) ScaleQuantumToLong(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001996 p++;
1997 }
1998 break;
1999 }
2000 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2001 {
2002 p=GetAuthenticPixelQueue(image);
2003 if (p == (const PixelPacket *) NULL)
2004 break;
cristybb503372010-05-27 20:51:26 +00002005 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002006 {
cristyce70c172010-01-07 17:15:30 +00002007 *q++=(unsigned int) ScaleQuantumToLong(GetRedPixelComponent(p));
2008 *q++=(unsigned int) ScaleQuantumToLong(GetGreenPixelComponent(p));
2009 *q++=(unsigned int) ScaleQuantumToLong(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002010 *q++=(unsigned int) ScaleQuantumToLong((Quantum)
cristy46f08202010-01-10 04:04:21 +00002011 (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00002012 p++;
2013 }
2014 break;
2015 }
2016 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2017 {
2018 p=GetAuthenticPixelQueue(image);
2019 if (p == (const PixelPacket *) NULL)
2020 break;
cristybb503372010-05-27 20:51:26 +00002021 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002022 {
cristyce70c172010-01-07 17:15:30 +00002023 *q++=(unsigned int) ScaleQuantumToLong(GetRedPixelComponent(p));
2024 *q++=(unsigned int) ScaleQuantumToLong(GetGreenPixelComponent(p));
2025 *q++=(unsigned int) ScaleQuantumToLong(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002026 *q++=0U;
2027 p++;
2028 }
2029 break;
2030 }
2031 p=GetAuthenticPixelQueue(image);
2032 if (p == (const PixelPacket *) NULL)
2033 break;
2034 indexes=GetAuthenticIndexQueue(image);
cristybb503372010-05-27 20:51:26 +00002035 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002036 {
cristybb503372010-05-27 20:51:26 +00002037 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002038 {
2039 *q=0;
2040 switch (quantum_map[i])
2041 {
2042 case RedQuantum:
2043 case CyanQuantum:
2044 {
cristyce70c172010-01-07 17:15:30 +00002045 *q=(unsigned int) ScaleQuantumToLong(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002046 break;
2047 }
2048 case GreenQuantum:
2049 case MagentaQuantum:
2050 {
cristyce70c172010-01-07 17:15:30 +00002051 *q=(unsigned int) ScaleQuantumToLong(GetGreenPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002052 break;
2053 }
2054 case BlueQuantum:
2055 case YellowQuantum:
2056 {
cristyce70c172010-01-07 17:15:30 +00002057 *q=(unsigned int) ScaleQuantumToLong(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002058 break;
2059 }
2060 case AlphaQuantum:
2061 {
2062 *q=(unsigned int) ScaleQuantumToLong((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002063 GetOpacityPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00002064 break;
2065 }
2066 case OpacityQuantum:
2067 {
cristyce70c172010-01-07 17:15:30 +00002068 *q=(unsigned int) ScaleQuantumToLong(GetOpacityPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002069 break;
2070 }
2071 case BlackQuantum:
2072 {
2073 if (image->colorspace == CMYKColorspace)
2074 *q=(unsigned int) ScaleQuantumToLong(indexes[x]);
2075 break;
2076 }
2077 case IndexQuantum:
2078 {
2079 *q=(unsigned int)
2080 ScaleQuantumToLong(PixelIntensityToQuantum(p));
2081 break;
2082 }
2083 default:
2084 *q=0;
2085 }
2086 q++;
2087 }
2088 p++;
2089 }
2090 break;
2091 }
2092 case LongPixel:
2093 {
cristybb503372010-05-27 20:51:26 +00002094 register size_t
cristy3ed852e2009-09-05 21:47:34 +00002095 *q;
2096
cristybb503372010-05-27 20:51:26 +00002097 q=(size_t *) stream_info->pixels;
cristy3ed852e2009-09-05 21:47:34 +00002098 if (LocaleCompare(stream_info->map,"BGR") == 0)
2099 {
2100 p=GetAuthenticPixelQueue(image);
2101 if (p == (const PixelPacket *) NULL)
2102 break;
cristybb503372010-05-27 20:51:26 +00002103 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002104 {
cristyce70c172010-01-07 17:15:30 +00002105 *q++=ScaleQuantumToLong(GetBluePixelComponent(p));
2106 *q++=ScaleQuantumToLong(GetGreenPixelComponent(p));
2107 *q++=ScaleQuantumToLong(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002108 p++;
2109 }
2110 break;
2111 }
2112 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2113 {
2114 p=GetAuthenticPixelQueue(image);
2115 if (p == (const PixelPacket *) NULL)
2116 break;
cristybb503372010-05-27 20:51:26 +00002117 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002118 {
cristyce70c172010-01-07 17:15:30 +00002119 *q++=ScaleQuantumToLong(GetBluePixelComponent(p));
2120 *q++=ScaleQuantumToLong(GetGreenPixelComponent(p));
2121 *q++=ScaleQuantumToLong(GetRedPixelComponent(p));
cristy46f08202010-01-10 04:04:21 +00002122 *q++=ScaleQuantumToLong((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00002123 p++;
2124 }
2125 break;
2126 }
2127 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2128 {
2129 p=GetAuthenticPixelQueue(image);
2130 if (p == (const PixelPacket *) NULL)
2131 break;
cristybb503372010-05-27 20:51:26 +00002132 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002133 {
cristyce70c172010-01-07 17:15:30 +00002134 *q++=ScaleQuantumToLong(GetBluePixelComponent(p));
2135 *q++=ScaleQuantumToLong(GetGreenPixelComponent(p));
2136 *q++=ScaleQuantumToLong(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002137 *q++=0;
2138 p++;
2139 }
2140 break;
2141 }
2142 if (LocaleCompare(stream_info->map,"I") == 0)
2143 {
2144 p=GetAuthenticPixelQueue(image);
2145 if (p == (const PixelPacket *) NULL)
2146 break;
cristybb503372010-05-27 20:51:26 +00002147 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002148 {
2149 *q++=ScaleQuantumToLong(PixelIntensityToQuantum(p));
2150 p++;
2151 }
2152 break;
2153 }
2154 if (LocaleCompare(stream_info->map,"RGB") == 0)
2155 {
2156 p=GetAuthenticPixelQueue(image);
2157 if (p == (const PixelPacket *) NULL)
2158 break;
cristybb503372010-05-27 20:51:26 +00002159 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002160 {
cristyce70c172010-01-07 17:15:30 +00002161 *q++=ScaleQuantumToLong(GetRedPixelComponent(p));
2162 *q++=ScaleQuantumToLong(GetGreenPixelComponent(p));
2163 *q++=ScaleQuantumToLong(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002164 p++;
2165 }
2166 break;
2167 }
2168 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2169 {
2170 p=GetAuthenticPixelQueue(image);
2171 if (p == (const PixelPacket *) NULL)
2172 break;
cristybb503372010-05-27 20:51:26 +00002173 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002174 {
cristyce70c172010-01-07 17:15:30 +00002175 *q++=ScaleQuantumToLong(GetRedPixelComponent(p));
2176 *q++=ScaleQuantumToLong(GetGreenPixelComponent(p));
2177 *q++=ScaleQuantumToLong(GetBluePixelComponent(p));
cristy46f08202010-01-10 04:04:21 +00002178 *q++=ScaleQuantumToLong((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00002179 p++;
2180 }
2181 break;
2182 }
2183 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2184 {
2185 p=GetAuthenticPixelQueue(image);
2186 if (p == (const PixelPacket *) NULL)
2187 break;
cristybb503372010-05-27 20:51:26 +00002188 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002189 {
cristyce70c172010-01-07 17:15:30 +00002190 *q++=ScaleQuantumToLong(GetRedPixelComponent(p));
2191 *q++=ScaleQuantumToLong(GetGreenPixelComponent(p));
2192 *q++=ScaleQuantumToLong(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002193 *q++=0;
2194 p++;
2195 }
2196 break;
2197 }
2198 p=GetAuthenticPixelQueue(image);
2199 if (p == (const PixelPacket *) NULL)
2200 break;
2201 indexes=GetAuthenticIndexQueue(image);
cristybb503372010-05-27 20:51:26 +00002202 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002203 {
cristybb503372010-05-27 20:51:26 +00002204 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002205 {
2206 *q=0;
2207 switch (quantum_map[i])
2208 {
2209 case RedQuantum:
2210 case CyanQuantum:
2211 {
cristyce70c172010-01-07 17:15:30 +00002212 *q=ScaleQuantumToLong(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002213 break;
2214 }
2215 case GreenQuantum:
2216 case MagentaQuantum:
2217 {
cristyce70c172010-01-07 17:15:30 +00002218 *q=ScaleQuantumToLong(GetGreenPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002219 break;
2220 }
2221 case BlueQuantum:
2222 case YellowQuantum:
2223 {
cristyce70c172010-01-07 17:15:30 +00002224 *q=ScaleQuantumToLong(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002225 break;
2226 }
2227 case AlphaQuantum:
2228 {
cristy46f08202010-01-10 04:04:21 +00002229 *q=ScaleQuantumToLong((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00002230 break;
2231 }
2232 case OpacityQuantum:
2233 {
cristyce70c172010-01-07 17:15:30 +00002234 *q=ScaleQuantumToLong(GetOpacityPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002235 break;
2236 }
2237 case BlackQuantum:
2238 {
2239 if (image->colorspace == CMYKColorspace)
2240 *q=ScaleQuantumToLong(indexes[x]);
2241 break;
2242 }
2243 case IndexQuantum:
2244 {
2245 *q=ScaleQuantumToLong(PixelIntensityToQuantum(p));
2246 break;
2247 }
2248 default:
2249 break;
2250 }
2251 q++;
2252 }
2253 p++;
2254 }
2255 break;
2256 }
2257 case QuantumPixel:
2258 {
2259 register Quantum
2260 *q;
2261
2262 q=(Quantum *) stream_info->pixels;
2263 if (LocaleCompare(stream_info->map,"BGR") == 0)
2264 {
2265 p=GetAuthenticPixelQueue(image);
2266 if (p == (const PixelPacket *) NULL)
2267 break;
cristybb503372010-05-27 20:51:26 +00002268 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002269 {
cristyce70c172010-01-07 17:15:30 +00002270 *q++=GetBluePixelComponent(p);
2271 *q++=GetGreenPixelComponent(p);
2272 *q++=GetRedPixelComponent(p);
cristy3ed852e2009-09-05 21:47:34 +00002273 p++;
2274 }
2275 break;
2276 }
2277 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2278 {
2279 p=GetAuthenticPixelQueue(image);
2280 if (p == (const PixelPacket *) NULL)
2281 break;
cristybb503372010-05-27 20:51:26 +00002282 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002283 {
cristyce70c172010-01-07 17:15:30 +00002284 *q++=GetBluePixelComponent(p);
2285 *q++=GetGreenPixelComponent(p);
2286 *q++=GetRedPixelComponent(p);
cristy46f08202010-01-10 04:04:21 +00002287 *q++=(Quantum) (GetAlphaPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002288 p++;
2289 }
2290 break;
2291 }
2292 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2293 {
2294 p=GetAuthenticPixelQueue(image);
2295 if (p == (const PixelPacket *) NULL)
2296 break;
cristybb503372010-05-27 20:51:26 +00002297 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002298 {
cristyce70c172010-01-07 17:15:30 +00002299 *q++=GetBluePixelComponent(p);
2300 *q++=GetGreenPixelComponent(p);
2301 *q++=GetRedPixelComponent(p);
cristy3ed852e2009-09-05 21:47:34 +00002302 *q++=0;
2303 p++;
2304 }
2305 break;
2306 }
2307 if (LocaleCompare(stream_info->map,"I") == 0)
2308 {
2309 p=GetAuthenticPixelQueue(image);
2310 if (p == (const PixelPacket *) NULL)
2311 break;
cristybb503372010-05-27 20:51:26 +00002312 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002313 {
2314 *q++=PixelIntensityToQuantum(p);
2315 p++;
2316 }
2317 break;
2318 }
2319 if (LocaleCompare(stream_info->map,"RGB") == 0)
2320 {
2321 p=GetAuthenticPixelQueue(image);
2322 if (p == (const PixelPacket *) NULL)
2323 break;
cristybb503372010-05-27 20:51:26 +00002324 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002325 {
cristyce70c172010-01-07 17:15:30 +00002326 *q++=GetRedPixelComponent(p);
2327 *q++=GetGreenPixelComponent(p);
2328 *q++=GetBluePixelComponent(p);
cristy3ed852e2009-09-05 21:47:34 +00002329 p++;
2330 }
2331 break;
2332 }
2333 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2334 {
2335 p=GetAuthenticPixelQueue(image);
2336 if (p == (const PixelPacket *) NULL)
2337 break;
cristybb503372010-05-27 20:51:26 +00002338 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002339 {
cristyce70c172010-01-07 17:15:30 +00002340 *q++=GetRedPixelComponent(p);
2341 *q++=GetGreenPixelComponent(p);
2342 *q++=GetBluePixelComponent(p);
cristy46f08202010-01-10 04:04:21 +00002343 *q++=(Quantum) (GetAlphaPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002344 p++;
2345 }
2346 break;
2347 }
2348 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2349 {
2350 p=GetAuthenticPixelQueue(image);
2351 if (p == (const PixelPacket *) NULL)
2352 break;
cristybb503372010-05-27 20:51:26 +00002353 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002354 {
cristyce70c172010-01-07 17:15:30 +00002355 *q++=GetRedPixelComponent(p);
2356 *q++=GetGreenPixelComponent(p);
2357 *q++=GetBluePixelComponent(p);
cristy3ed852e2009-09-05 21:47:34 +00002358 *q++=0U;
2359 p++;
2360 }
2361 break;
2362 }
2363 p=GetAuthenticPixelQueue(image);
2364 if (p == (const PixelPacket *) NULL)
2365 break;
2366 indexes=GetAuthenticIndexQueue(image);
cristybb503372010-05-27 20:51:26 +00002367 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002368 {
cristybb503372010-05-27 20:51:26 +00002369 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002370 {
2371 *q=(Quantum) 0;
2372 switch (quantum_map[i])
2373 {
2374 case RedQuantum:
2375 case CyanQuantum:
2376 {
cristyce70c172010-01-07 17:15:30 +00002377 *q=GetRedPixelComponent(p);
cristy3ed852e2009-09-05 21:47:34 +00002378 break;
2379 }
2380 case GreenQuantum:
2381 case MagentaQuantum:
2382 {
cristyce70c172010-01-07 17:15:30 +00002383 *q=GetGreenPixelComponent(p);
cristy3ed852e2009-09-05 21:47:34 +00002384 break;
2385 }
2386 case BlueQuantum:
2387 case YellowQuantum:
2388 {
cristyce70c172010-01-07 17:15:30 +00002389 *q=GetBluePixelComponent(p);
cristy3ed852e2009-09-05 21:47:34 +00002390 break;
2391 }
2392 case AlphaQuantum:
2393 {
cristy46f08202010-01-10 04:04:21 +00002394 *q=(Quantum) (GetAlphaPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002395 break;
2396 }
2397 case OpacityQuantum:
2398 {
cristyce70c172010-01-07 17:15:30 +00002399 *q=GetOpacityPixelComponent(p);
cristy3ed852e2009-09-05 21:47:34 +00002400 break;
2401 }
2402 case BlackQuantum:
2403 {
2404 if (image->colorspace == CMYKColorspace)
2405 *q=indexes[x];
2406 break;
2407 }
2408 case IndexQuantum:
2409 {
2410 *q=(PixelIntensityToQuantum(p));
2411 break;
2412 }
2413 default:
2414 *q=0;
2415 }
2416 q++;
2417 }
2418 p++;
2419 }
2420 break;
2421 }
2422 case ShortPixel:
2423 {
2424 register unsigned short
2425 *q;
2426
2427 q=(unsigned short *) stream_info->pixels;
2428 if (LocaleCompare(stream_info->map,"BGR") == 0)
2429 {
2430 p=GetAuthenticPixelQueue(image);
2431 if (p == (const PixelPacket *) NULL)
2432 break;
cristybb503372010-05-27 20:51:26 +00002433 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002434 {
cristyce70c172010-01-07 17:15:30 +00002435 *q++=ScaleQuantumToShort(GetBluePixelComponent(p));
2436 *q++=ScaleQuantumToShort(GetGreenPixelComponent(p));
2437 *q++=ScaleQuantumToShort(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002438 p++;
2439 }
2440 break;
2441 }
2442 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2443 {
2444 p=GetAuthenticPixelQueue(image);
2445 if (p == (const PixelPacket *) NULL)
2446 break;
cristybb503372010-05-27 20:51:26 +00002447 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002448 {
cristyce70c172010-01-07 17:15:30 +00002449 *q++=ScaleQuantumToShort(GetBluePixelComponent(p));
2450 *q++=ScaleQuantumToShort(GetGreenPixelComponent(p));
2451 *q++=ScaleQuantumToShort(GetRedPixelComponent(p));
cristy46f08202010-01-10 04:04:21 +00002452 *q++=ScaleQuantumToShort((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00002453 p++;
2454 }
2455 break;
2456 }
2457 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2458 {
2459 p=GetAuthenticPixelQueue(image);
2460 if (p == (const PixelPacket *) NULL)
2461 break;
cristybb503372010-05-27 20:51:26 +00002462 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002463 {
cristyce70c172010-01-07 17:15:30 +00002464 *q++=ScaleQuantumToShort(GetBluePixelComponent(p));
2465 *q++=ScaleQuantumToShort(GetGreenPixelComponent(p));
2466 *q++=ScaleQuantumToShort(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002467 *q++=0;
2468 p++;
2469 }
2470 break;
2471 }
2472 if (LocaleCompare(stream_info->map,"I") == 0)
2473 {
2474 p=GetAuthenticPixelQueue(image);
2475 if (p == (const PixelPacket *) NULL)
2476 break;
cristybb503372010-05-27 20:51:26 +00002477 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002478 {
2479 *q++=ScaleQuantumToShort(PixelIntensityToQuantum(p));
2480 p++;
2481 }
2482 break;
2483 }
2484 if (LocaleCompare(stream_info->map,"RGB") == 0)
2485 {
2486 p=GetAuthenticPixelQueue(image);
2487 if (p == (const PixelPacket *) NULL)
2488 break;
cristybb503372010-05-27 20:51:26 +00002489 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002490 {
cristyce70c172010-01-07 17:15:30 +00002491 *q++=ScaleQuantumToShort(GetRedPixelComponent(p));
2492 *q++=ScaleQuantumToShort(GetGreenPixelComponent(p));
2493 *q++=ScaleQuantumToShort(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002494 p++;
2495 }
2496 break;
2497 }
2498 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2499 {
2500 p=GetAuthenticPixelQueue(image);
2501 if (p == (const PixelPacket *) NULL)
2502 break;
cristybb503372010-05-27 20:51:26 +00002503 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002504 {
cristyce70c172010-01-07 17:15:30 +00002505 *q++=ScaleQuantumToShort(GetRedPixelComponent(p));
2506 *q++=ScaleQuantumToShort(GetGreenPixelComponent(p));
2507 *q++=ScaleQuantumToShort(GetBluePixelComponent(p));
cristy46f08202010-01-10 04:04:21 +00002508 *q++=ScaleQuantumToShort((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00002509 p++;
2510 }
2511 break;
2512 }
2513 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2514 {
2515 p=GetAuthenticPixelQueue(image);
2516 if (p == (const PixelPacket *) NULL)
2517 break;
cristybb503372010-05-27 20:51:26 +00002518 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002519 {
cristyce70c172010-01-07 17:15:30 +00002520 *q++=ScaleQuantumToShort(GetRedPixelComponent(p));
2521 *q++=ScaleQuantumToShort(GetGreenPixelComponent(p));
2522 *q++=ScaleQuantumToShort(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002523 *q++=0;
2524 p++;
2525 }
2526 break;
2527 }
2528 p=GetAuthenticPixelQueue(image);
2529 if (p == (const PixelPacket *) NULL)
2530 break;
2531 indexes=GetAuthenticIndexQueue(image);
cristybb503372010-05-27 20:51:26 +00002532 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002533 {
cristybb503372010-05-27 20:51:26 +00002534 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002535 {
2536 *q=0;
2537 switch (quantum_map[i])
2538 {
2539 case RedQuantum:
2540 case CyanQuantum:
2541 {
cristyce70c172010-01-07 17:15:30 +00002542 *q=ScaleQuantumToShort(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002543 break;
2544 }
2545 case GreenQuantum:
2546 case MagentaQuantum:
2547 {
cristyce70c172010-01-07 17:15:30 +00002548 *q=ScaleQuantumToShort(GetGreenPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002549 break;
2550 }
2551 case BlueQuantum:
2552 case YellowQuantum:
2553 {
cristyce70c172010-01-07 17:15:30 +00002554 *q=ScaleQuantumToShort(GetBluePixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002555 break;
2556 }
2557 case AlphaQuantum:
2558 {
cristy46f08202010-01-10 04:04:21 +00002559 *q=ScaleQuantumToShort((Quantum) (GetAlphaPixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00002560 break;
2561 }
2562 case OpacityQuantum:
2563 {
cristyce70c172010-01-07 17:15:30 +00002564 *q=ScaleQuantumToShort(GetOpacityPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00002565 break;
2566 }
2567 case BlackQuantum:
2568 {
2569 if (image->colorspace == CMYKColorspace)
2570 *q=ScaleQuantumToShort(indexes[x]);
2571 break;
2572 }
2573 case IndexQuantum:
2574 {
2575 *q=ScaleQuantumToShort(PixelIntensityToQuantum(p));
2576 break;
2577 }
2578 default:
2579 break;
2580 }
2581 q++;
2582 }
2583 p++;
2584 }
2585 break;
2586 }
2587 default:
2588 {
2589 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2590 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2591 "UnrecognizedPixelMap","`%s'",stream_info->map);
2592 break;
2593 }
2594 }
2595 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2596 return(MagickTrue);
2597}
2598
2599/*
2600%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2601% %
2602% %
2603% %
2604+ 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 %
2605% %
2606% %
2607% %
2608%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2609%
2610% SyncAuthenticPixelsStream() calls the user supplied callback method with
2611% the latest stream of pixels.
2612%
2613% The format of the SyncAuthenticPixelsStream method is:
2614%
2615% MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2616% ExceptionInfo *exception)
2617%
2618% A description of each parameter follows:
2619%
2620% o image: the image.
2621%
2622% o exception: return any errors or warnings in this structure.
2623%
2624*/
2625static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2626 ExceptionInfo *exception)
2627{
2628 CacheInfo
2629 *cache_info;
2630
2631 size_t
2632 length;
2633
2634 StreamHandler
2635 stream_handler;
2636
2637 assert(image != (Image *) NULL);
2638 assert(image->signature == MagickSignature);
2639 if (image->debug != MagickFalse)
2640 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2641 cache_info=(CacheInfo *) image->cache;
2642 assert(cache_info->signature == MagickSignature);
2643 stream_handler=GetBlobStreamHandler(image);
2644 if (stream_handler == (StreamHandler) NULL)
2645 {
2646 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
2647 "NoStreamHandlerIsDefined","`%s'",image->filename);
2648 return(MagickFalse);
2649 }
2650 length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
2651 return(length == cache_info->columns ? MagickTrue : MagickFalse);
2652}
2653
2654/*
2655%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2656% %
2657% %
2658% %
2659% W r i t e S t r e a m %
2660% %
2661% %
2662% %
2663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2664%
2665% WriteStream() makes the image pixels available to a user supplied callback
2666% method immediately upon writing pixel data with the WriteImage() method.
2667%
2668% The format of the WriteStream() method is:
2669%
2670% MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
2671% StreamHandler stream)
2672%
2673% A description of each parameter follows:
2674%
2675% o image_info: the image info.
2676%
2677% o stream: A callback method.
2678%
2679*/
2680MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
2681 Image *image,StreamHandler stream)
2682{
2683 ImageInfo
2684 *write_info;
2685
2686 MagickBooleanType
2687 status;
2688
2689 assert(image_info != (ImageInfo *) NULL);
2690 assert(image_info->signature == MagickSignature);
2691 if (image_info->debug != MagickFalse)
2692 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2693 image_info->filename);
2694 assert(image != (Image *) NULL);
2695 assert(image->signature == MagickSignature);
2696 write_info=CloneImageInfo(image_info);
2697 write_info->stream=stream;
2698 status=WriteImage(write_info,image);
2699 write_info=DestroyImageInfo(write_info);
2700 return(status);
2701}