MagickCore  7.1.1-43
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/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+=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+=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  stream_info->quantum_info=AcquireQuantumInfo(image_info,(Image *) NULL);
1325  if (stream_info->quantum_info == (QuantumInfo *) NULL)
1326  {
1327  read_info=DestroyImageInfo(read_info);
1328  return((Image *) NULL);
1329  }
1330  stream_info->exception=exception;
1331  read_info->client_data=(void *) stream_info;
1332  image=ReadStream(read_info,&WriteStreamImage,exception);
1333  read_info=DestroyImageInfo(read_info);
1334  stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
1335  stream_info->quantum_info=AcquireQuantumInfo(image_info,image);
1336  if (stream_info->quantum_info == (QuantumInfo *) NULL)
1337  image=DestroyImage(image);
1338  return(image);
1339 }
1340 
1341 /*
1342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1343 % %
1344 % %
1345 % %
1346 + S t r e a m I m a g e P i x e l s %
1347 % %
1348 % %
1349 % %
1350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1351 %
1352 % StreamImagePixels() extracts pixel data from an image and returns it in the
1353 % stream_info->pixels structure in the format as defined by
1354 % stream_info->quantum_info->map and stream_info->quantum_info->storage_type.
1355 %
1356 % The format of the StreamImagePixels method is:
1357 %
1358 % MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1359 % const Image *image,ExceptionInfo *exception)
1360 %
1361 % A description of each parameter follows:
1362 %
1363 % o stream_info: the stream info.
1364 %
1365 % o image: the image.
1366 %
1367 % o exception: return any errors or warnings in this structure.
1368 %
1369 */
1370 static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
1371  const Image *image,ExceptionInfo *exception)
1372 {
1373  QuantumInfo
1374  *quantum_info;
1375 
1376  QuantumType
1377  *quantum_map;
1378 
1379  const Quantum
1380  *p;
1381 
1382  ssize_t
1383  i,
1384  x;
1385 
1386  size_t
1387  length;
1388 
1389  assert(stream_info != (StreamInfo *) NULL);
1390  assert(stream_info->signature == MagickCoreSignature);
1391  assert(image != (Image *) NULL);
1392  assert(image->signature == MagickCoreSignature);
1393  if (IsEventLogging() != MagickFalse)
1394  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1395  length=strlen(stream_info->map);
1396  quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1397  if (quantum_map == (QuantumType *) NULL)
1398  {
1399  (void) ThrowMagickException(exception,GetMagickModule(),
1400  ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1401  return(MagickFalse);
1402  }
1403  (void) memset(quantum_map,0,length*sizeof(*quantum_map));
1404  for (i=0; i < (ssize_t) length; i++)
1405  {
1406  switch (stream_info->map[i])
1407  {
1408  case 'A':
1409  case 'a':
1410  {
1411  quantum_map[i]=AlphaQuantum;
1412  break;
1413  }
1414  case 'B':
1415  case 'b':
1416  {
1417  quantum_map[i]=BlueQuantum;
1418  break;
1419  }
1420  case 'C':
1421  case 'c':
1422  {
1423  quantum_map[i]=CyanQuantum;
1424  if (image->colorspace == CMYKColorspace)
1425  break;
1426  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1427  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1428  "ColorSeparatedImageRequired","`%s'",stream_info->map);
1429  return(MagickFalse);
1430  }
1431  case 'g':
1432  case 'G':
1433  {
1434  quantum_map[i]=GreenQuantum;
1435  break;
1436  }
1437  case 'I':
1438  case 'i':
1439  {
1440  quantum_map[i]=IndexQuantum;
1441  break;
1442  }
1443  case 'K':
1444  case 'k':
1445  {
1446  quantum_map[i]=BlackQuantum;
1447  if (image->colorspace == CMYKColorspace)
1448  break;
1449  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1450  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1451  "ColorSeparatedImageRequired","`%s'",stream_info->map);
1452  return(MagickFalse);
1453  }
1454  case 'M':
1455  case 'm':
1456  {
1457  quantum_map[i]=MagentaQuantum;
1458  if (image->colorspace == CMYKColorspace)
1459  break;
1460  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1461  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1462  "ColorSeparatedImageRequired","`%s'",stream_info->map);
1463  return(MagickFalse);
1464  }
1465  case 'o':
1466  case 'O':
1467  {
1468  quantum_map[i]=OpacityQuantum;
1469  break;
1470  }
1471  case 'P':
1472  case 'p':
1473  {
1474  quantum_map[i]=UndefinedQuantum;
1475  break;
1476  }
1477  case 'R':
1478  case 'r':
1479  {
1480  quantum_map[i]=RedQuantum;
1481  break;
1482  }
1483  case 'Y':
1484  case 'y':
1485  {
1486  quantum_map[i]=YellowQuantum;
1487  if (image->colorspace == CMYKColorspace)
1488  break;
1489  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1490  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1491  "ColorSeparatedImageRequired","`%s'",stream_info->map);
1492  return(MagickFalse);
1493  }
1494  default:
1495  {
1496  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1497  (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1498  "UnrecognizedPixelMap","`%s'",stream_info->map);
1499  return(MagickFalse);
1500  }
1501  }
1502  }
1503  quantum_info=stream_info->quantum_info;
1504  switch (stream_info->storage_type)
1505  {
1506  case CharPixel:
1507  {
1508  unsigned char
1509  *q;
1510 
1511  q=(unsigned char *) stream_info->pixels;
1512  if (LocaleCompare(stream_info->map,"BGR") == 0)
1513  {
1514  p=GetAuthenticPixelQueue(image);
1515  if (p == (const Quantum *) NULL)
1516  break;
1517  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1518  {
1519  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1520  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1521  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1522  p+=(ptrdiff_t) GetPixelChannels(image);
1523  }
1524  break;
1525  }
1526  if (LocaleCompare(stream_info->map,"BGRA") == 0)
1527  {
1528  p=GetAuthenticPixelQueue(image);
1529  if (p == (const Quantum *) NULL)
1530  break;
1531  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1532  {
1533  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1534  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1535  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1536  *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1537  p+=(ptrdiff_t) GetPixelChannels(image);
1538  }
1539  break;
1540  }
1541  if (LocaleCompare(stream_info->map,"BGRP") == 0)
1542  {
1543  p=GetAuthenticPixelQueue(image);
1544  if (p == (const Quantum *) NULL)
1545  break;
1546  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1547  {
1548  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1549  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1550  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1551  *q++=ScaleQuantumToChar((Quantum) 0);
1552  p+=(ptrdiff_t) GetPixelChannels(image);
1553  }
1554  break;
1555  }
1556  if (LocaleCompare(stream_info->map,"I") == 0)
1557  {
1558  p=GetAuthenticPixelQueue(image);
1559  if (p == (const Quantum *) NULL)
1560  break;
1561  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1562  {
1563  *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
1564  p+=(ptrdiff_t) GetPixelChannels(image);
1565  }
1566  break;
1567  }
1568  if (LocaleCompare(stream_info->map,"RGB") == 0)
1569  {
1570  p=GetAuthenticPixelQueue(image);
1571  if (p == (const Quantum *) NULL)
1572  break;
1573  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1574  {
1575  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1576  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1577  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1578  p+=(ptrdiff_t) GetPixelChannels(image);
1579  }
1580  break;
1581  }
1582  if (LocaleCompare(stream_info->map,"RGBA") == 0)
1583  {
1584  p=GetAuthenticPixelQueue(image);
1585  if (p == (const Quantum *) NULL)
1586  break;
1587  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1588  {
1589  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1590  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1591  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1592  *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1593  p+=(ptrdiff_t) GetPixelChannels(image);
1594  }
1595  break;
1596  }
1597  if (LocaleCompare(stream_info->map,"RGBP") == 0)
1598  {
1599  p=GetAuthenticPixelQueue(image);
1600  if (p == (const Quantum *) NULL)
1601  break;
1602  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1603  {
1604  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1605  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1606  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1607  *q++=ScaleQuantumToChar((Quantum) 0);
1608  p+=(ptrdiff_t) GetPixelChannels(image);
1609  }
1610  break;
1611  }
1612  p=GetAuthenticPixelQueue(image);
1613  if (p == (const Quantum *) NULL)
1614  break;
1615  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1616  {
1617  for (i=0; i < (ssize_t) length; i++)
1618  {
1619  *q=0;
1620  switch (quantum_map[i])
1621  {
1622  case RedQuantum:
1623  case CyanQuantum:
1624  {
1625  *q=ScaleQuantumToChar(GetPixelRed(image,p));
1626  break;
1627  }
1628  case GreenQuantum:
1629  case MagentaQuantum:
1630  {
1631  *q=ScaleQuantumToChar(GetPixelGreen(image,p));
1632  break;
1633  }
1634  case BlueQuantum:
1635  case YellowQuantum:
1636  {
1637  *q=ScaleQuantumToChar(GetPixelBlue(image,p));
1638  break;
1639  }
1640  case AlphaQuantum:
1641  {
1642  *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
1643  break;
1644  }
1645  case OpacityQuantum:
1646  {
1647  *q=ScaleQuantumToChar(GetPixelOpacity(image,p));
1648  break;
1649  }
1650  case BlackQuantum:
1651  {
1652  if (image->colorspace == CMYKColorspace)
1653  *q=ScaleQuantumToChar(GetPixelBlack(image,p));
1654  break;
1655  }
1656  case IndexQuantum:
1657  {
1658  *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
1659  break;
1660  }
1661  default:
1662  break;
1663  }
1664  q++;
1665  }
1666  p+=(ptrdiff_t) GetPixelChannels(image);
1667  }
1668  break;
1669  }
1670  case DoublePixel:
1671  {
1672  double
1673  *q;
1674 
1675  q=(double *) stream_info->pixels;
1676  if (LocaleCompare(stream_info->map,"BGR") == 0)
1677  {
1678  p=GetAuthenticPixelQueue(image);
1679  if (p == (const Quantum *) NULL)
1680  break;
1681  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1682  {
1683  *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1684  quantum_info->scale+quantum_info->minimum);
1685  *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1686  quantum_info->scale+quantum_info->minimum);
1687  *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1688  quantum_info->scale+quantum_info->minimum);
1689  p+=(ptrdiff_t) GetPixelChannels(image);
1690  }
1691  break;
1692  }
1693  if (LocaleCompare(stream_info->map,"BGRA") == 0)
1694  {
1695  p=GetAuthenticPixelQueue(image);
1696  if (p == (const Quantum *) NULL)
1697  break;
1698  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1699  {
1700  *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1701  quantum_info->scale+quantum_info->minimum);
1702  *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1703  quantum_info->scale+quantum_info->minimum);
1704  *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1705  quantum_info->scale+quantum_info->minimum);
1706  *q++=(double) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1707  quantum_info->scale+quantum_info->minimum);
1708  p+=(ptrdiff_t) GetPixelChannels(image);
1709  }
1710  break;
1711  }
1712  if (LocaleCompare(stream_info->map,"BGRP") == 0)
1713  {
1714  p=GetAuthenticPixelQueue(image);
1715  if (p == (const Quantum *) NULL)
1716  break;
1717  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1718  {
1719  *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1720  quantum_info->scale+quantum_info->minimum);
1721  *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1722  quantum_info->scale+quantum_info->minimum);
1723  *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1724  quantum_info->scale+quantum_info->minimum);
1725  *q++=0.0;
1726  p+=(ptrdiff_t) GetPixelChannels(image);
1727  }
1728  break;
1729  }
1730  if (LocaleCompare(stream_info->map,"I") == 0)
1731  {
1732  p=GetAuthenticPixelQueue(image);
1733  if (p == (const Quantum *) NULL)
1734  break;
1735  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1736  {
1737  *q++=(double) ((QuantumScale*(double) GetPixelIntensity(image,p))*
1738  quantum_info->scale+quantum_info->minimum);
1739  p+=(ptrdiff_t) GetPixelChannels(image);
1740  }
1741  break;
1742  }
1743  if (LocaleCompare(stream_info->map,"RGB") == 0)
1744  {
1745  p=GetAuthenticPixelQueue(image);
1746  if (p == (const Quantum *) NULL)
1747  break;
1748  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1749  {
1750  *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1751  quantum_info->scale+quantum_info->minimum);
1752  *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1753  quantum_info->scale+quantum_info->minimum);
1754  *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1755  quantum_info->scale+quantum_info->minimum);
1756  p+=(ptrdiff_t) GetPixelChannels(image);
1757  }
1758  break;
1759  }
1760  if (LocaleCompare(stream_info->map,"RGBA") == 0)
1761  {
1762  p=GetAuthenticPixelQueue(image);
1763  if (p == (const Quantum *) NULL)
1764  break;
1765  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1766  {
1767  *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1768  quantum_info->scale+quantum_info->minimum);
1769  *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1770  quantum_info->scale+quantum_info->minimum);
1771  *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1772  quantum_info->scale+quantum_info->minimum);
1773  *q++=(double) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1774  quantum_info->scale+quantum_info->minimum);
1775  p+=(ptrdiff_t) GetPixelChannels(image);
1776  }
1777  break;
1778  }
1779  if (LocaleCompare(stream_info->map,"RGBP") == 0)
1780  {
1781  p=GetAuthenticPixelQueue(image);
1782  if (p == (const Quantum *) NULL)
1783  break;
1784  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1785  {
1786  *q++=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1787  quantum_info->scale+quantum_info->minimum);
1788  *q++=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1789  quantum_info->scale+quantum_info->minimum);
1790  *q++=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1791  quantum_info->scale+quantum_info->minimum);
1792  *q++=0.0;
1793  p+=(ptrdiff_t) GetPixelChannels(image);
1794  }
1795  break;
1796  }
1797  p=GetAuthenticPixelQueue(image);
1798  if (p == (const Quantum *) NULL)
1799  break;
1800  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1801  {
1802  for (i=0; i < (ssize_t) length; i++)
1803  {
1804  *q=0;
1805  switch (quantum_map[i])
1806  {
1807  case RedQuantum:
1808  case CyanQuantum:
1809  {
1810  *q=(double) ((QuantumScale*(double) GetPixelRed(image,p))*
1811  quantum_info->scale+quantum_info->minimum);
1812  break;
1813  }
1814  case GreenQuantum:
1815  case MagentaQuantum:
1816  {
1817  *q=(double) ((QuantumScale*(double) GetPixelGreen(image,p))*
1818  quantum_info->scale+quantum_info->minimum);
1819  break;
1820  }
1821  case BlueQuantum:
1822  case YellowQuantum:
1823  {
1824  *q=(double) ((QuantumScale*(double) GetPixelBlue(image,p))*
1825  quantum_info->scale+quantum_info->minimum);
1826  break;
1827  }
1828  case AlphaQuantum:
1829  {
1830  *q=(double) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1831  quantum_info->scale+quantum_info->minimum);
1832  break;
1833  }
1834  case OpacityQuantum:
1835  {
1836  *q=(double) ((QuantumScale*(double) GetPixelOpacity(image,p))*
1837  quantum_info->scale+quantum_info->minimum);
1838  break;
1839  }
1840  case BlackQuantum:
1841  {
1842  if (image->colorspace == CMYKColorspace)
1843  *q=(double) ((QuantumScale*(double) GetPixelBlack(image,p))*
1844  quantum_info->scale+quantum_info->minimum);
1845  break;
1846  }
1847  case IndexQuantum:
1848  {
1849  *q=(double) ((QuantumScale*(double) GetPixelIntensity(image,p))*
1850  quantum_info->scale+quantum_info->minimum);
1851  break;
1852  }
1853  default:
1854  *q=0;
1855  }
1856  q++;
1857  }
1858  p+=(ptrdiff_t) GetPixelChannels(image);
1859  }
1860  break;
1861  }
1862  case FloatPixel:
1863  {
1864  float
1865  *q;
1866 
1867  q=(float *) stream_info->pixels;
1868  if (LocaleCompare(stream_info->map,"BGR") == 0)
1869  {
1870  p=GetAuthenticPixelQueue(image);
1871  if (p == (const Quantum *) NULL)
1872  break;
1873  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1874  {
1875  *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1876  quantum_info->scale+quantum_info->minimum);
1877  *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1878  quantum_info->scale+quantum_info->minimum);
1879  *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1880  quantum_info->scale+quantum_info->minimum);
1881  p+=(ptrdiff_t) GetPixelChannels(image);
1882  }
1883  break;
1884  }
1885  if (LocaleCompare(stream_info->map,"BGRA") == 0)
1886  {
1887  p=GetAuthenticPixelQueue(image);
1888  if (p == (const Quantum *) NULL)
1889  break;
1890  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1891  {
1892  *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1893  quantum_info->scale+quantum_info->minimum);
1894  *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1895  quantum_info->scale+quantum_info->minimum);
1896  *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1897  quantum_info->scale+quantum_info->minimum);
1898  *q++=(float) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1899  quantum_info->scale+quantum_info->minimum);
1900  p+=(ptrdiff_t) GetPixelChannels(image);
1901  }
1902  break;
1903  }
1904  if (LocaleCompare(stream_info->map,"BGRP") == 0)
1905  {
1906  p=GetAuthenticPixelQueue(image);
1907  if (p == (const Quantum *) NULL)
1908  break;
1909  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1910  {
1911  *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1912  quantum_info->scale+quantum_info->minimum);
1913  *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1914  quantum_info->scale+quantum_info->minimum);
1915  *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1916  quantum_info->scale+quantum_info->minimum);
1917  *q++=0.0;
1918  p+=(ptrdiff_t) GetPixelChannels(image);
1919  }
1920  break;
1921  }
1922  if (LocaleCompare(stream_info->map,"I") == 0)
1923  {
1924  p=GetAuthenticPixelQueue(image);
1925  if (p == (const Quantum *) NULL)
1926  break;
1927  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1928  {
1929  *q++=(float) ((QuantumScale*(double) GetPixelIntensity(image,p))*
1930  quantum_info->scale+quantum_info->minimum);
1931  p+=(ptrdiff_t) GetPixelChannels(image);
1932  }
1933  break;
1934  }
1935  if (LocaleCompare(stream_info->map,"RGB") == 0)
1936  {
1937  p=GetAuthenticPixelQueue(image);
1938  if (p == (const Quantum *) NULL)
1939  break;
1940  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1941  {
1942  *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1943  quantum_info->scale+quantum_info->minimum);
1944  *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1945  quantum_info->scale+quantum_info->minimum);
1946  *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1947  quantum_info->scale+quantum_info->minimum);
1948  p+=(ptrdiff_t) GetPixelChannels(image);
1949  }
1950  break;
1951  }
1952  if (LocaleCompare(stream_info->map,"RGBA") == 0)
1953  {
1954  p=GetAuthenticPixelQueue(image);
1955  if (p == (const Quantum *) NULL)
1956  break;
1957  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1958  {
1959  *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1960  quantum_info->scale+quantum_info->minimum);
1961  *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1962  quantum_info->scale+quantum_info->minimum);
1963  *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1964  quantum_info->scale+quantum_info->minimum);
1965  *q++=(float) ((QuantumScale*(double) GetPixelAlpha(image,p))*
1966  quantum_info->scale+quantum_info->minimum);
1967  p+=(ptrdiff_t) GetPixelChannels(image);
1968  }
1969  break;
1970  }
1971  if (LocaleCompare(stream_info->map,"RGBP") == 0)
1972  {
1973  p=GetAuthenticPixelQueue(image);
1974  if (p == (const Quantum *) NULL)
1975  break;
1976  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1977  {
1978  *q++=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
1979  quantum_info->scale+quantum_info->minimum);
1980  *q++=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
1981  quantum_info->scale+quantum_info->minimum);
1982  *q++=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
1983  quantum_info->scale+quantum_info->minimum);
1984  *q++=0.0;
1985  p+=(ptrdiff_t) GetPixelChannels(image);
1986  }
1987  break;
1988  }
1989  p=GetAuthenticPixelQueue(image);
1990  if (p == (const Quantum *) NULL)
1991  break;
1992  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
1993  {
1994  for (i=0; i < (ssize_t) length; i++)
1995  {
1996  *q=0;
1997  switch (quantum_map[i])
1998  {
1999  case RedQuantum:
2000  case CyanQuantum:
2001  {
2002  *q=(float) ((QuantumScale*(double) GetPixelRed(image,p))*
2003  quantum_info->scale+quantum_info->minimum);
2004  break;
2005  }
2006  case GreenQuantum:
2007  case MagentaQuantum:
2008  {
2009  *q=(float) ((QuantumScale*(double) GetPixelGreen(image,p))*
2010  quantum_info->scale+quantum_info->minimum);
2011  break;
2012  }
2013  case BlueQuantum:
2014  case YellowQuantum:
2015  {
2016  *q=(float) ((QuantumScale*(double) GetPixelBlue(image,p))*
2017  quantum_info->scale+quantum_info->minimum);
2018  break;
2019  }
2020  case AlphaQuantum:
2021  {
2022  *q=(float) ((QuantumScale*(double) GetPixelAlpha(image,p))*
2023  quantum_info->scale+quantum_info->minimum);
2024  break;
2025  }
2026  case OpacityQuantum:
2027  {
2028  *q=(float) ((QuantumScale*(double) GetPixelOpacity(image,p))*
2029  quantum_info->scale+quantum_info->minimum);
2030  break;
2031  }
2032  case BlackQuantum:
2033  {
2034  if (image->colorspace == CMYKColorspace)
2035  *q=(float) ((QuantumScale*(double) GetPixelBlack(image,p))*
2036  quantum_info->scale+quantum_info->minimum);
2037  break;
2038  }
2039  case IndexQuantum:
2040  {
2041  *q=(float) ((QuantumScale*(double) GetPixelIntensity(image,p))*
2042  quantum_info->scale+quantum_info->minimum);
2043  break;
2044  }
2045  default:
2046  *q=0;
2047  }
2048  q++;
2049  }
2050  p+=(ptrdiff_t) GetPixelChannels(image);
2051  }
2052  break;
2053  }
2054  case LongPixel:
2055  {
2056  unsigned int
2057  *q;
2058 
2059  q=(unsigned int *) stream_info->pixels;
2060  if (LocaleCompare(stream_info->map,"BGR") == 0)
2061  {
2062  p=GetAuthenticPixelQueue(image);
2063  if (p == (const Quantum *) NULL)
2064  break;
2065  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2066  {
2067  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2068  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2069  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2070  p+=(ptrdiff_t) GetPixelChannels(image);
2071  }
2072  break;
2073  }
2074  if (LocaleCompare(stream_info->map,"BGRA") == 0)
2075  {
2076  p=GetAuthenticPixelQueue(image);
2077  if (p == (const Quantum *) NULL)
2078  break;
2079  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2080  {
2081  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2082  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2083  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2084  *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
2085  p+=(ptrdiff_t) GetPixelChannels(image);
2086  }
2087  break;
2088  }
2089  if (LocaleCompare(stream_info->map,"BGRP") == 0)
2090  {
2091  p=GetAuthenticPixelQueue(image);
2092  if (p == (const Quantum *) NULL)
2093  break;
2094  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2095  {
2096  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2097  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2098  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2099  *q++=0;
2100  p+=(ptrdiff_t) GetPixelChannels(image);
2101  }
2102  break;
2103  }
2104  if (LocaleCompare(stream_info->map,"I") == 0)
2105  {
2106  p=GetAuthenticPixelQueue(image);
2107  if (p == (const Quantum *) NULL)
2108  break;
2109  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2110  {
2111  *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
2112  p+=(ptrdiff_t) GetPixelChannels(image);
2113  }
2114  break;
2115  }
2116  if (LocaleCompare(stream_info->map,"RGB") == 0)
2117  {
2118  p=GetAuthenticPixelQueue(image);
2119  if (p == (const Quantum *) NULL)
2120  break;
2121  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2122  {
2123  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2124  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2125  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2126  p+=(ptrdiff_t) GetPixelChannels(image);
2127  }
2128  break;
2129  }
2130  if (LocaleCompare(stream_info->map,"RGBA") == 0)
2131  {
2132  p=GetAuthenticPixelQueue(image);
2133  if (p == (const Quantum *) NULL)
2134  break;
2135  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2136  {
2137  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2138  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2139  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2140  *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
2141  p+=(ptrdiff_t) GetPixelChannels(image);
2142  }
2143  break;
2144  }
2145  if (LocaleCompare(stream_info->map,"RGBP") == 0)
2146  {
2147  p=GetAuthenticPixelQueue(image);
2148  if (p == (const Quantum *) NULL)
2149  break;
2150  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2151  {
2152  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
2153  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
2154  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
2155  *q++=0;
2156  p+=(ptrdiff_t) GetPixelChannels(image);
2157  }
2158  break;
2159  }
2160  p=GetAuthenticPixelQueue(image);
2161  if (p == (const Quantum *) NULL)
2162  break;
2163  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2164  {
2165  for (i=0; i < (ssize_t) length; i++)
2166  {
2167  *q=0;
2168  switch (quantum_map[i])
2169  {
2170  case RedQuantum:
2171  case CyanQuantum:
2172  {
2173  *q=ScaleQuantumToLong(GetPixelRed(image,p));
2174  break;
2175  }
2176  case GreenQuantum:
2177  case MagentaQuantum:
2178  {
2179  *q=ScaleQuantumToLong(GetPixelGreen(image,p));
2180  break;
2181  }
2182  case BlueQuantum:
2183  case YellowQuantum:
2184  {
2185  *q=ScaleQuantumToLong(GetPixelBlue(image,p));
2186  break;
2187  }
2188  case AlphaQuantum:
2189  {
2190  *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
2191  break;
2192  }
2193  case OpacityQuantum:
2194  {
2195  *q=ScaleQuantumToLong(GetPixelOpacity(image,p));
2196  break;
2197  }
2198  case BlackQuantum:
2199  {
2200  if (image->colorspace == CMYKColorspace)
2201  *q=ScaleQuantumToLong(GetPixelBlack(image,p));
2202  break;
2203  }
2204  case IndexQuantum:
2205  {
2206  *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
2207  break;
2208  }
2209  default:
2210  break;
2211  }
2212  q++;
2213  }
2214  p+=(ptrdiff_t) GetPixelChannels(image);
2215  }
2216  break;
2217  }
2218  case LongLongPixel:
2219  {
2220  MagickSizeType
2221  *q;
2222 
2223  q=(MagickSizeType *) stream_info->pixels;
2224  if (LocaleCompare(stream_info->map,"BGR") == 0)
2225  {
2226  p=GetAuthenticPixelQueue(image);
2227  if (p == (const Quantum *) NULL)
2228  break;
2229  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2230  {
2231  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2232  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2233  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2234  p+=(ptrdiff_t) GetPixelChannels(image);
2235  }
2236  break;
2237  }
2238  if (LocaleCompare(stream_info->map,"BGRA") == 0)
2239  {
2240  p=GetAuthenticPixelQueue(image);
2241  if (p == (const Quantum *) NULL)
2242  break;
2243  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2244  {
2245  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2246  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2247  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2248  *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2249  p+=(ptrdiff_t) GetPixelChannels(image);
2250  }
2251  break;
2252  }
2253  if (LocaleCompare(stream_info->map,"BGRP") == 0)
2254  {
2255  p=GetAuthenticPixelQueue(image);
2256  if (p == (const Quantum *) NULL)
2257  break;
2258  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2259  {
2260  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2261  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2262  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2263  *q++=0U;
2264  p+=(ptrdiff_t) GetPixelChannels(image);
2265  }
2266  break;
2267  }
2268  if (LocaleCompare(stream_info->map,"I") == 0)
2269  {
2270  p=GetAuthenticPixelQueue(image);
2271  if (p == (const Quantum *) NULL)
2272  break;
2273  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2274  {
2275  *q++=ScaleQuantumToLongLong(ClampToQuantum(
2276  GetPixelIntensity(image,p)));
2277  p+=(ptrdiff_t) GetPixelChannels(image);
2278  }
2279  break;
2280  }
2281  if (LocaleCompare(stream_info->map,"RGB") == 0)
2282  {
2283  p=GetAuthenticPixelQueue(image);
2284  if (p == (const Quantum *) NULL)
2285  break;
2286  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2287  {
2288  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2289  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2290  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2291  p+=(ptrdiff_t) GetPixelChannels(image);
2292  }
2293  break;
2294  }
2295  if (LocaleCompare(stream_info->map,"RGBA") == 0)
2296  {
2297  p=GetAuthenticPixelQueue(image);
2298  if (p == (const Quantum *) NULL)
2299  break;
2300  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2301  {
2302  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2303  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2304  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2305  *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2306  p+=(ptrdiff_t) GetPixelChannels(image);
2307  }
2308  break;
2309  }
2310  if (LocaleCompare(stream_info->map,"RGBP") == 0)
2311  {
2312  p=GetAuthenticPixelQueue(image);
2313  if (p == (const Quantum *) NULL)
2314  break;
2315  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2316  {
2317  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
2318  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2319  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2320  *q++=0U;
2321  p+=(ptrdiff_t) GetPixelChannels(image);
2322  }
2323  break;
2324  }
2325  p=GetAuthenticPixelQueue(image);
2326  if (p == (const Quantum *) NULL)
2327  break;
2328  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2329  {
2330  for (i=0; i < (ssize_t) length; i++)
2331  {
2332  *q=0;
2333  switch (quantum_map[i])
2334  {
2335  case RedQuantum:
2336  case CyanQuantum:
2337  {
2338  *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
2339  break;
2340  }
2341  case GreenQuantum:
2342  case MagentaQuantum:
2343  {
2344  *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
2345  break;
2346  }
2347  case BlueQuantum:
2348  case YellowQuantum:
2349  {
2350  *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
2351  break;
2352  }
2353  case AlphaQuantum:
2354  {
2355  *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
2356  break;
2357  }
2358  case OpacityQuantum:
2359  {
2360  *q=ScaleQuantumToLongLong(GetPixelOpacity(image,p));
2361  break;
2362  }
2363  case BlackQuantum:
2364  {
2365  if (image->colorspace == CMYKColorspace)
2366  *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
2367  break;
2368  }
2369  case IndexQuantum:
2370  {
2371  *q=ScaleQuantumToLongLong(ClampToQuantum(
2372  GetPixelIntensity(image,p)));
2373  break;
2374  }
2375  default:
2376  *q=0;
2377  }
2378  q++;
2379  }
2380  p+=(ptrdiff_t) GetPixelChannels(image);
2381  }
2382  break;
2383  }
2384  case QuantumPixel:
2385  {
2386  Quantum
2387  *q;
2388 
2389  q=(Quantum *) stream_info->pixels;
2390  if (LocaleCompare(stream_info->map,"BGR") == 0)
2391  {
2392  p=GetAuthenticPixelQueue(image);
2393  if (p == (const Quantum *) NULL)
2394  break;
2395  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2396  {
2397  *q++=GetPixelBlue(image,p);
2398  *q++=GetPixelGreen(image,p);
2399  *q++=GetPixelRed(image,p);
2400  p+=(ptrdiff_t) GetPixelChannels(image);
2401  }
2402  break;
2403  }
2404  if (LocaleCompare(stream_info->map,"BGRA") == 0)
2405  {
2406  p=GetAuthenticPixelQueue(image);
2407  if (p == (const Quantum *) NULL)
2408  break;
2409  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2410  {
2411  *q++=GetPixelBlue(image,p);
2412  *q++=GetPixelGreen(image,p);
2413  *q++=GetPixelRed(image,p);
2414  *q++=GetPixelAlpha(image,p);
2415  p+=(ptrdiff_t) GetPixelChannels(image);
2416  }
2417  break;
2418  }
2419  if (LocaleCompare(stream_info->map,"BGRP") == 0)
2420  {
2421  p=GetAuthenticPixelQueue(image);
2422  if (p == (const Quantum *) NULL)
2423  break;
2424  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2425  {
2426  *q++=GetPixelBlue(image,p);
2427  *q++=GetPixelGreen(image,p);
2428  *q++=GetPixelRed(image,p);
2429  *q++=(Quantum) 0;
2430  p+=(ptrdiff_t) GetPixelChannels(image);
2431  }
2432  break;
2433  }
2434  if (LocaleCompare(stream_info->map,"I") == 0)
2435  {
2436  p=GetAuthenticPixelQueue(image);
2437  if (p == (const Quantum *) NULL)
2438  break;
2439  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2440  {
2441  *q++=ClampToQuantum(GetPixelIntensity(image,p));
2442  p+=(ptrdiff_t) GetPixelChannels(image);
2443  }
2444  break;
2445  }
2446  if (LocaleCompare(stream_info->map,"RGB") == 0)
2447  {
2448  p=GetAuthenticPixelQueue(image);
2449  if (p == (const Quantum *) NULL)
2450  break;
2451  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2452  {
2453  *q++=GetPixelRed(image,p);
2454  *q++=GetPixelGreen(image,p);
2455  *q++=GetPixelBlue(image,p);
2456  p+=(ptrdiff_t) GetPixelChannels(image);
2457  }
2458  break;
2459  }
2460  if (LocaleCompare(stream_info->map,"RGBA") == 0)
2461  {
2462  p=GetAuthenticPixelQueue(image);
2463  if (p == (const Quantum *) NULL)
2464  break;
2465  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2466  {
2467  *q++=GetPixelRed(image,p);
2468  *q++=GetPixelGreen(image,p);
2469  *q++=GetPixelBlue(image,p);
2470  *q++=GetPixelAlpha(image,p);
2471  p+=(ptrdiff_t) GetPixelChannels(image);
2472  }
2473  break;
2474  }
2475  if (LocaleCompare(stream_info->map,"RGBP") == 0)
2476  {
2477  p=GetAuthenticPixelQueue(image);
2478  if (p == (const Quantum *) NULL)
2479  break;
2480  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2481  {
2482  *q++=GetPixelRed(image,p);
2483  *q++=GetPixelGreen(image,p);
2484  *q++=GetPixelBlue(image,p);
2485  *q++=(Quantum) 0;
2486  p+=(ptrdiff_t) GetPixelChannels(image);
2487  }
2488  break;
2489  }
2490  p=GetAuthenticPixelQueue(image);
2491  if (p == (const Quantum *) NULL)
2492  break;
2493  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2494  {
2495  for (i=0; i < (ssize_t) length; i++)
2496  {
2497  *q=(Quantum) 0;
2498  switch (quantum_map[i])
2499  {
2500  case RedQuantum:
2501  case CyanQuantum:
2502  {
2503  *q=GetPixelRed(image,p);
2504  break;
2505  }
2506  case GreenQuantum:
2507  case MagentaQuantum:
2508  {
2509  *q=GetPixelGreen(image,p);
2510  break;
2511  }
2512  case BlueQuantum:
2513  case YellowQuantum:
2514  {
2515  *q=GetPixelBlue(image,p);
2516  break;
2517  }
2518  case AlphaQuantum:
2519  {
2520  *q=GetPixelAlpha(image,p);
2521  break;
2522  }
2523  case OpacityQuantum:
2524  {
2525  *q=GetPixelOpacity(image,p);
2526  break;
2527  }
2528  case BlackQuantum:
2529  {
2530  if (image->colorspace == CMYKColorspace)
2531  *q=GetPixelBlack(image,p);
2532  break;
2533  }
2534  case IndexQuantum:
2535  {
2536  *q=ClampToQuantum(GetPixelIntensity(image,p));
2537  break;
2538  }
2539  default:
2540  *q=(Quantum) 0;
2541  }
2542  q++;
2543  }
2544  p+=(ptrdiff_t) GetPixelChannels(image);
2545  }
2546  break;
2547  }
2548  case ShortPixel:
2549  {
2550  unsigned short
2551  *q;
2552 
2553  q=(unsigned short *) stream_info->pixels;
2554  if (LocaleCompare(stream_info->map,"BGR") == 0)
2555  {
2556  p=GetAuthenticPixelQueue(image);
2557  if (p == (const Quantum *) NULL)
2558  break;
2559  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2560  {
2561  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2562  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2563  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2564  p+=(ptrdiff_t) GetPixelChannels(image);
2565  }
2566  break;
2567  }
2568  if (LocaleCompare(stream_info->map,"BGRA") == 0)
2569  {
2570  p=GetAuthenticPixelQueue(image);
2571  if (p == (const Quantum *) NULL)
2572  break;
2573  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2574  {
2575  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2576  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2577  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2578  *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
2579  p+=(ptrdiff_t) GetPixelChannels(image);
2580  }
2581  break;
2582  }
2583  if (LocaleCompare(stream_info->map,"BGRP") == 0)
2584  {
2585  p=GetAuthenticPixelQueue(image);
2586  if (p == (const Quantum *) NULL)
2587  break;
2588  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2589  {
2590  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2591  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2592  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2593  *q++=0;
2594  p+=(ptrdiff_t) GetPixelChannels(image);
2595  }
2596  break;
2597  }
2598  if (LocaleCompare(stream_info->map,"I") == 0)
2599  {
2600  p=GetAuthenticPixelQueue(image);
2601  if (p == (const Quantum *) NULL)
2602  break;
2603  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2604  {
2605  *q++=ScaleQuantumToShort(ClampToQuantum(
2606  GetPixelIntensity(image,p)));
2607  p+=(ptrdiff_t) GetPixelChannels(image);
2608  }
2609  break;
2610  }
2611  if (LocaleCompare(stream_info->map,"RGB") == 0)
2612  {
2613  p=GetAuthenticPixelQueue(image);
2614  if (p == (const Quantum *) NULL)
2615  break;
2616  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2617  {
2618  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2619  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2620  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2621  p+=(ptrdiff_t) GetPixelChannels(image);
2622  }
2623  break;
2624  }
2625  if (LocaleCompare(stream_info->map,"RGBA") == 0)
2626  {
2627  p=GetAuthenticPixelQueue(image);
2628  if (p == (const Quantum *) NULL)
2629  break;
2630  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2631  {
2632  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2633  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2634  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2635  *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
2636  p+=(ptrdiff_t) GetPixelChannels(image);
2637  }
2638  break;
2639  }
2640  if (LocaleCompare(stream_info->map,"RGBP") == 0)
2641  {
2642  p=GetAuthenticPixelQueue(image);
2643  if (p == (const Quantum *) NULL)
2644  break;
2645  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2646  {
2647  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
2648  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
2649  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
2650  *q++=0;
2651  p+=(ptrdiff_t) GetPixelChannels(image);
2652  }
2653  break;
2654  }
2655  p=GetAuthenticPixelQueue(image);
2656  if (p == (const Quantum *) NULL)
2657  break;
2658  for (x=0; x < (ssize_t) GetImageExtent(image); x++)
2659  {
2660  for (i=0; i < (ssize_t) length; i++)
2661  {
2662  *q=0;
2663  switch (quantum_map[i])
2664  {
2665  case RedQuantum:
2666  case CyanQuantum:
2667  {
2668  *q=ScaleQuantumToShort(GetPixelRed(image,p));
2669  break;
2670  }
2671  case GreenQuantum:
2672  case MagentaQuantum:
2673  {
2674  *q=ScaleQuantumToShort(GetPixelGreen(image,p));
2675  break;
2676  }
2677  case BlueQuantum:
2678  case YellowQuantum:
2679  {
2680  *q=ScaleQuantumToShort(GetPixelBlue(image,p));
2681  break;
2682  }
2683  case AlphaQuantum:
2684  {
2685  *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
2686  break;
2687  }
2688  case OpacityQuantum:
2689  {
2690  *q=ScaleQuantumToShort(GetPixelOpacity(image,p));
2691  break;
2692  }
2693  case BlackQuantum:
2694  {
2695  if (image->colorspace == CMYKColorspace)
2696  *q=ScaleQuantumToShort(GetPixelBlack(image,p));
2697  break;
2698  }
2699  case IndexQuantum:
2700  {
2701  *q=ScaleQuantumToShort(ClampToQuantum(
2702  GetPixelIntensity(image,p)));
2703  break;
2704  }
2705  default:
2706  break;
2707  }
2708  q++;
2709  }
2710  p+=(ptrdiff_t) GetPixelChannels(image);
2711  }
2712  break;
2713  }
2714  default:
2715  {
2716  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2717  (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2718  "UnrecognizedPixelMap","`%s'",stream_info->map);
2719  break;
2720  }
2721  }
2722  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2723  return(MagickTrue);
2724 }
2725 
2726 /*
2727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2728 % %
2729 % %
2730 % %
2731 + 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 %
2732 % %
2733 % %
2734 % %
2735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2736 %
2737 % SyncAuthenticPixelsStream() calls the user supplied callback method with
2738 % the latest stream of pixels.
2739 %
2740 % The format of the SyncAuthenticPixelsStream method is:
2741 %
2742 % MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2743 % ExceptionInfo *exception)
2744 %
2745 % A description of each parameter follows:
2746 %
2747 % o image: the image.
2748 %
2749 % o exception: return any errors or warnings in this structure.
2750 %
2751 */
2752 static MagickBooleanType SyncAuthenticPixelsStream(Image *image,
2753  ExceptionInfo *exception)
2754 {
2755  CacheInfo
2756  *cache_info;
2757 
2758  size_t
2759  length;
2760 
2761  StreamHandler
2762  stream_handler;
2763 
2764  assert(image != (Image *) NULL);
2765  assert(image->signature == MagickCoreSignature);
2766  if (IsEventLogging() != MagickFalse)
2767  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2768  cache_info=(CacheInfo *) image->cache;
2769  assert(cache_info->signature == MagickCoreSignature);
2770  stream_handler=GetBlobStreamHandler(image);
2771  if (stream_handler == (StreamHandler) NULL)
2772  {
2773  (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
2774  "NoStreamHandlerIsDefined","`%s'",image->filename);
2775  return(MagickFalse);
2776  }
2777  length=stream_handler(image,cache_info->pixels,(size_t) cache_info->columns);
2778  return(length == cache_info->columns ? MagickTrue : MagickFalse);
2779 }
2780 
2781 /*
2782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2783 % %
2784 % %
2785 % %
2786 % W r i t e S t r e a m %
2787 % %
2788 % %
2789 % %
2790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2791 %
2792 % WriteStream() makes the image pixels available to a user supplied callback
2793 % method immediately upon writing pixel data with the WriteImage() method.
2794 %
2795 % The format of the WriteStream() method is:
2796 %
2797 % MagickBooleanType WriteStream(const ImageInfo *image_info,Image *,
2798 % StreamHandler stream,ExceptionInfo *exception)
2799 %
2800 % A description of each parameter follows:
2801 %
2802 % o image_info: the image info.
2803 %
2804 % o stream: A callback method.
2805 %
2806 % o exception: return any errors or warnings in this structure.
2807 %
2808 */
2809 MagickExport MagickBooleanType WriteStream(const ImageInfo *image_info,
2810  Image *image,StreamHandler stream,ExceptionInfo *exception)
2811 {
2812  ImageInfo
2813  *write_info;
2814 
2815  MagickBooleanType
2816  status;
2817 
2818  assert(image_info != (ImageInfo *) NULL);
2819  assert(image_info->signature == MagickCoreSignature);
2820  if (IsEventLogging() != MagickFalse)
2821  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2822  image_info->filename);
2823  assert(image != (Image *) NULL);
2824  assert(image->signature == MagickCoreSignature);
2825  write_info=CloneImageInfo(image_info);
2826  *write_info->magick='\0';
2827  write_info->stream=stream;
2828  status=WriteImage(write_info,image,exception);
2829  write_info=DestroyImageInfo(write_info);
2830  return(status);
2831 }
_StreamInfo
Definition: stream.c:70
_NexusInfo
Definition: cache-private.h:104
_RectangleInfo
Definition: geometry.h:129
_QuantumInfo
Definition: quantum-private.h:45
SemaphoreInfo
Definition: semaphore.c:60
_Image
Definition: image.h:131
_CacheMethods
Definition: cache-private.h:68
_ImageInfo
Definition: image.h:358
_ExceptionInfo
Definition: exception.h:101
_PixelChannelMap
Definition: pixel.h:169
_CacheInfo
Definition: cache-private.h:132