mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-21 20:12:30 +00:00
Fixed code in gimp_transform_resize_crop() to calculate the maximum
2006-12-16 Mukund Sivaraman <muks@mukund.org> * app/core/gimp-transform-resize.c: Fixed code in gimp_transform_resize_crop() to calculate the maximum rectangle in the quadrilateral which results after a transform; added a function parameter for aspect ratio too.
This commit is contained in:
parent
3c5b0e2530
commit
ef51d1b89f
|
@ -1,3 +1,10 @@
|
|||
2006-12-16 Mukund Sivaraman <muks@mukund.org>
|
||||
|
||||
* app/core/gimp-transform-resize.c: Fixed code in
|
||||
gimp_transform_resize_crop() to calculate the maximum rectangle in
|
||||
the quadrilateral which results after a transform; added a function
|
||||
parameter for aspect ratio too.
|
||||
|
||||
2006-12-16 Tor Lillqvist <tml@novell.com>
|
||||
|
||||
* app/core/gimptooloptions.c: On Win32, include gimpwin32-io.h for
|
||||
|
|
|
@ -76,6 +76,7 @@ static void gimp_transform_resize_crop (gdouble dx1,
|
|||
gdouble dy3,
|
||||
gdouble dx4,
|
||||
gdouble dy4,
|
||||
gdouble aspect,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
|
@ -139,6 +140,7 @@ gimp_transform_resize_boundary (const GimpMatrix3 *inv,
|
|||
|
||||
case GIMP_TRANSFORM_SIZE_CROP:
|
||||
gimp_transform_resize_crop (dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4,
|
||||
0.0,
|
||||
x1, y1, x2, y2);
|
||||
break;
|
||||
}
|
||||
|
@ -178,6 +180,7 @@ edge_init (Edge *edge,
|
|||
{
|
||||
edge->xmin = MIN (ceil (p->x), ceil (q->x));
|
||||
edge->xmax = MAX (floor (p->x), floor (q->x));
|
||||
|
||||
edge->ymin = MIN (ceil (p->y), ceil (q->y));
|
||||
edge->ymax = MAX (floor (p->y), floor (q->y));
|
||||
|
||||
|
@ -194,15 +197,15 @@ find_edge (const Edge *edges,
|
|||
gboolean top)
|
||||
{
|
||||
const Edge *emax = edges;
|
||||
const Edge *e = edges;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
const Edge *e = edges + i;
|
||||
|
||||
if (e->xmin == x && e->xmax != e->xmin &&
|
||||
if ((e->xmin == x) && (e->xmax != e->xmin) &&
|
||||
((e->top && top) || (!e->top && !top)))
|
||||
emax = e;
|
||||
e++;
|
||||
}
|
||||
|
||||
return emax;
|
||||
|
@ -222,8 +225,8 @@ intersect_x (const Edge *edges,
|
|||
for (i = 0; i < 4; i++)
|
||||
if (edges[i].right && edges[i].ymin <= y && edges[i].ymax >= y)
|
||||
{
|
||||
x0 = (double) (y + 0.5 - edges[i].b) / edges[i].m;
|
||||
x1 = (double) (y - 0.5 - edges[i].b) / edges[i].m;
|
||||
x0 = (y + 0.5 - edges[i].b) / edges[i].m;
|
||||
x1 = (y - 0.5 - edges[i].b) / edges[i].m;
|
||||
}
|
||||
|
||||
return (gint) floor (MIN (x0, x1));
|
||||
|
@ -236,7 +239,7 @@ intersect_y (const Edge *edge,
|
|||
gdouble yfirst = edge->m * (xi - 0.5) + edge->b;
|
||||
gdouble ylast = edge->m * (xi + 0.5) + edge->b;
|
||||
|
||||
return (gint) floor (edge->top ? MAX (yfirst, ylast) : MIN (yfirst, ylast));
|
||||
return (gint) (edge->top ? ceil (MAX (yfirst, ylast)) : floor (MIN (yfirst, ylast)));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -248,6 +251,7 @@ gimp_transform_resize_crop (gdouble dx1,
|
|||
gdouble dy3,
|
||||
gdouble dx4,
|
||||
gdouble dy4,
|
||||
gdouble aspect,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
|
@ -259,11 +263,13 @@ gimp_transform_resize_crop (gdouble dx1,
|
|||
const Point *b;
|
||||
const Edge *top;
|
||||
const Edge *bottom;
|
||||
gint *px;
|
||||
gint xmin, ymin;
|
||||
gint xmax, ymax;
|
||||
gint cxmin, cymin;
|
||||
gint cxmax, cymax;
|
||||
Point *xint;
|
||||
|
||||
gint ymin, ymax;
|
||||
gint maxarea = 0;
|
||||
gint xi, y;
|
||||
gint xi;
|
||||
gint i;
|
||||
|
||||
/* fill in the points array */
|
||||
|
@ -277,48 +283,47 @@ gimp_transform_resize_crop (gdouble dx1,
|
|||
points[3].y = dy4;
|
||||
|
||||
/* create an array of edges */
|
||||
|
||||
cxmin = cxmax = points[3].x;
|
||||
cymin = cymax = points[3].y;
|
||||
|
||||
for (i = 0, a = points + 3, b = points; i < 4; i++, a = b, b++)
|
||||
edge_init (edges + i, a, b);
|
||||
|
||||
/* determine the bounding box */
|
||||
xmin = edges[0].xmin;
|
||||
xmax = edges[0].xmax;
|
||||
ymin = edges[0].ymin;
|
||||
ymax = edges[0].ymax;
|
||||
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
const Edge *edge = edges + i;
|
||||
if (G_UNLIKELY(i == 0))
|
||||
{
|
||||
cxmin = cxmax = a->x;
|
||||
cymin = cymax = a->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a->x < cxmin)
|
||||
cxmin = a->x;
|
||||
|
||||
if (edge->xmin < xmin)
|
||||
xmin = edge->xmin;
|
||||
if (a->x > cxmax)
|
||||
cxmax = a->x;
|
||||
|
||||
if (edge->xmax > xmax)
|
||||
xmax = edge->xmax;
|
||||
if (a->y < cymin)
|
||||
cymin = a->y;
|
||||
|
||||
if (edge->ymin < ymin)
|
||||
ymin = edge->ymin;
|
||||
if (a->y > cymax)
|
||||
cymax = a->y;
|
||||
}
|
||||
|
||||
if (edge->ymax > ymax)
|
||||
ymax = edge->ymax;
|
||||
edge_init (edges + i, a, b);
|
||||
}
|
||||
|
||||
g_printerr ("%d, %d -> %d, %d\n", xmin, ymin, xmax, ymax);
|
||||
xint = g_new (Point, cymax);
|
||||
|
||||
px = g_new (gint, ymax - ymin + 1);
|
||||
for (i = 0; i < cymax; i++)
|
||||
{
|
||||
xint[i].x = intersect_x (edges, i);
|
||||
xint[i].y = i;
|
||||
}
|
||||
|
||||
for (y = ymin, i = 0; y <= ymax; y++, i++)
|
||||
px[i] = intersect_x (edges, y);
|
||||
top = find_edge (edges, cxmin, TRUE);
|
||||
bottom = find_edge (edges, cxmin, FALSE);
|
||||
|
||||
top = find_edge (edges, xmin, TRUE);
|
||||
bottom = find_edge (edges, xmax, FALSE);
|
||||
|
||||
g_printerr ("top: %d, %d -> %d, %d\n",
|
||||
top->xmin, top->ymin, top->xmax, top->ymax);
|
||||
g_printerr ("bottom: %d, %d -> %d, %d\n",
|
||||
bottom->xmin, bottom->ymin, bottom->xmax, bottom->ymax);
|
||||
|
||||
for (xi = xmin; xi < xmax; xi++)
|
||||
for (xi = cxmin; xi < cxmax; xi++)
|
||||
{
|
||||
gint ylo, yhi;
|
||||
|
||||
|
@ -331,11 +336,30 @@ gimp_transform_resize_crop (gdouble dx1,
|
|||
{
|
||||
if (yhi > ylo)
|
||||
{
|
||||
gint xlo = px[ylo - ymin];
|
||||
gint xhi = px[yhi - ymin];
|
||||
gint width = MIN (xlo, xhi) - xi;
|
||||
gint height = yhi - ylo;
|
||||
gint area = width * height;
|
||||
gint xlo, xhi;
|
||||
gint xright;
|
||||
gint height, width, fixed_width;
|
||||
gint area;
|
||||
|
||||
xlo = xint[ylo].x;
|
||||
xhi = xint[yhi].x;
|
||||
|
||||
xright = MIN (xlo, xhi);
|
||||
|
||||
height = yhi - ylo;
|
||||
width = xright - xi;
|
||||
|
||||
if (aspect != 0)
|
||||
{
|
||||
fixed_width = (int) ceil((gdouble) height * aspect);
|
||||
|
||||
if (fixed_width <= width)
|
||||
width = fixed_width;
|
||||
else
|
||||
width = 0;
|
||||
}
|
||||
|
||||
area = width * height;
|
||||
|
||||
if (area > maxarea)
|
||||
{
|
||||
|
@ -357,7 +381,5 @@ gimp_transform_resize_crop (gdouble dx1,
|
|||
bottom = find_edge (edges, xi, FALSE);
|
||||
}
|
||||
|
||||
g_printerr ("%d, %d -> %d, %d\n", *x1, *y1, *x2, *y2);
|
||||
|
||||
g_free (px);
|
||||
g_free (xint);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue