blob: db2a11ddf36161721ae94b5ed31813d018b29552 [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"
55#include "MagickCore/pixel.h"
56#include "MagickCore/pixel-accessor.h"
57#include "MagickCore/quantum.h"
58#include "MagickCore/quantum-private.h"
59#include "MagickCore/semaphore.h"
60#include "MagickCore/stream.h"
61#include "MagickCore/stream-private.h"
62#include "MagickCore/string_.h"
cristy3ed852e2009-09-05 21:47:34 +000063
64/*
65 Typedef declaractions.
66*/
67struct _StreamInfo
68{
69 const ImageInfo
70 *image_info;
71
72 const Image
73 *image;
74
75 Image
76 *stream;
77
78 QuantumInfo
79 *quantum_info;
80
81 char
82 *map;
83
84 StorageType
85 storage_type;
86
87 unsigned char
88 *pixels;
89
90 RectangleInfo
91 extract_info;
92
cristybb503372010-05-27 20:51:26 +000093 ssize_t
cristy3ed852e2009-09-05 21:47:34 +000094 y;
95
96 ExceptionInfo
97 *exception;
98
99 const void
100 *client_data;
101
cristybb503372010-05-27 20:51:26 +0000102 size_t
cristy3ed852e2009-09-05 21:47:34 +0000103 signature;
104};
105
106/*
107 Declare pixel cache interfaces.
108*/
109#if defined(__cplusplus) || defined(c_plusplus)
110extern "C" {
111#endif
112
cristy4c08aed2011-07-01 19:47:50 +0000113static const Quantum
cristybb503372010-05-27 20:51:26 +0000114 *GetVirtualPixelStream(const Image *,const VirtualPixelMethod,const ssize_t,
115 const ssize_t,const size_t,const size_t,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000116
117static MagickBooleanType
118 StreamImagePixels(const StreamInfo *,const Image *,ExceptionInfo *),
119 SyncAuthenticPixelsStream(Image *,ExceptionInfo *);
120
cristy4c08aed2011-07-01 19:47:50 +0000121static Quantum
cristybb503372010-05-27 20:51:26 +0000122 *QueueAuthenticPixelsStream(Image *,const ssize_t,const ssize_t,const size_t,
123 const size_t,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000124
125#if defined(__cplusplus) || defined(c_plusplus)
126}
127#endif
128
129/*
130%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131% %
132% %
133% %
134+ A c q u i r e S t r e a m I n f o %
135% %
136% %
137% %
138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139%
140% AcquireStreamInfo() allocates the StreamInfo structure.
141%
142% The format of the AcquireStreamInfo method is:
143%
cristy9950d572011-10-01 18:22:35 +0000144% StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
145% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000146%
147% A description of each parameter follows:
148%
149% o image_info: the image info.
150%
cristy9950d572011-10-01 18:22:35 +0000151% o exception: return any errors or warnings in this structure.
152%
cristy3ed852e2009-09-05 21:47:34 +0000153*/
cristy9950d572011-10-01 18:22:35 +0000154MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
155 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000156{
157 StreamInfo
158 *stream_info;
159
cristy73bd4a52010-10-05 11:24:23 +0000160 stream_info=(StreamInfo *) AcquireMagickMemory(sizeof(*stream_info));
cristy3ed852e2009-09-05 21:47:34 +0000161 if (stream_info == (StreamInfo *) NULL)
162 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
163 (void) ResetMagickMemory(stream_info,0,sizeof(*stream_info));
cristy39c2e212012-08-18 18:14:34 +0000164 stream_info->pixels=(unsigned char *) AcquireAlignedMemory(1,
cristy3ed852e2009-09-05 21:47:34 +0000165 sizeof(*stream_info->pixels));
166 if (stream_info->pixels == (unsigned char *) NULL)
167 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
168 stream_info->map=ConstantString("RGB");
169 stream_info->storage_type=CharPixel;
cristy9950d572011-10-01 18:22:35 +0000170 stream_info->stream=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +0000171 stream_info->signature=MagickSignature;
172 return(stream_info);
173}
174
175/*
176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177% %
178% %
179% %
180+ D e s t r o y P i x e l S t r e a m %
181% %
182% %
183% %
184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185%
186% DestroyPixelStream() deallocates memory associated with the pixel stream.
187%
188% The format of the DestroyPixelStream() method is:
189%
190% void DestroyPixelStream(Image *image)
191%
192% A description of each parameter follows:
193%
194% o image: the image.
195%
196*/
197
198static inline void RelinquishStreamPixels(CacheInfo *cache_info)
199{
200 assert(cache_info != (CacheInfo *) NULL);
201 if (cache_info->mapped == MagickFalse)
cristy39c2e212012-08-18 18:14:34 +0000202 (void) RelinquishAlignedMemory(cache_info->pixels);
cristy3ed852e2009-09-05 21:47:34 +0000203 else
204 (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
cristy4c08aed2011-07-01 19:47:50 +0000205 cache_info->pixels=(Quantum *) NULL;
206 cache_info->metacontent=(void *) NULL;
cristy3ed852e2009-09-05 21:47:34 +0000207 cache_info->length=0;
208 cache_info->mapped=MagickFalse;
209}
210
211static void DestroyPixelStream(Image *image)
212{
213 CacheInfo
214 *cache_info;
215
216 MagickBooleanType
217 destroy;
218
219 assert(image != (Image *) NULL);
220 assert(image->signature == MagickSignature);
221 if (image->debug != MagickFalse)
222 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
223 cache_info=(CacheInfo *) image->cache;
224 assert(cache_info->signature == MagickSignature);
225 destroy=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000226 LockSemaphoreInfo(cache_info->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000227 cache_info->reference_count--;
228 if (cache_info->reference_count == 0)
229 destroy=MagickTrue;
cristyf84a1932010-01-03 18:00:18 +0000230 UnlockSemaphoreInfo(cache_info->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000231 if (destroy == MagickFalse)
232 return;
233 RelinquishStreamPixels(cache_info);
234 if (cache_info->nexus_info != (NexusInfo **) NULL)
235 cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
236 cache_info->number_threads);
237 if (cache_info->disk_semaphore != (SemaphoreInfo *) NULL)
238 DestroySemaphoreInfo(&cache_info->disk_semaphore);
239 if (cache_info->semaphore != (SemaphoreInfo *) NULL)
240 DestroySemaphoreInfo(&cache_info->semaphore);
241 cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
242}
243
244/*
245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246% %
247% %
248% %
249+ D e s t r o y S t r e a m I n f o %
250% %
251% %
252% %
253%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254%
255% DestroyStreamInfo() destroys memory associated with the StreamInfo
256% structure.
257%
258% The format of the DestroyStreamInfo method is:
259%
260% StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
261%
262% A description of each parameter follows:
263%
264% o stream_info: the stream info.
265%
266*/
267MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
268{
269 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
270 assert(stream_info != (StreamInfo *) NULL);
271 assert(stream_info->signature == MagickSignature);
272 if (stream_info->map != (char *) NULL)
273 stream_info->map=DestroyString(stream_info->map);
274 if (stream_info->pixels != (unsigned char *) NULL)
cristy39c2e212012-08-18 18:14:34 +0000275 stream_info->pixels=(unsigned char *) RelinquishAlignedMemory(
cristy3ed852e2009-09-05 21:47:34 +0000276 stream_info->pixels);
277 if (stream_info->stream != (Image *) NULL)
278 {
279 (void) CloseBlob(stream_info->stream);
280 stream_info->stream=DestroyImage(stream_info->stream);
281 }
282 if (stream_info->quantum_info != (QuantumInfo *) NULL)
283 stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
284 stream_info->signature=(~MagickSignature);
285 stream_info=(StreamInfo *) RelinquishMagickMemory(stream_info);
286 return(stream_info);
287}
288
289/*
290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291% %
292% %
293% %
cristy4c08aed2011-07-01 19:47:50 +0000294+ 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 +0000295% %
296% %
297% %
298%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299%
cristy4c08aed2011-07-01 19:47:50 +0000300% GetAuthenticMetacontentFromStream() returns the metacontent corresponding
301% with the last call to QueueAuthenticPixelsStream() or
302% GetAuthenticPixelsStream().
cristy3ed852e2009-09-05 21:47:34 +0000303%
cristy4c08aed2011-07-01 19:47:50 +0000304% The format of the GetAuthenticMetacontentFromStream() method is:
cristy3ed852e2009-09-05 21:47:34 +0000305%
cristy4c08aed2011-07-01 19:47:50 +0000306% void *GetAuthenticMetacontentFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000307%
308% A description of each parameter follows:
309%
310% o image: the image.
311%
312*/
cristy4c08aed2011-07-01 19:47:50 +0000313static void *GetAuthenticMetacontentFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000314{
315 CacheInfo
316 *cache_info;
317
318 assert(image != (Image *) NULL);
319 assert(image->signature == MagickSignature);
320 if (image->debug != MagickFalse)
321 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
322 cache_info=(CacheInfo *) image->cache;
323 assert(cache_info->signature == MagickSignature);
cristy4c08aed2011-07-01 19:47:50 +0000324 return(cache_info->metacontent);
cristy3ed852e2009-09-05 21:47:34 +0000325}
326
327/*
328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329% %
330% %
331% %
332+ G e t A u t h e n t i c P i x e l S t r e a m %
333% %
334% %
335% %
336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337%
338% GetAuthenticPixelsStream() gets pixels from the in-memory or disk pixel
339% cache as defined by the geometry parameters. A pointer to the pixels is
340% returned if the pixels are transferred, otherwise a NULL is returned. For
341% streams this method is a no-op.
342%
343% The format of the GetAuthenticPixelsStream() method is:
344%
cristy4c08aed2011-07-01 19:47:50 +0000345% Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000346% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000347% ExceptionInfo *exception)
348%
349% A description of each parameter follows:
350%
351% o image: the image.
352%
353% o x,y,columns,rows: These values define the perimeter of a region of
354% pixels.
355%
356% o exception: return any errors or warnings in this structure.
357%
358*/
cristy4c08aed2011-07-01 19:47:50 +0000359static Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000360 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000361 ExceptionInfo *exception)
362{
cristy4c08aed2011-07-01 19:47:50 +0000363 Quantum
cristy3ed852e2009-09-05 21:47:34 +0000364 *pixels;
365
366 assert(image != (Image *) NULL);
367 assert(image->signature == MagickSignature);
368 if (image->debug != MagickFalse)
369 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
370 pixels=QueueAuthenticPixelsStream(image,x,y,columns,rows,exception);
371 return(pixels);
372}
373
374/*
375%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376% %
377% %
378% %
379+ 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 %
380% %
381% %
382% %
383%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384%
385% GetAuthenticPixelsFromStream() returns the pixels associated with the last
386% call to QueueAuthenticPixelsStream() or GetAuthenticPixelsStream().
387%
388% The format of the GetAuthenticPixelsFromStream() method is:
389%
cristy4c08aed2011-07-01 19:47:50 +0000390% Quantum *GetAuthenticPixelsFromStream(const Image image)
cristy3ed852e2009-09-05 21:47:34 +0000391%
392% A description of each parameter follows:
393%
394% o image: the image.
395%
396*/
cristy4c08aed2011-07-01 19:47:50 +0000397static Quantum *GetAuthenticPixelsFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000398{
399 CacheInfo
400 *cache_info;
401
402 assert(image != (Image *) NULL);
403 assert(image->signature == MagickSignature);
404 if (image->debug != MagickFalse)
405 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
406 cache_info=(CacheInfo *) image->cache;
407 assert(cache_info->signature == MagickSignature);
408 return(cache_info->pixels);
409}
410
411/*
412%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
413% %
414% %
415% %
416+ 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 %
417% %
418% %
419% %
420%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
421%
422% GetOneAuthenticPixelFromStream() returns a single pixel at the specified
423% (x,y) location. The image background color is returned if an error occurs.
424%
425% The format of the GetOneAuthenticPixelFromStream() method is:
426%
427% MagickBooleanType GetOneAuthenticPixelFromStream(const Image image,
cristy2ed42f62011-10-02 19:49:57 +0000428% const ssize_t x,const ssize_t y,Quantum *pixel,
cristycfae90a2010-10-04 14:43:33 +0000429% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000430%
431% A description of each parameter follows:
432%
433% o image: the image.
434%
435% o pixel: return a pixel at the specified (x,y) location.
436%
437% o x,y: These values define the location of the pixel to return.
438%
439% o exception: return any errors or warnings in this structure.
440%
441*/
442static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
cristy2ed42f62011-10-02 19:49:57 +0000443 const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000444{
cristy4c08aed2011-07-01 19:47:50 +0000445 register Quantum
446 *q;
cristy3ed852e2009-09-05 21:47:34 +0000447
cristy2ed42f62011-10-02 19:49:57 +0000448 register ssize_t
449 i;
450
cristy3ed852e2009-09-05 21:47:34 +0000451 assert(image != (Image *) NULL);
452 assert(image->signature == MagickSignature);
cristy2ed42f62011-10-02 19:49:57 +0000453 (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
cristy4c08aed2011-07-01 19:47:50 +0000454 q=GetAuthenticPixelsStream(image,x,y,1,1,exception);
455 if (q != (Quantum *) NULL)
cristy2ed42f62011-10-02 19:49:57 +0000456 {
cristy100b8d92012-01-08 00:32:49 +0000457 pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
458 pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
459 pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
cristyd09f8802012-02-04 16:44:10 +0000460 pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
cristy100b8d92012-01-08 00:32:49 +0000461 pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
cristy2ed42f62011-10-02 19:49:57 +0000462 return(MagickFalse);
463 }
464 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
465 {
466 PixelChannel
467 channel;
468
cristye2a912b2011-12-05 20:02:07 +0000469 channel=GetPixelChannelMapChannel(image,i);
cristy2ed42f62011-10-02 19:49:57 +0000470 pixel[channel]=q[i];
471 }
cristy3ed852e2009-09-05 21:47:34 +0000472 return(MagickTrue);
473}
474
475/*
476%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477% %
478% %
479% %
480+ 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 %
481% %
482% %
483% %
484%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485%
486% GetOneVirtualPixelFromStream() returns a single pixel at the specified
487% (x.y) location. The image background color is returned if an error occurs.
488%
489% The format of the GetOneVirtualPixelFromStream() method is:
490%
491% MagickBooleanType GetOneVirtualPixelFromStream(const Image image,
cristybb503372010-05-27 20:51:26 +0000492% const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
cristy2ed42f62011-10-02 19:49:57 +0000493% const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000494%
495% A description of each parameter follows:
496%
497% o image: the image.
498%
499% o virtual_pixel_method: the virtual pixel method.
500%
501% o x,y: These values define the location of the pixel to return.
502%
503% o pixel: return a pixel at the specified (x,y) location.
504%
505% o exception: return any errors or warnings in this structure.
506%
507*/
508static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000509 const VirtualPixelMethod virtual_pixel_method,const ssize_t x,const ssize_t y,
cristy2ed42f62011-10-02 19:49:57 +0000510 Quantum *pixel,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000511{
cristy4c08aed2011-07-01 19:47:50 +0000512 const Quantum
cristy01cdc902011-08-31 01:05:44 +0000513 *p;
cristy3ed852e2009-09-05 21:47:34 +0000514
cristy2ed42f62011-10-02 19:49:57 +0000515 register ssize_t
516 i;
517
cristy3ed852e2009-09-05 21:47:34 +0000518 assert(image != (Image *) NULL);
519 assert(image->signature == MagickSignature);
cristy2ed42f62011-10-02 19:49:57 +0000520 (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
cristy01cdc902011-08-31 01:05:44 +0000521 p=GetVirtualPixelStream(image,virtual_pixel_method,x,y,1,1,exception);
522 if (p == (const Quantum *) NULL)
cristy2ed42f62011-10-02 19:49:57 +0000523 {
cristy100b8d92012-01-08 00:32:49 +0000524 pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
525 pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
526 pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
cristyd09f8802012-02-04 16:44:10 +0000527 pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
cristy100b8d92012-01-08 00:32:49 +0000528 pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
cristy2ed42f62011-10-02 19:49:57 +0000529 return(MagickFalse);
530 }
531 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
532 {
533 PixelChannel
534 channel;
535
cristye2a912b2011-12-05 20:02:07 +0000536 channel=GetPixelChannelMapChannel(image,i);
cristy2ed42f62011-10-02 19:49:57 +0000537 pixel[channel]=p[i];
538 }
cristy3ed852e2009-09-05 21:47:34 +0000539 return(MagickTrue);
540}
541
542/*
543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544% %
545% %
546% %
547+ G e t S t r e a m I n f o C l i e n t D a t a %
548% %
549% %
550% %
551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
552%
553% GetStreamInfoClientData() gets the stream info client data.
554%
cristy7832dc22011-09-05 01:21:53 +0000555% The format of the GetStreamInfoClientData method is:
cristy3ed852e2009-09-05 21:47:34 +0000556%
557% const void *GetStreamInfoClientData(StreamInfo *stream_info)
558%
559% A description of each parameter follows:
560%
561% o stream_info: the stream info.
562%
563*/
cristy7832dc22011-09-05 01:21:53 +0000564MagickPrivate const void *GetStreamInfoClientData(StreamInfo *stream_info)
cristy3ed852e2009-09-05 21:47:34 +0000565{
566 assert(stream_info != (StreamInfo *) NULL);
567 assert(stream_info->signature == MagickSignature);
568 return(stream_info->client_data);
569}
570
571/*
572%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
573% %
574% %
575% %
576+ 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 %
577% %
578% %
579% %
580%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581%
582% GetVirtualPixelsStream() returns the pixels associated with the last
583% call to QueueAuthenticPixelsStream() or GetVirtualPixelStream().
584%
585% The format of the GetVirtualPixelsStream() method is:
586%
cristy4c08aed2011-07-01 19:47:50 +0000587% const Quantum *GetVirtualPixelsStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000588%
589% A description of each parameter follows:
590%
cristy4c08aed2011-07-01 19:47:50 +0000591% o pixels: return the pixels associated corresponding with the last call to
cristy3ed852e2009-09-05 21:47:34 +0000592% QueueAuthenticPixelsStream() or GetVirtualPixelStream().
593%
594% o image: the image.
595%
596*/
cristy4c08aed2011-07-01 19:47:50 +0000597static const Quantum *GetVirtualPixelsStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000598{
599 CacheInfo
600 *cache_info;
601
602 assert(image != (Image *) NULL);
603 assert(image->signature == MagickSignature);
604 if (image->debug != MagickFalse)
605 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
606 cache_info=(CacheInfo *) image->cache;
607 assert(cache_info->signature == MagickSignature);
608 return(cache_info->pixels);
609}
610
611/*
612%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
613% %
614% %
615% %
616+ 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 %
617% %
618% %
619% %
620%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
621%
cristy20cc0872012-08-20 00:01:19 +0000622% GetVirtualMetacontentFromStream() returns the associated pixel channels
623% corresponding with the last call to QueueAuthenticPixelsStream() or
cristy4c08aed2011-07-01 19:47:50 +0000624% GetVirtualPixelStream().
cristy3ed852e2009-09-05 21:47:34 +0000625%
cristy4c08aed2011-07-01 19:47:50 +0000626% The format of the GetVirtualMetacontentFromStream() method is:
cristy3ed852e2009-09-05 21:47:34 +0000627%
cristy4c08aed2011-07-01 19:47:50 +0000628% const void *GetVirtualMetacontentFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000629%
630% A description of each parameter follows:
631%
632% o image: the image.
633%
634*/
cristy20cc0872012-08-20 00:01:19 +0000635static const void *GetVirtualMetacontentFromStream(const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000636{
637 CacheInfo
638 *cache_info;
639
640 assert(image != (Image *) NULL);
641 assert(image->signature == MagickSignature);
642 if (image->debug != MagickFalse)
643 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
644 cache_info=(CacheInfo *) image->cache;
645 assert(cache_info->signature == MagickSignature);
cristy4c08aed2011-07-01 19:47:50 +0000646 return(cache_info->metacontent);
cristy3ed852e2009-09-05 21:47:34 +0000647}
648
649/*
650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
651% %
652% %
653% %
654+ G e t V i r t u a l P i x e l S t r e a m %
655% %
656% %
657% %
658%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659%
660% GetVirtualPixelStream() gets pixels from the in-memory or disk pixel cache as
661% defined by the geometry parameters. A pointer to the pixels is returned if
662% the pixels are transferred, otherwise a NULL is returned. For streams this
663% method is a no-op.
664%
665% The format of the GetVirtualPixelStream() method is:
666%
cristy4c08aed2011-07-01 19:47:50 +0000667% const Quantum *GetVirtualPixelStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000668% const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
669% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000670% ExceptionInfo *exception)
671%
672% A description of each parameter follows:
673%
674% o image: the image.
675%
676% o virtual_pixel_method: the virtual pixel method.
677%
678% o x,y,columns,rows: These values define the perimeter of a region of
679% pixels.
680%
681% o exception: return any errors or warnings in this structure.
682%
683*/
684
685static inline MagickBooleanType AcquireStreamPixels(CacheInfo *cache_info,
686 ExceptionInfo *exception)
687{
688 if (cache_info->length != (MagickSizeType) ((size_t) cache_info->length))
689 return(MagickFalse);
690 cache_info->mapped=MagickFalse;
cristy39c2e212012-08-18 18:14:34 +0000691 cache_info->pixels=(Quantum *) AcquireAlignedMemory(1,(size_t)
cristy3ed852e2009-09-05 21:47:34 +0000692 cache_info->length);
cristy4c08aed2011-07-01 19:47:50 +0000693 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000694 {
695 cache_info->mapped=MagickTrue;
cristy4c08aed2011-07-01 19:47:50 +0000696 cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
cristy3ed852e2009-09-05 21:47:34 +0000697 cache_info->length);
698 }
cristy4c08aed2011-07-01 19:47:50 +0000699 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000700 {
701 (void) ThrowMagickException(exception,GetMagickModule(),
cristy20cc0872012-08-20 00:01:19 +0000702 ResourceLimitError,"MemoryAllocationFailed","'%s'",
cristy3ed852e2009-09-05 21:47:34 +0000703 cache_info->filename);
704 return(MagickFalse);
705 }
706 return(MagickTrue);
707}
708
cristy4c08aed2011-07-01 19:47:50 +0000709static const Quantum *GetVirtualPixelStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000710 const VirtualPixelMethod magick_unused(virtual_pixel_method),const ssize_t x,
711 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000712 ExceptionInfo *exception)
713{
714 CacheInfo
715 *cache_info;
716
717 MagickBooleanType
718 status;
719
720 MagickSizeType
721 number_pixels;
722
723 size_t
724 length;
725
726 /*
727 Validate pixel cache geometry.
728 */
729 assert(image != (const Image *) NULL);
730 assert(image->signature == MagickSignature);
731 if (image->debug != MagickFalse)
732 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy5dd71882010-08-01 20:53:13 +0000733 if ((x < 0) || (y < 0) ||
734 ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
735 ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
736 (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000737 {
738 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +0000739 "ImageDoesNotContainTheStreamGeometry","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000740 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000741 }
742 cache_info=(CacheInfo *) image->cache;
743 assert(cache_info->signature == MagickSignature);
744 /*
745 Pixels are stored in a temporary buffer until they are synced to the cache.
746 */
747 number_pixels=(MagickSizeType) columns*rows;
cristyed231572011-07-14 02:18:59 +0000748 length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
cristya13b07a2012-08-21 17:01:05 +0000749 if (cache_info->number_channels == 0)
750 length=number_pixels*sizeof(Quantum);
cristy4c08aed2011-07-01 19:47:50 +0000751 if (cache_info->metacontent_extent != 0)
752 length+=number_pixels*cache_info->metacontent_extent;
753 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000754 {
755 cache_info->length=length;
756 status=AcquireStreamPixels(cache_info,exception);
757 if (status == MagickFalse)
cristy33503f52010-10-04 17:32:27 +0000758 {
759 cache_info->length=0;
cristy4c08aed2011-07-01 19:47:50 +0000760 return((Quantum *) NULL);
cristy33503f52010-10-04 17:32:27 +0000761 }
cristy3ed852e2009-09-05 21:47:34 +0000762 }
763 else
764 if (cache_info->length != length)
765 {
766 RelinquishStreamPixels(cache_info);
767 cache_info->length=length;
768 status=AcquireStreamPixels(cache_info,exception);
769 if (status == MagickFalse)
cristy33503f52010-10-04 17:32:27 +0000770 {
771 cache_info->length=0;
cristy4c08aed2011-07-01 19:47:50 +0000772 return((Quantum *) NULL);
cristy33503f52010-10-04 17:32:27 +0000773 }
cristy3ed852e2009-09-05 21:47:34 +0000774 }
cristy4c08aed2011-07-01 19:47:50 +0000775 cache_info->metacontent=(void *) NULL;
776 if (cache_info->metacontent_extent != 0)
777 cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
cristyed231572011-07-14 02:18:59 +0000778 cache_info->number_channels);
cristy3ed852e2009-09-05 21:47:34 +0000779 return(cache_info->pixels);
780}
781
782/*
783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784% %
785% %
786% %
787+ O p e n S t r e a m %
788% %
789% %
790% %
791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792%
793% OpenStream() opens a stream for writing by the StreamImage() method.
794%
795% The format of the OpenStream method is:
796%
797% MagickBooleanType OpenStream(const ImageInfo *image_info,
798% StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
799%
800% A description of each parameter follows:
801%
802% o image_info: the image info.
803%
804% o stream_info: the stream info.
805%
806% o filename: the stream filename.
807%
808% o exception: return any errors or warnings in this structure.
809%
810*/
811MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
812 StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
813{
814 MagickBooleanType
815 status;
816
817 (void) CopyMagickString(stream_info->stream->filename,filename,MaxTextExtent);
818 status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
819 return(status);
820}
821
822/*
823%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824% %
825% %
826% %
827+ Q u e u e A u t h e n t i c P i x e l s S t r e a m %
828% %
829% %
830% %
831%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832%
833% QueueAuthenticPixelsStream() allocates an area to store image pixels as
834% defined by the region rectangle and returns a pointer to the area. This
835% area is subsequently transferred from the pixel cache with method
836% SyncAuthenticPixelsStream(). A pointer to the pixels is returned if the
837% pixels are transferred, otherwise a NULL is returned.
838%
839% The format of the QueueAuthenticPixelsStream() method is:
840%
cristy4c08aed2011-07-01 19:47:50 +0000841% Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000842% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000843% ExceptionInfo *exception)
844%
845% A description of each parameter follows:
846%
847% o image: the image.
848%
849% o x,y,columns,rows: These values define the perimeter of a region of
850% pixels.
851%
852*/
cristy4c08aed2011-07-01 19:47:50 +0000853static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000854 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000855 ExceptionInfo *exception)
856{
857 CacheInfo
858 *cache_info;
859
cristy20cc0872012-08-20 00:01:19 +0000860 MagickBooleanType
861 status;
862
cristy3ed852e2009-09-05 21:47:34 +0000863 MagickSizeType
864 number_pixels;
865
866 size_t
867 length;
868
869 StreamHandler
870 stream_handler;
871
872 /*
873 Validate pixel cache geometry.
874 */
875 assert(image != (Image *) NULL);
cristycfae90a2010-10-04 14:43:33 +0000876 if ((x < 0) || (y < 0) ||
877 ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
878 ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
879 (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000880 {
881 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +0000882 "ImageDoesNotContainTheStreamGeometry","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000883 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000884 }
885 stream_handler=GetBlobStreamHandler(image);
886 if (stream_handler == (StreamHandler) NULL)
887 {
888 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +0000889 "NoStreamHandlerIsDefined","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000890 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000891 }
892 cache_info=(CacheInfo *) image->cache;
893 assert(cache_info->signature == MagickSignature);
894 if ((image->storage_class != GetPixelCacheStorageClass(image->cache)) ||
895 (image->colorspace != GetPixelCacheColorspace(image->cache)))
896 {
897 if (GetPixelCacheStorageClass(image->cache) == UndefinedClass)
898 (void) stream_handler(image,(const void *) NULL,(size_t)
899 cache_info->columns);
900 cache_info->storage_class=image->storage_class;
901 cache_info->colorspace=image->colorspace;
902 cache_info->columns=image->columns;
903 cache_info->rows=image->rows;
904 image->cache=cache_info;
905 }
906 /*
907 Pixels are stored in a temporary buffer until they are synced to the cache.
908 */
909 cache_info->columns=columns;
910 cache_info->rows=rows;
911 number_pixels=(MagickSizeType) columns*rows;
cristyed231572011-07-14 02:18:59 +0000912 length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
cristyd62370b2012-08-20 00:22:14 +0000913 if (cache_info->number_channels == 0)
cristy20cc0872012-08-20 00:01:19 +0000914 length=number_pixels*sizeof(Quantum);
cristy4c08aed2011-07-01 19:47:50 +0000915 if (cache_info->metacontent_extent != 0)
916 length+=number_pixels*cache_info->metacontent_extent;
917 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000918 {
cristy20cc0872012-08-20 00:01:19 +0000919 cache_info->length=length;
920 status=AcquireStreamPixels(cache_info,exception);
921 if (status == MagickFalse)
922 {
923 cache_info->length=0;
924 return((Quantum *) NULL);
925 }
cristy3ed852e2009-09-05 21:47:34 +0000926 }
927 else
cristy20cc0872012-08-20 00:01:19 +0000928 if (cache_info->length < length)
cristy3ed852e2009-09-05 21:47:34 +0000929 {
cristy20cc0872012-08-20 00:01:19 +0000930 RelinquishStreamPixels(cache_info);
931 cache_info->length=length;
932 status=AcquireStreamPixels(cache_info,exception);
933 if (status == MagickFalse)
934 {
935 cache_info->length=0;
936 return((Quantum *) NULL);
937 }
cristy3ed852e2009-09-05 21:47:34 +0000938 }
cristy4c08aed2011-07-01 19:47:50 +0000939 cache_info->metacontent=(void *) NULL;
940 if (cache_info->metacontent_extent != 0)
941 cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
cristyed231572011-07-14 02:18:59 +0000942 cache_info->number_channels);
cristy3ed852e2009-09-05 21:47:34 +0000943 return(cache_info->pixels);
944}
945
946/*
947%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948% %
949% %
950% %
951% R e a d S t r e a m %
952% %
953% %
954% %
955%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956%
957% ReadStream() makes the image pixels available to a user supplied callback
958% method immediately upon reading a scanline with the ReadImage() method.
959%
960% The format of the ReadStream() method is:
961%
962% Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
963% ExceptionInfo *exception)
964%
965% A description of each parameter follows:
966%
967% o image_info: the image info.
968%
969% o stream: a callback method.
970%
971% o exception: return any errors or warnings in this structure.
972%
973*/
974MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
975 ExceptionInfo *exception)
976{
977 CacheMethods
978 cache_methods;
979
980 Image
981 *image;
982
983 ImageInfo
984 *read_info;
985
986 /*
987 Stream image pixels.
988 */
989 assert(image_info != (ImageInfo *) NULL);
990 assert(image_info->signature == MagickSignature);
991 if (image_info->debug != MagickFalse)
992 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
993 image_info->filename);
994 assert(exception != (ExceptionInfo *) NULL);
995 assert(exception->signature == MagickSignature);
996 read_info=CloneImageInfo(image_info);
997 read_info->cache=AcquirePixelCache(0);
998 GetPixelCacheMethods(&cache_methods);
999 cache_methods.get_virtual_pixel_handler=GetVirtualPixelStream;
cristy4c08aed2011-07-01 19:47:50 +00001000 cache_methods.get_virtual_metacontent_from_handler=
1001 GetVirtualMetacontentFromStream;
cristy3ed852e2009-09-05 21:47:34 +00001002 cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
1003 cache_methods.get_authentic_pixels_handler=GetAuthenticPixelsStream;
1004 cache_methods.queue_authentic_pixels_handler=QueueAuthenticPixelsStream;
1005 cache_methods.sync_authentic_pixels_handler=SyncAuthenticPixelsStream;
1006 cache_methods.get_authentic_pixels_from_handler=GetAuthenticPixelsFromStream;
cristy4c08aed2011-07-01 19:47:50 +00001007 cache_methods.get_authentic_metacontent_from_handler=
1008 GetAuthenticMetacontentFromStream;
cristy3ed852e2009-09-05 21:47:34 +00001009 cache_methods.get_one_virtual_pixel_from_handler=GetOneVirtualPixelFromStream;
1010 cache_methods.get_one_authentic_pixel_from_handler=
1011 GetOneAuthenticPixelFromStream;
1012 cache_methods.destroy_pixel_handler=DestroyPixelStream;
1013 SetPixelCacheMethods(read_info->cache,&cache_methods);
1014 read_info->stream=stream;
1015 image=ReadImage(read_info,exception);
1016 read_info=DestroyImageInfo(read_info);
1017 return(image);
1018}
1019
1020/*
1021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1022% %
1023% %
1024% %
1025+ S e t S t r e a m I n f o C l i e n t D a t a %
1026% %
1027% %
1028% %
1029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030%
1031% SetStreamInfoClientData() sets the stream info client data.
1032%
1033% The format of the SetStreamInfoClientData method is:
1034%
1035% void SetStreamInfoClientData(StreamInfo *stream_info,
1036% const void *client_data)
1037%
1038% A description of each parameter follows:
1039%
1040% o stream_info: the stream info.
1041%
1042% o client_data: the client data.
1043%
1044*/
cristy7832dc22011-09-05 01:21:53 +00001045MagickPrivate void SetStreamInfoClientData(StreamInfo *stream_info,
cristy3ed852e2009-09-05 21:47:34 +00001046 const void *client_data)
1047{
1048 assert(stream_info != (StreamInfo *) NULL);
1049 assert(stream_info->signature == MagickSignature);
1050 stream_info->client_data=client_data;
1051}
1052
1053/*
1054%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1055% %
1056% %
1057% %
1058+ S e t S t r e a m I n f o M a p %
1059% %
1060% %
1061% %
1062%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1063%
1064% SetStreamInfoMap() sets the stream info map member.
1065%
1066% The format of the SetStreamInfoMap method is:
1067%
1068% void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1069%
1070% A description of each parameter follows:
1071%
1072% o stream_info: the stream info.
1073%
1074% o map: the map.
1075%
1076*/
1077MagickExport void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1078{
1079 assert(stream_info != (StreamInfo *) NULL);
1080 assert(stream_info->signature == MagickSignature);
1081 (void) CloneString(&stream_info->map,map);
1082}
1083
1084/*
1085%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1086% %
1087% %
1088% %
1089+ S e t S t r e a m I n f o S t o r a g e T y p e %
1090% %
1091% %
1092% %
1093%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1094%
1095% SetStreamInfoStorageType() sets the stream info storage type member.
1096%
1097% The format of the SetStreamInfoStorageType method is:
1098%
1099% void SetStreamInfoStorageType(StreamInfo *stream_info,
1100% const StoreageType *storage_type)
1101%
1102% A description of each parameter follows:
1103%
1104% o stream_info: the stream info.
1105%
1106% o storage_type: the storage type.
1107%
1108*/
1109MagickExport void SetStreamInfoStorageType(StreamInfo *stream_info,
1110 const StorageType storage_type)
1111{
1112 assert(stream_info != (StreamInfo *) NULL);
1113 assert(stream_info->signature == MagickSignature);
1114 stream_info->storage_type=storage_type;
1115}
1116
1117/*
1118%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1119% %
1120% %
1121% %
1122+ S t r e a m I m a g e %
1123% %
1124% %
1125% %
1126%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1127%
1128% StreamImage() streams pixels from an image and writes them in a user
1129% defined format and storage type (e.g. RGBA as 8-bit unsigned char).
1130%
cristyd212bd02011-02-13 17:08:57 +00001131% The format of the StreamImage() method is:
cristy3ed852e2009-09-05 21:47:34 +00001132%
1133% Image *StreamImage(const ImageInfo *image_info,
1134% StreamInfo *stream_info,ExceptionInfo *exception)
1135%
1136% A description of each parameter follows:
1137%
1138% o image_info: the image info.
1139%
1140% o stream_info: the stream info.
1141%
1142% o exception: return any errors or warnings in this structure.
1143%
1144*/
1145
1146#if defined(__cplusplus) || defined(c_plusplus)
1147extern "C" {
1148#endif
1149
1150static size_t WriteStreamImage(const Image *image,const void *pixels,
1151 const size_t columns)
1152{
cristye3664f42010-05-14 00:59:57 +00001153 CacheInfo
1154 *cache_info;
1155
cristy3ed852e2009-09-05 21:47:34 +00001156 RectangleInfo
1157 extract_info;
1158
1159 size_t
1160 length,
1161 packet_size;
1162
1163 ssize_t
1164 count;
1165
1166 StreamInfo
1167 *stream_info;
1168
cristy654fdaf2011-02-24 15:24:33 +00001169 (void) pixels;
cristy3ed852e2009-09-05 21:47:34 +00001170 stream_info=(StreamInfo *) image->client_data;
1171 switch (stream_info->storage_type)
1172 {
cristy100b8d92012-01-08 00:32:49 +00001173 default: packet_size=sizeof(unsigned char); break;
1174 case CharPixel: packet_size=sizeof(unsigned char); break;
cristy3ed852e2009-09-05 21:47:34 +00001175 case DoublePixel: packet_size=sizeof(double); break;
1176 case FloatPixel: packet_size=sizeof(float); break;
cristy100b8d92012-01-08 00:32:49 +00001177 case LongPixel: packet_size=sizeof(unsigned int); break;
1178 case LongLongPixel: packet_size=sizeof(MagickSizeType); break;
cristy3ed852e2009-09-05 21:47:34 +00001179 case QuantumPixel: packet_size=sizeof(Quantum); break;
1180 case ShortPixel: packet_size=sizeof(unsigned short); break;
1181 }
cristye3664f42010-05-14 00:59:57 +00001182 cache_info=(CacheInfo *) image->cache;
1183 assert(cache_info->signature == MagickSignature);
cristy3ed852e2009-09-05 21:47:34 +00001184 packet_size*=strlen(stream_info->map);
cristye3664f42010-05-14 00:59:57 +00001185 length=packet_size*cache_info->columns*cache_info->rows;
cristy3ed852e2009-09-05 21:47:34 +00001186 if (image != stream_info->image)
1187 {
1188 ImageInfo
1189 *write_info;
1190
1191 /*
1192 Prepare stream for writing.
1193 */
cristy39c2e212012-08-18 18:14:34 +00001194 (void) RelinquishAlignedMemory(stream_info->pixels);
cristy20cc0872012-08-20 00:01:19 +00001195 stream_info->pixels=(unsigned char *) AcquireAlignedMemory(1,length);
cristy5dd71882010-08-01 20:53:13 +00001196 if (stream_info->pixels == (unsigned char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001197 return(0);
cristy39c2e212012-08-18 18:14:34 +00001198 (void) ResetMagickMemory(stream_info->pixels,0,length);
cristy3ed852e2009-09-05 21:47:34 +00001199 stream_info->image=image;
1200 write_info=CloneImageInfo(stream_info->image_info);
cristyd965a422010-03-03 17:47:35 +00001201 (void) SetImageInfo(write_info,1,stream_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001202 if (write_info->extract != (char *) NULL)
1203 (void) ParseAbsoluteGeometry(write_info->extract,
1204 &stream_info->extract_info);
1205 stream_info->y=0;
1206 write_info=DestroyImageInfo(write_info);
1207 }
1208 extract_info=stream_info->extract_info;
cristyd212bd02011-02-13 17:08:57 +00001209 if ((extract_info.width == 0) || (extract_info.height == 0))
cristy3ed852e2009-09-05 21:47:34 +00001210 {
1211 /*
1212 Write all pixels to stream.
1213 */
1214 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1215 count=WriteBlob(stream_info->stream,length,stream_info->pixels);
1216 stream_info->y++;
1217 return(count == 0 ? 0 : columns);
1218 }
1219 if ((stream_info->y < extract_info.y) ||
cristybb503372010-05-27 20:51:26 +00001220 (stream_info->y >= (ssize_t) (extract_info.y+extract_info.height)))
cristy3ed852e2009-09-05 21:47:34 +00001221 {
1222 stream_info->y++;
1223 return(columns);
1224 }
1225 /*
1226 Write a portion of the pixel row to the stream.
1227 */
1228 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1229 length=packet_size*extract_info.width;
cristy5dd71882010-08-01 20:53:13 +00001230 count=WriteBlob(stream_info->stream,length,stream_info->pixels+packet_size*
1231 extract_info.x);
cristy3ed852e2009-09-05 21:47:34 +00001232 stream_info->y++;
1233 return(count == 0 ? 0 : columns);
1234}
1235
1236#if defined(__cplusplus) || defined(c_plusplus)
1237}
1238#endif
1239
1240MagickExport Image *StreamImage(const ImageInfo *image_info,
1241 StreamInfo *stream_info,ExceptionInfo *exception)
1242{
1243 Image
1244 *image;
1245
1246 ImageInfo
1247 *read_info;
1248
1249 assert(image_info != (const ImageInfo *) NULL);
1250 assert(image_info->signature == MagickSignature);
1251 if (image_info->debug != MagickFalse)
1252 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1253 image_info->filename);
1254 assert(stream_info != (StreamInfo *) NULL);
1255 assert(stream_info->signature == MagickSignature);
1256 assert(exception != (ExceptionInfo *) NULL);
1257 read_info=CloneImageInfo(image_info);
1258 stream_info->image_info=image_info;
1259 stream_info->exception=exception;
1260 read_info->client_data=(void *) stream_info;
1261 image=ReadStream(read_info,&WriteStreamImage,exception);
1262 read_info=DestroyImageInfo(read_info);
1263 stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
1264 if (stream_info->quantum_info == (QuantumInfo *) NULL)
1265 image=DestroyImage(image);
1266 return(image);
1267}
1268
1269/*
1270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1271% %
1272% %
1273% %
1274+ S t r e a m I m a g e P i x e l s %
1275% %
1276% %
1277% %
1278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1279%
1280% StreamImagePixels() extracts pixel data from an image and returns it in the
1281% stream_info->pixels structure in the format as defined by
1282% stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
1283%
1284% The format of the StreamImagePixels method is:
1285%
1286% MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1287% const Image *image,ExceptionInfo *exception)
1288%
1289% A description of each parameter follows:
1290%
1291% o stream_info: the stream info.
1292%
1293% o image: the image.
1294%
1295% o exception: return any errors or warnings in this structure.
1296%
1297*/
1298static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1299 const Image *image,ExceptionInfo *exception)
1300{
1301 QuantumInfo
1302 *quantum_info;
1303
1304 QuantumType
1305 *quantum_map;
1306
cristy4c08aed2011-07-01 19:47:50 +00001307 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +00001308 *p;
1309
cristyd212bd02011-02-13 17:08:57 +00001310 register ssize_t
1311 i,
1312 x;
1313
cristy3ed852e2009-09-05 21:47:34 +00001314 size_t
1315 length;
1316
1317 assert(stream_info != (StreamInfo *) NULL);
1318 assert(stream_info->signature == MagickSignature);
1319 assert(image != (Image *) NULL);
1320 assert(image->signature == MagickSignature);
1321 if (image->debug != MagickFalse)
1322 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1323 length=strlen(stream_info->map);
1324 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1325 if (quantum_map == (QuantumType *) NULL)
1326 {
1327 (void) ThrowMagickException(exception,GetMagickModule(),
cristy20cc0872012-08-20 00:01:19 +00001328 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +00001329 return(MagickFalse);
1330 }
cristybb503372010-05-27 20:51:26 +00001331 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001332 {
1333 switch (stream_info->map[i])
1334 {
1335 case 'A':
1336 case 'a':
1337 {
1338 quantum_map[i]=AlphaQuantum;
1339 break;
1340 }
1341 case 'B':
1342 case 'b':
1343 {
1344 quantum_map[i]=BlueQuantum;
1345 break;
1346 }
1347 case 'C':
1348 case 'c':
1349 {
1350 quantum_map[i]=CyanQuantum;
1351 if (image->colorspace == CMYKColorspace)
1352 break;
1353 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1354 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001355 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001356 return(MagickFalse);
1357 }
1358 case 'g':
1359 case 'G':
1360 {
1361 quantum_map[i]=GreenQuantum;
1362 break;
1363 }
1364 case 'I':
1365 case 'i':
1366 {
1367 quantum_map[i]=IndexQuantum;
1368 break;
1369 }
1370 case 'K':
1371 case 'k':
1372 {
1373 quantum_map[i]=BlackQuantum;
1374 if (image->colorspace == CMYKColorspace)
1375 break;
1376 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1377 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001378 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001379 return(MagickFalse);
1380 }
1381 case 'M':
1382 case 'm':
1383 {
1384 quantum_map[i]=MagentaQuantum;
1385 if (image->colorspace == CMYKColorspace)
1386 break;
1387 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1388 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001389 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001390 return(MagickFalse);
1391 }
1392 case 'o':
1393 case 'O':
1394 {
1395 quantum_map[i]=OpacityQuantum;
1396 break;
1397 }
1398 case 'P':
1399 case 'p':
1400 {
1401 quantum_map[i]=UndefinedQuantum;
1402 break;
1403 }
1404 case 'R':
1405 case 'r':
1406 {
1407 quantum_map[i]=RedQuantum;
1408 break;
1409 }
1410 case 'Y':
1411 case 'y':
1412 {
1413 quantum_map[i]=YellowQuantum;
1414 if (image->colorspace == CMYKColorspace)
1415 break;
1416 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1417 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001418 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001419 return(MagickFalse);
1420 }
1421 default:
1422 {
1423 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1424 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristy20cc0872012-08-20 00:01:19 +00001425 "UnrecognizedPixelMap","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001426 return(MagickFalse);
1427 }
1428 }
1429 }
1430 quantum_info=stream_info->quantum_info;
1431 switch (stream_info->storage_type)
1432 {
1433 case CharPixel:
1434 {
1435 register unsigned char
1436 *q;
1437
1438 q=(unsigned char *) stream_info->pixels;
1439 if (LocaleCompare(stream_info->map,"BGR") == 0)
1440 {
cristy100b8d92012-01-08 00:32:49 +00001441 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001442 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001443 break;
cristybb503372010-05-27 20:51:26 +00001444 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001445 {
cristy4c08aed2011-07-01 19:47:50 +00001446 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1447 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1448 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001449 p++;
1450 }
1451 break;
1452 }
1453 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1454 {
cristy100b8d92012-01-08 00:32:49 +00001455 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001456 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001457 break;
cristybb503372010-05-27 20:51:26 +00001458 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001459 {
cristy4c08aed2011-07-01 19:47:50 +00001460 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1461 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1462 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1463 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001464 p++;
1465 }
1466 break;
1467 }
1468 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1469 {
cristy100b8d92012-01-08 00:32:49 +00001470 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001471 if (p == (const Quantum *) NULL)
cristy100b8d92012-01-08 00:32:49 +00001472 break;
cristybb503372010-05-27 20:51:26 +00001473 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001474 {
cristy4c08aed2011-07-01 19:47:50 +00001475 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1476 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1477 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001478 *q++=ScaleQuantumToChar((Quantum) 0);
1479 p++;
1480 }
1481 break;
1482 }
1483 if (LocaleCompare(stream_info->map,"I") == 0)
1484 {
cristy100b8d92012-01-08 00:32:49 +00001485 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001486 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001487 break;
cristybb503372010-05-27 20:51:26 +00001488 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001489 {
cristyf13c5942012-08-08 23:50:11 +00001490 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001491 p++;
1492 }
1493 break;
1494 }
1495 if (LocaleCompare(stream_info->map,"RGB") == 0)
1496 {
cristy100b8d92012-01-08 00:32:49 +00001497 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001498 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001499 break;
cristybb503372010-05-27 20:51:26 +00001500 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001501 {
cristy4c08aed2011-07-01 19:47:50 +00001502 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1503 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1504 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001505 p++;
1506 }
1507 break;
1508 }
1509 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1510 {
cristy100b8d92012-01-08 00:32:49 +00001511 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001512 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001513 break;
cristybb503372010-05-27 20:51:26 +00001514 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001515 {
cristy4c08aed2011-07-01 19:47:50 +00001516 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1517 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1518 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1519 *q++=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001520 p++;
1521 }
1522 break;
1523 }
1524 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1525 {
cristy100b8d92012-01-08 00:32:49 +00001526 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001527 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001528 break;
cristybb503372010-05-27 20:51:26 +00001529 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001530 {
cristy4c08aed2011-07-01 19:47:50 +00001531 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1532 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1533 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001534 *q++=ScaleQuantumToChar((Quantum) 0);
1535 p++;
1536 }
1537 break;
1538 }
cristy100b8d92012-01-08 00:32:49 +00001539 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001540 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001541 break;
cristybb503372010-05-27 20:51:26 +00001542 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001543 {
cristybb503372010-05-27 20:51:26 +00001544 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001545 {
1546 *q=0;
1547 switch (quantum_map[i])
1548 {
1549 case RedQuantum:
1550 case CyanQuantum:
1551 {
cristy4c08aed2011-07-01 19:47:50 +00001552 *q=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001553 break;
1554 }
1555 case GreenQuantum:
1556 case MagentaQuantum:
1557 {
cristy4c08aed2011-07-01 19:47:50 +00001558 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001559 break;
1560 }
1561 case BlueQuantum:
1562 case YellowQuantum:
1563 {
cristy4c08aed2011-07-01 19:47:50 +00001564 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001565 break;
1566 }
1567 case AlphaQuantum:
1568 {
cristy4c08aed2011-07-01 19:47:50 +00001569 *q=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001570 break;
1571 }
1572 case OpacityQuantum:
1573 {
cristy4c08aed2011-07-01 19:47:50 +00001574 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001575 break;
1576 }
1577 case BlackQuantum:
1578 {
1579 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001580 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001581 break;
1582 }
1583 case IndexQuantum:
1584 {
cristyf13c5942012-08-08 23:50:11 +00001585 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001586 break;
1587 }
1588 default:
1589 break;
1590 }
1591 q++;
1592 }
1593 p++;
1594 }
1595 break;
1596 }
1597 case DoublePixel:
1598 {
1599 register double
1600 *q;
1601
1602 q=(double *) stream_info->pixels;
1603 if (LocaleCompare(stream_info->map,"BGR") == 0)
1604 {
cristy100b8d92012-01-08 00:32:49 +00001605 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001606 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001607 break;
cristybb503372010-05-27 20:51:26 +00001608 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001609 {
cristy4c08aed2011-07-01 19:47:50 +00001610 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001611 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001612 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001613 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001614 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001615 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001616 p++;
1617 }
1618 break;
1619 }
1620 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1621 {
cristy100b8d92012-01-08 00:32:49 +00001622 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001623 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001624 break;
cristybb503372010-05-27 20:51:26 +00001625 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001626 {
cristy4c08aed2011-07-01 19:47:50 +00001627 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001628 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001629 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001630 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001631 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001632 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001633 *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001634 quantum_info->scale+quantum_info->minimum);
1635 p++;
1636 }
1637 break;
1638 }
1639 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1640 {
cristy100b8d92012-01-08 00:32:49 +00001641 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001642 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001643 break;
cristybb503372010-05-27 20:51:26 +00001644 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001645 {
cristy4c08aed2011-07-01 19:47:50 +00001646 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001647 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001648 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001649 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001650 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001651 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001652 *q++=0.0;
1653 p++;
1654 }
1655 break;
1656 }
1657 if (LocaleCompare(stream_info->map,"I") == 0)
1658 {
cristy100b8d92012-01-08 00:32:49 +00001659 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001660 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001661 break;
cristybb503372010-05-27 20:51:26 +00001662 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001663 {
cristy4c08aed2011-07-01 19:47:50 +00001664 *q++=(double) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001665 quantum_info->scale+quantum_info->minimum);
1666 p++;
1667 }
1668 break;
1669 }
1670 if (LocaleCompare(stream_info->map,"RGB") == 0)
1671 {
cristy100b8d92012-01-08 00:32:49 +00001672 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001673 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001674 break;
cristybb503372010-05-27 20:51:26 +00001675 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001676 {
cristy4c08aed2011-07-01 19:47:50 +00001677 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001678 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001679 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001680 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001681 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001682 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001683 p++;
1684 }
1685 break;
1686 }
1687 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1688 {
cristy100b8d92012-01-08 00:32:49 +00001689 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001690 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001691 break;
cristybb503372010-05-27 20:51:26 +00001692 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001693 {
cristy4c08aed2011-07-01 19:47:50 +00001694 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001695 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001696 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001697 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001698 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001699 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001700 *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001701 quantum_info->scale+quantum_info->minimum);
1702 p++;
1703 }
1704 break;
1705 }
1706 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1707 {
cristy100b8d92012-01-08 00:32:49 +00001708 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001709 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001710 break;
cristybb503372010-05-27 20:51:26 +00001711 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001712 {
cristy4c08aed2011-07-01 19:47:50 +00001713 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001714 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001715 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001716 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001717 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001718 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001719 *q++=0.0;
1720 p++;
1721 }
1722 break;
1723 }
cristy100b8d92012-01-08 00:32:49 +00001724 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001725 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001726 break;
cristybb503372010-05-27 20:51:26 +00001727 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001728 {
cristybb503372010-05-27 20:51:26 +00001729 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001730 {
1731 *q=0;
1732 switch (quantum_map[i])
1733 {
1734 case RedQuantum:
1735 case CyanQuantum:
1736 {
cristy4c08aed2011-07-01 19:47:50 +00001737 *q=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001738 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001739 break;
1740 }
1741 case GreenQuantum:
1742 case MagentaQuantum:
1743 {
cristy4c08aed2011-07-01 19:47:50 +00001744 *q=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001745 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001746 break;
1747 }
1748 case BlueQuantum:
1749 case YellowQuantum:
1750 {
cristy4c08aed2011-07-01 19:47:50 +00001751 *q=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001752 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001753 break;
1754 }
1755 case AlphaQuantum:
1756 {
cristy4c08aed2011-07-01 19:47:50 +00001757 *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001758 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001759 break;
1760 }
1761 case OpacityQuantum:
1762 {
cristy4c08aed2011-07-01 19:47:50 +00001763 *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001764 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001765 break;
1766 }
1767 case BlackQuantum:
1768 {
1769 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001770 *q=(double) ((QuantumScale*GetPixelBlack(image,p))*
cristyfba5a8b2011-05-03 17:12:12 +00001771 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001772 break;
1773 }
1774 case IndexQuantum:
1775 {
cristy4c08aed2011-07-01 19:47:50 +00001776 *q=(double) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001777 quantum_info->scale+quantum_info->minimum);
1778 break;
1779 }
1780 default:
1781 *q=0;
1782 }
1783 q++;
1784 }
1785 p++;
1786 }
1787 break;
1788 }
1789 case FloatPixel:
1790 {
1791 register float
1792 *q;
1793
1794 q=(float *) stream_info->pixels;
1795 if (LocaleCompare(stream_info->map,"BGR") == 0)
1796 {
cristy100b8d92012-01-08 00:32:49 +00001797 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001798 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001799 break;
cristybb503372010-05-27 20:51:26 +00001800 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001801 {
cristy4c08aed2011-07-01 19:47:50 +00001802 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001803 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001804 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001805 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001806 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001807 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001808 p++;
1809 }
1810 break;
1811 }
1812 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1813 {
cristy100b8d92012-01-08 00:32:49 +00001814 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001815 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001816 break;
cristybb503372010-05-27 20:51:26 +00001817 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001818 {
cristy4c08aed2011-07-01 19:47:50 +00001819 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001820 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001821 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001822 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001823 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001824 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001825 *q++=(float) ((QuantumScale*(Quantum) (GetPixelAlpha(image,p)))*
cristy3ed852e2009-09-05 21:47:34 +00001826 quantum_info->scale+quantum_info->minimum);
1827 p++;
1828 }
1829 break;
1830 }
1831 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1832 {
cristy100b8d92012-01-08 00:32:49 +00001833 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001834 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001835 break;
cristybb503372010-05-27 20:51:26 +00001836 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001837 {
cristy4c08aed2011-07-01 19:47:50 +00001838 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001839 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001840 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001841 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001842 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001843 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001844 *q++=0.0;
1845 p++;
1846 }
1847 break;
1848 }
1849 if (LocaleCompare(stream_info->map,"I") == 0)
1850 {
cristy100b8d92012-01-08 00:32:49 +00001851 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001852 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001853 break;
cristybb503372010-05-27 20:51:26 +00001854 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001855 {
cristy4c08aed2011-07-01 19:47:50 +00001856 *q++=(float) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001857 quantum_info->scale+quantum_info->minimum);
1858 p++;
1859 }
1860 break;
1861 }
1862 if (LocaleCompare(stream_info->map,"RGB") == 0)
1863 {
cristy100b8d92012-01-08 00:32:49 +00001864 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001865 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001866 break;
cristybb503372010-05-27 20:51:26 +00001867 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001868 {
cristy4c08aed2011-07-01 19:47:50 +00001869 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001870 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001871 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001872 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001873 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001874 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001875 p++;
1876 }
1877 break;
1878 }
1879 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1880 {
cristy100b8d92012-01-08 00:32:49 +00001881 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001882 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001883 break;
cristybb503372010-05-27 20:51:26 +00001884 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001885 {
cristy4c08aed2011-07-01 19:47:50 +00001886 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001887 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001888 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001889 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001890 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001891 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001892 *q++=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001893 quantum_info->scale+quantum_info->minimum);
1894 p++;
1895 }
1896 break;
1897 }
1898 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1899 {
cristy100b8d92012-01-08 00:32:49 +00001900 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001901 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001902 break;
cristybb503372010-05-27 20:51:26 +00001903 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001904 {
cristy4c08aed2011-07-01 19:47:50 +00001905 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001906 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001907 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001908 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001909 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001910 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001911 *q++=0.0;
1912 p++;
1913 }
1914 break;
1915 }
cristy100b8d92012-01-08 00:32:49 +00001916 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001917 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001918 break;
cristybb503372010-05-27 20:51:26 +00001919 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001920 {
cristybb503372010-05-27 20:51:26 +00001921 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001922 {
1923 *q=0;
1924 switch (quantum_map[i])
1925 {
1926 case RedQuantum:
1927 case CyanQuantum:
1928 {
cristy4c08aed2011-07-01 19:47:50 +00001929 *q=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001930 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001931 break;
1932 }
1933 case GreenQuantum:
1934 case MagentaQuantum:
1935 {
cristy4c08aed2011-07-01 19:47:50 +00001936 *q=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001937 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001938 break;
1939 }
1940 case BlueQuantum:
1941 case YellowQuantum:
1942 {
cristy4c08aed2011-07-01 19:47:50 +00001943 *q=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001944 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001945 break;
1946 }
1947 case AlphaQuantum:
1948 {
cristy4c08aed2011-07-01 19:47:50 +00001949 *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001950 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001951 break;
1952 }
1953 case OpacityQuantum:
1954 {
cristy4c08aed2011-07-01 19:47:50 +00001955 *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001956 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001957 break;
1958 }
1959 case BlackQuantum:
1960 {
1961 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001962 *q=(float) ((QuantumScale*GetPixelBlack(image,p))*
cristyfba5a8b2011-05-03 17:12:12 +00001963 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001964 break;
1965 }
1966 case IndexQuantum:
1967 {
cristy4c08aed2011-07-01 19:47:50 +00001968 *q=(float) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001969 quantum_info->scale+quantum_info->minimum);
1970 break;
1971 }
1972 default:
1973 *q=0;
1974 }
1975 q++;
1976 }
1977 p++;
1978 }
1979 break;
1980 }
cristy100b8d92012-01-08 00:32:49 +00001981 case LongPixel:
cristy3ed852e2009-09-05 21:47:34 +00001982 {
1983 register unsigned int
1984 *q;
1985
1986 q=(unsigned int *) stream_info->pixels;
1987 if (LocaleCompare(stream_info->map,"BGR") == 0)
1988 {
cristy100b8d92012-01-08 00:32:49 +00001989 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001990 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001991 break;
cristybb503372010-05-27 20:51:26 +00001992 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001993 {
cristy4c08aed2011-07-01 19:47:50 +00001994 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1995 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1996 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001997 p++;
1998 }
1999 break;
2000 }
2001 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2002 {
cristy100b8d92012-01-08 00:32:49 +00002003 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002004 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002005 break;
cristybb503372010-05-27 20:51:26 +00002006 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002007 {
cristy4c08aed2011-07-01 19:47:50 +00002008 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2009 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2010 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2011 *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002012 p++;
2013 }
2014 break;
2015 }
2016 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2017 {
cristy100b8d92012-01-08 00:32:49 +00002018 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002019 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002020 break;
cristybb503372010-05-27 20:51:26 +00002021 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002022 {
cristy4c08aed2011-07-01 19:47:50 +00002023 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2024 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2025 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002026 *q++=0;
2027 p++;
2028 }
2029 break;
2030 }
2031 if (LocaleCompare(stream_info->map,"I") == 0)
2032 {
cristy100b8d92012-01-08 00:32:49 +00002033 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002034 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002035 break;
cristybb503372010-05-27 20:51:26 +00002036 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002037 {
cristyf13c5942012-08-08 23:50:11 +00002038 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002039 p++;
2040 }
2041 break;
2042 }
2043 if (LocaleCompare(stream_info->map,"RGB") == 0)
2044 {
cristy100b8d92012-01-08 00:32:49 +00002045 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002046 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002047 break;
cristybb503372010-05-27 20:51:26 +00002048 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002049 {
cristy4c08aed2011-07-01 19:47:50 +00002050 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2051 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2052 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002053 p++;
2054 }
2055 break;
2056 }
2057 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2058 {
cristy100b8d92012-01-08 00:32:49 +00002059 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002060 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002061 break;
cristybb503372010-05-27 20:51:26 +00002062 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002063 {
cristy4c08aed2011-07-01 19:47:50 +00002064 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2065 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2066 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2067 *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002068 p++;
2069 }
2070 break;
2071 }
2072 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2073 {
cristy100b8d92012-01-08 00:32:49 +00002074 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002075 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002076 break;
cristybb503372010-05-27 20:51:26 +00002077 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002078 {
cristy4c08aed2011-07-01 19:47:50 +00002079 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2080 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2081 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002082 *q++=0;
2083 p++;
2084 }
2085 break;
2086 }
cristy100b8d92012-01-08 00:32:49 +00002087 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002088 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002089 break;
cristybb503372010-05-27 20:51:26 +00002090 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002091 {
cristybb503372010-05-27 20:51:26 +00002092 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002093 {
2094 *q=0;
2095 switch (quantum_map[i])
2096 {
2097 case RedQuantum:
2098 case CyanQuantum:
2099 {
cristy4c08aed2011-07-01 19:47:50 +00002100 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002101 break;
2102 }
2103 case GreenQuantum:
2104 case MagentaQuantum:
2105 {
cristy4c08aed2011-07-01 19:47:50 +00002106 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002107 break;
2108 }
2109 case BlueQuantum:
2110 case YellowQuantum:
2111 {
cristy4c08aed2011-07-01 19:47:50 +00002112 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002113 break;
2114 }
2115 case AlphaQuantum:
2116 {
cristy4c08aed2011-07-01 19:47:50 +00002117 *q=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002118 break;
2119 }
2120 case OpacityQuantum:
2121 {
cristy4c08aed2011-07-01 19:47:50 +00002122 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002123 break;
2124 }
2125 case BlackQuantum:
2126 {
2127 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002128 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002129 break;
2130 }
2131 case IndexQuantum:
2132 {
cristyf13c5942012-08-08 23:50:11 +00002133 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002134 break;
2135 }
2136 default:
2137 break;
2138 }
2139 q++;
2140 }
2141 p++;
2142 }
2143 break;
2144 }
cristy100b8d92012-01-08 00:32:49 +00002145 case LongLongPixel:
2146 {
2147 register MagickSizeType
2148 *q;
2149
2150 q=(MagickSizeType *) stream_info->pixels;
2151 if (LocaleCompare(stream_info->map,"BGR") == 0)
2152 {
2153 p=GetVirtualPixelQueue(image);
2154 if (p == (const Quantum *) NULL)
2155 break;
2156 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2157 {
2158 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2159 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2160 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2161 p++;
2162 }
2163 break;
2164 }
2165 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2166 {
2167 p=GetVirtualPixelQueue(image);
2168 if (p == (const Quantum *) NULL)
2169 break;
2170 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2171 {
2172 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2173 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2174 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2175 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2176 p++;
2177 }
2178 break;
2179 }
2180 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2181 {
2182 p=GetVirtualPixelQueue(image);
2183 if (p == (const Quantum *) NULL)
2184 break;
2185 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2186 {
2187 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2188 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2189 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2190 *q++=0U;
2191 p++;
2192 }
2193 break;
2194 }
2195 if (LocaleCompare(stream_info->map,"I") == 0)
2196 {
2197 p=GetVirtualPixelQueue(image);
2198 if (p == (const Quantum *) NULL)
2199 break;
2200 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2201 {
cristyf13c5942012-08-08 23:50:11 +00002202 *q++=ScaleQuantumToLongLong(ClampToQuantum(
2203 GetPixelIntensity(image,p)));
cristy100b8d92012-01-08 00:32:49 +00002204 p++;
2205 }
2206 break;
2207 }
2208 if (LocaleCompare(stream_info->map,"RGB") == 0)
2209 {
2210 p=GetVirtualPixelQueue(image);
2211 if (p == (const Quantum *) NULL)
2212 break;
2213 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2214 {
2215 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2216 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2217 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2218 p++;
2219 }
2220 break;
2221 }
2222 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2223 {
2224 p=GetVirtualPixelQueue(image);
2225 if (p == (const Quantum *) NULL)
2226 break;
2227 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2228 {
2229 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2230 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2231 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2232 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2233 p++;
2234 }
2235 break;
2236 }
2237 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2238 {
2239 p=GetVirtualPixelQueue(image);
2240 if (p == (const Quantum *) NULL)
2241 break;
2242 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2243 {
2244 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2245 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2246 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2247 *q++=0U;
2248 p++;
2249 }
2250 break;
2251 }
2252 p=GetVirtualPixelQueue(image);
2253 if (p == (const Quantum *) NULL)
2254 break;
2255 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2256 {
2257 for (i=0; i < (ssize_t) length; i++)
2258 {
2259 *q=0;
2260 switch (quantum_map[i])
2261 {
2262 case RedQuantum:
2263 case CyanQuantum:
2264 {
2265 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
2266 break;
2267 }
2268 case GreenQuantum:
2269 case MagentaQuantum:
2270 {
2271 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2272 break;
2273 }
2274 case BlueQuantum:
2275 case YellowQuantum:
2276 {
2277 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2278 break;
2279 }
2280 case AlphaQuantum:
2281 {
2282 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2283 break;
2284 }
2285 case OpacityQuantum:
2286 {
2287 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2288 break;
2289 }
2290 case BlackQuantum:
2291 {
2292 if (image->colorspace == CMYKColorspace)
2293 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
2294 break;
2295 }
2296 case IndexQuantum:
2297 {
cristyf13c5942012-08-08 23:50:11 +00002298 *q=ScaleQuantumToLongLong(ClampToQuantum(
2299 GetPixelIntensity(image,p)));
cristy100b8d92012-01-08 00:32:49 +00002300 break;
2301 }
2302 default:
2303 *q=0;
2304 }
2305 q++;
2306 }
2307 p++;
2308 }
2309 break;
2310 }
cristy3ed852e2009-09-05 21:47:34 +00002311 case QuantumPixel:
2312 {
2313 register Quantum
2314 *q;
2315
2316 q=(Quantum *) stream_info->pixels;
2317 if (LocaleCompare(stream_info->map,"BGR") == 0)
2318 {
cristy100b8d92012-01-08 00:32:49 +00002319 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002320 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002321 break;
cristybb503372010-05-27 20:51:26 +00002322 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002323 {
cristy4c08aed2011-07-01 19:47:50 +00002324 *q++=GetPixelBlue(image,p);
2325 *q++=GetPixelGreen(image,p);
2326 *q++=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002327 p++;
2328 }
2329 break;
2330 }
2331 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2332 {
cristy100b8d92012-01-08 00:32:49 +00002333 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002334 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002335 break;
cristybb503372010-05-27 20:51:26 +00002336 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002337 {
cristy4c08aed2011-07-01 19:47:50 +00002338 *q++=GetPixelBlue(image,p);
2339 *q++=GetPixelGreen(image,p);
2340 *q++=GetPixelRed(image,p);
cristy100b8d92012-01-08 00:32:49 +00002341 *q++=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002342 p++;
2343 }
2344 break;
2345 }
2346 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2347 {
cristy100b8d92012-01-08 00:32:49 +00002348 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002349 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002350 break;
cristybb503372010-05-27 20:51:26 +00002351 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002352 {
cristy4c08aed2011-07-01 19:47:50 +00002353 *q++=GetPixelBlue(image,p);
2354 *q++=GetPixelGreen(image,p);
2355 *q++=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002356 *q++=0;
2357 p++;
2358 }
2359 break;
2360 }
2361 if (LocaleCompare(stream_info->map,"I") == 0)
2362 {
cristy100b8d92012-01-08 00:32:49 +00002363 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002364 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002365 break;
cristybb503372010-05-27 20:51:26 +00002366 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002367 {
cristyf13c5942012-08-08 23:50:11 +00002368 *q++=ClampToQuantum(GetPixelIntensity(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002369 p++;
2370 }
2371 break;
2372 }
2373 if (LocaleCompare(stream_info->map,"RGB") == 0)
2374 {
cristy100b8d92012-01-08 00:32:49 +00002375 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002376 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002377 break;
cristybb503372010-05-27 20:51:26 +00002378 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002379 {
cristy4c08aed2011-07-01 19:47:50 +00002380 *q++=GetPixelRed(image,p);
2381 *q++=GetPixelGreen(image,p);
2382 *q++=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002383 p++;
2384 }
2385 break;
2386 }
2387 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2388 {
cristy100b8d92012-01-08 00:32:49 +00002389 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002390 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002391 break;
cristybb503372010-05-27 20:51:26 +00002392 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002393 {
cristy4c08aed2011-07-01 19:47:50 +00002394 *q++=GetPixelRed(image,p);
2395 *q++=GetPixelGreen(image,p);
2396 *q++=GetPixelBlue(image,p);
cristy100b8d92012-01-08 00:32:49 +00002397 *q++=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002398 p++;
2399 }
2400 break;
2401 }
2402 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2403 {
cristy100b8d92012-01-08 00:32:49 +00002404 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002405 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002406 break;
cristybb503372010-05-27 20:51:26 +00002407 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002408 {
cristy4c08aed2011-07-01 19:47:50 +00002409 *q++=GetPixelRed(image,p);
2410 *q++=GetPixelGreen(image,p);
2411 *q++=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002412 *q++=0U;
2413 p++;
2414 }
2415 break;
2416 }
cristy100b8d92012-01-08 00:32:49 +00002417 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002418 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002419 break;
cristybb503372010-05-27 20:51:26 +00002420 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002421 {
cristybb503372010-05-27 20:51:26 +00002422 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002423 {
2424 *q=(Quantum) 0;
2425 switch (quantum_map[i])
2426 {
2427 case RedQuantum:
2428 case CyanQuantum:
2429 {
cristy4c08aed2011-07-01 19:47:50 +00002430 *q=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002431 break;
2432 }
2433 case GreenQuantum:
2434 case MagentaQuantum:
2435 {
cristy4c08aed2011-07-01 19:47:50 +00002436 *q=GetPixelGreen(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002437 break;
2438 }
2439 case BlueQuantum:
2440 case YellowQuantum:
2441 {
cristy4c08aed2011-07-01 19:47:50 +00002442 *q=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002443 break;
2444 }
2445 case AlphaQuantum:
2446 {
cristy4c08aed2011-07-01 19:47:50 +00002447 *q=(Quantum) (GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002448 break;
2449 }
2450 case OpacityQuantum:
2451 {
cristy4c08aed2011-07-01 19:47:50 +00002452 *q=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002453 break;
2454 }
2455 case BlackQuantum:
2456 {
2457 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002458 *q=GetPixelBlack(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002459 break;
2460 }
2461 case IndexQuantum:
2462 {
cristyf13c5942012-08-08 23:50:11 +00002463 *q=ClampToQuantum(GetPixelIntensity(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002464 break;
2465 }
2466 default:
2467 *q=0;
2468 }
2469 q++;
2470 }
2471 p++;
2472 }
2473 break;
2474 }
2475 case ShortPixel:
2476 {
2477 register unsigned short
2478 *q;
2479
2480 q=(unsigned short *) stream_info->pixels;
2481 if (LocaleCompare(stream_info->map,"BGR") == 0)
2482 {
cristy100b8d92012-01-08 00:32:49 +00002483 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002484 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002485 break;
cristybb503372010-05-27 20:51:26 +00002486 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002487 {
cristy4c08aed2011-07-01 19:47:50 +00002488 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2489 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2490 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002491 p++;
2492 }
2493 break;
2494 }
2495 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2496 {
cristy100b8d92012-01-08 00:32:49 +00002497 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002498 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002499 break;
cristybb503372010-05-27 20:51:26 +00002500 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002501 {
cristy4c08aed2011-07-01 19:47:50 +00002502 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2503 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2504 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2505 *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002506 p++;
2507 }
2508 break;
2509 }
2510 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2511 {
cristy100b8d92012-01-08 00:32:49 +00002512 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002513 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002514 break;
cristybb503372010-05-27 20:51:26 +00002515 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002516 {
cristy4c08aed2011-07-01 19:47:50 +00002517 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2518 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2519 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002520 *q++=0;
2521 p++;
2522 }
2523 break;
2524 }
2525 if (LocaleCompare(stream_info->map,"I") == 0)
2526 {
cristy100b8d92012-01-08 00:32:49 +00002527 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002528 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002529 break;
cristybb503372010-05-27 20:51:26 +00002530 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002531 {
cristyf13c5942012-08-08 23:50:11 +00002532 *q++=ScaleQuantumToShort(ClampToQuantum(
2533 GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002534 p++;
2535 }
2536 break;
2537 }
2538 if (LocaleCompare(stream_info->map,"RGB") == 0)
2539 {
cristy100b8d92012-01-08 00:32:49 +00002540 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002541 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002542 break;
cristybb503372010-05-27 20:51:26 +00002543 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002544 {
cristy4c08aed2011-07-01 19:47:50 +00002545 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2546 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2547 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002548 p++;
2549 }
2550 break;
2551 }
2552 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2553 {
cristy100b8d92012-01-08 00:32:49 +00002554 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002555 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002556 break;
cristybb503372010-05-27 20:51:26 +00002557 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002558 {
cristy4c08aed2011-07-01 19:47:50 +00002559 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2560 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2561 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2562 *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002563 p++;
2564 }
2565 break;
2566 }
2567 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2568 {
cristy100b8d92012-01-08 00:32:49 +00002569 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002570 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002571 break;
cristybb503372010-05-27 20:51:26 +00002572 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002573 {
cristy4c08aed2011-07-01 19:47:50 +00002574 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2575 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2576 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002577 *q++=0;
2578 p++;
2579 }
2580 break;
2581 }
cristy100b8d92012-01-08 00:32:49 +00002582 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002583 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002584 break;
cristybb503372010-05-27 20:51:26 +00002585 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002586 {
cristybb503372010-05-27 20:51:26 +00002587 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002588 {
2589 *q=0;
2590 switch (quantum_map[i])
2591 {
2592 case RedQuantum:
2593 case CyanQuantum:
2594 {
cristy4c08aed2011-07-01 19:47:50 +00002595 *q=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002596 break;
2597 }
2598 case GreenQuantum:
2599 case MagentaQuantum:
2600 {
cristy4c08aed2011-07-01 19:47:50 +00002601 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002602 break;
2603 }
2604 case BlueQuantum:
2605 case YellowQuantum:
2606 {
cristy4c08aed2011-07-01 19:47:50 +00002607 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002608 break;
2609 }
2610 case AlphaQuantum:
2611 {
cristy4c08aed2011-07-01 19:47:50 +00002612 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002613 break;
2614 }
2615 case OpacityQuantum:
2616 {
cristy4c08aed2011-07-01 19:47:50 +00002617 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002618 break;
2619 }
2620 case BlackQuantum:
2621 {
2622 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002623 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002624 break;
2625 }
2626 case IndexQuantum:
2627 {
cristyf13c5942012-08-08 23:50:11 +00002628 *q=ScaleQuantumToShort(ClampToQuantum(
2629 GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002630 break;
2631 }
2632 default:
2633 break;
2634 }
2635 q++;
2636 }
2637 p++;
2638 }
2639 break;
2640 }
2641 default:
2642 {
2643 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2644 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristy20cc0872012-08-20 00:01:19 +00002645 "UnrecognizedPixelMap","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00002646 break;
2647 }
2648 }
2649 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2650 return(MagickTrue);
2651}
2652
2653/*
2654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2655% %
2656% %
2657% %
2658+ 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 %
2659% %
2660% %
2661% %
2662%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2663%
2664% SyncAuthenticPixelsStream() calls the user supplied callback method with
2665% the latest stream of pixels.
2666%
2667% The format of the SyncAuthenticPixelsStream method is:
2668%
2669% MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2670% ExceptionInfo *exception)
2671%
2672% A description of each parameter follows:
2673%
2674% o image: the image.
2675%
2676% o exception: return any errors or warnings in this structure.
2677%
2678*/
2679static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2680 ExceptionInfo *exception)
2681{
2682 CacheInfo
2683 *cache_info;
2684
2685 size_t
2686 length;
2687
2688 StreamHandler
2689 stream_handler;
2690
2691 assert(image != (Image *) NULL);
2692 assert(image->signature == MagickSignature);
2693 if (image->debug != MagickFalse)
2694 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2695 cache_info=(CacheInfo *) image->cache;
2696 assert(cache_info->signature == MagickSignature);
2697 stream_handler=GetBlobStreamHandler(image);
2698 if (stream_handler == (StreamHandler) NULL)
2699 {
2700 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +00002701 "NoStreamHandlerIsDefined","'%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +00002702 return(MagickFalse);
2703 }
2704 length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
2705 return(length == cache_info->columns ? MagickTrue : MagickFalse);
2706}
2707
2708/*
2709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2710% %
2711% %
2712% %
2713% W r i t e S t r e a m %
2714% %
2715% %
2716% %
2717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2718%
2719% WriteStream() makes the image pixels available to a user supplied callback
2720% method immediately upon writing pixel data with the WriteImage() method.
2721%
2722% The format of the WriteStream() method is:
2723%
2724% MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
cristyc82a27b2011-10-21 01:07:16 +00002725% StreamHandler stream,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002726%
2727% A description of each parameter follows:
2728%
2729% o image_info: the image info.
2730%
2731% o stream: A callback method.
2732%
cristyc82a27b2011-10-21 01:07:16 +00002733% o exception: return any errors or warnings in this structure.
2734%
cristy3ed852e2009-09-05 21:47:34 +00002735*/
2736MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
cristyc82a27b2011-10-21 01:07:16 +00002737 Image *image,StreamHandler stream,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002738{
2739 ImageInfo
2740 *write_info;
2741
2742 MagickBooleanType
2743 status;
2744
2745 assert(image_info != (ImageInfo *) NULL);
2746 assert(image_info->signature == MagickSignature);
2747 if (image_info->debug != MagickFalse)
2748 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2749 image_info->filename);
2750 assert(image != (Image *) NULL);
2751 assert(image->signature == MagickSignature);
2752 write_info=CloneImageInfo(image_info);
2753 write_info->stream=stream;
cristyc82a27b2011-10-21 01:07:16 +00002754 status=WriteImage(write_info,image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002755 write_info=DestroyImageInfo(write_info);
2756 return(status);
2757}