MagickCore  7.0.7
Convert, Edit, Or Compose Bitmap Images
vision.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % V V IIIII SSSSS IIIII OOO N N %
7 % V V I SS I O O NN N %
8 % V V I SSS I O O N N N %
9 % V V I SS I O O N NN %
10 % V IIIII SSSSS IIIII OOO N N %
11 % %
12 % %
13 % MagickCore Computer Vision Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % September 2014 %
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 #include "MagickCore/studio.h"
40 #include "MagickCore/artifact.h"
41 #include "MagickCore/blob.h"
42 #include "MagickCore/cache-view.h"
43 #include "MagickCore/color.h"
45 #include "MagickCore/colormap.h"
46 #include "MagickCore/colorspace.h"
47 #include "MagickCore/constitute.h"
48 #include "MagickCore/decorate.h"
49 #include "MagickCore/distort.h"
50 #include "MagickCore/draw.h"
51 #include "MagickCore/enhance.h"
52 #include "MagickCore/exception.h"
54 #include "MagickCore/effect.h"
55 #include "MagickCore/gem.h"
56 #include "MagickCore/geometry.h"
58 #include "MagickCore/list.h"
59 #include "MagickCore/log.h"
60 #include "MagickCore/matrix.h"
61 #include "MagickCore/memory_.h"
63 #include "MagickCore/monitor.h"
65 #include "MagickCore/montage.h"
66 #include "MagickCore/morphology.h"
69 #include "MagickCore/paint.h"
72 #include "MagickCore/property.h"
73 #include "MagickCore/quantum.h"
74 #include "MagickCore/resource_.h"
76 #include "MagickCore/string_.h"
79 #include "MagickCore/token.h"
80 #include "MagickCore/vision.h"
81 
82 /*
83 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 % %
85 % %
86 % %
87 % C o n n e c t e d C o m p o n e n t s I m a g e %
88 % %
89 % %
90 % %
91 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92 %
93 % ConnectedComponentsImage() returns the connected-components of the image
94 % uniquely labeled. The returned connected components image colors member
95 % defines the number of unique objects. Choose from 4 or 8-way connectivity.
96 %
97 % You are responsible for freeing the connected components objects resources
98 % with this statement;
99 %
100 % objects = (CCObjectInfo *) RelinquishMagickMemory(objects);
101 %
102 % The format of the ConnectedComponentsImage method is:
103 %
104 % Image *ConnectedComponentsImage(const Image *image,
105 % const size_t connectivity,CCObjectInfo **objects,
106 % ExceptionInfo *exception)
107 %
108 % A description of each parameter follows:
109 %
110 % o image: the image.
111 %
112 % o connectivity: how many neighbors to visit, choose from 4 or 8.
113 %
114 % o objects: return the attributes of each unique object.
115 %
116 % o exception: return any errors or warnings in this structure.
117 %
118 */
119 
120 static int CCObjectInfoCompare(const void *x,const void *y)
121 {
123  *p,
124  *q;
125 
126  p=(CCObjectInfo *) x;
127  q=(CCObjectInfo *) y;
128  return((int) (q->area-(ssize_t) p->area));
129 }
130 
132  const size_t connectivity,CCObjectInfo **objects,ExceptionInfo *exception)
133 {
134 #define ConnectedComponentsImageTag "ConnectedComponents/Image"
135 
136  CacheView
137  *image_view,
138  *component_view;
139 
141  *object;
142 
143  char
144  *c;
145 
146  const char
147  *artifact;
148 
149  double
150  area_threshold;
151 
152  Image
153  *component_image;
154 
156  status;
157 
159  progress;
160 
161  MatrixInfo
162  *equivalences;
163 
164  register ssize_t
165  i;
166 
167  size_t
168  size;
169 
170  ssize_t
171  first,
172  last,
173  n,
174  step,
175  y;
176 
177  /*
178  Initialize connected components image attributes.
179  */
180  assert(image != (Image *) NULL);
181  assert(image->signature == MagickCoreSignature);
182  if (image->debug != MagickFalse)
183  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
184  assert(exception != (ExceptionInfo *) NULL);
185  assert(exception->signature == MagickCoreSignature);
186  if (objects != (CCObjectInfo **) NULL)
187  *objects=(CCObjectInfo *) NULL;
188  component_image=CloneImage(image,image->columns,image->rows,MagickTrue,
189  exception);
190  if (component_image == (Image *) NULL)
191  return((Image *) NULL);
192  component_image->depth=MAGICKCORE_QUANTUM_DEPTH;
193  if (AcquireImageColormap(component_image,MaxColormapSize,exception) == MagickFalse)
194  {
195  component_image=DestroyImage(component_image);
196  ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
197  }
198  /*
199  Initialize connected components equivalences.
200  */
201  size=image->columns*image->rows;
202  if (image->columns != (size/image->rows))
203  {
204  component_image=DestroyImage(component_image);
205  ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
206  }
207  equivalences=AcquireMatrixInfo(size,1,sizeof(ssize_t),exception);
208  if (equivalences == (MatrixInfo *) NULL)
209  {
210  component_image=DestroyImage(component_image);
211  return((Image *) NULL);
212  }
213  for (n=0; n < (ssize_t) (image->columns*image->rows); n++)
214  (void) SetMatrixElement(equivalences,n,0,&n);
215  object=(CCObjectInfo *) AcquireQuantumMemory(MaxColormapSize,sizeof(*object));
216  if (object == (CCObjectInfo *) NULL)
217  {
218  equivalences=DestroyMatrixInfo(equivalences);
219  component_image=DestroyImage(component_image);
220  ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
221  }
222  (void) ResetMagickMemory(object,0,MaxColormapSize*sizeof(*object));
223  for (i=0; i < (ssize_t) MaxColormapSize; i++)
224  {
225  object[i].id=i;
226  object[i].bounding_box.x=(ssize_t) image->columns;
227  object[i].bounding_box.y=(ssize_t) image->rows;
228  GetPixelInfo(image,&object[i].color);
229  }
230  /*
231  Find connected components.
232  */
233  status=MagickTrue;
234  progress=0;
235  image_view=AcquireVirtualCacheView(image,exception);
236  for (n=0; n < (ssize_t) (connectivity > 4 ? 4 : 2); n++)
237  {
238  ssize_t
239  connect4[2][2] = { { -1, 0 }, { 0, -1 } },
240  connect8[4][2] = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 } },
241  dx,
242  dy;
243 
244  if (status == MagickFalse)
245  continue;
246  dy=connectivity > 4 ? connect8[n][0] : connect4[n][0];
247  dx=connectivity > 4 ? connect8[n][1] : connect4[n][1];
248  for (y=0; y < (ssize_t) image->rows; y++)
249  {
250  register const Quantum
251  *magick_restrict p;
252 
253  register ssize_t
254  x;
255 
256  if (status == MagickFalse)
257  continue;
258  p=GetCacheViewVirtualPixels(image_view,0,y-1,image->columns,3,exception);
259  if (p == (const Quantum *) NULL)
260  {
261  status=MagickFalse;
262  continue;
263  }
264  p+=GetPixelChannels(image)*image->columns;
265  for (x=0; x < (ssize_t) image->columns; x++)
266  {
267  PixelInfo
268  pixel,
269  target;
270 
271  ssize_t
272  neighbor_offset,
273  obj,
274  offset,
275  ox,
276  oy,
277  root;
278 
279  /*
280  Is neighbor an authentic pixel and a different color than the pixel?
281  */
282  GetPixelInfoPixel(image,p,&pixel);
283  if (((x+dx) < 0) || ((x+dx) >= (ssize_t) image->columns) ||
284  ((y+dy) < 0) || ((y+dy) >= (ssize_t) image->rows))
285  {
286  p+=GetPixelChannels(image);
287  continue;
288  }
289  neighbor_offset=dy*(GetPixelChannels(image)*image->columns)+dx*
290  GetPixelChannels(image);
291  GetPixelInfoPixel(image,p+neighbor_offset,&target);
292  if (IsFuzzyEquivalencePixelInfo(&pixel,&target) == MagickFalse)
293  {
294  p+=GetPixelChannels(image);
295  continue;
296  }
297  /*
298  Resolve this equivalence.
299  */
300  offset=y*image->columns+x;
301  neighbor_offset=dy*image->columns+dx;
302  ox=offset;
303  status=GetMatrixElement(equivalences,ox,0,&obj);
304  while (obj != ox)
305  {
306  ox=obj;
307  status=GetMatrixElement(equivalences,ox,0,&obj);
308  }
309  oy=offset+neighbor_offset;
310  status=GetMatrixElement(equivalences,oy,0,&obj);
311  while (obj != oy)
312  {
313  oy=obj;
314  status=GetMatrixElement(equivalences,oy,0,&obj);
315  }
316  if (ox < oy)
317  {
318  status=SetMatrixElement(equivalences,oy,0,&ox);
319  root=ox;
320  }
321  else
322  {
323  status=SetMatrixElement(equivalences,ox,0,&oy);
324  root=oy;
325  }
326  ox=offset;
327  status=GetMatrixElement(equivalences,ox,0,&obj);
328  while (obj != root)
329  {
330  status=GetMatrixElement(equivalences,ox,0,&obj);
331  status=SetMatrixElement(equivalences,ox,0,&root);
332  }
333  oy=offset+neighbor_offset;
334  status=GetMatrixElement(equivalences,oy,0,&obj);
335  while (obj != root)
336  {
337  status=GetMatrixElement(equivalences,oy,0,&obj);
338  status=SetMatrixElement(equivalences,oy,0,&root);
339  }
340  status=SetMatrixElement(equivalences,y*image->columns+x,0,&root);
341  p+=GetPixelChannels(image);
342  }
343  }
344  }
345  image_view=DestroyCacheView(image_view);
346  /*
347  Label connected components.
348  */
349  n=0;
350  image_view=AcquireVirtualCacheView(image,exception);
351  component_view=AcquireAuthenticCacheView(component_image,exception);
352  for (y=0; y < (ssize_t) component_image->rows; y++)
353  {
354  register const Quantum
355  *magick_restrict p;
356 
357  register Quantum
358  *magick_restrict q;
359 
360  register ssize_t
361  x;
362 
363  if (status == MagickFalse)
364  continue;
365  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
366  q=QueueCacheViewAuthenticPixels(component_view,0,y,component_image->columns,
367  1,exception);
368  if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
369  {
370  status=MagickFalse;
371  continue;
372  }
373  for (x=0; x < (ssize_t) component_image->columns; x++)
374  {
375  ssize_t
376  id,
377  offset;
378 
379  offset=y*image->columns+x;
380  status=GetMatrixElement(equivalences,offset,0,&id);
381  if (id != offset)
382  status=GetMatrixElement(equivalences,id,0,&id);
383  else
384  {
385  id=n++;
386  if (id >= (ssize_t) MaxColormapSize)
387  break;
388  }
389  status=SetMatrixElement(equivalences,offset,0,&id);
390  if (x < object[id].bounding_box.x)
391  object[id].bounding_box.x=x;
392  if (x >= (ssize_t) object[id].bounding_box.width)
393  object[id].bounding_box.width=(size_t) x;
394  if (y < object[id].bounding_box.y)
395  object[id].bounding_box.y=y;
396  if (y >= (ssize_t) object[id].bounding_box.height)
397  object[id].bounding_box.height=(size_t) y;
398  object[id].color.red+=QuantumScale*GetPixelRed(image,p);
399  object[id].color.green+=QuantumScale*GetPixelGreen(image,p);
400  object[id].color.blue+=QuantumScale*GetPixelBlue(image,p);
401  if (image->alpha_trait != UndefinedPixelTrait)
402  object[id].color.alpha+=QuantumScale*GetPixelAlpha(image,p);
403  if (image->colorspace == CMYKColorspace)
404  object[id].color.black+=QuantumScale*GetPixelBlack(image,p);
405  object[id].centroid.x+=x;
406  object[id].centroid.y+=y;
407  object[id].area++;
408  SetPixelIndex(component_image,(Quantum) id,q);
409  p+=GetPixelChannels(image);
410  q+=GetPixelChannels(component_image);
411  }
412  if (n > (ssize_t) MaxColormapSize)
413  break;
414  if (SyncCacheViewAuthenticPixels(component_view,exception) == MagickFalse)
415  status=MagickFalse;
416  if (image->progress_monitor != (MagickProgressMonitor) NULL)
417  {
419  proceed;
420 
421  proceed=SetImageProgress(image,ConnectedComponentsImageTag,progress++,
422  image->rows);
423  if (proceed == MagickFalse)
424  status=MagickFalse;
425  }
426  }
427  component_view=DestroyCacheView(component_view);
428  image_view=DestroyCacheView(image_view);
429  equivalences=DestroyMatrixInfo(equivalences);
430  if (n > (ssize_t) MaxColormapSize)
431  {
432  object=(CCObjectInfo *) RelinquishMagickMemory(object);
433  component_image=DestroyImage(component_image);
434  ThrowImageException(ResourceLimitError,"TooManyObjects");
435  }
436  component_image->colors=(size_t) n;
437  for (i=0; i < (ssize_t) component_image->colors; i++)
438  {
439  object[i].bounding_box.width-=(object[i].bounding_box.x-1);
440  object[i].bounding_box.height-=(object[i].bounding_box.y-1);
441  object[i].color.red=QuantumRange*(object[i].color.red/object[i].area);
442  object[i].color.green=QuantumRange*(object[i].color.green/object[i].area);
443  object[i].color.blue=QuantumRange*(object[i].color.blue/object[i].area);
444  if (image->alpha_trait != UndefinedPixelTrait)
445  object[i].color.alpha=QuantumRange*(object[i].color.alpha/object[i].area);
446  if (image->colorspace == CMYKColorspace)
447  object[i].color.black=QuantumRange*(object[i].color.black/object[i].area);
448  object[i].centroid.x=object[i].centroid.x/object[i].area;
449  object[i].centroid.y=object[i].centroid.y/object[i].area;
450  }
451  artifact=GetImageArtifact(image,"connected-components:area-threshold");
452  area_threshold=0.0;
453  if (artifact != (const char *) NULL)
454  area_threshold=StringToDouble(artifact,(char **) NULL);
455  if (area_threshold > 0.0)
456  {
457  /*
458  Merge object below area threshold.
459  */
460  component_view=AcquireAuthenticCacheView(component_image,exception);
461  for (i=0; i < (ssize_t) component_image->colors; i++)
462  {
463  double
464  census;
465 
467  bounding_box;
468 
469  register ssize_t
470  j;
471 
472  size_t
473  id;
474 
475  if (status == MagickFalse)
476  continue;
477  if ((double) object[i].area >= area_threshold)
478  continue;
479  for (j=0; j < (ssize_t) component_image->colors; j++)
480  object[j].census=0;
481  bounding_box=object[i].bounding_box;
482  for (y=0; y < (ssize_t) bounding_box.height+2; y++)
483  {
484  register const Quantum
485  *magick_restrict p;
486 
487  register ssize_t
488  x;
489 
490  if (status == MagickFalse)
491  continue;
492  p=GetCacheViewVirtualPixels(component_view,bounding_box.x-1,
493  bounding_box.y+y-1,bounding_box.width+2,1,exception);
494  if (p == (const Quantum *) NULL)
495  {
496  status=MagickFalse;
497  continue;
498  }
499  for (x=0; x < (ssize_t) bounding_box.width+2; x++)
500  {
501  j=(ssize_t) GetPixelIndex(component_image,p);
502  if (j != i)
503  object[j].census++;
504  p+=GetPixelChannels(component_image);
505  }
506  }
507  census=0;
508  id=0;
509  for (j=0; j < (ssize_t) component_image->colors; j++)
510  if (census < object[j].census)
511  {
512  census=object[j].census;
513  id=(size_t) j;
514  }
515  object[id].area+=object[i].area;
516  for (y=0; y < (ssize_t) bounding_box.height; y++)
517  {
518  register Quantum
519  *magick_restrict q;
520 
521  register ssize_t
522  x;
523 
524  if (status == MagickFalse)
525  continue;
526  q=GetCacheViewAuthenticPixels(component_view,bounding_box.x,
527  bounding_box.y+y,bounding_box.width,1,exception);
528  if (q == (Quantum *) NULL)
529  {
530  status=MagickFalse;
531  continue;
532  }
533  for (x=0; x < (ssize_t) bounding_box.width; x++)
534  {
535  if ((ssize_t) GetPixelIndex(component_image,q) == i)
536  SetPixelIndex(component_image,(Quantum) id,q);
537  q+=GetPixelChannels(component_image);
538  }
539  if (SyncCacheViewAuthenticPixels(component_view,exception) == MagickFalse)
540  status=MagickFalse;
541  }
542  }
543  component_view=DestroyCacheView(component_view);
544  (void) SyncImage(component_image,exception);
545  }
546  artifact=GetImageArtifact(image,"connected-components:mean-color");
547  if (IsStringTrue(artifact) != MagickFalse)
548  {
549  /*
550  Replace object with mean color.
551  */
552  for (i=0; i < (ssize_t) component_image->colors; i++)
553  component_image->colormap[i]=object[i].color;
554  }
555  artifact=GetImageArtifact(image,"connected-components:keep");
556  if (artifact != (const char *) NULL)
557  {
558  /*
559  Keep these object (make others transparent).
560  */
561  for (i=0; i < (ssize_t) component_image->colors; i++)
562  object[i].census=0;
563  for (c=(char *) artifact; *c != '\0';)
564  {
565  while ((isspace((int) ((unsigned char) *c)) != 0) || (*c == ','))
566  c++;
567  first=strtol(c,&c,10);
568  if (first < 0)
569  first+=(long) component_image->colors;
570  last=first;
571  while (isspace((int) ((unsigned char) *c)) != 0)
572  c++;
573  if (*c == '-')
574  {
575  last=strtol(c+1,&c,10);
576  if (last < 0)
577  last+=(long) component_image->colors;
578  }
579  for (step=first > last ? -1 : 1; first != (last+step); first+=step)
580  object[first].census++;
581  }
582  for (i=0; i < (ssize_t) component_image->colors; i++)
583  {
584  if (object[i].census != 0)
585  continue;
586  component_image->alpha_trait=BlendPixelTrait;
587  component_image->colormap[i].alpha=TransparentAlpha;
588  }
589  }
590  artifact=GetImageArtifact(image,"connected-components:remove");
591  if (artifact != (const char *) NULL)
592  {
593  /*
594  Remove these object (make them transparent).
595  */
596  for (c=(char *) artifact; *c != '\0';)
597  {
598  while ((isspace((int) ((unsigned char) *c)) != 0) || (*c == ','))
599  c++;
600  first=strtol(c,&c,10);
601  if (first < 0)
602  first+=(long) component_image->colors;
603  last=first;
604  while (isspace((int) ((unsigned char) *c)) != 0)
605  c++;
606  if (*c == '-')
607  {
608  last=strtol(c+1,&c,10);
609  if (last < 0)
610  last+=(long) component_image->colors;
611  }
612  for (step=first > last ? -1 : 1; first != (last+step); first+=step)
613  {
614  component_image->alpha_trait=BlendPixelTrait;
615  component_image->colormap[first].alpha=TransparentAlpha;
616  }
617  }
618  }
619  (void) SyncImage(component_image,exception);
620  artifact=GetImageArtifact(image,"connected-components:verbose");
621  if ((IsStringTrue(artifact) != MagickFalse) ||
622  (objects != (CCObjectInfo **) NULL))
623  {
624  /*
625  Report statistics on unique object.
626  */
627  for (i=0; i < (ssize_t) component_image->colors; i++)
628  {
629  object[i].bounding_box.width=0;
630  object[i].bounding_box.height=0;
631  object[i].bounding_box.x=(ssize_t) component_image->columns;
632  object[i].bounding_box.y=(ssize_t) component_image->rows;
633  object[i].centroid.x=0;
634  object[i].centroid.y=0;
635  object[i].area=0;
636  }
637  component_view=AcquireVirtualCacheView(component_image,exception);
638  for (y=0; y < (ssize_t) component_image->rows; y++)
639  {
640  register const Quantum
641  *magick_restrict p;
642 
643  register ssize_t
644  x;
645 
646  if (status == MagickFalse)
647  continue;
648  p=GetCacheViewVirtualPixels(component_view,0,y,
649  component_image->columns,1,exception);
650  if (p == (const Quantum *) NULL)
651  {
652  status=MagickFalse;
653  continue;
654  }
655  for (x=0; x < (ssize_t) component_image->columns; x++)
656  {
657  size_t
658  id;
659 
660  id=GetPixelIndex(component_image,p);
661  if (x < object[id].bounding_box.x)
662  object[id].bounding_box.x=x;
663  if (x > (ssize_t) object[id].bounding_box.width)
664  object[id].bounding_box.width=(size_t) x;
665  if (y < object[id].bounding_box.y)
666  object[id].bounding_box.y=y;
667  if (y > (ssize_t) object[id].bounding_box.height)
668  object[id].bounding_box.height=(size_t) y;
669  object[id].centroid.x+=x;
670  object[id].centroid.y+=y;
671  object[id].area++;
672  p+=GetPixelChannels(component_image);
673  }
674  }
675  for (i=0; i < (ssize_t) component_image->colors; i++)
676  {
677  object[i].bounding_box.width-=(object[i].bounding_box.x-1);
678  object[i].bounding_box.height-=(object[i].bounding_box.y-1);
679  object[i].centroid.x=object[i].centroid.x/object[i].area;
680  object[i].centroid.y=object[i].centroid.y/object[i].area;
681  }
682  component_view=DestroyCacheView(component_view);
683  qsort((void *) object,component_image->colors,sizeof(*object),
685  if (objects == (CCObjectInfo **) NULL)
686  {
687  (void) fprintf(stdout,
688  "Objects (id: bounding-box centroid area mean-color):\n");
689  for (i=0; i < (ssize_t) component_image->colors; i++)
690  {
691  char
692  mean_color[MagickPathExtent];
693 
694  if (status == MagickFalse)
695  break;
696  if (object[i].area <= area_threshold)
697  continue;
698  GetColorTuple(&object[i].color,MagickFalse,mean_color);
699  (void) fprintf(stdout,
700  " %.20g: %.20gx%.20g%+.20g%+.20g %.1f,%.1f %.20g %s\n",(double)
701  object[i].id,(double) object[i].bounding_box.width,(double)
702  object[i].bounding_box.height,(double) object[i].bounding_box.x,
703  (double) object[i].bounding_box.y,object[i].centroid.x,
704  object[i].centroid.y,(double) object[i].area,mean_color);
705  }
706  }
707  }
708  if (objects == (CCObjectInfo **) NULL)
709  object=(CCObjectInfo *) RelinquishMagickMemory(object);
710  else
711  *objects=object;
712  return(component_image);
713 }
size_t rows
Definition: image.h:172
#define magick_restrict
Definition: MagickCore.h:41
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
Definition: cache-view.c:252
MagickExport Image * ConnectedComponentsImage(const Image *image, const size_t connectivity, CCObjectInfo **objects, ExceptionInfo *exception)
Definition: vision.c:131
#define TransparentAlpha
Definition: image.h:26
static MagickBooleanType SetImageProgress(const Image *image, const char *tag, const MagickOffsetType offset, const MagickSizeType extent)
PixelInfo * colormap
Definition: image.h:179
MagickProgressMonitor progress_monitor
Definition: image.h:303
MagickExport MagickBooleanType SyncImage(Image *image, ExceptionInfo *exception)
Definition: image.c:3706
static Quantum GetPixelAlpha(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
static Quantum GetPixelRed(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
size_t signature
Definition: exception.h:123
MagickExport const char * GetImageArtifact(const Image *image, const char *artifact)
Definition: artifact.c:273
#define MaxColormapSize
Definition: magick-type.h:74
static double StringToDouble(const char *magick_restrict string, char **magick_restrict sentinal)
#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 GetMatrixElement(const MatrixInfo *matrix_info, const ssize_t x, const ssize_t y, void *value)
Definition: matrix.c:705
size_t width
Definition: geometry.h:129
Definition: log.h:52
ssize_t MagickOffsetType
Definition: magick-type.h:127
MagickExport void GetPixelInfo(const Image *image, PixelInfo *pixel)
Definition: pixel.c:2161
Definition: image.h:151
MagickExport MagickBooleanType SetMatrixElement(const MatrixInfo *matrix_info, const ssize_t x, const ssize_t y, const void *value)
Definition: matrix.c:1109
#define MagickCoreSignature
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
MagickBooleanType
Definition: magick-type.h:156
MagickExport void * ResetMagickMemory(void *memory, int byte, const size_t size)
Definition: memory.c:1164
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:529
MagickExport void GetColorTuple(const PixelInfo *pixel, const MagickBooleanType hex, char *tuple)
Definition: color.c:1556
#define MagickPathExtent
static Quantum GetPixelGreen(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1464
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
static Quantum GetPixelIndex(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
static Quantum GetPixelBlack(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport Quantum * QueueCacheViewAuthenticPixels(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:977
MagickExport MatrixInfo * AcquireMatrixInfo(const size_t columns, const size_t rows, const size_t stride, ExceptionInfo *exception)
Definition: matrix.c:200
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1397
size_t signature
Definition: image.h:354
#define QuantumScale
Definition: magick-type.h:113
size_t columns
Definition: image.h:172
ssize_t x
Definition: geometry.h:133
MagickBooleanType(* MagickProgressMonitor)(const char *, const MagickOffsetType, const MagickSizeType, void *)
Definition: monitor.h:26
size_t height
Definition: geometry.h:129
size_t colors
Definition: image.h:172
static size_t GetPixelChannels(const Image *magick_restrict image)
MagickExport MagickBooleanType AcquireImageColormap(Image *image, const size_t colors, ExceptionInfo *exception)
Definition: colormap.c:104
char filename[MagickPathExtent]
Definition: image.h:319
#define GetMagickModule()
Definition: log.h:28
#define ThrowImageException(severity, tag)
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
Definition: cache-view.c:149
double area
Definition: vision.h:40
unsigned short Quantum
Definition: magick-type.h:82
MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p, const PixelInfo *q)
Definition: pixel.c:6049
static void SetPixelIndex(const Image *magick_restrict image, const Quantum index, Quantum *magick_restrict pixel)
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1038
static int CCObjectInfoCompare(const void *x, const void *y)
Definition: vision.c:120
#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
static Quantum GetPixelBlue(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
#define ConnectedComponentsImageTag
MagickExport Image * DestroyImage(Image *image)
Definition: image.c:1182
MagickExport Image * CloneImage(const Image *image, const size_t columns, const size_t rows, const MagickBooleanType detach, ExceptionInfo *exception)
Definition: image.c:799
ColorspaceType colorspace
Definition: image.h:157
#define QuantumRange
Definition: magick-type.h:83
MagickBooleanType debug
Definition: image.h:334
MagickExport MatrixInfo * DestroyMatrixInfo(MatrixInfo *matrix_info)
Definition: matrix.c:369
size_t depth
Definition: image.h:172