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