blob: 2c0453b51957b0de9b83eb8c18700c7af4100a06 [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%
cristy4c08aed2011-07-01 19:47:50 +0000622% GetVirtualMetacontentFromStream() returns the associated pixel
623% channels corresponding with the last call to QueueAuthenticPixelsStream() or
624% 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*/
cristy4c08aed2011-07-01 19:47:50 +0000635static const void *GetVirtualMetacontentFromStream(
636 const Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000637{
638 CacheInfo
639 *cache_info;
640
641 assert(image != (Image *) NULL);
642 assert(image->signature == MagickSignature);
643 if (image->debug != MagickFalse)
644 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
645 cache_info=(CacheInfo *) image->cache;
646 assert(cache_info->signature == MagickSignature);
cristy4c08aed2011-07-01 19:47:50 +0000647 return(cache_info->metacontent);
cristy3ed852e2009-09-05 21:47:34 +0000648}
649
650/*
651%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652% %
653% %
654% %
655+ G e t V i r t u a l P i x e l S t r e a m %
656% %
657% %
658% %
659%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660%
661% GetVirtualPixelStream() gets pixels from the in-memory or disk pixel cache as
662% defined by the geometry parameters. A pointer to the pixels is returned if
663% the pixels are transferred, otherwise a NULL is returned. For streams this
664% method is a no-op.
665%
666% The format of the GetVirtualPixelStream() method is:
667%
cristy4c08aed2011-07-01 19:47:50 +0000668% const Quantum *GetVirtualPixelStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000669% const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
670% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000671% ExceptionInfo *exception)
672%
673% A description of each parameter follows:
674%
675% o image: the image.
676%
677% o virtual_pixel_method: the virtual pixel method.
678%
679% o x,y,columns,rows: These values define the perimeter of a region of
680% pixels.
681%
682% o exception: return any errors or warnings in this structure.
683%
684*/
685
686static inline MagickBooleanType AcquireStreamPixels(CacheInfo *cache_info,
687 ExceptionInfo *exception)
688{
689 if (cache_info->length != (MagickSizeType) ((size_t) cache_info->length))
690 return(MagickFalse);
691 cache_info->mapped=MagickFalse;
cristy39c2e212012-08-18 18:14:34 +0000692 cache_info->pixels=(Quantum *) AcquireAlignedMemory(1,(size_t)
cristy3ed852e2009-09-05 21:47:34 +0000693 cache_info->length);
cristy4c08aed2011-07-01 19:47:50 +0000694 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000695 {
696 cache_info->mapped=MagickTrue;
cristy4c08aed2011-07-01 19:47:50 +0000697 cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
cristy3ed852e2009-09-05 21:47:34 +0000698 cache_info->length);
699 }
cristy4c08aed2011-07-01 19:47:50 +0000700 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000701 {
702 (void) ThrowMagickException(exception,GetMagickModule(),
cristy39c2e212012-08-18 18:14:34 +0000703 ResourceLimitError,"MemoryAllocationFailed","`%s'",
cristy3ed852e2009-09-05 21:47:34 +0000704 cache_info->filename);
705 return(MagickFalse);
706 }
707 return(MagickTrue);
708}
709
cristy4c08aed2011-07-01 19:47:50 +0000710static const Quantum *GetVirtualPixelStream(const Image *image,
cristybb503372010-05-27 20:51:26 +0000711 const VirtualPixelMethod magick_unused(virtual_pixel_method),const ssize_t x,
712 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000713 ExceptionInfo *exception)
714{
715 CacheInfo
716 *cache_info;
717
718 MagickBooleanType
719 status;
720
721 MagickSizeType
722 number_pixels;
723
724 size_t
725 length;
726
727 /*
728 Validate pixel cache geometry.
729 */
730 assert(image != (const Image *) NULL);
731 assert(image->signature == MagickSignature);
732 if (image->debug != MagickFalse)
733 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy5dd71882010-08-01 20:53:13 +0000734 if ((x < 0) || (y < 0) ||
735 ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
736 ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
737 (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000738 {
739 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy39c2e212012-08-18 18:14:34 +0000740 "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000741 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000742 }
743 cache_info=(CacheInfo *) image->cache;
744 assert(cache_info->signature == MagickSignature);
745 /*
746 Pixels are stored in a temporary buffer until they are synced to the cache.
747 */
748 number_pixels=(MagickSizeType) columns*rows;
cristyed231572011-07-14 02:18:59 +0000749 length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
cristy4c08aed2011-07-01 19:47:50 +0000750 if (cache_info->metacontent_extent != 0)
751 length+=number_pixels*cache_info->metacontent_extent;
752 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000753 {
754 cache_info->length=length;
755 status=AcquireStreamPixels(cache_info,exception);
756 if (status == MagickFalse)
cristy33503f52010-10-04 17:32:27 +0000757 {
758 cache_info->length=0;
cristy4c08aed2011-07-01 19:47:50 +0000759 return((Quantum *) NULL);
cristy33503f52010-10-04 17:32:27 +0000760 }
cristy3ed852e2009-09-05 21:47:34 +0000761 }
762 else
763 if (cache_info->length != length)
764 {
765 RelinquishStreamPixels(cache_info);
766 cache_info->length=length;
767 status=AcquireStreamPixels(cache_info,exception);
768 if (status == MagickFalse)
cristy33503f52010-10-04 17:32:27 +0000769 {
770 cache_info->length=0;
cristy4c08aed2011-07-01 19:47:50 +0000771 return((Quantum *) NULL);
cristy33503f52010-10-04 17:32:27 +0000772 }
cristy3ed852e2009-09-05 21:47:34 +0000773 }
cristy4c08aed2011-07-01 19:47:50 +0000774 cache_info->metacontent=(void *) NULL;
775 if (cache_info->metacontent_extent != 0)
776 cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
cristyed231572011-07-14 02:18:59 +0000777 cache_info->number_channels);
cristy3ed852e2009-09-05 21:47:34 +0000778 return(cache_info->pixels);
779}
780
781/*
782%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783% %
784% %
785% %
786+ O p e n S t r e a m %
787% %
788% %
789% %
790%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791%
792% OpenStream() opens a stream for writing by the StreamImage() method.
793%
794% The format of the OpenStream method is:
795%
796% MagickBooleanType OpenStream(const ImageInfo *image_info,
797% StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
798%
799% A description of each parameter follows:
800%
801% o image_info: the image info.
802%
803% o stream_info: the stream info.
804%
805% o filename: the stream filename.
806%
807% o exception: return any errors or warnings in this structure.
808%
809*/
810MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
811 StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
812{
813 MagickBooleanType
814 status;
815
816 (void) CopyMagickString(stream_info->stream->filename,filename,MaxTextExtent);
817 status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
818 return(status);
819}
820
821/*
822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823% %
824% %
825% %
826+ 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 %
827% %
828% %
829% %
830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831%
832% QueueAuthenticPixelsStream() allocates an area to store image pixels as
833% defined by the region rectangle and returns a pointer to the area. This
834% area is subsequently transferred from the pixel cache with method
835% SyncAuthenticPixelsStream(). A pointer to the pixels is returned if the
836% pixels are transferred, otherwise a NULL is returned.
837%
838% The format of the QueueAuthenticPixelsStream() method is:
839%
cristy4c08aed2011-07-01 19:47:50 +0000840% Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000841% const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000842% ExceptionInfo *exception)
843%
844% A description of each parameter follows:
845%
846% o image: the image.
847%
848% o x,y,columns,rows: These values define the perimeter of a region of
849% pixels.
850%
851*/
cristy4c08aed2011-07-01 19:47:50 +0000852static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
cristybb503372010-05-27 20:51:26 +0000853 const ssize_t y,const size_t columns,const size_t rows,
cristy3ed852e2009-09-05 21:47:34 +0000854 ExceptionInfo *exception)
855{
856 CacheInfo
857 *cache_info;
858
859 MagickSizeType
860 number_pixels;
861
862 size_t
863 length;
864
865 StreamHandler
866 stream_handler;
867
868 /*
869 Validate pixel cache geometry.
870 */
871 assert(image != (Image *) NULL);
cristycfae90a2010-10-04 14:43:33 +0000872 if ((x < 0) || (y < 0) ||
873 ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
874 ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
875 (columns == 0) || (rows == 0))
cristy3ed852e2009-09-05 21:47:34 +0000876 {
877 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy39c2e212012-08-18 18:14:34 +0000878 "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000879 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000880 }
881 stream_handler=GetBlobStreamHandler(image);
882 if (stream_handler == (StreamHandler) NULL)
883 {
884 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy39c2e212012-08-18 18:14:34 +0000885 "NoStreamHandlerIsDefined","`%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +0000886 return((Quantum *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000887 }
888 cache_info=(CacheInfo *) image->cache;
889 assert(cache_info->signature == MagickSignature);
890 if ((image->storage_class != GetPixelCacheStorageClass(image->cache)) ||
891 (image->colorspace != GetPixelCacheColorspace(image->cache)))
892 {
893 if (GetPixelCacheStorageClass(image->cache) == UndefinedClass)
894 (void) stream_handler(image,(const void *) NULL,(size_t)
895 cache_info->columns);
896 cache_info->storage_class=image->storage_class;
897 cache_info->colorspace=image->colorspace;
898 cache_info->columns=image->columns;
899 cache_info->rows=image->rows;
900 image->cache=cache_info;
901 }
902 /*
903 Pixels are stored in a temporary buffer until they are synced to the cache.
904 */
905 cache_info->columns=columns;
906 cache_info->rows=rows;
907 number_pixels=(MagickSizeType) columns*rows;
cristyed231572011-07-14 02:18:59 +0000908 length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
cristy4c08aed2011-07-01 19:47:50 +0000909 if (cache_info->metacontent_extent != 0)
910 length+=number_pixels*cache_info->metacontent_extent;
911 if (cache_info->pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000912 {
cristy39c2e212012-08-18 18:14:34 +0000913 cache_info->pixels=(Quantum *) AcquireAlignedMemory(1,length);
cristy3ed852e2009-09-05 21:47:34 +0000914 cache_info->length=(MagickSizeType) length;
915 }
916 else
917 if (cache_info->length < (MagickSizeType) length)
918 {
cristy39c2e212012-08-18 18:14:34 +0000919 (void) RelinquishAlignedMemory(cache_info->pixels);
920 cache_info->pixels=(Quantum *) AcquireAlignedMemory(1,length);
cristy3ed852e2009-09-05 21:47:34 +0000921 cache_info->length=(MagickSizeType) length;
922 }
923 if (cache_info->pixels == (void *) NULL)
cristy4c08aed2011-07-01 19:47:50 +0000924 return((Quantum *) NULL);
925 cache_info->metacontent=(void *) NULL;
926 if (cache_info->metacontent_extent != 0)
927 cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
cristyed231572011-07-14 02:18:59 +0000928 cache_info->number_channels);
cristy3ed852e2009-09-05 21:47:34 +0000929 return(cache_info->pixels);
930}
931
932/*
933%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
934% %
935% %
936% %
937% R e a d S t r e a m %
938% %
939% %
940% %
941%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942%
943% ReadStream() makes the image pixels available to a user supplied callback
944% method immediately upon reading a scanline with the ReadImage() method.
945%
946% The format of the ReadStream() method is:
947%
948% Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
949% ExceptionInfo *exception)
950%
951% A description of each parameter follows:
952%
953% o image_info: the image info.
954%
955% o stream: a callback method.
956%
957% o exception: return any errors or warnings in this structure.
958%
959*/
960MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
961 ExceptionInfo *exception)
962{
963 CacheMethods
964 cache_methods;
965
966 Image
967 *image;
968
969 ImageInfo
970 *read_info;
971
972 /*
973 Stream image pixels.
974 */
975 assert(image_info != (ImageInfo *) NULL);
976 assert(image_info->signature == MagickSignature);
977 if (image_info->debug != MagickFalse)
978 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
979 image_info->filename);
980 assert(exception != (ExceptionInfo *) NULL);
981 assert(exception->signature == MagickSignature);
982 read_info=CloneImageInfo(image_info);
983 read_info->cache=AcquirePixelCache(0);
984 GetPixelCacheMethods(&cache_methods);
985 cache_methods.get_virtual_pixel_handler=GetVirtualPixelStream;
cristy4c08aed2011-07-01 19:47:50 +0000986 cache_methods.get_virtual_metacontent_from_handler=
987 GetVirtualMetacontentFromStream;
cristy3ed852e2009-09-05 21:47:34 +0000988 cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
989 cache_methods.get_authentic_pixels_handler=GetAuthenticPixelsStream;
990 cache_methods.queue_authentic_pixels_handler=QueueAuthenticPixelsStream;
991 cache_methods.sync_authentic_pixels_handler=SyncAuthenticPixelsStream;
992 cache_methods.get_authentic_pixels_from_handler=GetAuthenticPixelsFromStream;
cristy4c08aed2011-07-01 19:47:50 +0000993 cache_methods.get_authentic_metacontent_from_handler=
994 GetAuthenticMetacontentFromStream;
cristy3ed852e2009-09-05 21:47:34 +0000995 cache_methods.get_one_virtual_pixel_from_handler=GetOneVirtualPixelFromStream;
996 cache_methods.get_one_authentic_pixel_from_handler=
997 GetOneAuthenticPixelFromStream;
998 cache_methods.destroy_pixel_handler=DestroyPixelStream;
999 SetPixelCacheMethods(read_info->cache,&cache_methods);
1000 read_info->stream=stream;
1001 image=ReadImage(read_info,exception);
1002 read_info=DestroyImageInfo(read_info);
1003 return(image);
1004}
1005
1006/*
1007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008% %
1009% %
1010% %
1011+ S e t S t r e a m I n f o C l i e n t D a t a %
1012% %
1013% %
1014% %
1015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1016%
1017% SetStreamInfoClientData() sets the stream info client data.
1018%
1019% The format of the SetStreamInfoClientData method is:
1020%
1021% void SetStreamInfoClientData(StreamInfo *stream_info,
1022% const void *client_data)
1023%
1024% A description of each parameter follows:
1025%
1026% o stream_info: the stream info.
1027%
1028% o client_data: the client data.
1029%
1030*/
cristy7832dc22011-09-05 01:21:53 +00001031MagickPrivate void SetStreamInfoClientData(StreamInfo *stream_info,
cristy3ed852e2009-09-05 21:47:34 +00001032 const void *client_data)
1033{
1034 assert(stream_info != (StreamInfo *) NULL);
1035 assert(stream_info->signature == MagickSignature);
1036 stream_info->client_data=client_data;
1037}
1038
1039/*
1040%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1041% %
1042% %
1043% %
1044+ S e t S t r e a m I n f o M a p %
1045% %
1046% %
1047% %
1048%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049%
1050% SetStreamInfoMap() sets the stream info map member.
1051%
1052% The format of the SetStreamInfoMap method is:
1053%
1054% void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1055%
1056% A description of each parameter follows:
1057%
1058% o stream_info: the stream info.
1059%
1060% o map: the map.
1061%
1062*/
1063MagickExport void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1064{
1065 assert(stream_info != (StreamInfo *) NULL);
1066 assert(stream_info->signature == MagickSignature);
1067 (void) CloneString(&stream_info->map,map);
1068}
1069
1070/*
1071%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1072% %
1073% %
1074% %
1075+ S e t S t r e a m I n f o S t o r a g e T y p e %
1076% %
1077% %
1078% %
1079%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080%
1081% SetStreamInfoStorageType() sets the stream info storage type member.
1082%
1083% The format of the SetStreamInfoStorageType method is:
1084%
1085% void SetStreamInfoStorageType(StreamInfo *stream_info,
1086% const StoreageType *storage_type)
1087%
1088% A description of each parameter follows:
1089%
1090% o stream_info: the stream info.
1091%
1092% o storage_type: the storage type.
1093%
1094*/
1095MagickExport void SetStreamInfoStorageType(StreamInfo *stream_info,
1096 const StorageType storage_type)
1097{
1098 assert(stream_info != (StreamInfo *) NULL);
1099 assert(stream_info->signature == MagickSignature);
1100 stream_info->storage_type=storage_type;
1101}
1102
1103/*
1104%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1105% %
1106% %
1107% %
1108+ S t r e a m I m a g e %
1109% %
1110% %
1111% %
1112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1113%
1114% StreamImage() streams pixels from an image and writes them in a user
1115% defined format and storage type (e.g. RGBA as 8-bit unsigned char).
1116%
cristyd212bd02011-02-13 17:08:57 +00001117% The format of the StreamImage() method is:
cristy3ed852e2009-09-05 21:47:34 +00001118%
1119% Image *StreamImage(const ImageInfo *image_info,
1120% StreamInfo *stream_info,ExceptionInfo *exception)
1121%
1122% A description of each parameter follows:
1123%
1124% o image_info: the image info.
1125%
1126% o stream_info: the stream info.
1127%
1128% o exception: return any errors or warnings in this structure.
1129%
1130*/
1131
1132#if defined(__cplusplus) || defined(c_plusplus)
1133extern "C" {
1134#endif
1135
1136static size_t WriteStreamImage(const Image *image,const void *pixels,
1137 const size_t columns)
1138{
cristye3664f42010-05-14 00:59:57 +00001139 CacheInfo
1140 *cache_info;
1141
cristy3ed852e2009-09-05 21:47:34 +00001142 RectangleInfo
1143 extract_info;
1144
1145 size_t
1146 length,
1147 packet_size;
1148
1149 ssize_t
1150 count;
1151
1152 StreamInfo
1153 *stream_info;
1154
cristy654fdaf2011-02-24 15:24:33 +00001155 (void) pixels;
cristy3ed852e2009-09-05 21:47:34 +00001156 stream_info=(StreamInfo *) image->client_data;
1157 switch (stream_info->storage_type)
1158 {
cristy100b8d92012-01-08 00:32:49 +00001159 default: packet_size=sizeof(unsigned char); break;
1160 case CharPixel: packet_size=sizeof(unsigned char); break;
cristy3ed852e2009-09-05 21:47:34 +00001161 case DoublePixel: packet_size=sizeof(double); break;
1162 case FloatPixel: packet_size=sizeof(float); break;
cristy100b8d92012-01-08 00:32:49 +00001163 case LongPixel: packet_size=sizeof(unsigned int); break;
1164 case LongLongPixel: packet_size=sizeof(MagickSizeType); break;
cristy3ed852e2009-09-05 21:47:34 +00001165 case QuantumPixel: packet_size=sizeof(Quantum); break;
1166 case ShortPixel: packet_size=sizeof(unsigned short); break;
1167 }
cristye3664f42010-05-14 00:59:57 +00001168 cache_info=(CacheInfo *) image->cache;
1169 assert(cache_info->signature == MagickSignature);
cristy3ed852e2009-09-05 21:47:34 +00001170 packet_size*=strlen(stream_info->map);
cristye3664f42010-05-14 00:59:57 +00001171 length=packet_size*cache_info->columns*cache_info->rows;
cristy3ed852e2009-09-05 21:47:34 +00001172 if (image != stream_info->image)
1173 {
1174 ImageInfo
1175 *write_info;
1176
1177 /*
1178 Prepare stream for writing.
1179 */
cristy39c2e212012-08-18 18:14:34 +00001180 (void) RelinquishAlignedMemory(stream_info->pixels);
1181 stream_info->pixels=(unsigned char *) AcquireAlignedMemory(length,
1182 sizeof(*stream_info->pixels));
cristy5dd71882010-08-01 20:53:13 +00001183 if (stream_info->pixels == (unsigned char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001184 return(0);
cristy39c2e212012-08-18 18:14:34 +00001185 (void) ResetMagickMemory(stream_info->pixels,0,length);
cristy3ed852e2009-09-05 21:47:34 +00001186 stream_info->image=image;
1187 write_info=CloneImageInfo(stream_info->image_info);
cristyd965a422010-03-03 17:47:35 +00001188 (void) SetImageInfo(write_info,1,stream_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001189 if (write_info->extract != (char *) NULL)
1190 (void) ParseAbsoluteGeometry(write_info->extract,
1191 &stream_info->extract_info);
1192 stream_info->y=0;
1193 write_info=DestroyImageInfo(write_info);
1194 }
1195 extract_info=stream_info->extract_info;
cristyd212bd02011-02-13 17:08:57 +00001196 if ((extract_info.width == 0) || (extract_info.height == 0))
cristy3ed852e2009-09-05 21:47:34 +00001197 {
1198 /*
1199 Write all pixels to stream.
1200 */
1201 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1202 count=WriteBlob(stream_info->stream,length,stream_info->pixels);
1203 stream_info->y++;
1204 return(count == 0 ? 0 : columns);
1205 }
1206 if ((stream_info->y < extract_info.y) ||
cristybb503372010-05-27 20:51:26 +00001207 (stream_info->y >= (ssize_t) (extract_info.y+extract_info.height)))
cristy3ed852e2009-09-05 21:47:34 +00001208 {
1209 stream_info->y++;
1210 return(columns);
1211 }
1212 /*
1213 Write a portion of the pixel row to the stream.
1214 */
1215 (void) StreamImagePixels(stream_info,image,stream_info->exception);
1216 length=packet_size*extract_info.width;
cristy5dd71882010-08-01 20:53:13 +00001217 count=WriteBlob(stream_info->stream,length,stream_info->pixels+packet_size*
1218 extract_info.x);
cristy3ed852e2009-09-05 21:47:34 +00001219 stream_info->y++;
1220 return(count == 0 ? 0 : columns);
1221}
1222
1223#if defined(__cplusplus) || defined(c_plusplus)
1224}
1225#endif
1226
1227MagickExport Image *StreamImage(const ImageInfo *image_info,
1228 StreamInfo *stream_info,ExceptionInfo *exception)
1229{
1230 Image
1231 *image;
1232
1233 ImageInfo
1234 *read_info;
1235
1236 assert(image_info != (const ImageInfo *) NULL);
1237 assert(image_info->signature == MagickSignature);
1238 if (image_info->debug != MagickFalse)
1239 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1240 image_info->filename);
1241 assert(stream_info != (StreamInfo *) NULL);
1242 assert(stream_info->signature == MagickSignature);
1243 assert(exception != (ExceptionInfo *) NULL);
1244 read_info=CloneImageInfo(image_info);
1245 stream_info->image_info=image_info;
1246 stream_info->exception=exception;
1247 read_info->client_data=(void *) stream_info;
1248 image=ReadStream(read_info,&WriteStreamImage,exception);
1249 read_info=DestroyImageInfo(read_info);
1250 stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
1251 if (stream_info->quantum_info == (QuantumInfo *) NULL)
1252 image=DestroyImage(image);
1253 return(image);
1254}
1255
1256/*
1257%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1258% %
1259% %
1260% %
1261+ S t r e a m I m a g e P i x e l s %
1262% %
1263% %
1264% %
1265%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1266%
1267% StreamImagePixels() extracts pixel data from an image and returns it in the
1268% stream_info->pixels structure in the format as defined by
1269% stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
1270%
1271% The format of the StreamImagePixels method is:
1272%
1273% MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1274% const Image *image,ExceptionInfo *exception)
1275%
1276% A description of each parameter follows:
1277%
1278% o stream_info: the stream info.
1279%
1280% o image: the image.
1281%
1282% o exception: return any errors or warnings in this structure.
1283%
1284*/
1285static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1286 const Image *image,ExceptionInfo *exception)
1287{
1288 QuantumInfo
1289 *quantum_info;
1290
1291 QuantumType
1292 *quantum_map;
1293
cristy4c08aed2011-07-01 19:47:50 +00001294 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +00001295 *p;
1296
cristyd212bd02011-02-13 17:08:57 +00001297 register ssize_t
1298 i,
1299 x;
1300
cristy3ed852e2009-09-05 21:47:34 +00001301 size_t
1302 length;
1303
1304 assert(stream_info != (StreamInfo *) NULL);
1305 assert(stream_info->signature == MagickSignature);
1306 assert(image != (Image *) NULL);
1307 assert(image->signature == MagickSignature);
1308 if (image->debug != MagickFalse)
1309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1310 length=strlen(stream_info->map);
1311 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1312 if (quantum_map == (QuantumType *) NULL)
1313 {
1314 (void) ThrowMagickException(exception,GetMagickModule(),
cristy39c2e212012-08-18 18:14:34 +00001315 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +00001316 return(MagickFalse);
1317 }
cristybb503372010-05-27 20:51:26 +00001318 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001319 {
1320 switch (stream_info->map[i])
1321 {
1322 case 'A':
1323 case 'a':
1324 {
1325 quantum_map[i]=AlphaQuantum;
1326 break;
1327 }
1328 case 'B':
1329 case 'b':
1330 {
1331 quantum_map[i]=BlueQuantum;
1332 break;
1333 }
1334 case 'C':
1335 case 'c':
1336 {
1337 quantum_map[i]=CyanQuantum;
1338 if (image->colorspace == CMYKColorspace)
1339 break;
1340 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1341 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy39c2e212012-08-18 18:14:34 +00001342 "ColorSeparatedImageRequired","`%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001343 return(MagickFalse);
1344 }
1345 case 'g':
1346 case 'G':
1347 {
1348 quantum_map[i]=GreenQuantum;
1349 break;
1350 }
1351 case 'I':
1352 case 'i':
1353 {
1354 quantum_map[i]=IndexQuantum;
1355 break;
1356 }
1357 case 'K':
1358 case 'k':
1359 {
1360 quantum_map[i]=BlackQuantum;
1361 if (image->colorspace == CMYKColorspace)
1362 break;
1363 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1364 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy39c2e212012-08-18 18:14:34 +00001365 "ColorSeparatedImageRequired","`%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001366 return(MagickFalse);
1367 }
1368 case 'M':
1369 case 'm':
1370 {
1371 quantum_map[i]=MagentaQuantum;
1372 if (image->colorspace == CMYKColorspace)
1373 break;
1374 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1375 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy39c2e212012-08-18 18:14:34 +00001376 "ColorSeparatedImageRequired","`%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001377 return(MagickFalse);
1378 }
1379 case 'o':
1380 case 'O':
1381 {
1382 quantum_map[i]=OpacityQuantum;
1383 break;
1384 }
1385 case 'P':
1386 case 'p':
1387 {
1388 quantum_map[i]=UndefinedQuantum;
1389 break;
1390 }
1391 case 'R':
1392 case 'r':
1393 {
1394 quantum_map[i]=RedQuantum;
1395 break;
1396 }
1397 case 'Y':
1398 case 'y':
1399 {
1400 quantum_map[i]=YellowQuantum;
1401 if (image->colorspace == CMYKColorspace)
1402 break;
1403 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1404 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristy39c2e212012-08-18 18:14:34 +00001405 "ColorSeparatedImageRequired","`%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001406 return(MagickFalse);
1407 }
1408 default:
1409 {
1410 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1411 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristy39c2e212012-08-18 18:14:34 +00001412 "UnrecognizedPixelMap","`%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00001413 return(MagickFalse);
1414 }
1415 }
1416 }
1417 quantum_info=stream_info->quantum_info;
1418 switch (stream_info->storage_type)
1419 {
1420 case CharPixel:
1421 {
1422 register unsigned char
1423 *q;
1424
1425 q=(unsigned char *) stream_info->pixels;
1426 if (LocaleCompare(stream_info->map,"BGR") == 0)
1427 {
cristy100b8d92012-01-08 00:32:49 +00001428 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001429 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001430 break;
cristybb503372010-05-27 20:51:26 +00001431 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001432 {
cristy4c08aed2011-07-01 19:47:50 +00001433 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1434 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1435 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001436 p++;
1437 }
1438 break;
1439 }
1440 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1441 {
cristy100b8d92012-01-08 00:32:49 +00001442 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001443 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001444 break;
cristybb503372010-05-27 20:51:26 +00001445 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001446 {
cristy4c08aed2011-07-01 19:47:50 +00001447 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1448 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1449 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1450 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001451 p++;
1452 }
1453 break;
1454 }
1455 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1456 {
cristy100b8d92012-01-08 00:32:49 +00001457 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001458 if (p == (const Quantum *) NULL)
cristy100b8d92012-01-08 00:32:49 +00001459 break;
cristybb503372010-05-27 20:51:26 +00001460 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001461 {
cristy4c08aed2011-07-01 19:47:50 +00001462 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1463 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1464 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001465 *q++=ScaleQuantumToChar((Quantum) 0);
1466 p++;
1467 }
1468 break;
1469 }
1470 if (LocaleCompare(stream_info->map,"I") == 0)
1471 {
cristy100b8d92012-01-08 00:32:49 +00001472 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001473 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001474 break;
cristybb503372010-05-27 20:51:26 +00001475 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001476 {
cristyf13c5942012-08-08 23:50:11 +00001477 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001478 p++;
1479 }
1480 break;
1481 }
1482 if (LocaleCompare(stream_info->map,"RGB") == 0)
1483 {
cristy100b8d92012-01-08 00:32:49 +00001484 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001485 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001486 break;
cristybb503372010-05-27 20:51:26 +00001487 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001488 {
cristy4c08aed2011-07-01 19:47:50 +00001489 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1490 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1491 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001492 p++;
1493 }
1494 break;
1495 }
1496 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1497 {
cristy100b8d92012-01-08 00:32:49 +00001498 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001499 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001500 break;
cristybb503372010-05-27 20:51:26 +00001501 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001502 {
cristy4c08aed2011-07-01 19:47:50 +00001503 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1504 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1505 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1506 *q++=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001507 p++;
1508 }
1509 break;
1510 }
1511 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1512 {
cristy100b8d92012-01-08 00:32:49 +00001513 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001514 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001515 break;
cristybb503372010-05-27 20:51:26 +00001516 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001517 {
cristy4c08aed2011-07-01 19:47:50 +00001518 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1519 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1520 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001521 *q++=ScaleQuantumToChar((Quantum) 0);
1522 p++;
1523 }
1524 break;
1525 }
cristy100b8d92012-01-08 00:32:49 +00001526 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001527 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001528 break;
cristybb503372010-05-27 20:51:26 +00001529 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001530 {
cristybb503372010-05-27 20:51:26 +00001531 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001532 {
1533 *q=0;
1534 switch (quantum_map[i])
1535 {
1536 case RedQuantum:
1537 case CyanQuantum:
1538 {
cristy4c08aed2011-07-01 19:47:50 +00001539 *q=ScaleQuantumToChar(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001540 break;
1541 }
1542 case GreenQuantum:
1543 case MagentaQuantum:
1544 {
cristy4c08aed2011-07-01 19:47:50 +00001545 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001546 break;
1547 }
1548 case BlueQuantum:
1549 case YellowQuantum:
1550 {
cristy4c08aed2011-07-01 19:47:50 +00001551 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001552 break;
1553 }
1554 case AlphaQuantum:
1555 {
cristy4c08aed2011-07-01 19:47:50 +00001556 *q=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001557 break;
1558 }
1559 case OpacityQuantum:
1560 {
cristy4c08aed2011-07-01 19:47:50 +00001561 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001562 break;
1563 }
1564 case BlackQuantum:
1565 {
1566 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001567 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001568 break;
1569 }
1570 case IndexQuantum:
1571 {
cristyf13c5942012-08-08 23:50:11 +00001572 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001573 break;
1574 }
1575 default:
1576 break;
1577 }
1578 q++;
1579 }
1580 p++;
1581 }
1582 break;
1583 }
1584 case DoublePixel:
1585 {
1586 register double
1587 *q;
1588
1589 q=(double *) stream_info->pixels;
1590 if (LocaleCompare(stream_info->map,"BGR") == 0)
1591 {
cristy100b8d92012-01-08 00:32:49 +00001592 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001593 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001594 break;
cristybb503372010-05-27 20:51:26 +00001595 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001596 {
cristy4c08aed2011-07-01 19:47:50 +00001597 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001598 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001599 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001600 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001601 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001602 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001603 p++;
1604 }
1605 break;
1606 }
1607 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1608 {
cristy100b8d92012-01-08 00:32:49 +00001609 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001610 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001611 break;
cristybb503372010-05-27 20:51:26 +00001612 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001613 {
cristy4c08aed2011-07-01 19:47:50 +00001614 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001615 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001616 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001617 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001618 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001619 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001620 *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001621 quantum_info->scale+quantum_info->minimum);
1622 p++;
1623 }
1624 break;
1625 }
1626 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1627 {
cristy100b8d92012-01-08 00:32:49 +00001628 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001629 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001630 break;
cristybb503372010-05-27 20:51:26 +00001631 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001632 {
cristy4c08aed2011-07-01 19:47:50 +00001633 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001634 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001635 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001636 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001637 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001638 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001639 *q++=0.0;
1640 p++;
1641 }
1642 break;
1643 }
1644 if (LocaleCompare(stream_info->map,"I") == 0)
1645 {
cristy100b8d92012-01-08 00:32:49 +00001646 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001647 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001648 break;
cristybb503372010-05-27 20:51:26 +00001649 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001650 {
cristy4c08aed2011-07-01 19:47:50 +00001651 *q++=(double) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001652 quantum_info->scale+quantum_info->minimum);
1653 p++;
1654 }
1655 break;
1656 }
1657 if (LocaleCompare(stream_info->map,"RGB") == 0)
1658 {
cristy100b8d92012-01-08 00:32:49 +00001659 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001660 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001661 break;
cristybb503372010-05-27 20:51:26 +00001662 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001663 {
cristy4c08aed2011-07-01 19:47:50 +00001664 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001665 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001666 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001667 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001668 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001669 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001670 p++;
1671 }
1672 break;
1673 }
1674 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1675 {
cristy100b8d92012-01-08 00:32:49 +00001676 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001677 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001678 break;
cristybb503372010-05-27 20:51:26 +00001679 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001680 {
cristy4c08aed2011-07-01 19:47:50 +00001681 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001682 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001683 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001684 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001685 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001686 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001687 *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001688 quantum_info->scale+quantum_info->minimum);
1689 p++;
1690 }
1691 break;
1692 }
1693 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1694 {
cristy100b8d92012-01-08 00:32:49 +00001695 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001696 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001697 break;
cristybb503372010-05-27 20:51:26 +00001698 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001699 {
cristy4c08aed2011-07-01 19:47:50 +00001700 *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001701 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001702 *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001703 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001704 *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001705 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001706 *q++=0.0;
1707 p++;
1708 }
1709 break;
1710 }
cristy100b8d92012-01-08 00:32:49 +00001711 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001712 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001713 break;
cristybb503372010-05-27 20:51:26 +00001714 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001715 {
cristybb503372010-05-27 20:51:26 +00001716 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001717 {
1718 *q=0;
1719 switch (quantum_map[i])
1720 {
1721 case RedQuantum:
1722 case CyanQuantum:
1723 {
cristy4c08aed2011-07-01 19:47:50 +00001724 *q=(double) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001725 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001726 break;
1727 }
1728 case GreenQuantum:
1729 case MagentaQuantum:
1730 {
cristy4c08aed2011-07-01 19:47:50 +00001731 *q=(double) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001732 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001733 break;
1734 }
1735 case BlueQuantum:
1736 case YellowQuantum:
1737 {
cristy4c08aed2011-07-01 19:47:50 +00001738 *q=(double) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001739 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001740 break;
1741 }
1742 case AlphaQuantum:
1743 {
cristy4c08aed2011-07-01 19:47:50 +00001744 *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001745 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001746 break;
1747 }
1748 case OpacityQuantum:
1749 {
cristy4c08aed2011-07-01 19:47:50 +00001750 *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001751 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001752 break;
1753 }
1754 case BlackQuantum:
1755 {
1756 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001757 *q=(double) ((QuantumScale*GetPixelBlack(image,p))*
cristyfba5a8b2011-05-03 17:12:12 +00001758 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001759 break;
1760 }
1761 case IndexQuantum:
1762 {
cristy4c08aed2011-07-01 19:47:50 +00001763 *q=(double) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001764 quantum_info->scale+quantum_info->minimum);
1765 break;
1766 }
1767 default:
1768 *q=0;
1769 }
1770 q++;
1771 }
1772 p++;
1773 }
1774 break;
1775 }
1776 case FloatPixel:
1777 {
1778 register float
1779 *q;
1780
1781 q=(float *) stream_info->pixels;
1782 if (LocaleCompare(stream_info->map,"BGR") == 0)
1783 {
cristy100b8d92012-01-08 00:32:49 +00001784 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001785 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001786 break;
cristybb503372010-05-27 20:51:26 +00001787 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001788 {
cristy4c08aed2011-07-01 19:47:50 +00001789 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001790 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001791 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001792 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001793 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001794 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001795 p++;
1796 }
1797 break;
1798 }
1799 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1800 {
cristy100b8d92012-01-08 00:32:49 +00001801 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001802 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001803 break;
cristybb503372010-05-27 20:51:26 +00001804 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001805 {
cristy4c08aed2011-07-01 19:47:50 +00001806 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001807 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001808 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001809 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001810 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001811 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001812 *q++=(float) ((QuantumScale*(Quantum) (GetPixelAlpha(image,p)))*
cristy3ed852e2009-09-05 21:47:34 +00001813 quantum_info->scale+quantum_info->minimum);
1814 p++;
1815 }
1816 break;
1817 }
1818 if (LocaleCompare(stream_info->map,"BGRP") == 0)
1819 {
cristy100b8d92012-01-08 00:32:49 +00001820 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001821 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001822 break;
cristybb503372010-05-27 20:51:26 +00001823 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001824 {
cristy4c08aed2011-07-01 19:47:50 +00001825 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001826 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001827 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001828 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001829 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001830 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001831 *q++=0.0;
1832 p++;
1833 }
1834 break;
1835 }
1836 if (LocaleCompare(stream_info->map,"I") == 0)
1837 {
cristy100b8d92012-01-08 00:32:49 +00001838 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001839 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001840 break;
cristybb503372010-05-27 20:51:26 +00001841 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001842 {
cristy4c08aed2011-07-01 19:47:50 +00001843 *q++=(float) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001844 quantum_info->scale+quantum_info->minimum);
1845 p++;
1846 }
1847 break;
1848 }
1849 if (LocaleCompare(stream_info->map,"RGB") == 0)
1850 {
cristy100b8d92012-01-08 00:32:49 +00001851 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001852 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001853 break;
cristybb503372010-05-27 20:51:26 +00001854 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001855 {
cristy4c08aed2011-07-01 19:47:50 +00001856 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001857 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001858 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001859 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001860 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001861 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001862 p++;
1863 }
1864 break;
1865 }
1866 if (LocaleCompare(stream_info->map,"RGBA") == 0)
1867 {
cristy100b8d92012-01-08 00:32:49 +00001868 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001869 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001870 break;
cristybb503372010-05-27 20:51:26 +00001871 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001872 {
cristy4c08aed2011-07-01 19:47:50 +00001873 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001874 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001875 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001876 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001877 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001878 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001879 *q++=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001880 quantum_info->scale+quantum_info->minimum);
1881 p++;
1882 }
1883 break;
1884 }
1885 if (LocaleCompare(stream_info->map,"RGBP") == 0)
1886 {
cristy100b8d92012-01-08 00:32:49 +00001887 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001888 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001889 break;
cristybb503372010-05-27 20:51:26 +00001890 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001891 {
cristy4c08aed2011-07-01 19:47:50 +00001892 *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001893 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001894 *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001895 quantum_info->scale+quantum_info->minimum);
cristy4c08aed2011-07-01 19:47:50 +00001896 *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001897 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001898 *q++=0.0;
1899 p++;
1900 }
1901 break;
1902 }
cristy100b8d92012-01-08 00:32:49 +00001903 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001904 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001905 break;
cristybb503372010-05-27 20:51:26 +00001906 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001907 {
cristybb503372010-05-27 20:51:26 +00001908 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001909 {
1910 *q=0;
1911 switch (quantum_map[i])
1912 {
1913 case RedQuantum:
1914 case CyanQuantum:
1915 {
cristy4c08aed2011-07-01 19:47:50 +00001916 *q=(float) ((QuantumScale*GetPixelRed(image,p))*
cristy46f08202010-01-10 04:04:21 +00001917 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001918 break;
1919 }
1920 case GreenQuantum:
1921 case MagentaQuantum:
1922 {
cristy4c08aed2011-07-01 19:47:50 +00001923 *q=(float) ((QuantumScale*GetPixelGreen(image,p))*
cristy46f08202010-01-10 04:04:21 +00001924 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001925 break;
1926 }
1927 case BlueQuantum:
1928 case YellowQuantum:
1929 {
cristy4c08aed2011-07-01 19:47:50 +00001930 *q=(float) ((QuantumScale*GetPixelBlue(image,p))*
cristy46f08202010-01-10 04:04:21 +00001931 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001932 break;
1933 }
1934 case AlphaQuantum:
1935 {
cristy4c08aed2011-07-01 19:47:50 +00001936 *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001937 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001938 break;
1939 }
1940 case OpacityQuantum:
1941 {
cristy4c08aed2011-07-01 19:47:50 +00001942 *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
cristy46f08202010-01-10 04:04:21 +00001943 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001944 break;
1945 }
1946 case BlackQuantum:
1947 {
1948 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00001949 *q=(float) ((QuantumScale*GetPixelBlack(image,p))*
cristyfba5a8b2011-05-03 17:12:12 +00001950 quantum_info->scale+quantum_info->minimum);
cristy3ed852e2009-09-05 21:47:34 +00001951 break;
1952 }
1953 case IndexQuantum:
1954 {
cristy4c08aed2011-07-01 19:47:50 +00001955 *q=(float) ((QuantumScale*GetPixelIntensity(image,p))*
cristy3ed852e2009-09-05 21:47:34 +00001956 quantum_info->scale+quantum_info->minimum);
1957 break;
1958 }
1959 default:
1960 *q=0;
1961 }
1962 q++;
1963 }
1964 p++;
1965 }
1966 break;
1967 }
cristy100b8d92012-01-08 00:32:49 +00001968 case LongPixel:
cristy3ed852e2009-09-05 21:47:34 +00001969 {
1970 register unsigned int
1971 *q;
1972
1973 q=(unsigned int *) stream_info->pixels;
1974 if (LocaleCompare(stream_info->map,"BGR") == 0)
1975 {
cristy100b8d92012-01-08 00:32:49 +00001976 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001977 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001978 break;
cristybb503372010-05-27 20:51:26 +00001979 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001980 {
cristy4c08aed2011-07-01 19:47:50 +00001981 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1982 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1983 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001984 p++;
1985 }
1986 break;
1987 }
1988 if (LocaleCompare(stream_info->map,"BGRA") == 0)
1989 {
cristy100b8d92012-01-08 00:32:49 +00001990 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00001991 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001992 break;
cristybb503372010-05-27 20:51:26 +00001993 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00001994 {
cristy4c08aed2011-07-01 19:47:50 +00001995 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1996 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1997 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1998 *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001999 p++;
2000 }
2001 break;
2002 }
2003 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2004 {
cristy100b8d92012-01-08 00:32:49 +00002005 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002006 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002007 break;
cristybb503372010-05-27 20:51:26 +00002008 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002009 {
cristy4c08aed2011-07-01 19:47:50 +00002010 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2011 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2012 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002013 *q++=0;
2014 p++;
2015 }
2016 break;
2017 }
2018 if (LocaleCompare(stream_info->map,"I") == 0)
2019 {
cristy100b8d92012-01-08 00:32:49 +00002020 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002021 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002022 break;
cristybb503372010-05-27 20:51:26 +00002023 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002024 {
cristyf13c5942012-08-08 23:50:11 +00002025 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002026 p++;
2027 }
2028 break;
2029 }
2030 if (LocaleCompare(stream_info->map,"RGB") == 0)
2031 {
cristy100b8d92012-01-08 00:32:49 +00002032 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002033 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002034 break;
cristybb503372010-05-27 20:51:26 +00002035 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002036 {
cristy4c08aed2011-07-01 19:47:50 +00002037 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2038 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2039 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002040 p++;
2041 }
2042 break;
2043 }
2044 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2045 {
cristy100b8d92012-01-08 00:32:49 +00002046 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002047 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002048 break;
cristybb503372010-05-27 20:51:26 +00002049 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002050 {
cristy4c08aed2011-07-01 19:47:50 +00002051 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2052 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2053 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2054 *q++=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002055 p++;
2056 }
2057 break;
2058 }
2059 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2060 {
cristy100b8d92012-01-08 00:32:49 +00002061 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002062 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002063 break;
cristybb503372010-05-27 20:51:26 +00002064 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002065 {
cristy4c08aed2011-07-01 19:47:50 +00002066 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2067 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2068 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002069 *q++=0;
2070 p++;
2071 }
2072 break;
2073 }
cristy100b8d92012-01-08 00:32:49 +00002074 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002075 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002076 break;
cristybb503372010-05-27 20:51:26 +00002077 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002078 {
cristybb503372010-05-27 20:51:26 +00002079 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002080 {
2081 *q=0;
2082 switch (quantum_map[i])
2083 {
2084 case RedQuantum:
2085 case CyanQuantum:
2086 {
cristy4c08aed2011-07-01 19:47:50 +00002087 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002088 break;
2089 }
2090 case GreenQuantum:
2091 case MagentaQuantum:
2092 {
cristy4c08aed2011-07-01 19:47:50 +00002093 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002094 break;
2095 }
2096 case BlueQuantum:
2097 case YellowQuantum:
2098 {
cristy4c08aed2011-07-01 19:47:50 +00002099 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002100 break;
2101 }
2102 case AlphaQuantum:
2103 {
cristy4c08aed2011-07-01 19:47:50 +00002104 *q=ScaleQuantumToLong((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002105 break;
2106 }
2107 case OpacityQuantum:
2108 {
cristy4c08aed2011-07-01 19:47:50 +00002109 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002110 break;
2111 }
2112 case BlackQuantum:
2113 {
2114 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002115 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002116 break;
2117 }
2118 case IndexQuantum:
2119 {
cristyf13c5942012-08-08 23:50:11 +00002120 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002121 break;
2122 }
2123 default:
2124 break;
2125 }
2126 q++;
2127 }
2128 p++;
2129 }
2130 break;
2131 }
cristy100b8d92012-01-08 00:32:49 +00002132 case LongLongPixel:
2133 {
2134 register MagickSizeType
2135 *q;
2136
2137 q=(MagickSizeType *) stream_info->pixels;
2138 if (LocaleCompare(stream_info->map,"BGR") == 0)
2139 {
2140 p=GetVirtualPixelQueue(image);
2141 if (p == (const Quantum *) NULL)
2142 break;
2143 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2144 {
2145 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2146 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2147 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2148 p++;
2149 }
2150 break;
2151 }
2152 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2153 {
2154 p=GetVirtualPixelQueue(image);
2155 if (p == (const Quantum *) NULL)
2156 break;
2157 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2158 {
2159 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2160 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2161 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2162 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2163 p++;
2164 }
2165 break;
2166 }
2167 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2168 {
2169 p=GetVirtualPixelQueue(image);
2170 if (p == (const Quantum *) NULL)
2171 break;
2172 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2173 {
2174 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2175 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2176 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2177 *q++=0U;
2178 p++;
2179 }
2180 break;
2181 }
2182 if (LocaleCompare(stream_info->map,"I") == 0)
2183 {
2184 p=GetVirtualPixelQueue(image);
2185 if (p == (const Quantum *) NULL)
2186 break;
2187 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2188 {
cristyf13c5942012-08-08 23:50:11 +00002189 *q++=ScaleQuantumToLongLong(ClampToQuantum(
2190 GetPixelIntensity(image,p)));
cristy100b8d92012-01-08 00:32:49 +00002191 p++;
2192 }
2193 break;
2194 }
2195 if (LocaleCompare(stream_info->map,"RGB") == 0)
2196 {
2197 p=GetVirtualPixelQueue(image);
2198 if (p == (const Quantum *) NULL)
2199 break;
2200 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2201 {
2202 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2203 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2204 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2205 p++;
2206 }
2207 break;
2208 }
2209 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2210 {
2211 p=GetVirtualPixelQueue(image);
2212 if (p == (const Quantum *) NULL)
2213 break;
2214 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2215 {
2216 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2217 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2218 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2219 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2220 p++;
2221 }
2222 break;
2223 }
2224 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2225 {
2226 p=GetVirtualPixelQueue(image);
2227 if (p == (const Quantum *) NULL)
2228 break;
2229 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2230 {
2231 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2232 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2233 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2234 *q++=0U;
2235 p++;
2236 }
2237 break;
2238 }
2239 p=GetVirtualPixelQueue(image);
2240 if (p == (const Quantum *) NULL)
2241 break;
2242 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2243 {
2244 for (i=0; i < (ssize_t) length; i++)
2245 {
2246 *q=0;
2247 switch (quantum_map[i])
2248 {
2249 case RedQuantum:
2250 case CyanQuantum:
2251 {
2252 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
2253 break;
2254 }
2255 case GreenQuantum:
2256 case MagentaQuantum:
2257 {
2258 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2259 break;
2260 }
2261 case BlueQuantum:
2262 case YellowQuantum:
2263 {
2264 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2265 break;
2266 }
2267 case AlphaQuantum:
2268 {
2269 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2270 break;
2271 }
2272 case OpacityQuantum:
2273 {
2274 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2275 break;
2276 }
2277 case BlackQuantum:
2278 {
2279 if (image->colorspace == CMYKColorspace)
2280 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
2281 break;
2282 }
2283 case IndexQuantum:
2284 {
cristyf13c5942012-08-08 23:50:11 +00002285 *q=ScaleQuantumToLongLong(ClampToQuantum(
2286 GetPixelIntensity(image,p)));
cristy100b8d92012-01-08 00:32:49 +00002287 break;
2288 }
2289 default:
2290 *q=0;
2291 }
2292 q++;
2293 }
2294 p++;
2295 }
2296 break;
2297 }
cristy3ed852e2009-09-05 21:47:34 +00002298 case QuantumPixel:
2299 {
2300 register Quantum
2301 *q;
2302
2303 q=(Quantum *) stream_info->pixels;
2304 if (LocaleCompare(stream_info->map,"BGR") == 0)
2305 {
cristy100b8d92012-01-08 00:32:49 +00002306 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002307 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002308 break;
cristybb503372010-05-27 20:51:26 +00002309 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002310 {
cristy4c08aed2011-07-01 19:47:50 +00002311 *q++=GetPixelBlue(image,p);
2312 *q++=GetPixelGreen(image,p);
2313 *q++=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002314 p++;
2315 }
2316 break;
2317 }
2318 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2319 {
cristy100b8d92012-01-08 00:32:49 +00002320 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002321 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002322 break;
cristybb503372010-05-27 20:51:26 +00002323 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002324 {
cristy4c08aed2011-07-01 19:47:50 +00002325 *q++=GetPixelBlue(image,p);
2326 *q++=GetPixelGreen(image,p);
2327 *q++=GetPixelRed(image,p);
cristy100b8d92012-01-08 00:32:49 +00002328 *q++=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002329 p++;
2330 }
2331 break;
2332 }
2333 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2334 {
cristy100b8d92012-01-08 00:32:49 +00002335 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002336 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002337 break;
cristybb503372010-05-27 20:51:26 +00002338 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002339 {
cristy4c08aed2011-07-01 19:47:50 +00002340 *q++=GetPixelBlue(image,p);
2341 *q++=GetPixelGreen(image,p);
2342 *q++=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002343 *q++=0;
2344 p++;
2345 }
2346 break;
2347 }
2348 if (LocaleCompare(stream_info->map,"I") == 0)
2349 {
cristy100b8d92012-01-08 00:32:49 +00002350 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002351 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002352 break;
cristybb503372010-05-27 20:51:26 +00002353 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002354 {
cristyf13c5942012-08-08 23:50:11 +00002355 *q++=ClampToQuantum(GetPixelIntensity(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002356 p++;
2357 }
2358 break;
2359 }
2360 if (LocaleCompare(stream_info->map,"RGB") == 0)
2361 {
cristy100b8d92012-01-08 00:32:49 +00002362 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002363 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002364 break;
cristybb503372010-05-27 20:51:26 +00002365 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002366 {
cristy4c08aed2011-07-01 19:47:50 +00002367 *q++=GetPixelRed(image,p);
2368 *q++=GetPixelGreen(image,p);
2369 *q++=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002370 p++;
2371 }
2372 break;
2373 }
2374 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2375 {
cristy100b8d92012-01-08 00:32:49 +00002376 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002377 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002378 break;
cristybb503372010-05-27 20:51:26 +00002379 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002380 {
cristy4c08aed2011-07-01 19:47:50 +00002381 *q++=GetPixelRed(image,p);
2382 *q++=GetPixelGreen(image,p);
2383 *q++=GetPixelBlue(image,p);
cristy100b8d92012-01-08 00:32:49 +00002384 *q++=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002385 p++;
2386 }
2387 break;
2388 }
2389 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2390 {
cristy100b8d92012-01-08 00:32:49 +00002391 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002392 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002393 break;
cristybb503372010-05-27 20:51:26 +00002394 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002395 {
cristy4c08aed2011-07-01 19:47:50 +00002396 *q++=GetPixelRed(image,p);
2397 *q++=GetPixelGreen(image,p);
2398 *q++=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002399 *q++=0U;
2400 p++;
2401 }
2402 break;
2403 }
cristy100b8d92012-01-08 00:32:49 +00002404 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002405 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002406 break;
cristybb503372010-05-27 20:51:26 +00002407 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002408 {
cristybb503372010-05-27 20:51:26 +00002409 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002410 {
2411 *q=(Quantum) 0;
2412 switch (quantum_map[i])
2413 {
2414 case RedQuantum:
2415 case CyanQuantum:
2416 {
cristy4c08aed2011-07-01 19:47:50 +00002417 *q=GetPixelRed(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002418 break;
2419 }
2420 case GreenQuantum:
2421 case MagentaQuantum:
2422 {
cristy4c08aed2011-07-01 19:47:50 +00002423 *q=GetPixelGreen(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002424 break;
2425 }
2426 case BlueQuantum:
2427 case YellowQuantum:
2428 {
cristy4c08aed2011-07-01 19:47:50 +00002429 *q=GetPixelBlue(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002430 break;
2431 }
2432 case AlphaQuantum:
2433 {
cristy4c08aed2011-07-01 19:47:50 +00002434 *q=(Quantum) (GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002435 break;
2436 }
2437 case OpacityQuantum:
2438 {
cristy4c08aed2011-07-01 19:47:50 +00002439 *q=GetPixelAlpha(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002440 break;
2441 }
2442 case BlackQuantum:
2443 {
2444 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002445 *q=GetPixelBlack(image,p);
cristy3ed852e2009-09-05 21:47:34 +00002446 break;
2447 }
2448 case IndexQuantum:
2449 {
cristyf13c5942012-08-08 23:50:11 +00002450 *q=ClampToQuantum(GetPixelIntensity(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002451 break;
2452 }
2453 default:
2454 *q=0;
2455 }
2456 q++;
2457 }
2458 p++;
2459 }
2460 break;
2461 }
2462 case ShortPixel:
2463 {
2464 register unsigned short
2465 *q;
2466
2467 q=(unsigned short *) stream_info->pixels;
2468 if (LocaleCompare(stream_info->map,"BGR") == 0)
2469 {
cristy100b8d92012-01-08 00:32:49 +00002470 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002471 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002472 break;
cristybb503372010-05-27 20:51:26 +00002473 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002474 {
cristy4c08aed2011-07-01 19:47:50 +00002475 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2476 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2477 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002478 p++;
2479 }
2480 break;
2481 }
2482 if (LocaleCompare(stream_info->map,"BGRA") == 0)
2483 {
cristy100b8d92012-01-08 00:32:49 +00002484 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002485 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002486 break;
cristybb503372010-05-27 20:51:26 +00002487 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002488 {
cristy4c08aed2011-07-01 19:47:50 +00002489 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2490 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2491 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2492 *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002493 p++;
2494 }
2495 break;
2496 }
2497 if (LocaleCompare(stream_info->map,"BGRP") == 0)
2498 {
cristy100b8d92012-01-08 00:32:49 +00002499 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002500 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002501 break;
cristybb503372010-05-27 20:51:26 +00002502 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002503 {
cristy4c08aed2011-07-01 19:47:50 +00002504 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2505 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2506 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002507 *q++=0;
2508 p++;
2509 }
2510 break;
2511 }
2512 if (LocaleCompare(stream_info->map,"I") == 0)
2513 {
cristy100b8d92012-01-08 00:32:49 +00002514 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002515 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002516 break;
cristybb503372010-05-27 20:51:26 +00002517 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002518 {
cristyf13c5942012-08-08 23:50:11 +00002519 *q++=ScaleQuantumToShort(ClampToQuantum(
2520 GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002521 p++;
2522 }
2523 break;
2524 }
2525 if (LocaleCompare(stream_info->map,"RGB") == 0)
2526 {
cristy100b8d92012-01-08 00:32:49 +00002527 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002528 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002529 break;
cristybb503372010-05-27 20:51:26 +00002530 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002531 {
cristy4c08aed2011-07-01 19:47:50 +00002532 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2533 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2534 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002535 p++;
2536 }
2537 break;
2538 }
2539 if (LocaleCompare(stream_info->map,"RGBA") == 0)
2540 {
cristy100b8d92012-01-08 00:32:49 +00002541 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002542 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002543 break;
cristybb503372010-05-27 20:51:26 +00002544 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002545 {
cristy4c08aed2011-07-01 19:47:50 +00002546 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2547 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2548 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2549 *q++=ScaleQuantumToShort((Quantum) (GetPixelAlpha(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002550 p++;
2551 }
2552 break;
2553 }
2554 if (LocaleCompare(stream_info->map,"RGBP") == 0)
2555 {
cristy100b8d92012-01-08 00:32:49 +00002556 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002557 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002558 break;
cristybb503372010-05-27 20:51:26 +00002559 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002560 {
cristy4c08aed2011-07-01 19:47:50 +00002561 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2562 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2563 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002564 *q++=0;
2565 p++;
2566 }
2567 break;
2568 }
cristy100b8d92012-01-08 00:32:49 +00002569 p=GetVirtualPixelQueue(image);
cristy4c08aed2011-07-01 19:47:50 +00002570 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002571 break;
cristybb503372010-05-27 20:51:26 +00002572 for (x=0; x < (ssize_t) GetImageExtent(image); x++)
cristy3ed852e2009-09-05 21:47:34 +00002573 {
cristybb503372010-05-27 20:51:26 +00002574 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002575 {
2576 *q=0;
2577 switch (quantum_map[i])
2578 {
2579 case RedQuantum:
2580 case CyanQuantum:
2581 {
cristy4c08aed2011-07-01 19:47:50 +00002582 *q=ScaleQuantumToShort(GetPixelRed(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002583 break;
2584 }
2585 case GreenQuantum:
2586 case MagentaQuantum:
2587 {
cristy4c08aed2011-07-01 19:47:50 +00002588 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002589 break;
2590 }
2591 case BlueQuantum:
2592 case YellowQuantum:
2593 {
cristy4c08aed2011-07-01 19:47:50 +00002594 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002595 break;
2596 }
2597 case AlphaQuantum:
2598 {
cristy4c08aed2011-07-01 19:47:50 +00002599 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002600 break;
2601 }
2602 case OpacityQuantum:
2603 {
cristy4c08aed2011-07-01 19:47:50 +00002604 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002605 break;
2606 }
2607 case BlackQuantum:
2608 {
2609 if (image->colorspace == CMYKColorspace)
cristy4c08aed2011-07-01 19:47:50 +00002610 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
cristy3ed852e2009-09-05 21:47:34 +00002611 break;
2612 }
2613 case IndexQuantum:
2614 {
cristyf13c5942012-08-08 23:50:11 +00002615 *q=ScaleQuantumToShort(ClampToQuantum(
2616 GetPixelIntensity(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00002617 break;
2618 }
2619 default:
2620 break;
2621 }
2622 q++;
2623 }
2624 p++;
2625 }
2626 break;
2627 }
2628 default:
2629 {
2630 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2631 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristy39c2e212012-08-18 18:14:34 +00002632 "UnrecognizedPixelMap","`%s'",stream_info->map);
cristy3ed852e2009-09-05 21:47:34 +00002633 break;
2634 }
2635 }
2636 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2637 return(MagickTrue);
2638}
2639
2640/*
2641%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2642% %
2643% %
2644% %
2645+ 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 %
2646% %
2647% %
2648% %
2649%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2650%
2651% SyncAuthenticPixelsStream() calls the user supplied callback method with
2652% the latest stream of pixels.
2653%
2654% The format of the SyncAuthenticPixelsStream method is:
2655%
2656% MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2657% ExceptionInfo *exception)
2658%
2659% A description of each parameter follows:
2660%
2661% o image: the image.
2662%
2663% o exception: return any errors or warnings in this structure.
2664%
2665*/
2666static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2667 ExceptionInfo *exception)
2668{
2669 CacheInfo
2670 *cache_info;
2671
2672 size_t
2673 length;
2674
2675 StreamHandler
2676 stream_handler;
2677
2678 assert(image != (Image *) NULL);
2679 assert(image->signature == MagickSignature);
2680 if (image->debug != MagickFalse)
2681 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2682 cache_info=(CacheInfo *) image->cache;
2683 assert(cache_info->signature == MagickSignature);
2684 stream_handler=GetBlobStreamHandler(image);
2685 if (stream_handler == (StreamHandler) NULL)
2686 {
2687 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
cristy39c2e212012-08-18 18:14:34 +00002688 "NoStreamHandlerIsDefined","`%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +00002689 return(MagickFalse);
2690 }
2691 length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
2692 return(length == cache_info->columns ? MagickTrue : MagickFalse);
2693}
2694
2695/*
2696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2697% %
2698% %
2699% %
2700% W r i t e S t r e a m %
2701% %
2702% %
2703% %
2704%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2705%
2706% WriteStream() makes the image pixels available to a user supplied callback
2707% method immediately upon writing pixel data with the WriteImage() method.
2708%
2709% The format of the WriteStream() method is:
2710%
2711% MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
cristyc82a27b2011-10-21 01:07:16 +00002712% StreamHandler stream,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002713%
2714% A description of each parameter follows:
2715%
2716% o image_info: the image info.
2717%
2718% o stream: A callback method.
2719%
cristyc82a27b2011-10-21 01:07:16 +00002720% o exception: return any errors or warnings in this structure.
2721%
cristy3ed852e2009-09-05 21:47:34 +00002722*/
2723MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
cristyc82a27b2011-10-21 01:07:16 +00002724 Image *image,StreamHandler stream,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002725{
2726 ImageInfo
2727 *write_info;
2728
2729 MagickBooleanType
2730 status;
2731
2732 assert(image_info != (ImageInfo *) NULL);
2733 assert(image_info->signature == MagickSignature);
2734 if (image_info->debug != MagickFalse)
2735 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2736 image_info->filename);
2737 assert(image != (Image *) NULL);
2738 assert(image->signature == MagickSignature);
2739 write_info=CloneImageInfo(image_info);
2740 write_info->stream=stream;
cristyc82a27b2011-10-21 01:07:16 +00002741 status=WriteImage(write_info,image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002742 write_info=DestroyImageInfo(write_info);
2743 return(status);
2744}