blob: d52ef98362aadd530d615a3175531297675ca8f1 [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);
cristy4c08aed2011-07-01 19:47:50 +0000749 if (cache_info->metacontent_extent != 0)
750 length+=number_pixels*cache_info->metacontent_extent;
751 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000752 {
753 cache_info->length=length;
754 status=AcquireStreamPixels(cache_info,exception);
755 if (status == MagickFalse)
cristy33503f52010-10-04 17:32:27 +0000756 {
757 cache_info->length=0;
cristy4c08aed2011-07-01 19:47:50 +0000758 return((Quantum *) NULL);
cristy33503f52010-10-04 17:32:27 +0000759 }
cristy3ed852e2009-09-05 21:47:34 +0000760 }
761 else
762 if (cache_info->length != length)
763 {
764 RelinquishStreamPixels(cache_info);
765 cache_info->length=length;
766 status=AcquireStreamPixels(cache_info,exception);
767 if (status == MagickFalse)
cristy33503f52010-10-04 17:32:27 +0000768 {
769 cache_info->length=0;
cristy4c08aed2011-07-01 19:47:50 +0000770 return((Quantum *) NULL);
cristy33503f52010-10-04 17:32:27 +0000771 }
cristy3ed852e2009-09-05 21:47:34 +0000772 }
cristy4c08aed2011-07-01 19:47:50 +0000773 cache_info->metacontent=(void *) NULL;
774 if (cache_info->metacontent_extent != 0)
775 cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
cristyed231572011-07-14 02:18:59 +0000776 cache_info->number_channels);
cristy3ed852e2009-09-05 21:47:34 +0000777 return(cache_info->pixels);
778}
779
780/*
781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
782% %
783% %
784% %
785+ O p e n S t r e a m %
786% %
787% %
788% %
789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
790%
791% OpenStream() opens a stream for writing by the StreamImage() method.
792%
793% The format of the OpenStream method is:
794%
795% MagickBooleanType OpenStream(const ImageInfo *image_info,
796% StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
797%
798% A description of each parameter follows:
799%
800% o image_info: the image info.
801%
802% o stream_info: the stream info.
803%
804% o filename: the stream filename.
805%
806% o exception: return any errors or warnings in this structure.
807%
808*/
809MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
810 StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
811{
812 MagickBooleanType
813 status;
814
815 (void) CopyMagickString(stream_info->stream->filename,filename,MaxTextExtent);
816 status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
817 return(status);
818}
819
820/*
821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822% %
823% %
824% %
825+ 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 %
826% %
827% %
828% %
829%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830%
831% QueueAuthenticPixelsStream() allocates an area to store image pixels as
832% defined by the region rectangle and returns a pointer to the area. This
833% area is subsequently transferred from the pixel cache with method
834% SyncAuthenticPixelsStream(). A pointer to the pixels is returned if the
835% pixels are transferred, otherwise a NULL is returned.
836%
837% The format of the QueueAuthenticPixelsStream() method is:
838%
cristy4c08aed2011-07-01 19:47:50 +0000839% Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000840% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000841% ExceptionInfo *exception)
842%
843% A description of each parameter follows:
844%
845% o image: the image.
846%
847% o x,y,columns,rows: These values define the perimeter of a region of
848% pixels.
849%
850*/
cristy4c08aed2011-07-01 19:47:50 +0000851static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000852 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000853 ExceptionInfo *exception)
854{
855 CacheInfo
856 *cache_info;
857
cristy20cc0872012-08-20 00:01:19 +0000858 MagickBooleanType
859 status;
860
cristy3ed852e2009-09-05 21:47:34 +0000861 MagickSizeType
862 number_pixels;
863
864 size_t
865 length;
866
867 StreamHandler
868 stream_handler;
869
870 /*
871 Validate pixel cache geometry.
872 */
873 assert(image != (Image *) NULL);
cristycfae90a2010-10-04 14:43:33 +0000874 if ((x < 0) || (y < 0) ||
875 ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
876 ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
877 (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000878 {
879 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +0000880 "ImageDoesNotContainTheStreamGeometry","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000881 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000882 }
883 stream_handler=GetBlobStreamHandler(image);
884 if (stream_handler == (StreamHandler) NULL)
885 {
886 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +0000887 "NoStreamHandlerIsDefined","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000888 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000889 }
890 cache_info=(CacheInfo *) image->cache;
891 assert(cache_info->signature == MagickSignature);
892 if ((image->storage_class != GetPixelCacheStorageClass(image->cache)) ||
893 (image->colorspace != GetPixelCacheColorspace(image->cache)))
894 {
895 if (GetPixelCacheStorageClass(image->cache) == UndefinedClass)
896 (void) stream_handler(image,(const void *) NULL,(size_t)
897 cache_info->columns);
898 cache_info->storage_class=image->storage_class;
899 cache_info->colorspace=image->colorspace;
900 cache_info->columns=image->columns;
901 cache_info->rows=image->rows;
902 image->cache=cache_info;
903 }
904 /*
905 Pixels are stored in a temporary buffer until they are synced to the cache.
906 */
907 cache_info->columns=columns;
908 cache_info->rows=rows;
909 number_pixels=(MagickSizeType) columns*rows;
cristyed231572011-07-14 02:18:59 +0000910 length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
cristyd62370b2012-08-20 00:22:14 +0000911 if (cache_info->number_channels == 0)
cristy20cc0872012-08-20 00:01:19 +0000912 length=number_pixels*sizeof(Quantum);
cristy4c08aed2011-07-01 19:47:50 +0000913 if (cache_info->metacontent_extent != 0)
914 length+=number_pixels*cache_info->metacontent_extent;
915 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000916 {
cristy20cc0872012-08-20 00:01:19 +0000917 cache_info->length=length;
918 status=AcquireStreamPixels(cache_info,exception);
919 if (status == MagickFalse)
920 {
921 cache_info->length=0;
922 return((Quantum *) NULL);
923 }
cristy3ed852e2009-09-05 21:47:34 +0000924 }
925 else
cristy20cc0872012-08-20 00:01:19 +0000926 if (cache_info->length < length)
cristy3ed852e2009-09-05 21:47:34 +0000927 {
cristy20cc0872012-08-20 00:01:19 +0000928 RelinquishStreamPixels(cache_info);
929 cache_info->length=length;
930 status=AcquireStreamPixels(cache_info,exception);
931 if (status == MagickFalse)
932 {
933 cache_info->length=0;
934 return((Quantum *) NULL);
935 }
cristy3ed852e2009-09-05 21:47:34 +0000936 }
cristy4c08aed2011-07-01 19:47:50 +0000937 cache_info->metacontent=(void *) NULL;
938 if (cache_info->metacontent_extent != 0)
939 cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
cristyed231572011-07-14 02:18:59 +0000940 cache_info->number_channels);
cristy3ed852e2009-09-05 21:47:34 +0000941 return(cache_info->pixels);
942}
943
944/*
945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
946% %
947% %
948% %
949% R e a d S t r e a m %
950% %
951% %
952% %
953%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
954%
955% ReadStream() makes the image pixels available to a user supplied callback
956% method immediately upon reading a scanline with the ReadImage() method.
957%
958% The format of the ReadStream() method is:
959%
960% Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
961% ExceptionInfo *exception)
962%
963% A description of each parameter follows:
964%
965% o image_info: the image info.
966%
967% o stream: a callback method.
968%
969% o exception: return any errors or warnings in this structure.
970%
971*/
972MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
973 ExceptionInfo *exception)
974{
975 CacheMethods
976 cache_methods;
977
978 Image
979 *image;
980
981 ImageInfo
982 *read_info;
983
984 /*
985 Stream image pixels.
986 */
987 assert(image_info != (ImageInfo *) NULL);
988 assert(image_info->signature == MagickSignature);
989 if (image_info->debug != MagickFalse)
990 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
991 image_info->filename);
992 assert(exception != (ExceptionInfo *) NULL);
993 assert(exception->signature == MagickSignature);
994 read_info=CloneImageInfo(image_info);
995 read_info->cache=AcquirePixelCache(0);
996 GetPixelCacheMethods(&cache_methods);
997 cache_methods.get_virtual_pixel_handler=GetVirtualPixelStream;
cristy4c08aed2011-07-01 19:47:50 +0000998 cache_methods.get_virtual_metacontent_from_handler=
999 GetVirtualMetacontentFromStream;
cristy3ed852e2009-09-05 21:47:34 +00001000 cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
1001 cache_methods.get_authentic_pixels_handler=GetAuthenticPixelsStream;
1002 cache_methods.queue_authentic_pixels_handler=QueueAuthenticPixelsStream;
1003 cache_methods.sync_authentic_pixels_handler=SyncAuthenticPixelsStream;
1004 cache_methods.get_authentic_pixels_from_handler=GetAuthenticPixelsFromStream;
cristy4c08aed2011-07-01 19:47:50 +00001005 cache_methods.get_authentic_metacontent_from_handler=
1006 GetAuthenticMetacontentFromStream;
cristy3ed852e2009-09-05 21:47:34 +00001007 cache_methods.get_one_virtual_pixel_from_handler=GetOneVirtualPixelFromStream;
1008 cache_methods.get_one_authentic_pixel_from_handler=
1009 GetOneAuthenticPixelFromStream;
1010 cache_methods.destroy_pixel_handler=DestroyPixelStream;
1011 SetPixelCacheMethods(read_info->cache,&cache_methods);
1012 read_info->stream=stream;
1013 image=ReadImage(read_info,exception);
1014 read_info=DestroyImageInfo(read_info);
1015 return(image);
1016}
1017
1018/*
1019%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1020% %
1021% %
1022% %
1023+ S e t S t r e a m I n f o C l i e n t D a t a %
1024% %
1025% %
1026% %
1027%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1028%
1029% SetStreamInfoClientData() sets the stream info client data.
1030%
1031% The format of the SetStreamInfoClientData method is:
1032%
1033% void SetStreamInfoClientData(StreamInfo *stream_info,
1034% const void *client_data)
1035%
1036% A description of each parameter follows:
1037%
1038% o stream_info: the stream info.
1039%
1040% o client_data: the client data.
1041%
1042*/
cristy7832dc22011-09-05 01:21:53 +00001043MagickPrivate void SetStreamInfoClientData(StreamInfo *stream_info,
cristy3ed852e2009-09-05 21:47:34 +00001044 const void *client_data)
1045{
1046 assert(stream_info != (StreamInfo *) NULL);
1047 assert(stream_info->signature == MagickSignature);
1048 stream_info->client_data=client_data;
1049}
1050
1051/*
1052%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1053% %
1054% %
1055% %
1056+ S e t S t r e a m I n f o M a p %
1057% %
1058% %
1059% %
1060%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1061%
1062% SetStreamInfoMap() sets the stream info map member.
1063%
1064% The format of the SetStreamInfoMap method is:
1065%
1066% void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1067%
1068% A description of each parameter follows:
1069%
1070% o stream_info: the stream info.
1071%
1072% o map: the map.
1073%
1074*/
1075MagickExport void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1076{
1077 assert(stream_info != (StreamInfo *) NULL);
1078 assert(stream_info->signature == MagickSignature);
1079 (void) CloneString(&stream_info->map,map);
1080}
1081
1082/*
1083%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1084% %
1085% %
1086% %
1087+ S e t S t r e a m I n f o S t o r a g e T y p e %
1088% %
1089% %
1090% %
1091%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1092%
1093% SetStreamInfoStorageType() sets the stream info storage type member.
1094%
1095% The format of the SetStreamInfoStorageType method is:
1096%
1097% void SetStreamInfoStorageType(StreamInfo *stream_info,
1098% const StoreageType *storage_type)
1099%
1100% A description of each parameter follows:
1101%
1102% o stream_info: the stream info.
1103%
1104% o storage_type: the storage type.
1105%
1106*/
1107MagickExport void SetStreamInfoStorageType(StreamInfo *stream_info,
1108 const StorageType storage_type)
1109{
1110 assert(stream_info != (StreamInfo *) NULL);
1111 assert(stream_info->signature == MagickSignature);
1112 stream_info->storage_type=storage_type;
1113}
1114
1115/*
1116%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1117% %
1118% %
1119% %
1120+ S t r e a m I m a g e %
1121% %
1122% %
1123% %
1124%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1125%
1126% StreamImage() streams pixels from an image and writes them in a user
1127% defined format and storage type (e.g. RGBA as 8-bit unsigned char).
1128%
cristyd212bd02011-02-13 17:08:57 +00001129% The format of the StreamImage() method is:
cristy3ed852e2009-09-05 21:47:34 +00001130%
1131% Image *StreamImage(const ImageInfo *image_info,
1132% StreamInfo *stream_info,ExceptionInfo *exception)
1133%
1134% A description of each parameter follows:
1135%
1136% o image_info: the image info.
1137%
1138% o stream_info: the stream info.
1139%
1140% o exception: return any errors or warnings in this structure.
1141%
1142*/
1143
1144#if defined(__cplusplus) || defined(c_plusplus)
1145extern "C" {
1146#endif
1147
1148static size_t WriteStreamImage(const Image *image,const void *pixels,
1149 const size_t columns)
1150{
cristye3664f42010-05-14 00:59:57 +00001151 CacheInfo
1152 *cache_info;
1153
cristy3ed852e2009-09-05 21:47:34 +00001154 RectangleInfo
1155 extract_info;
1156
1157 size_t
1158 length,
1159 packet_size;
1160
1161 ssize_t
1162 count;
1163
1164 StreamInfo
1165 *stream_info;
1166
cristy654fdaf2011-02-24 15:24:33 +00001167 (void) pixels;
cristy3ed852e2009-09-05 21:47:34 +00001168 stream_info=(StreamInfo *) image->client_data;
1169 switch (stream_info->storage_type)
1170 {
cristy100b8d92012-01-08 00:32:49 +00001171 default: packet_size=sizeof(unsigned char); break;
1172 case CharPixel: packet_size=sizeof(unsigned char); break;
cristy3ed852e2009-09-05 21:47:34 +00001173 case DoublePixel: packet_size=sizeof(double); break;
1174 case FloatPixel: packet_size=sizeof(float); break;
cristy100b8d92012-01-08 00:32:49 +00001175 case LongPixel: packet_size=sizeof(unsigned int); break;
1176 case LongLongPixel: packet_size=sizeof(MagickSizeType); break;
cristy3ed852e2009-09-05 21:47:34 +00001177 case QuantumPixel: packet_size=sizeof(Quantum); break;
1178 case ShortPixel: packet_size=sizeof(unsigned short); break;
1179 }
cristye3664f42010-05-14 00:59:57 +00001180 cache_info=(CacheInfo *) image->cache;
1181 assert(cache_info->signature == MagickSignature);
cristy3ed852e2009-09-05 21:47:34 +00001182 packet_size*=strlen(stream_info->map);
cristye3664f42010-05-14 00:59:57 +00001183 length=packet_size*cache_info->columns*cache_info->rows;
cristy3ed852e2009-09-05 21:47:34 +00001184 if (image != stream_info->image)
1185 {
1186 ImageInfo
1187 *write_info;
1188
1189 /*
1190 Prepare stream for writing.
1191 */
cristy39c2e212012-08-18 18:14:34 +00001192 (void) RelinquishAlignedMemory(stream_info->pixels);
cristy20cc0872012-08-20 00:01:19 +00001193 stream_info->pixels=(unsigned char *) AcquireAlignedMemory(1,length);
cristy5dd71882010-08-01 20:53:13 +00001194 if (stream_info->pixels == (unsigned char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001195 return(0);
cristy39c2e212012-08-18 18:14:34 +00001196 (void) ResetMagickMemory(stream_info->pixels,0,length);
cristy3ed852e2009-09-05 21:47:34 +00001197 stream_info->image=image;
1198 write_info=CloneImageInfo(stream_info->image_info);
cristyd965a422010-03-03 17:47:35 +00001199 (void) SetImageInfo(write_info,1,stream_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001200 if (write_info->extract != (char *) NULL)
1201 (void) ParseAbsoluteGeometry(write_info->extract,
1202 &stream_info->extract_info);
1203 stream_info->y=0;
1204 write_info=DestroyImageInfo(write_info);
1205 }
1206 extract_info=stream_info->extract_info;
cristyd212bd02011-02-13 17:08:57 +00001207 if ((extract_info.width == 0) || (extract_info.height == 0))
cristy3ed852e2009-09-05 21:47:34 +00001208 {
1209 /*
1210 Write all pixels to stream.
1211 */
1212 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1213 count=WriteBlob(stream_info->stream,length,stream_info->pixels);
1214 stream_info->y++;
1215 return(count == 0 ? 0 : columns);
1216 }
1217 if ((stream_info->y < extract_info.y) ||
cristybb503372010-05-27 20:51:26 +00001218 (stream_info->y >= (ssize_t) (extract_info.y+extract_info.height)))
cristy3ed852e2009-09-05 21:47:34 +00001219 {
1220 stream_info->y++;
1221 return(columns);
1222 }
1223 /*
1224 Write a portion of the pixel row to the stream.
1225 */
1226 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1227 length=packet_size*extract_info.width;
cristy5dd71882010-08-01 20:53:13 +00001228 count=WriteBlob(stream_info->stream,length,stream_info->pixels+packet_size*
1229 extract_info.x);
cristy3ed852e2009-09-05 21:47:34 +00001230 stream_info->y++;
1231 return(count == 0 ? 0 : columns);
1232}
1233
1234#if defined(__cplusplus) || defined(c_plusplus)
1235}
1236#endif
1237
1238MagickExport Image *StreamImage(const ImageInfo *image_info,
1239 StreamInfo *stream_info,ExceptionInfo *exception)
1240{
1241 Image
1242 *image;
1243
1244 ImageInfo
1245 *read_info;
1246
1247 assert(image_info != (const ImageInfo *) NULL);
1248 assert(image_info->signature == MagickSignature);
1249 if (image_info->debug != MagickFalse)
1250 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1251 image_info->filename);
1252 assert(stream_info != (StreamInfo *) NULL);
1253 assert(stream_info->signature == MagickSignature);
1254 assert(exception != (ExceptionInfo *) NULL);
1255 read_info=CloneImageInfo(image_info);
1256 stream_info->image_info=image_info;
1257 stream_info->exception=exception;
1258 read_info->client_data=(void *) stream_info;
1259 image=ReadStream(read_info,&WriteStreamImage,exception);
1260 read_info=DestroyImageInfo(read_info);
1261 stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
1262 if (stream_info->quantum_info == (QuantumInfo *) NULL)
1263 image=DestroyImage(image);
1264 return(image);
1265}
1266
1267/*
1268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1269% %
1270% %
1271% %
1272+ S t r e a m I m a g e P i x e l s %
1273% %
1274% %
1275% %
1276%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1277%
1278% StreamImagePixels() extracts pixel data from an image and returns it in the
1279% stream_info->pixels structure in the format as defined by
1280% stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
1281%
1282% The format of the StreamImagePixels method is:
1283%
1284% MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1285% const Image *image,ExceptionInfo *exception)
1286%
1287% A description of each parameter follows:
1288%
1289% o stream_info: the stream info.
1290%
1291% o image: the image.
1292%
1293% o exception: return any errors or warnings in this structure.
1294%
1295*/
1296static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1297 const Image *image,ExceptionInfo *exception)
1298{
1299 QuantumInfo
1300 *quantum_info;
1301
1302 QuantumType
1303 *quantum_map;
1304
cristy4c08aed2011-07-01 19:47:50 +00001305 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +00001306 *p;
1307
cristyd212bd02011-02-13 17:08:57 +00001308 register ssize_t
1309 i,
1310 x;
1311
cristy3ed852e2009-09-05 21:47:34 +00001312 size_t
1313 length;
1314
1315 assert(stream_info != (StreamInfo *) NULL);
1316 assert(stream_info->signature == MagickSignature);
1317 assert(image != (Image *) NULL);
1318 assert(image->signature == MagickSignature);
1319 if (image->debug != MagickFalse)
1320 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1321 length=strlen(stream_info->map);
1322 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1323 if (quantum_map == (QuantumType *) NULL)
1324 {
1325 (void) ThrowMagickException(exception,GetMagickModule(),
cristy20cc0872012-08-20 00:01:19 +00001326 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +00001327 return(MagickFalse);
1328 }
cristybb503372010-05-27 20:51:26 +00001329 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001330 {
1331 switch (stream_info->map[i])
1332 {
1333 case 'A':
1334 case 'a':
1335 {
1336 quantum_map[i]=AlphaQuantum;
1337 break;
1338 }
1339 case 'B':
1340 case 'b':
1341 {
1342 quantum_map[i]=BlueQuantum;
1343 break;
1344 }
1345 case 'C':
1346 case 'c':
1347 {
1348 quantum_map[i]=CyanQuantum;
1349 if (image->colorspace == CMYKColorspace)
1350 break;
1351 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1352 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001353 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001354 return(MagickFalse);
1355 }
1356 case 'g':
1357 case 'G':
1358 {
1359 quantum_map[i]=GreenQuantum;
1360 break;
1361 }
1362 case 'I':
1363 case 'i':
1364 {
1365 quantum_map[i]=IndexQuantum;
1366 break;
1367 }
1368 case 'K':
1369 case 'k':
1370 {
1371 quantum_map[i]=BlackQuantum;
1372 if (image->colorspace == CMYKColorspace)
1373 break;
1374 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1375 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001376 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001377 return(MagickFalse);
1378 }
1379 case 'M':
1380 case 'm':
1381 {
1382 quantum_map[i]=MagentaQuantum;
1383 if (image->colorspace == CMYKColorspace)
1384 break;
1385 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1386 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001387 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001388 return(MagickFalse);
1389 }
1390 case 'o':
1391 case 'O':
1392 {
1393 quantum_map[i]=OpacityQuantum;
1394 break;
1395 }
1396 case 'P':
1397 case 'p':
1398 {
1399 quantum_map[i]=UndefinedQuantum;
1400 break;
1401 }
1402 case 'R':
1403 case 'r':
1404 {
1405 quantum_map[i]=RedQuantum;
1406 break;
1407 }
1408 case 'Y':
1409 case 'y':
1410 {
1411 quantum_map[i]=YellowQuantum;
1412 if (image->colorspace == CMYKColorspace)
1413 break;
1414 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1415 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy20cc0872012-08-20 00:01:19 +00001416 "ColorSeparatedImageRequired","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001417 return(MagickFalse);
1418 }
1419 default:
1420 {
1421 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1422 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristy20cc0872012-08-20 00:01:19 +00001423 "UnrecognizedPixelMap","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001424 return(MagickFalse);
1425 }
1426 }
1427 }
1428 quantum_info=stream_info->quantum_info;
1429 switch (stream_info->storage_type)
1430 {
1431 case CharPixel:
1432 {
1433 register unsigned char
1434 *q;
1435
1436 q=(unsigned char *) stream_info->pixels;
1437 if (LocaleCompare(stream_info->map,"BGR") == 0)
1438 {
cristy100b8d92012-01-08 00:32:49 +00001439 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001440 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001441 break;
cristybb503372010-05-27 20:51:26 +00001442 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001443 {
cristy4c08aed2011-07-01 19:47:50 +00001444 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1445 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1446 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001447 p++;
1448 }
1449 break;
1450 }
1451 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1452 {
cristy100b8d92012-01-08 00:32:49 +00001453 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001454 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001455 break;
cristybb503372010-05-27 20:51:26 +00001456 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001457 {
cristy4c08aed2011-07-01 19:47:50 +00001458 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1459 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1460 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1461 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001462 p++;
1463 }
1464 break;
1465 }
1466 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1467 {
cristy100b8d92012-01-08 00:32:49 +00001468 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001469 if (p == (const Quantum *) NULL)
cristy100b8d92012-01-08 00:32:49 +00001470 break;
cristybb503372010-05-27 20:51:26 +00001471 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001472 {
cristy4c08aed2011-07-01 19:47:50 +00001473 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1474 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1475 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001476 *q++=ScaleQuantumToChar((Quantum) 0);
1477 p++;
1478 }
1479 break;
1480 }
1481 if (LocaleCompare(stream_info->map,"I") == 0)
1482 {
cristy100b8d92012-01-08 00:32:49 +00001483 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001484 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001485 break;
cristybb503372010-05-27 20:51:26 +00001486 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001487 {
cristyf13c5942012-08-08 23:50:11 +00001488 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001489 p++;
1490 }
1491 break;
1492 }
1493 if (LocaleCompare(stream_info->map,"RGB") == 0)
1494 {
cristy100b8d92012-01-08 00:32:49 +00001495 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001496 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001497 break;
cristybb503372010-05-27 20:51:26 +00001498 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001499 {
cristy4c08aed2011-07-01 19:47:50 +00001500 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1501 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1502 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001503 p++;
1504 }
1505 break;
1506 }
1507 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1508 {
cristy100b8d92012-01-08 00:32:49 +00001509 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001510 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001511 break;
cristybb503372010-05-27 20:51:26 +00001512 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001513 {
cristy4c08aed2011-07-01 19:47:50 +00001514 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1515 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1516 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1517 *q++=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001518 p++;
1519 }
1520 break;
1521 }
1522 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1523 {
cristy100b8d92012-01-08 00:32:49 +00001524 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001525 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001526 break;
cristybb503372010-05-27 20:51:26 +00001527 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001528 {
cristy4c08aed2011-07-01 19:47:50 +00001529 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1530 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1531 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001532 *q++=ScaleQuantumToChar((Quantum) 0);
1533 p++;
1534 }
1535 break;
1536 }
cristy100b8d92012-01-08 00:32:49 +00001537 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001538 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001539 break;
cristybb503372010-05-27 20:51:26 +00001540 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001541 {
cristybb503372010-05-27 20:51:26 +00001542 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001543 {
1544 *q=0;
1545 switch (quantum_map[i])
1546 {
1547 case RedQuantum:
1548 case CyanQuantum:
1549 {
cristy4c08aed2011-07-01 19:47:50 +00001550 *q=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001551 break;
1552 }
1553 case GreenQuantum:
1554 case MagentaQuantum:
1555 {
cristy4c08aed2011-07-01 19:47:50 +00001556 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001557 break;
1558 }
1559 case BlueQuantum:
1560 case YellowQuantum:
1561 {
cristy4c08aed2011-07-01 19:47:50 +00001562 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001563 break;
1564 }
1565 case AlphaQuantum:
1566 {
cristy4c08aed2011-07-01 19:47:50 +00001567 *q=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001568 break;
1569 }
1570 case OpacityQuantum:
1571 {
cristy4c08aed2011-07-01 19:47:50 +00001572 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001573 break;
1574 }
1575 case BlackQuantum:
1576 {
1577 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001578 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001579 break;
1580 }
1581 case IndexQuantum:
1582 {
cristyf13c5942012-08-08 23:50:11 +00001583 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001584 break;
1585 }
1586 default:
1587 break;
1588 }
1589 q++;
1590 }
1591 p++;
1592 }
1593 break;
1594 }
1595 case DoublePixel:
1596 {
1597 register double
1598 *q;
1599
1600 q=(double *) stream_info->pixels;
1601 if (LocaleCompare(stream_info->map,"BGR") == 0)
1602 {
cristy100b8d92012-01-08 00:32:49 +00001603 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001604 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001605 break;
cristybb503372010-05-27 20:51:26 +00001606 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001607 {
cristy4c08aed2011-07-01 19:47:50 +00001608 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001609 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001610 *q++=(double) ((QuantumScale*GetPixelGreen(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*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001613 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001614 p++;
1615 }
1616 break;
1617 }
1618 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1619 {
cristy100b8d92012-01-08 00:32:49 +00001620 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001621 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001622 break;
cristybb503372010-05-27 20:51:26 +00001623 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001624 {
cristy4c08aed2011-07-01 19:47:50 +00001625 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001626 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001627 *q++=(double) ((QuantumScale*GetPixelGreen(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*GetPixelRed(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*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001632 quantum_info->scale+quantum_info->minimum);
1633 p++;
1634 }
1635 break;
1636 }
1637 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1638 {
cristy100b8d92012-01-08 00:32:49 +00001639 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001640 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001641 break;
cristybb503372010-05-27 20:51:26 +00001642 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001643 {
cristy4c08aed2011-07-01 19:47:50 +00001644 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001645 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001646 *q++=(double) ((QuantumScale*GetPixelGreen(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*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001649 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001650 *q++=0.0;
1651 p++;
1652 }
1653 break;
1654 }
1655 if (LocaleCompare(stream_info->map,"I") == 0)
1656 {
cristy100b8d92012-01-08 00:32:49 +00001657 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001658 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001659 break;
cristybb503372010-05-27 20:51:26 +00001660 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001661 {
cristy4c08aed2011-07-01 19:47:50 +00001662 *q++=(double) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001663 quantum_info->scale+quantum_info->minimum);
1664 p++;
1665 }
1666 break;
1667 }
1668 if (LocaleCompare(stream_info->map,"RGB") == 0)
1669 {
cristy100b8d92012-01-08 00:32:49 +00001670 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001671 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001672 break;
cristybb503372010-05-27 20:51:26 +00001673 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001674 {
cristy4c08aed2011-07-01 19:47:50 +00001675 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001676 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001677 *q++=(double) ((QuantumScale*GetPixelGreen(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*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001680 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001681 p++;
1682 }
1683 break;
1684 }
1685 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1686 {
cristy100b8d92012-01-08 00:32:49 +00001687 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001688 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001689 break;
cristybb503372010-05-27 20:51:26 +00001690 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001691 {
cristy4c08aed2011-07-01 19:47:50 +00001692 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001693 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001694 *q++=(double) ((QuantumScale*GetPixelGreen(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*GetPixelBlue(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*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001699 quantum_info->scale+quantum_info->minimum);
1700 p++;
1701 }
1702 break;
1703 }
1704 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1705 {
cristy100b8d92012-01-08 00:32:49 +00001706 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001707 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001708 break;
cristybb503372010-05-27 20:51:26 +00001709 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001710 {
cristy4c08aed2011-07-01 19:47:50 +00001711 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001712 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001713 *q++=(double) ((QuantumScale*GetPixelGreen(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*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001716 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001717 *q++=0.0;
1718 p++;
1719 }
1720 break;
1721 }
cristy100b8d92012-01-08 00:32:49 +00001722 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001723 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001724 break;
cristybb503372010-05-27 20:51:26 +00001725 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001726 {
cristybb503372010-05-27 20:51:26 +00001727 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001728 {
1729 *q=0;
1730 switch (quantum_map[i])
1731 {
1732 case RedQuantum:
1733 case CyanQuantum:
1734 {
cristy4c08aed2011-07-01 19:47:50 +00001735 *q=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001736 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001737 break;
1738 }
1739 case GreenQuantum:
1740 case MagentaQuantum:
1741 {
cristy4c08aed2011-07-01 19:47:50 +00001742 *q=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001743 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001744 break;
1745 }
1746 case BlueQuantum:
1747 case YellowQuantum:
1748 {
cristy4c08aed2011-07-01 19:47:50 +00001749 *q=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001750 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001751 break;
1752 }
1753 case AlphaQuantum:
1754 {
cristy4c08aed2011-07-01 19:47:50 +00001755 *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001756 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001757 break;
1758 }
1759 case OpacityQuantum:
1760 {
cristy4c08aed2011-07-01 19:47:50 +00001761 *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001762 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001763 break;
1764 }
1765 case BlackQuantum:
1766 {
1767 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001768 *q=(double) ((QuantumScale*GetPixelBlack(image,p))*
cristyfba5a8b2011-05-03 17:12:12 +00001769 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001770 break;
1771 }
1772 case IndexQuantum:
1773 {
cristy4c08aed2011-07-01 19:47:50 +00001774 *q=(double) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001775 quantum_info->scale+quantum_info->minimum);
1776 break;
1777 }
1778 default:
1779 *q=0;
1780 }
1781 q++;
1782 }
1783 p++;
1784 }
1785 break;
1786 }
1787 case FloatPixel:
1788 {
1789 register float
1790 *q;
1791
1792 q=(float *) stream_info->pixels;
1793 if (LocaleCompare(stream_info->map,"BGR") == 0)
1794 {
cristy100b8d92012-01-08 00:32:49 +00001795 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001796 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001797 break;
cristybb503372010-05-27 20:51:26 +00001798 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001799 {
cristy4c08aed2011-07-01 19:47:50 +00001800 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001801 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001802 *q++=(float) ((QuantumScale*GetPixelGreen(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*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001805 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001806 p++;
1807 }
1808 break;
1809 }
1810 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1811 {
cristy100b8d92012-01-08 00:32:49 +00001812 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001813 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001814 break;
cristybb503372010-05-27 20:51:26 +00001815 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001816 {
cristy4c08aed2011-07-01 19:47:50 +00001817 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001818 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001819 *q++=(float) ((QuantumScale*GetPixelGreen(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*GetPixelRed(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*(Quantum) (GetPixelAlpha(image,p)))*
cristy3ed852e2009-09-05 21:47:34 +00001824 quantum_info->scale+quantum_info->minimum);
1825 p++;
1826 }
1827 break;
1828 }
1829 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1830 {
cristy100b8d92012-01-08 00:32:49 +00001831 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001832 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001833 break;
cristybb503372010-05-27 20:51:26 +00001834 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001835 {
cristy4c08aed2011-07-01 19:47:50 +00001836 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001837 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001838 *q++=(float) ((QuantumScale*GetPixelGreen(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*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001841 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001842 *q++=0.0;
1843 p++;
1844 }
1845 break;
1846 }
1847 if (LocaleCompare(stream_info->map,"I") == 0)
1848 {
cristy100b8d92012-01-08 00:32:49 +00001849 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001850 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001851 break;
cristybb503372010-05-27 20:51:26 +00001852 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001853 {
cristy4c08aed2011-07-01 19:47:50 +00001854 *q++=(float) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001855 quantum_info->scale+quantum_info->minimum);
1856 p++;
1857 }
1858 break;
1859 }
1860 if (LocaleCompare(stream_info->map,"RGB") == 0)
1861 {
cristy100b8d92012-01-08 00:32:49 +00001862 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001863 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001864 break;
cristybb503372010-05-27 20:51:26 +00001865 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001866 {
cristy4c08aed2011-07-01 19:47:50 +00001867 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001868 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001869 *q++=(float) ((QuantumScale*GetPixelGreen(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*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001872 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001873 p++;
1874 }
1875 break;
1876 }
1877 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1878 {
cristy100b8d92012-01-08 00:32:49 +00001879 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001880 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001881 break;
cristybb503372010-05-27 20:51:26 +00001882 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001883 {
cristy4c08aed2011-07-01 19:47:50 +00001884 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001885 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001886 *q++=(float) ((QuantumScale*GetPixelGreen(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*GetPixelBlue(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*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001891 quantum_info->scale+quantum_info->minimum);
1892 p++;
1893 }
1894 break;
1895 }
1896 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1897 {
cristy100b8d92012-01-08 00:32:49 +00001898 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001899 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001900 break;
cristybb503372010-05-27 20:51:26 +00001901 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001902 {
cristy4c08aed2011-07-01 19:47:50 +00001903 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001904 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001905 *q++=(float) ((QuantumScale*GetPixelGreen(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*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001908 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001909 *q++=0.0;
1910 p++;
1911 }
1912 break;
1913 }
cristy100b8d92012-01-08 00:32:49 +00001914 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001915 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001916 break;
cristybb503372010-05-27 20:51:26 +00001917 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001918 {
cristybb503372010-05-27 20:51:26 +00001919 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001920 {
1921 *q=0;
1922 switch (quantum_map[i])
1923 {
1924 case RedQuantum:
1925 case CyanQuantum:
1926 {
cristy4c08aed2011-07-01 19:47:50 +00001927 *q=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001928 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001929 break;
1930 }
1931 case GreenQuantum:
1932 case MagentaQuantum:
1933 {
cristy4c08aed2011-07-01 19:47:50 +00001934 *q=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001935 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001936 break;
1937 }
1938 case BlueQuantum:
1939 case YellowQuantum:
1940 {
cristy4c08aed2011-07-01 19:47:50 +00001941 *q=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001942 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001943 break;
1944 }
1945 case AlphaQuantum:
1946 {
cristy4c08aed2011-07-01 19:47:50 +00001947 *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001948 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001949 break;
1950 }
1951 case OpacityQuantum:
1952 {
cristy4c08aed2011-07-01 19:47:50 +00001953 *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001954 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001955 break;
1956 }
1957 case BlackQuantum:
1958 {
1959 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001960 *q=(float) ((QuantumScale*GetPixelBlack(image,p))*
cristyfba5a8b2011-05-03 17:12:12 +00001961 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001962 break;
1963 }
1964 case IndexQuantum:
1965 {
cristy4c08aed2011-07-01 19:47:50 +00001966 *q=(float) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001967 quantum_info->scale+quantum_info->minimum);
1968 break;
1969 }
1970 default:
1971 *q=0;
1972 }
1973 q++;
1974 }
1975 p++;
1976 }
1977 break;
1978 }
cristy100b8d92012-01-08 00:32:49 +00001979 case LongPixel:
cristy3ed852e2009-09-05 21:47:34 +00001980 {
1981 register unsigned int
1982 *q;
1983
1984 q=(unsigned int *) stream_info->pixels;
1985 if (LocaleCompare(stream_info->map,"BGR") == 0)
1986 {
cristy100b8d92012-01-08 00:32:49 +00001987 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001988 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001989 break;
cristybb503372010-05-27 20:51:26 +00001990 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001991 {
cristy4c08aed2011-07-01 19:47:50 +00001992 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1993 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1994 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001995 p++;
1996 }
1997 break;
1998 }
1999 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2000 {
cristy100b8d92012-01-08 00:32:49 +00002001 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002002 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002003 break;
cristybb503372010-05-27 20:51:26 +00002004 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002005 {
cristy4c08aed2011-07-01 19:47:50 +00002006 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2007 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2008 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2009 *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002010 p++;
2011 }
2012 break;
2013 }
2014 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2015 {
cristy100b8d92012-01-08 00:32:49 +00002016 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002017 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002018 break;
cristybb503372010-05-27 20:51:26 +00002019 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002020 {
cristy4c08aed2011-07-01 19:47:50 +00002021 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2022 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2023 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002024 *q++=0;
2025 p++;
2026 }
2027 break;
2028 }
2029 if (LocaleCompare(stream_info->map,"I") == 0)
2030 {
cristy100b8d92012-01-08 00:32:49 +00002031 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002032 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002033 break;
cristybb503372010-05-27 20:51:26 +00002034 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002035 {
cristyf13c5942012-08-08 23:50:11 +00002036 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002037 p++;
2038 }
2039 break;
2040 }
2041 if (LocaleCompare(stream_info->map,"RGB") == 0)
2042 {
cristy100b8d92012-01-08 00:32:49 +00002043 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002044 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002045 break;
cristybb503372010-05-27 20:51:26 +00002046 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002047 {
cristy4c08aed2011-07-01 19:47:50 +00002048 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2049 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2050 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002051 p++;
2052 }
2053 break;
2054 }
2055 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2056 {
cristy100b8d92012-01-08 00:32:49 +00002057 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002058 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002059 break;
cristybb503372010-05-27 20:51:26 +00002060 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002061 {
cristy4c08aed2011-07-01 19:47:50 +00002062 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2063 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2064 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2065 *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002066 p++;
2067 }
2068 break;
2069 }
2070 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2071 {
cristy100b8d92012-01-08 00:32:49 +00002072 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002073 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002074 break;
cristybb503372010-05-27 20:51:26 +00002075 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002076 {
cristy4c08aed2011-07-01 19:47:50 +00002077 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2078 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2079 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002080 *q++=0;
2081 p++;
2082 }
2083 break;
2084 }
cristy100b8d92012-01-08 00:32:49 +00002085 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002086 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002087 break;
cristybb503372010-05-27 20:51:26 +00002088 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002089 {
cristybb503372010-05-27 20:51:26 +00002090 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002091 {
2092 *q=0;
2093 switch (quantum_map[i])
2094 {
2095 case RedQuantum:
2096 case CyanQuantum:
2097 {
cristy4c08aed2011-07-01 19:47:50 +00002098 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002099 break;
2100 }
2101 case GreenQuantum:
2102 case MagentaQuantum:
2103 {
cristy4c08aed2011-07-01 19:47:50 +00002104 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002105 break;
2106 }
2107 case BlueQuantum:
2108 case YellowQuantum:
2109 {
cristy4c08aed2011-07-01 19:47:50 +00002110 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002111 break;
2112 }
2113 case AlphaQuantum:
2114 {
cristy4c08aed2011-07-01 19:47:50 +00002115 *q=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002116 break;
2117 }
2118 case OpacityQuantum:
2119 {
cristy4c08aed2011-07-01 19:47:50 +00002120 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002121 break;
2122 }
2123 case BlackQuantum:
2124 {
2125 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002126 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002127 break;
2128 }
2129 case IndexQuantum:
2130 {
cristyf13c5942012-08-08 23:50:11 +00002131 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002132 break;
2133 }
2134 default:
2135 break;
2136 }
2137 q++;
2138 }
2139 p++;
2140 }
2141 break;
2142 }
cristy100b8d92012-01-08 00:32:49 +00002143 case LongLongPixel:
2144 {
2145 register MagickSizeType
2146 *q;
2147
2148 q=(MagickSizeType *) stream_info->pixels;
2149 if (LocaleCompare(stream_info->map,"BGR") == 0)
2150 {
2151 p=GetVirtualPixelQueue(image);
2152 if (p == (const Quantum *) NULL)
2153 break;
2154 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2155 {
2156 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2157 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2158 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2159 p++;
2160 }
2161 break;
2162 }
2163 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2164 {
2165 p=GetVirtualPixelQueue(image);
2166 if (p == (const Quantum *) NULL)
2167 break;
2168 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2169 {
2170 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2171 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2172 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2173 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2174 p++;
2175 }
2176 break;
2177 }
2178 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2179 {
2180 p=GetVirtualPixelQueue(image);
2181 if (p == (const Quantum *) NULL)
2182 break;
2183 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2184 {
2185 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2186 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2187 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2188 *q++=0U;
2189 p++;
2190 }
2191 break;
2192 }
2193 if (LocaleCompare(stream_info->map,"I") == 0)
2194 {
2195 p=GetVirtualPixelQueue(image);
2196 if (p == (const Quantum *) NULL)
2197 break;
2198 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2199 {
cristyf13c5942012-08-08 23:50:11 +00002200 *q++=ScaleQuantumToLongLong(ClampToQuantum(
2201 GetPixelIntensity(image,p)));
cristy100b8d92012-01-08 00:32:49 +00002202 p++;
2203 }
2204 break;
2205 }
2206 if (LocaleCompare(stream_info->map,"RGB") == 0)
2207 {
2208 p=GetVirtualPixelQueue(image);
2209 if (p == (const Quantum *) NULL)
2210 break;
2211 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2212 {
2213 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2214 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2215 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2216 p++;
2217 }
2218 break;
2219 }
2220 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2221 {
2222 p=GetVirtualPixelQueue(image);
2223 if (p == (const Quantum *) NULL)
2224 break;
2225 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2226 {
2227 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2228 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2229 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2230 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2231 p++;
2232 }
2233 break;
2234 }
2235 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2236 {
2237 p=GetVirtualPixelQueue(image);
2238 if (p == (const Quantum *) NULL)
2239 break;
2240 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2241 {
2242 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2243 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2244 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2245 *q++=0U;
2246 p++;
2247 }
2248 break;
2249 }
2250 p=GetVirtualPixelQueue(image);
2251 if (p == (const Quantum *) NULL)
2252 break;
2253 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2254 {
2255 for (i=0; i < (ssize_t) length; i++)
2256 {
2257 *q=0;
2258 switch (quantum_map[i])
2259 {
2260 case RedQuantum:
2261 case CyanQuantum:
2262 {
2263 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
2264 break;
2265 }
2266 case GreenQuantum:
2267 case MagentaQuantum:
2268 {
2269 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2270 break;
2271 }
2272 case BlueQuantum:
2273 case YellowQuantum:
2274 {
2275 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2276 break;
2277 }
2278 case AlphaQuantum:
2279 {
2280 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2281 break;
2282 }
2283 case OpacityQuantum:
2284 {
2285 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2286 break;
2287 }
2288 case BlackQuantum:
2289 {
2290 if (image->colorspace == CMYKColorspace)
2291 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
2292 break;
2293 }
2294 case IndexQuantum:
2295 {
cristyf13c5942012-08-08 23:50:11 +00002296 *q=ScaleQuantumToLongLong(ClampToQuantum(
2297 GetPixelIntensity(image,p)));
cristy100b8d92012-01-08 00:32:49 +00002298 break;
2299 }
2300 default:
2301 *q=0;
2302 }
2303 q++;
2304 }
2305 p++;
2306 }
2307 break;
2308 }
cristy3ed852e2009-09-05 21:47:34 +00002309 case QuantumPixel:
2310 {
2311 register Quantum
2312 *q;
2313
2314 q=(Quantum *) stream_info->pixels;
2315 if (LocaleCompare(stream_info->map,"BGR") == 0)
2316 {
cristy100b8d92012-01-08 00:32:49 +00002317 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002318 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002319 break;
cristybb503372010-05-27 20:51:26 +00002320 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002321 {
cristy4c08aed2011-07-01 19:47:50 +00002322 *q++=GetPixelBlue(image,p);
2323 *q++=GetPixelGreen(image,p);
2324 *q++=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002325 p++;
2326 }
2327 break;
2328 }
2329 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2330 {
cristy100b8d92012-01-08 00:32:49 +00002331 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002332 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002333 break;
cristybb503372010-05-27 20:51:26 +00002334 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002335 {
cristy4c08aed2011-07-01 19:47:50 +00002336 *q++=GetPixelBlue(image,p);
2337 *q++=GetPixelGreen(image,p);
2338 *q++=GetPixelRed(image,p);
cristy100b8d92012-01-08 00:32:49 +00002339 *q++=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002340 p++;
2341 }
2342 break;
2343 }
2344 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2345 {
cristy100b8d92012-01-08 00:32:49 +00002346 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002347 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002348 break;
cristybb503372010-05-27 20:51:26 +00002349 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002350 {
cristy4c08aed2011-07-01 19:47:50 +00002351 *q++=GetPixelBlue(image,p);
2352 *q++=GetPixelGreen(image,p);
2353 *q++=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002354 *q++=0;
2355 p++;
2356 }
2357 break;
2358 }
2359 if (LocaleCompare(stream_info->map,"I") == 0)
2360 {
cristy100b8d92012-01-08 00:32:49 +00002361 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002362 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002363 break;
cristybb503372010-05-27 20:51:26 +00002364 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002365 {
cristyf13c5942012-08-08 23:50:11 +00002366 *q++=ClampToQuantum(GetPixelIntensity(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002367 p++;
2368 }
2369 break;
2370 }
2371 if (LocaleCompare(stream_info->map,"RGB") == 0)
2372 {
cristy100b8d92012-01-08 00:32:49 +00002373 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002374 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002375 break;
cristybb503372010-05-27 20:51:26 +00002376 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002377 {
cristy4c08aed2011-07-01 19:47:50 +00002378 *q++=GetPixelRed(image,p);
2379 *q++=GetPixelGreen(image,p);
2380 *q++=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002381 p++;
2382 }
2383 break;
2384 }
2385 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2386 {
cristy100b8d92012-01-08 00:32:49 +00002387 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002388 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002389 break;
cristybb503372010-05-27 20:51:26 +00002390 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002391 {
cristy4c08aed2011-07-01 19:47:50 +00002392 *q++=GetPixelRed(image,p);
2393 *q++=GetPixelGreen(image,p);
2394 *q++=GetPixelBlue(image,p);
cristy100b8d92012-01-08 00:32:49 +00002395 *q++=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002396 p++;
2397 }
2398 break;
2399 }
2400 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2401 {
cristy100b8d92012-01-08 00:32:49 +00002402 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002403 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002404 break;
cristybb503372010-05-27 20:51:26 +00002405 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002406 {
cristy4c08aed2011-07-01 19:47:50 +00002407 *q++=GetPixelRed(image,p);
2408 *q++=GetPixelGreen(image,p);
2409 *q++=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002410 *q++=0U;
2411 p++;
2412 }
2413 break;
2414 }
cristy100b8d92012-01-08 00:32:49 +00002415 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002416 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002417 break;
cristybb503372010-05-27 20:51:26 +00002418 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002419 {
cristybb503372010-05-27 20:51:26 +00002420 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002421 {
2422 *q=(Quantum) 0;
2423 switch (quantum_map[i])
2424 {
2425 case RedQuantum:
2426 case CyanQuantum:
2427 {
cristy4c08aed2011-07-01 19:47:50 +00002428 *q=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002429 break;
2430 }
2431 case GreenQuantum:
2432 case MagentaQuantum:
2433 {
cristy4c08aed2011-07-01 19:47:50 +00002434 *q=GetPixelGreen(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002435 break;
2436 }
2437 case BlueQuantum:
2438 case YellowQuantum:
2439 {
cristy4c08aed2011-07-01 19:47:50 +00002440 *q=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002441 break;
2442 }
2443 case AlphaQuantum:
2444 {
cristy4c08aed2011-07-01 19:47:50 +00002445 *q=(Quantum) (GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002446 break;
2447 }
2448 case OpacityQuantum:
2449 {
cristy4c08aed2011-07-01 19:47:50 +00002450 *q=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002451 break;
2452 }
2453 case BlackQuantum:
2454 {
2455 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002456 *q=GetPixelBlack(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002457 break;
2458 }
2459 case IndexQuantum:
2460 {
cristyf13c5942012-08-08 23:50:11 +00002461 *q=ClampToQuantum(GetPixelIntensity(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002462 break;
2463 }
2464 default:
2465 *q=0;
2466 }
2467 q++;
2468 }
2469 p++;
2470 }
2471 break;
2472 }
2473 case ShortPixel:
2474 {
2475 register unsigned short
2476 *q;
2477
2478 q=(unsigned short *) stream_info->pixels;
2479 if (LocaleCompare(stream_info->map,"BGR") == 0)
2480 {
cristy100b8d92012-01-08 00:32:49 +00002481 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002482 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002483 break;
cristybb503372010-05-27 20:51:26 +00002484 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002485 {
cristy4c08aed2011-07-01 19:47:50 +00002486 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2487 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2488 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002489 p++;
2490 }
2491 break;
2492 }
2493 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2494 {
cristy100b8d92012-01-08 00:32:49 +00002495 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002496 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002497 break;
cristybb503372010-05-27 20:51:26 +00002498 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002499 {
cristy4c08aed2011-07-01 19:47:50 +00002500 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2501 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2502 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2503 *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002504 p++;
2505 }
2506 break;
2507 }
2508 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2509 {
cristy100b8d92012-01-08 00:32:49 +00002510 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002511 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002512 break;
cristybb503372010-05-27 20:51:26 +00002513 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002514 {
cristy4c08aed2011-07-01 19:47:50 +00002515 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2516 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2517 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002518 *q++=0;
2519 p++;
2520 }
2521 break;
2522 }
2523 if (LocaleCompare(stream_info->map,"I") == 0)
2524 {
cristy100b8d92012-01-08 00:32:49 +00002525 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002526 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002527 break;
cristybb503372010-05-27 20:51:26 +00002528 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002529 {
cristyf13c5942012-08-08 23:50:11 +00002530 *q++=ScaleQuantumToShort(ClampToQuantum(
2531 GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002532 p++;
2533 }
2534 break;
2535 }
2536 if (LocaleCompare(stream_info->map,"RGB") == 0)
2537 {
cristy100b8d92012-01-08 00:32:49 +00002538 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002539 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002540 break;
cristybb503372010-05-27 20:51:26 +00002541 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002542 {
cristy4c08aed2011-07-01 19:47:50 +00002543 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2544 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2545 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002546 p++;
2547 }
2548 break;
2549 }
2550 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2551 {
cristy100b8d92012-01-08 00:32:49 +00002552 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002553 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002554 break;
cristybb503372010-05-27 20:51:26 +00002555 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002556 {
cristy4c08aed2011-07-01 19:47:50 +00002557 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2558 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2559 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2560 *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002561 p++;
2562 }
2563 break;
2564 }
2565 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2566 {
cristy100b8d92012-01-08 00:32:49 +00002567 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002568 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002569 break;
cristybb503372010-05-27 20:51:26 +00002570 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002571 {
cristy4c08aed2011-07-01 19:47:50 +00002572 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2573 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2574 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002575 *q++=0;
2576 p++;
2577 }
2578 break;
2579 }
cristy100b8d92012-01-08 00:32:49 +00002580 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002581 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002582 break;
cristybb503372010-05-27 20:51:26 +00002583 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002584 {
cristybb503372010-05-27 20:51:26 +00002585 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002586 {
2587 *q=0;
2588 switch (quantum_map[i])
2589 {
2590 case RedQuantum:
2591 case CyanQuantum:
2592 {
cristy4c08aed2011-07-01 19:47:50 +00002593 *q=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002594 break;
2595 }
2596 case GreenQuantum:
2597 case MagentaQuantum:
2598 {
cristy4c08aed2011-07-01 19:47:50 +00002599 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002600 break;
2601 }
2602 case BlueQuantum:
2603 case YellowQuantum:
2604 {
cristy4c08aed2011-07-01 19:47:50 +00002605 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002606 break;
2607 }
2608 case AlphaQuantum:
2609 {
cristy4c08aed2011-07-01 19:47:50 +00002610 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002611 break;
2612 }
2613 case OpacityQuantum:
2614 {
cristy4c08aed2011-07-01 19:47:50 +00002615 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002616 break;
2617 }
2618 case BlackQuantum:
2619 {
2620 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002621 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002622 break;
2623 }
2624 case IndexQuantum:
2625 {
cristyf13c5942012-08-08 23:50:11 +00002626 *q=ScaleQuantumToShort(ClampToQuantum(
2627 GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002628 break;
2629 }
2630 default:
2631 break;
2632 }
2633 q++;
2634 }
2635 p++;
2636 }
2637 break;
2638 }
2639 default:
2640 {
2641 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2642 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristy20cc0872012-08-20 00:01:19 +00002643 "UnrecognizedPixelMap","'%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00002644 break;
2645 }
2646 }
2647 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2648 return(MagickTrue);
2649}
2650
2651/*
2652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2653% %
2654% %
2655% %
2656+ 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 %
2657% %
2658% %
2659% %
2660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2661%
2662% SyncAuthenticPixelsStream() calls the user supplied callback method with
2663% the latest stream of pixels.
2664%
2665% The format of the SyncAuthenticPixelsStream method is:
2666%
2667% MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2668% ExceptionInfo *exception)
2669%
2670% A description of each parameter follows:
2671%
2672% o image: the image.
2673%
2674% o exception: return any errors or warnings in this structure.
2675%
2676*/
2677static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2678 ExceptionInfo *exception)
2679{
2680 CacheInfo
2681 *cache_info;
2682
2683 size_t
2684 length;
2685
2686 StreamHandler
2687 stream_handler;
2688
2689 assert(image != (Image *) NULL);
2690 assert(image->signature == MagickSignature);
2691 if (image->debug != MagickFalse)
2692 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2693 cache_info=(CacheInfo *) image->cache;
2694 assert(cache_info->signature == MagickSignature);
2695 stream_handler=GetBlobStreamHandler(image);
2696 if (stream_handler == (StreamHandler) NULL)
2697 {
2698 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy20cc0872012-08-20 00:01:19 +00002699 "NoStreamHandlerIsDefined","'%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +00002700 return(MagickFalse);
2701 }
2702 length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
2703 return(length == cache_info->columns ? MagickTrue : MagickFalse);
2704}
2705
2706/*
2707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2708% %
2709% %
2710% %
2711% W r i t e S t r e a m %
2712% %
2713% %
2714% %
2715%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2716%
2717% WriteStream() makes the image pixels available to a user supplied callback
2718% method immediately upon writing pixel data with the WriteImage() method.
2719%
2720% The format of the WriteStream() method is:
2721%
2722% MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
cristyc82a27b2011-10-21 01:07:16 +00002723% StreamHandler stream,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002724%
2725% A description of each parameter follows:
2726%
2727% o image_info: the image info.
2728%
2729% o stream: A callback method.
2730%
cristyc82a27b2011-10-21 01:07:16 +00002731% o exception: return any errors or warnings in this structure.
2732%
cristy3ed852e2009-09-05 21:47:34 +00002733*/
2734MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
cristyc82a27b2011-10-21 01:07:16 +00002735 Image *image,StreamHandler stream,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002736{
2737 ImageInfo
2738 *write_info;
2739
2740 MagickBooleanType
2741 status;
2742
2743 assert(image_info != (ImageInfo *) NULL);
2744 assert(image_info->signature == MagickSignature);
2745 if (image_info->debug != MagickFalse)
2746 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2747 image_info->filename);
2748 assert(image != (Image *) NULL);
2749 assert(image->signature == MagickSignature);
2750 write_info=CloneImageInfo(image_info);
2751 write_info->stream=stream;
cristyc82a27b2011-10-21 01:07:16 +00002752 status=WriteImage(write_info,image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002753 write_info=DestroyImageInfo(write_info);
2754 return(status);
2755}