blob: 5e83f3d80e2f8b30e444f295c1a0c00c3354c595 [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% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 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*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
46#include "MagickCore/cache.h"
47#include "MagickCore/cache-private.h"
48#include "MagickCore/color-private.h"
49#include "MagickCore/composite-private.h"
50#include "MagickCore/constitute.h"
51#include "MagickCore/exception.h"
52#include "MagickCore/exception-private.h"
53#include "MagickCore/geometry.h"
54#include "MagickCore/memory_.h"
cristye42639a2012-08-23 01:53:24 +000055#include "MagickCore/memory-private.h"
cristy4c08aed2011-07-01 19:47:50 +000056#include "MagickCore/pixel.h"
57#include "MagickCore/pixel-accessor.h"
58#include "MagickCore/quantum.h"
59#include "MagickCore/quantum-private.h"
60#include "MagickCore/semaphore.h"
61#include "MagickCore/stream.h"
62#include "MagickCore/stream-private.h"
63#include "MagickCore/string_.h"
cristy3ed852e2009-09-05 21:47:34 +000064
65/*
66 Typedef declaractions.
67*/
68struct _StreamInfo
69{
70 const ImageInfo
71 *image_info;
72
73 const Image
74 *image;
75
76 Image
77 *stream;
78
79 QuantumInfo
80 *quantum_info;
81
82 char
83 *map;
84
85 StorageType
86 storage_type;
87
88 unsigned char
89 *pixels;
90
91 RectangleInfo
92 extract_info;
93
cristybb503372010-05-27 20:51:26 +000094 ssize_t
cristy3ed852e2009-09-05 21:47:34 +000095 y;
96
97 ExceptionInfo
98 *exception;
99
100 const void
101 *client_data;
102
cristybb503372010-05-27 20:51:26 +0000103 size_t
cristy3ed852e2009-09-05 21:47:34 +0000104 signature;
105};
106
107/*
108 Declare pixel cache interfaces.
109*/
110#if defined(__cplusplus) || defined(c_plusplus)
111extern "C" {
112#endif
113
cristy4c08aed2011-07-01 19:47:50 +0000114static const Quantum
cristybb503372010-05-27 20:51:26 +0000115 *GetVirtualPixelStream(const Image *,const VirtualPixelMethod,const ssize_t,
116 const ssize_t,const size_t,const size_t,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000117
118static MagickBooleanType
119 StreamImagePixels(const StreamInfo *,const Image *,ExceptionInfo *),
120 SyncAuthenticPixelsStream(Image *,ExceptionInfo *);
121
cristy4c08aed2011-07-01 19:47:50 +0000122static Quantum
cristybb503372010-05-27 20:51:26 +0000123 *QueueAuthenticPixelsStream(Image *,const ssize_t,const ssize_t,const size_t,
124 const size_t,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000125
126#if defined(__cplusplus) || defined(c_plusplus)
127}
128#endif
129
130/*
131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132% %
133% %
134% %
135+ A c q u i r e S t r e a m I n f o %
136% %
137% %
138% %
139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140%
141% AcquireStreamInfo() allocates the StreamInfo structure.
142%
143% The format of the AcquireStreamInfo method is:
144%
cristy9950d572011-10-01 18:22:35 +0000145% StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
146% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000147%
148% A description of each parameter follows:
149%
150% o image_info: the image info.
151%
cristy9950d572011-10-01 18:22:35 +0000152% o exception: return any errors or warnings in this structure.
153%
cristy3ed852e2009-09-05 21:47:34 +0000154*/
cristy9950d572011-10-01 18:22:35 +0000155MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
156 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000157{
158 StreamInfo
159 *stream_info;
160
cristy73bd4a52010-10-05 11:24:23 +0000161 stream_info=(StreamInfo *) AcquireMagickMemory(sizeof(*stream_info));
cristy3ed852e2009-09-05 21:47:34 +0000162 if (stream_info == (StreamInfo *) NULL)
163 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
164 (void) ResetMagickMemory(stream_info,0,sizeof(*stream_info));
cristye42639a2012-08-23 01:53:24 +0000165 stream_info->pixels=(unsigned char *) MagickAssumeAligned(
166 AcquireAlignedMemory(1,sizeof(*stream_info->pixels)));
cristy3ed852e2009-09-05 21:47:34 +0000167 if (stream_info->pixels == (unsigned char *) NULL)
168 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
169 stream_info->map=ConstantString("RGB");
170 stream_info->storage_type=CharPixel;
cristy9950d572011-10-01 18:22:35 +0000171 stream_info->stream=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +0000172 stream_info->signature=MagickSignature;
173 return(stream_info);
174}
175
176/*
177%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178% %
179% %
180% %
181+ D e s t r o y P i x e l S t r e a m %
182% %
183% %
184% %
185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186%
187% DestroyPixelStream() deallocates memory associated with the pixel stream.
188%
189% The format of the DestroyPixelStream() method is:
190%
191% void DestroyPixelStream(Image *image)
192%
193% A description of each parameter follows:
194%
195% o image: the image.
196%
197*/
198
199static inline void RelinquishStreamPixels(CacheInfo *cache_info)
200{
201 assert(cache_info != (CacheInfo *) NULL);
202 if (cache_info->mapped == MagickFalse)
cristy39c2e212012-08-18 18:14:34 +0000203 (void) RelinquishAlignedMemory(cache_info->pixels);
cristy3ed852e2009-09-05 21:47:34 +0000204 else
205 (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
cristy4c08aed2011-07-01 19:47:50 +0000206 cache_info->pixels=(Quantum *) NULL;
207 cache_info->metacontent=(void *) NULL;
cristy3ed852e2009-09-05 21:47:34 +0000208 cache_info->length=0;
209 cache_info->mapped=MagickFalse;
210}
211
212static void DestroyPixelStream(Image *image)
213{
214 CacheInfo
215 *cache_info;
216
217 MagickBooleanType
218 destroy;
219
220 assert(image != (Image *) NULL);
221 assert(image->signature == MagickSignature);
222 if (image->debug != MagickFalse)
223 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
224 cache_info=(CacheInfo *) image->cache;
225 assert(cache_info->signature == MagickSignature);
226 destroy=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000227 LockSemaphoreInfo(cache_info->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000228 cache_info->reference_count--;
229 if (cache_info->reference_count == 0)
230 destroy=MagickTrue;
cristyf84a1932010-01-03 18:00:18 +0000231 UnlockSemaphoreInfo(cache_info->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000232 if (destroy == MagickFalse)
233 return;
234 RelinquishStreamPixels(cache_info);
235 if (cache_info->nexus_info != (NexusInfo **) NULL)
236 cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
237 cache_info->number_threads);
238 if (cache_info->disk_semaphore != (SemaphoreInfo *) NULL)
239 DestroySemaphoreInfo(&cache_info->disk_semaphore);
240 if (cache_info->semaphore != (SemaphoreInfo *) NULL)
241 DestroySemaphoreInfo(&cache_info->semaphore);
242 cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
243}
244
245/*
246%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
247% %
248% %
249% %
250+ D e s t r o y S t r e a m I n f o %
251% %
252% %
253% %
254%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
255%
256% DestroyStreamInfo() destroys memory associated with the StreamInfo
257% structure.
258%
259% The format of the DestroyStreamInfo method is:
260%
261% StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
262%
263% A description of each parameter follows:
264%
265% o stream_info: the stream info.
266%
267*/
268MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
269{
270 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
271 assert(stream_info != (StreamInfo *) NULL);
272 assert(stream_info->signature == MagickSignature);
273 if (stream_info->map != (char *) NULL)
274 stream_info->map=DestroyString(stream_info->map);
275 if (stream_info->pixels != (unsigned char *) NULL)
cristy39c2e212012-08-18 18:14:34 +0000276 stream_info->pixels=(unsigned char *) RelinquishAlignedMemory(
cristy3ed852e2009-09-05 21:47:34 +0000277 stream_info->pixels);
278 if (stream_info->stream != (Image *) NULL)
279 {
280 (void) CloseBlob(stream_info->stream);
281 stream_info->stream=DestroyImage(stream_info->stream);
282 }
283 if (stream_info->quantum_info != (QuantumInfo *) NULL)
284 stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
285 stream_info->signature=(~MagickSignature);
286 stream_info=(StreamInfo *) RelinquishMagickMemory(stream_info);
287 return(stream_info);
288}
289
290/*
291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292% %
293% %
294% %
cristy4c08aed2011-07-01 19:47:50 +0000295+ G e t A u t h e n t i c M e t a c o n t e n t F r o m S t r e a m %
cristy3ed852e2009-09-05 21:47:34 +0000296% %
297% %
298% %
299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
300%
cristy4c08aed2011-07-01 19:47:50 +0000301% GetAuthenticMetacontentFromStream() returns the metacontent corresponding
302% with the last call to QueueAuthenticPixelsStream() or
303% GetAuthenticPixelsStream().
cristy3ed852e2009-09-05 21:47:34 +0000304%
cristy4c08aed2011-07-01 19:47:50 +0000305% The format of the GetAuthenticMetacontentFromStream() method is:
cristy3ed852e2009-09-05 21:47:34 +0000306%
cristy4c08aed2011-07-01 19:47:50 +0000307% void *GetAuthenticMetacontentFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000308%
309% A description of each parameter follows:
310%
311% o image: the image.
312%
313*/
cristy4c08aed2011-07-01 19:47:50 +0000314static void *GetAuthenticMetacontentFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000315{
316 CacheInfo
317 *cache_info;
318
319 assert(image != (Image *) NULL);
320 assert(image->signature == MagickSignature);
321 if (image->debug != MagickFalse)
322 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
323 cache_info=(CacheInfo *) image->cache;
324 assert(cache_info->signature == MagickSignature);
cristy4c08aed2011-07-01 19:47:50 +0000325 return(cache_info->metacontent);
cristy3ed852e2009-09-05 21:47:34 +0000326}
327
328/*
329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330% %
331% %
332% %
333+ G e t A u t h e n t i c P i x e l S t r e a m %
334% %
335% %
336% %
337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338%
339% GetAuthenticPixelsStream() gets pixels from the in-memory or disk pixel
340% cache as defined by the geometry parameters. A pointer to the pixels is
341% returned if the pixels are transferred, otherwise a NULL is returned. For
342% streams this method is a no-op.
343%
344% The format of the GetAuthenticPixelsStream() method is:
345%
cristy4c08aed2011-07-01 19:47:50 +0000346% Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000347% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000348% ExceptionInfo *exception)
349%
350% A description of each parameter follows:
351%
352% o image: the image.
353%
354% o x,y,columns,rows: These values define the perimeter of a region of
355% pixels.
356%
357% o exception: return any errors or warnings in this structure.
358%
359*/
cristy4c08aed2011-07-01 19:47:50 +0000360static Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000361 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000362 ExceptionInfo *exception)
363{
cristy4c08aed2011-07-01 19:47:50 +0000364 Quantum
cristy3ed852e2009-09-05 21:47:34 +0000365 *pixels;
366
367 assert(image != (Image *) NULL);
368 assert(image->signature == MagickSignature);
369 if (image->debug != MagickFalse)
370 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
371 pixels=QueueAuthenticPixelsStream(image,x,y,columns,rows,exception);
372 return(pixels);
373}
374
375/*
376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377% %
378% %
379% %
380+ G e t A u t h e n t i c P i x e l F r o m S t e a m %
381% %
382% %
383% %
384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385%
386% GetAuthenticPixelsFromStream() returns the pixels associated with the last
387% call to QueueAuthenticPixelsStream() or GetAuthenticPixelsStream().
388%
389% The format of the GetAuthenticPixelsFromStream() method is:
390%
cristy4c08aed2011-07-01 19:47:50 +0000391% Quantum *GetAuthenticPixelsFromStream(const Image image)
cristy3ed852e2009-09-05 21:47:34 +0000392%
393% A description of each parameter follows:
394%
395% o image: the image.
396%
397*/
cristy4c08aed2011-07-01 19:47:50 +0000398static Quantum *GetAuthenticPixelsFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000399{
400 CacheInfo
401 *cache_info;
402
403 assert(image != (Image *) NULL);
404 assert(image->signature == MagickSignature);
405 if (image->debug != MagickFalse)
406 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
407 cache_info=(CacheInfo *) image->cache;
408 assert(cache_info->signature == MagickSignature);
409 return(cache_info->pixels);
410}
411
412/*
413%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
414% %
415% %
416% %
417+ G e t O n e A u t h e n t i c P i x e l F r o m S t r e a m %
418% %
419% %
420% %
421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
422%
423% GetOneAuthenticPixelFromStream() returns a single pixel at the specified
424% (x,y) location. The image background color is returned if an error occurs.
425%
426% The format of the GetOneAuthenticPixelFromStream() method is:
427%
428% MagickBooleanType GetOneAuthenticPixelFromStream(const Image image,
cristy2ed42f62011-10-02 19:49:57 +0000429% const ssize_t x,const ssize_t y,Quantum *pixel,
cristycfae90a2010-10-04 14:43:33 +0000430% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000431%
432% A description of each parameter follows:
433%
434% o image: the image.
435%
436% o pixel: return a pixel at the specified (x,y) location.
437%
438% o x,y: These values define the location of the pixel to return.
439%
440% o exception: return any errors or warnings in this structure.
441%
442*/
443static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
cristy2ed42f62011-10-02 19:49:57 +0000444 const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000445{
cristy4c08aed2011-07-01 19:47:50 +0000446 register Quantum
447 *q;
cristy3ed852e2009-09-05 21:47:34 +0000448
cristy2ed42f62011-10-02 19:49:57 +0000449 register ssize_t
450 i;
451
cristy3ed852e2009-09-05 21:47:34 +0000452 assert(image != (Image *) NULL);
453 assert(image->signature == MagickSignature);
cristy2ed42f62011-10-02 19:49:57 +0000454 (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
cristy4c08aed2011-07-01 19:47:50 +0000455 q=GetAuthenticPixelsStream(image,x,y,1,1,exception);
456 if (q != (Quantum *) NULL)
cristy2ed42f62011-10-02 19:49:57 +0000457 {
cristy100b8d92012-01-08 00:32:49 +0000458 pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
459 pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
460 pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
cristyd09f8802012-02-04 16:44:10 +0000461 pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
cristy100b8d92012-01-08 00:32:49 +0000462 pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
cristy2ed42f62011-10-02 19:49:57 +0000463 return(MagickFalse);
464 }
465 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
466 {
467 PixelChannel
468 channel;
469
cristycf1296e2012-08-26 23:40:49 +0000470 channel=GetPixelChannelChannel(image,i);
cristy2ed42f62011-10-02 19:49:57 +0000471 pixel[channel]=q[i];
472 }
cristy3ed852e2009-09-05 21:47:34 +0000473 return(MagickTrue);
474}
475
476/*
477%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478% %
479% %
480% %
481+ 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 %
482% %
483% %
484% %
485%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
486%
487% GetOneVirtualPixelFromStream() returns a single pixel at the specified
488% (x.y) location. The image background color is returned if an error occurs.
489%
490% The format of the GetOneVirtualPixelFromStream() method is:
491%
492% MagickBooleanType GetOneVirtualPixelFromStream(const Image image,
cristybb503372010-05-27 20:51:26 +0000493% const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
cristy2ed42f62011-10-02 19:49:57 +0000494% const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000495%
496% A description of each parameter follows:
497%
498% o image: the image.
499%
500% o virtual_pixel_method: the virtual pixel method.
501%
502% o x,y: These values define the location of the pixel to return.
503%
504% o pixel: return a pixel at the specified (x,y) location.
505%
506% o exception: return any errors or warnings in this structure.
507%
508*/
509static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000510 const VirtualPixelMethod virtual_pixel_method,const ssize_t x,const ssize_t y,
cristy2ed42f62011-10-02 19:49:57 +0000511 Quantum *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000512{
cristy4c08aed2011-07-01 19:47:50 +0000513 const Quantum
cristy01cdc902011-08-31 01:05:44 +0000514 *p;
cristy3ed852e2009-09-05 21:47:34 +0000515
cristy2ed42f62011-10-02 19:49:57 +0000516 register ssize_t
517 i;
518
cristy3ed852e2009-09-05 21:47:34 +0000519 assert(image != (Image *) NULL);
520 assert(image->signature == MagickSignature);
cristy2ed42f62011-10-02 19:49:57 +0000521 (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
cristy01cdc902011-08-31 01:05:44 +0000522 p=GetVirtualPixelStream(image,virtual_pixel_method,x,y,1,1,exception);
523 if (p == (const Quantum *) NULL)
cristy2ed42f62011-10-02 19:49:57 +0000524 {
cristy100b8d92012-01-08 00:32:49 +0000525 pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
526 pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
527 pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
cristyd09f8802012-02-04 16:44:10 +0000528 pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
cristy100b8d92012-01-08 00:32:49 +0000529 pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
cristy2ed42f62011-10-02 19:49:57 +0000530 return(MagickFalse);
531 }
532 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
533 {
534 PixelChannel
535 channel;
536
cristycf1296e2012-08-26 23:40:49 +0000537 channel=GetPixelChannelChannel(image,i);
cristy2ed42f62011-10-02 19:49:57 +0000538 pixel[channel]=p[i];
539 }
cristy3ed852e2009-09-05 21:47:34 +0000540 return(MagickTrue);
541}
542
543/*
544%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545% %
546% %
547% %
548+ G e t S t r e a m I n f o C l i e n t D a t a %
549% %
550% %
551% %
552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553%
554% GetStreamInfoClientData() gets the stream info client data.
555%
cristy7832dc22011-09-05 01:21:53 +0000556% The format of the GetStreamInfoClientData method is:
cristy3ed852e2009-09-05 21:47:34 +0000557%
558% const void *GetStreamInfoClientData(StreamInfo *stream_info)
559%
560% A description of each parameter follows:
561%
562% o stream_info: the stream info.
563%
564*/
cristy7832dc22011-09-05 01:21:53 +0000565MagickPrivate const void *GetStreamInfoClientData(StreamInfo *stream_info)
cristy3ed852e2009-09-05 21:47:34 +0000566{
567 assert(stream_info != (StreamInfo *) NULL);
568 assert(stream_info->signature == MagickSignature);
569 return(stream_info->client_data);
570}
571
572/*
573%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574% %
575% %
576% %
577+ 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 %
578% %
579% %
580% %
581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582%
583% GetVirtualPixelsStream() returns the pixels associated with the last
584% call to QueueAuthenticPixelsStream() or GetVirtualPixelStream().
585%
586% The format of the GetVirtualPixelsStream() method is:
587%
cristy4c08aed2011-07-01 19:47:50 +0000588% const Quantum *GetVirtualPixelsStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000589%
590% A description of each parameter follows:
591%
cristy4c08aed2011-07-01 19:47:50 +0000592% o pixels: return the pixels associated corresponding with the last call to
cristy3ed852e2009-09-05 21:47:34 +0000593% QueueAuthenticPixelsStream() or GetVirtualPixelStream().
594%
595% o image: the image.
596%
597*/
cristy4c08aed2011-07-01 19:47:50 +0000598static const Quantum *GetVirtualPixelsStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000599{
600 CacheInfo
601 *cache_info;
602
603 assert(image != (Image *) NULL);
604 assert(image->signature == MagickSignature);
605 if (image->debug != MagickFalse)
606 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
607 cache_info=(CacheInfo *) image->cache;
608 assert(cache_info->signature == MagickSignature);
609 return(cache_info->pixels);
610}
611
612/*
613%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614% %
615% %
616% %
617+ 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 %
618% %
619% %
620% %
621%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622%
cristy20cc0872012-08-20 00:01:19 +0000623% GetVirtualMetacontentFromStream() returns the associated pixel channels
624% corresponding with the last call to QueueAuthenticPixelsStream() or
cristy4c08aed2011-07-01 19:47:50 +0000625% GetVirtualPixelStream().
cristy3ed852e2009-09-05 21:47:34 +0000626%
cristy4c08aed2011-07-01 19:47:50 +0000627% The format of the GetVirtualMetacontentFromStream() method is:
cristy3ed852e2009-09-05 21:47:34 +0000628%
cristy4c08aed2011-07-01 19:47:50 +0000629% const void *GetVirtualMetacontentFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000630%
631% A description of each parameter follows:
632%
633% o image: the image.
634%
635*/
cristy20cc0872012-08-20 00:01:19 +0000636static const void *GetVirtualMetacontentFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000637{
638 CacheInfo
639 *cache_info;
640
641 assert(image != (Image *) NULL);
642 assert(image->signature == MagickSignature);
643 if (image->debug != MagickFalse)
644 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
645 cache_info=(CacheInfo *) image->cache;
646 assert(cache_info->signature == MagickSignature);
cristy4c08aed2011-07-01 19:47:50 +0000647 return(cache_info->metacontent);
cristy3ed852e2009-09-05 21:47:34 +0000648}
649
650/*
651%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652% %
653% %
654% %
655+ G e t V i r t u a l P i x e l S t r e a m %
656% %
657% %
658% %
659%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660%
661% GetVirtualPixelStream() gets pixels from the in-memory or disk pixel cache as
662% defined by the geometry parameters. A pointer to the pixels is returned if
663% the pixels are transferred, otherwise a NULL is returned. For streams this
664% method is a no-op.
665%
666% The format of the GetVirtualPixelStream() method is:
667%
cristy4c08aed2011-07-01 19:47:50 +0000668% const Quantum *GetVirtualPixelStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000669% const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
670% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000671% ExceptionInfo *exception)
672%
673% A description of each parameter follows:
674%
675% o image: the image.
676%
677% o virtual_pixel_method: the virtual pixel method.
678%
679% o x,y,columns,rows: These values define the perimeter of a region of
680% pixels.
681%
682% o exception: return any errors or warnings in this structure.
683%
684*/
685
686static inline MagickBooleanType AcquireStreamPixels(CacheInfo *cache_info,
687 ExceptionInfo *exception)
688{
689 if (cache_info->length != (MagickSizeType) ((size_t) cache_info->length))
690 return(MagickFalse);
691 cache_info->mapped=MagickFalse;
cristy39c2e212012-08-18 18:14:34 +0000692 cache_info->pixels=(Quantum *) AcquireAlignedMemory(1,(size_t)
cristy3ed852e2009-09-05 21:47:34 +0000693 cache_info->length);
cristy4c08aed2011-07-01 19:47:50 +0000694 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000695 {
696 cache_info->mapped=MagickTrue;
cristy4c08aed2011-07-01 19:47:50 +0000697 cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
cristy3ed852e2009-09-05 21:47:34 +0000698 cache_info->length);
699 }
cristy4c08aed2011-07-01 19:47:50 +0000700 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000701 {
702 (void) ThrowMagickException(exception,GetMagickModule(),
cristy20cc0872012-08-20 00:01:19 +0000703 ResourceLimitError,"MemoryAllocationFailed","'%s'",
cristy3ed852e2009-09-05 21:47:34 +0000704 cache_info->filename);
705 return(MagickFalse);
706 }
707 return(MagickTrue);
708}
709
cristy4c08aed2011-07-01 19:47:50 +0000710static const Quantum *GetVirtualPixelStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000711 const VirtualPixelMethod magick_unused(virtual_pixel_method),const ssize_t x,
712 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000713 ExceptionInfo *exception)
714{
715 CacheInfo
716 *cache_info;
717
718 MagickBooleanType
719 status;
720
721 MagickSizeType
722 number_pixels;
723
724 size_t
725 length;
726
727 /*
728 Validate pixel cache geometry.
729 */
730 assert(image != (const Image *) NULL);
731 assert(image->signature == MagickSignature);
732 if (image->debug != MagickFalse)
733 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy5dd71882010-08-01 20:53:13 +0000734 if ((x < 0) || (y < 0) ||
735 ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
736 ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
737 (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000738 {
739 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +0000740 "ImageDoesNotContainTheStreamGeometry","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000741 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000742 }
743 cache_info=(CacheInfo *) image->cache;
744 assert(cache_info->signature == MagickSignature);
745 /*
746 Pixels are stored in a temporary buffer until they are synced to the cache.
747 */
748 number_pixels=(MagickSizeType) columns*rows;
cristyed231572011-07-14 02:18:59 +0000749 length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
cristya13b07a2012-08-21 17:01:05 +0000750 if (cache_info->number_channels == 0)
751 length=number_pixels*sizeof(Quantum);
cristy4c08aed2011-07-01 19:47:50 +0000752 if (cache_info->metacontent_extent != 0)
753 length+=number_pixels*cache_info->metacontent_extent;
754 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000755 {
756 cache_info->length=length;
757 status=AcquireStreamPixels(cache_info,exception);
758 if (status == MagickFalse)
cristy33503f52010-10-04 17:32:27 +0000759 {
760 cache_info->length=0;
cristy4c08aed2011-07-01 19:47:50 +0000761 return((Quantum *) NULL);
cristy33503f52010-10-04 17:32:27 +0000762 }
cristy3ed852e2009-09-05 21:47:34 +0000763 }
764 else
765 if (cache_info->length != length)
766 {
767 RelinquishStreamPixels(cache_info);
768 cache_info->length=length;
769 status=AcquireStreamPixels(cache_info,exception);
770 if (status == MagickFalse)
cristy33503f52010-10-04 17:32:27 +0000771 {
772 cache_info->length=0;
cristy4c08aed2011-07-01 19:47:50 +0000773 return((Quantum *) NULL);
cristy33503f52010-10-04 17:32:27 +0000774 }
cristy3ed852e2009-09-05 21:47:34 +0000775 }
cristy4c08aed2011-07-01 19:47:50 +0000776 cache_info->metacontent=(void *) NULL;
777 if (cache_info->metacontent_extent != 0)
778 cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
cristyed231572011-07-14 02:18:59 +0000779 cache_info->number_channels);
cristy3ed852e2009-09-05 21:47:34 +0000780 return(cache_info->pixels);
781}
782
783/*
784%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
785% %
786% %
787% %
788+ O p e n S t r e a m %
789% %
790% %
791% %
792%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
793%
794% OpenStream() opens a stream for writing by the StreamImage() method.
795%
796% The format of the OpenStream method is:
797%
798% MagickBooleanType OpenStream(const ImageInfo *image_info,
799% StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
800%
801% A description of each parameter follows:
802%
803% o image_info: the image info.
804%
805% o stream_info: the stream info.
806%
807% o filename: the stream filename.
808%
809% o exception: return any errors or warnings in this structure.
810%
811*/
812MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
813 StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
814{
815 MagickBooleanType
816 status;
817
818 (void) CopyMagickString(stream_info->stream->filename,filename,MaxTextExtent);
819 status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
820 return(status);
821}
822
823/*
824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825% %
826% %
827% %
828+ 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 %
829% %
830% %
831% %
832%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
833%
834% QueueAuthenticPixelsStream() allocates an area to store image pixels as
835% defined by the region rectangle and returns a pointer to the area. This
836% area is subsequently transferred from the pixel cache with method
837% SyncAuthenticPixelsStream(). A pointer to the pixels is returned if the
838% pixels are transferred, otherwise a NULL is returned.
839%
840% The format of the QueueAuthenticPixelsStream() method is:
841%
cristy4c08aed2011-07-01 19:47:50 +0000842% Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000843% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000844% ExceptionInfo *exception)
845%
846% A description of each parameter follows:
847%
848% o image: the image.
849%
850% o x,y,columns,rows: These values define the perimeter of a region of
851% pixels.
852%
853*/
cristy4c08aed2011-07-01 19:47:50 +0000854static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000855 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000856 ExceptionInfo *exception)
857{
858 CacheInfo
859 *cache_info;
860
cristy20cc0872012-08-20 00:01:19 +0000861 MagickBooleanType
862 status;
863
cristy3ed852e2009-09-05 21:47:34 +0000864 MagickSizeType
865 number_pixels;
866
867 size_t
868 length;
869
870 StreamHandler
871 stream_handler;
872
873 /*
874 Validate pixel cache geometry.
875 */
876 assert(image != (Image *) NULL);
cristycfae90a2010-10-04 14:43:33 +0000877 if ((x < 0) || (y < 0) ||
878 ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
879 ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
880 (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000881 {
882 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +0000883 "ImageDoesNotContainTheStreamGeometry","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000884 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000885 }
886 stream_handler=GetBlobStreamHandler(image);
887 if (stream_handler == (StreamHandler) NULL)
888 {
889 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +0000890 "NoStreamHandlerIsDefined","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000891 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000892 }
893 cache_info=(CacheInfo *) image->cache;
894 assert(cache_info->signature == MagickSignature);
895 if ((image->storage_class != GetPixelCacheStorageClass(image->cache)) ||
896 (image->colorspace != GetPixelCacheColorspace(image->cache)))
897 {
898 if (GetPixelCacheStorageClass(image->cache) == UndefinedClass)
899 (void) stream_handler(image,(const void *) NULL,(size_t)
900 cache_info->columns);
901 cache_info->storage_class=image->storage_class;
902 cache_info->colorspace=image->colorspace;
903 cache_info->columns=image->columns;
904 cache_info->rows=image->rows;
905 image->cache=cache_info;
906 }
907 /*
908 Pixels are stored in a temporary buffer until they are synced to the cache.
909 */
910 cache_info->columns=columns;
911 cache_info->rows=rows;
912 number_pixels=(MagickSizeType) columns*rows;
cristyed231572011-07-14 02:18:59 +0000913 length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
cristyd62370b2012-08-20 00:22:14 +0000914 if (cache_info->number_channels == 0)
cristy20cc0872012-08-20 00:01:19 +0000915 length=number_pixels*sizeof(Quantum);
cristy4c08aed2011-07-01 19:47:50 +0000916 if (cache_info->metacontent_extent != 0)
917 length+=number_pixels*cache_info->metacontent_extent;
918 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000919 {
cristy20cc0872012-08-20 00:01:19 +0000920 cache_info->length=length;
921 status=AcquireStreamPixels(cache_info,exception);
922 if (status == MagickFalse)
923 {
924 cache_info->length=0;
925 return((Quantum *) NULL);
926 }
cristy3ed852e2009-09-05 21:47:34 +0000927 }
928 else
cristy20cc0872012-08-20 00:01:19 +0000929 if (cache_info->length < length)
cristy3ed852e2009-09-05 21:47:34 +0000930 {
cristy20cc0872012-08-20 00:01:19 +0000931 RelinquishStreamPixels(cache_info);
932 cache_info->length=length;
933 status=AcquireStreamPixels(cache_info,exception);
934 if (status == MagickFalse)
935 {
936 cache_info->length=0;
937 return((Quantum *) NULL);
938 }
cristy3ed852e2009-09-05 21:47:34 +0000939 }
cristy4c08aed2011-07-01 19:47:50 +0000940 cache_info->metacontent=(void *) NULL;
941 if (cache_info->metacontent_extent != 0)
942 cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
cristyed231572011-07-14 02:18:59 +0000943 cache_info->number_channels);
cristy3ed852e2009-09-05 21:47:34 +0000944 return(cache_info->pixels);
945}
946
947/*
948%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949% %
950% %
951% %
952% R e a d S t r e a m %
953% %
954% %
955% %
956%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957%
958% ReadStream() makes the image pixels available to a user supplied callback
959% method immediately upon reading a scanline with the ReadImage() method.
960%
961% The format of the ReadStream() method is:
962%
963% Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
964% ExceptionInfo *exception)
965%
966% A description of each parameter follows:
967%
968% o image_info: the image info.
969%
970% o stream: a callback method.
971%
972% o exception: return any errors or warnings in this structure.
973%
974*/
975MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
976 ExceptionInfo *exception)
977{
978 CacheMethods
979 cache_methods;
980
981 Image
982 *image;
983
984 ImageInfo
985 *read_info;
986
987 /*
988 Stream image pixels.
989 */
990 assert(image_info != (ImageInfo *) NULL);
991 assert(image_info->signature == MagickSignature);
992 if (image_info->debug != MagickFalse)
993 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
994 image_info->filename);
995 assert(exception != (ExceptionInfo *) NULL);
996 assert(exception->signature == MagickSignature);
997 read_info=CloneImageInfo(image_info);
998 read_info->cache=AcquirePixelCache(0);
999 GetPixelCacheMethods(&cache_methods);
1000 cache_methods.get_virtual_pixel_handler=GetVirtualPixelStream;
cristy4c08aed2011-07-01 19:47:50 +00001001 cache_methods.get_virtual_metacontent_from_handler=
1002 GetVirtualMetacontentFromStream;
cristy3ed852e2009-09-05 21:47:34 +00001003 cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
1004 cache_methods.get_authentic_pixels_handler=GetAuthenticPixelsStream;
1005 cache_methods.queue_authentic_pixels_handler=QueueAuthenticPixelsStream;
1006 cache_methods.sync_authentic_pixels_handler=SyncAuthenticPixelsStream;
1007 cache_methods.get_authentic_pixels_from_handler=GetAuthenticPixelsFromStream;
cristy4c08aed2011-07-01 19:47:50 +00001008 cache_methods.get_authentic_metacontent_from_handler=
1009 GetAuthenticMetacontentFromStream;
cristy3ed852e2009-09-05 21:47:34 +00001010 cache_methods.get_one_virtual_pixel_from_handler=GetOneVirtualPixelFromStream;
1011 cache_methods.get_one_authentic_pixel_from_handler=
1012 GetOneAuthenticPixelFromStream;
1013 cache_methods.destroy_pixel_handler=DestroyPixelStream;
1014 SetPixelCacheMethods(read_info->cache,&cache_methods);
1015 read_info->stream=stream;
1016 image=ReadImage(read_info,exception);
1017 read_info=DestroyImageInfo(read_info);
1018 return(image);
1019}
1020
1021/*
1022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1023% %
1024% %
1025% %
1026+ S e t S t r e a m I n f o C l i e n t D a t a %
1027% %
1028% %
1029% %
1030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031%
1032% SetStreamInfoClientData() sets the stream info client data.
1033%
1034% The format of the SetStreamInfoClientData method is:
1035%
1036% void SetStreamInfoClientData(StreamInfo *stream_info,
1037% const void *client_data)
1038%
1039% A description of each parameter follows:
1040%
1041% o stream_info: the stream info.
1042%
1043% o client_data: the client data.
1044%
1045*/
cristy7832dc22011-09-05 01:21:53 +00001046MagickPrivate void SetStreamInfoClientData(StreamInfo *stream_info,
cristy3ed852e2009-09-05 21:47:34 +00001047 const void *client_data)
1048{
1049 assert(stream_info != (StreamInfo *) NULL);
1050 assert(stream_info->signature == MagickSignature);
1051 stream_info->client_data=client_data;
1052}
1053
1054/*
1055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1056% %
1057% %
1058% %
1059+ S e t S t r e a m I n f o M a p %
1060% %
1061% %
1062% %
1063%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1064%
1065% SetStreamInfoMap() sets the stream info map member.
1066%
1067% The format of the SetStreamInfoMap method is:
1068%
1069% void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1070%
1071% A description of each parameter follows:
1072%
1073% o stream_info: the stream info.
1074%
1075% o map: the map.
1076%
1077*/
1078MagickExport void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1079{
1080 assert(stream_info != (StreamInfo *) NULL);
1081 assert(stream_info->signature == MagickSignature);
1082 (void) CloneString(&stream_info->map,map);
1083}
1084
1085/*
1086%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087% %
1088% %
1089% %
1090+ S e t S t r e a m I n f o S t o r a g e T y p e %
1091% %
1092% %
1093% %
1094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1095%
1096% SetStreamInfoStorageType() sets the stream info storage type member.
1097%
1098% The format of the SetStreamInfoStorageType method is:
1099%
1100% void SetStreamInfoStorageType(StreamInfo *stream_info,
1101% const StoreageType *storage_type)
1102%
1103% A description of each parameter follows:
1104%
1105% o stream_info: the stream info.
1106%
1107% o storage_type: the storage type.
1108%
1109*/
1110MagickExport void SetStreamInfoStorageType(StreamInfo *stream_info,
1111 const StorageType storage_type)
1112{
1113 assert(stream_info != (StreamInfo *) NULL);
1114 assert(stream_info->signature == MagickSignature);
1115 stream_info->storage_type=storage_type;
1116}
1117
1118/*
1119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1120% %
1121% %
1122% %
1123+ S t r e a m I m a g e %
1124% %
1125% %
1126% %
1127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1128%
1129% StreamImage() streams pixels from an image and writes them in a user
1130% defined format and storage type (e.g. RGBA as 8-bit unsigned char).
1131%
cristyd212bd02011-02-13 17:08:57 +00001132% The format of the StreamImage() method is:
cristy3ed852e2009-09-05 21:47:34 +00001133%
1134% Image *StreamImage(const ImageInfo *image_info,
1135% StreamInfo *stream_info,ExceptionInfo *exception)
1136%
1137% A description of each parameter follows:
1138%
1139% o image_info: the image info.
1140%
1141% o stream_info: the stream info.
1142%
1143% o exception: return any errors or warnings in this structure.
1144%
1145*/
1146
1147#if defined(__cplusplus) || defined(c_plusplus)
1148extern "C" {
1149#endif
1150
1151static size_t WriteStreamImage(const Image *image,const void *pixels,
1152 const size_t columns)
1153{
cristye3664f42010-05-14 00:59:57 +00001154 CacheInfo
1155 *cache_info;
1156
cristy3ed852e2009-09-05 21:47:34 +00001157 RectangleInfo
1158 extract_info;
1159
1160 size_t
1161 length,
1162 packet_size;
1163
1164 ssize_t
1165 count;
1166
1167 StreamInfo
1168 *stream_info;
1169
cristy654fdaf2011-02-24 15:24:33 +00001170 (void) pixels;
cristy3ed852e2009-09-05 21:47:34 +00001171 stream_info=(StreamInfo *) image->client_data;
1172 switch (stream_info->storage_type)
1173 {
cristy100b8d92012-01-08 00:32:49 +00001174 default: packet_size=sizeof(unsigned char); break;
1175 case CharPixel: packet_size=sizeof(unsigned char); break;
cristy3ed852e2009-09-05 21:47:34 +00001176 case DoublePixel: packet_size=sizeof(double); break;
1177 case FloatPixel: packet_size=sizeof(float); break;
cristy100b8d92012-01-08 00:32:49 +00001178 case LongPixel: packet_size=sizeof(unsigned int); break;
1179 case LongLongPixel: packet_size=sizeof(MagickSizeType); break;
cristy3ed852e2009-09-05 21:47:34 +00001180 case QuantumPixel: packet_size=sizeof(Quantum); break;
1181 case ShortPixel: packet_size=sizeof(unsigned short); break;
1182 }
cristye3664f42010-05-14 00:59:57 +00001183 cache_info=(CacheInfo *) image->cache;
1184 assert(cache_info->signature == MagickSignature);
cristy3ed852e2009-09-05 21:47:34 +00001185 packet_size*=strlen(stream_info->map);
cristye3664f42010-05-14 00:59:57 +00001186 length=packet_size*cache_info->columns*cache_info->rows;
cristy3ed852e2009-09-05 21:47:34 +00001187 if (image != stream_info->image)
1188 {
1189 ImageInfo
1190 *write_info;
1191
1192 /*
1193 Prepare stream for writing.
1194 */
cristy39c2e212012-08-18 18:14:34 +00001195 (void) RelinquishAlignedMemory(stream_info->pixels);
cristy20cc0872012-08-20 00:01:19 +00001196 stream_info->pixels=(unsigned char *) AcquireAlignedMemory(1,length);
cristy5dd71882010-08-01 20:53:13 +00001197 if (stream_info->pixels == (unsigned char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001198 return(0);
cristy39c2e212012-08-18 18:14:34 +00001199 (void) ResetMagickMemory(stream_info->pixels,0,length);
cristy3ed852e2009-09-05 21:47:34 +00001200 stream_info->image=image;
1201 write_info=CloneImageInfo(stream_info->image_info);
cristyd965a422010-03-03 17:47:35 +00001202 (void) SetImageInfo(write_info,1,stream_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001203 if (write_info->extract != (char *) NULL)
1204 (void) ParseAbsoluteGeometry(write_info->extract,
1205 &stream_info->extract_info);
1206 stream_info->y=0;
1207 write_info=DestroyImageInfo(write_info);
1208 }
1209 extract_info=stream_info->extract_info;
cristyd212bd02011-02-13 17:08:57 +00001210 if ((extract_info.width == 0) || (extract_info.height == 0))
cristy3ed852e2009-09-05 21:47:34 +00001211 {
1212 /*
1213 Write all pixels to stream.
1214 */
1215 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1216 count=WriteBlob(stream_info->stream,length,stream_info->pixels);
1217 stream_info->y++;
1218 return(count == 0 ? 0 : columns);
1219 }
1220 if ((stream_info->y < extract_info.y) ||
cristybb503372010-05-27 20:51:26 +00001221 (stream_info->y >= (ssize_t) (extract_info.y+extract_info.height)))
cristy3ed852e2009-09-05 21:47:34 +00001222 {
1223 stream_info->y++;
1224 return(columns);
1225 }
1226 /*
1227 Write a portion of the pixel row to the stream.
1228 */
1229 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1230 length=packet_size*extract_info.width;
cristy5dd71882010-08-01 20:53:13 +00001231 count=WriteBlob(stream_info->stream,length,stream_info->pixels+packet_size*
1232 extract_info.x);
cristy3ed852e2009-09-05 21:47:34 +00001233 stream_info->y++;
1234 return(count == 0 ? 0 : columns);
1235}
1236
1237#if defined(__cplusplus) || defined(c_plusplus)
1238}
1239#endif
1240
1241MagickExport Image *StreamImage(const ImageInfo *image_info,
1242 StreamInfo *stream_info,ExceptionInfo *exception)
1243{
1244 Image
1245 *image;
1246
1247 ImageInfo
1248 *read_info;
1249
1250 assert(image_info != (const ImageInfo *) NULL);
1251 assert(image_info->signature == MagickSignature);
1252 if (image_info->debug != MagickFalse)
1253 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1254 image_info->filename);
1255 assert(stream_info != (StreamInfo *) NULL);
1256 assert(stream_info->signature == MagickSignature);
1257 assert(exception != (ExceptionInfo *) NULL);
1258 read_info=CloneImageInfo(image_info);
1259 stream_info->image_info=image_info;
1260 stream_info->exception=exception;
1261 read_info->client_data=(void *) stream_info;
1262 image=ReadStream(read_info,&WriteStreamImage,exception);
1263 read_info=DestroyImageInfo(read_info);
1264 stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
1265 if (stream_info->quantum_info == (QuantumInfo *) NULL)
1266 image=DestroyImage(image);
1267 return(image);
1268}
1269
1270/*
1271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272% %
1273% %
1274% %
1275+ S t r e a m I m a g e P i x e l s %
1276% %
1277% %
1278% %
1279%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1280%
1281% StreamImagePixels() extracts pixel data from an image and returns it in the
1282% stream_info->pixels structure in the format as defined by
1283% stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
1284%
1285% The format of the StreamImagePixels method is:
1286%
1287% MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1288% const Image *image,ExceptionInfo *exception)
1289%
1290% A description of each parameter follows:
1291%
1292% o stream_info: the stream info.
1293%
1294% o image: the image.
1295%
1296% o exception: return any errors or warnings in this structure.
1297%
1298*/
1299static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1300 const Image *image,ExceptionInfo *exception)
1301{
1302 QuantumInfo
1303 *quantum_info;
1304
1305 QuantumType
1306 *quantum_map;
1307
cristy4c08aed2011-07-01 19:47:50 +00001308 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +00001309 *p;
1310
cristyd212bd02011-02-13 17:08:57 +00001311 register ssize_t
1312 i,
1313 x;
1314
cristy3ed852e2009-09-05 21:47:34 +00001315 size_t
1316 length;
1317
1318 assert(stream_info != (StreamInfo *) NULL);
1319 assert(stream_info->signature == MagickSignature);
1320 assert(image != (Image *) NULL);
1321 assert(image->signature == MagickSignature);
1322 if (image->debug != MagickFalse)
1323 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1324 length=strlen(stream_info->map);
1325 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1326 if (quantum_map == (QuantumType *) NULL)
1327 {
1328 (void) ThrowMagickException(exception,GetMagickModule(),
cristy20cc0872012-08-20 00:01:19 +00001329 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +00001330 return(MagickFalse);
1331 }
cristybb503372010-05-27 20:51:26 +00001332 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001333 {
1334 switch (stream_info->map[i])
1335 {
1336 case 'A':
1337 case 'a':
1338 {
1339 quantum_map[i]=AlphaQuantum;
1340 break;
1341 }
1342 case 'B':
1343 case 'b':
1344 {
1345 quantum_map[i]=BlueQuantum;
1346 break;
1347 }
1348 case 'C':
1349 case 'c':
1350 {
1351 quantum_map[i]=CyanQuantum;
1352 if (image->colorspace == CMYKColorspace)
1353 break;
1354 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1355 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001356 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001357 return(MagickFalse);
1358 }
1359 case 'g':
1360 case 'G':
1361 {
1362 quantum_map[i]=GreenQuantum;
1363 break;
1364 }
1365 case 'I':
1366 case 'i':
1367 {
1368 quantum_map[i]=IndexQuantum;
1369 break;
1370 }
1371 case 'K':
1372 case 'k':
1373 {
1374 quantum_map[i]=BlackQuantum;
1375 if (image->colorspace == CMYKColorspace)
1376 break;
1377 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1378 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001379 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001380 return(MagickFalse);
1381 }
1382 case 'M':
1383 case 'm':
1384 {
1385 quantum_map[i]=MagentaQuantum;
1386 if (image->colorspace == CMYKColorspace)
1387 break;
1388 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1389 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001390 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001391 return(MagickFalse);
1392 }
1393 case 'o':
1394 case 'O':
1395 {
1396 quantum_map[i]=OpacityQuantum;
1397 break;
1398 }
1399 case 'P':
1400 case 'p':
1401 {
1402 quantum_map[i]=UndefinedQuantum;
1403 break;
1404 }
1405 case 'R':
1406 case 'r':
1407 {
1408 quantum_map[i]=RedQuantum;
1409 break;
1410 }
1411 case 'Y':
1412 case 'y':
1413 {
1414 quantum_map[i]=YellowQuantum;
1415 if (image->colorspace == CMYKColorspace)
1416 break;
1417 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1418 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001419 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001420 return(MagickFalse);
1421 }
1422 default:
1423 {
1424 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1425 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristy20cc0872012-08-20 00:01:19 +00001426 "UnrecognizedPixelMap","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001427 return(MagickFalse);
1428 }
1429 }
1430 }
1431 quantum_info=stream_info->quantum_info;
1432 switch (stream_info->storage_type)
1433 {
1434 case CharPixel:
1435 {
1436 register unsigned char
1437 *q;
1438
1439 q=(unsigned char *) stream_info->pixels;
1440 if (LocaleCompare(stream_info->map,"BGR") == 0)
1441 {
cristy100b8d92012-01-08 00:32:49 +00001442 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001443 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001444 break;
cristybb503372010-05-27 20:51:26 +00001445 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001446 {
cristy4c08aed2011-07-01 19:47:50 +00001447 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1448 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1449 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001450 p++;
1451 }
1452 break;
1453 }
1454 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1455 {
cristy100b8d92012-01-08 00:32:49 +00001456 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001457 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001458 break;
cristybb503372010-05-27 20:51:26 +00001459 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001460 {
cristy4c08aed2011-07-01 19:47:50 +00001461 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1462 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1463 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1464 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001465 p++;
1466 }
1467 break;
1468 }
1469 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1470 {
cristy100b8d92012-01-08 00:32:49 +00001471 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001472 if (p == (const Quantum *) NULL)
cristy100b8d92012-01-08 00:32:49 +00001473 break;
cristybb503372010-05-27 20:51:26 +00001474 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001475 {
cristy4c08aed2011-07-01 19:47:50 +00001476 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1477 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1478 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001479 *q++=ScaleQuantumToChar((Quantum) 0);
1480 p++;
1481 }
1482 break;
1483 }
1484 if (LocaleCompare(stream_info->map,"I") == 0)
1485 {
cristy100b8d92012-01-08 00:32:49 +00001486 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001487 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001488 break;
cristybb503372010-05-27 20:51:26 +00001489 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001490 {
cristyf13c5942012-08-08 23:50:11 +00001491 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001492 p++;
1493 }
1494 break;
1495 }
1496 if (LocaleCompare(stream_info->map,"RGB") == 0)
1497 {
cristy100b8d92012-01-08 00:32:49 +00001498 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001499 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001500 break;
cristybb503372010-05-27 20:51:26 +00001501 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001502 {
cristy4c08aed2011-07-01 19:47:50 +00001503 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1504 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1505 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001506 p++;
1507 }
1508 break;
1509 }
1510 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1511 {
cristy100b8d92012-01-08 00:32:49 +00001512 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001513 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001514 break;
cristybb503372010-05-27 20:51:26 +00001515 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001516 {
cristy4c08aed2011-07-01 19:47:50 +00001517 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1518 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1519 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1520 *q++=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001521 p++;
1522 }
1523 break;
1524 }
1525 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1526 {
cristy100b8d92012-01-08 00:32:49 +00001527 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001528 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001529 break;
cristybb503372010-05-27 20:51:26 +00001530 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001531 {
cristy4c08aed2011-07-01 19:47:50 +00001532 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1533 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1534 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001535 *q++=ScaleQuantumToChar((Quantum) 0);
1536 p++;
1537 }
1538 break;
1539 }
cristy100b8d92012-01-08 00:32:49 +00001540 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001541 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001542 break;
cristybb503372010-05-27 20:51:26 +00001543 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001544 {
cristybb503372010-05-27 20:51:26 +00001545 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001546 {
1547 *q=0;
1548 switch (quantum_map[i])
1549 {
1550 case RedQuantum:
1551 case CyanQuantum:
1552 {
cristy4c08aed2011-07-01 19:47:50 +00001553 *q=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001554 break;
1555 }
1556 case GreenQuantum:
1557 case MagentaQuantum:
1558 {
cristy4c08aed2011-07-01 19:47:50 +00001559 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001560 break;
1561 }
1562 case BlueQuantum:
1563 case YellowQuantum:
1564 {
cristy4c08aed2011-07-01 19:47:50 +00001565 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001566 break;
1567 }
1568 case AlphaQuantum:
1569 {
cristy4c08aed2011-07-01 19:47:50 +00001570 *q=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001571 break;
1572 }
1573 case OpacityQuantum:
1574 {
cristy4c08aed2011-07-01 19:47:50 +00001575 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001576 break;
1577 }
1578 case BlackQuantum:
1579 {
1580 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001581 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001582 break;
1583 }
1584 case IndexQuantum:
1585 {
cristyf13c5942012-08-08 23:50:11 +00001586 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001587 break;
1588 }
1589 default:
1590 break;
1591 }
1592 q++;
1593 }
1594 p++;
1595 }
1596 break;
1597 }
1598 case DoublePixel:
1599 {
1600 register double
1601 *q;
1602
1603 q=(double *) stream_info->pixels;
1604 if (LocaleCompare(stream_info->map,"BGR") == 0)
1605 {
cristy100b8d92012-01-08 00:32:49 +00001606 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001607 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001608 break;
cristybb503372010-05-27 20:51:26 +00001609 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001610 {
cristy4c08aed2011-07-01 19:47:50 +00001611 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001612 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001613 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001614 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001615 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001616 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001617 p++;
1618 }
1619 break;
1620 }
1621 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1622 {
cristy100b8d92012-01-08 00:32:49 +00001623 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001624 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001625 break;
cristybb503372010-05-27 20:51:26 +00001626 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001627 {
cristy4c08aed2011-07-01 19:47:50 +00001628 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001629 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001630 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001631 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001632 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001633 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001634 *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001635 quantum_info->scale+quantum_info->minimum);
1636 p++;
1637 }
1638 break;
1639 }
1640 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1641 {
cristy100b8d92012-01-08 00:32:49 +00001642 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001643 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001644 break;
cristybb503372010-05-27 20:51:26 +00001645 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001646 {
cristy4c08aed2011-07-01 19:47:50 +00001647 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001648 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001649 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001650 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001651 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001652 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001653 *q++=0.0;
1654 p++;
1655 }
1656 break;
1657 }
1658 if (LocaleCompare(stream_info->map,"I") == 0)
1659 {
cristy100b8d92012-01-08 00:32:49 +00001660 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001661 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001662 break;
cristybb503372010-05-27 20:51:26 +00001663 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001664 {
cristy4c08aed2011-07-01 19:47:50 +00001665 *q++=(double) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001666 quantum_info->scale+quantum_info->minimum);
1667 p++;
1668 }
1669 break;
1670 }
1671 if (LocaleCompare(stream_info->map,"RGB") == 0)
1672 {
cristy100b8d92012-01-08 00:32:49 +00001673 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001674 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001675 break;
cristybb503372010-05-27 20:51:26 +00001676 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001677 {
cristy4c08aed2011-07-01 19:47:50 +00001678 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001679 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001680 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001681 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001682 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001683 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001684 p++;
1685 }
1686 break;
1687 }
1688 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1689 {
cristy100b8d92012-01-08 00:32:49 +00001690 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001691 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001692 break;
cristybb503372010-05-27 20:51:26 +00001693 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001694 {
cristy4c08aed2011-07-01 19:47:50 +00001695 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001696 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001697 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001698 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001699 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001700 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001701 *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001702 quantum_info->scale+quantum_info->minimum);
1703 p++;
1704 }
1705 break;
1706 }
1707 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1708 {
cristy100b8d92012-01-08 00:32:49 +00001709 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001710 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001711 break;
cristybb503372010-05-27 20:51:26 +00001712 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001713 {
cristy4c08aed2011-07-01 19:47:50 +00001714 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001715 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001716 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001717 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001718 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001719 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001720 *q++=0.0;
1721 p++;
1722 }
1723 break;
1724 }
cristy100b8d92012-01-08 00:32:49 +00001725 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001726 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001727 break;
cristybb503372010-05-27 20:51:26 +00001728 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001729 {
cristybb503372010-05-27 20:51:26 +00001730 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001731 {
1732 *q=0;
1733 switch (quantum_map[i])
1734 {
1735 case RedQuantum:
1736 case CyanQuantum:
1737 {
cristy4c08aed2011-07-01 19:47:50 +00001738 *q=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001739 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001740 break;
1741 }
1742 case GreenQuantum:
1743 case MagentaQuantum:
1744 {
cristy4c08aed2011-07-01 19:47:50 +00001745 *q=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001746 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001747 break;
1748 }
1749 case BlueQuantum:
1750 case YellowQuantum:
1751 {
cristy4c08aed2011-07-01 19:47:50 +00001752 *q=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001753 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001754 break;
1755 }
1756 case AlphaQuantum:
1757 {
cristy4c08aed2011-07-01 19:47:50 +00001758 *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001759 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001760 break;
1761 }
1762 case OpacityQuantum:
1763 {
cristy4c08aed2011-07-01 19:47:50 +00001764 *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001765 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001766 break;
1767 }
1768 case BlackQuantum:
1769 {
1770 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001771 *q=(double) ((QuantumScale*GetPixelBlack(image,p))*
cristyfba5a8b2011-05-03 17:12:12 +00001772 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001773 break;
1774 }
1775 case IndexQuantum:
1776 {
cristy4c08aed2011-07-01 19:47:50 +00001777 *q=(double) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001778 quantum_info->scale+quantum_info->minimum);
1779 break;
1780 }
1781 default:
1782 *q=0;
1783 }
1784 q++;
1785 }
1786 p++;
1787 }
1788 break;
1789 }
1790 case FloatPixel:
1791 {
1792 register float
1793 *q;
1794
1795 q=(float *) stream_info->pixels;
1796 if (LocaleCompare(stream_info->map,"BGR") == 0)
1797 {
cristy100b8d92012-01-08 00:32:49 +00001798 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001799 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001800 break;
cristybb503372010-05-27 20:51:26 +00001801 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001802 {
cristy4c08aed2011-07-01 19:47:50 +00001803 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001804 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001805 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001806 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001807 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001808 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001809 p++;
1810 }
1811 break;
1812 }
1813 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1814 {
cristy100b8d92012-01-08 00:32:49 +00001815 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001816 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001817 break;
cristybb503372010-05-27 20:51:26 +00001818 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001819 {
cristy4c08aed2011-07-01 19:47:50 +00001820 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001821 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001822 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001823 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001824 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001825 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001826 *q++=(float) ((QuantumScale*(Quantum) (GetPixelAlpha(image,p)))*
cristy3ed852e2009-09-05 21:47:34 +00001827 quantum_info->scale+quantum_info->minimum);
1828 p++;
1829 }
1830 break;
1831 }
1832 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1833 {
cristy100b8d92012-01-08 00:32:49 +00001834 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001835 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001836 break;
cristybb503372010-05-27 20:51:26 +00001837 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001838 {
cristy4c08aed2011-07-01 19:47:50 +00001839 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001840 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001841 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001842 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001843 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001844 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001845 *q++=0.0;
1846 p++;
1847 }
1848 break;
1849 }
1850 if (LocaleCompare(stream_info->map,"I") == 0)
1851 {
cristy100b8d92012-01-08 00:32:49 +00001852 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001853 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001854 break;
cristybb503372010-05-27 20:51:26 +00001855 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001856 {
cristy4c08aed2011-07-01 19:47:50 +00001857 *q++=(float) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001858 quantum_info->scale+quantum_info->minimum);
1859 p++;
1860 }
1861 break;
1862 }
1863 if (LocaleCompare(stream_info->map,"RGB") == 0)
1864 {
cristy100b8d92012-01-08 00:32:49 +00001865 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001866 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001867 break;
cristybb503372010-05-27 20:51:26 +00001868 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001869 {
cristy4c08aed2011-07-01 19:47:50 +00001870 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001871 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001872 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001873 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001874 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001875 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001876 p++;
1877 }
1878 break;
1879 }
1880 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1881 {
cristy100b8d92012-01-08 00:32:49 +00001882 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001883 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001884 break;
cristybb503372010-05-27 20:51:26 +00001885 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001886 {
cristy4c08aed2011-07-01 19:47:50 +00001887 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001888 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001889 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001890 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001891 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001892 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001893 *q++=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001894 quantum_info->scale+quantum_info->minimum);
1895 p++;
1896 }
1897 break;
1898 }
1899 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1900 {
cristy100b8d92012-01-08 00:32:49 +00001901 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001902 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001903 break;
cristybb503372010-05-27 20:51:26 +00001904 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001905 {
cristy4c08aed2011-07-01 19:47:50 +00001906 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001907 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001908 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001909 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001910 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001911 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001912 *q++=0.0;
1913 p++;
1914 }
1915 break;
1916 }
cristy100b8d92012-01-08 00:32:49 +00001917 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001918 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001919 break;
cristybb503372010-05-27 20:51:26 +00001920 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001921 {
cristybb503372010-05-27 20:51:26 +00001922 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001923 {
1924 *q=0;
1925 switch (quantum_map[i])
1926 {
1927 case RedQuantum:
1928 case CyanQuantum:
1929 {
cristy4c08aed2011-07-01 19:47:50 +00001930 *q=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001931 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001932 break;
1933 }
1934 case GreenQuantum:
1935 case MagentaQuantum:
1936 {
cristy4c08aed2011-07-01 19:47:50 +00001937 *q=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001938 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001939 break;
1940 }
1941 case BlueQuantum:
1942 case YellowQuantum:
1943 {
cristy4c08aed2011-07-01 19:47:50 +00001944 *q=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001945 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001946 break;
1947 }
1948 case AlphaQuantum:
1949 {
cristy4c08aed2011-07-01 19:47:50 +00001950 *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001951 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001952 break;
1953 }
1954 case OpacityQuantum:
1955 {
cristy4c08aed2011-07-01 19:47:50 +00001956 *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001957 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001958 break;
1959 }
1960 case BlackQuantum:
1961 {
1962 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001963 *q=(float) ((QuantumScale*GetPixelBlack(image,p))*
cristyfba5a8b2011-05-03 17:12:12 +00001964 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001965 break;
1966 }
1967 case IndexQuantum:
1968 {
cristy4c08aed2011-07-01 19:47:50 +00001969 *q=(float) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001970 quantum_info->scale+quantum_info->minimum);
1971 break;
1972 }
1973 default:
1974 *q=0;
1975 }
1976 q++;
1977 }
1978 p++;
1979 }
1980 break;
1981 }
cristy100b8d92012-01-08 00:32:49 +00001982 case LongPixel:
cristy3ed852e2009-09-05 21:47:34 +00001983 {
1984 register unsigned int
1985 *q;
1986
1987 q=(unsigned int *) stream_info->pixels;
1988 if (LocaleCompare(stream_info->map,"BGR") == 0)
1989 {
cristy100b8d92012-01-08 00:32:49 +00001990 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001991 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001992 break;
cristybb503372010-05-27 20:51:26 +00001993 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001994 {
cristy4c08aed2011-07-01 19:47:50 +00001995 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1996 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1997 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001998 p++;
1999 }
2000 break;
2001 }
2002 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2003 {
cristy100b8d92012-01-08 00:32:49 +00002004 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002005 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002006 break;
cristybb503372010-05-27 20:51:26 +00002007 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002008 {
cristy4c08aed2011-07-01 19:47:50 +00002009 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2010 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2011 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2012 *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002013 p++;
2014 }
2015 break;
2016 }
2017 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2018 {
cristy100b8d92012-01-08 00:32:49 +00002019 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002020 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002021 break;
cristybb503372010-05-27 20:51:26 +00002022 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002023 {
cristy4c08aed2011-07-01 19:47:50 +00002024 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2025 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2026 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002027 *q++=0;
2028 p++;
2029 }
2030 break;
2031 }
2032 if (LocaleCompare(stream_info->map,"I") == 0)
2033 {
cristy100b8d92012-01-08 00:32:49 +00002034 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002035 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002036 break;
cristybb503372010-05-27 20:51:26 +00002037 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002038 {
cristyf13c5942012-08-08 23:50:11 +00002039 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002040 p++;
2041 }
2042 break;
2043 }
2044 if (LocaleCompare(stream_info->map,"RGB") == 0)
2045 {
cristy100b8d92012-01-08 00:32:49 +00002046 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002047 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002048 break;
cristybb503372010-05-27 20:51:26 +00002049 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002050 {
cristy4c08aed2011-07-01 19:47:50 +00002051 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2052 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2053 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002054 p++;
2055 }
2056 break;
2057 }
2058 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2059 {
cristy100b8d92012-01-08 00:32:49 +00002060 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002061 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002062 break;
cristybb503372010-05-27 20:51:26 +00002063 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002064 {
cristy4c08aed2011-07-01 19:47:50 +00002065 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2066 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2067 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2068 *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002069 p++;
2070 }
2071 break;
2072 }
2073 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2074 {
cristy100b8d92012-01-08 00:32:49 +00002075 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002076 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002077 break;
cristybb503372010-05-27 20:51:26 +00002078 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002079 {
cristy4c08aed2011-07-01 19:47:50 +00002080 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2081 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2082 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002083 *q++=0;
2084 p++;
2085 }
2086 break;
2087 }
cristy100b8d92012-01-08 00:32:49 +00002088 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002089 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002090 break;
cristybb503372010-05-27 20:51:26 +00002091 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002092 {
cristybb503372010-05-27 20:51:26 +00002093 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002094 {
2095 *q=0;
2096 switch (quantum_map[i])
2097 {
2098 case RedQuantum:
2099 case CyanQuantum:
2100 {
cristy4c08aed2011-07-01 19:47:50 +00002101 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002102 break;
2103 }
2104 case GreenQuantum:
2105 case MagentaQuantum:
2106 {
cristy4c08aed2011-07-01 19:47:50 +00002107 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002108 break;
2109 }
2110 case BlueQuantum:
2111 case YellowQuantum:
2112 {
cristy4c08aed2011-07-01 19:47:50 +00002113 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002114 break;
2115 }
2116 case AlphaQuantum:
2117 {
cristy4c08aed2011-07-01 19:47:50 +00002118 *q=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002119 break;
2120 }
2121 case OpacityQuantum:
2122 {
cristy4c08aed2011-07-01 19:47:50 +00002123 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002124 break;
2125 }
2126 case BlackQuantum:
2127 {
2128 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002129 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002130 break;
2131 }
2132 case IndexQuantum:
2133 {
cristyf13c5942012-08-08 23:50:11 +00002134 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002135 break;
2136 }
2137 default:
2138 break;
2139 }
2140 q++;
2141 }
2142 p++;
2143 }
2144 break;
2145 }
cristy100b8d92012-01-08 00:32:49 +00002146 case LongLongPixel:
2147 {
2148 register MagickSizeType
2149 *q;
2150
2151 q=(MagickSizeType *) stream_info->pixels;
2152 if (LocaleCompare(stream_info->map,"BGR") == 0)
2153 {
2154 p=GetVirtualPixelQueue(image);
2155 if (p == (const Quantum *) NULL)
2156 break;
2157 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2158 {
2159 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2160 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2161 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2162 p++;
2163 }
2164 break;
2165 }
2166 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2167 {
2168 p=GetVirtualPixelQueue(image);
2169 if (p == (const Quantum *) NULL)
2170 break;
2171 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2172 {
2173 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2174 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2175 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2176 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2177 p++;
2178 }
2179 break;
2180 }
2181 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2182 {
2183 p=GetVirtualPixelQueue(image);
2184 if (p == (const Quantum *) NULL)
2185 break;
2186 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2187 {
2188 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2189 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2190 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2191 *q++=0U;
2192 p++;
2193 }
2194 break;
2195 }
2196 if (LocaleCompare(stream_info->map,"I") == 0)
2197 {
2198 p=GetVirtualPixelQueue(image);
2199 if (p == (const Quantum *) NULL)
2200 break;
2201 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2202 {
cristyf13c5942012-08-08 23:50:11 +00002203 *q++=ScaleQuantumToLongLong(ClampToQuantum(
2204 GetPixelIntensity(image,p)));
cristy100b8d92012-01-08 00:32:49 +00002205 p++;
2206 }
2207 break;
2208 }
2209 if (LocaleCompare(stream_info->map,"RGB") == 0)
2210 {
2211 p=GetVirtualPixelQueue(image);
2212 if (p == (const Quantum *) NULL)
2213 break;
2214 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2215 {
2216 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2217 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2218 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2219 p++;
2220 }
2221 break;
2222 }
2223 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2224 {
2225 p=GetVirtualPixelQueue(image);
2226 if (p == (const Quantum *) NULL)
2227 break;
2228 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2229 {
2230 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2231 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2232 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2233 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2234 p++;
2235 }
2236 break;
2237 }
2238 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2239 {
2240 p=GetVirtualPixelQueue(image);
2241 if (p == (const Quantum *) NULL)
2242 break;
2243 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2244 {
2245 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2246 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2247 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2248 *q++=0U;
2249 p++;
2250 }
2251 break;
2252 }
2253 p=GetVirtualPixelQueue(image);
2254 if (p == (const Quantum *) NULL)
2255 break;
2256 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2257 {
2258 for (i=0; i < (ssize_t) length; i++)
2259 {
2260 *q=0;
2261 switch (quantum_map[i])
2262 {
2263 case RedQuantum:
2264 case CyanQuantum:
2265 {
2266 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
2267 break;
2268 }
2269 case GreenQuantum:
2270 case MagentaQuantum:
2271 {
2272 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2273 break;
2274 }
2275 case BlueQuantum:
2276 case YellowQuantum:
2277 {
2278 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2279 break;
2280 }
2281 case AlphaQuantum:
2282 {
2283 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2284 break;
2285 }
2286 case OpacityQuantum:
2287 {
2288 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2289 break;
2290 }
2291 case BlackQuantum:
2292 {
2293 if (image->colorspace == CMYKColorspace)
2294 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
2295 break;
2296 }
2297 case IndexQuantum:
2298 {
cristyf13c5942012-08-08 23:50:11 +00002299 *q=ScaleQuantumToLongLong(ClampToQuantum(
2300 GetPixelIntensity(image,p)));
cristy100b8d92012-01-08 00:32:49 +00002301 break;
2302 }
2303 default:
2304 *q=0;
2305 }
2306 q++;
2307 }
2308 p++;
2309 }
2310 break;
2311 }
cristy3ed852e2009-09-05 21:47:34 +00002312 case QuantumPixel:
2313 {
2314 register Quantum
2315 *q;
2316
2317 q=(Quantum *) stream_info->pixels;
2318 if (LocaleCompare(stream_info->map,"BGR") == 0)
2319 {
cristy100b8d92012-01-08 00:32:49 +00002320 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002321 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002322 break;
cristybb503372010-05-27 20:51:26 +00002323 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002324 {
cristy4c08aed2011-07-01 19:47:50 +00002325 *q++=GetPixelBlue(image,p);
2326 *q++=GetPixelGreen(image,p);
2327 *q++=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002328 p++;
2329 }
2330 break;
2331 }
2332 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2333 {
cristy100b8d92012-01-08 00:32:49 +00002334 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002335 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002336 break;
cristybb503372010-05-27 20:51:26 +00002337 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002338 {
cristy4c08aed2011-07-01 19:47:50 +00002339 *q++=GetPixelBlue(image,p);
2340 *q++=GetPixelGreen(image,p);
2341 *q++=GetPixelRed(image,p);
cristy100b8d92012-01-08 00:32:49 +00002342 *q++=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002343 p++;
2344 }
2345 break;
2346 }
2347 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2348 {
cristy100b8d92012-01-08 00:32:49 +00002349 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002350 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002351 break;
cristybb503372010-05-27 20:51:26 +00002352 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002353 {
cristy4c08aed2011-07-01 19:47:50 +00002354 *q++=GetPixelBlue(image,p);
2355 *q++=GetPixelGreen(image,p);
2356 *q++=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002357 *q++=0;
2358 p++;
2359 }
2360 break;
2361 }
2362 if (LocaleCompare(stream_info->map,"I") == 0)
2363 {
cristy100b8d92012-01-08 00:32:49 +00002364 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002365 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002366 break;
cristybb503372010-05-27 20:51:26 +00002367 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002368 {
cristyf13c5942012-08-08 23:50:11 +00002369 *q++=ClampToQuantum(GetPixelIntensity(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002370 p++;
2371 }
2372 break;
2373 }
2374 if (LocaleCompare(stream_info->map,"RGB") == 0)
2375 {
cristy100b8d92012-01-08 00:32:49 +00002376 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002377 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002378 break;
cristybb503372010-05-27 20:51:26 +00002379 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002380 {
cristy4c08aed2011-07-01 19:47:50 +00002381 *q++=GetPixelRed(image,p);
2382 *q++=GetPixelGreen(image,p);
2383 *q++=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002384 p++;
2385 }
2386 break;
2387 }
2388 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2389 {
cristy100b8d92012-01-08 00:32:49 +00002390 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002391 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002392 break;
cristybb503372010-05-27 20:51:26 +00002393 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002394 {
cristy4c08aed2011-07-01 19:47:50 +00002395 *q++=GetPixelRed(image,p);
2396 *q++=GetPixelGreen(image,p);
2397 *q++=GetPixelBlue(image,p);
cristy100b8d92012-01-08 00:32:49 +00002398 *q++=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002399 p++;
2400 }
2401 break;
2402 }
2403 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2404 {
cristy100b8d92012-01-08 00:32:49 +00002405 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002406 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002407 break;
cristybb503372010-05-27 20:51:26 +00002408 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002409 {
cristy4c08aed2011-07-01 19:47:50 +00002410 *q++=GetPixelRed(image,p);
2411 *q++=GetPixelGreen(image,p);
2412 *q++=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002413 *q++=0U;
2414 p++;
2415 }
2416 break;
2417 }
cristy100b8d92012-01-08 00:32:49 +00002418 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002419 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002420 break;
cristybb503372010-05-27 20:51:26 +00002421 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002422 {
cristybb503372010-05-27 20:51:26 +00002423 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002424 {
2425 *q=(Quantum) 0;
2426 switch (quantum_map[i])
2427 {
2428 case RedQuantum:
2429 case CyanQuantum:
2430 {
cristy4c08aed2011-07-01 19:47:50 +00002431 *q=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002432 break;
2433 }
2434 case GreenQuantum:
2435 case MagentaQuantum:
2436 {
cristy4c08aed2011-07-01 19:47:50 +00002437 *q=GetPixelGreen(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002438 break;
2439 }
2440 case BlueQuantum:
2441 case YellowQuantum:
2442 {
cristy4c08aed2011-07-01 19:47:50 +00002443 *q=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002444 break;
2445 }
2446 case AlphaQuantum:
2447 {
cristy4c08aed2011-07-01 19:47:50 +00002448 *q=(Quantum) (GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002449 break;
2450 }
2451 case OpacityQuantum:
2452 {
cristy4c08aed2011-07-01 19:47:50 +00002453 *q=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002454 break;
2455 }
2456 case BlackQuantum:
2457 {
2458 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002459 *q=GetPixelBlack(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002460 break;
2461 }
2462 case IndexQuantum:
2463 {
cristyf13c5942012-08-08 23:50:11 +00002464 *q=ClampToQuantum(GetPixelIntensity(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002465 break;
2466 }
2467 default:
2468 *q=0;
2469 }
2470 q++;
2471 }
2472 p++;
2473 }
2474 break;
2475 }
2476 case ShortPixel:
2477 {
2478 register unsigned short
2479 *q;
2480
2481 q=(unsigned short *) stream_info->pixels;
2482 if (LocaleCompare(stream_info->map,"BGR") == 0)
2483 {
cristy100b8d92012-01-08 00:32:49 +00002484 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002485 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002486 break;
cristybb503372010-05-27 20:51:26 +00002487 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002488 {
cristy4c08aed2011-07-01 19:47:50 +00002489 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2490 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2491 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002492 p++;
2493 }
2494 break;
2495 }
2496 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2497 {
cristy100b8d92012-01-08 00:32:49 +00002498 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002499 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002500 break;
cristybb503372010-05-27 20:51:26 +00002501 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002502 {
cristy4c08aed2011-07-01 19:47:50 +00002503 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2504 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2505 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2506 *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002507 p++;
2508 }
2509 break;
2510 }
2511 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2512 {
cristy100b8d92012-01-08 00:32:49 +00002513 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002514 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002515 break;
cristybb503372010-05-27 20:51:26 +00002516 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002517 {
cristy4c08aed2011-07-01 19:47:50 +00002518 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2519 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2520 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002521 *q++=0;
2522 p++;
2523 }
2524 break;
2525 }
2526 if (LocaleCompare(stream_info->map,"I") == 0)
2527 {
cristy100b8d92012-01-08 00:32:49 +00002528 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002529 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002530 break;
cristybb503372010-05-27 20:51:26 +00002531 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002532 {
cristyf13c5942012-08-08 23:50:11 +00002533 *q++=ScaleQuantumToShort(ClampToQuantum(
2534 GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002535 p++;
2536 }
2537 break;
2538 }
2539 if (LocaleCompare(stream_info->map,"RGB") == 0)
2540 {
cristy100b8d92012-01-08 00:32:49 +00002541 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002542 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002543 break;
cristybb503372010-05-27 20:51:26 +00002544 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002545 {
cristy4c08aed2011-07-01 19:47:50 +00002546 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2547 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2548 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002549 p++;
2550 }
2551 break;
2552 }
2553 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2554 {
cristy100b8d92012-01-08 00:32:49 +00002555 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002556 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002557 break;
cristybb503372010-05-27 20:51:26 +00002558 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002559 {
cristy4c08aed2011-07-01 19:47:50 +00002560 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2561 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2562 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2563 *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002564 p++;
2565 }
2566 break;
2567 }
2568 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2569 {
cristy100b8d92012-01-08 00:32:49 +00002570 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002571 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002572 break;
cristybb503372010-05-27 20:51:26 +00002573 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002574 {
cristy4c08aed2011-07-01 19:47:50 +00002575 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2576 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2577 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002578 *q++=0;
2579 p++;
2580 }
2581 break;
2582 }
cristy100b8d92012-01-08 00:32:49 +00002583 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002584 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002585 break;
cristybb503372010-05-27 20:51:26 +00002586 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002587 {
cristybb503372010-05-27 20:51:26 +00002588 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002589 {
2590 *q=0;
2591 switch (quantum_map[i])
2592 {
2593 case RedQuantum:
2594 case CyanQuantum:
2595 {
cristy4c08aed2011-07-01 19:47:50 +00002596 *q=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002597 break;
2598 }
2599 case GreenQuantum:
2600 case MagentaQuantum:
2601 {
cristy4c08aed2011-07-01 19:47:50 +00002602 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002603 break;
2604 }
2605 case BlueQuantum:
2606 case YellowQuantum:
2607 {
cristy4c08aed2011-07-01 19:47:50 +00002608 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002609 break;
2610 }
2611 case AlphaQuantum:
2612 {
cristy4c08aed2011-07-01 19:47:50 +00002613 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002614 break;
2615 }
2616 case OpacityQuantum:
2617 {
cristy4c08aed2011-07-01 19:47:50 +00002618 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002619 break;
2620 }
2621 case BlackQuantum:
2622 {
2623 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002624 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002625 break;
2626 }
2627 case IndexQuantum:
2628 {
cristyf13c5942012-08-08 23:50:11 +00002629 *q=ScaleQuantumToShort(ClampToQuantum(
2630 GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002631 break;
2632 }
2633 default:
2634 break;
2635 }
2636 q++;
2637 }
2638 p++;
2639 }
2640 break;
2641 }
2642 default:
2643 {
2644 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2645 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristy20cc0872012-08-20 00:01:19 +00002646 "UnrecognizedPixelMap","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00002647 break;
2648 }
2649 }
2650 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2651 return(MagickTrue);
2652}
2653
2654/*
2655%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2656% %
2657% %
2658% %
2659+ S y n c A u t h e n t i c P i x e l s S t r e a m %
2660% %
2661% %
2662% %
2663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2664%
2665% SyncAuthenticPixelsStream() calls the user supplied callback method with
2666% the latest stream of pixels.
2667%
2668% The format of the SyncAuthenticPixelsStream method is:
2669%
2670% MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2671% ExceptionInfo *exception)
2672%
2673% A description of each parameter follows:
2674%
2675% o image: the image.
2676%
2677% o exception: return any errors or warnings in this structure.
2678%
2679*/
2680static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2681 ExceptionInfo *exception)
2682{
2683 CacheInfo
2684 *cache_info;
2685
2686 size_t
2687 length;
2688
2689 StreamHandler
2690 stream_handler;
2691
2692 assert(image != (Image *) NULL);
2693 assert(image->signature == MagickSignature);
2694 if (image->debug != MagickFalse)
2695 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2696 cache_info=(CacheInfo *) image->cache;
2697 assert(cache_info->signature == MagickSignature);
2698 stream_handler=GetBlobStreamHandler(image);
2699 if (stream_handler == (StreamHandler) NULL)
2700 {
2701 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +00002702 "NoStreamHandlerIsDefined","'%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +00002703 return(MagickFalse);
2704 }
2705 length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
2706 return(length == cache_info->columns ? MagickTrue : MagickFalse);
2707}
2708
2709/*
2710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2711% %
2712% %
2713% %
2714% W r i t e S t r e a m %
2715% %
2716% %
2717% %
2718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2719%
2720% WriteStream() makes the image pixels available to a user supplied callback
2721% method immediately upon writing pixel data with the WriteImage() method.
2722%
2723% The format of the WriteStream() method is:
2724%
2725% MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
cristyc82a27b2011-10-21 01:07:16 +00002726% StreamHandler stream,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002727%
2728% A description of each parameter follows:
2729%
2730% o image_info: the image info.
2731%
2732% o stream: A callback method.
2733%
cristyc82a27b2011-10-21 01:07:16 +00002734% o exception: return any errors or warnings in this structure.
2735%
cristy3ed852e2009-09-05 21:47:34 +00002736*/
2737MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
cristyc82a27b2011-10-21 01:07:16 +00002738 Image *image,StreamHandler stream,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002739{
2740 ImageInfo
2741 *write_info;
2742
2743 MagickBooleanType
2744 status;
2745
2746 assert(image_info != (ImageInfo *) NULL);
2747 assert(image_info->signature == MagickSignature);
2748 if (image_info->debug != MagickFalse)
2749 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2750 image_info->filename);
2751 assert(image != (Image *) NULL);
2752 assert(image->signature == MagickSignature);
2753 write_info=CloneImageInfo(image_info);
2754 write_info->stream=stream;
cristyc82a27b2011-10-21 01:07:16 +00002755 status=WriteImage(write_info,image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002756 write_info=DestroyImageInfo(write_info);
2757 return(status);
2758}