MagickCore  7.1.0
Convert, Edit, Or Compose Bitmap Images
stream.c
1 /*
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 % Cristy %
17 % March 2000 %
18 % %
19 % %
20 % Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
21 % 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 % https://imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39 ␌
40 /*
41  Include declarations.
42 */
43 #include "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/memory-private.h"
56 #include "MagickCore/pixel.h"
57 #include "MagickCore/pixel-accessor.h"
58 #include "MagickCore/policy.h"
59 #include "MagickCore/quantum.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/semaphore.h"
62 #include "MagickCore/stream.h"
63 #include "MagickCore/stream-private.h"
64 #include "MagickCore/string_.h"
65 ␌
66 /*
67  Typedef declaractions.
68 */
70 {
71  const ImageInfo
72  *image_info;
73 
74  const Image
75  *image;
76 
77  Image
78  *stream;
79 
81  *quantum_info;
82 
83  char
84  *map;
85 
86  StorageType
87  storage_type;
88 
89  unsigned char
90  *pixels;
91 
93  extract_info;
94 
95  ssize_t
96  y;
97 
99  *exception;
100 
101  const void
102  *client_data;
103 
104  size_t
105  signature;
106 };
107 ␌
108 /*
109  Declare pixel cache interfaces.
110 */
111 #if defined(__cplusplus) || defined(c_plusplus)
112 extern "C" {
113 #endif
114 
115 static const Quantum
116  *GetVirtualPixelStream(const Image *,const VirtualPixelMethod,const ssize_t,
117  const ssize_t,const size_t,const size_t,ExceptionInfo *);
118 
119 static MagickBooleanType
120  StreamImagePixels(const StreamInfo *,const Image *,ExceptionInfo *),
121  SyncAuthenticPixelsStream(Image *,ExceptionInfo *);
122 
123 static Quantum
124  *QueueAuthenticPixelsStream(Image *,const ssize_t,const ssize_t,const size_t,
125  const size_t,ExceptionInfo *);
126 
127 #if defined(__cplusplus) || defined(c_plusplus)
128 }
129 #endif
130 ␌
131 /*
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133 % %
134 % %
135 % %
136 + A c q u i r e S t r e a m I n f o %
137 % %
138 % %
139 % %
140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141 %
142 % AcquireStreamInfo() allocates the StreamInfo structure.
143 %
144 % The format of the AcquireStreamInfo method is:
145 %
146 % StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
147 % ExceptionInfo *exception)
148 %
149 % A description of each parameter follows:
150 %
151 % o image_info: the image info.
152 %
153 % o exception: return any errors or warnings in this structure.
154 %
155 */
156 MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
157  ExceptionInfo *exception)
158 {
159  StreamInfo
160  *stream_info;
161 
162  stream_info=(StreamInfo *) AcquireCriticalMemory(sizeof(*stream_info));
163  (void) memset(stream_info,0,sizeof(*stream_info));
164  stream_info->pixels=(unsigned char *) MagickAssumeAligned(
165  AcquireAlignedMemory(1,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;
170  stream_info->stream=AcquireImage(image_info,exception);
171  stream_info->signature=MagickCoreSignature;
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 
198 static inline void RelinquishStreamPixels(CacheInfo *cache_info)
199 {
200  assert(cache_info != (CacheInfo *) NULL);
201  if (cache_info->pixels != (Quantum *) NULL)
202  {
203  if (cache_info->mapped == MagickFalse)
204  cache_info->pixels=(Quantum *) RelinquishAlignedMemory(
205  cache_info->pixels);
206  else
207  {
208  (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
209  cache_info->pixels=(Quantum *) NULL;
210  }
211  }
212  cache_info->mapped=MagickFalse;
213  cache_info->metacontent=(void *) NULL;
214  cache_info->length=0;
215 }
216 
217 static void DestroyPixelStream(Image *image)
218 {
219  CacheInfo
220  *cache_info;
221 
222  MagickBooleanType
223  destroy;
224 
225  assert(image != (Image *) NULL);
226  assert(image->signature == MagickCoreSignature);
227  if (IsEventLogging() != MagickFalse)
228  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
229  cache_info=(CacheInfo *) image->cache;
230  assert(cache_info->signature == MagickCoreSignature);
231  destroy=MagickFalse;
232  LockSemaphoreInfo(cache_info->semaphore);
233  cache_info->reference_count--;
234  if (cache_info->reference_count == 0)
235  destroy=MagickTrue;
236  UnlockSemaphoreInfo(cache_info->semaphore);
237  if (destroy == MagickFalse)
238  return;
239  RelinquishStreamPixels(cache_info);
240  if (cache_info->nexus_info != (NexusInfo **) NULL)
241  cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
242  cache_info->number_threads);
243  if (cache_info->file_semaphore != (SemaphoreInfo *) NULL)
244  RelinquishSemaphoreInfo(&cache_info->file_semaphore);
245  if (cache_info->semaphore != (SemaphoreInfo *) NULL)
246  RelinquishSemaphoreInfo(&cache_info->semaphore);
247  cache_info=(CacheInfo *) RelinquishAlignedMemory(cache_info);
248 }
249 ␌
250 /*
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 % %
253 % %
254 % %
255 + D e s t r o y S t r e a m I n f o %
256 % %
257 % %
258 % %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 %
261 % DestroyStreamInfo() destroys memory associated with the StreamInfo
262 % structure.
263 %
264 % The format of the DestroyStreamInfo method is:
265 %
266 % StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
267 %
268 % A description of each parameter follows:
269 %
270 % o stream_info: the stream info.
271 %
272 */
273 MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
274 {
275  assert(stream_info != (StreamInfo *) NULL);
276  assert(stream_info->signature == MagickCoreSignature);
277  if (IsEventLogging() != MagickFalse)
278  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
279  if (stream_info->map != (char *) NULL)
280  stream_info->map=DestroyString(stream_info->map);
281  if (stream_info->pixels != (unsigned char *) NULL)
282  stream_info->pixels=(unsigned char *) RelinquishAlignedMemory(
283  stream_info->pixels);
284  if (stream_info->stream != (Image *) NULL)
285  {
286  (void) CloseBlob(stream_info->stream);
287  stream_info->stream=DestroyImage(stream_info->stream);
288  }
289  if (stream_info->quantum_info != (QuantumInfo *) NULL)
290  stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
291  stream_info->signature=(~MagickCoreSignature);
292  stream_info=(StreamInfo *) RelinquishMagickMemory(stream_info);
293  return(stream_info);
294 }
295 ␌
296 /*
297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298 % %
299 % %
300 % %
301 + 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 %
302 % %
303 % %
304 % %
305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306 %
307 % GetAuthenticMetacontentFromStream() returns the metacontent corresponding
308 % with the last call to QueueAuthenticPixelsStream() or
309 % GetAuthenticPixelsStream().
310 %
311 % The format of the GetAuthenticMetacontentFromStream() method is:
312 %
313 % void *GetAuthenticMetacontentFromStream(const Image *image)
314 %
315 % A description of each parameter follows:
316 %
317 % o image: the image.
318 %
319 */
320 static void *GetAuthenticMetacontentFromStream(const Image *image)
321 {
322  CacheInfo
323  *cache_info;
324 
325  assert(image != (Image *) NULL);
326  assert(image->signature == MagickCoreSignature);
327  if (IsEventLogging() != MagickFalse)
328  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
329  cache_info=(CacheInfo *) image->cache;
330  assert(cache_info->signature == MagickCoreSignature);
331  return(cache_info->metacontent);
332 }
333 ␌
334 /*
335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
336 % %
337 % %
338 % %
339 + G e t A u t h e n t i c P i x e l S t r e a m %
340 % %
341 % %
342 % %
343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 %
345 % GetAuthenticPixelsStream() gets pixels from the in-memory or disk pixel
346 % cache as defined by the geometry parameters. A pointer to the pixels is
347 % returned if the pixels are transferred, otherwise a NULL is returned. For
348 % streams this method is a no-op.
349 %
350 % The format of the GetAuthenticPixelsStream() method is:
351 %
352 % Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
353 % const ssize_t y,const size_t columns,const size_t rows,
354 % ExceptionInfo *exception)
355 %
356 % A description of each parameter follows:
357 %
358 % o image: the image.
359 %
360 % o x,y,columns,rows: These values define the perimeter of a region of
361 % pixels.
362 %
363 % o exception: return any errors or warnings in this structure.
364 %
365 */
366 static Quantum *GetAuthenticPixelsStream(Image *image,const ssize_t x,
367  const ssize_t y,const size_t columns,const size_t rows,
368  ExceptionInfo *exception)
369 {
370  Quantum
371  *pixels;
372 
373  assert(image != (Image *) NULL);
374  assert(image->signature == MagickCoreSignature);
375  if (IsEventLogging() != MagickFalse)
376  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
377  pixels=QueueAuthenticPixelsStream(image,x,y,columns,rows,exception);
378  return(pixels);
379 }
380 ␌
381 /*
382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383 % %
384 % %
385 % %
386 + 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 %
387 % %
388 % %
389 % %
390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391 %
392 % GetAuthenticPixelsFromStream() returns the pixels associated with the last
393 % call to QueueAuthenticPixelsStream() or GetAuthenticPixelsStream().
394 %
395 % The format of the GetAuthenticPixelsFromStream() method is:
396 %
397 % Quantum *GetAuthenticPixelsFromStream(const Image image)
398 %
399 % A description of each parameter follows:
400 %
401 % o image: the image.
402 %
403 */
404 static Quantum *GetAuthenticPixelsFromStream(const Image *image)
405 {
406  CacheInfo
407  *cache_info;
408 
409  assert(image != (Image *) NULL);
410  assert(image->signature == MagickCoreSignature);
411  if (IsEventLogging() != MagickFalse)
412  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
413  cache_info=(CacheInfo *) image->cache;
414  assert(cache_info->signature == MagickCoreSignature);
415  return(cache_info->pixels);
416 }
417 ␌
418 /*
419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420 % %
421 % %
422 % %
423 + 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 %
424 % %
425 % %
426 % %
427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
428 %
429 % GetOneAuthenticPixelFromStream() returns a single pixel at the specified
430 % (x,y) location. The image background color is returned if an error occurs.
431 %
432 % The format of the GetOneAuthenticPixelFromStream() method is:
433 %
434 % MagickBooleanType GetOneAuthenticPixelFromStream(const Image image,
435 % const ssize_t x,const ssize_t y,Quantum *pixel,
436 % ExceptionInfo *exception)
437 %
438 % A description of each parameter follows:
439 %
440 % o image: the image.
441 %
442 % o pixel: return a pixel at the specified (x,y) location.
443 %
444 % o x,y: These values define the location of the pixel to return.
445 %
446 % o exception: return any errors or warnings in this structure.
447 %
448 */
449 static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
450  const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
451 {
452  Quantum
453  *p;
454 
455  ssize_t
456  i;
457 
458  assert(image != (Image *) NULL);
459  assert(image->signature == MagickCoreSignature);
460  (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
461  p=GetAuthenticPixelsStream(image,x,y,1,1,exception);
462  if (p == (Quantum *) NULL)
463  {
464  pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
465  pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
466  pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
467  pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
468  pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
469  return(MagickFalse);
470  }
471  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
472  {
473  PixelChannel channel = GetPixelChannelChannel(image,i);
474  pixel[channel]=p[i];
475  }
476  return(MagickTrue);
477 }
478 ␌
479 /*
480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 % %
482 % %
483 % %
484 + 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 %
485 % %
486 % %
487 % %
488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489 %
490 % GetOneVirtualPixelFromStream() returns a single pixel at the specified
491 % (x.y) location. The image background color is returned if an error occurs.
492 %
493 % The format of the GetOneVirtualPixelFromStream() method is:
494 %
495 % MagickBooleanType GetOneVirtualPixelFromStream(const Image image,
496 % const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
497 % const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
498 %
499 % A description of each parameter follows:
500 %
501 % o image: the image.
502 %
503 % o virtual_pixel_method: the virtual pixel method.
504 %
505 % o x,y: These values define the location of the pixel to return.
506 %
507 % o pixel: return a pixel at the specified (x,y) location.
508 %
509 % o exception: return any errors or warnings in this structure.
510 %
511 */
512 static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
513  const VirtualPixelMethod virtual_pixel_method,const ssize_t x,const ssize_t y,
514  Quantum *pixel,ExceptionInfo *exception)
515 {
516  const Quantum
517  *p;
518 
519  ssize_t
520  i;
521 
522  assert(image != (Image *) NULL);
523  assert(image->signature == MagickCoreSignature);
524  (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
525  p=GetVirtualPixelStream(image,virtual_pixel_method,x,y,1,1,exception);
526  if (p == (const Quantum *) NULL)
527  {
528  pixel[RedPixelChannel]=ClampToQuantum(image->background_color.red);
529  pixel[GreenPixelChannel]=ClampToQuantum(image->background_color.green);
530  pixel[BluePixelChannel]=ClampToQuantum(image->background_color.blue);
531  pixel[BlackPixelChannel]=ClampToQuantum(image->background_color.black);
532  pixel[AlphaPixelChannel]=ClampToQuantum(image->background_color.alpha);
533  return(MagickFalse);
534  }
535  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
536  {
537  PixelChannel channel = GetPixelChannelChannel(image,i);
538  pixel[channel]=p[i];
539  }
540  return(MagickTrue);
541 }
542 ␌
543 /*
544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545 % %
546 % %
547 % %
548 + G e t S t r e a m I n f o C l i e n t D a t a %
549 % %
550 % %
551 % %
552 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553 %
554 % GetStreamInfoClientData() gets the stream info client data.
555 %
556 % The format of the GetStreamInfoClientData method is:
557 %
558 % const void *GetStreamInfoClientData(StreamInfo *stream_info)
559 %
560 % A description of each parameter follows:
561 %
562 % o stream_info: the stream info.
563 %
564 */
565 MagickPrivate const void *GetStreamInfoClientData(StreamInfo *stream_info)
566 {
567  assert(stream_info != (StreamInfo *) NULL);
568  assert(stream_info->signature == MagickCoreSignature);
569  return(stream_info->client_data);
570 }
571 ␌
572 /*
573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574 % %
575 % %
576 % %
577 + G e t V i r t u a l P i x e l s F r o m S t r e a m %
578 % %
579 % %
580 % %
581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 %
583 % GetVirtualPixelsStream() returns the pixels associated with the last call to
584 % QueueAuthenticPixelsStream() or GetVirtualPixelStream().
585 %
586 % The format of the GetVirtualPixelsStream() method is:
587 %
588 % const Quantum *GetVirtualPixelsStream(const Image *image)
589 %
590 % A description of each parameter follows:
591 %
592 % o pixels: return the pixels associated corresponding with the last call to
593 % QueueAuthenticPixelsStream() or GetVirtualPixelStream().
594 %
595 % o image: the image.
596 %
597 */
598 static const Quantum *GetVirtualPixelsStream(const Image *image)
599 {
600  CacheInfo
601  *cache_info;
602 
603  assert(image != (Image *) NULL);
604  assert(image->signature == MagickCoreSignature);
605  if (IsEventLogging() != MagickFalse)
606  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
607  cache_info=(CacheInfo *) image->cache;
608  assert(cache_info->signature == MagickCoreSignature);
609  return(cache_info->pixels);
610 }
611 ␌
612 /*
613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614 % %
615 % %
616 % %
617 + G e t V i r t u a l I n d e x e s F r o m S t r e a m %
618 % %
619 % %
620 % %
621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622 %
623 % GetVirtualMetacontentFromStream() returns the associated pixel channels
624 % corresponding with the last call to QueueAuthenticPixelsStream() or
625 % GetVirtualPixelStream().
626 %
627 % The format of the GetVirtualMetacontentFromStream() method is:
628 %
629 % const void *GetVirtualMetacontentFromStream(const Image *image)
630 %
631 % A description of each parameter follows:
632 %
633 % o image: the image.
634 %
635 */
636 static const void *GetVirtualMetacontentFromStream(const Image *image)
637 {
638  CacheInfo
639  *cache_info;
640 
641  assert(image != (Image *) NULL);
642  assert(image->signature == MagickCoreSignature);
643  if (IsEventLogging() != MagickFalse)
644  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
645  cache_info=(CacheInfo *) image->cache;
646  assert(cache_info->signature == MagickCoreSignature);
647  return(cache_info->metacontent);
648 }
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 %
668 % const Quantum *GetVirtualPixelStream(const Image *image,
669 % const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
670 % const ssize_t y,const size_t columns,const size_t rows,
671 % 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 
686 static 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->pixels=(Quantum *) MagickAssumeAligned(AcquireAlignedMemory(1,
692  (size_t) cache_info->length));
693  if (cache_info->pixels != (Quantum *) NULL)
694  (void) memset(cache_info->pixels,0,(size_t) cache_info->length);
695  else
696  {
697  (void) ThrowMagickException(exception,GetMagickModule(),
698  ResourceLimitError,"MemoryAllocationFailed","`%s'",
699  cache_info->filename);
700  return(MagickFalse);
701  }
702  return(MagickTrue);
703 }
704 
705 static const Quantum *GetVirtualPixelStream(const Image *image,
706  const VirtualPixelMethod magick_unused(virtual_pixel_method),const ssize_t x,
707  const ssize_t y,const size_t columns,const size_t rows,
708  ExceptionInfo *exception)
709 {
710  CacheInfo
711  *cache_info;
712 
713  MagickBooleanType
714  status;
715 
716  MagickSizeType
717  number_pixels;
718 
719  size_t
720  length;
721 
722  magick_unreferenced(virtual_pixel_method);
723 
724  /*
725  Validate pixel cache geometry.
726  */
727  assert(image != (const Image *) NULL);
728  assert(image->signature == MagickCoreSignature);
729  if (IsEventLogging() != MagickFalse)
730  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
731  if ((x < 0) || (y < 0) ||
732  ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
733  ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
734  (columns == 0) || (rows == 0))
735  {
736  (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
737  "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
738  return((Quantum *) NULL);
739  }
740  cache_info=(CacheInfo *) image->cache;
741  assert(cache_info->signature == MagickCoreSignature);
742  /*
743  Pixels are stored in a temporary buffer until they are synced to the cache.
744  */
745  number_pixels=(MagickSizeType) columns*rows;
746  length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
747  if (cache_info->number_channels == 0)
748  length=(size_t) number_pixels*sizeof(Quantum);
749  if (cache_info->metacontent_extent != 0)
750  length+=number_pixels*cache_info->metacontent_extent;
751  if (cache_info->pixels == (Quantum *) NULL)
752  {
753  cache_info->length=length;
754  status=AcquireStreamPixels(cache_info,exception);
755  if (status == MagickFalse)
756  {
757  cache_info->length=0;
758  return((Quantum *) NULL);
759  }
760  }
761  else
762  if (cache_info->length < length)
763  {
764  RelinquishStreamPixels(cache_info);
765  cache_info->length=length;
766  status=AcquireStreamPixels(cache_info,exception);
767  if (status == MagickFalse)
768  {
769  cache_info->length=0;
770  return((Quantum *) NULL);
771  }
772  }
773  cache_info->metacontent=(void *) NULL;
774  if (cache_info->metacontent_extent != 0)
775  cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
776  cache_info->number_channels);
777  return(cache_info->pixels);
778 }
779 ␌
780 /*
781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
782 % %
783 % %
784 % %
785 + O p e n S t r e a m %
786 % %
787 % %
788 % %
789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
790 %
791 % OpenStream() opens a stream for writing by the StreamImage() method.
792 %
793 % The format of the OpenStream method is:
794 %
795 % MagickBooleanType OpenStream(const ImageInfo *image_info,
796 % StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
797 %
798 % A description of each parameter follows:
799 %
800 % o image_info: the image info.
801 %
802 % o stream_info: the stream info.
803 %
804 % o filename: the stream filename.
805 %
806 % o exception: return any errors or warnings in this structure.
807 %
808 */
809 MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
810  StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
811 {
812  MagickBooleanType
813  status;
814 
815  (void) CopyMagickString(stream_info->stream->filename,filename,
816  MagickPathExtent);
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 %
840 % Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
841 % const ssize_t y,const size_t columns,const size_t rows,
842 % 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 */
852 
853 static inline MagickBooleanType ValidatePixelCacheMorphology(
854  const Image *magick_restrict image)
855 {
856  const CacheInfo
857  *magick_restrict cache_info;
858 
859  const PixelChannelMap
860  *magick_restrict p,
861  *magick_restrict q;
862 
863  /*
864  Does the image match the pixel cache morphology?
865  */
866  cache_info=(CacheInfo *) image->cache;
867  p=image->channel_map;
868  q=cache_info->channel_map;
869  if ((image->storage_class != cache_info->storage_class) ||
870  (image->colorspace != cache_info->colorspace) ||
871  (image->alpha_trait != cache_info->alpha_trait) ||
872  (image->channels != cache_info->channels) ||
873  (image->columns != cache_info->columns) ||
874  (image->rows != cache_info->rows) ||
875  (image->number_channels != cache_info->number_channels) ||
876  (memcmp(p,q,image->number_channels*sizeof(*p)) != 0) ||
877  (image->metacontent_extent != cache_info->metacontent_extent) ||
878  (cache_info->nexus_info == (NexusInfo **) NULL))
879  return(MagickFalse);
880  return(MagickTrue);
881 }
882 
883 static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
884  const ssize_t y,const size_t columns,const size_t rows,
885  ExceptionInfo *exception)
886 {
887  CacheInfo
888  *cache_info;
889 
890  MagickBooleanType
891  status;
892 
893  MagickSizeType
894  number_pixels;
895 
896  size_t
897  length;
898 
899  StreamHandler
900  stream_handler;
901 
902  /*
903  Validate pixel cache geometry.
904  */
905  assert(image != (Image *) NULL);
906  if ((x < 0) || (y < 0) ||
907  ((x+(ssize_t) columns) > (ssize_t) image->columns) ||
908  ((y+(ssize_t) rows) > (ssize_t) image->rows) ||
909  (columns == 0) || (rows == 0))
910  {
911  (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
912  "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
913  return((Quantum *) NULL);
914  }
915  stream_handler=GetBlobStreamHandler(image);
916  if (stream_handler == (StreamHandler) NULL)
917  {
918  (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
919  "NoStreamHandlerIsDefined","`%s'",image->filename);
920  return((Quantum *) NULL);
921  }
922  cache_info=(CacheInfo *) image->cache;
923  assert(cache_info->signature == MagickCoreSignature);
924  if (ValidatePixelCacheMorphology(image) == MagickFalse)
925  {
926  if (cache_info->storage_class == UndefinedClass)
927  (void) stream_handler(image,(const void *) NULL,(size_t)
928  cache_info->columns);
929  cache_info->storage_class=image->storage_class;
930  cache_info->colorspace=image->colorspace;
931  cache_info->alpha_trait=image->alpha_trait;
932  cache_info->channels=image->channels;
933  cache_info->columns=image->columns;
934  cache_info->rows=image->rows;
935  cache_info->number_channels=image->number_channels;
936  InitializePixelChannelMap(image);
937  ResetPixelCacheChannels(image);
938  image->cache=cache_info;
939  }
940  /*
941  Pixels are stored in a temporary buffer until they are synced to the cache.
942  */
943  cache_info->columns=columns;
944  cache_info->rows=rows;
945  number_pixels=(MagickSizeType) columns*rows;
946  length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
947  if (cache_info->number_channels == 0)
948  length=(size_t) number_pixels*sizeof(Quantum);
949  if (cache_info->metacontent_extent != 0)
950  length+=number_pixels*cache_info->metacontent_extent;
951  if (cache_info->pixels == (Quantum *) NULL)
952  {
953  cache_info->length=length;
954  status=AcquireStreamPixels(cache_info,exception);
955  if (status == MagickFalse)
956  {
957  cache_info->length=0;
958  return((Quantum *) NULL);
959  }
960  }
961  else
962  if (cache_info->length < length)
963  {
964  RelinquishStreamPixels(cache_info);
965  cache_info->length=length;
966  status=AcquireStreamPixels(cache_info,exception);
967  if (status == MagickFalse)
968  {
969  cache_info->length=0;
970  return((Quantum *) NULL);
971  }
972  }
973  cache_info->metacontent=(void *) NULL;
974  if (cache_info->metacontent_extent != 0)
975  cache_info->metacontent=(void *) (cache_info->pixels+number_pixels*
976  cache_info->number_channels);
977  return(cache_info->pixels);
978 }
979 ␌
980 /*
981 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
982 % %
983 % %
984 % %
985 % R e a d S t r e a m %
986 % %
987 % %
988 % %
989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
990 %
991 % ReadStream() makes the image pixels available to a user supplied callback
992 % method immediately upon reading a scanline with the ReadImage() method.
993 %
994 % The format of the ReadStream() method is:
995 %
996 % Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
997 % ExceptionInfo *exception)
998 %
999 % A description of each parameter follows:
1000 %
1001 % o image_info: the image info.
1002 %
1003 % o stream: a callback method.
1004 %
1005 % o exception: return any errors or warnings in this structure.
1006 %
1007 */
1008 MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
1009  ExceptionInfo *exception)
1010 {
1011  CacheMethods
1012  cache_methods;
1013 
1014  Image
1015  *image;
1016 
1017  ImageInfo
1018  *read_info;
1019 
1020  /*
1021  Stream image pixels.
1022  */
1023  assert(image_info != (ImageInfo *) NULL);
1024  assert(image_info->signature == MagickCoreSignature);
1025  assert(exception != (ExceptionInfo *) NULL);
1026  assert(exception->signature == MagickCoreSignature);
1027  if (IsEventLogging() != MagickFalse)
1028  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1029  image_info->filename);
1030  read_info=CloneImageInfo(image_info);
1031  read_info->cache=AcquirePixelCache(0);
1032  GetPixelCacheMethods(&cache_methods);
1033  cache_methods.get_virtual_pixel_handler=GetVirtualPixelStream;
1034  cache_methods.get_virtual_pixels_handler=GetVirtualPixelsStream;
1035  cache_methods.get_virtual_metacontent_from_handler=
1036  GetVirtualMetacontentFromStream;
1037  cache_methods.get_authentic_pixels_handler=GetAuthenticPixelsStream;
1038  cache_methods.queue_authentic_pixels_handler=QueueAuthenticPixelsStream;
1039  cache_methods.sync_authentic_pixels_handler=SyncAuthenticPixelsStream;
1040  cache_methods.get_authentic_pixels_from_handler=GetAuthenticPixelsFromStream;
1041  cache_methods.get_authentic_metacontent_from_handler=
1042  GetAuthenticMetacontentFromStream;
1043  cache_methods.get_one_virtual_pixel_from_handler=GetOneVirtualPixelFromStream;
1044  cache_methods.get_one_authentic_pixel_from_handler=
1045  GetOneAuthenticPixelFromStream;
1046  cache_methods.destroy_pixel_handler=DestroyPixelStream;
1047  SetPixelCacheMethods(read_info->cache,&cache_methods);
1048  read_info->stream=stream;
1049  image=ReadImage(read_info,exception);
1050  if (image != (Image *) NULL)
1051  {
1052  InitializePixelChannelMap(image);
1053  ResetPixelCacheChannels(image);
1054  }
1055  read_info=DestroyImageInfo(read_info);
1056  return(image);
1057 }
1058 ␌
1059 /*
1060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1061 % %
1062 % %
1063 % %
1064 + R e s e t S t r e a m A n o n y m o u s M e m o r y %
1065 % %
1066 % %
1067 % %
1068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1069 %
1070 % ResetStreamAnonymousMemory() resets the anonymous_memory value.
1071 %
1072 % The format of the ResetStreamAnonymousMemory method is:
1073 %
1074 % void ResetStreamAnonymousMemory(void)
1075 %
1076 */
1077 MagickPrivate void ResetStreamAnonymousMemory(void)
1078 {
1079 }
1080 ␌
1081 /*
1082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1083 % %
1084 % %
1085 % %
1086 + S e t S t r e a m I n f o C l i e n t D a t a %
1087 % %
1088 % %
1089 % %
1090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1091 %
1092 % SetStreamInfoClientData() sets the stream info client data.
1093 %
1094 % The format of the SetStreamInfoClientData method is:
1095 %
1096 % void SetStreamInfoClientData(StreamInfo *stream_info,
1097 % const void *client_data)
1098 %
1099 % A description of each parameter follows:
1100 %
1101 % o stream_info: the stream info.
1102 %
1103 % o client_data: the client data.
1104 %
1105 */
1106 MagickPrivate void SetStreamInfoClientData(StreamInfo *stream_info,
1107  const void *client_data)
1108 {
1109  assert(stream_info != (StreamInfo *) NULL);
1110  assert(stream_info->signature == MagickCoreSignature);
1111  stream_info->client_data=client_data;
1112 }
1113 ␌
1114 /*
1115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1116 % %
1117 % %
1118 % %
1119 + S e t S t r e a m I n f o M a p %
1120 % %
1121 % %
1122 % %
1123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1124 %
1125 % SetStreamInfoMap() sets the stream info map member.
1126 %
1127 % The format of the SetStreamInfoMap method is:
1128 %
1129 % void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1130 %
1131 % A description of each parameter follows:
1132 %
1133 % o stream_info: the stream info.
1134 %
1135 % o map: the map.
1136 %
1137 */
1138 MagickExport void SetStreamInfoMap(StreamInfo *stream_info,const char *map)
1139 {
1140  assert(stream_info != (StreamInfo *) NULL);
1141  assert(stream_info->signature == MagickCoreSignature);
1142  (void) CloneString(&stream_info->map,map);
1143 }
1144 ␌
1145 /*
1146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1147 % %
1148 % %
1149 % %
1150 + S e t S t r e a m I n f o S t o r a g e T y p e %
1151 % %
1152 % %
1153 % %
1154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155 %
1156 % SetStreamInfoStorageType() sets the stream info storage type member.
1157 %
1158 % The format of the SetStreamInfoStorageType method is:
1159 %
1160 % void SetStreamInfoStorageType(StreamInfo *stream_info,
1161 % const StoreageType *storage_type)
1162 %
1163 % A description of each parameter follows:
1164 %
1165 % o stream_info: the stream info.
1166 %
1167 % o storage_type: the storage type.
1168 %
1169 */
1170 MagickExport void SetStreamInfoStorageType(StreamInfo *stream_info,
1171  const StorageType storage_type)
1172 {
1173  assert(stream_info != (StreamInfo *) NULL);
1174  assert(stream_info->signature == MagickCoreSignature);
1175  stream_info->storage_type=storage_type;
1176 }
1177 ␌
1178 /*
1179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1180 % %
1181 % %
1182 % %
1183 + S t r e a m I m a g e %
1184 % %
1185 % %
1186 % %
1187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1188 %
1189 % StreamImage() streams pixels from an image and writes them in a user
1190 % defined format and storage type (e.g. RGBA as 8-bit unsigned char).
1191 %
1192 % The format of the StreamImage() method is:
1193 %
1194 % Image *StreamImage(const ImageInfo *image_info,
1195 % StreamInfo *stream_info,ExceptionInfo *exception)
1196 %
1197 % A description of each parameter follows:
1198 %
1199 % o image_info: the image info.
1200 %
1201 % o stream_info: the stream info.
1202 %
1203 % o exception: return any errors or warnings in this structure.
1204 %
1205 */
1206 
1207 #if defined(__cplusplus) || defined(c_plusplus)
1208 extern "C" {
1209 #endif
1210 
1211 static size_t WriteStreamImage(const Image *image,const void *pixels,
1212  const size_t columns)
1213 {
1214  CacheInfo
1215  *cache_info;
1216 
1218  extract_info;
1219 
1220  size_t
1221  length,
1222  packet_size;
1223 
1224  ssize_t
1225  count;
1226 
1227  StreamInfo
1228  *stream_info;
1229 
1230  (void) pixels;
1231  stream_info=(StreamInfo *) image->client_data;
1232  switch (stream_info->storage_type)
1233  {
1234  default: packet_size=sizeof(unsigned char); break;
1235  case CharPixel: packet_size=sizeof(unsigned char); break;
1236  case DoublePixel: packet_size=sizeof(double); break;
1237  case FloatPixel: packet_size=sizeof(float); break;
1238  case LongPixel: packet_size=sizeof(unsigned int); break;
1239  case LongLongPixel: packet_size=sizeof(MagickSizeType); break;
1240  case QuantumPixel: packet_size=sizeof(Quantum); break;
1241  case ShortPixel: packet_size=sizeof(unsigned short); break;
1242  }
1243  cache_info=(CacheInfo *) image->cache;
1244  assert(cache_info->signature == MagickCoreSignature);
1245  packet_size*=strlen(stream_info->map);
1246  length=packet_size*cache_info->columns*cache_info->rows;
1247  if (image != stream_info->image)
1248  {
1249  ImageInfo
1250  *write_info;
1251 
1252  /*
1253  Prepare stream for writing.
1254  */
1255  (void) RelinquishAlignedMemory(stream_info->pixels);
1256  stream_info->pixels=(unsigned char *) AcquireAlignedMemory(1,length);
1257  if (stream_info->pixels == (unsigned char *) NULL)
1258  return(0);
1259  (void) memset(stream_info->pixels,0,length);
1260  stream_info->image=image;
1261  write_info=CloneImageInfo(stream_info->image_info);
1262  (void) SetImageInfo(write_info,1,stream_info->exception);
1263  if (write_info->extract != (char *) NULL)
1264  (void) ParseAbsoluteGeometry(write_info->extract,
1265  &stream_info->extract_info);
1266  stream_info->y=0;
1267  write_info=DestroyImageInfo(write_info);
1268  }
1269  extract_info=stream_info->extract_info;
1270  if ((extract_info.width == 0) || (extract_info.height == 0))
1271  {
1272  /*
1273  Write all pixels to stream.
1274  */
1275  (void) StreamImagePixels(stream_info,image,stream_info->exception);
1276  count=WriteBlob(stream_info->stream,length,stream_info->pixels);
1277  stream_info->y++;
1278  return(count == 0 ? 0 : columns);
1279  }
1280  if ((stream_info->y < extract_info.y) ||
1281  (stream_info->y >= (ssize_t) (extract_info.y+extract_info.height)))
1282  {
1283  stream_info->y++;
1284  return(columns);
1285  }
1286  /*
1287  Write a portion of the pixel row to the stream.
1288  */
1289  (void) StreamImagePixels(stream_info,image,stream_info->exception);
1290  length=packet_size*extract_info.width;
1291  count=WriteBlob(stream_info->stream,length,stream_info->pixels+packet_size*
1292  extract_info.x);
1293  stream_info->y++;
1294  return(count == 0 ? 0 : columns);
1295 }
1296 
1297 #if defined(__cplusplus) || defined(c_plusplus)
1298 }
1299 #endif
1300 
1301 MagickExport Image *StreamImage(const ImageInfo *image_info,
1302  StreamInfo *stream_info,ExceptionInfo *exception)
1303 {
1304  Image
1305  *image;
1306 
1307  ImageInfo
1308  *read_info;
1309 
1310  assert(image_info != (const ImageInfo *) NULL);
1311  assert(image_info->signature == MagickCoreSignature);
1312  assert(stream_info != (StreamInfo *) NULL);
1313  assert(stream_info->signature == MagickCoreSignature);
1314  assert(exception != (ExceptionInfo *) NULL);
1315  if (IsEventLogging() != MagickFalse)
1316  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1317  image_info->filename);
1318  read_info=CloneImageInfo(image_info);
1319  stream_info->image_info=image_info;
1320  stream_info->quantum_info=AcquireQuantumInfo(image_info,(Image *) NULL);
1321  if (stream_info->quantum_info == (QuantumInfo *) NULL)
1322  {
1323  read_info=DestroyImageInfo(read_info);
1324  return((Image *) NULL);
1325  }
1326  stream_info->exception=exception;
1327  read_info->client_data=(void *) stream_info;
1328  image=ReadStream(read_info,&WriteStreamImage,exception);
1329  read_info=DestroyImageInfo(read_info);
1330  stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
1331  stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
1332  if (stream_info->quantum_info == (QuantumInfo *) NULL)
1333  image=DestroyImage(image);
1334  return(image);
1335 }
1336 ␌
1337 /*
1338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1339 % %
1340 % %
1341 % %
1342 + S t r e a m I m a g e P i x e l s %
1343 % %
1344 % %
1345 % %
1346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1347 %
1348 % StreamImagePixels() extracts pixel data from an image and returns it in the
1349 % stream_info->pixels structure in the format as defined by
1350 % stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
1351 %
1352 % The format of the StreamImagePixels method is:
1353 %
1354 % MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1355 % const Image *image,ExceptionInfo *exception)
1356 %
1357 % A description of each parameter follows:
1358 %
1359 % o stream_info: the stream info.
1360 %
1361 % o image: the image.
1362 %
1363 % o exception: return any errors or warnings in this structure.
1364 %
1365 */
1366 static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1367  const Image *image,ExceptionInfo *exception)
1368 {
1369  QuantumInfo
1370  *quantum_info;
1371 
1372  QuantumType
1373  *quantum_map;
1374 
1375  const Quantum
1376  *p;
1377 
1378  ssize_t
1379  i,
1380  x;
1381 
1382  size_t
1383  length;
1384 
1385  assert(stream_info != (StreamInfo *) NULL);
1386  assert(stream_info->signature == MagickCoreSignature);
1387  assert(image != (Image *) NULL);
1388  assert(image->signature == MagickCoreSignature);
1389  if (IsEventLogging() != MagickFalse)
1390  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1391  length=strlen(stream_info->map);
1392  quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1393  if (quantum_map == (QuantumType *) NULL)
1394  {
1395  (void) ThrowMagickException(exception,GetMagickModule(),
1396  ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1397  return(MagickFalse);
1398  }
1399  (void) memset(quantum_map,0,length*sizeof(*quantum_map));
1400  for (i=0; i < (ssize_t) length; i++)
1401  {
1402  switch (stream_info->map[i])
1403  {
1404  case 'A':
1405  case 'a':
1406  {
1407  quantum_map[i]=AlphaQuantum;
1408  break;
1409  }
1410  case 'B':
1411  case 'b':
1412  {
1413  quantum_map[i]=BlueQuantum;
1414  break;
1415  }
1416  case 'C':
1417  case 'c':
1418  {
1419  quantum_map[i]=CyanQuantum;
1420  if (image->colorspace == CMYKColorspace)
1421  break;
1422  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1423  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1424  "ColorSeparatedImageRequired","`%s'",stream_info->map);
1425  return(MagickFalse);
1426  }
1427  case 'g':
1428  case 'G':
1429  {
1430  quantum_map[i]=GreenQuantum;
1431  break;
1432  }
1433  case 'I':
1434  case 'i':
1435  {
1436  quantum_map[i]=IndexQuantum;
1437  break;
1438  }
1439  case 'K':
1440  case 'k':
1441  {
1442  quantum_map[i]=BlackQuantum;
1443  if (image->colorspace == CMYKColorspace)
1444  break;
1445  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1446  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1447  "ColorSeparatedImageRequired","`%s'",stream_info->map);
1448  return(MagickFalse);
1449  }
1450  case 'M':
1451  case 'm':
1452  {
1453  quantum_map[i]=MagentaQuantum;
1454  if (image->colorspace == CMYKColorspace)
1455  break;
1456  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1457  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1458  "ColorSeparatedImageRequired","`%s'",stream_info->map);
1459  return(MagickFalse);
1460  }
1461  case 'o':
1462  case 'O':
1463  {
1464  quantum_map[i]=OpacityQuantum;
1465  break;
1466  }
1467  case 'P':
1468  case 'p':
1469  {
1470  quantum_map[i]=UndefinedQuantum;
1471  break;
1472  }
1473  case 'R':
1474  case 'r':
1475  {
1476  quantum_map[i]=RedQuantum;
1477  break;
1478  }
1479  case 'Y':
1480  case 'y':
1481  {
1482  quantum_map[i]=YellowQuantum;
1483  if (image->colorspace == CMYKColorspace)
1484  break;
1485  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1486  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1487  "ColorSeparatedImageRequired","`%s'",stream_info->map);
1488  return(MagickFalse);
1489  }
1490  default:
1491  {
1492  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1493  (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1494  "UnrecognizedPixelMap","`%s'",stream_info->map);
1495  return(MagickFalse);
1496  }
1497  }
1498  }
1499  quantum_info=stream_info->quantum_info;
1500  switch (stream_info->storage_type)
1501  {
1502  case CharPixel:
1503  {
1504  unsigned char
1505  *q;
1506 
1507  q=(unsigned char *) stream_info->pixels;
1508  if (LocaleCompare(stream_info->map,"BGR") == 0)
1509  {
1510  p=GetAuthenticPixelQueue(image);
1511  if (p == (const Quantum *) NULL)
1512  break;
1513  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1514  {
1515  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1516  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1517  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1518  p+=GetPixelChannels(image);
1519  }
1520  break;
1521  }
1522  if (LocaleCompare(stream_info->map,"BGRA") == 0)
1523  {
1524  p=GetAuthenticPixelQueue(image);
1525  if (p == (const Quantum *) NULL)
1526  break;
1527  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1528  {
1529  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1530  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1531  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1532  *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1533  p+=GetPixelChannels(image);
1534  }
1535  break;
1536  }
1537  if (LocaleCompare(stream_info->map,"BGRP") == 0)
1538  {
1539  p=GetAuthenticPixelQueue(image);
1540  if (p == (const Quantum *) NULL)
1541  break;
1542  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1543  {
1544  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1545  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1546  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1547  *q++=ScaleQuantumToChar((Quantum) 0);
1548  p+=GetPixelChannels(image);
1549  }
1550  break;
1551  }
1552  if (LocaleCompare(stream_info->map,"I") == 0)
1553  {
1554  p=GetAuthenticPixelQueue(image);
1555  if (p == (const Quantum *) NULL)
1556  break;
1557  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1558  {
1559  *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
1560  p+=GetPixelChannels(image);
1561  }
1562  break;
1563  }
1564  if (LocaleCompare(stream_info->map,"RGB") == 0)
1565  {
1566  p=GetAuthenticPixelQueue(image);
1567  if (p == (const Quantum *) NULL)
1568  break;
1569  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1570  {
1571  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1572  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1573  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1574  p+=GetPixelChannels(image);
1575  }
1576  break;
1577  }
1578  if (LocaleCompare(stream_info->map,"RGBA") == 0)
1579  {
1580  p=GetAuthenticPixelQueue(image);
1581  if (p == (const Quantum *) NULL)
1582  break;
1583  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1584  {
1585  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1586  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1587  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1588  *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1589  p+=GetPixelChannels(image);
1590  }
1591  break;
1592  }
1593  if (LocaleCompare(stream_info->map,"RGBP") == 0)
1594  {
1595  p=GetAuthenticPixelQueue(image);
1596  if (p == (const Quantum *) NULL)
1597  break;
1598  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1599  {
1600  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1601  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1602  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1603  *q++=ScaleQuantumToChar((Quantum) 0);
1604  p+=GetPixelChannels(image);
1605  }
1606  break;
1607  }
1608  p=GetAuthenticPixelQueue(image);
1609  if (p == (const Quantum *) NULL)
1610  break;
1611  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1612  {
1613  for (i=0; i < (ssize_t) length; i++)
1614  {
1615  *q=0;
1616  switch (quantum_map[i])
1617  {
1618  case RedQuantum:
1619  case CyanQuantum:
1620  {
1621  *q=ScaleQuantumToChar(GetPixelRed(image,p));
1622  break;
1623  }
1624  case GreenQuantum:
1625  case MagentaQuantum:
1626  {
1627  *q=ScaleQuantumToChar(GetPixelGreen(image,p));
1628  break;
1629  }
1630  case BlueQuantum:
1631  case YellowQuantum:
1632  {
1633  *q=ScaleQuantumToChar(GetPixelBlue(image,p));
1634  break;
1635  }
1636  case AlphaQuantum:
1637  {
1638  *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
1639  break;
1640  }
1641  case OpacityQuantum:
1642  {
1643  *q=ScaleQuantumToChar(GetPixelOpacity(image,p));
1644  break;
1645  }
1646  case BlackQuantum:
1647  {
1648  if (image->colorspace == CMYKColorspace)
1649  *q=ScaleQuantumToChar(GetPixelBlack(image,p));
1650  break;
1651  }
1652  case IndexQuantum:
1653  {
1654  *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
1655  break;
1656  }
1657  default:
1658  break;
1659  }
1660  q++;
1661  }
1662  p+=GetPixelChannels(image);
1663  }
1664  break;
1665  }
1666  case DoublePixel:
1667  {
1668  double
1669  *q;
1670 
1671  q=(double *) stream_info->pixels;
1672  if (LocaleCompare(stream_info->map,"BGR") == 0)
1673  {
1674  p=GetAuthenticPixelQueue(image);
1675  if (p == (const Quantum *) NULL)
1676  break;
1677  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1678  {
1679  *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
1680  quantum_info->scale+quantum_info->minimum);
1681  *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
1682  quantum_info->scale+quantum_info->minimum);
1683  *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
1684  quantum_info->scale+quantum_info->minimum);
1685  p+=GetPixelChannels(image);
1686  }
1687  break;
1688  }
1689  if (LocaleCompare(stream_info->map,"BGRA") == 0)
1690  {
1691  p=GetAuthenticPixelQueue(image);
1692  if (p == (const Quantum *) NULL)
1693  break;
1694  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1695  {
1696  *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
1697  quantum_info->scale+quantum_info->minimum);
1698  *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
1699  quantum_info->scale+quantum_info->minimum);
1700  *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
1701  quantum_info->scale+quantum_info->minimum);
1702  *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
1703  quantum_info->scale+quantum_info->minimum);
1704  p+=GetPixelChannels(image);
1705  }
1706  break;
1707  }
1708  if (LocaleCompare(stream_info->map,"BGRP") == 0)
1709  {
1710  p=GetAuthenticPixelQueue(image);
1711  if (p == (const Quantum *) NULL)
1712  break;
1713  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1714  {
1715  *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
1716  quantum_info->scale+quantum_info->minimum);
1717  *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
1718  quantum_info->scale+quantum_info->minimum);
1719  *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
1720  quantum_info->scale+quantum_info->minimum);
1721  *q++=0.0;
1722  p+=GetPixelChannels(image);
1723  }
1724  break;
1725  }
1726  if (LocaleCompare(stream_info->map,"I") == 0)
1727  {
1728  p=GetAuthenticPixelQueue(image);
1729  if (p == (const Quantum *) NULL)
1730  break;
1731  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1732  {
1733  *q++=(double) ((QuantumScale*GetPixelIntensity(image,p))*
1734  quantum_info->scale+quantum_info->minimum);
1735  p+=GetPixelChannels(image);
1736  }
1737  break;
1738  }
1739  if (LocaleCompare(stream_info->map,"RGB") == 0)
1740  {
1741  p=GetAuthenticPixelQueue(image);
1742  if (p == (const Quantum *) NULL)
1743  break;
1744  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1745  {
1746  *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
1747  quantum_info->scale+quantum_info->minimum);
1748  *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
1749  quantum_info->scale+quantum_info->minimum);
1750  *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
1751  quantum_info->scale+quantum_info->minimum);
1752  p+=GetPixelChannels(image);
1753  }
1754  break;
1755  }
1756  if (LocaleCompare(stream_info->map,"RGBA") == 0)
1757  {
1758  p=GetAuthenticPixelQueue(image);
1759  if (p == (const Quantum *) NULL)
1760  break;
1761  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1762  {
1763  *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
1764  quantum_info->scale+quantum_info->minimum);
1765  *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
1766  quantum_info->scale+quantum_info->minimum);
1767  *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
1768  quantum_info->scale+quantum_info->minimum);
1769  *q++=(double) ((QuantumScale*GetPixelAlpha(image,p))*
1770  quantum_info->scale+quantum_info->minimum);
1771  p+=GetPixelChannels(image);
1772  }
1773  break;
1774  }
1775  if (LocaleCompare(stream_info->map,"RGBP") == 0)
1776  {
1777  p=GetAuthenticPixelQueue(image);
1778  if (p == (const Quantum *) NULL)
1779  break;
1780  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1781  {
1782  *q++=(double) ((QuantumScale*GetPixelRed(image,p))*
1783  quantum_info->scale+quantum_info->minimum);
1784  *q++=(double) ((QuantumScale*GetPixelGreen(image,p))*
1785  quantum_info->scale+quantum_info->minimum);
1786  *q++=(double) ((QuantumScale*GetPixelBlue(image,p))*
1787  quantum_info->scale+quantum_info->minimum);
1788  *q++=0.0;
1789  p+=GetPixelChannels(image);
1790  }
1791  break;
1792  }
1793  p=GetAuthenticPixelQueue(image);
1794  if (p == (const Quantum *) NULL)
1795  break;
1796  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1797  {
1798  for (i=0; i < (ssize_t) length; i++)
1799  {
1800  *q=0;
1801  switch (quantum_map[i])
1802  {
1803  case RedQuantum:
1804  case CyanQuantum:
1805  {
1806  *q=(double) ((QuantumScale*GetPixelRed(image,p))*
1807  quantum_info->scale+quantum_info->minimum);
1808  break;
1809  }
1810  case GreenQuantum:
1811  case MagentaQuantum:
1812  {
1813  *q=(double) ((QuantumScale*GetPixelGreen(image,p))*
1814  quantum_info->scale+quantum_info->minimum);
1815  break;
1816  }
1817  case BlueQuantum:
1818  case YellowQuantum:
1819  {
1820  *q=(double) ((QuantumScale*GetPixelBlue(image,p))*
1821  quantum_info->scale+quantum_info->minimum);
1822  break;
1823  }
1824  case AlphaQuantum:
1825  {
1826  *q=(double) ((QuantumScale*GetPixelAlpha(image,p))*
1827  quantum_info->scale+quantum_info->minimum);
1828  break;
1829  }
1830  case OpacityQuantum:
1831  {
1832  *q=(double) ((QuantumScale*GetPixelOpacity(image,p))*
1833  quantum_info->scale+quantum_info->minimum);
1834  break;
1835  }
1836  case BlackQuantum:
1837  {
1838  if (image->colorspace == CMYKColorspace)
1839  *q=(double) ((QuantumScale*GetPixelBlack(image,p))*
1840  quantum_info->scale+quantum_info->minimum);
1841  break;
1842  }
1843  case IndexQuantum:
1844  {
1845  *q=(double) ((QuantumScale*GetPixelIntensity(image,p))*
1846  quantum_info->scale+quantum_info->minimum);
1847  break;
1848  }
1849  default:
1850  *q=0;
1851  }
1852  q++;
1853  }
1854  p+=GetPixelChannels(image);
1855  }
1856  break;
1857  }
1858  case FloatPixel:
1859  {
1860  float
1861  *q;
1862 
1863  q=(float *) stream_info->pixels;
1864  if (LocaleCompare(stream_info->map,"BGR") == 0)
1865  {
1866  p=GetAuthenticPixelQueue(image);
1867  if (p == (const Quantum *) NULL)
1868  break;
1869  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1870  {
1871  *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
1872  quantum_info->scale+quantum_info->minimum);
1873  *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
1874  quantum_info->scale+quantum_info->minimum);
1875  *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
1876  quantum_info->scale+quantum_info->minimum);
1877  p+=GetPixelChannels(image);
1878  }
1879  break;
1880  }
1881  if (LocaleCompare(stream_info->map,"BGRA") == 0)
1882  {
1883  p=GetAuthenticPixelQueue(image);
1884  if (p == (const Quantum *) NULL)
1885  break;
1886  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1887  {
1888  *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
1889  quantum_info->scale+quantum_info->minimum);
1890  *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
1891  quantum_info->scale+quantum_info->minimum);
1892  *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
1893  quantum_info->scale+quantum_info->minimum);
1894  *q++=(float) ((QuantumScale*GetPixelAlpha(image,p))*
1895  quantum_info->scale+quantum_info->minimum);
1896  p+=GetPixelChannels(image);
1897  }
1898  break;
1899  }
1900  if (LocaleCompare(stream_info->map,"BGRP") == 0)
1901  {
1902  p=GetAuthenticPixelQueue(image);
1903  if (p == (const Quantum *) NULL)
1904  break;
1905  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1906  {
1907  *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
1908  quantum_info->scale+quantum_info->minimum);
1909  *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
1910  quantum_info->scale+quantum_info->minimum);
1911  *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
1912  quantum_info->scale+quantum_info->minimum);
1913  *q++=0.0;
1914  p+=GetPixelChannels(image);
1915  }
1916  break;
1917  }
1918  if (LocaleCompare(stream_info->map,"I") == 0)
1919  {
1920  p=GetAuthenticPixelQueue(image);
1921  if (p == (const Quantum *) NULL)
1922  break;
1923  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1924  {
1925  *q++=(float) ((QuantumScale*GetPixelIntensity(image,p))*
1926  quantum_info->scale+quantum_info->minimum);
1927  p+=GetPixelChannels(image);
1928  }
1929  break;
1930  }
1931  if (LocaleCompare(stream_info->map,"RGB") == 0)
1932  {
1933  p=GetAuthenticPixelQueue(image);
1934  if (p == (const Quantum *) NULL)
1935  break;
1936  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1937  {
1938  *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
1939  quantum_info->scale+quantum_info->minimum);
1940  *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
1941  quantum_info->scale+quantum_info->minimum);
1942  *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
1943  quantum_info->scale+quantum_info->minimum);
1944  p+=GetPixelChannels(image);
1945  }
1946  break;
1947  }
1948  if (LocaleCompare(stream_info->map,"RGBA") == 0)
1949  {
1950  p=GetAuthenticPixelQueue(image);
1951  if (p == (const Quantum *) NULL)
1952  break;
1953  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1954  {
1955  *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
1956  quantum_info->scale+quantum_info->minimum);
1957  *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
1958  quantum_info->scale+quantum_info->minimum);
1959  *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
1960  quantum_info->scale+quantum_info->minimum);
1961  *q++=(float) ((QuantumScale*GetPixelAlpha(image,p))*
1962  quantum_info->scale+quantum_info->minimum);
1963  p+=GetPixelChannels(image);
1964  }
1965  break;
1966  }
1967  if (LocaleCompare(stream_info->map,"RGBP") == 0)
1968  {
1969  p=GetAuthenticPixelQueue(image);
1970  if (p == (const Quantum *) NULL)
1971  break;
1972  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1973  {
1974  *q++=(float) ((QuantumScale*GetPixelRed(image,p))*
1975  quantum_info->scale+quantum_info->minimum);
1976  *q++=(float) ((QuantumScale*GetPixelGreen(image,p))*
1977  quantum_info->scale+quantum_info->minimum);
1978  *q++=(float) ((QuantumScale*GetPixelBlue(image,p))*
1979  quantum_info->scale+quantum_info->minimum);
1980  *q++=0.0;
1981  p+=GetPixelChannels(image);
1982  }
1983  break;
1984  }
1985  p=GetAuthenticPixelQueue(image);
1986  if (p == (const Quantum *) NULL)
1987  break;
1988  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1989  {
1990  for (i=0; i < (ssize_t) length; i++)
1991  {
1992  *q=0;
1993  switch (quantum_map[i])
1994  {
1995  case RedQuantum:
1996  case CyanQuantum:
1997  {
1998  *q=(float) ((QuantumScale*GetPixelRed(image,p))*
1999  quantum_info->scale+quantum_info->minimum);
2000  break;
2001  }
2002  case GreenQuantum:
2003  case MagentaQuantum:
2004  {
2005  *q=(float) ((QuantumScale*GetPixelGreen(image,p))*
2006  quantum_info->scale+quantum_info->minimum);
2007  break;
2008  }
2009  case BlueQuantum:
2010  case YellowQuantum:
2011  {
2012  *q=(float) ((QuantumScale*GetPixelBlue(image,p))*
2013  quantum_info->scale+quantum_info->minimum);
2014  break;
2015  }
2016  case AlphaQuantum:
2017  {
2018  *q=(float) ((QuantumScale*GetPixelAlpha(image,p))*
2019  quantum_info->scale+quantum_info->minimum);
2020  break;
2021  }
2022  case OpacityQuantum:
2023  {
2024  *q=(float) ((QuantumScale*GetPixelOpacity(image,p))*
2025  quantum_info->scale+quantum_info->minimum);
2026  break;
2027  }
2028  case BlackQuantum:
2029  {
2030  if (image->colorspace == CMYKColorspace)
2031  *q=(float) ((QuantumScale*GetPixelBlack(image,p))*
2032  quantum_info->scale+quantum_info->minimum);
2033  break;
2034  }
2035  case IndexQuantum:
2036  {
2037  *q=(float) ((QuantumScale*GetPixelIntensity(image,p))*
2038  quantum_info->scale+quantum_info->minimum);
2039  break;
2040  }
2041  default:
2042  *q=0;
2043  }
2044  q++;
2045  }
2046  p+=GetPixelChannels(image);
2047  }
2048  break;
2049  }
2050  case LongPixel:
2051  {
2052  unsigned int
2053  *q;
2054 
2055  q=(unsigned int *) stream_info->pixels;
2056  if (LocaleCompare(stream_info->map,"BGR") == 0)
2057  {
2058  p=GetAuthenticPixelQueue(image);
2059  if (p == (const Quantum *) NULL)
2060  break;
2061  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2062  {
2063  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2064  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2065  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2066  p+=GetPixelChannels(image);
2067  }
2068  break;
2069  }
2070  if (LocaleCompare(stream_info->map,"BGRA") == 0)
2071  {
2072  p=GetAuthenticPixelQueue(image);
2073  if (p == (const Quantum *) NULL)
2074  break;
2075  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2076  {
2077  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2078  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2079  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2080  *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
2081  p+=GetPixelChannels(image);
2082  }
2083  break;
2084  }
2085  if (LocaleCompare(stream_info->map,"BGRP") == 0)
2086  {
2087  p=GetAuthenticPixelQueue(image);
2088  if (p == (const Quantum *) NULL)
2089  break;
2090  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2091  {
2092  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2093  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2094  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2095  *q++=0;
2096  p+=GetPixelChannels(image);
2097  }
2098  break;
2099  }
2100  if (LocaleCompare(stream_info->map,"I") == 0)
2101  {
2102  p=GetAuthenticPixelQueue(image);
2103  if (p == (const Quantum *) NULL)
2104  break;
2105  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2106  {
2107  *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
2108  p+=GetPixelChannels(image);
2109  }
2110  break;
2111  }
2112  if (LocaleCompare(stream_info->map,"RGB") == 0)
2113  {
2114  p=GetAuthenticPixelQueue(image);
2115  if (p == (const Quantum *) NULL)
2116  break;
2117  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2118  {
2119  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2120  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2121  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2122  p+=GetPixelChannels(image);
2123  }
2124  break;
2125  }
2126  if (LocaleCompare(stream_info->map,"RGBA") == 0)
2127  {
2128  p=GetAuthenticPixelQueue(image);
2129  if (p == (const Quantum *) NULL)
2130  break;
2131  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2132  {
2133  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2134  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2135  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2136  *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
2137  p+=GetPixelChannels(image);
2138  }
2139  break;
2140  }
2141  if (LocaleCompare(stream_info->map,"RGBP") == 0)
2142  {
2143  p=GetAuthenticPixelQueue(image);
2144  if (p == (const Quantum *) NULL)
2145  break;
2146  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2147  {
2148  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2149  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2150  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2151  *q++=0;
2152  p+=GetPixelChannels(image);
2153  }
2154  break;
2155  }
2156  p=GetAuthenticPixelQueue(image);
2157  if (p == (const Quantum *) NULL)
2158  break;
2159  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2160  {
2161  for (i=0; i < (ssize_t) length; i++)
2162  {
2163  *q=0;
2164  switch (quantum_map[i])
2165  {
2166  case RedQuantum:
2167  case CyanQuantum:
2168  {
2169  *q=ScaleQuantumToLong(GetPixelRed(image,p));
2170  break;
2171  }
2172  case GreenQuantum:
2173  case MagentaQuantum:
2174  {
2175  *q=ScaleQuantumToLong(GetPixelGreen(image,p));
2176  break;
2177  }
2178  case BlueQuantum:
2179  case YellowQuantum:
2180  {
2181  *q=ScaleQuantumToLong(GetPixelBlue(image,p));
2182  break;
2183  }
2184  case AlphaQuantum:
2185  {
2186  *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
2187  break;
2188  }
2189  case OpacityQuantum:
2190  {
2191  *q=ScaleQuantumToLong(GetPixelOpacity(image,p));
2192  break;
2193  }
2194  case BlackQuantum:
2195  {
2196  if (image->colorspace == CMYKColorspace)
2197  *q=ScaleQuantumToLong(GetPixelBlack(image,p));
2198  break;
2199  }
2200  case IndexQuantum:
2201  {
2202  *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
2203  break;
2204  }
2205  default:
2206  break;
2207  }
2208  q++;
2209  }
2210  p+=GetPixelChannels(image);
2211  }
2212  break;
2213  }
2214  case LongLongPixel:
2215  {
2216  MagickSizeType
2217  *q;
2218 
2219  q=(MagickSizeType *) stream_info->pixels;
2220  if (LocaleCompare(stream_info->map,"BGR") == 0)
2221  {
2222  p=GetAuthenticPixelQueue(image);
2223  if (p == (const Quantum *) NULL)
2224  break;
2225  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2226  {
2227  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2228  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2229  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2230  p+=GetPixelChannels(image);
2231  }
2232  break;
2233  }
2234  if (LocaleCompare(stream_info->map,"BGRA") == 0)
2235  {
2236  p=GetAuthenticPixelQueue(image);
2237  if (p == (const Quantum *) NULL)
2238  break;
2239  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2240  {
2241  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2242  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2243  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2244  *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2245  p+=GetPixelChannels(image);
2246  }
2247  break;
2248  }
2249  if (LocaleCompare(stream_info->map,"BGRP") == 0)
2250  {
2251  p=GetAuthenticPixelQueue(image);
2252  if (p == (const Quantum *) NULL)
2253  break;
2254  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2255  {
2256  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2257  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2258  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2259  *q++=0U;
2260  p+=GetPixelChannels(image);
2261  }
2262  break;
2263  }
2264  if (LocaleCompare(stream_info->map,"I") == 0)
2265  {
2266  p=GetAuthenticPixelQueue(image);
2267  if (p == (const Quantum *) NULL)
2268  break;
2269  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2270  {
2271  *q++=ScaleQuantumToLongLong(ClampToQuantum(
2272  GetPixelIntensity(image,p)));
2273  p+=GetPixelChannels(image);
2274  }
2275  break;
2276  }
2277  if (LocaleCompare(stream_info->map,"RGB") == 0)
2278  {
2279  p=GetAuthenticPixelQueue(image);
2280  if (p == (const Quantum *) NULL)
2281  break;
2282  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2283  {
2284  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2285  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2286  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2287  p+=GetPixelChannels(image);
2288  }
2289  break;
2290  }
2291  if (LocaleCompare(stream_info->map,"RGBA") == 0)
2292  {
2293  p=GetAuthenticPixelQueue(image);
2294  if (p == (const Quantum *) NULL)
2295  break;
2296  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2297  {
2298  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2299  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2300  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2301  *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2302  p+=GetPixelChannels(image);
2303  }
2304  break;
2305  }
2306  if (LocaleCompare(stream_info->map,"RGBP") == 0)
2307  {
2308  p=GetAuthenticPixelQueue(image);
2309  if (p == (const Quantum *) NULL)
2310  break;
2311  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2312  {
2313  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2314  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2315  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2316  *q++=0U;
2317  p+=GetPixelChannels(image);
2318  }
2319  break;
2320  }
2321  p=GetAuthenticPixelQueue(image);
2322  if (p == (const Quantum *) NULL)
2323  break;
2324  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2325  {
2326  for (i=0; i < (ssize_t) length; i++)
2327  {
2328  *q=0;
2329  switch (quantum_map[i])
2330  {
2331  case RedQuantum:
2332  case CyanQuantum:
2333  {
2334  *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
2335  break;
2336  }
2337  case GreenQuantum:
2338  case MagentaQuantum:
2339  {
2340  *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2341  break;
2342  }
2343  case BlueQuantum:
2344  case YellowQuantum:
2345  {
2346  *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2347  break;
2348  }
2349  case AlphaQuantum:
2350  {
2351  *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2352  break;
2353  }
2354  case OpacityQuantum:
2355  {
2356  *q=ScaleQuantumToLongLong(GetPixelOpacity(image,p));
2357  break;
2358  }
2359  case BlackQuantum:
2360  {
2361  if (image->colorspace == CMYKColorspace)
2362  *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
2363  break;
2364  }
2365  case IndexQuantum:
2366  {
2367  *q=ScaleQuantumToLongLong(ClampToQuantum(
2368  GetPixelIntensity(image,p)));
2369  break;
2370  }
2371  default:
2372  *q=0;
2373  }
2374  q++;
2375  }
2376  p+=GetPixelChannels(image);
2377  }
2378  break;
2379  }
2380  case QuantumPixel:
2381  {
2382  Quantum
2383  *q;
2384 
2385  q=(Quantum *) stream_info->pixels;
2386  if (LocaleCompare(stream_info->map,"BGR") == 0)
2387  {
2388  p=GetAuthenticPixelQueue(image);
2389  if (p == (const Quantum *) NULL)
2390  break;
2391  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2392  {
2393  *q++=GetPixelBlue(image,p);
2394  *q++=GetPixelGreen(image,p);
2395  *q++=GetPixelRed(image,p);
2396  p+=GetPixelChannels(image);
2397  }
2398  break;
2399  }
2400  if (LocaleCompare(stream_info->map,"BGRA") == 0)
2401  {
2402  p=GetAuthenticPixelQueue(image);
2403  if (p == (const Quantum *) NULL)
2404  break;
2405  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2406  {
2407  *q++=GetPixelBlue(image,p);
2408  *q++=GetPixelGreen(image,p);
2409  *q++=GetPixelRed(image,p);
2410  *q++=GetPixelAlpha(image,p);
2411  p+=GetPixelChannels(image);
2412  }
2413  break;
2414  }
2415  if (LocaleCompare(stream_info->map,"BGRP") == 0)
2416  {
2417  p=GetAuthenticPixelQueue(image);
2418  if (p == (const Quantum *) NULL)
2419  break;
2420  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2421  {
2422  *q++=GetPixelBlue(image,p);
2423  *q++=GetPixelGreen(image,p);
2424  *q++=GetPixelRed(image,p);
2425  *q++=(Quantum) 0;
2426  p+=GetPixelChannels(image);
2427  }
2428  break;
2429  }
2430  if (LocaleCompare(stream_info->map,"I") == 0)
2431  {
2432  p=GetAuthenticPixelQueue(image);
2433  if (p == (const Quantum *) NULL)
2434  break;
2435  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2436  {
2437  *q++=ClampToQuantum(GetPixelIntensity(image,p));
2438  p+=GetPixelChannels(image);
2439  }
2440  break;
2441  }
2442  if (LocaleCompare(stream_info->map,"RGB") == 0)
2443  {
2444  p=GetAuthenticPixelQueue(image);
2445  if (p == (const Quantum *) NULL)
2446  break;
2447  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2448  {
2449  *q++=GetPixelRed(image,p);
2450  *q++=GetPixelGreen(image,p);
2451  *q++=GetPixelBlue(image,p);
2452  p+=GetPixelChannels(image);
2453  }
2454  break;
2455  }
2456  if (LocaleCompare(stream_info->map,"RGBA") == 0)
2457  {
2458  p=GetAuthenticPixelQueue(image);
2459  if (p == (const Quantum *) NULL)
2460  break;
2461  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2462  {
2463  *q++=GetPixelRed(image,p);
2464  *q++=GetPixelGreen(image,p);
2465  *q++=GetPixelBlue(image,p);
2466  *q++=GetPixelAlpha(image,p);
2467  p+=GetPixelChannels(image);
2468  }
2469  break;
2470  }
2471  if (LocaleCompare(stream_info->map,"RGBP") == 0)
2472  {
2473  p=GetAuthenticPixelQueue(image);
2474  if (p == (const Quantum *) NULL)
2475  break;
2476  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2477  {
2478  *q++=GetPixelRed(image,p);
2479  *q++=GetPixelGreen(image,p);
2480  *q++=GetPixelBlue(image,p);
2481  *q++=(Quantum) 0;
2482  p+=GetPixelChannels(image);
2483  }
2484  break;
2485  }
2486  p=GetAuthenticPixelQueue(image);
2487  if (p == (const Quantum *) NULL)
2488  break;
2489  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2490  {
2491  for (i=0; i < (ssize_t) length; i++)
2492  {
2493  *q=(Quantum) 0;
2494  switch (quantum_map[i])
2495  {
2496  case RedQuantum:
2497  case CyanQuantum:
2498  {
2499  *q=GetPixelRed(image,p);
2500  break;
2501  }
2502  case GreenQuantum:
2503  case MagentaQuantum:
2504  {
2505  *q=GetPixelGreen(image,p);
2506  break;
2507  }
2508  case BlueQuantum:
2509  case YellowQuantum:
2510  {
2511  *q=GetPixelBlue(image,p);
2512  break;
2513  }
2514  case AlphaQuantum:
2515  {
2516  *q=GetPixelAlpha(image,p);
2517  break;
2518  }
2519  case OpacityQuantum:
2520  {
2521  *q=GetPixelOpacity(image,p);
2522  break;
2523  }
2524  case BlackQuantum:
2525  {
2526  if (image->colorspace == CMYKColorspace)
2527  *q=GetPixelBlack(image,p);
2528  break;
2529  }
2530  case IndexQuantum:
2531  {
2532  *q=ClampToQuantum(GetPixelIntensity(image,p));
2533  break;
2534  }
2535  default:
2536  *q=(Quantum) 0;
2537  }
2538  q++;
2539  }
2540  p+=GetPixelChannels(image);
2541  }
2542  break;
2543  }
2544  case ShortPixel:
2545  {
2546  unsigned short
2547  *q;
2548 
2549  q=(unsigned short *) stream_info->pixels;
2550  if (LocaleCompare(stream_info->map,"BGR") == 0)
2551  {
2552  p=GetAuthenticPixelQueue(image);
2553  if (p == (const Quantum *) NULL)
2554  break;
2555  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2556  {
2557  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2558  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2559  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2560  p+=GetPixelChannels(image);
2561  }
2562  break;
2563  }
2564  if (LocaleCompare(stream_info->map,"BGRA") == 0)
2565  {
2566  p=GetAuthenticPixelQueue(image);
2567  if (p == (const Quantum *) NULL)
2568  break;
2569  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2570  {
2571  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2572  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2573  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2574  *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
2575  p+=GetPixelChannels(image);
2576  }
2577  break;
2578  }
2579  if (LocaleCompare(stream_info->map,"BGRP") == 0)
2580  {
2581  p=GetAuthenticPixelQueue(image);
2582  if (p == (const Quantum *) NULL)
2583  break;
2584  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2585  {
2586  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2587  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2588  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2589  *q++=0;
2590  p+=GetPixelChannels(image);
2591  }
2592  break;
2593  }
2594  if (LocaleCompare(stream_info->map,"I") == 0)
2595  {
2596  p=GetAuthenticPixelQueue(image);
2597  if (p == (const Quantum *) NULL)
2598  break;
2599  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2600  {
2601  *q++=ScaleQuantumToShort(ClampToQuantum(
2602  GetPixelIntensity(image,p)));
2603  p+=GetPixelChannels(image);
2604  }
2605  break;
2606  }
2607  if (LocaleCompare(stream_info->map,"RGB") == 0)
2608  {
2609  p=GetAuthenticPixelQueue(image);
2610  if (p == (const Quantum *) NULL)
2611  break;
2612  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2613  {
2614  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2615  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2616  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2617  p+=GetPixelChannels(image);
2618  }
2619  break;
2620  }
2621  if (LocaleCompare(stream_info->map,"RGBA") == 0)
2622  {
2623  p=GetAuthenticPixelQueue(image);
2624  if (p == (const Quantum *) NULL)
2625  break;
2626  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2627  {
2628  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2629  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2630  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2631  *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
2632  p+=GetPixelChannels(image);
2633  }
2634  break;
2635  }
2636  if (LocaleCompare(stream_info->map,"RGBP") == 0)
2637  {
2638  p=GetAuthenticPixelQueue(image);
2639  if (p == (const Quantum *) NULL)
2640  break;
2641  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2642  {
2643  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2644  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2645  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2646  *q++=0;
2647  p+=GetPixelChannels(image);
2648  }
2649  break;
2650  }
2651  p=GetAuthenticPixelQueue(image);
2652  if (p == (const Quantum *) NULL)
2653  break;
2654  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2655  {
2656  for (i=0; i < (ssize_t) length; i++)
2657  {
2658  *q=0;
2659  switch (quantum_map[i])
2660  {
2661  case RedQuantum:
2662  case CyanQuantum:
2663  {
2664  *q=ScaleQuantumToShort(GetPixelRed(image,p));
2665  break;
2666  }
2667  case GreenQuantum:
2668  case MagentaQuantum:
2669  {
2670  *q=ScaleQuantumToShort(GetPixelGreen(image,p));
2671  break;
2672  }
2673  case BlueQuantum:
2674  case YellowQuantum:
2675  {
2676  *q=ScaleQuantumToShort(GetPixelBlue(image,p));
2677  break;
2678  }
2679  case AlphaQuantum:
2680  {
2681  *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
2682  break;
2683  }
2684  case OpacityQuantum:
2685  {
2686  *q=ScaleQuantumToShort(GetPixelOpacity(image,p));
2687  break;
2688  }
2689  case BlackQuantum:
2690  {
2691  if (image->colorspace == CMYKColorspace)
2692  *q=ScaleQuantumToShort(GetPixelBlack(image,p));
2693  break;
2694  }
2695  case IndexQuantum:
2696  {
2697  *q=ScaleQuantumToShort(ClampToQuantum(
2698  GetPixelIntensity(image,p)));
2699  break;
2700  }
2701  default:
2702  break;
2703  }
2704  q++;
2705  }
2706  p+=GetPixelChannels(image);
2707  }
2708  break;
2709  }
2710  default:
2711  {
2712  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2713  (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2714  "UnrecognizedPixelMap","`%s'",stream_info->map);
2715  break;
2716  }
2717  }
2718  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2719  return(MagickTrue);
2720 }
2721 ␌
2722 /*
2723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2724 % %
2725 % %
2726 % %
2727 + 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 %
2728 % %
2729 % %
2730 % %
2731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2732 %
2733 % SyncAuthenticPixelsStream() calls the user supplied callback method with
2734 % the latest stream of pixels.
2735 %
2736 % The format of the SyncAuthenticPixelsStream method is:
2737 %
2738 % MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2739 % ExceptionInfo *exception)
2740 %
2741 % A description of each parameter follows:
2742 %
2743 % o image: the image.
2744 %
2745 % o exception: return any errors or warnings in this structure.
2746 %
2747 */
2748 static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2749  ExceptionInfo *exception)
2750 {
2751  CacheInfo
2752  *cache_info;
2753 
2754  size_t
2755  length;
2756 
2757  StreamHandler
2758  stream_handler;
2759 
2760  assert(image != (Image *) NULL);
2761  assert(image->signature == MagickCoreSignature);
2762  if (IsEventLogging() != MagickFalse)
2763  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2764  cache_info=(CacheInfo *) image->cache;
2765  assert(cache_info->signature == MagickCoreSignature);
2766  stream_handler=GetBlobStreamHandler(image);
2767  if (stream_handler == (StreamHandler) NULL)
2768  {
2769  (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
2770  "NoStreamHandlerIsDefined","`%s'",image->filename);
2771  return(MagickFalse);
2772  }
2773  length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
2774  return(length == cache_info->columns ? MagickTrue : MagickFalse);
2775 }
2776 ␌
2777 /*
2778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2779 % %
2780 % %
2781 % %
2782 % W r i t e S t r e a m %
2783 % %
2784 % %
2785 % %
2786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2787 %
2788 % WriteStream() makes the image pixels available to a user supplied callback
2789 % method immediately upon writing pixel data with the WriteImage() method.
2790 %
2791 % The format of the WriteStream() method is:
2792 %
2793 % MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
2794 % StreamHandler stream,ExceptionInfo *exception)
2795 %
2796 % A description of each parameter follows:
2797 %
2798 % o image_info: the image info.
2799 %
2800 % o stream: A callback method.
2801 %
2802 % o exception: return any errors or warnings in this structure.
2803 %
2804 */
2805 MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
2806  Image *image,StreamHandler stream,ExceptionInfo *exception)
2807 {
2808  ImageInfo
2809  *write_info;
2810 
2811  MagickBooleanType
2812  status;
2813 
2814  assert(image_info != (ImageInfo *) NULL);
2815  assert(image_info->signature == MagickCoreSignature);
2816  if (IsEventLogging() != MagickFalse)
2817  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2818  image_info->filename);
2819  assert(image != (Image *) NULL);
2820  assert(image->signature == MagickCoreSignature);
2821  write_info=CloneImageInfo(image_info);
2822  *write_info->magick='\0';
2823  write_info->stream=stream;
2824  status=WriteImage(write_info,image,exception);
2825  write_info=DestroyImageInfo(write_info);
2826  return(status);
2827 }
Definition: image.h:152