MagickCore  6.9.13-18
Convert, Edit, Or Compose Bitmap Images
deprecate.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % DDDD EEEEE PPPP RRRR EEEEE CCCC AAA TTTTT EEEEE %
7 % D D E P P R R E C A A T E %
8 % D D EEE PPPPP RRRR EEE C AAAAA T EEE %
9 % D D E P R R E C A A T E %
10 % DDDD EEEEE P R R EEEEE CCCC A A T EEEEE %
11 % %
12 % %
13 % MagickCore Deprecated Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % October 2002 %
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 "magick/studio.h"
44 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
45 # if defined(__CYGWIN__)
46 # include <windows.h>
47 # else
48  /* All MinGW needs ... */
49 # include "magick/nt-base-private.h"
50 # include <wingdi.h>
51 # endif
52 #endif
53 #include "magick/blob.h"
54 #include "magick/blob-private.h"
55 #include "magick/cache.h"
56 #include "magick/cache-view.h"
57 #include "magick/channel.h"
58 #include "magick/client.h"
59 #include "magick/color.h"
60 #include "magick/color-private.h"
61 #include "magick/colormap.h"
62 #include "magick/colormap-private.h"
63 #include "magick/colorspace.h"
64 #include "magick/colorspace-private.h"
65 #include "magick/composite.h"
66 #include "magick/composite-private.h"
67 #include "magick/constitute.h"
68 #include "magick/deprecate.h"
69 #include "magick/draw.h"
70 #include "magick/draw-private.h"
71 #include "magick/effect.h"
72 #include "magick/enhance.h"
73 #include "magick/exception.h"
74 #include "magick/exception-private.h"
75 #include "magick/fx.h"
76 #include "magick/geometry.h"
77 #include "magick/identify.h"
78 #include "magick/image.h"
79 #include "magick/image-private.h"
80 #include "magick/list.h"
81 #include "magick/log.h"
82 #include "magick/memory_.h"
83 #include "magick/magick.h"
84 #include "magick/monitor.h"
85 #include "magick/monitor-private.h"
86 #include "magick/morphology.h"
87 #include "magick/mutex.h"
88 #include "magick/nt-feature.h"
89 #include "magick/paint.h"
90 #include "magick/pixel.h"
91 #include "magick/pixel-accessor.h"
92 #include "magick/pixel-private.h"
93 #include "magick/property.h"
94 #include "magick/quantize.h"
95 #include "magick/random_.h"
96 #include "magick/resource_.h"
97 #include "magick/semaphore.h"
98 #include "magick/semaphore-private.h"
99 #include "magick/segment.h"
100 #include "magick/splay-tree.h"
101 #include "magick/statistic.h"
102 #include "magick/string_.h"
103 #include "magick/threshold.h"
104 #include "magick/thread_.h"
105 #include "magick/thread-private.h"
106 #include "magick/token.h"
107 #include "magick/transform.h"
108 #include "magick/utility.h"
109 ␌
110 #if !defined(MAGICKCORE_EXCLUDE_DEPRECATED)
111 /*
112  Global declarations.
113 */
114 static MonitorHandler
115  monitor_handler = (MonitorHandler) NULL;
116 ␌
117 /*
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119 % %
120 % %
121 % %
122 % A c q u i r e C a c h e V i e w I n d e x e s %
123 % %
124 % %
125 % %
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 %
128 % AcquireCacheViewIndexes() returns the indexes associated with the specified
129 % view.
130 %
131 % Deprecated, replace with:
132 %
133 % GetCacheViewVirtualIndexQueue(cache_view);
134 %
135 % The format of the AcquireCacheViewIndexes method is:
136 %
137 % const IndexPacket *AcquireCacheViewIndexes(const CacheView *cache_view)
138 %
139 % A description of each parameter follows:
140 %
141 % o cache_view: the cache view.
142 %
143 */
144 MagickExport const IndexPacket *AcquireCacheViewIndexes(
145  const CacheView *cache_view)
146 {
147  return(GetCacheViewVirtualIndexQueue(cache_view));
148 }
149 ␌
150 /*
151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
152 % %
153 % %
154 % %
155 % A c q u i r e C a c h e V i e w P i x e l s %
156 % %
157 % %
158 % %
159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160 %
161 % AcquireCacheViewPixels() gets pixels from the in-memory or disk pixel cache
162 % as defined by the geometry parameters. A pointer to the pixels is returned
163 % if the pixels are transferred, otherwise a NULL is returned.
164 %
165 % Deprecated, replace with:
166 %
167 % GetCacheViewVirtualPixels(cache_view,x,y,columns,rows,exception);
168 %
169 % The format of the AcquireCacheViewPixels method is:
170 %
171 % const PixelPacket *AcquireCacheViewPixels(const CacheView *cache_view,
172 % const ssize_t x,const ssize_t y,const size_t columns,
173 % const size_t rows,ExceptionInfo *exception)
174 %
175 % A description of each parameter follows:
176 %
177 % o cache_view: the cache view.
178 %
179 % o x,y,columns,rows: These values define the perimeter of a region of
180 % pixels.
181 %
182 % o exception: return any errors or warnings in this structure.
183 %
184 */
185 MagickExport const PixelPacket *AcquireCacheViewPixels(
186  const CacheView *cache_view,const ssize_t x,const ssize_t y,
187  const size_t columns,const size_t rows,ExceptionInfo *exception)
188 {
189  return(GetCacheViewVirtualPixels(cache_view,x,y,columns,rows,exception));
190 }
191 ␌
192 /*
193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194 % %
195 % %
196 % %
197 % A c q u i r e I m a g e P i x e l s %
198 % %
199 % %
200 % %
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202 %
203 % AcquireImagePixels() returns an immutable pixel region. If the
204 % region is successfully accessed, a pointer to it is returned, otherwise
205 % NULL is returned. The returned pointer may point to a temporary working
206 % copy of the pixels or it may point to the original pixels in memory.
207 % Performance is maximized if the selected region is part of one row, or one
208 % or more full rows, since there is opportunity to access the pixels in-place
209 % (without a copy) if the image is in RAM, or in a memory-mapped file. The
210 % returned pointer should *never* be deallocated by the user.
211 %
212 % Pixels accessed via the returned pointer represent a simple array of type
213 % PixelPacket. If the image type is CMYK or the storage class is PseudoClass,
214 % call GetAuthenticIndexQueue() after invoking GetAuthenticPixels() to access
215 % the black color component or to obtain the colormap indexes (of type
216 % IndexPacket) corresponding to the region.
217 %
218 % If you plan to modify the pixels, use GetAuthenticPixels() instead.
219 %
220 % Note, the AcquireImagePixels() and GetAuthenticPixels() methods are not
221 % thread-safe. In a threaded environment, use GetCacheViewVirtualPixels() or
222 % GetCacheViewAuthenticPixels() instead.
223 %
224 % Deprecated, replace with:
225 %
226 % GetVirtualPixels(image,x,y,columns,rows,exception);
227 %
228 % The format of the AcquireImagePixels() method is:
229 %
230 % const PixelPacket *AcquireImagePixels(const Image *image,const ssize_t x,
231 % const ssize_t y,const size_t columns,const size_t rows,
232 % ExceptionInfo *exception)
233 %
234 % A description of each parameter follows:
235 %
236 % o image: the image.
237 %
238 % o x,y,columns,rows: These values define the perimeter of a region of
239 % pixels.
240 %
241 % o exception: return any errors or warnings in this structure.
242 %
243 */
244 MagickExport const PixelPacket *AcquireImagePixels(const Image *image,
245  const ssize_t x,const ssize_t y,const size_t columns,
246  const size_t rows,ExceptionInfo *exception)
247 {
248  return(GetVirtualPixels(image,x,y,columns,rows,exception));
249 }
250 ␌
251 /*
252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253 % %
254 % %
255 % %
256 % A c q u i r e I n d e x e s %
257 % %
258 % %
259 % %
260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 %
262 % AcquireIndexes() returns the black channel or the colormap indexes
263 % associated with the last call to QueueAuthenticPixels() or
264 % GetVirtualPixels(). NULL is returned if the black channel or colormap
265 % indexes are not available.
266 %
267 % Deprecated, replace with:
268 %
269 % GetVirtualIndexQueue(image);
270 %
271 % The format of the AcquireIndexes() method is:
272 %
273 % const IndexPacket *AcquireIndexes(const Image *image)
274 %
275 % A description of each parameter follows:
276 %
277 % o indexes: AcquireIndexes() returns the indexes associated with the last
278 % call to QueueAuthenticPixels() or GetVirtualPixels().
279 %
280 % o image: the image.
281 %
282 */
283 MagickExport const IndexPacket *AcquireIndexes(const Image *image)
284 {
285  return(GetVirtualIndexQueue(image));
286 }
287 ␌
288 /*
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290 % %
291 % %
292 % %
293 % A c q u i r e M e m o r y %
294 % %
295 % %
296 % %
297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298 %
299 % AcquireMemory() returns a pointer to a block of memory at least size bytes
300 % suitably aligned for any use.
301 %
302 % The format of the AcquireMemory method is:
303 %
304 % void *AcquireMemory(const size_t size)
305 %
306 % A description of each parameter follows:
307 %
308 % o size: the size of the memory in bytes to allocate.
309 %
310 */
311 MagickExport void *AcquireMemory(const size_t size)
312 {
313  void
314  *allocation;
315 
316  assert(size != 0);
317  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
318  allocation=malloc(size);
319  return(allocation);
320 }
321 ␌
322 /*
323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
324 % %
325 % %
326 % %
327 % A c q u i r e O n e C a c h e V i e w P i x e l %
328 % %
329 % %
330 % %
331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332 %
333 % AcquireOneCacheViewPixel() returns a single pixel at the specified (x,y)
334 % location. The image background color is returned if an error occurs. If
335 % you plan to modify the pixel, use GetOneCacheViewAuthenticPixel() instead.
336 %
337 % Deprecated, replace with:
338 %
339 % GetOneCacheViewVirtualPixel(cache_view,x,y,pixel,exception);
340 %
341 % The format of the AcquireOneCacheViewPixel method is:
342 %
343 % MagickBooleanType AcquireOneCacheViewPixel(const CacheView *cache_view,
344 % const ssize_t x,const ssize_t y,PixelPacket *pixel,
345 % ExceptionInfo *exception)
346 %
347 % A description of each parameter follows:
348 %
349 % o cache_view: the cache view.
350 %
351 % o x,y: These values define the offset of the pixel.
352 %
353 % o pixel: return a pixel at the specified (x,y) location.
354 %
355 % o exception: return any errors or warnings in this structure.
356 %
357 */
358 MagickExport MagickBooleanType AcquireOneCacheViewPixel(
359  const CacheView *cache_view,const ssize_t x,const ssize_t y,
360  PixelPacket *pixel,ExceptionInfo *exception)
361 {
362  return(GetOneCacheViewVirtualPixel(cache_view,x,y,pixel,exception));
363 }
364 ␌
365 /*
366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367 % %
368 % %
369 % %
370 % A c q u i r e O n e C a c h e V i e w V i r t u a l P i x e l %
371 % %
372 % %
373 % %
374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375 %
376 % AcquireOneCacheViewVirtualPixel() returns a single pixel at the specified
377 % (x,y) location. The image background color is returned if an error occurs.
378 % If you plan to modify the pixel, use GetOneCacheViewAuthenticPixel() instead.
379 %
380 % Deprecated, replace with:
381 %
382 % GetOneCacheViewVirtualMethodPixel(cache_view,virtual_pixel_method,
383 % x,y,pixel,exception);
384 %
385 % The format of the AcquireOneCacheViewPixel method is:
386 %
387 % MagickBooleanType AcquireOneCacheViewVirtualPixel(
388 % const CacheView *cache_view,
389 % const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
390 % const ssize_t y,PixelPacket *pixel,ExceptionInfo *exception)
391 %
392 % A description of each parameter follows:
393 %
394 % o cache_view: the cache view.
395 %
396 % o virtual_pixel_method: the virtual pixel method.
397 %
398 % o x,y: These values define the offset of the pixel.
399 %
400 % o pixel: return a pixel at the specified (x,y) location.
401 %
402 % o exception: return any errors or warnings in this structure.
403 %
404 */
405 MagickExport MagickBooleanType AcquireOneCacheViewVirtualPixel(
406  const CacheView *cache_view,const VirtualPixelMethod virtual_pixel_method,
407  const ssize_t x,const ssize_t y,PixelPacket *pixel,ExceptionInfo *exception)
408 {
409  MagickBooleanType
410  status;
411 
412  status=GetOneCacheViewVirtualMethodPixel(cache_view,virtual_pixel_method,
413  x,y,pixel,exception);
414  return(status);
415 }
416 ␌
417 /*
418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
419 % %
420 % %
421 % %
422 % A c q u i r e O n e M a g i c k P i x e l %
423 % %
424 % %
425 % %
426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
427 %
428 % AcquireOneMagickPixel() returns a single pixel at the specified (x,y)
429 % location. The image background color is returned if an error occurs. If
430 % you plan to modify the pixel, use GetOnePixel() instead.
431 %
432 % Deprecated, replace with:
433 %
434 % MagickPixelPacket pixel;
435 % GetOneVirtualMagickPixel(image,x,y,&pixel,exception);
436 %
437 % The format of the AcquireOneMagickPixel() method is:
438 %
439 % MagickPixelPacket AcquireOneMagickPixel(const Image image,const ssize_t x,
440 % const ssize_t y,ExceptionInfo exception)
441 %
442 % A description of each parameter follows:
443 %
444 % o image: the image.
445 %
446 % o x,y: These values define the location of the pixel to return.
447 %
448 % o exception: return any errors or warnings in this structure.
449 %
450 */
451 MagickExport MagickPixelPacket AcquireOneMagickPixel(const Image *image,
452  const ssize_t x,const ssize_t y,ExceptionInfo *exception)
453 {
455  pixel;
456 
457  (void) GetOneVirtualMagickPixel(image,x,y,&pixel,exception);
458  return(pixel);
459 }
460 ␌
461 /*
462 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
463 % %
464 % %
465 % %
466 % A c q u i r e O n e P i x e l %
467 % %
468 % %
469 % %
470 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
471 %
472 % AcquireOnePixel() returns a single pixel at the specified (x,y) location.
473 % The image background color is returned if an error occurs. If you plan to
474 % modify the pixel, use GetOnePixel() instead.
475 %
476 % Deprecated, replace with:
477 %
478 % PixelPacket pixel;
479 % GetOneVirtualPixel(image,x,y,&pixel,exception);
480 %
481 % The format of the AcquireOnePixel() method is:
482 %
483 % PixelPacket AcquireOnePixel(const Image image,const ssize_t x,
484 % const ssize_t y,ExceptionInfo exception)
485 %
486 % A description of each parameter follows:
487 %
488 % o image: the image.
489 %
490 % o x,y: These values define the location of the pixel to return.
491 %
492 % o exception: return any errors or warnings in this structure.
493 %
494 */
495 MagickExport PixelPacket AcquireOnePixel(const Image *image,const ssize_t x,
496  const ssize_t y,ExceptionInfo *exception)
497 {
499  pixel;
500 
501  (void) GetOneVirtualPixel(image,x,y,&pixel,exception);
502  return(pixel);
503 }
504 ␌
505 /*
506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
507 % %
508 % %
509 % %
510 % A c q u i r e O n e V i r t u a l P i x e l %
511 % %
512 % %
513 % %
514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
515 %
516 % AcquireOneVirtualPixel() returns a single pixel at the specified (x,y)
517 % location as defined by specified pixel method. The image background color
518 % is returned if an error occurs. If you plan to modify the pixel, use
519 % GetOnePixel() instead.
520 %
521 % Deprecated, replace with:
522 %
523 % PixelPacket pixel;
524 % GetOneVirtualMethodPixel(image,virtual_pixel_method,x,y,&pixel,exception);
525 %
526 % The format of the AcquireOneVirtualPixel() method is:
527 %
528 % PixelPacket AcquireOneVirtualPixel(const Image image,
529 % const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
530 % const ssize_t y,ExceptionInfo exception)
531 %
532 % A description of each parameter follows:
533 %
534 % o virtual_pixel_method: the virtual pixel method.
535 %
536 % o image: the image.
537 %
538 % o x,y: These values define the location of the pixel to return.
539 %
540 % o exception: return any errors or warnings in this structure.
541 %
542 */
543 MagickExport PixelPacket AcquireOneVirtualPixel(const Image *image,
544  const VirtualPixelMethod virtual_pixel_method,const ssize_t x,const ssize_t y,
545  ExceptionInfo *exception)
546 {
548  pixel;
549 
550  (void) GetOneVirtualMethodPixel(image,virtual_pixel_method,x,y,&pixel,
551  exception);
552  return(pixel);
553 }
554 ␌
555 /*
556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
557 % %
558 % %
559 % %
560 % A c q u i r e P i x e l s %
561 % %
562 % %
563 % %
564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
565 %
566 % AcquirePixels() returns the pixels associated with the last call to
567 % QueueAuthenticPixels() or GetVirtualPixels().
568 %
569 % Deprecated, replace with:
570 %
571 % GetVirtualPixelQueue(image);
572 %
573 % The format of the AcquirePixels() method is:
574 %
575 % const PixelPacket *AcquirePixels(const Image image)
576 %
577 % A description of each parameter follows:
578 %
579 % o image: the image.
580 %
581 */
582 MagickExport const PixelPacket *AcquirePixels(const Image *image)
583 {
584  return(GetVirtualPixelQueue(image));
585 }
586 ␌
587 /*
588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589 % %
590 % %
591 % %
592 % A c q u i r e S e m a p h o r e I n f o %
593 % %
594 % %
595 % %
596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597 %
598 % AcquireSemaphoreInfo() acquires a semaphore.
599 %
600 % The format of the AcquireSemaphoreInfo method is:
601 %
602 % void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
603 %
604 % A description of each parameter follows:
605 %
606 % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
607 %
608 */
609 MagickExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
610 {
611  assert(semaphore_info != (SemaphoreInfo **) NULL);
612  if (*semaphore_info == (SemaphoreInfo *) NULL)
613  {
614  InitializeMagickMutex();
615  LockMagickMutex();
616  if (*semaphore_info == (SemaphoreInfo *) NULL)
617  *semaphore_info=AllocateSemaphoreInfo();
618  UnlockMagickMutex();
619  }
620 }
621 ␌
622 /*
623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
624 % %
625 % %
626 % %
627 % A f f i n i t y I m a g e %
628 % %
629 % %
630 % %
631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632 %
633 % AffinityImage() replaces the colors of an image with the closest color from
634 % a reference image.
635 %
636 % Deprecated, replace with:
637 %
638 % RemapImage(quantize_info,image,affinity_image);
639 %
640 % The format of the AffinityImage method is:
641 %
642 % MagickBooleanType AffinityImage(const QuantizeInfo *quantize_info,
643 % Image *image,const Image *affinity_image)
644 %
645 % A description of each parameter follows:
646 %
647 % o quantize_info: Specifies a pointer to an QuantizeInfo structure.
648 %
649 % o image: the image.
650 %
651 % o affinity_image: the reference image.
652 %
653 */
654 MagickExport MagickBooleanType AffinityImage(const QuantizeInfo *quantize_info,
655  Image *image,const Image *affinity_image)
656 {
657  return(RemapImage(quantize_info,image,affinity_image));
658 }
659 ␌
660 /*
661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
662 % %
663 % %
664 % %
665 % A f f i n i t y I m a g e s %
666 % %
667 % %
668 % %
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
670 %
671 % AffinityImages() replaces the colors of a sequence of images with the
672 % closest color from a reference image.
673 %
674 % Deprecated, replace with:
675 %
676 % RemapImages(quantize_info,images,affinity_image);
677 %
678 % The format of the AffinityImage method is:
679 %
680 % MagickBooleanType AffinityImages(const QuantizeInfo *quantize_info,
681 % Image *images,Image *affinity_image)
682 %
683 % A description of each parameter follows:
684 %
685 % o quantize_info: Specifies a pointer to an QuantizeInfo structure.
686 %
687 % o images: the image sequence.
688 %
689 % o affinity_image: the reference image.
690 %
691 */
692 MagickExport MagickBooleanType AffinityImages(const QuantizeInfo *quantize_info,
693  Image *images,const Image *affinity_image)
694 {
695  return(RemapImages(quantize_info,images,affinity_image));
696 }
697 ␌
698 /*
699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
700 % %
701 % %
702 % %
703 % A l l o c a t e I m a g e %
704 % %
705 % %
706 % %
707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708 %
709 % AllocateImage() returns a pointer to an image structure initialized to
710 % default values.
711 %
712 % Deprecated, replace with:
713 %
714 % AcquireImage(image_info);
715 %
716 % The format of the AllocateImage method is:
717 %
718 % Image *AllocateImage(const ImageInfo *image_info)
719 %
720 % A description of each parameter follows:
721 %
722 % o image_info: Many of the image default values are set from this
723 % structure. For example, filename, compression, depth, background color,
724 % and others.
725 %
726 */
727 MagickExport Image *AllocateImage(const ImageInfo *image_info)
728 {
729  return(AcquireImage(image_info));
730 }
731 ␌
732 /*
733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
734 % %
735 % %
736 % %
737 % A l l o c a t e I m a g e C o l o r m a p %
738 % %
739 % %
740 % %
741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742 %
743 % AllocateImageColormap() allocates an image colormap and initializes
744 % it to a linear gray colorspace. If the image already has a colormap,
745 % it is replaced. AllocateImageColormap() returns MagickTrue if successful,
746 % otherwise MagickFalse if there is not enough memory.
747 %
748 % Deprecated, replace with:
749 %
750 % AcquireImageColormap(image,colors);
751 %
752 % The format of the AllocateImageColormap method is:
753 %
754 % MagickBooleanType AllocateImageColormap(Image *image,
755 % const size_t colors)
756 %
757 % A description of each parameter follows:
758 %
759 % o image: the image.
760 %
761 % o colors: the number of colors in the image colormap.
762 %
763 */
764 MagickExport MagickBooleanType AllocateImageColormap(Image *image,
765  const size_t colors)
766 {
767  return(AcquireImageColormap(image,colors));
768 }
769 ␌
770 /*
771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
772 % %
773 % %
774 % %
775 % A l l o c a t e N e x t I m a g e %
776 % %
777 % %
778 % %
779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
780 %
781 % AllocateNextImage() initializes the next image in a sequence to
782 % default values. The next member of image points to the newly allocated
783 % image. If there is a memory shortage, next is assigned NULL.
784 %
785 % Deprecated, replace with:
786 %
787 % AcquireNextImage(image_info,image);
788 %
789 % The format of the AllocateNextImage method is:
790 %
791 % void AllocateNextImage(const ImageInfo *image_info,Image *image)
792 %
793 % A description of each parameter follows:
794 %
795 % o image_info: Many of the image default values are set from this
796 % structure. For example, filename, compression, depth, background color,
797 % and others.
798 %
799 % o image: the image.
800 %
801 */
802 MagickExport void AllocateNextImage(const ImageInfo *image_info,Image *image)
803 {
804  AcquireNextImage(image_info,image);
805 }
806 ␌
807 /*
808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
809 % %
810 % %
811 % %
812 % A l l o c a t e S t r i n g %
813 % %
814 % %
815 % %
816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817 %
818 % AllocateString() allocates memory for a string and copies the source string
819 % to that memory location (and returns it).
820 %
821 % The format of the AllocateString method is:
822 %
823 % char *AllocateString(const char *source)
824 %
825 % A description of each parameter follows:
826 %
827 % o source: A character string.
828 %
829 */
830 MagickExport char *AllocateString(const char *source)
831 {
832  char
833  *destination;
834 
835  size_t
836  length;
837 
838  assert(source != (const char *) NULL);
839  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
840  length=strlen(source)+MaxTextExtent+1;
841  destination=(char *) AcquireQuantumMemory(length,sizeof(*destination));
842  if (destination == (char *) NULL)
843  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
844  *destination='\0';
845  (void) CopyMagickString(destination,source,length);
846  return(destination);
847 }
848 ␌
849 /*
850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851 % %
852 % %
853 % %
854 % A v e r a g e I m a g e s %
855 % %
856 % %
857 % %
858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859 %
860 % AverageImages() takes a set of images and averages them together. Each
861 % image in the set must have the same width and height. AverageImages()
862 % returns a single image with each corresponding pixel component of each
863 % image averaged. On failure, a NULL image is returned and exception
864 % describes the reason for the failure.
865 %
866 % Deprecated, replace with:
867 %
868 % EvaluateImages(images,MeanEvaluateOperator,exception);
869 %
870 % The format of the AverageImages method is:
871 %
872 % Image *AverageImages(Image *images,ExceptionInfo *exception)
873 %
874 % A description of each parameter follows:
875 %
876 % o image: the image sequence.
877 %
878 % o exception: return any errors or warnings in this structure.
879 %
880 */
881 MagickExport Image *AverageImages(const Image *images,ExceptionInfo *exception)
882 {
883  return(EvaluateImages(images,MeanEvaluateOperator,exception));
884 }
885 ␌
886 /*
887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
888 % %
889 % %
890 % %
891 % C h a n n e l I m a g e %
892 % %
893 % %
894 % %
895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
896 %
897 % Extract a channel from the image. A channel is a particular color component
898 % of each pixel in the image.
899 %
900 % Deprecated, replace with:
901 %
902 % SeparateImageChannel(image,channel);
903 %
904 % The format of the ChannelImage method is:
905 %
906 % unsigned int ChannelImage(Image *image,const ChannelType channel)
907 %
908 % A description of each parameter follows:
909 %
910 % o image: the image.
911 %
912 % o channel: Identify which channel to extract: RedChannel, GreenChannel,
913 % BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
914 % or BlackChannel.
915 %
916 */
917 MagickExport unsigned int ChannelImage(Image *image,const ChannelType channel)
918 {
919  return(SeparateImageChannel(image,channel));
920 }
921 ␌
922 /*
923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924 % %
925 % %
926 % %
927 % C h a n n e l T h r e s h o l d I m a g e %
928 % %
929 % %
930 % %
931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932 %
933 % ChannelThresholdImage() changes the value of individual pixels based on
934 % the intensity of each pixel channel. The result is a high-contrast image.
935 %
936 % The format of the ChannelThresholdImage method is:
937 %
938 % unsigned int ChannelThresholdImage(Image *image,const char *level)
939 %
940 % A description of each parameter follows:
941 %
942 % o image: the image.
943 %
944 % o level: define the threshold values.
945 %
946 */
947 MagickExport unsigned int ChannelThresholdImage(Image *image,const char *level)
948 {
950  threshold;
951 
953  geometry_info;
954 
955  unsigned int
956  flags,
957  status;
958 
959  assert(image != (Image *) NULL);
960  assert(image->signature == MagickCoreSignature);
961  if (IsEventLogging() != MagickFalse)
962  {
963  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
964  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
965  "last use: v5.5.7");
966  }
967  if (level == (char *) NULL)
968  return(MagickFalse);
969  flags=ParseGeometry(level,&geometry_info);
970  threshold.red=geometry_info.rho;
971  threshold.green=geometry_info.sigma;
972  if ((flags & SigmaValue) == 0)
973  threshold.green=threshold.red;
974  threshold.blue=geometry_info.xi;
975  if ((flags & XiValue) == 0)
976  threshold.blue=threshold.red;
977  status=BilevelImageChannel(image,RedChannel,threshold.red);
978  status&=BilevelImageChannel(image,GreenChannel,threshold.green);
979  status&=BilevelImageChannel(image,BlueChannel,threshold.blue);
980  return(status);
981 }
982 ␌
983 /*
984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
985 % %
986 % %
987 % %
988 % C l i p I m a g e P a t h %
989 % %
990 % %
991 % %
992 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
993 %
994 % ClipPathImage() sets the image clip mask based any clipping path information
995 % if it exists.
996 %
997 % Deprecated, replace with:
998 %
999 % ClipImagePath(image,pathname,inside);
1000 %
1001 % The format of the ClipImage method is:
1002 %
1003 % MagickBooleanType ClipPathImage(Image *image,const char *pathname,
1004 % const MagickBooleanType inside)
1005 %
1006 % A description of each parameter follows:
1007 %
1008 % o image: the image.
1009 %
1010 % o pathname: name of clipping path resource. If name is preceded by #, use
1011 % clipping path numbered by name.
1012 %
1013 % o inside: if non-zero, later operations take effect inside clipping path.
1014 % Otherwise later operations take effect outside clipping path.
1015 %
1016 */
1017 MagickExport MagickBooleanType ClipPathImage(Image *image,const char *pathname,
1018  const MagickBooleanType inside)
1019 {
1020  return(ClipImagePath(image,pathname,inside));
1021 }
1022 ␌
1023 /*
1024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025 % %
1026 % %
1027 % %
1028 % C l o n e I m a g e A t t r i b u t e s %
1029 % %
1030 % %
1031 % %
1032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1033 %
1034 % CloneImageAttributes() clones one or more image attributes.
1035 %
1036 % Deprecated, replace with:
1037 %
1038 % CloneImageProperties(image,clone_image);
1039 %
1040 % The format of the CloneImageAttributes method is:
1041 %
1042 % MagickBooleanType CloneImageAttributes(Image *image,
1043 % const Image *clone_image)
1044 %
1045 % A description of each parameter follows:
1046 %
1047 % o image: the image.
1048 %
1049 % o clone_image: the clone image.
1050 %
1051 */
1052 MagickExport MagickBooleanType CloneImageAttributes(Image *image,
1053  const Image *clone_image)
1054 {
1055  return(CloneImageProperties(image,clone_image));
1056 }
1057 ␌
1058 /*
1059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1060 % %
1061 % %
1062 % %
1063 % C l o n e M e m o r y %
1064 % %
1065 % %
1066 % %
1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1068 %
1069 % CloneMemory() copies size bytes from memory area source to the destination.
1070 % Copying between objects that overlap will take place correctly. It returns
1071 % destination.
1072 %
1073 % The format of the CloneMemory method is:
1074 %
1075 % void *CloneMemory(void *destination,const void *source,
1076 % const size_t size)
1077 %
1078 % A description of each parameter follows:
1079 %
1080 % o destination: the destination.
1081 %
1082 % o source: the source.
1083 %
1084 % o size: the size of the memory in bytes to allocate.
1085 %
1086 */
1087 MagickExport void *CloneMemory(void *destination,const void *source,
1088  const size_t size)
1089 {
1090  const unsigned char
1091  *p;
1092 
1093  unsigned char
1094  *q;
1095 
1096  ssize_t
1097  i;
1098 
1099  assert(destination != (void *) NULL);
1100  assert(source != (const void *) NULL);
1101  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
1102  p=(const unsigned char *) source;
1103  q=(unsigned char *) destination;
1104  if ((p <= q) || ((p+size) >= q))
1105  return(memcpy(destination,source,size));
1106  /*
1107  Overlap, copy backwards.
1108  */
1109  p+=size;
1110  q+=size;
1111  for (i=(ssize_t) (size-1); i >= 0; i--)
1112  *--q=(*--p);
1113  return(destination);
1114 }
1115 ␌
1116 /*
1117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1118 % %
1119 % %
1120 % %
1121 % C l o s e C a c h e V i e w %
1122 % %
1123 % %
1124 % %
1125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1126 %
1127 % CloseCacheView() closes the specified view returned by a previous call to
1128 % OpenCacheView().
1129 %
1130 % Deprecated, replace with:
1131 %
1132 % DestroyCacheView(view_info);
1133 %
1134 % The format of the CloseCacheView method is:
1135 %
1136 % CacheView *CloseCacheView(CacheView *view_info)
1137 %
1138 % A description of each parameter follows:
1139 %
1140 % o view_info: the address of a structure of type CacheView.
1141 %
1142 */
1143 MagickExport CacheView *CloseCacheView(CacheView *view_info)
1144 {
1145  return(DestroyCacheView(view_info));
1146 }
1147 ␌
1148 /*
1149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1150 % %
1151 % %
1152 % %
1153 % C o l o r F l o o d f i l l I m a g e %
1154 % %
1155 % %
1156 % %
1157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1158 %
1159 % ColorFloodfill() changes the color value of any pixel that matches
1160 % target and is an immediate neighbor. If the method FillToBorderMethod is
1161 % specified, the color value is changed for any neighbor pixel that does not
1162 % match the bordercolor member of image.
1163 %
1164 % By default target must match a particular pixel color exactly.
1165 % However, in many cases two colors may differ by a small amount. The
1166 % fuzz member of image defines how much tolerance is acceptable to
1167 % consider two colors as the same. For example, set fuzz to 10 and the
1168 % color red at intensities of 100 and 102 respectively are now
1169 % interpreted as the same color for the purposes of the floodfill.
1170 %
1171 % The format of the ColorFloodfillImage method is:
1172 %
1173 % MagickBooleanType ColorFloodfillImage(Image *image,
1174 % const DrawInfo *draw_info,const PixelPacket target,
1175 % const ssize_t x_offset,const ssize_t y_offset,const PaintMethod method)
1176 %
1177 % A description of each parameter follows:
1178 %
1179 % o image: the image.
1180 %
1181 % o draw_info: the draw info.
1182 %
1183 % o target: the RGB value of the target color.
1184 %
1185 % o x,y: the starting location of the operation.
1186 %
1187 % o method: Choose either FloodfillMethod or FillToBorderMethod.
1188 %
1189 */
1190 
1191 #define MaxStacksize (1UL << 15)
1192 #define PushSegmentStack(up,left,right,delta) \
1193 { \
1194  if (s >= (segment_stack+MaxStacksize)) \
1195  ThrowBinaryImageException(DrawError,"SegmentStackOverflow",image->filename) \
1196  else \
1197  { \
1198  if ((((up)+(delta)) >= 0) && (((up)+(delta)) < (ssize_t) image->rows)) \
1199  { \
1200  s->x1=(double) (left); \
1201  s->y1=(double) (up); \
1202  s->x2=(double) (right); \
1203  s->y2=(double) (delta); \
1204  s++; \
1205  } \
1206  } \
1207 }
1208 
1209 MagickExport MagickBooleanType ColorFloodfillImage(Image *image,
1210  const DrawInfo *draw_info,const PixelPacket target,const ssize_t x_offset,
1211  const ssize_t y_offset,const PaintMethod method)
1212 {
1213  Image
1214  *floodplane_image;
1215 
1216  MagickBooleanType
1217  skip;
1218 
1219  PixelPacket
1220  fill_color;
1221 
1222  SegmentInfo
1223  *s;
1224 
1225  SegmentInfo
1226  *segment_stack;
1227 
1228  ssize_t
1229  offset,
1230  start,
1231  x,
1232  x1,
1233  x2,
1234  y;
1235 
1236  /*
1237  Check boundary conditions.
1238  */
1239  assert(image != (Image *) NULL);
1240  assert(image->signature == MagickCoreSignature);
1241  assert(draw_info != (DrawInfo *) NULL);
1242  assert(draw_info->signature == MagickCoreSignature);
1243  if (IsEventLogging() != MagickFalse)
1244  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1245  if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns))
1246  return(MagickFalse);
1247  if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows))
1248  return(MagickFalse);
1249  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1250  return(MagickFalse);
1251  if (image->matte == MagickFalse)
1252  (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
1253  floodplane_image=CloneImage(image,0,0,MagickTrue,&image->exception);
1254  if (floodplane_image == (Image *) NULL)
1255  return(MagickFalse);
1256  (void) SetImageAlphaChannel(floodplane_image,OpaqueAlphaChannel);
1257  /*
1258  Set floodfill color.
1259  */
1260  segment_stack=(SegmentInfo *) AcquireQuantumMemory(MaxStacksize,
1261  sizeof(*segment_stack));
1262  if (segment_stack == (SegmentInfo *) NULL)
1263  {
1264  floodplane_image=DestroyImage(floodplane_image);
1265  ThrowBinaryImageException(ResourceLimitError,"MemoryAllocationFailed",
1266  image->filename);
1267  }
1268  /*
1269  Push initial segment on stack.
1270  */
1271  x=x_offset;
1272  y=y_offset;
1273  start=0;
1274  s=segment_stack;
1275  PushSegmentStack(y,x,x,1);
1276  PushSegmentStack(y+1,x,x,-1);
1277  while (s > segment_stack)
1278  {
1279  const PixelPacket
1280  *magick_restrict p;
1281 
1282  ssize_t
1283  x;
1284 
1285  PixelPacket
1286  *magick_restrict q;
1287 
1288  /*
1289  Pop segment off stack.
1290  */
1291  s--;
1292  x1=(ssize_t) s->x1;
1293  x2=(ssize_t) s->x2;
1294  offset=(ssize_t) s->y2;
1295  y=(ssize_t) s->y1+offset;
1296  /*
1297  Recolor neighboring pixels.
1298  */
1299  p=GetVirtualPixels(image,0,y,(size_t) (x1+1),1,&image->exception);
1300  q=GetAuthenticPixels(floodplane_image,0,y,(size_t) (x1+1),1,
1301  &image->exception);
1302  if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
1303  break;
1304  p+=x1;
1305  q+=x1;
1306  for (x=x1; x >= 0; x--)
1307  {
1308  if (q->opacity == (Quantum) TransparentOpacity)
1309  break;
1310  if (method == FloodfillMethod)
1311  {
1312  if (IsColorSimilar(image,p,&target) == MagickFalse)
1313  break;
1314  }
1315  else
1316  if (IsColorSimilar(image,p,&target) != MagickFalse)
1317  break;
1318  q->opacity=(Quantum) TransparentOpacity;
1319  p--;
1320  q--;
1321  }
1322  if (SyncAuthenticPixels(floodplane_image,&image->exception) == MagickFalse)
1323  break;
1324  skip=x >= x1 ? MagickTrue : MagickFalse;
1325  if (skip == MagickFalse)
1326  {
1327  start=x+1;
1328  if (start < x1)
1329  PushSegmentStack(y,start,x1-1,-offset);
1330  x=x1+1;
1331  }
1332  do
1333  {
1334  if (skip == MagickFalse)
1335  {
1336  if (x < (ssize_t) image->columns)
1337  {
1338  p=GetVirtualPixels(image,x,y,image->columns-x,1,
1339  &image->exception);
1340  q=GetAuthenticPixels(floodplane_image,x,y,image->columns-x,1,
1341  &image->exception);
1342  if ((p == (const PixelPacket *) NULL) ||
1343  (q == (PixelPacket *) NULL))
1344  break;
1345  for ( ; x < (ssize_t) image->columns; x++)
1346  {
1347  if (q->opacity == (Quantum) TransparentOpacity)
1348  break;
1349  if (method == FloodfillMethod)
1350  {
1351  if (IsColorSimilar(image,p,&target) == MagickFalse)
1352  break;
1353  }
1354  else
1355  if (IsColorSimilar(image,p,&target) != MagickFalse)
1356  break;
1357  q->opacity=(Quantum) TransparentOpacity;
1358  p++;
1359  q++;
1360  }
1361  if (SyncAuthenticPixels(floodplane_image,&image->exception) == MagickFalse)
1362  break;
1363  }
1364  PushSegmentStack(y,start,x-1,offset);
1365  if (x > (x2+1))
1366  PushSegmentStack(y,x2+1,x-1,-offset);
1367  }
1368  skip=MagickFalse;
1369  x++;
1370  if (x <= x2)
1371  {
1372  p=GetVirtualPixels(image,x,y,(size_t) (x2-x+1),1,
1373  &image->exception);
1374  q=GetAuthenticPixels(floodplane_image,x,y,(size_t) (x2-x+1),1,
1375  &image->exception);
1376  if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
1377  break;
1378  for ( ; x <= x2; x++)
1379  {
1380  if (q->opacity == (Quantum) TransparentOpacity)
1381  break;
1382  if (method == FloodfillMethod)
1383  {
1384  if (IsColorSimilar(image,p,&target) != MagickFalse)
1385  break;
1386  }
1387  else
1388  if (IsColorSimilar(image,p,&target) == MagickFalse)
1389  break;
1390  p++;
1391  q++;
1392  }
1393  }
1394  start=x;
1395  } while (x <= x2);
1396  }
1397  for (y=0; y < (ssize_t) image->rows; y++)
1398  {
1399  const PixelPacket
1400  *magick_restrict p;
1401 
1402  ssize_t
1403  x;
1404 
1405  PixelPacket
1406  *magick_restrict q;
1407 
1408  /*
1409  Tile fill color onto floodplane.
1410  */
1411  p=GetVirtualPixels(floodplane_image,0,y,image->columns,1,
1412  &image->exception);
1413  q=GetAuthenticPixels(image,0,y,image->columns,1,&image->exception);
1414  if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
1415  break;
1416  for (x=0; x < (ssize_t) image->columns; x++)
1417  {
1418  if (GetPixelOpacity(p) != OpaqueOpacity)
1419  {
1420  (void) GetFillColor(draw_info,x,y,&fill_color);
1421  MagickCompositeOver(&fill_color,(MagickRealType) fill_color.opacity,q,
1422  (MagickRealType) q->opacity,q);
1423  }
1424  p++;
1425  q++;
1426  }
1427  if (SyncAuthenticPixels(image,&image->exception) == MagickFalse)
1428  break;
1429  }
1430  segment_stack=(SegmentInfo *) RelinquishMagickMemory(segment_stack);
1431  floodplane_image=DestroyImage(floodplane_image);
1432  return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
1433 }
1434 ␌
1435 /*
1436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1437 % %
1438 % %
1439 % %
1440 + C o n s t i t u t e C o m p o n e n t G e n e s i s %
1441 % %
1442 % %
1443 % %
1444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1445 %
1446 % ConstituteComponentGenesis() instantiates the constitute component.
1447 %
1448 % The format of the ConstituteComponentGenesis method is:
1449 %
1450 % MagickBooleanType ConstituteComponentGenesis(void)
1451 %
1452 */
1453 MagickExport MagickBooleanType ConstituteComponentGenesis(void)
1454 {
1455  return(MagickTrue);
1456 }
1457 ␌
1458 /*
1459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1460 % %
1461 % %
1462 % %
1463 + C o n s t i t u t e C o m p o n e n t T e r m i n u s %
1464 % %
1465 % %
1466 % %
1467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1468 %
1469 % ConstituteComponentTerminus() destroys the constitute component.
1470 %
1471 % The format of the ConstituteComponentTerminus method is:
1472 %
1473 % ConstituteComponentTerminus(void)
1474 %
1475 */
1476 MagickExport void ConstituteComponentTerminus(void)
1477 {
1478 }
1479 ␌
1480 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
1481 /*
1482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1483 % %
1484 % %
1485 % %
1486 % C r o p I m a g e T o H B i t m a p %
1487 % %
1488 % %
1489 % %
1490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1491 %
1492 % CropImageToHBITMAP() extracts a specified region of the image and returns
1493 % it as a Windows HBITMAP. While the same functionality can be accomplished by
1494 % invoking CropImage() followed by ImageToHBITMAP(), this method is more
1495 % efficient since it copies pixels directly to the HBITMAP.
1496 %
1497 % The format of the CropImageToHBITMAP method is:
1498 %
1499 % HBITMAP CropImageToHBITMAP(Image* image,const RectangleInfo *geometry,
1500 % ExceptionInfo *exception)
1501 %
1502 % A description of each parameter follows:
1503 %
1504 % o image: the image.
1505 %
1506 % o geometry: Define the region of the image to crop with members
1507 % x, y, width, and height.
1508 %
1509 % o exception: return any errors or warnings in this structure.
1510 %
1511 */
1512 MagickExport void *CropImageToHBITMAP(Image *image,
1513  const RectangleInfo *geometry,ExceptionInfo *exception)
1514 {
1515 #define CropImageTag "Crop/Image"
1516 
1517  BITMAP
1518  bitmap;
1519 
1520  HBITMAP
1521  bitmapH;
1522 
1523  HANDLE
1524  bitmap_bitsH;
1525 
1526  MagickBooleanType
1527  proceed;
1528 
1530  page;
1531 
1532  const PixelPacket
1533  *p;
1534 
1535  RGBQUAD
1536  *q;
1537 
1538  RGBQUAD
1539  *bitmap_bits;
1540 
1541  ssize_t
1542  y;
1543 
1544  /*
1545  Check crop geometry.
1546  */
1547  assert(image != (const Image *) NULL);
1548  assert(image->signature == MagickCoreSignature);
1549  assert(geometry != (const RectangleInfo *) NULL);
1550  assert(exception != (ExceptionInfo *) NULL);
1551  assert(exception->signature == MagickCoreSignature);
1552  if (IsEventLogging() != MagickFalse)
1553  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1554  if (((geometry->x+(ssize_t) geometry->width) < 0) ||
1555  ((geometry->y+(ssize_t) geometry->height) < 0) ||
1556  (geometry->x >= (ssize_t) image->columns) ||
1557  (geometry->y >= (ssize_t) image->rows))
1558  ThrowImageException(OptionError,"GeometryDoesNotContainImage");
1559  page=(*geometry);
1560  if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
1561  page.width=image->columns-page.x;
1562  if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
1563  page.height=image->rows-page.y;
1564  if (page.x < 0)
1565  {
1566  page.width+=page.x;
1567  page.x=0;
1568  }
1569  if (page.y < 0)
1570  {
1571  page.height+=page.y;
1572  page.y=0;
1573  }
1574 
1575  if ((page.width == 0) || (page.height == 0))
1576  ThrowImageException(OptionError,"GeometryDimensionsAreZero");
1577  /*
1578  Initialize crop image attributes.
1579  */
1580  bitmap.bmType = 0;
1581  bitmap.bmWidth = (LONG) page.width;
1582  bitmap.bmHeight = (LONG) page.height;
1583  bitmap.bmWidthBytes = bitmap.bmWidth * 4;
1584  bitmap.bmPlanes = 1;
1585  bitmap.bmBitsPixel = 32;
1586  bitmap.bmBits = NULL;
1587 
1588  bitmap_bitsH=(HANDLE) GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,page.width*
1589  page.height*bitmap.bmBitsPixel);
1590  if (bitmap_bitsH == NULL)
1591  return(NULL);
1592  bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH);
1593  if ( bitmap.bmBits == NULL )
1594  bitmap.bmBits = bitmap_bits;
1595  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
1596  SetImageColorspace(image,sRGBColorspace);
1597  /*
1598  Extract crop image.
1599  */
1600  q=bitmap_bits;
1601  for (y=0; y < (ssize_t) page.height; y++)
1602  {
1603  ssize_t
1604  x;
1605 
1606  p=GetVirtualPixels(image,page.x,page.y+y,page.width,1,exception);
1607  if (p == (const PixelPacket *) NULL)
1608  break;
1609 
1610  /* Transfer pixels, scaling to Quantum */
1611  for( x=(ssize_t) page.width ; x> 0 ; x-- )
1612  {
1613  q->rgbRed = ScaleQuantumToChar(GetPixelRed(p));
1614  q->rgbGreen = ScaleQuantumToChar(GetPixelGreen(p));
1615  q->rgbBlue = ScaleQuantumToChar(GetPixelBlue(p));
1616  q->rgbReserved = 0;
1617  p++;
1618  q++;
1619  }
1620  proceed=SetImageProgress(image,CropImageTag,y,page.height);
1621  if (proceed == MagickFalse)
1622  break;
1623  }
1624  if (y < (ssize_t) page.height)
1625  {
1626  GlobalUnlock((HGLOBAL) bitmap_bitsH);
1627  GlobalFree((HGLOBAL) bitmap_bitsH);
1628  return((void *) NULL);
1629  }
1630  bitmap.bmBits=bitmap_bits;
1631  bitmapH=CreateBitmapIndirect(&bitmap);
1632  GlobalUnlock((HGLOBAL) bitmap_bitsH);
1633  GlobalFree((HGLOBAL) bitmap_bitsH);
1634  return((void *) bitmapH);
1635 }
1636 #endif
1637 ␌
1638 /*
1639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1640 % %
1641 % %
1642 % %
1643 % D e l e t e I m a g e A t t r i b u t e %
1644 % %
1645 % %
1646 % %
1647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1648 %
1649 % DeleteImageAttribute() deletes an attribute from the image.
1650 %
1651 % Deprecated, replace with:
1652 %
1653 % DeleteImageProperty(image,key);
1654 %
1655 % The format of the DeleteImageAttribute method is:
1656 %
1657 % MagickBooleanType DeleteImageAttribute(Image *image,const char *key)
1658 %
1659 % A description of each parameter follows:
1660 %
1661 % o image: the image info.
1662 %
1663 % o key: the image key.
1664 %
1665 */
1666 MagickExport MagickBooleanType DeleteImageAttribute(Image *image,
1667  const char *key)
1668 {
1669  return(DeleteImageProperty(image,key));
1670 }
1671 ␌
1672 /*
1673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1674 % %
1675 % %
1676 % %
1677 % D e l e t e I m a g e L i s t %
1678 % %
1679 % %
1680 % %
1681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1682 %
1683 % DeleteImageList() deletes an image at the specified position in the list.
1684 %
1685 % The format of the DeleteImageList method is:
1686 %
1687 % unsigned int DeleteImageList(Image *images,const ssize_t offset)
1688 %
1689 % A description of each parameter follows:
1690 %
1691 % o images: the image list.
1692 %
1693 % o offset: the position within the list.
1694 %
1695 */
1696 MagickExport unsigned int DeleteImageList(Image *images,const ssize_t offset)
1697 {
1698  ssize_t
1699  i;
1700 
1701  if (images->debug != MagickFalse)
1702  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
1703  while (GetPreviousImageInList(images) != (Image *) NULL)
1704  images=GetPreviousImageInList(images);
1705  for (i=0; i < offset; i++)
1706  {
1707  if (GetNextImageInList(images) == (Image *) NULL)
1708  return(MagickFalse);
1709  images=GetNextImageInList(images);
1710  }
1711  DeleteImageFromList(&images);
1712  return(MagickTrue);
1713 }
1714 ␌
1715 /*
1716 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1717 % %
1718 % %
1719 % %
1720 % D e l e t e M a g i c k R e g i s t r y %
1721 % %
1722 % %
1723 % %
1724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1725 %
1726 % DeleteMagickRegistry() deletes an entry in the registry as defined by the id.
1727 % It returns MagickTrue if the entry is deleted otherwise MagickFalse if no
1728 % entry is found in the registry that matches the id.
1729 %
1730 % Deprecated, replace with:
1731 %
1732 % char key[MaxTextExtent];
1733 % FormatLocaleString(key,MaxTextExtent,"%ld\n",id);
1734 % DeleteImageRegistry(key);
1735 %
1736 % The format of the DeleteMagickRegistry method is:
1737 %
1738 % MagickBooleanType DeleteMagickRegistry(const ssize_t id)
1739 %
1740 % A description of each parameter follows:
1741 %
1742 % o id: the registry id.
1743 %
1744 */
1745 MagickExport MagickBooleanType DeleteMagickRegistry(const ssize_t id)
1746 {
1747  char
1748  key[MaxTextExtent];
1749 
1750  (void) FormatLocaleString(key,MaxTextExtent,"%.20g\n",(double) id);
1751  return(DeleteImageRegistry(key));
1752 }
1753 ␌
1754 /*
1755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1756 % %
1757 % %
1758 % %
1759 + D e s t r o y C o n s t i t u t e %
1760 % %
1761 % %
1762 % %
1763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1764 %
1765 % DestroyConstitute() destroys the constitute component.
1766 %
1767 % The format of the DestroyConstitute method is:
1768 %
1769 % DestroyConstitute(void)
1770 %
1771 */
1772 MagickExport void DestroyConstitute(void)
1773 {
1774 }
1775 ␌
1776 /*
1777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1778 % %
1779 % %
1780 % %
1781 + D e s t r o y M a g i c k R e g i s t r y %
1782 % %
1783 % %
1784 % %
1785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1786 %
1787 % DestroyMagickRegistry() deallocates memory associated the magick registry.
1788 %
1789 % Deprecated, replace with:
1790 %
1791 % RegistryComponentTerminus();
1792 %
1793 % The format of the DestroyMagickRegistry method is:
1794 %
1795 % void DestroyMagickRegistry(void)
1796 %
1797 */
1798 MagickExport void DestroyMagickRegistry(void)
1799 {
1800  RegistryComponentTerminus();
1801 }
1802 ␌
1803 /*
1804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1805 % %
1806 % %
1807 % %
1808 % D e s c r i b e I m a g e %
1809 % %
1810 % %
1811 % %
1812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1813 %
1814 % DescribeImage() describes an image by printing its attributes to the file.
1815 % Attributes include the image width, height, size, and others.
1816 %
1817 % Deprecated, replace with:
1818 %
1819 % IdentifyImage(image,file,verbose);
1820 %
1821 % The format of the DescribeImage method is:
1822 %
1823 % MagickBooleanType DescribeImage(Image *image,FILE *file,
1824 % const MagickBooleanType verbose)
1825 %
1826 % A description of each parameter follows:
1827 %
1828 % o image: the image.
1829 %
1830 % o file: the file, typically stdout.
1831 %
1832 % o verbose: A value other than zero prints more detailed information
1833 % about the image.
1834 %
1835 */
1836 MagickExport MagickBooleanType DescribeImage(Image *image,FILE *file,
1837  const MagickBooleanType verbose)
1838 {
1839  return(IdentifyImage(image,file,verbose));
1840 }
1841 ␌
1842 /*
1843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1844 % %
1845 % %
1846 % %
1847 % D e s t r o y I m a g e A t t r i b u t e s %
1848 % %
1849 % %
1850 % %
1851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1852 %
1853 % DestroyImageAttributes() deallocates memory associated with the image
1854 % attribute list.
1855 %
1856 % The format of the DestroyImageAttributes method is:
1857 %
1858 % DestroyImageAttributes(Image *image)
1859 %
1860 % A description of each parameter follows:
1861 %
1862 % o image: the image.
1863 %
1864 */
1865 MagickExport void DestroyImageAttributes(Image *image)
1866 {
1867  assert(image != (Image *) NULL);
1868  assert(image->signature == MagickCoreSignature);
1869  if (IsEventLogging() != MagickFalse)
1870  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1871  if (image->attributes != (void *) NULL)
1872  image->attributes=(void *) DestroySplayTree((SplayTreeInfo *)
1873  image->attributes);
1874 }
1875 ␌
1876 /*
1877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1878 % %
1879 % %
1880 % %
1881 % D e s t r o y I m a g e s %
1882 % %
1883 % %
1884 % %
1885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1886 %
1887 % DestroyImages() destroys an image list.
1888 %
1889 % Deprecated, replace with:
1890 %
1891 % DestroyImageList(image);
1892 %
1893 % The format of the DestroyImages method is:
1894 %
1895 % void DestroyImages(Image *image)
1896 %
1897 % A description of each parameter follows:
1898 %
1899 % o image: the image sequence.
1900 %
1901 */
1902 MagickExport void DestroyImages(Image *image)
1903 {
1904  if (image == (Image *) NULL)
1905  return;
1906  if (IsEventLogging() != MagickFalse)
1907  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.4.3");
1908  image=DestroyImageList(image);
1909 }
1910 ␌
1911 /*
1912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1913 % %
1914 % %
1915 % %
1916 % D e s t r o y M a g i c k %
1917 % %
1918 % %
1919 % %
1920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1921 %
1922 % DestroyMagick() destroys the ImageMagick environment.
1923 %
1924 % Deprecated, replace with:
1925 %
1926 % MagickCoreTerminus();
1927 %
1928 % The format of the DestroyMagick function is:
1929 %
1930 % DestroyMagick(void)
1931 %
1932 */
1933 MagickExport void DestroyMagick(void)
1934 {
1935  MagickCoreTerminus();
1936 }
1937 ␌
1938 /*
1939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1940 % %
1941 % %
1942 % %
1943 % D i s p a t c h I m a g e %
1944 % %
1945 % %
1946 % %
1947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1948 %
1949 % DispatchImage() extracts pixel data from an image and returns it to you.
1950 % The method returns MagickFalse on success otherwise MagickTrue if an error is
1951 % encountered. The data is returned as char, short int, int, ssize_t, float,
1952 % or double in the order specified by map.
1953 %
1954 % Suppose you want to extract the first scanline of a 640x480 image as
1955 % character data in red-green-blue order:
1956 %
1957 % DispatchImage(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
1958 %
1959 % Deprecated, replace with:
1960 %
1961 % ExportImagePixels(image,x_offset,y_offset,columns,rows,map,type,pixels,
1962 % exception);
1963 %
1964 % The format of the DispatchImage method is:
1965 %
1966 % unsigned int DispatchImage(const Image *image,const ssize_t x_offset,
1967 % const ssize_t y_offset,const size_t columns,
1968 % const size_t rows,const char *map,const StorageType type,
1969 % void *pixels,ExceptionInfo *exception)
1970 %
1971 % A description of each parameter follows:
1972 %
1973 % o image: the image.
1974 %
1975 % o x_offset, y_offset, columns, rows: These values define the perimeter
1976 % of a region of pixels you want to extract.
1977 %
1978 % o map: This string reflects the expected ordering of the pixel array.
1979 % It can be any combination or order of R = red, G = green, B = blue,
1980 % A = alpha, C = cyan, Y = yellow, M = magenta, K = black, or
1981 % I = intensity (for grayscale).
1982 %
1983 % o type: Define the data type of the pixels. Float and double types are
1984 % normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
1985 % types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel, or
1986 % DoublePixel.
1987 %
1988 % o pixels: This array of values contain the pixel components as defined by
1989 % map and type. You must preallocate this array where the expected
1990 % length varies depending on the values of width, height, map, and type.
1991 %
1992 % o exception: return any errors or warnings in this structure.
1993 %
1994 */
1995 MagickExport unsigned int DispatchImage(const Image *image,const ssize_t x_offset,
1996  const ssize_t y_offset,const size_t columns,const size_t rows,
1997  const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
1998 {
1999  unsigned int
2000  status;
2001 
2002  if (IsEventLogging() != MagickFalse)
2003  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.6");
2004  status=ExportImagePixels(image,x_offset,y_offset,columns,rows,map,type,pixels,
2005  exception);
2006  return(status);
2007 }
2008 ␌
2009 /*
2010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2011 % %
2012 % %
2013 % %
2014 % E x t r a c t S u b i m a g e F r o m I m a g e %
2015 % %
2016 % %
2017 % %
2018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2019 %
2020 % ExtractSubimageFromImageImage() extracts a region of the image that most
2021 % closely resembles the reference.
2022 %
2023 % The format of the ExtractSubimageFromImageImage method is:
2024 %
2025 % Image *ExtractSubimageFromImage(const Image *image,
2026 % const Image *reference,ExceptionInfo *exception)
2027 %
2028 % A description of each parameter follows:
2029 %
2030 % o image: the image.
2031 %
2032 % o reference: find an area of the image that closely resembles this image.
2033 %
2034 % o exception: return any errors or warnings in this structure.
2035 %
2036 */
2037 
2038 static double GetSimilarityMetric(const Image *image,const Image *reference,
2039  const ssize_t x_offset,const ssize_t y_offset,
2040  const double similarity_threshold,ExceptionInfo *exception)
2041 {
2042  CacheView
2043  *image_view,
2044  *reference_view;
2045 
2046  double
2047  channels,
2048  normalized_similarity,
2049  similarity;
2050 
2051  ssize_t
2052  y;
2053 
2054  /*
2055  Compute the similarity in pixels between two images.
2056  */
2057  normalized_similarity=1.0;
2058  similarity=0.0;
2059  channels=3;
2060  if ((image->matte != MagickFalse) && (reference->matte != MagickFalse))
2061  channels++;
2062  if ((image->colorspace == CMYKColorspace) &&
2063  (reference->colorspace == CMYKColorspace))
2064  channels++;
2065  image_view=AcquireVirtualCacheView(image,exception);
2066  reference_view=AcquireVirtualCacheView(reference,exception);
2067  for (y=0; y < (ssize_t) reference->rows; y++)
2068  {
2069  const IndexPacket
2070  *indexes,
2071  *reference_indexes;
2072 
2073  const PixelPacket
2074  *p,
2075  *q;
2076 
2077  ssize_t
2078  x;
2079 
2080  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset+y,
2081  reference->columns,1,exception);
2082  q=GetCacheViewVirtualPixels(reference_view,0,y,reference->columns,1,
2083  exception);
2084  if ((p == (const PixelPacket *) NULL) || (q == (const PixelPacket *) NULL))
2085  continue;
2086  indexes=GetCacheViewVirtualIndexQueue(image_view);
2087  reference_indexes=GetCacheViewVirtualIndexQueue(reference_view);
2088  for (x=0; x < (ssize_t) reference->columns; x++)
2089  {
2090  MagickRealType
2091  pixel;
2092 
2093  pixel=QuantumScale*((double) GetPixelRed(p)-(double) GetPixelRed(q));
2094  similarity+=pixel*pixel;
2095  pixel=QuantumScale*((double) GetPixelGreen(p)-(double) GetPixelGreen(q));
2096  similarity+=pixel*pixel;
2097  pixel=QuantumScale*((double) GetPixelBlue(p)-(double) GetPixelBlue(q));
2098  similarity+=pixel*pixel;
2099  if ((image->matte != MagickFalse) && (reference->matte != MagickFalse))
2100  {
2101  pixel=QuantumScale*((double) GetPixelOpacity(p)-(double)
2102  GetPixelOpacity(q));
2103  similarity+=pixel*pixel;
2104  }
2105  if ((image->colorspace == CMYKColorspace) &&
2106  (reference->colorspace == CMYKColorspace))
2107  {
2108  pixel=QuantumScale*((double) GetPixelIndex(indexes+x)-(double)
2109  GetPixelIndex(reference_indexes+x));
2110  similarity+=pixel*pixel;
2111  }
2112  p++;
2113  q++;
2114  }
2115  normalized_similarity=sqrt(similarity)/reference->columns/reference->rows/
2116  channels;
2117  if (normalized_similarity > similarity_threshold)
2118  break;
2119  }
2120  reference_view=DestroyCacheView(reference_view);
2121  image_view=DestroyCacheView(image_view);
2122  return(normalized_similarity);
2123 }
2124 
2125 MagickExport Image *ExtractSubimageFromImage(Image *image,
2126  const Image *reference,ExceptionInfo *exception)
2127 {
2128  double
2129  similarity_threshold;
2130 
2132  offset;
2133 
2134  ssize_t
2135  y;
2136 
2137  /*
2138  Extract reference from image.
2139  */
2140  if ((reference->columns > image->columns) || (reference->rows > image->rows))
2141  return((Image *) NULL);
2142  similarity_threshold=(double) image->columns*image->rows;
2143  SetGeometry(reference,&offset);
2144 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2145  #pragma omp parallel for schedule(static)
2146 #endif
2147  for (y=0; y < (ssize_t) (image->rows-reference->rows); y++)
2148  {
2149  double
2150  similarity;
2151 
2152  ssize_t
2153  x;
2154 
2155  for (x=0; x < (ssize_t) (image->columns-reference->columns); x++)
2156  {
2157  similarity=GetSimilarityMetric(image,reference,x,y,similarity_threshold,
2158  exception);
2159 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2160  #pragma omp critical (MagickCore_ExtractSubimageFromImage)
2161 #endif
2162  if (similarity < similarity_threshold)
2163  {
2164  similarity_threshold=similarity;
2165  offset.x=x;
2166  offset.y=y;
2167  }
2168  }
2169  }
2170  if (similarity_threshold > (QuantumScale*reference->fuzz/100.0))
2171  return((Image *) NULL);
2172  return(CropImage(image,&offset,exception));
2173 }
2174 ␌
2175 /*
2176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2177 % %
2178 % %
2179 % %
2180 % F l a t t e n I m a g e %
2181 % %
2182 % %
2183 % %
2184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2185 %
2186 % FlattenImages() Obsolete Function: Use MergeImageLayers() instead.
2187 %
2188 % Deprecated, replace with:
2189 %
2190 % MergeImageLayers(image,FlattenLayer,exception);
2191 %
2192 % The format of the FlattenImage method is:
2193 %
2194 % Image *FlattenImage(Image *image,ExceptionInfo *exception)
2195 %
2196 % A description of each parameter follows:
2197 %
2198 % o image: the image sequence.
2199 %
2200 % o exception: return any errors or warnings in this structure.
2201 %
2202 */
2203 MagickExport Image *FlattenImages(Image *image,ExceptionInfo *exception)
2204 {
2205  return(MergeImageLayers(image,FlattenLayer,exception));
2206 }
2207 ␌
2208 /*
2209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2210 % %
2211 % %
2212 % %
2213 % F o r m a t I m a g e A t t r i b u t e %
2214 % %
2215 % %
2216 % %
2217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2218 %
2219 % FormatImageAttribute() permits formatted key/value pairs to be saved as an
2220 % image attribute.
2221 %
2222 % The format of the FormatImageAttribute method is:
2223 %
2224 % MagickBooleanType FormatImageAttribute(Image *image,const char *key,
2225 % const char *format,...)
2226 %
2227 % A description of each parameter follows.
2228 %
2229 % o image: The image.
2230 %
2231 % o key: The attribute key.
2232 %
2233 % o format: A string describing the format to use to write the remaining
2234 % arguments.
2235 %
2236 */
2237 
2238 MagickExport MagickBooleanType FormatImageAttributeList(Image *image,
2239  const char *key,const char *format,va_list operands)
2240 {
2241  char
2242  value[MaxTextExtent];
2243 
2244  int
2245  n;
2246 
2247 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
2248  n=vsnprintf(value,MaxTextExtent,format,operands);
2249 #else
2250  n=vsprintf(value,format,operands);
2251 #endif
2252  if (n < 0)
2253  value[MaxTextExtent-1]='\0';
2254  return(SetImageProperty(image,key,value));
2255 }
2256 
2257 MagickExport MagickBooleanType FormatImagePropertyList(Image *image,
2258  const char *property,const char *format,va_list operands)
2259 {
2260  char
2261  value[MaxTextExtent];
2262 
2263  int
2264  n;
2265 
2266 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
2267  n=vsnprintf(value,MaxTextExtent,format,operands);
2268 #else
2269  n=vsprintf(value,format,operands);
2270 #endif
2271  if (n < 0)
2272  value[MaxTextExtent-1]='\0';
2273  return(SetImageProperty(image,property,value));
2274 }
2275 
2276 MagickExport MagickBooleanType FormatImageAttribute(Image *image,
2277  const char *key,const char *format,...)
2278 {
2279  char
2280  value[MaxTextExtent];
2281 
2282  int
2283  n;
2284 
2285  va_list
2286  operands;
2287 
2288  va_start(operands,format);
2289  n=FormatLocaleStringList(value,MaxTextExtent,format,operands);
2290  (void) n;
2291  va_end(operands);
2292  return(SetImageProperty(image,key,value));
2293 }
2294 ␌
2295 /*
2296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2297 % %
2298 % %
2299 % %
2300 % F o r m a t M a g i c k S t r i n g %
2301 % %
2302 % %
2303 % %
2304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2305 %
2306 % FormatMagickString() prints formatted output of a variable argument list.
2307 %
2308 % The format of the FormatMagickString method is:
2309 %
2310 % ssize_t FormatMagickString(char *string,const size_t length,
2311 % const char *format,...)
2312 %
2313 % A description of each parameter follows.
2314 %
2315 % o string: FormatMagickString() returns the formatted string in this
2316 % character buffer.
2317 %
2318 % o length: the maximum length of the string.
2319 %
2320 % o format: A string describing the format to use to write the remaining
2321 % arguments.
2322 %
2323 */
2324 
2325 MagickExport ssize_t FormatMagickStringList(char *string,const size_t length,
2326  const char *format,va_list operands)
2327 {
2328  int
2329  n;
2330 
2331 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
2332  n=vsnprintf(string,length,format,operands);
2333 #else
2334  n=vsprintf(string,format,operands);
2335 #endif
2336  if (n < 0)
2337  string[length-1]='\0';
2338  return((ssize_t) n);
2339 }
2340 
2341 MagickExport ssize_t FormatMagickString(char *string,const size_t length,
2342  const char *format,...)
2343 {
2344  ssize_t
2345  n;
2346 
2347  va_list
2348  operands;
2349 
2350  va_start(operands,format);
2351  n=(ssize_t) FormatMagickStringList(string,length,format,operands);
2352  va_end(operands);
2353  return(n);
2354 }
2355 ␌
2356 /*
2357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2358 % %
2359 % %
2360 % %
2361 % F o r m a t S t r i n g %
2362 % %
2363 % %
2364 % %
2365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2366 %
2367 % FormatString() prints formatted output of a variable argument list.
2368 %
2369 % The format of the FormatString method is:
2370 %
2371 % void FormatString(char *string,const char *format,...)
2372 %
2373 % A description of each parameter follows.
2374 %
2375 % o string: Method FormatString returns the formatted string in this
2376 % character buffer.
2377 %
2378 % o format: A string describing the format to use to write the remaining
2379 % arguments.
2380 %
2381 */
2382 
2383 MagickExport void FormatStringList(char *string,const char *format,
2384  va_list operands)
2385 {
2386  int
2387  n;
2388 
2389  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
2390 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
2391  n=vsnprintf(string,MaxTextExtent,format,operands);
2392 #else
2393  n=vsprintf(string,format,operands);
2394 #endif
2395  if (n < 0)
2396  string[MaxTextExtent-1]='\0';
2397 }
2398 
2399 MagickExport void FormatString(char *string,const char *format,...)
2400 {
2401  va_list
2402  operands;
2403 
2404  va_start(operands,format);
2405  (void) FormatLocaleStringList(string,MaxTextExtent,format,operands);
2406  va_end(operands);
2407  return;
2408 }
2409 ␌
2410 /*
2411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2412 % %
2413 % %
2414 % %
2415 + F u z z y C o l o r M a t c h %
2416 % %
2417 % %
2418 % %
2419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2420 %
2421 % FuzzyColorMatch() returns true if two pixels are identical in color.
2422 %
2423 % The format of the ColorMatch method is:
2424 %
2425 % void FuzzyColorMatch(const PixelPacket *p,const PixelPacket *q,
2426 % const double fuzz)
2427 %
2428 % A description of each parameter follows:
2429 %
2430 % o p: Pixel p.
2431 %
2432 % o q: Pixel q.
2433 %
2434 % o distance: Define how much tolerance is acceptable to consider
2435 % two colors as the same.
2436 %
2437 */
2438 MagickExport unsigned int FuzzyColorMatch(const PixelPacket *p,
2439  const PixelPacket *q,const double fuzz)
2440 {
2442  pixel;
2443 
2444  MagickRealType
2445  distance;
2446 
2447  if ((fuzz == 0.0) && (GetPixelRed(p) == GetPixelRed(q)) &&
2448  (GetPixelGreen(p) == GetPixelGreen(q)) &&
2449  (GetPixelBlue(p) == GetPixelBlue(q)))
2450  return(MagickTrue);
2451  pixel.red=(MagickRealType) GetPixelRed(p)-(MagickRealType) GetPixelRed(q);
2452  distance=pixel.red*pixel.red;
2453  if (distance > (fuzz*fuzz))
2454  return(MagickFalse);
2455  pixel.green=(MagickRealType) GetPixelGreen(p)-(MagickRealType)
2456  GetPixelGreen(q);
2457  distance+=pixel.green*pixel.green;
2458  if (distance > (fuzz*fuzz))
2459  return(MagickFalse);
2460  pixel.blue=(MagickRealType) GetPixelBlue(p)-(MagickRealType) GetPixelBlue(q);
2461  distance+=pixel.blue*pixel.blue;
2462  if (distance > (fuzz*fuzz))
2463  return(MagickFalse);
2464  return(MagickTrue);
2465 }
2466 ␌
2467 /*
2468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2469 % %
2470 % %
2471 % %
2472 + F u z z y C o l o r C o m p a r e %
2473 % %
2474 % %
2475 % %
2476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2477 %
2478 % FuzzyColorCompare() returns MagickTrue if the distance between two colors is
2479 % less than the specified distance in a linear three dimensional color space.
2480 % This method is used by ColorFloodFill() and other algorithms which
2481 % compare two colors.
2482 %
2483 % The format of the FuzzyColorCompare method is:
2484 %
2485 % void FuzzyColorCompare(const Image *image,const PixelPacket *p,
2486 % const PixelPacket *q)
2487 %
2488 % A description of each parameter follows:
2489 %
2490 % o image: the image.
2491 %
2492 % o p: Pixel p.
2493 %
2494 % o q: Pixel q.
2495 %
2496 */
2497 MagickExport MagickBooleanType FuzzyColorCompare(const Image *image,
2498  const PixelPacket *p,const PixelPacket *q)
2499 {
2500  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.2.5");
2501  return(IsColorSimilar(image,p,q));
2502 }
2503 ␌
2504 /*
2505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2506 % %
2507 % %
2508 % %
2509 + F u z z y O p a c i t y C o m p a r e %
2510 % %
2511 % %
2512 % %
2513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2514 %
2515 % FuzzyOpacityCompare() returns true if the distance between two opacity
2516 % values is less than the specified distance in a linear color space. This
2517 % method is used by MatteFloodFill() and other algorithms which compare
2518 % two opacity values.
2519 %
2520 % Deprecated, replace with:
2521 %
2522 % IsOpacitySimilar(image,p,q);
2523 %
2524 % The format of the FuzzyOpacityCompare method is:
2525 %
2526 % void FuzzyOpacityCompare(const Image *image,const PixelPacket *p,
2527 % const PixelPacket *q)
2528 %
2529 % A description of each parameter follows:
2530 %
2531 % o image: the image.
2532 %
2533 % o p: Pixel p.
2534 %
2535 % o q: Pixel q.
2536 %
2537 */
2538 MagickExport MagickBooleanType FuzzyOpacityCompare(const Image *image,
2539  const PixelPacket *p,const PixelPacket *q)
2540 {
2541  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.2.5");
2542  return(IsOpacitySimilar(image,p,q));
2543 }
2544 ␌
2545 /*
2546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2547 % %
2548 % %
2549 % %
2550 % G e t C o n f i g u r e B l o b %
2551 % %
2552 % %
2553 % %
2554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2555 %
2556 % GetConfigureBlob() returns the specified configure file as a blob.
2557 %
2558 % The format of the GetConfigureBlob method is:
2559 %
2560 % void *GetConfigureBlob(const char *filename,ExceptionInfo *exception)
2561 %
2562 % A description of each parameter follows:
2563 %
2564 % o filename: the configure file name.
2565 %
2566 % o path: return the full path information of the configure file.
2567 %
2568 % o length: This pointer to a size_t integer sets the initial length of the
2569 % blob. On return, it reflects the actual length of the blob.
2570 %
2571 % o exception: return any errors or warnings in this structure.
2572 %
2573 */
2574 MagickExport void *GetConfigureBlob(const char *filename,char *path,
2575  size_t *length,ExceptionInfo *exception)
2576 {
2577  void
2578  *blob;
2579 
2580  assert(filename != (const char *) NULL);
2581  if (IsEventLogging() != MagickFalse)
2582  {
2583  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
2584  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
2585  "last use: v5.5.7");
2586  }
2587  assert(path != (char *) NULL);
2588  assert(length != (size_t *) NULL);
2589  assert(exception != (ExceptionInfo *) NULL);
2590  blob=(void *) NULL;
2591  (void) CopyMagickString(path,filename,MaxTextExtent);
2592 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
2593 #if defined(MAGICKCORE_LIBRARY_ABSOLUTE_PATH)
2594  if (blob == (void *) NULL)
2595  {
2596  /*
2597  Search hard coded paths.
2598  */
2599  (void) FormatLocaleString(path,MaxTextExtent,"%s%s",
2600  MAGICKCORE_LIBRARY_ABSOLUTE_PATH,filename);
2601  if (IsPathAccessible(path) != MagickFalse)
2602  blob=FileToBlob(path,~0UL,length,exception);
2603  }
2604 #endif
2605 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
2606  if (blob == (void *) NULL)
2607  {
2608  unsigned char
2609  *key_value;
2610 
2611  /*
2612  Locate file via registry key.
2613  */
2614  key_value=NTRegistryKeyLookup("ConfigurePath");
2615  if (key_value != (unsigned char *) NULL)
2616  {
2617  (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",(char *)
2618  key_value,DirectorySeparator,filename);
2619  if (IsPathAccessible(path) != MagickFalse)
2620  blob=FileToBlob(path,~0UL,length,exception);
2621  }
2622  }
2623 #endif
2624 #else
2625  if (blob == (void *) NULL)
2626  {
2627  char
2628  *home;
2629 
2630  home=GetEnvironmentValue("MAGICK_HOME");
2631  if (home != (char *) NULL)
2632  {
2633  /*
2634  Search MAGICK_HOME.
2635  */
2636 #if !defined(MAGICKCORE_POSIX_SUPPORT)
2637  (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",home,
2638  DirectorySeparator,filename);
2639 #else
2640  (void) FormatLocaleString(path,MaxTextExtent,"%s/lib/%s/%s",home,
2641  MAGICKCORE_LIBRARY_RELATIVE_PATH,filename);
2642 #endif
2643  if (IsPathAccessible(path) != MagickFalse)
2644  blob=FileToBlob(path,~0UL,length,exception);
2645  home=DestroyString(home);
2646  }
2647  home=GetEnvironmentValue("HOME");
2648  if (home == (char *) NULL)
2649  home=GetEnvironmentValue("USERPROFILE");
2650  if (home != (char *) NULL)
2651  {
2652  /*
2653  Search $HOME/.magick.
2654  */
2655  (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s%s",home,
2656  DirectorySeparator,DirectorySeparator,filename);
2657  if ((IsPathAccessible(path) != MagickFalse) && (blob == (void *) NULL))
2658  blob=FileToBlob(path,~0UL,length,exception);
2659  home=DestroyString(home);
2660  }
2661  }
2662  if ((blob == (void *) NULL) && (*GetClientPath() != '\0'))
2663  {
2664 #if !defined(MAGICKCORE_POSIX_SUPPORT)
2665  (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
2666  DirectorySeparator,filename);
2667 #else
2668  char
2669  prefix[MaxTextExtent];
2670 
2671  /*
2672  Search based on executable directory if directory is known.
2673  */
2674  (void) CopyMagickString(prefix,GetClientPath(),
2675  MaxTextExtent);
2676  ChopPathComponents(prefix,1);
2677  (void) FormatLocaleString(path,MaxTextExtent,"%s/lib/%s/%s",prefix,
2678  MAGICKCORE_LIBRARY_RELATIVE_PATH,filename);
2679 #endif
2680  if (IsPathAccessible(path) != MagickFalse)
2681  blob=FileToBlob(path,~0UL,length,exception);
2682  }
2683  /*
2684  Search current directory.
2685  */
2686  if ((blob == (void *) NULL) && (IsPathAccessible(path) != MagickFalse))
2687  blob=FileToBlob(path,~0UL,length,exception);
2688 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
2689  /*
2690  Search Windows registry.
2691  */
2692  if (blob == (void *) NULL)
2693  blob=NTResourceToBlob(filename);
2694 #endif
2695 #endif
2696  if (blob == (void *) NULL)
2697  (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
2698  "UnableToOpenConfigureFile","`%s'",path);
2699  return(blob);
2700 }
2701 ␌
2702 /*
2703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2704 % %
2705 % %
2706 % %
2707 % G e t C a c h e V i e w %
2708 % %
2709 % %
2710 % %
2711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2712 %
2713 % GetCacheView() gets pixels from the in-memory or disk pixel cache as
2714 % defined by the geometry parameters. A pointer to the pixels is returned if
2715 % the pixels are transferred, otherwise a NULL is returned.
2716 %
2717 % Deprecated, replace with:
2718 %
2719 % GetCacheViewAuthenticPixels(cache_view,x,y,columns,rows,
2720 % GetCacheViewException(cache_view));
2721 %
2722 % The format of the GetCacheView method is:
2723 %
2724 % PixelPacket *GetCacheView(CacheView *cache_view,const ssize_t x,
2725 % const ssize_t y,const size_t columns,const size_t rows)
2726 %
2727 % A description of each parameter follows:
2728 %
2729 % o cache_view: the address of a structure of type CacheView.
2730 %
2731 % o x,y,columns,rows: These values define the perimeter of a region of
2732 % pixels.
2733 %
2734 */
2735 MagickExport PixelPacket *GetCacheView(CacheView *cache_view,const ssize_t x,
2736  const ssize_t y,const size_t columns,const size_t rows)
2737 {
2738  PixelPacket
2739  *pixels;
2740 
2741  pixels=GetCacheViewAuthenticPixels(cache_view,x,y,columns,rows,
2742  GetCacheViewException(cache_view));
2743  return(pixels);
2744 }
2745 ␌
2746 /*
2747 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2748 % %
2749 % %
2750 % %
2751 % G e t C a c h e V i e w I n d e x e s %
2752 % %
2753 % %
2754 % %
2755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2756 %
2757 % GetCacheViewIndexes() returns the indexes associated with the specified
2758 % view.
2759 %
2760 % Deprecated, replace with:
2761 %
2762 % GetCacheViewAuthenticIndexQueue(cache_view);
2763 %
2764 % The format of the GetCacheViewIndexes method is:
2765 %
2766 % IndexPacket *GetCacheViewIndexes(CacheView *cache_view)
2767 %
2768 % A description of each parameter follows:
2769 %
2770 % o cache_view: the cache view.
2771 %
2772 */
2773 MagickExport IndexPacket *GetCacheViewIndexes(CacheView *cache_view)
2774 {
2775  return(GetCacheViewAuthenticIndexQueue(cache_view));
2776 }
2777 ␌
2778 /*
2779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2780 % %
2781 % %
2782 % %
2783 % G e t C a c h e V i e w P i x e l s %
2784 % %
2785 % %
2786 % %
2787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2788 %
2789 % GetCacheViewPixels() gets pixels from the in-memory or disk pixel cache as
2790 % defined by the geometry parameters. A pointer to the pixels is returned if
2791 % the pixels are transferred, otherwise a NULL is returned.
2792 %
2793 % Deprecated, replace with:
2794 %
2795 % GetCacheViewAuthenticPixels(cache_view,x,y,columns,rows,
2796 % GetCacheViewException(cache_view));
2797 %
2798 % The format of the GetCacheViewPixels method is:
2799 %
2800 % PixelPacket *GetCacheViewPixels(CacheView *cache_view,const ssize_t x,
2801 % const ssize_t y,const size_t columns,const size_t rows)
2802 %
2803 % A description of each parameter follows:
2804 %
2805 % o cache_view: the cache view.
2806 %
2807 % o x,y,columns,rows: These values define the perimeter of a region of
2808 % pixels.
2809 %
2810 */
2811 MagickExport PixelPacket *GetCacheViewPixels(CacheView *cache_view,const ssize_t x,
2812  const ssize_t y,const size_t columns,const size_t rows)
2813 {
2814  PixelPacket
2815  *pixels;
2816 
2817  pixels=GetCacheViewAuthenticPixels(cache_view,x,y,columns,rows,
2818  GetCacheViewException(cache_view));
2819  return(pixels);
2820 }
2821 ␌
2822 /*
2823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2824 % %
2825 % %
2826 % %
2827 % G e t E x c e p t i o n I n f o %
2828 % %
2829 % %
2830 % %
2831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2832 %
2833 % GetExceptionInfo() initializes an exception to default values.
2834 %
2835 % The format of the GetExceptionInfo method is:
2836 %
2837 % GetExceptionInfo(ExceptionInfo *exception)
2838 %
2839 % A description of each parameter follows:
2840 %
2841 % o exception: the exception info.
2842 %
2843 */
2844 MagickExport void GetExceptionInfo(ExceptionInfo *exception)
2845 {
2846  assert(exception != (ExceptionInfo *) NULL);
2847  (void) memset(exception,0,sizeof(*exception));
2848  exception->severity=UndefinedException;
2849  exception->exceptions=(void *) NewLinkedList(0);
2850  exception->semaphore=AllocateSemaphoreInfo();
2851  exception->signature=MagickCoreSignature;
2852 }
2853 ␌
2854 /*
2855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2856 % %
2857 % %
2858 % %
2859 % G e t I m a g e A t t r i b u t e %
2860 % %
2861 % %
2862 % %
2863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2864 %
2865 % GetImageAttribute() searches the list of image attributes and returns
2866 % a pointer to the attribute if it exists otherwise NULL.
2867 %
2868 % The format of the GetImageAttribute method is:
2869 %
2870 % const ImageAttribute *GetImageAttribute(const Image *image,
2871 % const char *key)
2872 %
2873 % A description of each parameter follows:
2874 %
2875 % o image: the image.
2876 %
2877 % o key: These character strings are the name of an image attribute to
2878 % return.
2879 %
2880 */
2881 
2882 static void *DestroyAttribute(void *attribute)
2883 {
2885  *p;
2886 
2887  p=(ImageAttribute *) attribute;
2888  if (p->value != (char *) NULL)
2889  p->value=DestroyString(p->value);
2890  return(RelinquishMagickMemory(p));
2891 }
2892 
2893 MagickExport const ImageAttribute *GetImageAttribute(const Image *image,
2894  const char *key)
2895 {
2896  const char
2897  *value;
2898 
2900  *attribute;
2901 
2902  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.3.1");
2903  value=GetImageProperty(image,key);
2904  if (value == (const char *) NULL)
2905  return((const ImageAttribute *) NULL);
2906  if (image->attributes == (void *) NULL)
2907  ((Image *) image)->attributes=NewSplayTree(CompareSplayTreeString,
2908  RelinquishMagickMemory,DestroyAttribute);
2909  else
2910  {
2911  const ImageAttribute
2912  *attribute;
2913 
2914  attribute=(const ImageAttribute *) GetValueFromSplayTree((SplayTreeInfo *)
2915  image->attributes,key);
2916  if (attribute != (const ImageAttribute *) NULL)
2917  return(attribute);
2918  }
2919  attribute=(ImageAttribute *) AcquireMagickMemory(sizeof(*attribute));
2920  if (attribute == (ImageAttribute *) NULL)
2921  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
2922  (void) memset(attribute,0,sizeof(*attribute));
2923  attribute->key=ConstantString(key);
2924  attribute->value=ConstantString(value);
2925  (void) AddValueToSplayTree((SplayTreeInfo *) ((Image *) image)->attributes,
2926  attribute->key,attribute);
2927  return((const ImageAttribute *) attribute);
2928 }
2929 ␌
2930 /*
2931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2932 % %
2933 % %
2934 % %
2935 % G e t I m a g e C l i p p i n g P a t h A t t r i b u t e %
2936 % %
2937 % %
2938 % %
2939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2940 %
2941 % GetImageClippingPathAttribute() searches the list of image attributes and
2942 % returns a pointer to a clipping path if it exists otherwise NULL.
2943 %
2944 % Deprecated, replace with:
2945 %
2946 % GetImageAttribute(image,"8BIM:1999,2998");
2947 %
2948 % The format of the GetImageClippingPathAttribute method is:
2949 %
2950 % const ImageAttribute *GetImageClippingPathAttribute(Image *image)
2951 %
2952 % A description of each parameter follows:
2953 %
2954 % o attribute: Method GetImageClippingPathAttribute returns the clipping
2955 % path if it exists otherwise NULL.
2956 %
2957 % o image: the image.
2958 %
2959 */
2960 MagickExport const ImageAttribute *GetImageClippingPathAttribute(Image *image)
2961 {
2962  return(GetImageAttribute(image,"8BIM:1999,2998"));
2963 }
2964 ␌
2965 /*
2966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2967 % %
2968 % %
2969 % %
2970 % G e t I m a g e F r o m M a g i c k R e g i s t r y %
2971 % %
2972 % %
2973 % %
2974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2975 %
2976 % GetImageFromMagickRegistry() gets an image from the registry as defined by
2977 % its name. If the image is not found, a NULL image is returned.
2978 %
2979 % Deprecated, replace with:
2980 %
2981 % GetImageRegistry(ImageRegistryType,name,exception);
2982 %
2983 % The format of the GetImageFromMagickRegistry method is:
2984 %
2985 % Image *GetImageFromMagickRegistry(const char *name,ssize_t *id,
2986 % ExceptionInfo *exception)
2987 %
2988 % A description of each parameter follows:
2989 %
2990 % o name: the name of the image to retrieve from the registry.
2991 %
2992 % o id: the registry id.
2993 %
2994 % o exception: return any errors or warnings in this structure.
2995 %
2996 */
2997 MagickExport Image *GetImageFromMagickRegistry(const char *name,ssize_t *id,
2998  ExceptionInfo *exception)
2999 {
3000  *id=0L;
3001  return((Image *) GetImageRegistry(ImageRegistryType,name,exception));
3002 }
3003 ␌
3004 /*
3005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3006 % %
3007 % %
3008 % %
3009 % G e t M a g i c k R e g i s t r y %
3010 % %
3011 % %
3012 % %
3013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3014 %
3015 % GetMagickRegistry() gets a blob from the registry as defined by the id. If
3016 % the blob that matches the id is not found, NULL is returned.
3017 %
3018 % The format of the GetMagickRegistry method is:
3019 %
3020 % const void *GetMagickRegistry(const ssize_t id,RegistryType *type,
3021 % size_t *length,ExceptionInfo *exception)
3022 %
3023 % A description of each parameter follows:
3024 %
3025 % o id: the registry id.
3026 %
3027 % o type: the registry type.
3028 %
3029 % o length: the blob length in number of bytes.
3030 %
3031 % o exception: return any errors or warnings in this structure.
3032 %
3033 */
3034 MagickExport void *GetMagickRegistry(const ssize_t id,RegistryType *type,
3035  size_t *length,ExceptionInfo *exception)
3036 {
3037  char
3038  key[MaxTextExtent];
3039 
3040  void
3041  *blob;
3042 
3043  *type=UndefinedRegistryType;
3044  *length=0;
3045  (void) FormatLocaleString(key,MaxTextExtent,"%.20g\n",(double) id);
3046  blob=(void *) GetImageRegistry(ImageRegistryType,key,exception);
3047  if (blob != (void *) NULL)
3048  return(blob);
3049  blob=(void *) GetImageRegistry(ImageInfoRegistryType,key,exception);
3050  if (blob != (void *) NULL)
3051  return(blob);
3052  return((void *) GetImageRegistry(UndefinedRegistryType,key,exception));
3053 }
3054 ␌
3055 /*
3056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3057 % %
3058 % %
3059 % %
3060 + G e t M a g i c k T o k e n %
3061 % %
3062 % %
3063 % %
3064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3065 %
3066 % GetMagickToken() gets a token from the token stream. A token is defined as
3067 % a sequence of characters delimited by whitespace (e.g. clip-path), a
3068 % sequence delimited with quotes (.e.g "Quote me"), or a sequence enclosed in
3069 % parenthesis (e.g. rgb(0,0,0)). GetMagickToken() also recognizes these
3070 % separator characters: ':', '=', ',', and ';'.
3071 %
3072 % The format of the GetMagickToken method is:
3073 %
3074 % void GetMagickToken(const char *start,const char **end,char *token)
3075 %
3076 % A description of each parameter follows:
3077 %
3078 % o start: the start of the token sequence.
3079 %
3080 % o end: point to the end of the token sequence.
3081 %
3082 % o token: copy the token to this buffer.
3083 %
3084 */
3085 MagickExport void GetMagickToken(const char *start,const char **end,char *token)
3086 {
3087  (void) GetNextToken(start,end,~0UL,token);
3088 }
3089 ␌
3090 /*
3091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3092 % %
3093 % %
3094 % %
3095 % G e t I m a g e G e o m e t r y %
3096 % %
3097 % %
3098 % %
3099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3100 %
3101 % GetImageGeometry() returns a region as defined by the geometry string with
3102 % respect to the image and its gravity.
3103 %
3104 % Deprecated, replace with:
3105 %
3106 % if (size_to_fit != MagickFalse)
3107 % ParseRegionGeometry(image,geometry,region_info,&image->exception); else
3108 % ParsePageGeometry(image,geometry,region_info,&image->exception);
3109 %
3110 % The format of the GetImageGeometry method is:
3111 %
3112 % int GetImageGeometry(Image *image,const char *geometry,
3113 % const unsigned int size_to_fit,RectangeInfo *region_info)
3114 %
3115 % A description of each parameter follows:
3116 %
3117 % o flags: Method GetImageGeometry returns a bitmask that indicates
3118 % which of the four values were located in the geometry string.
3119 %
3120 % o geometry: The geometry (e.g. 100x100+10+10).
3121 %
3122 % o size_to_fit: A value other than 0 means to scale the region so it
3123 % fits within the specified width and height.
3124 %
3125 % o region_info: the region as defined by the geometry string with
3126 % respect to the image and its gravity.
3127 %
3128 */
3129 MagickExport int GetImageGeometry(Image *image,const char *geometry,
3130  const unsigned int size_to_fit,RectangleInfo *region_info)
3131 {
3132  if (IsEventLogging() != MagickFalse)
3133  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.4");
3134  if (size_to_fit != MagickFalse)
3135  return((int) ParseRegionGeometry(image,geometry,region_info,&image->exception));
3136  return((int) ParsePageGeometry(image,geometry,region_info,&image->exception));
3137 }
3138 ␌
3139 /*
3140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3141 % %
3142 % %
3143 % %
3144 % G e t I m a g e L i s t %
3145 % %
3146 % %
3147 % %
3148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3149 %
3150 % GetImageList() returns an image at the specified position in the list.
3151 %
3152 % Deprecated, replace with:
3153 %
3154 % CloneImage(GetImageFromList(images,(ssize_t) offset),0,0,MagickTrue,
3155 % exception);
3156 %
3157 % The format of the GetImageList method is:
3158 %
3159 % Image *GetImageList(const Image *images,const ssize_t offset,
3160 % ExceptionInfo *exception)
3161 %
3162 % A description of each parameter follows:
3163 %
3164 % o images: the image list.
3165 %
3166 % o offset: the position within the list.
3167 %
3168 % o exception: return any errors or warnings in this structure.
3169 %
3170 */
3171 MagickExport Image *GetImageList(const Image *images,const ssize_t offset,
3172  ExceptionInfo *exception)
3173 {
3174  Image
3175  *image;
3176 
3177  if (images->debug != MagickFalse)
3178  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
3179  image=CloneImage(GetImageFromList(images,(ssize_t) offset),0,0,MagickTrue,
3180  exception);
3181  return(image);
3182 }
3183 ␌
3184 /*
3185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3186 % %
3187 % %
3188 % %
3189 % G e t I m a g e L i s t I n d e x %
3190 % %
3191 % %
3192 % %
3193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3194 %
3195 % GetImageListIndex() returns the position in the list of the specified
3196 % image.
3197 %
3198 % Deprecated, replace with:
3199 %
3200 % GetImageIndexInList(images);
3201 %
3202 % The format of the GetImageListIndex method is:
3203 %
3204 % ssize_t GetImageListIndex(const Image *images)
3205 %
3206 % A description of each parameter follows:
3207 %
3208 % o images: the image list.
3209 %
3210 */
3211 MagickExport ssize_t GetImageListIndex(const Image *images)
3212 {
3213  if (images->debug != MagickFalse)
3214  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
3215  return(GetImageIndexInList(images));
3216 }
3217 ␌
3218 /*
3219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3220 % %
3221 % %
3222 % %
3223 % G e t I m a g e L i s t S i z e %
3224 % %
3225 % %
3226 % %
3227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3228 %
3229 % GetImageListSize() returns the number of images in the list.
3230 %
3231 % Deprecated, replace with:
3232 %
3233 % GetImageListLength(images);
3234 %
3235 % The format of the GetImageListSize method is:
3236 %
3237 % size_t GetImageListSize(const Image *images)
3238 %
3239 % A description of each parameter follows:
3240 %
3241 % o images: the image list.
3242 %
3243 */
3244 MagickExport size_t GetImageListSize(const Image *images)
3245 {
3246  if (images->debug != MagickFalse)
3247  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
3248  return(GetImageListLength(images));
3249 }
3250 ␌
3251 /*
3252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3253 % %
3254 % %
3255 % %
3256 % G e t I m a g e P i x e l s %
3257 % %
3258 % %
3259 % %
3260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3261 %
3262 % GetImagePixels() obtains a pixel region for read/write access. If the
3263 % region is successfully accessed, a pointer to a PixelPacket array
3264 % representing the region is returned, otherwise NULL is returned.
3265 %
3266 % The returned pointer may point to a temporary working copy of the pixels
3267 % or it may point to the original pixels in memory. Performance is maximized
3268 % if the selected region is part of one row, or one or more full rows, since
3269 % then there is opportunity to access the pixels in-place (without a copy)
3270 % if the image is in RAM, or in a memory-mapped file. The returned pointer
3271 % should *never* be deallocated by the user.
3272 %
3273 % Pixels accessed via the returned pointer represent a simple array of type
3274 % PixelPacket. If the image type is CMYK or if the storage class is
3275 % PseduoClass, call GetAuthenticIndexQueue() after invoking GetImagePixels()
3276 % to obtain the black color component or colormap indexes (of type IndexPacket)
3277 % corresponding to the region. Once the PixelPacket (and/or IndexPacket)
3278 % array has been updated, the changes must be saved back to the underlying
3279 % image using SyncAuthenticPixels() or they may be lost.
3280 %
3281 % Deprecated, replace with:
3282 %
3283 % GetAuthenticPixels(image,x,y,columns,rows,&image->exception);
3284 %
3285 % The format of the GetImagePixels() method is:
3286 %
3287 % PixelPacket *GetImagePixels(Image *image,const ssize_t x,const ssize_t y,
3288 % const size_t columns,const size_t rows)
3289 %
3290 % A description of each parameter follows:
3291 %
3292 % o image: the image.
3293 %
3294 % o x,y,columns,rows: These values define the perimeter of a region of
3295 % pixels.
3296 %
3297 */
3298 MagickExport PixelPacket *GetImagePixels(Image *image,const ssize_t x,const ssize_t y,
3299  const size_t columns,const size_t rows)
3300 {
3301  return(GetAuthenticPixels(image,x,y,columns,rows,&image->exception));
3302 }
3303 ␌
3304 /*
3305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3306 % %
3307 % %
3308 % %
3309 % G e t I n d e x e s %
3310 % %
3311 % %
3312 % %
3313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3314 %
3315 % GetIndexes() returns the black channel or the colormap indexes associated
3316 % with the last call to QueueAuthenticPixels() or GetVirtualPixels(). NULL is
3317 % returned if the black channel or colormap indexes are not available.
3318 %
3319 % Deprecated, replace with:
3320 %
3321 % GetAuthenticIndexQueue(image);
3322 %
3323 % The format of the GetIndexes() method is:
3324 %
3325 % IndexPacket *GetIndexes(const Image *image)
3326 %
3327 % A description of each parameter follows:
3328 %
3329 % o indexes: GetIndexes() returns the indexes associated with the last
3330 % call to QueueAuthenticPixels() or GetAuthenticPixels().
3331 %
3332 % o image: the image.
3333 %
3334 */
3335 MagickExport IndexPacket *GetIndexes(const Image *image)
3336 {
3337  return(GetAuthenticIndexQueue(image));
3338 }
3339 ␌
3340 /*
3341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3342 % %
3343 % %
3344 % %
3345 + G e t M a g i c k G e o m e t r y %
3346 % %
3347 % %
3348 % %
3349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3350 %
3351 % GetMagickGeometry() is similar to GetGeometry() except the returned
3352 % geometry is modified as determined by the meta characters: %, !, <, >,
3353 % and ~.
3354 %
3355 % Deprecated, replace with:
3356 %
3357 % ParseMetaGeometry(geometry,x,y,width,height);
3358 %
3359 % The format of the GetMagickGeometry method is:
3360 %
3361 % unsigned int GetMagickGeometry(const char *geometry,ssize_t *x,ssize_t *y,
3362 % size_t *width,size_t *height)
3363 %
3364 % A description of each parameter follows:
3365 %
3366 % o geometry: Specifies a character string representing the geometry
3367 % specification.
3368 %
3369 % o x,y: A pointer to an integer. The x and y offset as determined by
3370 % the geometry specification is returned here.
3371 %
3372 % o width,height: A pointer to an unsigned integer. The width and height
3373 % as determined by the geometry specification is returned here.
3374 %
3375 */
3376 MagickExport unsigned int GetMagickGeometry(const char *geometry,ssize_t *x,
3377  ssize_t *y,size_t *width,size_t *height)
3378 {
3379  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.3");
3380  return(ParseMetaGeometry(geometry,x,y,width,height));
3381 }
3382 ␌
3383 /*
3384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3385 % %
3386 % %
3387 % %
3388 % G e t N e x t I m a g e %
3389 % %
3390 % %
3391 % %
3392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3393 %
3394 % GetNextImage() returns the next image in a list.
3395 %
3396 % Deprecated, replace with:
3397 %
3398 % GetNextImageInList(images);
3399 %
3400 % The format of the GetNextImage method is:
3401 %
3402 % Image *GetNextImage(const Image *images)
3403 %
3404 % A description of each parameter follows:
3405 %
3406 % o images: the image list.
3407 %
3408 */
3409 MagickExport Image *GetNextImage(const Image *images)
3410 {
3411  if (images->debug != MagickFalse)
3412  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
3413  return(GetNextImageInList(images));
3414 }
3415 ␌
3416 /*
3417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3418 % %
3419 % %
3420 % %
3421 % G e t N e x t I m a g e A t t r i b u t e %
3422 % %
3423 % %
3424 % %
3425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3426 %
3427 % GetNextImageAttribute() gets the next image attribute.
3428 %
3429 % Deprecated, replace with:
3430 %
3431 % const char *property;
3432 % property=GetNextImageProperty(image);
3433 % if (property != (const char *) NULL)
3434 % GetImageAttribute(image,property);
3435 %
3436 % The format of the GetNextImageAttribute method is:
3437 %
3438 % const ImageAttribute *GetNextImageAttribute(const Image *image)
3439 %
3440 % A description of each parameter follows:
3441 %
3442 % o image: the image.
3443 %
3444 */
3445 MagickExport const ImageAttribute *GetNextImageAttribute(const Image *image)
3446 {
3447  const char
3448  *property;
3449 
3450  property=GetNextImageProperty(image);
3451  if (property == (const char *) NULL)
3452  return((const ImageAttribute *) NULL);
3453  return(GetImageAttribute(image,property));
3454 }
3455 ␌
3456 /*
3457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3458 % %
3459 % %
3460 % %
3461 % G e t N u m b e r S c e n e s %
3462 % %
3463 % %
3464 % %
3465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3466 %
3467 % GetNumberScenes() returns the number of images in the list.
3468 %
3469 % Deprecated, replace with:
3470 %
3471 % GetImageListLength(image);
3472 %
3473 % The format of the GetNumberScenes method is:
3474 %
3475 % unsigned int GetNumberScenes(const Image *images)
3476 %
3477 % A description of each parameter follows:
3478 %
3479 % o images: the image list.
3480 %
3481 */
3482 MagickExport unsigned int GetNumberScenes(const Image *image)
3483 {
3484  if (IsEventLogging() != MagickFalse)
3485  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
3486  return((unsigned int) GetImageListLength(image));
3487 }
3488 ␌
3489 /*
3490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3491 % %
3492 % %
3493 % %
3494 % G e t O n e P i x e l %
3495 % %
3496 % %
3497 % %
3498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3499 %
3500 % GetOnePixel() returns a single pixel at the specified (x,y) location.
3501 % The image background color is returned if an error occurs.
3502 %
3503 % Deprecated, replace with:
3504 %
3505 % GetOneAuthenticPixel(image,x,y,&pixel,&image->exception);
3506 %
3507 % The format of the GetOnePixel() method is:
3508 %
3509 % PixelPacket GetOnePixel(const Image image,const ssize_t x,const ssize_t y)
3510 %
3511 % A description of each parameter follows:
3512 %
3513 % o image: the image.
3514 %
3515 % o x,y: These values define the location of the pixel to return.
3516 %
3517 */
3518 MagickExport PixelPacket GetOnePixel(Image *image,const ssize_t x,const ssize_t y)
3519 {
3520  PixelPacket
3521  pixel;
3522 
3523  (void) GetOneAuthenticPixel(image,x,y,&pixel,&image->exception);
3524  return(pixel);
3525 }
3526 ␌
3527 /*
3528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3529 % %
3530 % %
3531 % %
3532 % G e t P i x e l s %
3533 % %
3534 % %
3535 % %
3536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3537 %
3538 % GetPixels() returns the pixels associated with the last call to
3539 % QueueAuthenticPixels() or GetAuthenticPixels().
3540 %
3541 % Deprecated, replace with:
3542 %
3543 % GetAuthenticPixelQueue(image);
3544 %
3545 % The format of the GetPixels() method is:
3546 %
3547 % PixelPacket *GetPixels(const Image image)
3548 %
3549 % A description of each parameter follows:
3550 %
3551 % o pixels: GetPixels() returns the pixels associated with the last call
3552 % to QueueAuthenticPixels() or GetAuthenticPixels().
3553 %
3554 % o image: the image.
3555 %
3556 */
3557 MagickExport PixelPacket *GetPixels(const Image *image)
3558 {
3559  return(GetAuthenticPixelQueue(image));
3560 }
3561 ␌
3562 /*
3563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3564 % %
3565 % %
3566 % %
3567 % G e t P r e v i o u s I m a g e %
3568 % %
3569 % %
3570 % %
3571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3572 %
3573 % GetPreviousImage() returns the previous image in a list.
3574 %
3575 % Deprecated, replace with:
3576 %
3577 % GetPreviousImageInList(images));
3578 %
3579 % The format of the GetPreviousImage method is:
3580 %
3581 % Image *GetPreviousImage(const Image *images)
3582 %
3583 % A description of each parameter follows:
3584 %
3585 % o images: the image list.
3586 %
3587 */
3588 MagickExport Image *GetPreviousImage(const Image *images)
3589 {
3590  if (images->debug != MagickFalse)
3591  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
3592  return(GetPreviousImageInList(images));
3593 }
3594 ␌
3595 /*
3596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3597 % %
3598 % %
3599 % %
3600 % H S L T r a n s f o r m %
3601 % %
3602 % %
3603 % %
3604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3605 %
3606 % HSLTransform() converts a (hue, saturation, lightness) to a (red, green,
3607 % blue) triple.
3608 %
3609 % The format of the HSLTransformImage method is:
3610 %
3611 % void HSLTransform(const double hue,const double saturation,
3612 % const double lightness,Quantum *red,Quantum *green,Quantum *blue)
3613 %
3614 % A description of each parameter follows:
3615 %
3616 % o hue, saturation, lightness: A double value representing a
3617 % component of the HSL color space.
3618 %
3619 % o red, green, blue: A pointer to a pixel component of type Quantum.
3620 %
3621 */
3622 
3623 static inline MagickRealType HueToRGB(MagickRealType m1,MagickRealType m2,
3624  MagickRealType hue)
3625 {
3626  if (hue < 0.0)
3627  hue+=1.0;
3628  if (hue > 1.0)
3629  hue-=1.0;
3630  if ((6.0*hue) < 1.0)
3631  return(m1+6.0*(m2-m1)*hue);
3632  if ((2.0*hue) < 1.0)
3633  return(m2);
3634  if ((3.0*hue) < 2.0)
3635  return(m1+6.0*(m2-m1)*(2.0/3.0-hue));
3636  return(m1);
3637 }
3638 
3639 MagickExport void HSLTransform(const double hue,const double saturation,
3640  const double lightness,Quantum *red,Quantum *green,Quantum *blue)
3641 {
3642  MagickRealType
3643  b,
3644  g,
3645  r,
3646  m1,
3647  m2;
3648 
3649  /*
3650  Convert HSL to RGB colorspace.
3651  */
3652  assert(red != (Quantum *) NULL);
3653  assert(green != (Quantum *) NULL);
3654  assert(blue != (Quantum *) NULL);
3655  if (lightness <= 0.5)
3656  m2=lightness*(saturation+1.0);
3657  else
3658  m2=lightness+saturation-lightness*saturation;
3659  m1=2.0*lightness-m2;
3660  r=HueToRGB(m1,m2,hue+1.0/3.0);
3661  g=HueToRGB(m1,m2,hue);
3662  b=HueToRGB(m1,m2,hue-1.0/3.0);
3663  *red=ClampToQuantum((MagickRealType) QuantumRange*r);
3664  *green=ClampToQuantum((MagickRealType) QuantumRange*g);
3665  *blue=ClampToQuantum((MagickRealType) QuantumRange*b);
3666 }
3667 ␌
3668 /*
3669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3670 % %
3671 % %
3672 % %
3673 % I d e n t i t y A f f i n e %
3674 % %
3675 % %
3676 % %
3677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3678 %
3679 % IdentityAffine() initializes the affine transform to the identity matrix.
3680 %
3681 % The format of the IdentityAffine method is:
3682 %
3683 % IdentityAffine(AffineMatrix *affine)
3684 %
3685 % A description of each parameter follows:
3686 %
3687 % o affine: A pointer the affine transform of type AffineMatrix.
3688 %
3689 */
3690 MagickExport void IdentityAffine(AffineMatrix *affine)
3691 {
3692  assert(affine != (AffineMatrix *) NULL);
3693  if (IsEventLogging() != MagickFalse)
3694  {
3695  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3696  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
3697  "last use: v5.5.7");
3698  }
3699  (void) memset(affine,0,sizeof(AffineMatrix));
3700  affine->sx=1.0;
3701  affine->sy=1.0;
3702 }
3703 ␌
3704 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
3705 /*
3706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3707 % %
3708 % %
3709 % %
3710 % I m a g e T o H B i t m a p %
3711 % %
3712 % %
3713 % %
3714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3715 %
3716 % ImageToHBITMAP() creates a Windows HBITMAP from an image.
3717 %
3718 % The format of the ImageToHBITMAP method is:
3719 %
3720 % HBITMAP ImageToHBITMAP(Image *image,Exceptioninfo *exception)
3721 %
3722 % A description of each parameter follows:
3723 %
3724 % o image: the image to convert.
3725 %
3726 */
3727 MagickExport void *ImageToHBITMAP(Image *image,ExceptionInfo *exception)
3728 {
3729  BITMAP
3730  bitmap;
3731 
3732  HANDLE
3733  bitmap_bitsH;
3734 
3735  HBITMAP
3736  bitmapH;
3737 
3738  ssize_t
3739  x;
3740 
3741  const PixelPacket
3742  *p;
3743 
3744  RGBQUAD
3745  *q;
3746 
3747  RGBQUAD
3748  *bitmap_bits;
3749 
3750  size_t
3751  length;
3752 
3753  ssize_t
3754  y;
3755 
3756  (void) memset(&bitmap,0,sizeof(bitmap));
3757  bitmap.bmType=0;
3758  bitmap.bmWidth=(LONG) image->columns;
3759  bitmap.bmHeight=(LONG) image->rows;
3760  bitmap.bmWidthBytes=4*bitmap.bmWidth;
3761  bitmap.bmPlanes=1;
3762  bitmap.bmBitsPixel=32;
3763  bitmap.bmBits=NULL;
3764  length=bitmap.bmWidthBytes*bitmap.bmHeight;
3765  bitmap_bitsH=(HANDLE) GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,length);
3766  if (bitmap_bitsH == NULL)
3767  {
3768  char
3769  *message;
3770 
3771  message=GetExceptionMessage(errno);
3772  (void) ThrowMagickException(exception,GetMagickModule(),
3773  ResourceLimitError,"MemoryAllocationFailed","`%s'",message);
3774  message=DestroyString(message);
3775  return(NULL);
3776  }
3777  bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH);
3778  q=bitmap_bits;
3779  if (bitmap.bmBits == NULL)
3780  bitmap.bmBits=bitmap_bits;
3781  (void) SetImageColorspace(image,sRGBColorspace);
3782  for (y=0; y < (ssize_t) image->rows; y++)
3783  {
3784  p=GetVirtualPixels(image,0,y,image->columns,1,exception);
3785  if (p == (const PixelPacket *) NULL)
3786  break;
3787  for (x=0; x < (ssize_t) image->columns; x++)
3788  {
3789  q->rgbRed=ScaleQuantumToChar(GetPixelRed(p));
3790  q->rgbGreen=ScaleQuantumToChar(GetPixelGreen(p));
3791  q->rgbBlue=ScaleQuantumToChar(GetPixelBlue(p));
3792  q->rgbReserved=0;
3793  p++;
3794  q++;
3795  }
3796  }
3797  bitmap.bmBits=bitmap_bits;
3798  bitmapH=CreateBitmapIndirect(&bitmap);
3799  if (bitmapH == NULL)
3800  {
3801  char
3802  *message;
3803 
3804  message=GetExceptionMessage(errno);
3805  (void) ThrowMagickException(exception,GetMagickModule(),
3806  ResourceLimitError,"MemoryAllocationFailed","`%s'",message);
3807  message=DestroyString(message);
3808  }
3809  GlobalUnlock((HGLOBAL) bitmap_bitsH);
3810  GlobalFree((HGLOBAL) bitmap_bitsH);
3811  return((void *) bitmapH);
3812 }
3813 #endif
3814 ␌
3815 /*
3816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3817 % %
3818 % %
3819 % %
3820 % I n i t i a l i z e M a g i c k %
3821 % %
3822 % %
3823 % %
3824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3825 %
3826 % InitializeMagick() initializes the ImageMagick environment.
3827 %
3828 % Deprecated, replace with:
3829 %
3830 % MagickCoreGenesis(path,MagickFalse);
3831 %
3832 % The format of the InitializeMagick function is:
3833 %
3834 % InitializeMagick(const char *path)
3835 %
3836 % A description of each parameter follows:
3837 %
3838 % o path: the execution path of the current ImageMagick client.
3839 %
3840 */
3841 MagickExport void InitializeMagick(const char *path)
3842 {
3843  MagickCoreGenesis(path,MagickFalse);
3844 }
3845 ␌
3846 /*
3847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3848 % %
3849 % %
3850 % %
3851 % I n t e r p o l a t e P i x e l C o l o r %
3852 % %
3853 % %
3854 % %
3855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3856 %
3857 % InterpolatePixelColor() applies bi-linear or tri-linear interpolation
3858 % between a pixel and it's neighbors.
3859 %
3860 % The format of the InterpolatePixelColor method is:
3861 %
3862 % MagickPixelPacket InterpolatePixelColor(const Image *image,
3863 % CacheView *view_info,InterpolatePixelMethod method,const double x,
3864 % const double y,ExceptionInfo *exception)
3865 %
3866 % A description of each parameter follows:
3867 %
3868 % o image: the image.
3869 %
3870 % o image_view: the image cache view.
3871 %
3872 % o type: the type of pixel color interpolation.
3873 %
3874 % o x,y: A double representing the current (x,y) position of the pixel.
3875 %
3876 % o exception: return any errors or warnings in this structure.
3877 %
3878 */
3879 
3880 static void BicubicInterpolate(const MagickPixelPacket *pixels,const double dx,
3881  MagickPixelPacket *pixel)
3882 {
3883  MagickRealType
3884  dx2,
3885  p,
3886  q,
3887  r,
3888  s;
3889 
3890  dx2=dx*dx;
3891  p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
3892  q=(pixels[0].red-pixels[1].red)-p;
3893  r=pixels[2].red-pixels[0].red;
3894  s=pixels[1].red;
3895  pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
3896  p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
3897  q=(pixels[0].green-pixels[1].green)-p;
3898  r=pixels[2].green-pixels[0].green;
3899  s=pixels[1].green;
3900  pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
3901  p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
3902  q=(pixels[0].blue-pixels[1].blue)-p;
3903  r=pixels[2].blue-pixels[0].blue;
3904  s=pixels[1].blue;
3905  pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
3906  p=(pixels[3].opacity-pixels[2].opacity)-(pixels[0].opacity-pixels[1].opacity);
3907  q=(pixels[0].opacity-pixels[1].opacity)-p;
3908  r=pixels[2].opacity-pixels[0].opacity;
3909  s=pixels[1].opacity;
3910  pixel->opacity=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
3911  if (pixel->colorspace == CMYKColorspace)
3912  {
3913  p=(pixels[3].index-pixels[2].index)-(pixels[0].index-pixels[1].index);
3914  q=(pixels[0].index-pixels[1].index)-p;
3915  r=pixels[2].index-pixels[0].index;
3916  s=pixels[1].index;
3917  pixel->index=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
3918  }
3919 }
3920 
3921 static inline MagickRealType CubicWeightingFunction(const MagickRealType x)
3922 {
3923  MagickRealType
3924  alpha,
3925  gamma;
3926 
3927  alpha=MagickMax(x+2.0,0.0);
3928  gamma=1.0*alpha*alpha*alpha;
3929  alpha=MagickMax(x+1.0,0.0);
3930  gamma-=4.0*alpha*alpha*alpha;
3931  alpha=MagickMax(x+0.0,0.0);
3932  gamma+=6.0*alpha*alpha*alpha;
3933  alpha=MagickMax(x-1.0,0.0);
3934  gamma-=4.0*alpha*alpha*alpha;
3935  return(gamma/6.0);
3936 }
3937 
3938 static inline double MeshInterpolate(const PointInfo *delta,const double p,
3939  const double x,const double y)
3940 {
3941  return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
3942 }
3943 
3944 static inline ssize_t NearestNeighbor(MagickRealType x)
3945 {
3946  if (x >= 0.0)
3947  return((ssize_t) (x+0.5));
3948  return((ssize_t) (x-0.5));
3949 }
3950 
3951 MagickExport MagickPixelPacket InterpolatePixelColor(const Image *image,
3952  CacheView *image_view,const InterpolatePixelMethod method,const double x,
3953  const double y,ExceptionInfo *exception)
3954 {
3956  pixel;
3957 
3958  const IndexPacket
3959  *indexes;
3960 
3961  const PixelPacket
3962  *p;
3963 
3964  ssize_t
3965  i;
3966 
3967  assert(image != (Image *) NULL);
3968  assert(image->signature == MagickCoreSignature);
3969  assert(image_view != (CacheView *) NULL);
3970  GetMagickPixelPacket(image,&pixel);
3971  switch (method)
3972  {
3973  case AverageInterpolatePixel:
3974  {
3975  double
3976  gamma;
3977 
3979  pixels[16];
3980 
3981  MagickRealType
3982  alpha[16];
3983 
3984  p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x)-1,(ssize_t)
3985  floor(y)-1,4,4,exception);
3986  if (p == (const PixelPacket *) NULL)
3987  break;
3988  indexes=GetCacheViewVirtualIndexQueue(image_view);
3989  for (i=0; i < 16L; i++)
3990  {
3991  GetMagickPixelPacket(image,pixels+i);
3992  SetMagickPixelPacket(image,p,indexes+i,pixels+i);
3993  alpha[i]=1.0;
3994  if (image->matte != MagickFalse)
3995  {
3996  alpha[i]=QuantumScale*((MagickRealType) GetPixelAlpha(p));
3997  pixels[i].red*=alpha[i];
3998  pixels[i].green*=alpha[i];
3999  pixels[i].blue*=alpha[i];
4000  if (image->colorspace == CMYKColorspace)
4001  pixels[i].index*=alpha[i];
4002  }
4003  gamma=alpha[i];
4004  gamma=PerceptibleReciprocal(gamma);
4005  pixel.red+=gamma*0.0625*pixels[i].red;
4006  pixel.green+=gamma*0.0625*pixels[i].green;
4007  pixel.blue+=gamma*0.0625*pixels[i].blue;
4008  pixel.opacity+=0.0625*pixels[i].opacity;
4009  if (image->colorspace == CMYKColorspace)
4010  pixel.index+=gamma*0.0625*pixels[i].index;
4011  p++;
4012  }
4013  break;
4014  }
4015  case BicubicInterpolatePixel:
4016  {
4018  pixels[16],
4019  u[4];
4020 
4021  MagickRealType
4022  alpha[16];
4023 
4024  PointInfo
4025  delta;
4026 
4027  p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x)-1,(ssize_t)
4028  floor(y)-1,4,4,exception);
4029  if (p == (const PixelPacket *) NULL)
4030  break;
4031  indexes=GetCacheViewVirtualIndexQueue(image_view);
4032  for (i=0; i < 4L; i++)
4033  GetMagickPixelPacket(image,u+i);
4034  for (i=0; i < 16L; i++)
4035  {
4036  GetMagickPixelPacket(image,pixels+i);
4037  SetMagickPixelPacket(image,p,indexes+i,pixels+i);
4038  alpha[i]=1.0;
4039  if (image->matte != MagickFalse)
4040  {
4041  alpha[i]=QuantumScale*((MagickRealType) GetPixelAlpha(p));
4042  pixels[i].red*=alpha[i];
4043  pixels[i].green*=alpha[i];
4044  pixels[i].blue*=alpha[i];
4045  if (image->colorspace == CMYKColorspace)
4046  pixels[i].index*=alpha[i];
4047  }
4048  p++;
4049  }
4050  delta.x=x-floor(x);
4051  for (i=0; i < 4L; i++)
4052  {
4053  GetMagickPixelPacket(image,pixels+4*i);
4054  BicubicInterpolate(pixels+4*i,delta.x,u+i);
4055  }
4056  delta.y=y-floor(y);
4057  BicubicInterpolate(u,delta.y,&pixel);
4058  break;
4059  }
4060  case BilinearInterpolatePixel:
4061  default:
4062  {
4063  double
4064  gamma;
4065 
4067  pixels[16];
4068 
4069  MagickRealType
4070  alpha[16];
4071 
4072  PointInfo
4073  delta;
4074 
4075  p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x),(ssize_t)
4076  floor(y),2,2,exception);
4077  if (p == (const PixelPacket *) NULL)
4078  break;
4079  indexes=GetCacheViewVirtualIndexQueue(image_view);
4080  for (i=0; i < 4L; i++)
4081  {
4082  GetMagickPixelPacket(image,pixels+i);
4083  SetMagickPixelPacket(image,p,indexes+i,pixels+i);
4084  alpha[i]=1.0;
4085  if (image->matte != MagickFalse)
4086  {
4087  alpha[i]=QuantumScale*((MagickRealType) GetPixelAlpha(p));
4088  pixels[i].red*=alpha[i];
4089  pixels[i].green*=alpha[i];
4090  pixels[i].blue*=alpha[i];
4091  if (image->colorspace == CMYKColorspace)
4092  pixels[i].index*=alpha[i];
4093  }
4094  p++;
4095  }
4096  delta.x=x-floor(x);
4097  delta.y=y-floor(y);
4098  gamma=(((1.0-delta.y)*((1.0-delta.x)*alpha[0]+delta.x*alpha[1])+delta.y*
4099  ((1.0-delta.x)*alpha[2]+delta.x*alpha[3])));
4100  gamma=PerceptibleReciprocal(gamma);
4101  pixel.red=gamma*((1.0-delta.y)*((1.0-delta.x)*pixels[0].red+delta.x*
4102  pixels[1].red)+delta.y*((1.0-delta.x)*pixels[2].red+delta.x*
4103  pixels[3].red));
4104  pixel.green=gamma*((1.0-delta.y)*((1.0-delta.x)*pixels[0].green+delta.x*
4105  pixels[1].green)+delta.y*((1.0-delta.x)*pixels[2].green+
4106  delta.x*pixels[3].green));
4107  pixel.blue=gamma*((1.0-delta.y)*((1.0-delta.x)*pixels[0].blue+delta.x*
4108  pixels[1].blue)+delta.y*((1.0-delta.x)*pixels[2].blue+delta.x*
4109  pixels[3].blue));
4110  pixel.opacity=((1.0-delta.y)*((1.0-delta.x)*pixels[0].opacity+delta.x*
4111  pixels[1].opacity)+delta.y*((1.0-delta.x)*pixels[2].opacity+delta.x*
4112  pixels[3].opacity));
4113  if (image->colorspace == CMYKColorspace)
4114  pixel.index=gamma*((1.0-delta.y)*((1.0-delta.x)*pixels[0].index+delta.x*
4115  pixels[1].index)+delta.y*((1.0-delta.x)*pixels[2].index+delta.x*
4116  pixels[3].index));
4117  break;
4118  }
4119  case FilterInterpolatePixel:
4120  {
4121  Image
4122  *excerpt_image,
4123  *filter_image;
4124 
4126  pixels[1];
4127 
4129  geometry;
4130 
4131  geometry.width=4L;
4132  geometry.height=4L;
4133  geometry.x=(ssize_t) floor(x)-1L;
4134  geometry.y=(ssize_t) floor(y)-1L;
4135  excerpt_image=ExcerptImage(image,&geometry,exception);
4136  if (excerpt_image == (Image *) NULL)
4137  break;
4138  filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
4139  exception);
4140  excerpt_image=DestroyImage(excerpt_image);
4141  if (filter_image == (Image *) NULL)
4142  break;
4143  p=GetVirtualPixels(filter_image,0,0,1,1,exception);
4144  if (p == (const PixelPacket *) NULL)
4145  {
4146  filter_image=DestroyImage(filter_image);
4147  break;
4148  }
4149  indexes=GetVirtualIndexQueue(filter_image);
4150  GetMagickPixelPacket(image,pixels);
4151  SetMagickPixelPacket(image,p,indexes,&pixel);
4152  filter_image=DestroyImage(filter_image);
4153  break;
4154  }
4155  case IntegerInterpolatePixel:
4156  {
4158  pixels[1];
4159 
4160  p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x),(ssize_t)
4161  floor(y),1,1,exception);
4162  if (p == (const PixelPacket *) NULL)
4163  break;
4164  indexes=GetCacheViewVirtualIndexQueue(image_view);
4165  GetMagickPixelPacket(image,pixels);
4166  SetMagickPixelPacket(image,p,indexes,&pixel);
4167  break;
4168  }
4169  case MeshInterpolatePixel:
4170  {
4171  double
4172  gamma;
4173 
4175  pixels[4];
4176 
4177  MagickRealType
4178  alpha[4];
4179 
4180  PointInfo
4181  delta,
4182  luminance;
4183 
4184  p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x),(ssize_t)
4185  floor(y),2,2,exception);
4186  if (p == (const PixelPacket *) NULL)
4187  break;
4188  indexes=GetCacheViewVirtualIndexQueue(image_view);
4189  for (i=0; i < 4L; i++)
4190  {
4191  GetMagickPixelPacket(image,pixels+i);
4192  SetMagickPixelPacket(image,p,indexes+i,pixels+i);
4193  alpha[i]=1.0;
4194  if (image->matte != MagickFalse)
4195  {
4196  alpha[i]=QuantumScale*((MagickRealType) GetPixelAlpha(p));
4197  pixels[i].red*=alpha[i];
4198  pixels[i].green*=alpha[i];
4199  pixels[i].blue*=alpha[i];
4200  if (image->colorspace == CMYKColorspace)
4201  pixels[i].index*=alpha[i];
4202  }
4203  p++;
4204  }
4205  delta.x=x-floor(x);
4206  delta.y=y-floor(y);
4207  luminance.x=MagickPixelLuma(pixels+0)-MagickPixelLuma(pixels+3);
4208  luminance.y=MagickPixelLuma(pixels+1)-MagickPixelLuma(pixels+2);
4209  if (fabs(luminance.x) < fabs(luminance.y))
4210  {
4211  /*
4212  Diagonal 0-3 NW-SE.
4213  */
4214  if (delta.x <= delta.y)
4215  {
4216  /*
4217  Bottom-left triangle (pixel:2, diagonal: 0-3).
4218  */
4219  delta.y=1.0-delta.y;
4220  gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4221  gamma=PerceptibleReciprocal(gamma);
4222  pixel.red=gamma*MeshInterpolate(&delta,pixels[2].red,
4223  pixels[3].red,pixels[0].red);
4224  pixel.green=gamma*MeshInterpolate(&delta,pixels[2].green,
4225  pixels[3].green,pixels[0].green);
4226  pixel.blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
4227  pixels[3].blue,pixels[0].blue);
4228  pixel.opacity=gamma*MeshInterpolate(&delta,pixels[2].opacity,
4229  pixels[3].opacity,pixels[0].opacity);
4230  if (image->colorspace == CMYKColorspace)
4231  pixel.index=gamma*MeshInterpolate(&delta,pixels[2].index,
4232  pixels[3].index,pixels[0].index);
4233  }
4234  else
4235  {
4236  /*
4237  Top-right triangle (pixel:1, diagonal: 0-3).
4238  */
4239  delta.x=1.0-delta.x;
4240  gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4241  gamma=PerceptibleReciprocal(gamma);
4242  pixel.red=gamma*MeshInterpolate(&delta,pixels[1].red,
4243  pixels[0].red,pixels[3].red);
4244  pixel.green=gamma*MeshInterpolate(&delta,pixels[1].green,
4245  pixels[0].green,pixels[3].green);
4246  pixel.blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
4247  pixels[0].blue,pixels[3].blue);
4248  pixel.opacity=gamma*MeshInterpolate(&delta,pixels[1].opacity,
4249  pixels[0].opacity,pixels[3].opacity);
4250  if (image->colorspace == CMYKColorspace)
4251  pixel.index=gamma*MeshInterpolate(&delta,pixels[1].index,
4252  pixels[0].index,pixels[3].index);
4253  }
4254  }
4255  else
4256  {
4257  /*
4258  Diagonal 1-2 NE-SW.
4259  */
4260  if (delta.x <= (1.0-delta.y))
4261  {
4262  /*
4263  Top-left triangle (pixel 0, diagonal: 1-2).
4264  */
4265  gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4266  gamma=PerceptibleReciprocal(gamma);
4267  pixel.red=gamma*MeshInterpolate(&delta,pixels[0].red,
4268  pixels[1].red,pixels[2].red);
4269  pixel.green=gamma*MeshInterpolate(&delta,pixels[0].green,
4270  pixels[1].green,pixels[2].green);
4271  pixel.blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
4272  pixels[1].blue,pixels[2].blue);
4273  pixel.opacity=gamma*MeshInterpolate(&delta,pixels[0].opacity,
4274  pixels[1].opacity,pixels[2].opacity);
4275  if (image->colorspace == CMYKColorspace)
4276  pixel.index=gamma*MeshInterpolate(&delta,pixels[0].index,
4277  pixels[1].index,pixels[2].index);
4278  }
4279  else
4280  {
4281  /*
4282  Bottom-right triangle (pixel: 3, diagonal: 1-2).
4283  */
4284  delta.x=1.0-delta.x;
4285  delta.y=1.0-delta.y;
4286  gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4287  gamma=PerceptibleReciprocal(gamma);
4288  pixel.red=gamma*MeshInterpolate(&delta,pixels[3].red,
4289  pixels[2].red,pixels[1].red);
4290  pixel.green=gamma*MeshInterpolate(&delta,pixels[3].green,
4291  pixels[2].green,pixels[1].green);
4292  pixel.blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
4293  pixels[2].blue,pixels[1].blue);
4294  pixel.opacity=gamma*MeshInterpolate(&delta,pixels[3].opacity,
4295  pixels[2].opacity,pixels[1].opacity);
4296  if (image->colorspace == CMYKColorspace)
4297  pixel.index=gamma*MeshInterpolate(&delta,pixels[3].index,
4298  pixels[2].index,pixels[1].index);
4299  }
4300  }
4301  break;
4302  }
4303  case NearestNeighborInterpolatePixel:
4304  {
4306  pixels[1];
4307 
4308  p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
4309  NearestNeighbor(y),1,1,exception);
4310  if (p == (const PixelPacket *) NULL)
4311  break;
4312  indexes=GetCacheViewVirtualIndexQueue(image_view);
4313  GetMagickPixelPacket(image,pixels);
4314  SetMagickPixelPacket(image,p,indexes,&pixel);
4315  break;
4316  }
4317  case SplineInterpolatePixel:
4318  {
4319  double
4320  gamma;
4321 
4323  pixels[16];
4324 
4325  MagickRealType
4326  alpha[16],
4327  dx,
4328  dy;
4329 
4330  PointInfo
4331  delta;
4332 
4333  ssize_t
4334  j,
4335  n;
4336 
4337  p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x)-1,(ssize_t)
4338  floor(y)-1,4,4,exception);
4339  if (p == (const PixelPacket *) NULL)
4340  break;
4341  indexes=GetCacheViewVirtualIndexQueue(image_view);
4342  n=0;
4343  delta.x=x-floor(x);
4344  delta.y=y-floor(y);
4345  for (i=(-1); i < 3L; i++)
4346  {
4347  dy=CubicWeightingFunction((MagickRealType) i-delta.y);
4348  for (j=(-1); j < 3L; j++)
4349  {
4350  GetMagickPixelPacket(image,pixels+n);
4351  SetMagickPixelPacket(image,p,indexes+n,pixels+n);
4352  alpha[n]=1.0;
4353  if (image->matte != MagickFalse)
4354  {
4355  alpha[n]=QuantumScale*((MagickRealType)
4356  GetPixelAlpha(p));
4357  pixels[n].red*=alpha[n];
4358  pixels[n].green*=alpha[n];
4359  pixels[n].blue*=alpha[n];
4360  if (image->colorspace == CMYKColorspace)
4361  pixels[n].index*=alpha[n];
4362  }
4363  dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
4364  gamma=alpha[n];
4365  gamma=PerceptibleReciprocal(gamma);
4366  pixel.red+=gamma*dx*dy*pixels[n].red;
4367  pixel.green+=gamma*dx*dy*pixels[n].green;
4368  pixel.blue+=gamma*dx*dy*pixels[n].blue;
4369  if (image->matte != MagickFalse)
4370  pixel.opacity+=dx*dy*pixels[n].opacity;
4371  if (image->colorspace == CMYKColorspace)
4372  pixel.index+=gamma*dx*dy*pixels[n].index;
4373  n++;
4374  p++;
4375  }
4376  }
4377  break;
4378  }
4379  }
4380  return(pixel);
4381 }
4382 ␌
4383 /*
4384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4385 % %
4386 % %
4387 % %
4388 % I n t e r p r e t I m a g e A t t r i b u t e s %
4389 % %
4390 % %
4391 % %
4392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4393 %
4394 % InterpretImageAttributes() replaces any embedded formatting characters with
4395 % the appropriate image attribute and returns the translated text.
4396 %
4397 % Deprecated, replace with:
4398 %
4399 % InterpretImageProperties(image_info,image,embed_text);
4400 %
4401 % The format of the InterpretImageAttributes method is:
4402 %
4403 % char *InterpretImageAttributes(const ImageInfo *image_info,Image *image,
4404 % const char *embed_text)
4405 %
4406 % A description of each parameter follows:
4407 %
4408 % o image_info: the image info.
4409 %
4410 % o image: the image.
4411 %
4412 % o embed_text: the address of a character string containing the embedded
4413 % formatting characters.
4414 %
4415 */
4416 MagickExport char *InterpretImageAttributes(const ImageInfo *image_info,
4417  Image *image,const char *embed_text)
4418 {
4419  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.3.1");
4420  return(InterpretImageProperties(image_info,image,embed_text));
4421 }
4422 ␌
4423 /*
4424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4425 % %
4426 % %
4427 % %
4428 % I n v e r s e s R G B C o m p a n d o r %
4429 % %
4430 % %
4431 % %
4432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4433 %
4434 % InversesRGBCompandor() removes the gamma function from a sRGB pixel.
4435 %
4436 % The format of the InversesRGBCompandor method is:
4437 %
4438 % MagickRealType InversesRGBCompandor(const MagickRealType pixel)
4439 %
4440 % A description of each parameter follows:
4441 %
4442 % o pixel: the pixel.
4443 %
4444 */
4445 MagickExport MagickRealType InversesRGBCompandor(const MagickRealType pixel)
4446 {
4447  if (pixel <= (0.0404482362771076*(double) QuantumRange))
4448  return(pixel/12.92);
4449  return((MagickRealType) QuantumRange*pow((QuantumScale*pixel+0.055)/1.055,
4450  2.4));
4451 }
4452 ␌
4453 /*
4454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4455 % %
4456 % %
4457 % %
4458 % I s M a g i c k I n s t a n t i a t e d %
4459 % %
4460 % %
4461 % %
4462 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4463 %
4464 % IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
4465 % is currently instantiated: MagickCoreGenesis() has been called but
4466 % MagickDestroy() has not.
4467 %
4468 % The format of the IsMagickInstantiated method is:
4469 %
4470 % MagickBooleanType IsMagickInstantiated(void)
4471 %
4472 */
4473 MagickExport MagickBooleanType IsMagickInstantiated(void)
4474 {
4475  return(IsMagickCoreInstantiated());
4476 }
4477 ␌
4478 /*
4479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4480 % %
4481 % %
4482 % %
4483 + I s S u b i m a g e %
4484 % %
4485 % %
4486 % %
4487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4488 %
4489 % IsSubimage() returns MagickTrue if the geometry is a valid subimage
4490 % specification (e.g. [1], [1-9], [1,7,4]).
4491 %
4492 % The format of the IsSubimage method is:
4493 %
4494 % unsigned int IsSubimage(const char *geometry,const unsigned int pedantic)
4495 %
4496 % A description of each parameter follows:
4497 %
4498 % o geometry: This string is the geometry specification.
4499 %
4500 % o pedantic: A value other than 0 invokes a more restrictive set of
4501 % conditions for a valid specification (e.g. [1], [1-4], [4-1]).
4502 %
4503 */
4504 MagickExport unsigned int IsSubimage(const char *geometry,
4505  const unsigned int pedantic)
4506 {
4507  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
4508  if (geometry == (const char *) NULL)
4509  return(MagickFalse);
4510  if ((strchr(geometry,'x') != (char *) NULL) ||
4511  (strchr(geometry,'X') != (char *) NULL))
4512  return(MagickFalse);
4513  if ((pedantic != MagickFalse) && (strchr(geometry,',') != (char *) NULL))
4514  return(MagickFalse);
4515  return(MagickTrue);
4516 }
4517 ␌
4518 /*
4519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4520 % %
4521 % %
4522 % %
4523 % L e v e l I m a g e C o l o r s %
4524 % %
4525 % %
4526 % %
4527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4528 %
4529 % LevelImageColor() will map the given color to "black" and "white"
4530 % values, limearly spreading out the colors, and level values on a channel by
4531 % channel bases, as per LevelImage(). The given colors allows you to specify
4532 % different level ranges for each of the color channels separately.
4533 %
4534 % If the boolean 'invert' is set true the image values will modifyed in the
4535 % reverse direction. That is any existing "black" and "white" colors in the
4536 % image will become the color values given, with all other values compressed
4537 % appropriatally. This effectivally maps a greyscale gradient into the given
4538 % color gradient.
4539 %
4540 % Deprecated, replace with:
4541 %
4542 % LevelColorsImageChannel(image,channel,black_color,white_color,invert);
4543 %
4544 % The format of the LevelImageColors method is:
4545 %
4546 % MagickBooleanType LevelImageColors(Image *image,const ChannelType channel,
4547 % const MagickPixelPacket *black_color,const MagickPixelPacket *white_color,
4548 % const MagickBooleanType invert)
4549 %
4550 % A description of each parameter follows:
4551 %
4552 % o image: the image.
4553 %
4554 % o channel: the channel.
4555 %
4556 % o black_color: The color to map black to/from
4557 %
4558 % o white_point: The color to map white to/from
4559 %
4560 % o invert: if true map the colors (levelize), rather than from (level)
4561 %
4562 */
4563 MagickBooleanType LevelImageColors(Image *image,const ChannelType channel,
4564  const MagickPixelPacket *black_color,const MagickPixelPacket *white_color,
4565  const MagickBooleanType invert)
4566 {
4567  return(LevelColorsImageChannel(image,channel,black_color,white_color,invert));
4568 }
4569 ␌
4570 /*
4571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4572 % %
4573 % %
4574 % %
4575 % L i b e r a t e M e m o r y %
4576 % %
4577 % %
4578 % %
4579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4580 %
4581 % LiberateMemory() frees memory that has already been allocated, and NULL's
4582 % the pointer to it.
4583 %
4584 % The format of the LiberateMemory method is:
4585 %
4586 % void LiberateMemory(void **memory)
4587 %
4588 % A description of each parameter follows:
4589 %
4590 % o memory: A pointer to a block of memory to free for reuse.
4591 %
4592 */
4593 MagickExport void LiberateMemory(void **memory)
4594 {
4595  assert(memory != (void **) NULL);
4596  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
4597  if (*memory == (void *) NULL)
4598  return;
4599  free(*memory);
4600  *memory=(void *) NULL;
4601 }
4602 ␌
4603 /*
4604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4605 % %
4606 % %
4607 % %
4608 % L i b e r a t e S e m a p h o r e I n f o %
4609 % %
4610 % %
4611 % %
4612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4613 %
4614 % LiberateSemaphoreInfo() relinquishes a semaphore.
4615 %
4616 % Deprecated, replace with:
4617 %
4618 % UnlockSemaphoreInfo(*semaphore_info);
4619 %
4620 % The format of the LiberateSemaphoreInfo method is:
4621 %
4622 % LiberateSemaphoreInfo(void **semaphore_info)
4623 %
4624 % A description of each parameter follows:
4625 %
4626 % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
4627 %
4628 */
4629 MagickExport void LiberateSemaphoreInfo(SemaphoreInfo **semaphore_info)
4630 {
4631  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
4632  UnlockSemaphoreInfo(*semaphore_info);
4633 }
4634 ␌
4635 /*
4636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4637 % %
4638 % %
4639 % %
4640 % M a g i c k I n c a r n a t e %
4641 % %
4642 % %
4643 % %
4644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4645 %
4646 % MagickIncarnate() initializes the ImageMagick environment.
4647 %
4648 % Deprecated, replace with:
4649 %
4650 % MagickCoreGenesis(path,MagickFalse);
4651 %
4652 % The format of the MagickIncarnate function is:
4653 %
4654 % MagickIncarnate(const char *path)
4655 %
4656 % A description of each parameter follows:
4657 %
4658 % o path: the execution path of the current ImageMagick client.
4659 %
4660 */
4661 
4662 MagickExport void MagickIncarnate(const char *path)
4663 {
4664  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.1");
4665  MagickCoreGenesis(path,MagickFalse);
4666 }
4667 ␌
4668 /*
4669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4670 % %
4671 % %
4672 % %
4673 % M a g i c k M o n i t o r %
4674 % %
4675 % %
4676 % %
4677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4678 %
4679 % MagickMonitor() calls the monitor handler method with a text string that
4680 % describes the task and a measure of completion. The method returns
4681 % MagickTrue on success otherwise MagickFalse if an error is encountered, e.g.
4682 % if there was a user interrupt.
4683 %
4684 % The format of the MagickMonitor method is:
4685 %
4686 % MagickBooleanType MagickMonitor(const char *text,
4687 % const MagickOffsetType offset,const MagickSizeType span,
4688 % void *client_data)
4689 %
4690 % A description of each parameter follows:
4691 %
4692 % o offset: the position relative to the span parameter which represents
4693 % how much progress has been made toward completing a task.
4694 %
4695 % o span: the span relative to completing a task.
4696 %
4697 % o client_data: the client data.
4698 %
4699 */
4700 MagickExport MagickBooleanType MagickMonitor(const char *text,
4701  const MagickOffsetType offset,const MagickSizeType span,
4702  void *magick_unused(client_data))
4703 {
4705  *exception;
4706 
4707  MagickBooleanType
4708  status;
4709 
4710  magick_unreferenced(client_data);
4711 
4712  assert(text != (const char *) NULL);
4713  if (IsEventLogging() != MagickFalse)
4714  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",text);
4715  ProcessPendingEvents(text);
4716  status=MagickTrue;
4717  exception=AcquireExceptionInfo();
4718  if (monitor_handler != (MonitorHandler) NULL)
4719  status=(*monitor_handler)(text,offset,span,exception);
4720  exception=DestroyExceptionInfo(exception);
4721  return(status);
4722 }
4723 ␌
4724 /*
4725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4726 % %
4727 % %
4728 % %
4729 % M a p I m a g e %
4730 % %
4731 % %
4732 % %
4733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4734 %
4735 % MapImage() replaces the colors of an image with the closest color from a
4736 % reference image.
4737 %
4738 % Deprecated, replace with:
4739 %
4740 % QuantizeInfo quantize_info;
4741 % GetQuantizeInfo(&quantize_info);
4742 % quantize_info.dither=dither;
4743 % RemapImage(&quantize_info,image,map_image);
4744 %
4745 % The format of the MapImage method is:
4746 %
4747 % MagickBooleanType MapImage(Image *image,const Image *map_image,
4748 % const MagickBooleanType dither)
4749 %
4750 % A description of each parameter follows:
4751 %
4752 % o image: Specifies a pointer to an Image structure.
4753 %
4754 % o map_image: the image. Reduce image to a set of colors represented by
4755 % this image.
4756 %
4757 % o dither: Set this integer value to something other than zero to
4758 % dither the mapped image.
4759 %
4760 */
4761 MagickExport MagickBooleanType MapImage(Image *image,const Image *map_image,
4762  const MagickBooleanType dither)
4763 {
4764  QuantizeInfo
4765  quantize_info;
4766 
4767  /*
4768  Initialize color cube.
4769  */
4770  assert(image != (Image *) NULL);
4771  assert(image->signature == MagickCoreSignature);
4772  assert(map_image != (Image *) NULL);
4773  assert(map_image->signature == MagickCoreSignature);
4774  if (IsEventLogging() != MagickFalse)
4775  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4776  GetQuantizeInfo(&quantize_info);
4777  quantize_info.dither=dither;
4778  return(RemapImage(&quantize_info,image,map_image));
4779 }
4780 ␌
4781 /*
4782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4783 % %
4784 % %
4785 % %
4786 % M a p I m a g e s %
4787 % %
4788 % %
4789 % %
4790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4791 %
4792 % MapImages() replaces the colors of a sequence of images with the closest
4793 % color from a reference image.
4794 %
4795 % Deprecated, replace with:
4796 %
4797 % QuantizeInfo quantize_info;
4798 % GetQuantizeInfo(&quantize_info);
4799 % quantize_info.dither=dither;
4800 % RemapImages(&quantize_info,images,map_image);
4801 %
4802 % The format of the MapImage method is:
4803 %
4804 % MagickBooleanType MapImages(Image *images,Image *map_image,
4805 % const MagickBooleanType dither)
4806 %
4807 % A description of each parameter follows:
4808 %
4809 % o image: Specifies a pointer to a set of Image structures.
4810 %
4811 % o map_image: the image. Reduce image to a set of colors represented by
4812 % this image.
4813 %
4814 % o dither: Set this integer value to something other than zero to
4815 % dither the quantized image.
4816 %
4817 */
4818 MagickExport MagickBooleanType MapImages(Image *images,const Image *map_image,
4819  const MagickBooleanType dither)
4820 {
4821  QuantizeInfo
4822  quantize_info;
4823 
4824  assert(images != (Image *) NULL);
4825  assert(images->signature == MagickCoreSignature);
4826  if (IsEventLogging() != MagickFalse)
4827  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
4828  GetQuantizeInfo(&quantize_info);
4829  quantize_info.dither=dither;
4830  return(RemapImages(&quantize_info,images,map_image));
4831 }
4832 ␌
4833 /*
4834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4835 % %
4836 % %
4837 % %
4838 % M a t t e F l o o d f i l l I m a g e %
4839 % %
4840 % %
4841 % %
4842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4843 %
4844 % MatteFloodfill() changes the transparency value of any pixel that matches
4845 % target and is an immediate neighbor. If the method FillToBorderMethod
4846 % is specified, the transparency value is changed for any neighbor pixel
4847 % that does not match the bordercolor member of image.
4848 %
4849 % By default target must match a particular pixel transparency exactly.
4850 % However, in many cases two transparency values may differ by a
4851 % small amount. The fuzz member of image defines how much tolerance is
4852 % acceptable to consider two transparency values as the same. For example,
4853 % set fuzz to 10 and the opacity values of 100 and 102 respectively are
4854 % now interpreted as the same value for the purposes of the floodfill.
4855 %
4856 % The format of the MatteFloodfillImage method is:
4857 %
4858 % MagickBooleanType MatteFloodfillImage(Image *image,
4859 % const PixelPacket target,const Quantum opacity,const ssize_t x_offset,
4860 % const ssize_t y_offset,const PaintMethod method)
4861 %
4862 % A description of each parameter follows:
4863 %
4864 % o image: the image.
4865 %
4866 % o target: the RGB value of the target color.
4867 %
4868 % o opacity: the level of transparency: 0 is fully opaque and QuantumRange is
4869 % fully transparent.
4870 %
4871 % o x,y: the starting location of the operation.
4872 %
4873 % o method: Choose either FloodfillMethod or FillToBorderMethod.
4874 %
4875 */
4876 MagickExport MagickBooleanType MatteFloodfillImage(Image *image,
4877  const PixelPacket target,const Quantum opacity,const ssize_t x_offset,
4878  const ssize_t y_offset,const PaintMethod method)
4879 {
4880  Image
4881  *floodplane_image;
4882 
4883  MagickBooleanType
4884  skip;
4885 
4886  SegmentInfo
4887  *s;
4888 
4889  SegmentInfo
4890  *segment_stack;
4891 
4892  ssize_t
4893  offset,
4894  start,
4895  x,
4896  x1,
4897  x2,
4898  y;
4899 
4900  /*
4901  Check boundary conditions.
4902  */
4903  assert(image != (Image *) NULL);
4904  assert(image->signature == MagickCoreSignature);
4905  if (IsEventLogging() != MagickFalse)
4906  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4907  if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns))
4908  return(MagickFalse);
4909  if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows))
4910  return(MagickFalse);
4911  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
4912  return(MagickFalse);
4913  if (image->matte == MagickFalse)
4914  (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
4915  floodplane_image=CloneImage(image,0,0,MagickTrue,&image->exception);
4916  if (floodplane_image == (Image *) NULL)
4917  return(MagickFalse);
4918  (void) SetImageAlphaChannel(floodplane_image,OpaqueAlphaChannel);
4919  /*
4920  Set floodfill color.
4921  */
4922  segment_stack=(SegmentInfo *) AcquireQuantumMemory(MaxStacksize,
4923  sizeof(*segment_stack));
4924  if (segment_stack == (SegmentInfo *) NULL)
4925  {
4926  floodplane_image=DestroyImage(floodplane_image);
4927  ThrowBinaryImageException(ResourceLimitError,"MemoryAllocationFailed",
4928  image->filename);
4929  }
4930  /*
4931  Push initial segment on stack.
4932  */
4933  x=x_offset;
4934  y=y_offset;
4935  start=0;
4936  s=segment_stack;
4937  PushSegmentStack(y,x,x,1);
4938  PushSegmentStack(y+1,x,x,-1);
4939  while (s > segment_stack)
4940  {
4941  const PixelPacket
4942  *magick_restrict p;
4943 
4944  ssize_t
4945  x;
4946 
4947  PixelPacket
4948  *magick_restrict q;
4949 
4950  /*
4951  Pop segment off stack.
4952  */
4953  s--;
4954  x1=(ssize_t) s->x1;
4955  x2=(ssize_t) s->x2;
4956  offset=(ssize_t) s->y2;
4957  y=(ssize_t) s->y1+offset;
4958  /*
4959  Recolor neighboring pixels.
4960  */
4961  p=GetVirtualPixels(image,0,y,(size_t) (x1+1),1,&image->exception);
4962  q=GetAuthenticPixels(floodplane_image,0,y,(size_t) (x1+1),1,
4963  &image->exception);
4964  if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
4965  break;
4966  p+=x1;
4967  q+=x1;
4968  for (x=x1; x >= 0; x--)
4969  {
4970  if (q->opacity == (Quantum) TransparentOpacity)
4971  break;
4972  if (method == FloodfillMethod)
4973  {
4974  if (IsColorSimilar(image,p,&target) == MagickFalse)
4975  break;
4976  }
4977  else
4978  if (IsColorSimilar(image,p,&target) != MagickFalse)
4979  break;
4980  q->opacity=(Quantum) TransparentOpacity;
4981  q--;
4982  p--;
4983  }
4984  if (SyncAuthenticPixels(floodplane_image,&image->exception) == MagickFalse)
4985  break;
4986  skip=x >= x1 ? MagickTrue : MagickFalse;
4987  if (skip == MagickFalse)
4988  {
4989  start=x+1;
4990  if (start < x1)
4991  PushSegmentStack(y,start,x1-1,-offset);
4992  x=x1+1;
4993  }
4994  do
4995  {
4996  if (skip == MagickFalse)
4997  {
4998  if (x < (ssize_t) image->columns)
4999  {
5000  p=GetVirtualPixels(image,x,y,image->columns-x,1,
5001  &image->exception);
5002  q=GetAuthenticPixels(floodplane_image,x,y,image->columns-x,1,
5003  &image->exception);
5004  if ((p == (const PixelPacket *) NULL) ||
5005  (q == (PixelPacket *) NULL))
5006  break;
5007  for ( ; x < (ssize_t) image->columns; x++)
5008  {
5009  if (q->opacity == (Quantum) TransparentOpacity)
5010  break;
5011  if (method == FloodfillMethod)
5012  {
5013  if (IsColorSimilar(image,p,&target) == MagickFalse)
5014  break;
5015  }
5016  else
5017  if (IsColorSimilar(image,p,&target) != MagickFalse)
5018  break;
5019  q->opacity=(Quantum) TransparentOpacity;
5020  q++;
5021  p++;
5022  }
5023  if (SyncAuthenticPixels(floodplane_image,&image->exception) == MagickFalse)
5024  break;
5025  }
5026  PushSegmentStack(y,start,x-1,offset);
5027  if (x > (x2+1))
5028  PushSegmentStack(y,x2+1,x-1,-offset);
5029  }
5030  skip=MagickFalse;
5031  x++;
5032  if (x <= x2)
5033  {
5034  p=GetVirtualPixels(image,x,y,(size_t) (x2-x+1),1,
5035  &image->exception);
5036  q=GetAuthenticPixels(floodplane_image,x,y,(size_t) (x2-x+1),1,
5037  &image->exception);
5038  if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
5039  break;
5040  for ( ; x <= x2; x++)
5041  {
5042  if (q->opacity == (Quantum) TransparentOpacity)
5043  break;
5044  if (method == FloodfillMethod)
5045  {
5046  if (IsColorSimilar(image,p,&target) != MagickFalse)
5047  break;
5048  }
5049  else
5050  if (IsColorSimilar(image,p,&target) == MagickFalse)
5051  break;
5052  p++;
5053  q++;
5054  }
5055  }
5056  start=x;
5057  } while (x <= x2);
5058  }
5059  for (y=0; y < (ssize_t) image->rows; y++)
5060  {
5061  const PixelPacket
5062  *magick_restrict p;
5063 
5064  ssize_t
5065  x;
5066 
5067  PixelPacket
5068  *magick_restrict q;
5069 
5070  /*
5071  Tile fill color onto floodplane.
5072  */
5073  p=GetVirtualPixels(floodplane_image,0,y,image->columns,1,
5074  &image->exception);
5075  q=GetAuthenticPixels(image,0,y,image->columns,1,&image->exception);
5076  if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
5077  break;
5078  for (x=0; x < (ssize_t) image->columns; x++)
5079  {
5080  if (GetPixelOpacity(p) != OpaqueOpacity)
5081  q->opacity=opacity;
5082  p++;
5083  q++;
5084  }
5085  if (SyncAuthenticPixels(image,&image->exception) == MagickFalse)
5086  break;
5087  }
5088  segment_stack=(SegmentInfo *) RelinquishMagickMemory(segment_stack);
5089  floodplane_image=DestroyImage(floodplane_image);
5090  return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
5091 }
5092 ␌
5093 /*
5094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5095 % %
5096 % %
5097 % %
5098 % M a x i m u m I m a g e s %
5099 % %
5100 % %
5101 % %
5102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5103 %
5104 % MaximumImages() returns the maximum intensity of an image sequence.
5105 %
5106 % Deprecated, replace with:
5107 %
5108 % EvaluateImages(images,MinEvaluateOperator,exception);
5109 %
5110 % The format of the MaxImages method is:
5111 %
5112 % Image *MaximumImages(Image *images,ExceptionInfo *exception)
5113 %
5114 % A description of each parameter follows:
5115 %
5116 % o images: the image sequence.
5117 %
5118 % o exception: return any errors or warnings in this structure.
5119 %
5120 */
5121 MagickExport Image *MaximumImages(const Image *images,ExceptionInfo *exception)
5122 {
5123  return(EvaluateImages(images,MinEvaluateOperator,exception));
5124 }
5125 ␌
5126 /*
5127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5128 % %
5129 % %
5130 % %
5131 % M i n i m u m I m a g e s %
5132 % %
5133 % %
5134 % %
5135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5136 %
5137 % MinimumImages() returns the minimum intensity of an image sequence.
5138 %
5139 % Deprecated, replace with:
5140 %
5141 % EvaluateImages(images,MinEvaluateOperator,exception);
5142 %
5143 % The format of the MinimumImages method is:
5144 %
5145 % Image *MinimumImages(Image *images,ExceptionInfo *exception)
5146 %
5147 % A description of each parameter follows:
5148 %
5149 % o images: the image sequence.
5150 %
5151 % o exception: return any errors or warnings in this structure.
5152 %
5153 */
5154 MagickExport Image *MinimumImages(const Image *images,ExceptionInfo *exception)
5155 {
5156  return(EvaluateImages(images,MinEvaluateOperator,exception));
5157 }
5158 ␌
5159 /*
5160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5161 % %
5162 % %
5163 % %
5164 % M e d i a n F i l t e r I m a g e %
5165 % %
5166 % %
5167 % %
5168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5169 %
5170 % MedianFilterImage() applies a digital filter that improves the quality
5171 % of a noisy image. Each pixel is replaced by the median in a set of
5172 % neighboring pixels as defined by radius.
5173 %
5174 % The algorithm was contributed by Mike Edmonds and implements an insertion
5175 % sort for selecting median color-channel values. For more on this algorithm
5176 % see "Skip Lists: A probabilistic Alternative to Balanced Trees" by William
5177 % Pugh in the June 1990 of Communications of the ACM.
5178 %
5179 % The format of the MedianFilterImage method is:
5180 %
5181 % Image *MedianFilterImage(const Image *image,const double radius,
5182 % ExceptionInfo *exception)
5183 %
5184 % A description of each parameter follows:
5185 %
5186 % o image: the image.
5187 %
5188 % o radius: the radius of the pixel neighborhood.
5189 %
5190 % o exception: return any errors or warnings in this structure.
5191 %
5192 */
5193 MagickExport Image *MedianFilterImage(const Image *image,const double radius,
5194  ExceptionInfo *exception)
5195 {
5196  Image
5197  *median_image;
5198 
5199  median_image=StatisticImage(image,MedianStatistic,(size_t) radius,(size_t)
5200  radius,exception);
5201  return(median_image);
5202 }
5203 ␌
5204 /*
5205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5206 % %
5207 % %
5208 % %
5209 % M o d e I m a g e %
5210 % %
5211 % %
5212 % %
5213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5214 %
5215 % ModeImage() makes each pixel the 'predominant color' of the neighborhood
5216 % of the specified radius.
5217 %
5218 % The format of the ModeImage method is:
5219 %
5220 % Image *ModeImage(const Image *image,const double radius,
5221 % ExceptionInfo *exception)
5222 %
5223 % A description of each parameter follows:
5224 %
5225 % o image: the image.
5226 %
5227 % o radius: the radius of the pixel neighborhood.
5228 %
5229 % o exception: return any errors or warnings in this structure.
5230 %
5231 */
5232 MagickExport Image *ModeImage(const Image *image,const double radius,
5233  ExceptionInfo *exception)
5234 {
5235  Image
5236  *mode_image;
5237 
5238  mode_image=StatisticImage(image,ModeStatistic,(size_t) radius,(size_t) radius,
5239  exception);
5240  return(mode_image);
5241 }
5242 ␌
5243 /*
5244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5245 % %
5246 % %
5247 % %
5248 % M o s a i c I m a g e s %
5249 % %
5250 % %
5251 % %
5252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5253 %
5254 % MosaicImages() Obsolete Function: Use MergeImageLayers() instead.
5255 %
5256 % Deprecated, replace with:
5257 %
5258 % MergeImageLayers(image,MosaicLayer,exception);
5259 %
5260 % The format of the MosaicImage method is:
5261 %
5262 % Image *MosaicImages(const Image *image,ExceptionInfo *exception)
5263 %
5264 % A description of each parameter follows:
5265 %
5266 % o image: the image list to be composited together
5267 %
5268 % o exception: return any errors or warnings in this structure.
5269 %
5270 */
5271 MagickExport Image *MosaicImages(Image *image,ExceptionInfo *exception)
5272 {
5273  return(MergeImageLayers(image,MosaicLayer,exception));
5274 }
5275 ␌
5276 /*
5277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5278 % %
5279 % %
5280 % %
5281 % O p a q u e I m a g e %
5282 % %
5283 % %
5284 % %
5285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5286 %
5287 % OpaqueImage() changes any pixel that matches color with the color
5288 % defined by fill.
5289 %
5290 % By default color must match a particular pixel color exactly. However,
5291 % in many cases two colors may differ by a small amount. Fuzz defines
5292 % how much tolerance is acceptable to consider two colors as the same.
5293 % For example, set fuzz to 10 and the color red at intensities of 100 and
5294 % 102 respectively are now interpreted as the same color.
5295 %
5296 % The format of the OpaqueImage method is:
5297 %
5298 % MagickBooleanType OpaqueImage(Image *image,
5299 % const PixelPacket *target,const PixelPacket fill)
5300 %
5301 % A description of each parameter follows:
5302 %
5303 % o image: the image.
5304 %
5305 % o target: the RGB value of the target color.
5306 %
5307 % o fill: the replacement color.
5308 %
5309 */
5310 MagickExport MagickBooleanType OpaqueImage(Image *image,
5311  const PixelPacket target,const PixelPacket fill)
5312 {
5313 #define OpaqueImageTag "Opaque/Image"
5314 
5315  MagickBooleanType
5316  proceed;
5317 
5318  ssize_t
5319  i;
5320 
5321  ssize_t
5322  y;
5323 
5324  /*
5325  Make image color opaque.
5326  */
5327  assert(image != (Image *) NULL);
5328  assert(image->signature == MagickCoreSignature);
5329  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.1.0");
5330  if (IsEventLogging() != MagickFalse)
5331  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
5332  switch (image->storage_class)
5333  {
5334  case DirectClass:
5335  default:
5336  {
5337  /*
5338  Make DirectClass image opaque.
5339  */
5340  for (y=0; y < (ssize_t) image->rows; y++)
5341  {
5342  ssize_t
5343  x;
5344 
5345  PixelPacket
5346  *magick_restrict q;
5347 
5348  q=GetAuthenticPixels(image,0,y,image->columns,1,&image->exception);
5349  if (q == (PixelPacket *) NULL)
5350  break;
5351  for (x=0; x < (ssize_t) image->columns; x++)
5352  {
5353  if (IsColorSimilar(image,q,&target) != MagickFalse)
5354  *q=fill;
5355  q++;
5356  }
5357  if (SyncAuthenticPixels(image,&image->exception) == MagickFalse)
5358  break;
5359  proceed=SetImageProgress(image,OpaqueImageTag,(MagickOffsetType) y,
5360  image->rows);
5361  if (proceed == MagickFalse)
5362  break;
5363  }
5364  break;
5365  }
5366  case PseudoClass:
5367  {
5368  /*
5369  Make PseudoClass image opaque.
5370  */
5371  for (i=0; i < (ssize_t) image->colors; i++)
5372  {
5373  if (IsColorSimilar(image,&image->colormap[i],&target) != MagickFalse)
5374  image->colormap[i]=fill;
5375  }
5376  if (fill.opacity != OpaqueOpacity)
5377  {
5378  for (y=0; y < (ssize_t) image->rows; y++)
5379  {
5380  ssize_t
5381  x;
5382 
5383  PixelPacket
5384  *magick_restrict q;
5385 
5386  q=GetAuthenticPixels(image,0,y,image->columns,1,&image->exception);
5387  if (q == (PixelPacket *) NULL)
5388  break;
5389  for (x=0; x < (ssize_t) image->columns; x++)
5390  {
5391  if (IsColorSimilar(image,q,&target) != MagickFalse)
5392  q->opacity=fill.opacity;
5393  q++;
5394  }
5395  if (SyncAuthenticPixels(image,&image->exception) == MagickFalse)
5396  break;
5397  }
5398  }
5399  (void) SyncImage(image);
5400  break;
5401  }
5402  }
5403  if (fill.opacity != OpaqueOpacity)
5404  image->matte=MagickTrue;
5405  return(MagickTrue);
5406 }
5407 ␌
5408 /*
5409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5410 % %
5411 % %
5412 % %
5413 % O p e n C a c h e V i e w %
5414 % %
5415 % %
5416 % %
5417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5418 %
5419 % OpenCacheView() opens a view into the pixel cache, using the
5420 % VirtualPixelMethod that is defined within the given image itself.
5421 %
5422 % Deprecated, replace with:
5423 %
5424 % AcquireVirtualCacheView(image,&image->exception);
5425 %
5426 % The format of the OpenCacheView method is:
5427 %
5428 % CacheView *OpenCacheView(const Image *image)
5429 %
5430 % A description of each parameter follows:
5431 %
5432 % o image: the image.
5433 %
5434 */
5435 MagickExport CacheView *OpenCacheView(const Image *image)
5436 {
5437  return(AcquireVirtualCacheView(image,&((Image *) image)->exception));
5438 }
5439 ␌
5440 /*
5441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5442 % %
5443 % %
5444 % %
5445 % O p e n M a g i c k S t r e a m %
5446 % %
5447 % %
5448 % %
5449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5450 %
5451 % OpenMagickStream() opens the file at the specified path and return the
5452 % associated stream.
5453 %
5454 % The path of the OpenMagickStream method is:
5455 %
5456 % FILE *OpenMagickStream(const char *path,const char *mode)
5457 %
5458 % A description of each parameter follows.
5459 %
5460 % o path: the file path.
5461 %
5462 % o mode: the file mode.
5463 %
5464 */
5465 
5466 #if defined(MAGICKCORE_HAVE__WFOPEN)
5467 static size_t UTF8ToUTF16(const unsigned char *utf8,wchar_t *utf16)
5468 {
5469  const unsigned char
5470  *p;
5471 
5472  if (utf16 != (wchar_t *) NULL)
5473  {
5474  wchar_t
5475  *q;
5476 
5477  wchar_t
5478  c;
5479 
5480  /*
5481  Convert UTF-8 to UTF-16.
5482  */
5483  q=utf16;
5484  for (p=utf8; *p != '\0'; p++)
5485  {
5486  if ((*p & 0x80) == 0)
5487  *q=(*p);
5488  else
5489  if ((*p & 0xE0) == 0xC0)
5490  {
5491  c=(*p);
5492  *q=(c & 0x1F) << 6;
5493  p++;
5494  if ((*p & 0xC0) != 0x80)
5495  return(0);
5496  *q|=(*p & 0x3F);
5497  }
5498  else
5499  if ((*p & 0xF0) == 0xE0)
5500  {
5501  c=(*p);
5502  *q=c << 12;
5503  p++;
5504  if ((*p & 0xC0) != 0x80)
5505  return(0);
5506  c=(*p);
5507  *q|=(c & 0x3F) << 6;
5508  p++;
5509  if ((*p & 0xC0) != 0x80)
5510  return(0);
5511  *q|=(*p & 0x3F);
5512  }
5513  else
5514  return(0);
5515  q++;
5516  }
5517  *q++='\0';
5518  return(q-utf16);
5519  }
5520  /*
5521  Compute UTF-16 string length.
5522  */
5523  for (p=utf8; *p != '\0'; p++)
5524  {
5525  if ((*p & 0x80) == 0)
5526  ;
5527  else
5528  if ((*p & 0xE0) == 0xC0)
5529  {
5530  p++;
5531  if ((*p & 0xC0) != 0x80)
5532  return(0);
5533  }
5534  else
5535  if ((*p & 0xF0) == 0xE0)
5536  {
5537  p++;
5538  if ((*p & 0xC0) != 0x80)
5539  return(0);
5540  p++;
5541  if ((*p & 0xC0) != 0x80)
5542  return(0);
5543  }
5544  else
5545  return(0);
5546  }
5547  return(p-utf8);
5548 }
5549 
5550 static wchar_t *ConvertUTF8ToUTF16(const unsigned char *source)
5551 {
5552  size_t
5553  length;
5554 
5555  wchar_t
5556  *utf16;
5557 
5558  length=UTF8ToUTF16(source,(wchar_t *) NULL);
5559  if (length == 0)
5560  {
5561  ssize_t
5562  i;
5563 
5564  /*
5565  Not UTF-8, just copy.
5566  */
5567  length=strlen((const char *) source);
5568  utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
5569  if (utf16 == (wchar_t *) NULL)
5570  return((wchar_t *) NULL);
5571  for (i=0; i <= (ssize_t) length; i++)
5572  utf16[i]=source[i];
5573  return(utf16);
5574  }
5575  utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
5576  if (utf16 == (wchar_t *) NULL)
5577  return((wchar_t *) NULL);
5578  length=UTF8ToUTF16(source,utf16);
5579  return(utf16);
5580 }
5581 #endif
5582 
5583 MagickExport FILE *OpenMagickStream(const char *path,const char *mode)
5584 {
5585  FILE
5586  *file;
5587 
5588  if ((path == (const char *) NULL) || (mode == (const char *) NULL))
5589  {
5590  errno=EINVAL;
5591  return((FILE *) NULL);
5592  }
5593  file=(FILE *) NULL;
5594 #if defined(MAGICKCORE_HAVE__WFOPEN)
5595  {
5596  wchar_t
5597  *unicode_mode,
5598  *unicode_path;
5599 
5600  unicode_path=ConvertUTF8ToUTF16((const unsigned char *) path);
5601  if (unicode_path == (wchar_t *) NULL)
5602  return((FILE *) NULL);
5603  unicode_mode=ConvertUTF8ToUTF16((const unsigned char *) mode);
5604  if (unicode_mode == (wchar_t *) NULL)
5605  {
5606  unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
5607  return((FILE *) NULL);
5608  }
5609  file=_wfopen(unicode_path,unicode_mode);
5610  unicode_mode=(wchar_t *) RelinquishMagickMemory(unicode_mode);
5611  unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
5612  }
5613 #endif
5614  if (file == (FILE *) NULL)
5615  file=fopen(path,mode);
5616  return(file);
5617 }
5618 ␌
5619 /*
5620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5621 % %
5622 % %
5623 % %
5624 % P a i n t F l o o d f i l l I m a g e %
5625 % %
5626 % %
5627 % %
5628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5629 %
5630 % PaintFloodfill() changes the color value of any pixel that matches
5631 % target and is an immediate neighbor. If the method FillToBorderMethod is
5632 % specified, the color value is changed for any neighbor pixel that does not
5633 % match the bordercolor member of image.
5634 %
5635 % By default target must match a particular pixel color exactly.
5636 % However, in many cases two colors may differ by a small amount. The
5637 % fuzz member of image defines how much tolerance is acceptable to
5638 % consider two colors as the same. For example, set fuzz to 10 and the
5639 % color red at intensities of 100 and 102 respectively are now
5640 % interpreted as the same color for the purposes of the floodfill.
5641 %
5642 % Deprecated, replace with:
5643 %
5644 % FloodfillPaintImage(image,channel,draw_info,target,x,y,
5645 % method == FloodfillMethod ? MagickFalse : MagickTrue);
5646 %
5647 % The format of the PaintFloodfillImage method is:
5648 %
5649 % MagickBooleanType PaintFloodfillImage(Image *image,
5650 % const ChannelType channel,const MagickPixelPacket target,
5651 % const ssize_t x,const ssize_t y,const DrawInfo *draw_info,
5652 % const PaintMethod method)
5653 %
5654 % A description of each parameter follows:
5655 %
5656 % o image: the image.
5657 %
5658 % o channel: the channel(s).
5659 %
5660 % o target: the RGB value of the target color.
5661 %
5662 % o x,y: the starting location of the operation.
5663 %
5664 % o draw_info: the draw info.
5665 %
5666 % o method: Choose either FloodfillMethod or FillToBorderMethod.
5667 %
5668 */
5669 MagickExport MagickBooleanType PaintFloodfillImage(Image *image,
5670  const ChannelType channel,const MagickPixelPacket *target,const ssize_t x,
5671  const ssize_t y,const DrawInfo *draw_info,const PaintMethod method)
5672 {
5673  MagickBooleanType
5674  status;
5675 
5676  status=FloodfillPaintImage(image,channel,draw_info,target,x,y,
5677  method == FloodfillMethod ? MagickFalse : MagickTrue);
5678  return(status);
5679 }
5680 ␌
5681 /*
5682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5683 % %
5684 % %
5685 % P a i n t O p a q u e I m a g e %
5686 % %
5687 % %
5688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5689 %
5690 % PaintOpaqueImage() changes any pixel that matches color with the color
5691 % defined by fill.
5692 %
5693 % By default color must match a particular pixel color exactly. However,
5694 % in many cases two colors may differ by a small amount. Fuzz defines
5695 % how much tolerance is acceptable to consider two colors as the same.
5696 % For example, set fuzz to 10 and the color red at intensities of 100 and
5697 % 102 respectively are now interpreted as the same color.
5698 %
5699 % Deprecated, replace with:
5700 %
5701 % OpaquePaintImageChannel(image,DefaultChannels,target,fill,MagickFalse);
5702 % OpaquePaintImageChannel(image,channel,target,fill,MagickFalse);
5703 %
5704 % The format of the PaintOpaqueImage method is:
5705 %
5706 % MagickBooleanType PaintOpaqueImage(Image *image,
5707 % const PixelPacket *target,const PixelPacket *fill)
5708 % MagickBooleanType PaintOpaqueImageChannel(Image *image,
5709 % const ChannelType channel,const PixelPacket *target,
5710 % const PixelPacket *fill)
5711 %
5712 % A description of each parameter follows:
5713 %
5714 % o image: the image.
5715 %
5716 % o channel: the channel(s).
5717 %
5718 % o target: the RGB value of the target color.
5719 %
5720 % o fill: the replacement color.
5721 %
5722 */
5723 
5724 MagickExport MagickBooleanType PaintOpaqueImage(Image *image,
5725  const MagickPixelPacket *target,const MagickPixelPacket *fill)
5726 {
5727  MagickBooleanType
5728  status;
5729 
5730  status=OpaquePaintImageChannel(image,DefaultChannels,target,fill,MagickFalse);
5731  return(status);
5732 }
5733 
5734 MagickExport MagickBooleanType PaintOpaqueImageChannel(Image *image,
5735  const ChannelType channel,const MagickPixelPacket *target,
5736  const MagickPixelPacket *fill)
5737 {
5738  return(OpaquePaintImageChannel(image,channel,target,fill,MagickFalse));
5739 }
5740 ␌
5741 /*
5742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5743 % %
5744 % %
5745 % %
5746 % P a i n t T r a n s p a r e n t I m a g e %
5747 % %
5748 % %
5749 % %
5750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5751 %
5752 % PaintTransparentImage() changes the opacity value associated with any pixel
5753 % that matches color to the value defined by opacity.
5754 %
5755 % By default color must match a particular pixel color exactly. However,
5756 % in many cases two colors may differ by a small amount. Fuzz defines
5757 % how much tolerance is acceptable to consider two colors as the same.
5758 % For example, set fuzz to 10 and the color red at intensities of 100 and
5759 % 102 respectively are now interpreted as the same color.
5760 %
5761 % Deprecated, replace with:
5762 %
5763 % TransparentPaintImage(image,target,opacity,MagickFalse);
5764 %
5765 % The format of the PaintTransparentImage method is:
5766 %
5767 % MagickBooleanType PaintTransparentImage(Image *image,
5768 % const MagickPixelPacket *target,const Quantum opacity)
5769 %
5770 % A description of each parameter follows:
5771 %
5772 % o image: the image.
5773 %
5774 % o target: the RGB value of the target color.
5775 %
5776 % o opacity: the replacement opacity value.
5777 %
5778 */
5779 MagickExport MagickBooleanType PaintTransparentImage(Image *image,
5780  const MagickPixelPacket *target,const Quantum opacity)
5781 {
5782  return(TransparentPaintImage(image,target,opacity,MagickFalse));
5783 }
5784 ␌
5785 /*
5786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5787 % %
5788 % %
5789 % %
5790 + P a r s e I m a g e G e o m e t r y %
5791 % %
5792 % %
5793 % %
5794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5795 %
5796 % ParseImageGeometry() is similar to GetGeometry() except the returned
5797 % geometry is modified as determined by the meta characters: %, !, <,
5798 % and >.
5799 %
5800 % Deprecated, replace with:
5801 %
5802 % ParseMetaGeometry(geometry,x,y,width,height);
5803 %
5804 % The format of the ParseImageGeometry method is:
5805 %
5806 % int ParseImageGeometry(char *geometry,ssize_t *x,ssize_t *y,
5807 % size_t *width,size_t *height)
5808 %
5809 % A description of each parameter follows:
5810 %
5811 % o flags: Method ParseImageGeometry returns a bitmask that indicates
5812 % which of the four values were located in the geometry string.
5813 %
5814 % o image_geometry: Specifies a character string representing the geometry
5815 % specification.
5816 %
5817 % o x,y: A pointer to an integer. The x and y offset as determined by
5818 % the geometry specification is returned here.
5819 %
5820 % o width,height: A pointer to an unsigned integer. The width and height
5821 % as determined by the geometry specification is returned here.
5822 %
5823 */
5824 MagickExport int ParseImageGeometry(const char *geometry,ssize_t *x,ssize_t *y,
5825  size_t *width,size_t *height)
5826 {
5827  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.1");
5828  return((int) ParseMetaGeometry(geometry,x,y,width,height));
5829 }
5830 ␌
5831 /*
5832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5833 % %
5834 % %
5835 % %
5836 % P a r s e S i z e G e o m e t r y %
5837 % %
5838 % %
5839 % %
5840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5841 %
5842 % ParseSizeGeometry() returns a region as defined by the geometry string with
5843 % respect to the image dimensions and aspect ratio.
5844 %
5845 % Deprecated, replace with:
5846 %
5847 % ParseMetaGeometry(geometry,&region_info->x,&region_info->y,
5848 % &region_info->width,&region_info->height);
5849 %
5850 % The format of the ParseSizeGeometry method is:
5851 %
5852 % MagickStatusType ParseSizeGeometry(const Image *image,
5853 % const char *geometry,RectangeInfo *region_info)
5854 %
5855 % A description of each parameter follows:
5856 %
5857 % o geometry: The geometry (e.g. 100x100+10+10).
5858 %
5859 % o region_info: the region as defined by the geometry string.
5860 %
5861 */
5862 MagickExport MagickStatusType ParseSizeGeometry(const Image *image,
5863  const char *geometry,RectangleInfo *region_info)
5864 {
5865  MagickStatusType
5866  flags;
5867 
5868  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.4.7");
5869  SetGeometry(image,region_info);
5870  flags=ParseMetaGeometry(geometry,&region_info->x,&region_info->y,
5871  &region_info->width,&region_info->height);
5872  return(flags);
5873 }
5874 ␌
5875 /*
5876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5877 % %
5878 % %
5879 % %
5880 % P o p I m a g e L i s t %
5881 % %
5882 % %
5883 % %
5884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5885 %
5886 % PopImageList() removes the last image in the list.
5887 %
5888 % Deprecated, replace with:
5889 %
5890 % RemoveLastImageFromList(images);
5891 %
5892 % The format of the PopImageList method is:
5893 %
5894 % Image *PopImageList(Image **images)
5895 %
5896 % A description of each parameter follows:
5897 %
5898 % o images: the image list.
5899 %
5900 */
5901 MagickExport Image *PopImageList(Image **images)
5902 {
5903  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
5904  return(RemoveLastImageFromList(images));
5905 }
5906 ␌
5907 /*
5908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5909 % %
5910 % %
5911 % %
5912 % P o p I m a g e P i x e l s %
5913 % %
5914 % %
5915 % %
5916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5917 %
5918 % PopImagePixels() transfers one or more pixel components from the image pixel
5919 % cache to a user supplied buffer. The pixels are returned in network byte
5920 % order. MagickTrue is returned if the pixels are successfully transferred,
5921 % otherwise MagickFalse.
5922 %
5923 % The format of the PopImagePixels method is:
5924 %
5925 % size_t PopImagePixels(Image *,const QuantumType quantum,
5926 % unsigned char *destination)
5927 %
5928 % A description of each parameter follows:
5929 %
5930 % o image: the image.
5931 %
5932 % o quantum: Declare which pixel components to transfer (RGB, RGBA, etc).
5933 %
5934 % o destination: The components are transferred to this buffer.
5935 %
5936 */
5937 MagickExport size_t PopImagePixels(Image *image,const QuantumType quantum,
5938  unsigned char *destination)
5939 {
5940  QuantumInfo
5941  *quantum_info;
5942 
5943  size_t
5944  length;
5945 
5946  quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
5947  if (quantum_info == (QuantumInfo *) NULL)
5948  return(0);
5949  length=ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info,
5950  quantum,destination,&image->exception);
5951  quantum_info=DestroyQuantumInfo(quantum_info);
5952  return(length);
5953 }
5954 ␌
5955 /*
5956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5957 % %
5958 % %
5959 % %
5960 % P o s t s c r i p t G e o m e t r y %
5961 % %
5962 % %
5963 % %
5964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5965 %
5966 % PostscriptGeometry() replaces any page mneumonic with the equivalent size in
5967 % picas.
5968 %
5969 % Deprecated, replace with:
5970 %
5971 % GetPageGeometry(page);
5972 %
5973 % The format of the PostscriptGeometry method is:
5974 %
5975 % char *PostscriptGeometry(const char *page)
5976 %
5977 % A description of each parameter follows.
5978 %
5979 % o page: Specifies a pointer to an array of characters.
5980 % The string is either a Postscript page name (e.g. A4) or a postscript
5981 % page geometry (e.g. 612x792+36+36).
5982 %
5983 */
5984 MagickExport char *PostscriptGeometry(const char *page)
5985 {
5986  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.1");
5987  return(GetPageGeometry(page));
5988 }
5989 ␌
5990 /*
5991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5992 % %
5993 % %
5994 % %
5995 % P u s h I m a g e L i s t %
5996 % %
5997 % %
5998 % %
5999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6000 %
6001 % PushImageList() adds an image to the end of the list.
6002 %
6003 % Deprecated, replace with:
6004 %
6005 % AppendImageToList(images,CloneImageList(image,exception));
6006 %
6007 % The format of the PushImageList method is:
6008 %
6009 % unsigned int PushImageList(Image *images,const Image *image,
6010 % ExceptionInfo *exception)
6011 %
6012 % A description of each parameter follows:
6013 %
6014 % o images: the image list.
6015 %
6016 % o image: the image.
6017 %
6018 % o exception: return any errors or warnings in this structure.
6019 %
6020 */
6021 MagickExport unsigned int PushImageList(Image **images,const Image *image,
6022  ExceptionInfo *exception)
6023 {
6024  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
6025  AppendImageToList(images,CloneImageList(image,exception));
6026  return(MagickTrue);
6027 }
6028 ␌
6029 /*
6030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6031 % %
6032 % %
6033 % %
6034 % P u s h I m a g e P i x e l s %
6035 % %
6036 % %
6037 % %
6038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6039 %
6040 % PushImagePixels() transfers one or more pixel components from a user
6041 % supplied buffer into the image pixel cache of an image. The pixels are
6042 % expected in network byte order. It returns MagickTrue if the pixels are
6043 % successfully transferred, otherwise MagickFalse.
6044 %
6045 % The format of the PushImagePixels method is:
6046 %
6047 % size_t PushImagePixels(Image *image,const QuantumType quantum,
6048 % const unsigned char *source)
6049 %
6050 % A description of each parameter follows:
6051 %
6052 % o image: the image.
6053 %
6054 % o quantum: Declare which pixel components to transfer (red, green, blue,
6055 % opacity, RGB, or RGBA).
6056 %
6057 % o source: The pixel components are transferred from this buffer.
6058 %
6059 */
6060 MagickExport size_t PushImagePixels(Image *image,const QuantumType quantum,
6061  const unsigned char *source)
6062 {
6063  QuantumInfo
6064  *quantum_info;
6065 
6066  size_t
6067  length;
6068 
6069  quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
6070  if (quantum_info == (QuantumInfo *) NULL)
6071  return(0);
6072  length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,quantum,
6073  source,&image->exception);
6074  quantum_info=DestroyQuantumInfo(quantum_info);
6075  return(length);
6076 }
6077 ␌
6078 /*
6079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6080 % %
6081 % %
6082 % %
6083 % Q u a n t i z a t i o n E r r o r %
6084 % %
6085 % %
6086 % %
6087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6088 %
6089 % QuantizationError() measures the difference between the original and
6090 % quantized images. This difference is the total quantization error. The
6091 % error is computed by summing over all pixels in an image the distance
6092 % squared in RGB space between each reference pixel value and its quantized
6093 % value. These values are computed:
6094 %
6095 % o mean_error_per_pixel: This value is the mean error for any single
6096 % pixel in the image.
6097 %
6098 % o normalized_mean_square_error: This value is the normalized mean
6099 % quantization error for any single pixel in the image. This distance
6100 % measure is normalized to a range between 0 and 1. It is independent
6101 % of the range of red, green, and blue values in the image.
6102 %
6103 % o normalized_maximum_square_error: Thsi value is the normalized
6104 % maximum quantization error for any single pixel in the image. This
6105 % distance measure is normalized to a range between 0 and 1. It is
6106 % independent of the range of red, green, and blue values in your image.
6107 %
6108 % Deprecated, replace with:
6109 %
6110 % GetImageQuantizeError(image);
6111 %
6112 % The format of the QuantizationError method is:
6113 %
6114 % unsigned int QuantizationError(Image *image)
6115 %
6116 % A description of each parameter follows.
6117 %
6118 % o image: Specifies a pointer to an Image structure; returned from
6119 % ReadImage.
6120 %
6121 */
6122 MagickExport unsigned int QuantizationError(Image *image)
6123 {
6124  if (IsEventLogging() != MagickFalse)
6125  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.3");
6126  return(GetImageQuantizeError(image));
6127 }
6128 ␌
6129 /*
6130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6131 % %
6132 % %
6133 % %
6134 % R a d i a l B l u r I m a g e %
6135 % %
6136 % %
6137 % %
6138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6139 %
6140 % RadialBlurImage() applies a radial blur to the image.
6141 %
6142 % Andrew Protano contributed this effect.
6143 %
6144 % The format of the RadialBlurImage method is:
6145 %
6146 % Image *RadialBlurImage(const Image *image,const double angle,
6147 % ExceptionInfo *exception)
6148 % Image *RadialBlurImageChannel(const Image *image,const ChannelType channel,
6149 % const double angle,ExceptionInfo *exception)
6150 %
6151 % A description of each parameter follows:
6152 %
6153 % o image: the image.
6154 %
6155 % o channel: the channel type.
6156 %
6157 % o angle: the angle of the radial blur.
6158 %
6159 % o exception: return any errors or warnings in this structure.
6160 %
6161 */
6162 
6163 MagickExport Image *RadialBlurImage(const Image *image,const double angle,
6164  ExceptionInfo *exception)
6165 {
6166  return(RotationalBlurImage(image,angle,exception));
6167 }
6168 
6169 MagickExport Image *RadialBlurImageChannel(const Image *image,
6170  const ChannelType channel,const double angle,ExceptionInfo *exception)
6171 {
6172  return(RotationalBlurImageChannel(image,channel,angle,exception));
6173 }
6174 ␌
6175 /*
6176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6177 % %
6178 % %
6179 % R a n d o m C h a n n e l T h r e s h o l d I m a g e %
6180 % %
6181 % %
6182 % %
6183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6184 %
6185 % RandomChannelThresholdImage() changes the value of individual pixels based
6186 % on the intensity of each pixel compared to a random threshold. The result
6187 % is a low-contrast, two color image.
6188 %
6189 % The format of the RandomChannelThresholdImage method is:
6190 %
6191 % unsigned int RandomChannelThresholdImage(Image *image,
6192 % const char *channel, const char *thresholds,
6193 % ExceptionInfo *exception)
6194 %
6195 % A description of each parameter follows:
6196 %
6197 % o image: the image.
6198 %
6199 % o channel: the channel or channels to be thresholded.
6200 %
6201 % o thresholds: a geometry string containing LOWxHIGH thresholds.
6202 % If the string contains 2x2, 3x3, or 4x4, then an ordered
6203 % dither of order 2, 3, or 4 will be performed instead.
6204 %
6205 % o exception: return any errors or warnings in this structure.
6206 %
6207 */
6208 MagickExport unsigned int RandomChannelThresholdImage(Image *image,
6209  const char *channel,const char *thresholds,ExceptionInfo *exception)
6210 {
6211 #define RandomChannelThresholdImageText " RandomChannelThreshold image... "
6212 
6213  double
6214  lower_threshold,
6215  upper_threshold;
6216 
6217  RandomInfo
6218  *random_info;
6219 
6220  ssize_t
6221  count,
6222  y;
6223 
6224  static MagickRealType
6225  o2[4]={0.2f, 0.6f, 0.8f, 0.4f},
6226  o3[9]={0.1f, 0.6f, 0.3f, 0.7f, 0.5f, 0.8f, 0.4f, 0.9f, 0.2f},
6227  o4[16]={0.1f, 0.7f, 1.1f, 0.3f, 1.0f, 0.5f, 1.5f, 0.8f, 1.4f, 1.6f, 0.6f,
6228  1.2f, 0.4f, 0.9f, 1.3f, 0.2f},
6229  threshold=128;
6230 
6231  size_t
6232  order;
6233 
6234  /*
6235  Threshold image.
6236  */
6237  assert(image != (Image *) NULL);
6238  assert(image->signature == MagickCoreSignature);
6239  if (IsEventLogging() != MagickFalse)
6240  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
6241  assert(exception != (ExceptionInfo *) NULL);
6242  assert(exception->signature == MagickCoreSignature);
6243  if (IsEventLogging() != MagickFalse)
6244  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
6245  if (thresholds == (const char *) NULL)
6246  return(MagickTrue);
6247  lower_threshold=0;
6248  upper_threshold=0;
6249  if (LocaleCompare(thresholds,"2x2") == 0)
6250  order=2;
6251  else
6252  if (LocaleCompare(thresholds,"3x3") == 0)
6253  order=3;
6254  else
6255  if (LocaleCompare(thresholds,"4x4") == 0)
6256  order=4;
6257  else
6258  {
6259  order=1;
6260  count=(ssize_t) sscanf(thresholds,"%lf[/x%%]%lf",&lower_threshold,
6261  &upper_threshold);
6262  if (strchr(thresholds,'%') != (char *) NULL)
6263  {
6264  upper_threshold*=(.01*(MagickRealType) QuantumRange);
6265  lower_threshold*=(.01*(MagickRealType) QuantumRange);
6266  }
6267  if (count == 1)
6268  upper_threshold=(MagickRealType) QuantumRange-lower_threshold;
6269  }
6270  if (IsEventLogging() != MagickFalse)
6271  (void) LogMagickEvent(TransformEvent,GetMagickModule(),
6272  " RandomChannelThresholdImage: channel type=%s",channel);
6273  if (IsEventLogging() != MagickFalse)
6274  (void) LogMagickEvent(TransformEvent,GetMagickModule(),
6275  " Thresholds: %s (%fx%f)",thresholds,lower_threshold,upper_threshold);
6276  if (LocaleCompare(channel,"all") == 0 ||
6277  LocaleCompare(channel,"intensity") == 0)
6278  if (AcquireImageColormap(image,2) == MagickFalse)
6279  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6280  image->filename);
6281  random_info=AcquireRandomInfo();
6282  for (y=0; y < (ssize_t) image->rows; y++)
6283  {
6284  ssize_t
6285  x;
6286 
6287  IndexPacket
6288  index,
6289  *magick_restrict indexes;
6290 
6291  PixelPacket
6292  *magick_restrict q;
6293 
6294  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
6295  if (q == (PixelPacket *) NULL)
6296  break;
6297  if (LocaleCompare(channel,"all") == 0 ||
6298  LocaleCompare(channel,"intensity") == 0)
6299  {
6300  indexes=GetAuthenticIndexQueue(image);
6301  for (x=0; x < (ssize_t) image->columns; x++)
6302  {
6303  MagickRealType
6304  intensity;
6305 
6306  intensity=GetPixelIntensity(image,q);
6307  if (order == 1)
6308  {
6309  if (intensity < lower_threshold)
6310  threshold=lower_threshold;
6311  else if (intensity > upper_threshold)
6312  threshold=upper_threshold;
6313  else
6314  threshold=(MagickRealType) QuantumRange*
6315  GetPseudoRandomValue(random_info);
6316  }
6317  else if (order == 2)
6318  threshold=(MagickRealType) QuantumRange*o2[(x%2)+2*(y%2)];
6319  else if (order == 3)
6320  threshold=(MagickRealType) QuantumRange*o3[(x%3)+3*(y%3)];
6321  else if (order == 4)
6322  threshold=(MagickRealType) QuantumRange*o4[(x%4)+4*(y%4)];
6323  index=(IndexPacket) (intensity <= threshold ? 0 : 1);
6324  SetPixelIndex(indexes+x,index);
6325  SetPixelRGBO(q,image->colormap+(ssize_t) index);
6326  q++;
6327  }
6328  }
6329  if (LocaleCompare(channel,"opacity") == 0 ||
6330  LocaleCompare(channel,"all") == 0 ||
6331  LocaleCompare(channel,"matte") == 0)
6332  {
6333  if (image->matte != MagickFalse)
6334  for (x=0; x < (ssize_t) image->columns; x++)
6335  {
6336  if (order == 1)
6337  {
6338  if ((MagickRealType) q->opacity < lower_threshold)
6339  threshold=lower_threshold;
6340  else if ((MagickRealType) q->opacity > upper_threshold)
6341  threshold=upper_threshold;
6342  else
6343  threshold=(MagickRealType) QuantumRange*
6344  GetPseudoRandomValue(random_info);
6345  }
6346  else if (order == 2)
6347  threshold=(MagickRealType) QuantumRange*o2[(x%2)+2*(y%2)];
6348  else if (order == 3)
6349  threshold=(MagickRealType) QuantumRange*o3[(x%3)+3*(y%3)];
6350  else if (order == 4)
6351  threshold=(MagickRealType) QuantumRange*o4[(x%4)+4*(y%4)]/1.7;
6352  SetPixelOpacity(q,(MagickRealType) q->opacity <=
6353  threshold ? 0 : QuantumRange);
6354  q++;
6355  }
6356  }
6357  else
6358  {
6359  /* To Do: red, green, blue, cyan, magenta, yellow, black */
6360  if (LocaleCompare(channel,"intensity") != 0)
6361  ThrowBinaryException(OptionError,"UnrecognizedChannelType",
6362  image->filename);
6363  }
6364  if (SyncAuthenticPixels(image,exception) == MagickFalse)
6365  break;
6366  }
6367  random_info=DestroyRandomInfo(random_info);
6368  return(MagickTrue);
6369 }
6370 ␌
6371 /*
6372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6373 % %
6374 % %
6375 % %
6376 % R e a c q u i r e M e m o r y %
6377 % %
6378 % %
6379 % %
6380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6381 %
6382 % ReacquireMemory() changes the size of the memory and returns a pointer to
6383 % the (possibly moved) block. The contents will be unchanged up to the
6384 % lesser of the new and old sizes.
6385 %
6386 % The format of the ReacquireMemory method is:
6387 %
6388 % void ReacquireMemory(void **memory,const size_t size)
6389 %
6390 % A description of each parameter follows:
6391 %
6392 % o memory: A pointer to a memory allocation. On return the pointer
6393 % may change but the contents of the original allocation will not.
6394 %
6395 % o size: the new size of the allocated memory.
6396 %
6397 */
6398 MagickExport void ReacquireMemory(void **memory,const size_t size)
6399 {
6400  void
6401  *allocation;
6402 
6403  assert(memory != (void **) NULL);
6404  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
6405  if (*memory == (void *) NULL)
6406  {
6407  *memory=AcquireMagickMemory(size);
6408  return;
6409  }
6410  allocation=realloc(*memory,size);
6411  if (allocation == (void *) NULL)
6412  *memory=RelinquishMagickMemory(*memory);
6413  *memory=allocation;
6414 }
6415 ␌
6416 /*
6417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6418 % %
6419 % %
6420 % %
6421 % R e c o l o r I m a g e %
6422 % %
6423 % %
6424 % %
6425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6426 %
6427 % RecolorImage() apply color transformation to an image. The method permits
6428 % saturation changes, hue rotation, luminance to alpha, and various other
6429 % effects. Although variable-sized transformation matrices can be used,
6430 % typically one uses a 5x5 matrix for an RGBA image and a 6x6 for CMYKA
6431 % (or RGBA with offsets). The matrix is similar to those used by Adobe Flash
6432 % except offsets are in column 6 rather than 5 (in support of CMYKA images)
6433 % and offsets are normalized (divide Flash offset by 255).
6434 %
6435 % The format of the RecolorImage method is:
6436 %
6437 % Image *RecolorImage(const Image *image,const size_t order,
6438 % const double *color_matrix,ExceptionInfo *exception)
6439 %
6440 % A description of each parameter follows:
6441 %
6442 % o image: the image.
6443 %
6444 % o order: the number of columns and rows in the recolor matrix.
6445 %
6446 % o color_matrix: An array of double representing the recolor matrix.
6447 %
6448 % o exception: return any errors or warnings in this structure.
6449 %
6450 */
6451 MagickExport Image *RecolorImage(const Image *image,const size_t order,
6452  const double *color_matrix,ExceptionInfo *exception)
6453 {
6454  KernelInfo
6455  *kernel_info;
6456 
6457  Image
6458  *recolor_image;
6459 
6460  kernel_info=AcquireKernelInfo("1");
6461  if (kernel_info == (KernelInfo *) NULL)
6462  return((Image *) NULL);
6463  kernel_info->width=order;
6464  kernel_info->height=order;
6465  kernel_info->values=(double *) color_matrix;
6466  recolor_image=ColorMatrixImage(image,kernel_info,exception);
6467  kernel_info->values=(double *) NULL;
6468  kernel_info=DestroyKernelInfo(kernel_info);
6469  return(recolor_image);
6470 }
6471 ␌
6472 /*
6473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6474 % %
6475 % %
6476 % %
6477 % R e d u c e N o i s e I m a g e %
6478 % %
6479 % %
6480 % %
6481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6482 %
6483 % ReduceNoiseImage() smooths the contours of an image while still preserving
6484 % edge information. The algorithm works by replacing each pixel with its
6485 % neighbor closest in value. A neighbor is defined by radius. Use a radius
6486 % of 0 and ReduceNoise() selects a suitable radius for you.
6487 %
6488 % The format of the ReduceNoiseImage method is:
6489 %
6490 % Image *ReduceNoiseImage(const Image *image,const double radius,
6491 % ExceptionInfo *exception)
6492 %
6493 % A description of each parameter follows:
6494 %
6495 % o image: the image.
6496 %
6497 % o radius: the radius of the pixel neighborhood.
6498 %
6499 % o exception: return any errors or warnings in this structure.
6500 %
6501 */
6502 MagickExport Image *ReduceNoiseImage(const Image *image,const double radius,
6503  ExceptionInfo *exception)
6504 {
6505  Image
6506  *reduce_image;
6507 
6508  reduce_image=StatisticImage(image,NonpeakStatistic,(size_t) radius,(size_t)
6509  radius,exception);
6510  return(reduce_image);
6511 }
6512 ␌
6513 /*
6514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6515 % %
6516 % %
6517 % %
6518 % R e l i n g u i s h S e m a p h o r e I n f o %
6519 % %
6520 % %
6521 % %
6522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6523 %
6524 % RelinquishSemaphoreInfo() relinquishes a semaphore.
6525 %
6526 % The format of the RelinquishSemaphoreInfo method is:
6527 %
6528 % RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
6529 %
6530 % A description of each parameter follows:
6531 %
6532 % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
6533 %
6534 */
6535 MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
6536 {
6537  assert(semaphore_info != (SemaphoreInfo *) NULL);
6538  UnlockSemaphoreInfo(semaphore_info);
6539 }
6540 ␌
6541 /*
6542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6543 % %
6544 % %
6545 % %
6546 % R e s e t I m a g e A t t r i b u t e I t e r a t o r %
6547 % %
6548 % %
6549 % %
6550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6551 %
6552 % ResetImageAttributeIterator() resets the image attributes iterator. Use it
6553 % in conjunction with GetNextImageAttribute() to iterate over all the values
6554 % associated with an image.
6555 %
6556 % Deprecated, replace with:
6557 %
6558 % ResetImagePropertyIterator(image);
6559 %
6560 % The format of the ResetImageAttributeIterator method is:
6561 %
6562 % ResetImageAttributeIterator(const ImageInfo *image)
6563 %
6564 % A description of each parameter follows:
6565 %
6566 % o image: the image.
6567 %
6568 */
6569 MagickExport void ResetImageAttributeIterator(const Image *image)
6570 {
6571  ResetImagePropertyIterator(image);
6572 }
6573 ␌
6574 /*
6575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6576 % %
6577 % %
6578 % %
6579 % S e t C a c h e V i e w P i x e l s %
6580 % %
6581 % %
6582 % %
6583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6584 %
6585 % SetCacheViewPixels() gets pixels from the in-memory or disk pixel cache as
6586 % defined by the geometry parameters. A pointer to the pixels is returned
6587 % if the pixels are transferred, otherwise a NULL is returned.
6588 %
6589 % Deprecated, replace with:
6590 %
6591 % QueueCacheViewAuthenticPixels(cache_view,x,y,columns,rows,
6592 % GetCacheViewException(cache_view));
6593 %
6594 % The format of the SetCacheViewPixels method is:
6595 %
6596 % PixelPacket *SetCacheViewPixels(CacheView *cache_view,const ssize_t x,
6597 % const ssize_t y,const size_t columns,const size_t rows)
6598 %
6599 % A description of each parameter follows:
6600 %
6601 % o cache_view: the cache view.
6602 %
6603 % o x,y,columns,rows: These values define the perimeter of a region of
6604 % pixels.
6605 %
6606 */
6607 MagickExport PixelPacket *SetCacheViewPixels(CacheView *cache_view,const ssize_t x,
6608  const ssize_t y,const size_t columns,const size_t rows)
6609 {
6610  PixelPacket
6611  *pixels;
6612 
6613  pixels=QueueCacheViewAuthenticPixels(cache_view,x,y,columns,rows,
6614  GetCacheViewException(cache_view));
6615  return(pixels);
6616 }
6617 ␌
6618 /*
6619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6620 % %
6621 % %
6622 % %
6623 + S e t C a c h e T h e s h o l d %
6624 % %
6625 % %
6626 % %
6627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6628 %
6629 % SetCacheThreshold() sets the amount of free memory allocated for the pixel
6630 % cache. Once this threshold is exceeded, all subsequent pixels cache
6631 % operations are to/from disk.
6632 %
6633 % The format of the SetCacheThreshold() method is:
6634 %
6635 % void SetCacheThreshold(const size_t threshold)
6636 %
6637 % A description of each parameter follows:
6638 %
6639 % o threshold: the number of megabytes of memory available to the pixel
6640 % cache.
6641 %
6642 */
6643 MagickExport void SetCacheThreshold(const size_t size)
6644 {
6645  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.1");
6646  (void) SetMagickResourceLimit(MemoryResource,size*1024*1024);
6647  (void) SetMagickResourceLimit(MapResource,2*size*1024*1024);
6648 }
6649 ␌
6650 /*
6651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6652 % %
6653 % %
6654 % %
6655 % S e t E x c e p t i o n I n f o %
6656 % %
6657 % %
6658 % %
6659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6660 %
6661 % SetExceptionInfo() sets the exception severity.
6662 %
6663 % The format of the SetExceptionInfo method is:
6664 %
6665 % MagickBooleanType SetExceptionInfo(ExceptionInfo *exception,
6666 % ExceptionType severity)
6667 %
6668 % A description of each parameter follows:
6669 %
6670 % o exception: the exception info.
6671 %
6672 % o severity: the exception severity.
6673 %
6674 */
6675 MagickExport MagickBooleanType SetExceptionInfo(ExceptionInfo *exception,
6676  ExceptionType severity)
6677 {
6678  assert(exception != (ExceptionInfo *) NULL);
6679  ClearMagickException(exception);
6680  exception->severity=severity;
6681  return(MagickTrue);
6682 }
6683 ␌
6684 /*
6685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6686 % %
6687 % %
6688 % %
6689 % S e t I m a g e %
6690 % %
6691 % %
6692 % %
6693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6694 %
6695 % SetImage() sets the red, green, and blue components of each pixel to
6696 % the image background color and the opacity component to the specified
6697 % level of transparency. The background color is defined by the
6698 % background_color member of the image.
6699 %
6700 % The format of the SetImage method is:
6701 %
6702 % void SetImage(Image *image,const Quantum opacity)
6703 %
6704 % A description of each parameter follows:
6705 %
6706 % o image: the image.
6707 %
6708 % o opacity: Set each pixel to this level of transparency.
6709 %
6710 */
6711 MagickExport void SetImage(Image *image,const Quantum opacity)
6712 {
6713  PixelPacket
6714  background_color;
6715 
6716  ssize_t
6717  y;
6718 
6719  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.2.0");
6720  assert(image != (Image *) NULL);
6721  if (IsEventLogging() != MagickFalse)
6722  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
6723  assert(image->signature == MagickCoreSignature);
6724  background_color=image->background_color;
6725  if (opacity != OpaqueOpacity)
6726  background_color.opacity=opacity;
6727  if (background_color.opacity != OpaqueOpacity)
6728  {
6729  (void) SetImageStorageClass(image,DirectClass);
6730  image->matte=MagickTrue;
6731  }
6732  if ((image->storage_class == PseudoClass) ||
6733  (image->colorspace == CMYKColorspace))
6734  {
6735  /*
6736  Set colormapped or CMYK image.
6737  */
6738  for (y=0; y < (ssize_t) image->rows; y++)
6739  {
6740  IndexPacket
6741  *magick_restrict indexes;
6742 
6743  ssize_t
6744  x;
6745 
6746  PixelPacket
6747  *magick_restrict q;
6748 
6749  q=QueueAuthenticPixels(image,0,y,image->columns,1,&image->exception);
6750  if (q == (PixelPacket *) NULL)
6751  break;
6752  for (x=0; x < (ssize_t) image->columns; x++)
6753  {
6754  SetPixelRGBO(q,&background_color);
6755  q++;
6756  }
6757  indexes=GetAuthenticIndexQueue(image);
6758  for (x=0; x < (ssize_t) image->columns; x++)
6759  SetPixelIndex(indexes+x,0);
6760  if (SyncAuthenticPixels(image,&image->exception) == MagickFalse)
6761  break;
6762  }
6763  return;
6764  }
6765  /*
6766  Set DirectClass image.
6767  */
6768  for (y=0; y < (ssize_t) image->rows; y++)
6769  {
6770  ssize_t
6771  x;
6772 
6773  PixelPacket
6774  *magick_restrict q;
6775 
6776  q=QueueAuthenticPixels(image,0,y,image->columns,1,&image->exception);
6777  if (q == (PixelPacket *) NULL)
6778  break;
6779  for (x=0; x < (ssize_t) image->columns; x++)
6780  {
6781  SetPixelRGBO(q,&background_color);
6782  q++;
6783  }
6784  if (SyncAuthenticPixels(image,&image->exception) == MagickFalse)
6785  break;
6786  }
6787 }
6788 ␌
6789 /*
6790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6791 % %
6792 % %
6793 % %
6794 % S e t I m a g e A t t r i b u t e %
6795 % %
6796 % %
6797 % %
6798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6799 %
6800 % SetImageAttribute() searches the list of image attributes and replaces the
6801 % attribute value. If it is not found in the list, the attribute name
6802 % and value is added to the list.
6803 %
6804 % Deprecated, replace with:
6805 %
6806 % SetImageProperty(image,key,value);
6807 %
6808 % The format of the SetImageAttribute method is:
6809 %
6810 % MagickBooleanType SetImageAttribute(Image *image,const char *key,
6811 % const char *value)
6812 %
6813 % A description of each parameter follows:
6814 %
6815 % o image: the image.
6816 %
6817 % o key: the key.
6818 %
6819 % o value: the value.
6820 %
6821 */
6822 MagickExport MagickBooleanType SetImageAttribute(Image *image,const char *key,
6823  const char *value)
6824 {
6825  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.3.1");
6826  return(SetImageProperty(image,key,value));
6827 }
6828 ␌
6829 /*
6830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6831 % %
6832 % %
6833 % %
6834 % S e t I m a g e L i s t %
6835 % %
6836 % %
6837 % %
6838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6839 %
6840 % SetImageList() inserts an image into the list at the specified position.
6841 %
6842 % The format of the SetImageList method is:
6843 %
6844 % unsigned int SetImageList(Image *images,const Image *image,
6845 % const ssize_t offset,ExceptionInfo *exception)
6846 %
6847 % A description of each parameter follows:
6848 %
6849 % o images: the image list.
6850 %
6851 % o image: the image.
6852 %
6853 % o offset: the position within the list.
6854 %
6855 % o exception: return any errors or warnings in this structure.
6856 %
6857 */
6858 MagickExport unsigned int SetImageList(Image **images,const Image *image,
6859  const ssize_t offset,ExceptionInfo *exception)
6860 {
6861  Image
6862  *clone;
6863 
6864  ssize_t
6865  i;
6866 
6867  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
6868  clone=CloneImageList(image,exception);
6869  while (GetPreviousImageInList(*images) != (Image *) NULL)
6870  (*images)=GetPreviousImageInList(*images);
6871  for (i=0; i < offset; i++)
6872  {
6873  if (GetNextImageInList(*images) == (Image *) NULL)
6874  return(MagickFalse);
6875  (*images)=GetNextImageInList(*images);
6876  }
6877  InsertImageInList(images,clone);
6878  return(MagickTrue);
6879 }
6880 ␌
6881 /*
6882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6883 % %
6884 % %
6885 % %
6886 % S e t I m a g e P i x e l s %
6887 % %
6888 % %
6889 % %
6890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6891 %
6892 % SetImagePixels() queues a mutable pixel region.
6893 % If the region is successfully initialized a pointer to a PixelPacket
6894 % array representing the region is returned, otherwise NULL is returned.
6895 % The returned pointer may point to a temporary working buffer for the
6896 % pixels or it may point to the final location of the pixels in memory.
6897 %
6898 % Write-only access means that any existing pixel values corresponding to
6899 % the region are ignored. This useful while the initial image is being
6900 % created from scratch, or if the existing pixel values are to be
6901 % completely replaced without need to refer to their pre-existing values.
6902 % The application is free to read and write the pixel buffer returned by
6903 % SetImagePixels() any way it pleases. SetImagePixels() does not initialize
6904 % the pixel array values. Initializing pixel array values is the
6905 % application's responsibility.
6906 %
6907 % Performance is maximized if the selected region is part of one row, or
6908 % one or more full rows, since then there is opportunity to access the
6909 % pixels in-place (without a copy) if the image is in RAM, or in a
6910 % memory-mapped file. The returned pointer should *never* be deallocated
6911 % by the user.
6912 %
6913 % Pixels accessed via the returned pointer represent a simple array of type
6914 % PixelPacket. If the image type is CMYK or the storage class is PseudoClass,
6915 % call GetAuthenticIndexQueue() after invoking GetAuthenticPixels() to obtain
6916 % the black color component or the colormap indexes (of type IndexPacket)
6917 % corresponding to the region. Once the PixelPacket (and/or IndexPacket)
6918 % array has been updated, the changes must be saved back to the underlying
6919 % image using SyncAuthenticPixels() or they may be lost.
6920 %
6921 % Deprecated, replace with:
6922 %
6923 % QueueAuthenticPixels(image,x,y,columns,rows,&image->exception);
6924 %
6925 % The format of the SetImagePixels() method is:
6926 %
6927 % PixelPacket *SetImagePixels(Image *image,const ssize_t x,const ssize_t y,
6928 % const size_t columns,const size_t rows)
6929 %
6930 % A description of each parameter follows:
6931 %
6932 % o pixels: SetImagePixels returns a pointer to the pixels if they are
6933 % transferred, otherwise a NULL is returned.
6934 %
6935 % o image: the image.
6936 %
6937 % o x,y,columns,rows: These values define the perimeter of a region of
6938 % pixels.
6939 %
6940 */
6941 MagickExport PixelPacket *SetImagePixels(Image *image,const ssize_t x,const ssize_t y,
6942  const size_t columns,const size_t rows)
6943 {
6944  return(QueueAuthenticPixels(image,x,y,columns,rows,&image->exception));
6945 }
6946 ␌
6947 /*
6948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6949 % %
6950 % %
6951 % %
6952 % S e t M a g i c k R e g i s t r y %
6953 % %
6954 % %
6955 % %
6956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6957 %
6958 % SetMagickRegistry() sets a blob into the registry and returns a unique ID.
6959 % If an error occurs, -1 is returned.
6960 %
6961 % The format of the SetMagickRegistry method is:
6962 %
6963 % ssize_t SetMagickRegistry(const RegistryType type,const void *blob,
6964 % const size_t length,ExceptionInfo *exception)
6965 %
6966 % A description of each parameter follows:
6967 %
6968 % o type: the registry type.
6969 %
6970 % o blob: the address of a Binary Large OBject.
6971 %
6972 % o length: For a registry type of ImageRegistryType use sizeof(Image)
6973 % otherise the blob length in number of bytes.
6974 %
6975 % o exception: return any errors or warnings in this structure.
6976 %
6977 */
6978 MagickExport ssize_t SetMagickRegistry(const RegistryType type,const void *blob,
6979  const size_t magick_unused(length),ExceptionInfo *exception)
6980 {
6981  char
6982  key[MaxTextExtent];
6983 
6984  MagickBooleanType
6985  status;
6986 
6987  static ssize_t
6988  id = 0;
6989 
6990  magick_unreferenced(length);
6991 
6992  (void) FormatLocaleString(key,MaxTextExtent,"%.20g\n",(double) id);
6993  status=SetImageRegistry(type,key,blob,exception);
6994  if (status == MagickFalse)
6995  return(-1);
6996  return(id++);
6997 }
6998 ␌
6999 /*
7000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7001 % %
7002 % %
7003 % %
7004 % S e t M o n i t o r H a n d l e r %
7005 % %
7006 % %
7007 % %
7008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7009 %
7010 % SetMonitorHandler() sets the monitor handler to the specified method
7011 % and returns the previous monitor handler.
7012 %
7013 % The format of the SetMonitorHandler method is:
7014 %
7015 % MonitorHandler SetMonitorHandler(MonitorHandler handler)
7016 %
7017 % A description of each parameter follows:
7018 %
7019 % o handler: Specifies a pointer to a method to handle monitors.
7020 %
7021 */
7022 
7023 MagickExport MonitorHandler GetMonitorHandler(void)
7024 {
7025  return(monitor_handler);
7026 }
7027 
7028 MagickExport MonitorHandler SetMonitorHandler(MonitorHandler handler)
7029 {
7030  MonitorHandler
7031  previous_handler;
7032 
7033  previous_handler=monitor_handler;
7034  monitor_handler=handler;
7035  return(previous_handler);
7036 }
7037 ␌
7038 /*
7039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7040 % %
7041 % %
7042 % %
7043 % S h i f t I m a g e L i s t %
7044 % %
7045 % %
7046 % %
7047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7048 %
7049 % ShiftImageList() removes an image from the beginning of the list.
7050 %
7051 % Deprecated, replace with:
7052 %
7053 % RemoveFirstImageFromList(images);
7054 %
7055 % The format of the ShiftImageList method is:
7056 %
7057 % Image *ShiftImageList(Image **images)
7058 %
7059 % A description of each parameter follows:
7060 %
7061 % o images: the image list.
7062 %
7063 */
7064 MagickExport Image *ShiftImageList(Image **images)
7065 {
7066  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
7067  return(RemoveFirstImageFromList(images));
7068 }
7069 ␌
7070 /*
7071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7072 % %
7073 % %
7074 % %
7075 + S i z e B l o b %
7076 % %
7077 % %
7078 % %
7079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7080 %
7081 % SizeBlob() returns the current length of the image file or blob.
7082 %
7083 % Deprecated, replace with:
7084 %
7085 % GetBlobSize(image);
7086 %
7087 % The format of the SizeBlob method is:
7088 %
7089 % off_t SizeBlob(Image *image)
7090 %
7091 % A description of each parameter follows:
7092 %
7093 % o size: Method SizeBlob returns the current length of the image file
7094 % or blob.
7095 %
7096 % o image: the image.
7097 %
7098 */
7099 MagickExport MagickOffsetType SizeBlob(Image *image)
7100 {
7101  if (IsEventLogging() != MagickFalse)
7102  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.4.3");
7103  return((MagickOffsetType) GetBlobSize(image));
7104 }
7105 ␌
7106 /*
7107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7108 % %
7109 % %
7110 % %
7111 % S p l i c e I m a g e L i s t %
7112 % %
7113 % %
7114 % %
7115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7116 %
7117 % SpliceImageList() removes the images designated by offset and length from
7118 % the list and replaces them with the specified list.
7119 %
7120 % The format of the SpliceImageList method is:
7121 %
7122 % Image *SpliceImageList(Image *images,const ssize_t offset,
7123 % const size_t length,const Image *splices,
7124 % ExceptionInfo *exception)
7125 %
7126 % A description of each parameter follows:
7127 %
7128 % o images: the image list.
7129 %
7130 % o offset: the position within the list.
7131 %
7132 % o length: the length of the image list to remove.
7133 %
7134 % o splice: Replace the removed image list with this list.
7135 %
7136 % o exception: return any errors or warnings in this structure.
7137 %
7138 */
7139 MagickExport Image *SpliceImageList(Image *images,const ssize_t offset,
7140  const size_t length,const Image *splices,ExceptionInfo *exception)
7141 {
7142  Image
7143  *clone;
7144 
7145  ssize_t
7146  i;
7147 
7148  if (images->debug != MagickFalse)
7149  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
7150  clone=CloneImageList(splices,exception);
7151  while (GetPreviousImageInList(images) != (Image *) NULL)
7152  images=GetPreviousImageInList(images);
7153  for (i=0; i < offset; i++)
7154  {
7155  if (GetNextImageInList(images) == (Image *) NULL)
7156  return((Image *) NULL);
7157  images=GetNextImageInList(images);
7158  }
7159  (void) SpliceImageIntoList(&images,length,clone);
7160  return(images);
7161 }
7162 ␌
7163 /*
7164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7165 % %
7166 % %
7167 % %
7168 % s R G B C o m p a n d o r %
7169 % %
7170 % %
7171 % %
7172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7173 %
7174 % sRGBCompandor() adds the gamma function to a sRGB pixel.
7175 %
7176 % The format of the sRGBCompandor method is:
7177 %
7178 % MagickRealType sRGBCompandor(const MagickRealType pixel)
7179 %
7180 % A description of each parameter follows:
7181 %
7182 % o pixel: the pixel.
7183 %
7184 */
7185 MagickExport MagickRealType sRGBCompandor(const MagickRealType pixel)
7186 {
7187  if (pixel <= (0.0031306684425005883*(double) QuantumRange))
7188  return(12.92*pixel);
7189  return((MagickRealType) QuantumRange*(1.055*pow(QuantumScale*pixel,1.0/2.4)-
7190  0.055));
7191 }
7192 ␌
7193 /*
7194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7195 % %
7196 % %
7197 % %
7198 % S t r i p %
7199 % %
7200 % %
7201 % %
7202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7203 %
7204 % Strip() strips any whitespace or quotes from the beginning and end of a
7205 % string of characters.
7206 %
7207 % The format of the Strip method is:
7208 %
7209 % void Strip(char *message)
7210 %
7211 % A description of each parameter follows:
7212 %
7213 % o message: Specifies an array of characters.
7214 %
7215 */
7216 MagickExport void Strip(char *message)
7217 {
7218  char
7219  *p,
7220  *q;
7221 
7222  assert(message != (char *) NULL);
7223  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
7224  if (*message == '\0')
7225  return;
7226  if (strlen(message) == 1)
7227  return;
7228  p=message;
7229  while (isspace((int) ((unsigned char) *p)) != 0)
7230  p++;
7231  if ((*p == '\'') || (*p == '"'))
7232  p++;
7233  q=message+strlen(message)-1;
7234  while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
7235  q--;
7236  if (q > p)
7237  if ((*q == '\'') || (*q == '"'))
7238  q--;
7239  (void) memcpy(message,p,(size_t) (q-p+1));
7240  message[q-p+1]='\0';
7241 }
7242 ␌
7243 /*
7244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7245 % %
7246 % %
7247 % %
7248 % S y n c C a c h e V i e w %
7249 % %
7250 % %
7251 % %
7252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7253 %
7254 % SyncCacheView() saves the cache view pixels to the in-memory or disk
7255 % cache. It returns MagickTrue if the pixel region is synced, otherwise
7256 % MagickFalse.
7257 %
7258 % Deprecated, replace with:
7259 %
7260 % SyncCacheViewAuthenticPixels(cache_view,GetCacheViewException(cache_view));
7261 %
7262 % The format of the SyncCacheView method is:
7263 %
7264 % MagickBooleanType SyncCacheView(CacheView *cache_view)
7265 %
7266 % A description of each parameter follows:
7267 %
7268 % o cache_view: the cache view.
7269 %
7270 */
7271 MagickExport MagickBooleanType SyncCacheView(CacheView *cache_view)
7272 {
7273  MagickBooleanType
7274  status;
7275 
7276  status=SyncCacheViewAuthenticPixels(cache_view,
7277  GetCacheViewException(cache_view));
7278  return(status);
7279 }
7280 ␌
7281 /*
7282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7283 % %
7284 % %
7285 % %
7286 % S y n c C a c h e V i e w P i x e l s %
7287 % %
7288 % %
7289 % %
7290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7291 %
7292 % SyncCacheViewPixels() saves the cache view pixels to the in-memory
7293 % or disk cache. It returns MagickTrue if the pixel region is flushed,
7294 % otherwise MagickFalse.
7295 %
7296 % Deprecated, replace with:
7297 %
7298 % SyncCacheViewAuthenticPixels(cache_view,GetCacheViewException(cache_view));
7299 %
7300 % The format of the SyncCacheViewPixels method is:
7301 %
7302 % MagickBooleanType SyncCacheViewPixels(CacheView *cache_view)
7303 %
7304 % A description of each parameter follows:
7305 %
7306 % o cache_view: the cache view.
7307 %
7308 % o exception: return any errors or warnings in this structure.
7309 %
7310 */
7311 MagickExport MagickBooleanType SyncCacheViewPixels(CacheView *cache_view)
7312 {
7313  MagickBooleanType
7314  status;
7315 
7316  status=SyncCacheViewAuthenticPixels(cache_view,
7317  GetCacheViewException(cache_view));
7318  return(status);
7319 }
7320 ␌
7321 /*
7322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7323 % %
7324 % %
7325 % %
7326 % S y n c I m a g e P i x e l s %
7327 % %
7328 % %
7329 % %
7330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7331 %
7332 % SyncImagePixels() saves the image pixels to the in-memory or disk cache.
7333 % The method returns MagickTrue if the pixel region is synced, otherwise
7334 % MagickFalse.
7335 %
7336 % Deprecated, replace with:
7337 %
7338 % SyncAuthenticPixels(image,&image->exception);
7339 %
7340 % The format of the SyncImagePixels() method is:
7341 %
7342 % MagickBooleanType SyncImagePixels(Image *image)
7343 %
7344 % A description of each parameter follows:
7345 %
7346 % o image: the image.
7347 %
7348 */
7349 MagickExport MagickBooleanType SyncImagePixels(Image *image)
7350 {
7351  return(SyncAuthenticPixels(image,&image->exception));
7352 }
7353 ␌
7354 /*
7355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7356 % %
7357 % %
7358 % %
7359 % S y s t e m C o m m a n d %
7360 % %
7361 % %
7362 % %
7363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7364 %
7365 % SystemCommand() executes the specified command and waits until it
7366 % terminates. The returned value is the exit status of the command.
7367 %
7368 % The format of the SystemCommand method is:
7369 %
7370 % int SystemCommand(const MagickBooleanType asynchronous,
7371 % const MagickBooleanType verbose,const char *command,
7372 % ExceptionInfo *exception)
7373 %
7374 % A description of each parameter follows:
7375 %
7376 % o asynchronous: a value other than 0 executes the parent program
7377 % concurrently with the new child process.
7378 %
7379 % o verbose: a value other than 0 prints the executed command before it is
7380 % invoked.
7381 %
7382 % o command: this string is the command to execute.
7383 %
7384 % o exception: return any errors here.
7385 %
7386 */
7387 MagickExport int SystemCommand(const MagickBooleanType asynchronous,
7388  const MagickBooleanType verbose,const char *command,ExceptionInfo *exception)
7389 {
7390  int
7391  status;
7392 
7393  status=ExternalDelegateCommand(asynchronous,verbose,command,(char *) NULL,
7394  exception);
7395  return(status);
7396 }
7397 ␌
7398 /*
7399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7400 % %
7401 % %
7402 % %
7403 % T e m p o r a r y F i l e n a m e %
7404 % %
7405 % %
7406 % %
7407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7408 %
7409 % TemporaryFilename() replaces the contents of path by a unique path name.
7410 %
7411 % The format of the TemporaryFilename method is:
7412 %
7413 % void TemporaryFilename(char *path)
7414 %
7415 % A description of each parameter follows.
7416 %
7417 % o path: Specifies a pointer to an array of characters. The unique path
7418 % name is returned in this array.
7419 %
7420 */
7421 MagickExport void TemporaryFilename(char *path)
7422 {
7423  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.6");
7424  (void) AcquireUniqueFilename(path);
7425  (void) RelinquishUniqueFileResource(path);
7426 }
7427 ␌
7428 /*
7429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7430 % %
7431 % %
7432 % %
7433 % T h r e s h o l d I m a g e %
7434 % %
7435 % %
7436 % %
7437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7438 %
7439 % ThresholdImage() changes the value of individual pixels based on
7440 % the intensity of each pixel compared to threshold. The result is a
7441 % high-contrast, two color image.
7442 %
7443 % The format of the ThresholdImage method is:
7444 %
7445 % unsigned int ThresholdImage(Image *image,const double threshold)
7446 %
7447 % A description of each parameter follows:
7448 %
7449 % o image: the image.
7450 %
7451 % o threshold: Define the threshold value
7452 %
7453 */
7454 MagickExport unsigned int ThresholdImage(Image *image,const double threshold)
7455 {
7456 #define ThresholdImageTag "Threshold/Image"
7457 
7458  IndexPacket
7459  index;
7460 
7461  ssize_t
7462  y;
7463 
7464  /*
7465  Threshold image.
7466  */
7467  assert(image != (Image *) NULL);
7468  assert(image->signature == MagickCoreSignature);
7469  if (IsEventLogging() != MagickFalse)
7470  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7471  if (IsEventLogging() != MagickFalse)
7472  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.7");
7473  if (!AcquireImageColormap(image,2))
7474  ThrowBinaryImageException(ResourceLimitError,"MemoryAllocationFailed",
7475  "UnableToThresholdImage");
7476  for (y=0; y < (ssize_t) image->rows; y++)
7477  {
7478  IndexPacket
7479  *magick_restrict indexes;
7480 
7481  ssize_t
7482  x;
7483 
7484  PixelPacket
7485  *magick_restrict q;
7486 
7487  q=GetAuthenticPixels(image,0,y,image->columns,1,&image->exception);
7488  if (q == (PixelPacket *) NULL)
7489  break;
7490  indexes=GetAuthenticIndexQueue(image);
7491  for (x=0; x < (ssize_t) image->columns; x++)
7492  {
7493  index=(IndexPacket) (GetPixelIntensity(image,q) <=
7494  threshold ? 0 : 1);
7495  SetPixelIndex(indexes+x,index);
7496  SetPixelRGBO(q,image->colormap+(ssize_t) index);
7497  q++;
7498  }
7499  if (!SyncAuthenticPixels(image,&image->exception))
7500  break;
7501  }
7502  return(MagickTrue);
7503 }
7504 ␌
7505 /*
7506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7507 % %
7508 % %
7509 % %
7510 % T h r e s h o l d I m a g e C h a n n e l %
7511 % %
7512 % %
7513 % %
7514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7515 %
7516 % ThresholdImageChannel() changes the value of individual pixels based on
7517 % the intensity of each pixel channel. The result is a high-contrast image.
7518 %
7519 % The format of the ThresholdImageChannel method is:
7520 %
7521 % unsigned int ThresholdImageChannel(Image *image,const char *threshold)
7522 %
7523 % A description of each parameter follows:
7524 %
7525 % o image: the image.
7526 %
7527 % o threshold: define the threshold values.
7528 %
7529 */
7530 MagickExport unsigned int ThresholdImageChannel(Image *image,
7531  const char *threshold)
7532 {
7533 #define ThresholdImageTag "Threshold/Image"
7534 
7536  pixel;
7537 
7538  GeometryInfo
7539  geometry_info;
7540 
7541  IndexPacket
7542  index;
7543 
7544  ssize_t
7545  y;
7546 
7547  unsigned int
7548  flags;
7549 
7550  /*
7551  Threshold image.
7552  */
7553  assert(image != (Image *) NULL);
7554  assert(image->signature == MagickCoreSignature);
7555  if (IsEventLogging() != MagickFalse)
7556  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7557  if (threshold == (const char *) NULL)
7558  return(MagickTrue);
7559  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
7560  return(MagickFalse);
7561  GetMagickPixelPacket(image,&pixel);
7562  flags=ParseGeometry(threshold,&geometry_info);
7563  pixel.red=geometry_info.rho;
7564  if (flags & SigmaValue)
7565  pixel.green=geometry_info.sigma;
7566  else
7567  pixel.green=pixel.red;
7568  if (flags & XiValue)
7569  pixel.blue=geometry_info.xi;
7570  else
7571  pixel.blue=pixel.red;
7572  if (flags & PsiValue)
7573  pixel.opacity=geometry_info.psi;
7574  else
7575  pixel.opacity=(MagickRealType) OpaqueOpacity;
7576  if (flags & PercentValue)
7577  {
7578  pixel.red*=(MagickRealType) QuantumRange/100.0;
7579  pixel.green*=(MagickRealType) QuantumRange/100.0;
7580  pixel.blue*=(MagickRealType) QuantumRange/100.0;
7581  pixel.opacity*=(MagickRealType) QuantumRange/100.0;
7582  }
7583  if (!(flags & SigmaValue))
7584  {
7585  if (!AcquireImageColormap(image,2))
7586  ThrowBinaryImageException(ResourceLimitError,"MemoryAllocationFailed",
7587  "UnableToThresholdImage");
7588  if (pixel.red == 0)
7589  (void) GetImageDynamicThreshold(image,2.0,2.0,&pixel,&image->exception);
7590  }
7591  for (y=0; y < (ssize_t) image->rows; y++)
7592  {
7593  IndexPacket
7594  *magick_restrict indexes;
7595 
7596  ssize_t
7597  x;
7598 
7599  PixelPacket
7600  *magick_restrict q;
7601 
7602  q=GetAuthenticPixels(image,0,y,image->columns,1,&image->exception);
7603  if (q == (PixelPacket *) NULL)
7604  break;
7605  indexes=GetAuthenticIndexQueue(image);
7606  if (IsMagickGray(&pixel) != MagickFalse)
7607  for (x=0; x < (ssize_t) image->columns; x++)
7608  {
7609  index=(IndexPacket) (GetPixelIntensity(image,q) <= pixel.red ? 0 : 1);
7610  SetPixelIndex(indexes+x,index);
7611  SetPixelRed(q,image->colormap[(ssize_t) index].red);
7612  SetPixelGreen(q,image->colormap[(ssize_t) index].green);
7613  SetPixelBlue(q,image->colormap[(ssize_t) index].blue);
7614  q++;
7615  }
7616  else
7617  for (x=0; x < (ssize_t) image->columns; x++)
7618  {
7619  SetPixelRed(q,(MagickRealType) q->red <= pixel.red
7620  ? 0 : QuantumRange);
7621  SetPixelGreen(q,(MagickRealType) q->green <= pixel.green
7622  ? 0 : QuantumRange);
7623  SetPixelBlue(q,(MagickRealType) q->blue <= pixel.blue
7624  ? 0 : QuantumRange);
7625  SetPixelOpacity(q,(MagickRealType) q->opacity <= pixel.opacity
7626  ? 0 : QuantumRange);
7627  q++;
7628  }
7629  if (!SyncAuthenticPixels(image,&image->exception))
7630  break;
7631  }
7632  return(MagickTrue);
7633 }
7634 ␌
7635 /*
7636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7637 % %
7638 % %
7639 % %
7640 + T r a n s f o r m C o l o r s p a c e %
7641 % %
7642 % %
7643 % %
7644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7645 %
7646 % TransformColorspace() converts the image to a specified colorspace.
7647 % If the image is already in the requested colorspace, no work is performed.
7648 % Note that the current colorspace is stored in the image colorspace member.
7649 % The transformation matrices are not necessarily the standard ones: the
7650 % weights are rescaled to normalize the range of the transformed values to
7651 % be [0..QuantumRange].
7652 %
7653 % Deprecated, replace with:
7654 %
7655 % TransformImageColorspace(image,colorspace);
7656 %
7657 % The format of the TransformColorspace method is:
7658 %
7659 % unsigned int (void) TransformColorspace(Image *image,
7660 % const ColorspaceType colorspace)
7661 %
7662 % A description of each parameter follows:
7663 %
7664 % o image: the image to transform
7665 %
7666 % o colorspace: the desired colorspace.
7667 %
7668 */
7669 MagickExport unsigned int TransformColorspace(Image *image,
7670  const ColorspaceType colorspace)
7671 {
7672  assert(image != (Image *) NULL);
7673  assert(image->signature == MagickCoreSignature);
7674  if (IsEventLogging() != MagickFalse)
7675  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.6");
7676  return(TransformImageColorspace(image,colorspace));
7677 }
7678 ␌
7679 /*
7680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7681 % %
7682 % %
7683 % %
7684 % T r a n s f o r m H S L %
7685 % %
7686 % %
7687 % %
7688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7689 %
7690 % TransformHSL() converts a (red, green, blue) to a (hue, saturation,
7691 % lightness) triple.
7692 %
7693 % The format of the TransformHSL method is:
7694 %
7695 % void TransformHSL(const Quantum red,const Quantum green,
7696 % const Quantum blue,double *hue,double *saturation,double *lightness)
7697 %
7698 % A description of each parameter follows:
7699 %
7700 % o red, green, blue: A Quantum value representing the red, green, and
7701 % blue component of a pixel..
7702 %
7703 % o hue, saturation, lightness: A pointer to a double value representing a
7704 % component of the HSL color space.
7705 %
7706 */
7707 MagickExport void TransformHSL(const Quantum red,const Quantum green,
7708  const Quantum blue,double *hue,double *saturation,double *lightness)
7709 {
7710  MagickRealType
7711  b,
7712  delta,
7713  g,
7714  max,
7715  min,
7716  r;
7717 
7718  /*
7719  Convert RGB to HSL colorspace.
7720  */
7721  assert(hue != (double *) NULL);
7722  assert(saturation != (double *) NULL);
7723  assert(lightness != (double *) NULL);
7724  r=QuantumScale*(MagickRealType) red;
7725  g=QuantumScale*(MagickRealType) green;
7726  b=QuantumScale*(MagickRealType) blue;
7727  max=MagickMax(r,MagickMax(g,b));
7728  min=MagickMin(r,MagickMin(g,b));
7729  *hue=0.0;
7730  *saturation=0.0;
7731  *lightness=(double) ((min+max)/2.0);
7732  delta=max-min;
7733  if (delta == 0.0)
7734  return;
7735  *saturation=(double) (delta/((*lightness < 0.5) ? (min+max) :
7736  (2.0-max-min)));
7737  if (r == max)
7738  *hue=(double) (g == min ? 5.0+(max-b)/delta : 1.0-(max-g)/delta);
7739  else
7740  if (g == max)
7741  *hue=(double) (b == min ? 1.0+(max-r)/delta : 3.0-(max-b)/delta);
7742  else
7743  *hue=(double) (r == min ? 3.0+(max-g)/delta : 5.0-(max-r)/delta);
7744  *hue/=6.0;
7745 }
7746 ␌
7747 /*
7748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7749 % %
7750 % %
7751 % %
7752 % T r a n s l a t e T e x t %
7753 % %
7754 % %
7755 % %
7756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7757 %
7758 % TranslateText() replaces any embedded formatting characters with the
7759 % appropriate image attribute and returns the translated text.
7760 %
7761 % Deprecated, replace with:
7762 %
7763 % InterpretImageProperties(image_info,image,embed_text);
7764 %
7765 % The format of the TranslateText method is:
7766 %
7767 % char *TranslateText(const ImageInfo *image_info,Image *image,
7768 % const char *embed_text)
7769 %
7770 % A description of each parameter follows:
7771 %
7772 % o image_info: the image info.
7773 %
7774 % o image: the image.
7775 %
7776 % o embed_text: the address of a character string containing the embedded
7777 % formatting characters.
7778 %
7779 */
7780 MagickExport char *TranslateText(const ImageInfo *image_info,Image *image,
7781  const char *embed_text)
7782 {
7783  assert(image != (Image *) NULL);
7784  assert(image->signature == MagickCoreSignature);
7785  if (IsEventLogging() != MagickFalse)
7786  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.2.6");
7787  return(InterpretImageProperties(image_info,image,embed_text));
7788 }
7789 ␌
7790 /*
7791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7792 % %
7793 % %
7794 % %
7795 % T r a n s p a r e n t I m a g e %
7796 % %
7797 % %
7798 % %
7799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7800 %
7801 % TransparentImage() changes the opacity value associated with any pixel
7802 % that matches color to the value defined by opacity.
7803 %
7804 % By default color must match a particular pixel color exactly. However,
7805 % in many cases two colors may differ by a small amount. Fuzz defines
7806 % how much tolerance is acceptable to consider two colors as the same.
7807 % For example, set fuzz to 10 and the color red at intensities of 100 and
7808 % 102 respectively are now interpreted as the same color.
7809 %
7810 % The format of the TransparentImage method is:
7811 %
7812 % MagickBooleanType TransparentImage(Image *image,
7813 % const PixelPacket target,const Quantum opacity)
7814 %
7815 % A description of each parameter follows:
7816 %
7817 % o image: the image.
7818 %
7819 % o target: the RGB value of the target color.
7820 %
7821 % o opacity: the replacement opacity value.
7822 %
7823 */
7824 MagickExport MagickBooleanType TransparentImage(Image *image,
7825  const PixelPacket target,const Quantum opacity)
7826 {
7827 #define TransparentImageTag "Transparent/Image"
7828 
7829  MagickBooleanType
7830  proceed;
7831 
7832  ssize_t
7833  y;
7834 
7835  /*
7836  Make image color transparent.
7837  */
7838  assert(image != (Image *) NULL);
7839  assert(image->signature == MagickCoreSignature);
7840  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v6.1.0");
7841  if (IsEventLogging() != MagickFalse)
7842  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7843  if (image->matte == MagickFalse)
7844  (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
7845  for (y=0; y < (ssize_t) image->rows; y++)
7846  {
7847  ssize_t
7848  x;
7849 
7850  PixelPacket
7851  *magick_restrict q;
7852 
7853  q=GetAuthenticPixels(image,0,y,image->columns,1,&image->exception);
7854  if (q == (PixelPacket *) NULL)
7855  break;
7856  for (x=0; x < (ssize_t) image->columns; x++)
7857  {
7858  if (IsColorSimilar(image,q,&target) != MagickFalse)
7859  q->opacity=opacity;
7860  q++;
7861  }
7862  if (SyncAuthenticPixels(image,&image->exception) == MagickFalse)
7863  break;
7864  proceed=SetImageProgress(image,TransparentImageTag,(MagickOffsetType) y,
7865  image->rows);
7866  if (proceed == MagickFalse)
7867  break;
7868  }
7869  return(MagickTrue);
7870 }
7871 ␌
7872 /*
7873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7874 % %
7875 % %
7876 % %
7877 % U n s h i f t I m a g e L i s t %
7878 % %
7879 % %
7880 % %
7881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7882 %
7883 % UnshiftImageList() adds the image to the beginning of the list.
7884 %
7885 % Deprecated, replace with:
7886 %
7887 % PrependImageToList(images,CloneImageList(image,exception));
7888 %
7889 % The format of the UnshiftImageList method is:
7890 %
7891 % unsigned int UnshiftImageList(Image *images,const Image *image,
7892 % ExceptionInfo *exception)
7893 %
7894 % A description of each parameter follows:
7895 %
7896 % o images: the image list.
7897 %
7898 % o image: the image.
7899 %
7900 % o exception: return any errors or warnings in this structure.
7901 %
7902 */
7903 MagickExport unsigned int UnshiftImageList(Image **images,const Image *image,
7904  ExceptionInfo *exception)
7905 {
7906  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.5.2");
7907  PrependImageToList(images,CloneImageList(image,exception));
7908  return(MagickTrue);
7909 }
7910 ␌
7911 /*
7912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7913 % %
7914 % %
7915 % %
7916 + V a l i d a t e C o l o r m a p I n d e x %
7917 % %
7918 % %
7919 % %
7920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7921 %
7922 % ValidateColormapIndex() validates the colormap index. If the index does
7923 % not range from 0 to the number of colors in the colormap an exception
7924 % issued and 0 is returned.
7925 %
7926 % Deprecated, replace with:
7927 %
7928 % ConstrainColormapIndex(image,index);
7929 %
7930 % The format of the ValidateColormapIndex method is:
7931 %
7932 % IndexPacket ValidateColormapIndex(Image *image,const unsigned int index)
7933 %
7934 % A description of each parameter follows:
7935 %
7936 % o index: Method ValidateColormapIndex returns colormap index if it is
7937 % valid other an exception issued and 0 is returned.
7938 %
7939 % o image: the image.
7940 %
7941 % o index: This integer is the colormap index.
7942 %
7943 */
7944 MagickExport IndexPacket ValidateColormapIndex(Image *image,
7945  const size_t index)
7946 {
7947  if (IsEventLogging() != MagickFalse)
7948  (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),"last use: v5.4.4");
7949  return(ConstrainColormapIndex(image,index));
7950 }
7951 ␌
7952 /*
7953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7954 % %
7955 % %
7956 % %
7957 % Z o o m I m a g e %
7958 % %
7959 % %
7960 % %
7961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7962 %
7963 % ZoomImage() creates a new image that is a scaled size of an existing one.
7964 % It allocates the memory necessary for the new Image structure and returns a
7965 % pointer to the new image. The Point filter gives fast pixel replication,
7966 % Triangle is equivalent to bi-linear interpolation, and Mitchel giver slower,
7967 % very high-quality results. See Graphic Gems III for details on this
7968 % algorithm.
7969 %
7970 % The filter member of the Image structure specifies which image filter to
7971 % use. Blur specifies the blur factor where > 1 is blurry, < 1 is sharp.
7972 %
7973 % The format of the ZoomImage method is:
7974 %
7975 % Image *ZoomImage(const Image *image,const size_t columns,
7976 % const size_t rows,ExceptionInfo *exception)
7977 %
7978 % A description of each parameter follows:
7979 %
7980 % o image: the image.
7981 %
7982 % o columns: An integer that specifies the number of columns in the zoom
7983 % image.
7984 %
7985 % o rows: An integer that specifies the number of rows in the scaled
7986 % image.
7987 %
7988 % o exception: return any errors or warnings in this structure.
7989 %
7990 */
7991 MagickExport Image *ZoomImage(const Image *image,const size_t columns,
7992  const size_t rows,ExceptionInfo *exception)
7993 {
7994  Image
7995  *zoom_image;
7996 
7997  assert(image != (const Image *) NULL);
7998  assert(image->signature == MagickCoreSignature);
7999  assert(exception != (ExceptionInfo *) NULL);
8000  assert(exception->signature == MagickCoreSignature);
8001  if (IsEventLogging() != MagickFalse)
8002  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8003  zoom_image=ResizeImage(image,columns,rows,image->filter,image->blur,
8004  exception);
8005  return(zoom_image);
8006 }
8007 #endif
Definition: image.h:134