MagickCore  7.0.7
Convert, Edit, Or Compose Bitmap Images
attribute.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % AAA TTTTT TTTTT RRRR IIIII BBBB U U TTTTT EEEEE %
7 % A A T T R R I B B U U T E %
8 % AAAAA T T RRRR I BBBB U U T EEE %
9 % A A T T R R I B B U U T E %
10 % A A T T R R IIIII BBBB UUU T EEEEE %
11 % %
12 % %
13 % MagickCore Get / Set Image Attributes %
14 % %
15 % Software Design %
16 % Cristy %
17 % October 2002 %
18 % %
19 % %
20 % Copyright 1999-2018 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://www.imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39 
40 /*
41  Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/artifact.h"
45 #include "MagickCore/attribute.h"
46 #include "MagickCore/blob.h"
48 #include "MagickCore/cache.h"
50 #include "MagickCore/cache-view.h"
51 #include "MagickCore/channel.h"
52 #include "MagickCore/client.h"
53 #include "MagickCore/color.h"
55 #include "MagickCore/colormap.h"
57 #include "MagickCore/colorspace.h"
59 #include "MagickCore/composite.h"
61 #include "MagickCore/constitute.h"
62 #include "MagickCore/draw.h"
64 #include "MagickCore/effect.h"
65 #include "MagickCore/enhance.h"
66 #include "MagickCore/exception.h"
68 #include "MagickCore/geometry.h"
69 #include "MagickCore/histogram.h"
70 #include "MagickCore/identify.h"
71 #include "MagickCore/image.h"
73 #include "MagickCore/list.h"
74 #include "MagickCore/log.h"
75 #include "MagickCore/memory_.h"
76 #include "MagickCore/magick.h"
77 #include "MagickCore/monitor.h"
79 #include "MagickCore/option.h"
80 #include "MagickCore/paint.h"
81 #include "MagickCore/pixel.h"
83 #include "MagickCore/property.h"
84 #include "MagickCore/quantize.h"
86 #include "MagickCore/random_.h"
87 #include "MagickCore/resource_.h"
88 #include "MagickCore/semaphore.h"
89 #include "MagickCore/segment.h"
90 #include "MagickCore/splay-tree.h"
91 #include "MagickCore/string_.h"
93 #include "MagickCore/threshold.h"
94 #include "MagickCore/transform.h"
95 #include "MagickCore/utility.h"
96 
97 /*
98 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99 % %
100 % %
101 % %
102 + G e t I m a g e B o u n d i n g B o x %
103 % %
104 % %
105 % %
106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107 %
108 % GetImageBoundingBox() returns the bounding box of an image canvas.
109 %
110 % The format of the GetImageBoundingBox method is:
111 %
112 % RectangleInfo GetImageBoundingBox(const Image *image,
113 % ExceptionInfo *exception)
114 %
115 % A description of each parameter follows:
116 %
117 % o bounds: Method GetImageBoundingBox returns the bounding box of an
118 % image canvas.
119 %
120 % o image: the image.
121 %
122 % o exception: return any errors or warnings in this structure.
123 %
124 */
126  ExceptionInfo *exception)
127 {
128  CacheView
129  *image_view;
130 
132  status;
133 
134  PixelInfo
135  target[3],
136  zero;
137 
139  bounds;
140 
141  register const Quantum
142  *r;
143 
144  ssize_t
145  y;
146 
147  assert(image != (Image *) NULL);
148  assert(image->signature == MagickCoreSignature);
149  if (image->debug != MagickFalse)
150  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
151  bounds.width=0;
152  bounds.height=0;
153  bounds.x=(ssize_t) image->columns;
154  bounds.y=(ssize_t) image->rows;
155  GetPixelInfo(image,&target[0]);
156  image_view=AcquireVirtualCacheView(image,exception);
157  r=GetCacheViewVirtualPixels(image_view,0,0,1,1,exception);
158  if (r == (const Quantum *) NULL)
159  {
160  image_view=DestroyCacheView(image_view);
161  return(bounds);
162  }
163  GetPixelInfoPixel(image,r,&target[0]);
164  GetPixelInfo(image,&target[1]);
165  r=GetCacheViewVirtualPixels(image_view,(ssize_t) image->columns-1,0,1,1,
166  exception);
167  if (r != (const Quantum *) NULL)
168  GetPixelInfoPixel(image,r,&target[1]);
169  GetPixelInfo(image,&target[2]);
170  r=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-1,1,1,
171  exception);
172  if (r != (const Quantum *) NULL)
173  GetPixelInfoPixel(image,r,&target[2]);
174  status=MagickTrue;
175  GetPixelInfo(image,&zero);
176 #if defined(MAGICKCORE_OPENMP_SUPPORT)
177  #pragma omp parallel for schedule(static,4) shared(status) \
178  magick_number_threads(image,image,image->rows,1)
179 #endif
180  for (y=0; y < (ssize_t) image->rows; y++)
181  {
182  PixelInfo
183  pixel;
184 
186  bounding_box;
187 
188  register const Quantum
189  *magick_restrict p;
190 
191  register ssize_t
192  x;
193 
194  if (status == MagickFalse)
195  continue;
196 #if defined(MAGICKCORE_OPENMP_SUPPORT)
197 # pragma omp critical (MagickCore_GetImageBoundingBox)
198 #endif
199  bounding_box=bounds;
200  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
201  if (p == (const Quantum *) NULL)
202  {
203  status=MagickFalse;
204  continue;
205  }
206  pixel=zero;
207  for (x=0; x < (ssize_t) image->columns; x++)
208  {
209  GetPixelInfoPixel(image,p,&pixel);
210  if ((x < bounding_box.x) &&
211  (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse))
212  bounding_box.x=x;
213  if ((x > (ssize_t) bounding_box.width) &&
214  (IsFuzzyEquivalencePixelInfo(&pixel,&target[1]) == MagickFalse))
215  bounding_box.width=(size_t) x;
216  if ((y < bounding_box.y) &&
217  (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse))
218  bounding_box.y=y;
219  if ((y > (ssize_t) bounding_box.height) &&
220  (IsFuzzyEquivalencePixelInfo(&pixel,&target[2]) == MagickFalse))
221  bounding_box.height=(size_t) y;
222  p+=GetPixelChannels(image);
223  }
224 #if defined(MAGICKCORE_OPENMP_SUPPORT)
225 # pragma omp critical (MagickCore_GetImageBoundingBox)
226 #endif
227  {
228  if (bounding_box.x < bounds.x)
229  bounds.x=bounding_box.x;
230  if (bounding_box.y < bounds.y)
231  bounds.y=bounding_box.y;
232  if (bounding_box.width > bounds.width)
233  bounds.width=bounding_box.width;
234  if (bounding_box.height > bounds.height)
235  bounds.height=bounding_box.height;
236  }
237  }
238  image_view=DestroyCacheView(image_view);
239  if ((bounds.width == 0) && (bounds.height == 0))
241  "GeometryDoesNotContainImage","`%s'",image->filename);
242  else
243  {
244  bounds.width-=(bounds.x-1);
245  bounds.height-=(bounds.y-1);
246  }
247  return(bounds);
248 }
249 
250 /*
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 % %
253 % %
254 % %
255 % G e t I m a g e D e p t h %
256 % %
257 % %
258 % %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 %
261 % GetImageDepth() returns the depth of a particular image channel.
262 %
263 % The format of the GetImageDepth method is:
264 %
265 % size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
266 %
267 % A description of each parameter follows:
268 %
269 % o image: the image.
270 %
271 % o exception: return any errors or warnings in this structure.
272 %
273 */
274 MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
275 {
276  CacheView
277  *image_view;
278 
280  status;
281 
282  register ssize_t
283  i;
284 
285  size_t
286  *current_depth,
287  depth,
288  number_threads;
289 
290  ssize_t
291  y;
292 
293  /*
294  Compute image depth.
295  */
296  assert(image != (Image *) NULL);
297  assert(image->signature == MagickCoreSignature);
298  if (image->debug != MagickFalse)
299  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
300  number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
301  current_depth=(size_t *) AcquireQuantumMemory(number_threads,
302  sizeof(*current_depth));
303  if (current_depth == (size_t *) NULL)
304  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
305  status=MagickTrue;
306  for (i=0; i < (ssize_t) number_threads; i++)
307  current_depth[i]=1;
308  if ((image->storage_class == PseudoClass) &&
309  (image->alpha_trait == UndefinedPixelTrait))
310  {
311  for (i=0; i < (ssize_t) image->colors; i++)
312  {
313  const int
314  id = GetOpenMPThreadId();
315 
316  while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
317  {
319  atDepth;
320 
321  QuantumAny
322  range;
323 
324  atDepth=MagickTrue;
325  range=GetQuantumRange(current_depth[id]);
326  if ((atDepth != MagickFalse) &&
327  (GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
328  if (IsPixelAtDepth(ClampToQuantum(image->colormap[i].red),range) == MagickFalse)
329  atDepth=MagickFalse;
330  if ((atDepth != MagickFalse) &&
331  (GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
332  if (IsPixelAtDepth(ClampToQuantum(image->colormap[i].green),range) == MagickFalse)
333  atDepth=MagickFalse;
334  if ((atDepth != MagickFalse) &&
335  (GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
336  if (IsPixelAtDepth(ClampToQuantum(image->colormap[i].blue),range) == MagickFalse)
337  atDepth=MagickFalse;
338  if ((atDepth != MagickFalse))
339  break;
340  current_depth[id]++;
341  }
342  }
343  depth=current_depth[0];
344  for (i=1; i < (ssize_t) number_threads; i++)
345  if (depth < current_depth[i])
346  depth=current_depth[i];
347  current_depth=(size_t *) RelinquishMagickMemory(current_depth);
348  return(depth);
349  }
350  image_view=AcquireVirtualCacheView(image,exception);
351 #if !defined(MAGICKCORE_HDRI_SUPPORT)
352  if ((1UL*QuantumRange) <= MaxMap)
353  {
354  size_t
355  *depth_map;
356 
357  /*
358  Scale pixels to desired (optimized with depth map).
359  */
360  depth_map=(size_t *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
361  if (depth_map == (size_t *) NULL)
362  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
363  for (i=0; i <= (ssize_t) MaxMap; i++)
364  {
365  unsigned int
366  depth;
367 
368  for (depth=1; depth < MAGICKCORE_QUANTUM_DEPTH; depth++)
369  {
370  Quantum
371  pixel;
372 
373  QuantumAny
374  range;
375 
376  range=GetQuantumRange(depth);
377  pixel=(Quantum) i;
378  if (pixel == ScaleAnyToQuantum(ScaleQuantumToAny(pixel,range),range))
379  break;
380  }
381  depth_map[i]=depth;
382  }
383 #if defined(MAGICKCORE_OPENMP_SUPPORT)
384  #pragma omp parallel for schedule(static,4) shared(status) \
385  magick_number_threads(image,image,image->rows,1)
386 #endif
387  for (y=0; y < (ssize_t) image->rows; y++)
388  {
389  const int
390  id = GetOpenMPThreadId();
391 
392  register const Quantum
393  *magick_restrict p;
394 
395  register ssize_t
396  x;
397 
398  if (status == MagickFalse)
399  continue;
400  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
401  if (p == (const Quantum *) NULL)
402  continue;
403  for (x=0; x < (ssize_t) image->columns; x++)
404  {
405  register ssize_t
406  i;
407 
408  if (GetPixelWriteMask(image,p) <= (QuantumRange/2))
409  {
410  p+=GetPixelChannels(image);
411  continue;
412  }
413  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
414  {
415  PixelChannel channel = GetPixelChannelChannel(image,i);
416  PixelTrait traits = GetPixelChannelTraits(image,channel);
417  if ((traits == UndefinedPixelTrait) ||
418  (channel == IndexPixelChannel) ||
419  (channel == ReadMaskPixelChannel) ||
420  (channel == MetaPixelChannel))
421  continue;
422  if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id])
423  current_depth[id]=depth_map[ScaleQuantumToMap(p[i])];
424  }
425  p+=GetPixelChannels(image);
426  }
427  if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
428  status=MagickFalse;
429  }
430  image_view=DestroyCacheView(image_view);
431  depth=current_depth[0];
432  for (i=1; i < (ssize_t) number_threads; i++)
433  if (depth < current_depth[i])
434  depth=current_depth[i];
435  depth_map=(size_t *) RelinquishMagickMemory(depth_map);
436  current_depth=(size_t *) RelinquishMagickMemory(current_depth);
437  return(depth);
438  }
439 #endif
440  /*
441  Compute pixel depth.
442  */
443 #if defined(MAGICKCORE_OPENMP_SUPPORT)
444  #pragma omp parallel for schedule(static,4) shared(status) \
445  magick_number_threads(image,image,image->rows,1)
446 #endif
447  for (y=0; y < (ssize_t) image->rows; y++)
448  {
449  const int
450  id = GetOpenMPThreadId();
451 
452  register const Quantum
453  *magick_restrict p;
454 
455  register ssize_t
456  x;
457 
458  if (status == MagickFalse)
459  continue;
460  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
461  if (p == (const Quantum *) NULL)
462  continue;
463  for (x=0; x < (ssize_t) image->columns; x++)
464  {
465  register ssize_t
466  i;
467 
468  if (GetPixelWriteMask(image,p) <= (QuantumRange/2))
469  {
470  p+=GetPixelChannels(image);
471  continue;
472  }
473  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
474  {
476  channel;
477 
478  PixelTrait
479  traits;
480 
481  channel=GetPixelChannelChannel(image,i);
482  traits=GetPixelChannelTraits(image,channel);
483  if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
484  (channel == ReadMaskPixelChannel))
485  continue;
486  while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
487  {
488  QuantumAny
489  range;
490 
491  range=GetQuantumRange(current_depth[id]);
492  if (p[i] == ScaleAnyToQuantum(ScaleQuantumToAny(p[i],range),range))
493  break;
494  current_depth[id]++;
495  }
496  }
497  p+=GetPixelChannels(image);
498  }
499  if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
500  status=MagickFalse;
501  }
502  image_view=DestroyCacheView(image_view);
503  depth=current_depth[0];
504  for (i=1; i < (ssize_t) number_threads; i++)
505  if (depth < current_depth[i])
506  depth=current_depth[i];
507  current_depth=(size_t *) RelinquishMagickMemory(current_depth);
508  return(depth);
509 }
510 
511 /*
512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513 % %
514 % %
515 % %
516 % G e t I m a g e Q u a n t u m D e p t h %
517 % %
518 % %
519 % %
520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
521 %
522 % GetImageQuantumDepth() returns the depth of the image rounded to a legal
523 % quantum depth: 8, 16, or 32.
524 %
525 % The format of the GetImageQuantumDepth method is:
526 %
527 % size_t GetImageQuantumDepth(const Image *image,
528 % const MagickBooleanType constrain)
529 %
530 % A description of each parameter follows:
531 %
532 % o image: the image.
533 %
534 % o constrain: A value other than MagickFalse, constrains the depth to
535 % a maximum of MAGICKCORE_QUANTUM_DEPTH.
536 %
537 */
539  const MagickBooleanType constrain)
540 {
541  size_t
542  depth;
543 
544  depth=image->depth;
545  if (depth <= 8)
546  depth=8;
547  else
548  if (depth <= 16)
549  depth=16;
550  else
551  if (depth <= 32)
552  depth=32;
553  else
554  if (depth <= 64)
555  depth=64;
556  if (constrain != MagickFalse)
557  depth=(size_t) MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH);
558  return(depth);
559 }
560 
561 /*
562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
563 % %
564 % %
565 % %
566 % G e t I m a g e T y p e %
567 % %
568 % %
569 % %
570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
571 %
572 % GetImageType() returns the type of image:
573 %
574 % Bilevel Grayscale GrayscaleMatte
575 % Palette PaletteMatte TrueColor
576 % TrueColorMatte ColorSeparation ColorSeparationMatte
577 %
578 % The format of the GetImageType method is:
579 %
580 % ImageType GetImageType(const Image *image)
581 %
582 % A description of each parameter follows:
583 %
584 % o image: the image.
585 %
586 */
588 {
589  assert(image != (Image *) NULL);
590  assert(image->signature == MagickCoreSignature);
591  if (image->colorspace == CMYKColorspace)
592  {
593  if (image->alpha_trait == UndefinedPixelTrait)
594  return(ColorSeparationType);
595  return(ColorSeparationAlphaType);
596  }
597  if (IsImageMonochrome(image) != MagickFalse)
598  return(BilevelType);
599  if (IsImageGray(image) != MagickFalse)
600  {
601  if (image->alpha_trait != UndefinedPixelTrait)
602  return(GrayscaleAlphaType);
603  return(GrayscaleType);
604  }
605  if (IsPaletteImage(image) != MagickFalse)
606  {
607  if (image->alpha_trait != UndefinedPixelTrait)
608  return(PaletteAlphaType);
609  return(PaletteType);
610  }
611  if (image->alpha_trait != UndefinedPixelTrait)
612  return(TrueColorAlphaType);
613  return(TrueColorType);
614 }
615 
616 /*
617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
618 % %
619 % %
620 % %
621 % I d e n t i f y I m a g e G r a y %
622 % %
623 % %
624 % %
625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
626 %
627 % IdentifyImageGray() returns grayscale if all the pixels in the image have
628 % the same red, green, and blue intensities, and bi-level is the intensity is
629 % either 0 or QuantumRange. Otherwise undefined is returned.
630 %
631 % The format of the IdentifyImageGray method is:
632 %
633 % ImageType IdentifyImageGray(const Image *image,ExceptionInfo *exception)
634 %
635 % A description of each parameter follows:
636 %
637 % o image: the image.
638 %
639 % o exception: return any errors or warnings in this structure.
640 %
641 */
643  ExceptionInfo *exception)
644 {
645  CacheView
646  *image_view;
647 
648  ImageType
649  type;
650 
651  register const Quantum
652  *p;
653 
654  register ssize_t
655  x;
656 
657  ssize_t
658  y;
659 
660  assert(image != (Image *) NULL);
661  assert(image->signature == MagickCoreSignature);
662  if (image->debug != MagickFalse)
663  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
664  if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
665  (image->type == GrayscaleAlphaType))
666  return(image->type);
668  return(UndefinedType);
669  type=BilevelType;
670  image_view=AcquireVirtualCacheView(image,exception);
671  for (y=0; y < (ssize_t) image->rows; y++)
672  {
673  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
674  if (p == (const Quantum *) NULL)
675  break;
676  for (x=0; x < (ssize_t) image->columns; x++)
677  {
678  if (IsPixelGray(image,p) == MagickFalse)
679  {
680  type=UndefinedType;
681  break;
682  }
683  if ((type == BilevelType) &&
684  (IsPixelMonochrome(image,p) == MagickFalse))
685  type=GrayscaleType;
686  p+=GetPixelChannels(image);
687  }
688  if (type == UndefinedType)
689  break;
690  }
691  image_view=DestroyCacheView(image_view);
692  if ((type == GrayscaleType) && (image->alpha_trait != UndefinedPixelTrait))
693  type=GrayscaleAlphaType;
694  return(type);
695 }
696 
697 /*
698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
699 % %
700 % %
701 % %
702 % I d e n t i f y I m a g e M o n o c h r o m e %
703 % %
704 % %
705 % %
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 %
708 % IdentifyImageMonochrome() returns MagickTrue if all the pixels in the image
709 % have the same red, green, and blue intensities and the intensity is either
710 % 0 or QuantumRange.
711 %
712 % The format of the IdentifyImageMonochrome method is:
713 %
714 % MagickBooleanType IdentifyImageMonochrome(const Image *image,
715 % ExceptionInfo *exception)
716 %
717 % A description of each parameter follows:
718 %
719 % o image: the image.
720 %
721 % o exception: return any errors or warnings in this structure.
722 %
723 */
725  ExceptionInfo *exception)
726 {
727  CacheView
728  *image_view;
729 
730  ImageType
731  type;
732 
733  register ssize_t
734  x;
735 
736  register const Quantum
737  *p;
738 
739  ssize_t
740  y;
741 
742  assert(image != (Image *) NULL);
743  assert(image->signature == MagickCoreSignature);
744  if (image->debug != MagickFalse)
745  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
746  if (image->type == BilevelType)
747  return(MagickTrue);
749  return(MagickFalse);
750  type=BilevelType;
751  image_view=AcquireVirtualCacheView(image,exception);
752  for (y=0; y < (ssize_t) image->rows; y++)
753  {
754  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
755  if (p == (const Quantum *) NULL)
756  break;
757  for (x=0; x < (ssize_t) image->columns; x++)
758  {
759  if (IsPixelMonochrome(image,p) == MagickFalse)
760  {
761  type=UndefinedType;
762  break;
763  }
764  p+=GetPixelChannels(image);
765  }
766  if (type == UndefinedType)
767  break;
768  }
769  image_view=DestroyCacheView(image_view);
770  if (type == BilevelType)
771  return(MagickTrue);
772  return(MagickFalse);
773 }
774 
775 /*
776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777 % %
778 % %
779 % %
780 % I d e n t i f y I m a g e T y p e %
781 % %
782 % %
783 % %
784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
785 %
786 % IdentifyImageType() returns the potential type of image:
787 %
788 % Bilevel Grayscale GrayscaleMatte
789 % Palette PaletteMatte TrueColor
790 % TrueColorMatte ColorSeparation ColorSeparationMatte
791 %
792 % To ensure the image type matches its potential, use SetImageType():
793 %
794 % (void) SetImageType(image,IdentifyImageType(image,exception),exception);
795 %
796 % The format of the IdentifyImageType method is:
797 %
798 % ImageType IdentifyImageType(const Image *image,ExceptionInfo *exception)
799 %
800 % A description of each parameter follows:
801 %
802 % o image: the image.
803 %
804 % o exception: return any errors or warnings in this structure.
805 %
806 */
808  ExceptionInfo *exception)
809 {
810  assert(image != (Image *) NULL);
811  assert(image->signature == MagickCoreSignature);
812  if (image->debug != MagickFalse)
813  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
814  if (image->colorspace == CMYKColorspace)
815  {
816  if (image->alpha_trait == UndefinedPixelTrait)
817  return(ColorSeparationType);
818  return(ColorSeparationAlphaType);
819  }
820  if (IdentifyImageMonochrome(image,exception) != MagickFalse)
821  return(BilevelType);
822  if (IdentifyImageGray(image,exception) != UndefinedType)
823  {
824  if (image->alpha_trait != UndefinedPixelTrait)
825  return(GrayscaleAlphaType);
826  return(GrayscaleType);
827  }
828  if (IdentifyPaletteImage(image,exception) != MagickFalse)
829  {
830  if (image->alpha_trait != UndefinedPixelTrait)
831  return(PaletteAlphaType);
832  return(PaletteType);
833  }
834  if (image->alpha_trait != UndefinedPixelTrait)
835  return(TrueColorAlphaType);
836  return(TrueColorType);
837 }
838 
839 /*
840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
841 % %
842 % %
843 % %
844 % I s I m a g e G r a y %
845 % %
846 % %
847 % %
848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
849 %
850 % IsImageGray() returns MagickTrue if the type of the image is grayscale or
851 % bi-level.
852 %
853 % The format of the IsImageGray method is:
854 %
855 % MagickBooleanType IsImageGray(const Image *image)
856 %
857 % A description of each parameter follows:
858 %
859 % o image: the image.
860 %
861 */
863 {
864  assert(image != (Image *) NULL);
865  assert(image->signature == MagickCoreSignature);
866  if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
867  (image->type == GrayscaleAlphaType))
868  return(MagickTrue);
869  return(MagickFalse);
870 }
871 
872 /*
873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
874 % %
875 % %
876 % %
877 % I s I m a g e M o n o c h r o m e %
878 % %
879 % %
880 % %
881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
882 %
883 % IsImageMonochrome() returns MagickTrue if type of the image is bi-level.
884 %
885 % The format of the IsImageMonochrome method is:
886 %
887 % MagickBooleanType IsImageMonochrome(const Image *image)
888 %
889 % A description of each parameter follows:
890 %
891 % o image: the image.
892 %
893 */
895 {
896  assert(image != (Image *) NULL);
897  assert(image->signature == MagickCoreSignature);
898  if (image->type == BilevelType)
899  return(MagickTrue);
900  return(MagickFalse);
901 }
902 
903 /*
904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
905 % %
906 % %
907 % %
908 % I s I m a g e O p a q u e %
909 % %
910 % %
911 % %
912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
913 %
914 % IsImageOpaque() returns MagickTrue if none of the pixels in the image have
915 % an alpha value other than OpaqueAlpha (QuantumRange).
916 %
917 % Will return true immediatally is alpha channel is not available.
918 %
919 % The format of the IsImageOpaque method is:
920 %
921 % MagickBooleanType IsImageOpaque(const Image *image,
922 % ExceptionInfo *exception)
923 %
924 % A description of each parameter follows:
925 %
926 % o image: the image.
927 %
928 % o exception: return any errors or warnings in this structure.
929 %
930 */
932  ExceptionInfo *exception)
933 {
934  CacheView
935  *image_view;
936 
937  register const Quantum
938  *p;
939 
940  register ssize_t
941  x;
942 
943  ssize_t
944  y;
945 
946  /*
947  Determine if image is opaque.
948  */
949  assert(image != (Image *) NULL);
950  assert(image->signature == MagickCoreSignature);
951  if (image->debug != MagickFalse)
952  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
953  if (image->alpha_trait == UndefinedPixelTrait)
954  return(MagickTrue);
955  image_view=AcquireVirtualCacheView(image,exception);
956  for (y=0; y < (ssize_t) image->rows; y++)
957  {
958  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
959  if (p == (const Quantum *) NULL)
960  break;
961  for (x=0; x < (ssize_t) image->columns; x++)
962  {
963  if (GetPixelAlpha(image,p) != OpaqueAlpha)
964  break;
965  p+=GetPixelChannels(image);
966  }
967  if (x < (ssize_t) image->columns)
968  break;
969  }
970  image_view=DestroyCacheView(image_view);
971  return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue);
972 }
973 
974 /*
975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
976 % %
977 % %
978 % %
979 % S e t I m a g e D e p t h %
980 % %
981 % %
982 % %
983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
984 %
985 % SetImageDepth() sets the depth of the image.
986 %
987 % The format of the SetImageDepth method is:
988 %
989 % MagickBooleanType SetImageDepth(Image *image,const size_t depth,
990 % ExceptionInfo *exception)
991 %
992 % A description of each parameter follows:
993 %
994 % o image: the image.
995 %
996 % o channel: the channel.
997 %
998 % o depth: the image depth.
999 %
1000 % o exception: return any errors or warnings in this structure.
1001 %
1002 */
1004  const size_t depth,ExceptionInfo *exception)
1005 {
1006  CacheView
1007  *image_view;
1008 
1010  status;
1011 
1012  QuantumAny
1013  range;
1014 
1015  ssize_t
1016  y;
1017 
1018  assert(image != (Image *) NULL);
1019  if (image->debug != MagickFalse)
1020  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1021  assert(image->signature == MagickCoreSignature);
1022  if (depth >= MAGICKCORE_QUANTUM_DEPTH)
1023  {
1024  image->depth=depth;
1025  return(MagickTrue);
1026  }
1027  range=GetQuantumRange(depth);
1028  if (image->storage_class == PseudoClass)
1029  {
1030  register ssize_t
1031  i;
1032 
1033 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1034  #pragma omp parallel for schedule(static,4) shared(status) \
1035  magick_number_threads(image,image,image->colors,1)
1036 #endif
1037  for (i=0; i < (ssize_t) image->colors; i++)
1038  {
1039  if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
1040  image->colormap[i].red=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
1041  ClampPixel(image->colormap[i].red),range),range);
1042  if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
1044  ClampPixel(image->colormap[i].green),range),range);
1045  if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
1046  image->colormap[i].blue=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
1047  ClampPixel(image->colormap[i].blue),range),range);
1048  if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
1050  ClampPixel(image->colormap[i].alpha),range),range);
1051  }
1052  }
1053  status=MagickTrue;
1054  image_view=AcquireAuthenticCacheView(image,exception);
1055 #if !defined(MAGICKCORE_HDRI_SUPPORT)
1056  if ((1UL*QuantumRange) <= MaxMap)
1057  {
1058  Quantum
1059  *depth_map;
1060 
1061  register ssize_t
1062  i;
1063 
1064  /*
1065  Scale pixels to desired (optimized with depth map).
1066  */
1067  depth_map=(Quantum *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
1068  if (depth_map == (Quantum *) NULL)
1069  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1070  for (i=0; i <= (ssize_t) MaxMap; i++)
1071  depth_map[i]=ScaleAnyToQuantum(ScaleQuantumToAny((Quantum) i,range),
1072  range);
1073 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1074  #pragma omp parallel for schedule(static,4) shared(status) \
1075  magick_number_threads(image,image,image->rows,1)
1076 #endif
1077  for (y=0; y < (ssize_t) image->rows; y++)
1078  {
1079  register ssize_t
1080  x;
1081 
1082  register Quantum
1083  *magick_restrict q;
1084 
1085  if (status == MagickFalse)
1086  continue;
1087  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1088  exception);
1089  if (q == (Quantum *) NULL)
1090  {
1091  status=MagickFalse;
1092  continue;
1093  }
1094  for (x=0; x < (ssize_t) image->columns; x++)
1095  {
1096  register ssize_t
1097  i;
1098 
1099  if (GetPixelWriteMask(image,q) <= (QuantumRange/2))
1100  {
1101  q+=GetPixelChannels(image);
1102  continue;
1103  }
1104  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1105  {
1106  PixelChannel
1107  channel;
1108 
1109  PixelTrait
1110  traits;
1111 
1112  channel=GetPixelChannelChannel(image,i);
1113  traits=GetPixelChannelTraits(image,channel);
1114  if ((traits == UndefinedPixelTrait) ||
1115  (channel == IndexPixelChannel) ||
1116  (channel == ReadMaskPixelChannel))
1117  continue;
1118  q[i]=depth_map[ScaleQuantumToMap(q[i])];
1119  }
1120  q+=GetPixelChannels(image);
1121  }
1122  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1123  {
1124  status=MagickFalse;
1125  continue;
1126  }
1127  }
1128  image_view=DestroyCacheView(image_view);
1129  depth_map=(Quantum *) RelinquishMagickMemory(depth_map);
1130  if (status != MagickFalse)
1131  image->depth=depth;
1132  return(status);
1133  }
1134 #endif
1135  /*
1136  Scale pixels to desired depth.
1137  */
1138 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1139  #pragma omp parallel for schedule(static,4) shared(status) \
1140  magick_number_threads(image,image,image->rows,1)
1141 #endif
1142  for (y=0; y < (ssize_t) image->rows; y++)
1143  {
1144  register ssize_t
1145  x;
1146 
1147  register Quantum
1148  *magick_restrict q;
1149 
1150  if (status == MagickFalse)
1151  continue;
1152  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
1153  if (q == (Quantum *) NULL)
1154  {
1155  status=MagickFalse;
1156  continue;
1157  }
1158  for (x=0; x < (ssize_t) image->columns; x++)
1159  {
1160  register ssize_t
1161  i;
1162 
1163  if (GetPixelWriteMask(image,q) <= (QuantumRange/2))
1164  {
1165  q+=GetPixelChannels(image);
1166  continue;
1167  }
1168  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1169  {
1170  PixelChannel
1171  channel;
1172 
1173  PixelTrait
1174  traits;
1175 
1176  channel=GetPixelChannelChannel(image,i);
1177  traits=GetPixelChannelTraits(image,channel);
1178  if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
1179  (channel == ReadMaskPixelChannel))
1180  continue;
1182  q[i]),range),range);
1183  }
1184  q+=GetPixelChannels(image);
1185  }
1186  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1187  {
1188  status=MagickFalse;
1189  continue;
1190  }
1191  }
1192  image_view=DestroyCacheView(image_view);
1193  if (status != MagickFalse)
1194  image->depth=depth;
1195  return(status);
1196 }
1197 
1198 /*
1199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1200 % %
1201 % %
1202 % %
1203 % S e t I m a g e T y p e %
1204 % %
1205 % %
1206 % %
1207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1208 %
1209 % SetImageType() sets the type of image. Choose from these types:
1210 %
1211 % Bilevel Grayscale GrayscaleMatte
1212 % Palette PaletteMatte TrueColor
1213 % TrueColorMatte ColorSeparation ColorSeparationMatte
1214 % OptimizeType
1215 %
1216 % The format of the SetImageType method is:
1217 %
1218 % MagickBooleanType SetImageType(Image *image,const ImageType type,
1219 % ExceptionInfo *exception)
1220 %
1221 % A description of each parameter follows:
1222 %
1223 % o image: the image.
1224 %
1225 % o type: Image type.
1226 %
1227 % o exception: return any errors or warnings in this structure.
1228 %
1229 */
1231  ExceptionInfo *exception)
1232 {
1233  const char
1234  *artifact;
1235 
1236  ImageInfo
1237  *image_info;
1238 
1240  status;
1241 
1242  QuantizeInfo
1243  *quantize_info;
1244 
1245  assert(image != (Image *) NULL);
1246  if (image->debug != MagickFalse)
1247  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1248  assert(image->signature == MagickCoreSignature);
1249  status=MagickTrue;
1250  image_info=AcquireImageInfo();
1251  image_info->dither=image->dither;
1252  artifact=GetImageArtifact(image,"dither");
1253  if (artifact != (const char *) NULL)
1254  (void) SetImageOption(image_info,"dither",artifact);
1255  switch (type)
1256  {
1257  case BilevelType:
1258  {
1259  if (SetImageMonochrome(image,exception) == MagickFalse)
1260  {
1261  status=TransformImageColorspace(image,GRAYColorspace,exception);
1262  (void) NormalizeImage(image,exception);
1263  quantize_info=AcquireQuantizeInfo(image_info);
1264  quantize_info->number_colors=2;
1265  quantize_info->colorspace=GRAYColorspace;
1266  status=QuantizeImage(quantize_info,image,exception);
1267  quantize_info=DestroyQuantizeInfo(quantize_info);
1268  }
1270  break;
1271  }
1272  case GrayscaleType:
1273  {
1274  if (SetImageGray(image,exception) == MagickFalse)
1275  status=TransformImageColorspace(image,GRAYColorspace,exception);
1277  break;
1278  }
1279  case GrayscaleAlphaType:
1280  {
1281  if (SetImageGray(image,exception) == MagickFalse)
1282  status=TransformImageColorspace(image,GRAYColorspace,exception);
1283  if (image->alpha_trait == UndefinedPixelTrait)
1284  (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1285  break;
1286  }
1287  case PaletteType:
1288  {
1290  status=TransformImageColorspace(image,sRGBColorspace,exception);
1291  if ((image->storage_class == DirectClass) || (image->colors > 256))
1292  {
1293  quantize_info=AcquireQuantizeInfo(image_info);
1294  quantize_info->number_colors=256;
1295  status=QuantizeImage(quantize_info,image,exception);
1296  quantize_info=DestroyQuantizeInfo(quantize_info);
1297  }
1299  break;
1300  }
1302  {
1303  ChannelType
1304  channel_mask;
1305 
1307  status=TransformImageColorspace(image,sRGBColorspace,exception);
1308  if (image->alpha_trait == UndefinedPixelTrait)
1309  (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1310  channel_mask=SetImageChannelMask(image,AlphaChannel);
1311  (void) BilevelImage(image,(double) QuantumRange/2.0,exception);
1312  (void) SetImageChannelMask(image,channel_mask);
1313  quantize_info=AcquireQuantizeInfo(image_info);
1314  status=QuantizeImage(quantize_info,image,exception);
1315  quantize_info=DestroyQuantizeInfo(quantize_info);
1316  break;
1317  }
1318  case PaletteAlphaType:
1319  {
1321  status=TransformImageColorspace(image,sRGBColorspace,exception);
1322  if (image->alpha_trait == UndefinedPixelTrait)
1323  (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1324  quantize_info=AcquireQuantizeInfo(image_info);
1325  quantize_info->colorspace=TransparentColorspace;
1326  status=QuantizeImage(quantize_info,image,exception);
1327  quantize_info=DestroyQuantizeInfo(quantize_info);
1328  break;
1329  }
1330  case TrueColorType:
1331  {
1333  status=TransformImageColorspace(image,sRGBColorspace,exception);
1334  if (image->storage_class != DirectClass)
1335  status=SetImageStorageClass(image,DirectClass,exception);
1337  break;
1338  }
1339  case TrueColorAlphaType:
1340  {
1342  status=TransformImageColorspace(image,sRGBColorspace,exception);
1343  if (image->storage_class != DirectClass)
1344  status=SetImageStorageClass(image,DirectClass,exception);
1345  if (image->alpha_trait == UndefinedPixelTrait)
1346  (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1347  break;
1348  }
1349  case ColorSeparationType:
1350  {
1351  if (image->colorspace != CMYKColorspace)
1352  {
1354  status=TransformImageColorspace(image,sRGBColorspace,exception);
1355  status=TransformImageColorspace(image,CMYKColorspace,exception);
1356  }
1357  if (image->storage_class != DirectClass)
1358  status=SetImageStorageClass(image,DirectClass,exception);
1360  break;
1361  }
1363  {
1364  if (image->colorspace != CMYKColorspace)
1365  {
1367  status=TransformImageColorspace(image,sRGBColorspace,exception);
1368  status=TransformImageColorspace(image,CMYKColorspace,exception);
1369  }
1370  if (image->storage_class != DirectClass)
1371  status=SetImageStorageClass(image,DirectClass,exception);
1372  if (image->alpha_trait == UndefinedPixelTrait)
1373  status=SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1374  break;
1375  }
1376  case OptimizeType:
1377  case UndefinedType:
1378  break;
1379  }
1380  image_info=DestroyImageInfo(image_info);
1381  if (status == MagickFalse)
1382  return(status);
1383  image->type=type;
1384  return(MagickTrue);
1385 }
size_t rows
Definition: image.h:172
#define magick_restrict
Definition: MagickCore.h:41
MagickDoubleType MagickRealType
Definition: magick-type.h:118
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
Definition: cache-view.c:252
PixelInfo * colormap
Definition: image.h:179
static MagickSizeType GetQuantumRange(const size_t depth)
MagickExport ImageInfo * AcquireImageInfo(void)
Definition: image.c:341
ImageType type
Definition: image.h:264
static Quantum GetPixelAlpha(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
static PixelTrait GetPixelRedTraits(const Image *magick_restrict image)
MagickExport MagickBooleanType TransformImageColorspace(Image *image, const ColorspaceType colorspace, ExceptionInfo *exception)
Definition: colorspace.c:1272
static PixelTrait GetPixelAlphaTraits(const Image *magick_restrict image)
ColorspaceType colorspace
Definition: quantize.h:44
MagickExport MagickBooleanType SetImageDepth(Image *image, const size_t depth, ExceptionInfo *exception)
Definition: attribute.c:1003
#define ThrowFatalException(severity, tag)
MagickExport ImageType IdentifyImageGray(const Image *image, ExceptionInfo *exception)
Definition: attribute.c:642
#define OpaqueAlpha
Definition: image.h:25
MagickExport QuantizeInfo * DestroyQuantizeInfo(QuantizeInfo *quantize_info)
Definition: quantize.c:1383
MagickExport const char * GetImageArtifact(const Image *image, const char *artifact)
Definition: artifact.c:273
MagickRealType red
Definition: pixel.h:188
static PixelTrait GetPixelChannelTraits(const Image *magick_restrict image, const PixelChannel channel)
static MagickBooleanType IsPixelMonochrome(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
#define MAGICKCORE_QUANTUM_DEPTH
Definition: magick-type.h:28
MagickExport const Quantum * GetCacheViewVirtualPixels(const CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:651
MagickRealType alpha
Definition: pixel.h:188
MagickExport MagickBooleanType IdentifyImageMonochrome(const Image *image, ExceptionInfo *exception)
Definition: attribute.c:724
ClassType storage_class
Definition: image.h:154
size_t width
Definition: geometry.h:129
Definition: log.h:52
MagickExport void GetPixelInfo(const Image *image, PixelInfo *pixel)
Definition: pixel.c:2161
MagickExport MagickBooleanType SetImageOption(ImageInfo *image_info, const char *option, const char *value)
Definition: option.c:3223
Definition: image.h:151
MagickExport MagickBooleanType SetImageGray(Image *image, ExceptionInfo *exception)
Definition: colorspace.c:1161
#define MagickCoreSignature
MagickExport MagickBooleanType SetImageType(Image *image, const ImageType type, ExceptionInfo *exception)
Definition: attribute.c:1230
MagickExport Quantum * GetCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:299
static Quantum ClampPixel(const MagickRealType pixel)
MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, const AlphaChannelOption alpha_type, ExceptionInfo *exception)
Definition: channel.c:966
MagickBooleanType
Definition: magick-type.h:156
static Quantum ScaleAnyToQuantum(const QuantumAny quantum, const QuantumAny range)
static MagickBooleanType IssRGBCompatibleColorspace(const ColorspaceType colorspace)
static Quantum GetPixelWriteMask(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport MagickBooleanType NormalizeImage(Image *image, ExceptionInfo *exception)
Definition: enhance.c:3598
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:529
MagickExport ImageType GetImageType(const Image *image)
Definition: attribute.c:587
static int GetOpenMPThreadId(void)
static MagickBooleanType IsPixelAtDepth(const Quantum pixel, const QuantumAny range)
size_t number_colors
Definition: quantize.h:38
static void GetPixelInfoPixel(const Image *magick_restrict image, const Quantum *magick_restrict pixel, PixelInfo *magick_restrict pixel_info)
PixelTrait alpha_trait
Definition: image.h:280
MagickRealType blue
Definition: pixel.h:188
MagickExport MagickBooleanType IdentifyPaletteImage(const Image *image, ExceptionInfo *exception)
Definition: histogram.c:769
MagickExport ChannelType SetImageChannelMask(Image *image, const ChannelType channel_mask)
Definition: image.c:2392
MagickBooleanType dither
Definition: image.h:267
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
Definition: exception.c:1058
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1397
MagickExport MagickBooleanType QuantizeImage(const QuantizeInfo *quantize_info, Image *image, ExceptionInfo *exception)
Definition: quantize.c:2637
size_t signature
Definition: image.h:354
MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
Definition: resource.c:758
size_t columns
Definition: image.h:172
MagickExport size_t GetImageQuantumDepth(const Image *image, const MagickBooleanType constrain)
Definition: attribute.c:538
ssize_t x
Definition: geometry.h:133
static MagickBooleanType IsPixelGray(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
size_t height
Definition: geometry.h:129
MagickExport ImageType IdentifyImageType(const Image *image, ExceptionInfo *exception)
Definition: attribute.c:807
static PixelTrait GetPixelGreenTraits(const Image *magick_restrict image)
ChannelType
Definition: pixel.h:33
MagickExport MagickBooleanType SetImageStorageClass(Image *image, const ClassType storage_class, ExceptionInfo *exception)
Definition: image.c:2508
PixelChannel
Definition: pixel.h:66
#define MaxMap
Definition: magick-type.h:75
size_t colors
Definition: image.h:172
static size_t GetPixelChannels(const Image *magick_restrict image)
MagickExport MagickBooleanType IsPaletteImage(const Image *image)
Definition: histogram.c:840
MagickExport QuantizeInfo * AcquireQuantizeInfo(const ImageInfo *image_info)
Definition: quantize.c:373
char filename[MagickPathExtent]
Definition: image.h:319
#define GetMagickModule()
Definition: log.h:28
static Quantum ClampToQuantum(const MagickRealType value)
Definition: quantum.h:84
static PixelChannel GetPixelChannelChannel(const Image *magick_restrict image, const ssize_t offset)
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
Definition: cache-view.c:149
MagickExport ImageInfo * DestroyImageInfo(ImageInfo *image_info)
Definition: image.c:1253
MagickExport MagickBooleanType IsImageGray(const Image *image)
Definition: attribute.c:862
MagickExport size_t GetImageDepth(const Image *image, ExceptionInfo *exception)
Definition: attribute.c:274
unsigned short Quantum
Definition: magick-type.h:82
MagickExport MagickBooleanType IsImageMonochrome(const Image *image)
Definition: attribute.c:894
MagickExport RectangleInfo GetImageBoundingBox(const Image *image, ExceptionInfo *exception)
Definition: attribute.c:125
MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p, const PixelInfo *q)
Definition: pixel.c:6049
MagickBooleanType dither
Definition: image.h:423
#define MagickMin(x, y)
Definition: image-private.h:27
MagickExport MagickBooleanType BilevelImage(Image *image, const double threshold, ExceptionInfo *exception)
Definition: threshold.c:802
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1038
MagickRealType green
Definition: pixel.h:188
ImageType
Definition: image.h:48
#define MagickExport
MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *magick_restrict cache_view, ExceptionInfo *exception)
Definition: cache-view.c:1100
ssize_t y
Definition: geometry.h:133
MagickExport CacheView * AcquireAuthenticCacheView(const Image *image, ExceptionInfo *exception)
Definition: cache-view.c:112
MagickExport MagickBooleanType SetImageMonochrome(Image *image, ExceptionInfo *exception)
Definition: colorspace.c:1218
PixelTrait
Definition: pixel.h:132
static QuantumAny ScaleQuantumToAny(const Quantum quantum, const QuantumAny range)
MagickSizeType QuantumAny
Definition: magick-type.h:142
ColorspaceType colorspace
Definition: image.h:157
MagickExport MagickBooleanType IsImageOpaque(const Image *image, ExceptionInfo *exception)
Definition: attribute.c:931
#define QuantumRange
Definition: magick-type.h:83
MagickBooleanType debug
Definition: image.h:334
static PixelTrait GetPixelBlueTraits(const Image *magick_restrict image)
size_t depth
Definition: image.h:172