138 const size_t height,
const ssize_t x_offset,
const ssize_t y_offset,
189 (ssize_t) image->
rows-1,1,1,exception);
202 if (artifact != (
const char *) NULL)
205 if (artifact != (
const char *) NULL)
207 edge_geometry.
width=width;
208 edge_geometry.
height=height;
209 edge_geometry.
x=x_offset;
210 edge_geometry.
y=y_offset;
212 edge_image=
CropImage(image,&edge_geometry,exception);
213 if (edge_image == (
Image *) NULL)
217 for (y=0; y < (ssize_t) edge_image->
rows; y++)
223 if (p == (
const Quantum *) NULL)
225 for (x=0; x < (ssize_t) edge_image->
columns; x++)
233 census/=((double) edge_image->
columns*edge_image->
rows);
275 assert(image != (
Image *) NULL);
281 if (edge_image == (
Image *) NULL)
284 (void) memset(&vertex,0,
sizeof(vertex));
294 percent_background=1.0;
296 if (artifact != (
const char *) NULL)
301 for ( ; background_census < percent_background;
315 vertex.
top,exception);
318 vertex.
top,exception);
333 vertex.
top,exception);
336 vertex.
top,exception);
351 vertex.
top,exception);
354 vertex.
top,exception);
357 vertex.
top,exception);
369 vertex.
top,exception);
372 vertex.
top,exception);
381 bounds.
x=(ssize_t) vertex.
left;
382 bounds.
y=(ssize_t) vertex.
top;
385 "GeometryDoesNotContainImage",
"`%s'",image->
filename);
414 assert(image != (
Image *) NULL);
419 if (artifact != (
const char *) NULL)
422 if (artifact == (
const char *) NULL)
427 bounds.
y=(ssize_t) image->
rows;
445 bounds.
y=(ssize_t) image->
rows;
458 if (p == (
const Quantum *) NULL)
467 if (p != (
const Quantum *) NULL)
472 if (p != (
const Quantum *) NULL)
476 #if defined(MAGICKCORE_OPENMP_SUPPORT) 477 #pragma omp parallel for schedule(static) shared(status) \ 478 magick_number_threads(image,image,image->rows,1) 480 for (y=0; y < (ssize_t) image->
rows; y++)
496 #if defined(MAGICKCORE_OPENMP_SUPPORT) 497 # pragma omp critical (MagickCore_GetImageBoundingBox) 501 if (p == (
const Quantum *) NULL)
507 for (x=0; x < (ssize_t) image->
columns; x++)
510 if ((x < bounding_box.
x) &&
513 if ((x > (ssize_t) bounding_box.
width) &&
515 bounding_box.
width=(size_t) x;
516 if ((y < bounding_box.
y) &&
519 if ((y > (ssize_t) bounding_box.
height) &&
521 bounding_box.
height=(size_t) y;
524 #if defined(MAGICKCORE_OPENMP_SUPPORT) 525 # pragma omp critical (MagickCore_GetImageBoundingBox) 528 if (bounding_box.
x < bounds.
x)
529 bounds.
x=bounding_box.
x;
530 if (bounding_box.
y < bounds.
y)
531 bounds.
y=bounding_box.
y;
541 "GeometryDoesNotContainImage",
"`%s'",image->
filename);
544 bounds.
width-=(bounds.
x-1);
583 return((b->
x-a->
x)*(c->
y-a->
y)-(b->
y-a->
y)*(c->
x-a->
x));
607 if (artifact == (
const char *) NULL)
609 #if defined(MAGICKCORE_OPENMP_SUPPORT) 610 #pragma omp parallel for schedule(static) 612 for (i=0; i < 4; i++)
636 (void) memset(&edge_geometry,0,
sizeof(edge_geometry));
645 edge_geometry.
width=1;
653 edge_geometry.
width=1;
660 edge_geometry.
width=0;
666 (ssize_t) image->
rows-1,1,1,exception);
668 edge_geometry.
width=0;
673 if (artifact != (
const char *) NULL)
677 edge_image=
CropImage(image,&edge_geometry,exception);
678 if (edge_image == (
Image *) NULL)
681 for (y=0; y < (ssize_t) edge_image->
rows; y++)
688 if (p == (
const Quantum *) NULL)
690 for (x=0; x < (ssize_t) edge_image->
columns; x++)
702 for (i=0; i < 4; i++)
703 if (census[i] > edge_census)
705 edge_background=background[i];
706 edge_census=census[i];
708 return(edge_background);
712 PointInfo ***monotone_chain,
size_t *chain_length)
727 chain=(*monotone_chain);
729 for (i=0; i < (ssize_t) number_vertices; i++)
734 chain[n++]=(&vertices[i]);
737 for (i=(ssize_t) number_vertices-2; i >= 0; i--)
739 while ((n >= demark) &&
742 chain[n++]=(&vertices[i]);
777 assert(image != (
Image *) NULL);
785 image->
rows*
sizeof(*monotone_chain));
801 for (y=0; y < (ssize_t) image->
rows; y++)
812 if (p == (
const Quantum *) NULL)
817 for (x=0; x < (ssize_t) image->
columns; x++)
825 vertices[n].
x=(double) x;
826 vertices[n].
y=(double) y;
838 sizeof(*convex_hull));
840 for (n=0; n < *number_vertices; n++)
841 convex_hull[n]=(*monotone_chain[n]);
893 assert(image != (
Image *) NULL);
899 sizeof(*current_depth));
900 if (current_depth == (
size_t *) NULL)
903 for (i=0; i < (ssize_t) number_threads; i++)
908 for (i=0; i < (ssize_t) image->
colors; i++)
939 depth=current_depth[0];
940 for (i=1; i < (ssize_t) number_threads; i++)
941 if (depth < current_depth[i])
942 depth=current_depth[i];
947 #if !defined(MAGICKCORE_HDRI_SUPPORT) 957 if (depth_map == (
size_t *) NULL)
959 for (i=0; i <= (ssize_t)
MaxMap; i++)
979 #if defined(MAGICKCORE_OPENMP_SUPPORT) 980 #pragma omp parallel for schedule(static) shared(status) \ 981 magick_number_threads(image,image,image->rows,1) 983 for (y=0; y < (ssize_t) image->
rows; y++)
997 if (p == (
const Quantum *) NULL)
999 for (x=0; x < (ssize_t) image->
columns; x++)
1010 if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[
id])
1011 current_depth[id]=depth_map[ScaleQuantumToMap(p[i])];
1019 depth=current_depth[0];
1020 for (i=1; i < (ssize_t) number_threads; i++)
1021 if (depth < current_depth[i])
1022 depth=current_depth[i];
1031 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1032 #pragma omp parallel for schedule(static) shared(status) \ 1033 magick_number_threads(image,image,image->rows,1) 1035 for (y=0; y < (ssize_t) image->
rows; y++)
1049 if (p == (
const Quantum *) NULL)
1051 for (x=0; x < (ssize_t) image->
columns; x++)
1076 current_depth[id]++;
1085 depth=current_depth[0];
1086 for (i=1; i < (ssize_t) number_threads; i++)
1087 if (depth < current_depth[i])
1088 depth=current_depth[i];
1152 distance=hypot(p->
x-q->
x,p->
y-q->
y);
1153 return(distance*distance);
1167 return((q->
x-p->
x)*(v->
x-p->
x)+(v->
y-p->
y)*(q->
y-p->
y))/sqrt(distance);
1181 return((q->
x-p->
x)*(v->
y-p->
y)-(v->
x-p->
x)*(q->
y-p->
y))/sqrt(distance);
1206 number_hull_vertices;
1211 assert(image != (
Image *) NULL);
1221 sizeof(*bounding_box));
1231 caliper_info.
p=(-1);
1232 caliper_info.
q=(-1);
1233 caliper_info.
v=(-1);
1234 for (i=0; i < (ssize_t) number_hull_vertices; i++)
1238 max_projection = 0.0,
1239 min_diameter = -1.0,
1240 min_projection = 0.0;
1251 for (j=0; j < (ssize_t) number_hull_vertices; j++)
1257 &vertices[(i+1) % number_hull_vertices],&vertices[j]));
1258 if (min_diameter < diameter)
1260 min_diameter=diameter;
1262 q=(i+1) % number_hull_vertices;
1266 for (k=0; k < (ssize_t) number_hull_vertices; k++)
1274 projection=
getProjection(&vertices[p],&vertices[q],&vertices[k]);
1275 min_projection=
MagickMin(min_projection,projection);
1276 max_projection=
MagickMax(max_projection,projection);
1278 area=min_diameter*(max_projection-min_projection);
1279 if (caliper_info.
area > area)
1281 caliper_info.
area=area;
1282 caliper_info.
width=min_diameter;
1283 caliper_info.
height=max_projection-min_projection;
1294 &vertices[caliper_info.
q],&vertices[caliper_info.
v]);
1295 angle=atan2(vertices[caliper_info.
q].
y-vertices[caliper_info.
p].
y,
1296 vertices[caliper_info.
q].
x-vertices[caliper_info.
p].
x);
1297 bounding_box[0].
x=vertices[caliper_info.
p].
x+cos(angle)*
1299 bounding_box[0].
y=vertices[caliper_info.
p].
y+sin(angle)*
1301 bounding_box[1].
x=floor(bounding_box[0].x+cos(angle+
MagickPI/2.0)*diameter+
1303 bounding_box[1].
y=floor(bounding_box[0].y+sin(angle+
MagickPI/2.0)*diameter+
1305 bounding_box[2].
x=floor(bounding_box[1].x+cos(angle)*(-caliper_info.
height)+
1307 bounding_box[2].
y=floor(bounding_box[1].y+sin(angle)*(-caliper_info.
height)+
1309 bounding_box[3].
x=floor(bounding_box[2].x+cos(angle+
MagickPI/2.0)*(-diameter)+
1311 bounding_box[3].
y=floor(bounding_box[2].y+sin(angle+
MagickPI/2.0)*(-diameter)+
1334 distance=hypot(bounding_box[0].x,bounding_box[0].y);
1335 angle=
getAngle(&bounding_box[0],&bounding_box[1]);
1336 for (i=1; i < 4; i++)
1338 double d = hypot(bounding_box[i].x,bounding_box[i].y);
1342 angle=
getAngle(&bounding_box[i],&bounding_box[(i+1) % 4]);
1346 if (artifact != (
const char *) NULL)
1360 point=bounding_box[0];
1361 for (i=1; i < 4; i++)
1363 if (bounding_box[i].x < point.
x)
1364 point.
x=bounding_box[i].
x;
1365 if (bounding_box[i].y < point.
y)
1366 point.
y=bounding_box[i].
y;
1368 for (i=0; i < 4; i++)
1370 bounding_box[i].
x-=point.
x;
1371 bounding_box[i].
y-=point.
y;
1373 for (i=0; i < 4; i++)
1380 delta.
x=bounding_box[(i+1) % 4].x-bounding_box[i].x;
1381 delta.
y=bounding_box[(i+1) % 4].y-bounding_box[i].y;
1383 intercept=bounding_box[(i+1) % 4].y-slope*bounding_box[i].x;
1384 d=fabs((slope*bounding_box[i].x-bounding_box[i].y+intercept)*
1386 if ((i == 0) || (d < distance))
1393 length=hypot(point.
x,point.
y);
1400 if (p_length > q_length)
1401 angle+=(angle < 0.0) ? 90.0 : -90.0;
1406 if (p_length < q_length)
1407 angle+=(angle >= 0.0) ? 90.0 : -90.0;
1415 return(bounding_box);
1496 assert(image != (
Image *) NULL);
1567 assert(image != (
Image *) NULL);
1573 return(image->
type);
1578 for (y=0; y < (ssize_t) image->
rows; y++)
1581 if (p == (
const Quantum *) NULL)
1583 for (x=0; x < (ssize_t) image->
columns; x++)
1649 assert(image != (
Image *) NULL);
1659 for (y=0; y < (ssize_t) image->
rows; y++)
1662 if (p == (
const Quantum *) NULL)
1664 for (x=0; x < (ssize_t) image->
columns; x++)
1715 assert(image != (
Image *) NULL);
1769 assert(image != (
Image *) NULL);
1801 assert(image != (
Image *) NULL);
1854 assert(image != (
Image *) NULL);
1861 for (y=0; y < (ssize_t) image->
rows; y++)
1864 if (p == (
const Quantum *) NULL)
1866 for (x=0; x < (ssize_t) image->
columns; x++)
1872 if (x < (ssize_t) image->
columns)
1923 assert(image != (
Image *) NULL);
1938 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1939 #pragma omp parallel for schedule(static) shared(status) \ 1940 magick_number_threads(image,image,image->colors,1) 1942 for (i=0; i < (ssize_t) image->
colors; i++)
1960 #if !defined(MAGICKCORE_HDRI_SUPPORT) 1973 if (depth_map == (
Quantum *) NULL)
1975 for (i=0; i <= (ssize_t)
MaxMap; i++)
1978 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1979 #pragma omp parallel for schedule(static) shared(status) \ 1980 magick_number_threads(image,image,image->rows,1) 1982 for (y=0; y < (ssize_t) image->
rows; y++)
1999 for (x=0; x < (ssize_t) image->
columns; x++)
2016 q[i]=depth_map[ScaleQuantumToMap(q[i])];
2036 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2037 #pragma omp parallel for schedule(static) shared(status) \ 2038 magick_number_threads(image,image,image->rows,1) 2040 for (y=0; y < (ssize_t) image->
rows; y++)
2056 for (x=0; x < (ssize_t) image->
columns; x++)
2074 q[i]),range),range);
2137 assert(image != (
Image *) NULL);
2145 if (artifact != (
const char *) NULL)
MagickDoubleType MagickRealType
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
MagickExport MemoryInfo * RelinquishVirtualMemory(MemoryInfo *memory_info)
static MagickSizeType GetQuantumRange(const size_t depth)
MagickExport ImageInfo * AcquireImageInfo(void)
static RectangleInfo GetEdgeBoundingBox(const Image *image, ExceptionInfo *exception)
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)
static PixelTrait GetPixelAlphaTraits(const Image *magick_restrict image)
ColorspaceType colorspace
static double getAngle(PointInfo *p, PointInfo *q)
MagickExport MagickBooleanType SetImageDepth(Image *image, const size_t depth, ExceptionInfo *exception)
#define ThrowFatalException(severity, tag)
MagickExport MemoryInfo * AcquireVirtualMemory(const size_t count, const size_t quantum)
void TraceConvexHull(PointInfo *vertices, size_t number_vertices, PointInfo ***monotone_chain, size_t *chain_length)
MagickExport ImageType IdentifyImageGray(const Image *image, ExceptionInfo *exception)
MagickExport MagickStatusType ParseAbsoluteGeometry(const char *geometry, RectangleInfo *region_info)
MagickExport QuantizeInfo * DestroyQuantizeInfo(QuantizeInfo *quantize_info)
MagickExport PointInfo * GetImageMinimumBoundingBox(Image *image, size_t *number_vertices, ExceptionInfo *exception)
MagickExport const char * GetImageArtifact(const Image *image, const char *artifact)
static double StringToDouble(const char *magick_restrict string, char **magick_restrict sentinal)
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
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)
MagickExport MagickBooleanType IdentifyImageMonochrome(const Image *image, ExceptionInfo *exception)
struct _CaliperInfo CaliperInfo
static Quantum ClampToQuantum(const MagickRealType quantum)
MagickExport void GetPixelInfo(const Image *image, PixelInfo *pixel)
MagickExport MagickBooleanType SetImageOption(ImageInfo *image_info, const char *option, const char *value)
struct _EdgeInfo EdgeInfo
#define MagickCoreSignature
MagickExport MagickBooleanType SetImageType(Image *image, const ImageType type, ExceptionInfo *exception)
MagickExport Quantum * GetCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
static Quantum ClampPixel(const MagickRealType pixel)
MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, const AlphaChannelOption alpha_type, ExceptionInfo *exception)
MagickExport char * AcquireString(const char *source)
static double PerceptibleReciprocal(const double x)
static Quantum ScaleAnyToQuantum(const QuantumAny quantum, const QuantumAny range)
static double getDistance(PointInfo *p, PointInfo *q)
static double getFeretDiameter(PointInfo *p, PointInfo *q, PointInfo *v)
static MagickBooleanType IssRGBCompatibleColorspace(const ColorspaceType colorspace)
MagickExport MagickBooleanType NormalizeImage(Image *image, ExceptionInfo *exception)
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
MagickExport ImageType GetImageType(const Image *image)
static int GetOpenMPThreadId(void)
static MagickBooleanType IsPixelAtDepth(const Quantum pixel, const QuantumAny range)
MagickExport PointInfo * GetImageConvexHull(const Image *image, size_t *number_vertices, ExceptionInfo *exception)
static void GetPixelInfoPixel(const Image *magick_restrict image, const Quantum *magick_restrict pixel, PixelInfo *magick_restrict pixel_info)
MagickExport int GetMagickPrecision(void)
MagickExport MagickBooleanType IdentifyPaletteImage(const Image *image, ExceptionInfo *exception)
MagickExport ChannelType SetImageChannelMask(Image *image, const ChannelType channel_mask)
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
MagickExport MagickBooleanType QuantizeImage(const QuantizeInfo *quantize_info, Image *image, ExceptionInfo *exception)
MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
MagickExport size_t GetImageQuantumDepth(const Image *image, const MagickBooleanType constrain)
static MagickBooleanType IsPixelGray(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport ImageType IdentifyImageType(const Image *image, ExceptionInfo *exception)
static PixelTrait GetPixelGreenTraits(const Image *magick_restrict image)
MagickExport MagickBooleanType QueryColorCompliance(const char *name, const ComplianceType compliance, PixelInfo *color, ExceptionInfo *exception)
MagickExport MagickBooleanType SetImageStorageClass(Image *image, const ClassType storage_class, ExceptionInfo *exception)
static double GetEdgeBackgroundCensus(const Image *image, const CacheView *image_view, const GravityType gravity, const size_t width, const size_t height, const ssize_t x_offset, const ssize_t y_offset, ExceptionInfo *exception)
static PixelInfo GetEdgeBackgroundColor(const Image *image, const CacheView *image_view, ExceptionInfo *exception)
static size_t GetPixelChannels(const Image *magick_restrict image)
MagickExport int LocaleCompare(const char *p, const char *q)
MagickExport MagickBooleanType IsPaletteImage(const Image *image)
MagickExport QuantizeInfo * AcquireQuantizeInfo(const ImageInfo *image_info)
static double LexicographicalOrder(PointInfo *a, PointInfo *b, PointInfo *c)
char filename[MagickPathExtent]
#define GetMagickModule()
static PixelChannel GetPixelChannelChannel(const Image *magick_restrict image, const ssize_t offset)
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
static double RadiansToDegrees(const double radians)
MagickExport ImageInfo * DestroyImageInfo(ImageInfo *image_info)
MagickExport char * StringToken(const char *delimiters, char **string)
MagickExport MagickBooleanType IsImageGray(const Image *image)
MagickExport size_t GetImageDepth(const Image *image, ExceptionInfo *exception)
MagickExport MagickBooleanType IsImageMonochrome(const Image *image)
MagickExport RectangleInfo GetImageBoundingBox(const Image *image, ExceptionInfo *exception)
MagickExport char * DestroyString(char *string)
MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p, const PixelInfo *q)
MagickExport void SetGeometry(const Image *image, RectangleInfo *geometry)
MagickExport MagickBooleanType BilevelImage(Image *image, const double threshold, ExceptionInfo *exception)
MagickExport void * RelinquishMagickMemory(void *memory)
MagickExport void GravityAdjustGeometry(const size_t width, const size_t height, const GravityType gravity, RectangleInfo *region)
MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *magick_restrict cache_view, ExceptionInfo *exception)
MagickExport MagickBooleanType FormatImageProperty(Image *image, const char *property, const char *format,...)
MagickExport CacheView * AcquireAuthenticCacheView(const Image *image, ExceptionInfo *exception)
static double GetMinEdgeBackgroundCensus(const EdgeInfo *edge)
MagickExport void * GetVirtualMemoryBlob(const MemoryInfo *memory_info)
static QuantumAny ScaleQuantumToAny(const Quantum quantum, const QuantumAny range)
MagickSizeType QuantumAny
MagickExport Image * DestroyImage(Image *image)
MagickExport Image * CloneImage(const Image *image, const size_t columns, const size_t rows, const MagickBooleanType detach, ExceptionInfo *exception)
static double getProjection(PointInfo *p, PointInfo *q, PointInfo *v)
ColorspaceType colorspace
MagickExport MagickBooleanType IsImageOpaque(const Image *image, ExceptionInfo *exception)
static PixelTrait GetPixelBlueTraits(const Image *magick_restrict image)