83#include <config_auto.h>
86#include "allheaders.h"
111l_int32 x1, y1, w1, h1, x2, y2, w2, h2, valid1, valid2;
114 return ERROR_INT(
"&result not defined", __func__, 1);
117 return ERROR_INT(
"boxes not both defined", __func__, 1);
118 boxIsValid(box1, &valid1);
119 boxIsValid(box2, &valid2);
120 if (!valid1 || !valid2)
121 return ERROR_INT(
"boxes not both valid", __func__, 1);
123 boxGetGeometry(box1, &x1, &y1, &w1, &h1);
124 boxGetGeometry(box2, &x2, &y2, &w2, &h2);
125 if (x1 <= x2 && y1 <= y2 && (x1 + w1 >= x2 + w2) && (y1 + h1 >= y2 + h2))
144l_int32 l1, l2, r1, r2, t1, t2, b1, b2, w1, h1, w2, h2, valid1, valid2;
147 return ERROR_INT(
"&result not defined", __func__, 1);
150 return ERROR_INT(
"boxes not both defined", __func__, 1);
151 boxIsValid(box1, &valid1);
152 boxIsValid(box2, &valid2);
153 if (!valid1 || !valid2)
154 return ERROR_INT(
"boxes not both valid", __func__, 1);
156 boxGetGeometry(box1, &l1, &t1, &w1, &h1);
157 boxGetGeometry(box2, &l2, &t2, &w2, &h2);
162 if (b2 < t1 || b1 < t2 || r1 < l2 || r2 < l1)
188l_int32 i, n, val, valid;
193 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
195 return (
BOXA *)ERROR_PTR(
"box not defined", __func__, NULL);
196 n = boxaGetCount(boxas);
197 boxIsValid(box, &valid);
198 if (n == 0 || !valid)
199 return boxaCreate(1);
201 boxad = boxaCreate(0);
202 for (i = 0; i < n; i++) {
203 if ((box1 = boxaGetValidBox(boxas, i,
L_CLONE)) == NULL)
207 boxaAddBox(boxad, box1,
L_COPY);
233l_int32 i, n, val, valid;
237 return ERROR_INT(
"&count not defined", __func__, 1);
240 return ERROR_INT(
"boxa not defined", __func__, 1);
242 return ERROR_INT(
"box not defined", __func__, 1);
243 n = boxaGetCount(boxa);
244 boxIsValid(box, &valid);
245 if (n == 0 || !valid)
248 for (i = 0; i < n; i++) {
249 if ((box1 = boxaGetValidBox(boxa, i,
L_CLONE)) == NULL)
273l_int32 i, j, n1, n2, cont, result;
277 return ERROR_INT(
"&contained not defined", __func__, 1);
279 if (!boxa1 || !boxa2)
280 return ERROR_INT(
"boxa1 and boxa2 not both defined", __func__, 1);
282 n1 = boxaGetCount(boxa1);
283 n2 = boxaGetCount(boxa2);
284 for (i = 0; i < n2; i++) {
285 if ((box2 = boxaGetValidBox(boxa2, i,
L_CLONE)) == NULL)
288 for (j = 0; j < n1; j++) {
289 if ((box1 = boxaGetValidBox(boxa1, j,
L_CLONE)) == NULL)
325l_int32 i, n, val, valid;
330 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
332 return (
BOXA *)ERROR_PTR(
"box not defined", __func__, NULL);
333 n = boxaGetCount(boxas);
334 boxIsValid(box, &valid);
335 if (n == 0 || !valid)
336 return boxaCreate(1);
338 boxad = boxaCreate(0);
339 for (i = 0; i < n; i++) {
340 if ((box1 = boxaGetValidBox(boxas, i,
L_CLONE)) == NULL)
344 boxaAddBox(boxad, box1,
L_COPY);
365l_int32 i, n, val, valid;
369 return ERROR_INT(
"&count not defined", __func__, 1);
372 return ERROR_INT(
"boxa not defined", __func__, 1);
374 return ERROR_INT(
"box not defined", __func__, 1);
375 n = boxaGetCount(boxa);
376 boxIsValid(box, &valid);
377 if (n == 0 || !valid)
380 for (i = 0; i < n; i++) {
381 if ((box1 = boxaGetValidBox(boxa, i,
L_CLONE)) == NULL)
414 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
416 return (
BOXA *)ERROR_PTR(
"box not defined", __func__, NULL);
417 n = boxaGetCount(boxas);
418 boxIsValid(box, &valid);
419 if (n == 0 || !valid)
420 return boxaCreate(1);
422 boxad = boxaCreate(0);
423 for (i = 0; i < n; i++) {
424 if ((box1 = boxaGetValidBox(boxas, i,
L_CLONE)) == NULL)
466l_int32 i, j, w, h, n1, n2, overlap, niters;
467BOX *box1, *box2, *box3;
472 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
474 if (pixadb) boxaGetExtent(boxas, &w, &h, NULL);
476 boxa1 = boxaCopy(boxas,
L_COPY);
477 n1 = boxaGetCount(boxa1);
482 pix1 = pixCreate(w + 5, h + 5, 32);
484 pixRenderBoxaArb(pix1, boxa1, 2, 255, 0, 0);
485 pixaAddPix(pixadb, pix1,
L_COPY);
489 for (i = 0; i < n1; i++) {
490 if ((box1 = boxaGetValidBox(boxa1, i,
L_COPY)) == NULL)
492 for (j = i + 1; j < n1; j++) {
493 if ((box2 = boxaGetValidBox(boxa1, j,
L_COPY)) == NULL)
498 boxaReplaceBox(boxa1, i, box3);
499 boxaReplaceBox(boxa1, j, boxCreate(0, 0, 0, 0));
501 box1 = boxCopy(box3);
507 boxa2 = boxaSaveValid(boxa1,
L_COPY);
508 n2 = boxaGetCount(boxa2);
512 if (pixadb) pixDestroy(&pix1);
517 pixRenderBoxaArb(pix1, boxa1, 2, 0, 255, 0);
523 L_INFO(
"number of iterations: %d\n", __func__, niters);
561l_int32 i, j, w, h, w2, h2, n1, n2, n1i, n2i, niters;
562l_int32 overlap, bigger, area1, area2;
563BOX *box1, *box2, *box3;
564BOXA *boxa1, *boxa2, *boxac1, *boxac2;
567 if (pboxad1) *pboxad1 = NULL;
568 if (pboxad2) *pboxad2 = NULL;
569 if (!boxas1 || !boxas2)
570 return ERROR_INT(
"boxas1 and boxas2 not both defined", __func__, 1);
571 if (!pboxad1 || !pboxad2)
572 return ERROR_INT(
"&boxad1 and &boxad2 not both defined", __func__, 1);
575 boxaGetExtent(boxas1, &w, &h, NULL);
576 boxaGetExtent(boxas2, &w2, &h2, NULL);
582 boxaGetArea(boxas1, &area1);
583 boxaGetArea(boxas2, &area2);
584 if (area1 >= area2) {
585 boxac1 = boxaCopy(boxas1,
L_COPY);
586 boxac2 = boxaCopy(boxas2,
L_COPY);
588 boxac1 = boxaCopy(boxas2,
L_COPY);
589 boxac2 = boxaCopy(boxas1,
L_COPY);
592 n1i = boxaGetCount(boxac1);
593 n2i = boxaGetCount(boxac2);
598 pix1 = pixCreate(w + 5, h + 5, 32);
600 pixRenderBoxaArb(pix1, boxac1, 2, 255, 0, 0);
601 pixRenderBoxaArb(pix1, boxac2, 2, 0, 255, 0);
610 n1 = boxaGetCount(boxa1);
611 n2 = boxaGetCount(boxa2);
612 for (i = 0; i < n1; i++) {
613 if ((box1 = boxaGetValidBox(boxa1, i,
L_COPY)) == NULL)
615 for (j = 0; j < n2; j++) {
616 if ((box2 = boxaGetValidBox(boxa2, j,
L_COPY)) == NULL)
620 if (overlap && (bigger == 1)) {
622 boxaReplaceBox(boxa1, i, box3);
623 boxaReplaceBox(boxa2, j, boxCreate(0, 0, 0, 0));
625 box1 = boxCopy(box3);
631 for (i = 0; i < n2; i++) {
632 if ((box2 = boxaGetValidBox(boxa2, i,
L_COPY)) == NULL)
634 for (j = 0; j < n1; j++) {
635 if ((box1 = boxaGetValidBox(boxa1, j,
L_COPY)) == NULL)
639 if (overlap && (bigger == 1)) {
641 boxaReplaceBox(boxa2, i, box3);
642 boxaReplaceBox(boxa1, j, boxCreate(0, 0, 0, 0));
644 box2 = boxCopy(box3);
650 boxaDestroy(&boxac1);
651 boxaDestroy(&boxac2);
652 boxac1 = boxaSaveValid(boxa1,
L_COPY);
653 boxac2 = boxaSaveValid(boxa2,
L_COPY);
656 n1 = boxaGetCount(boxac1);
657 n2 = boxaGetCount(boxac2);
658 if (n1 == n1i && n2 == n2i)
break;
662 pix1 = pixCreate(w + 5, h + 5, 32);
664 pixRenderBoxaArb(pix1, boxac1, 2, 255, 0, 0);
665 pixRenderBoxaArb(pix1, boxac2, 2, 0, 255, 0);
671 L_INFO(
"number of iterations: %d\n", __func__, niters);
694l_int32 l1, l2, r1, r2, t1, t2, b1, b2, w1, h1, w2, h2, ld, td, rd, bd;
695l_int32 valid1, valid2;
698 return (
BOX *)ERROR_PTR(
"boxes not both defined", __func__, NULL);
699 boxIsValid(box1, &valid1);
700 boxIsValid(box2, &valid2);
701 if (!valid1 || !valid2) {
702 L_WARNING(
"at least one box is invalid\n", __func__);
706 boxGetGeometry(box1, &l1, &t1, &w1, &h1);
707 boxGetGeometry(box2, &l2, &t2, &w2, &h2);
712 if (b2 < t1 || b1 < t2 || r1 < l2 || r2 < l1)
719 return boxCreate(ld, td, rd - ld + 1, bd - td + 1);
742l_int32 l1, l2, r1, r2, t1, t2, b1, b2, w1, h1, w2, h2, ld, td, rd, bd;
743l_int32 valid1, valid2;
746 return (
BOX *)ERROR_PTR(
"boxes not both defined", __func__, NULL);
747 boxIsValid(box1, &valid1);
748 boxIsValid(box2, &valid2);
749 if (!valid1 && !valid2) {
750 L_WARNING(
"both boxes are invalid\n", __func__);
751 return boxCreate(0, 0, 0, 0);
753 if (valid1 && !valid2)
754 return boxCopy(box1);
755 if (!valid1 && valid2)
756 return boxCopy(box2);
758 boxGetGeometry(box1, &l1, &t1, &w1, &h1);
759 boxGetGeometry(box2, &l2, &t2, &w2, &h2);
768 return boxCreate(ld, td, rd - ld + 1, bd - td + 1);
791l_int32 w2, h2, w, h, valid1, valid2;
795 return ERROR_INT(
"&fract not defined", __func__, 1);
798 return ERROR_INT(
"boxes not both defined", __func__, 1);
799 boxIsValid(box1, &valid1);
800 boxIsValid(box2, &valid2);
801 if (!valid1 || !valid2) {
802 L_WARNING(
"boxes not both valid\n", __func__);
809 boxGetGeometry(box2, NULL, NULL, &w2, &h2);
810 boxGetGeometry(boxo, NULL, NULL, &w, &h);
811 *pfract = (l_float32)(w * h) / (l_float32)(w2 * h2);
829l_int32 w, h, valid1, valid2;
833 return ERROR_INT(
"&area not defined", __func__, 1);
836 return ERROR_INT(
"boxes not both defined", __func__, 1);
837 boxIsValid(box1, &valid1);
838 boxIsValid(box2, &valid2);
839 if (!valid1 || !valid2)
840 return ERROR_INT(
"boxes not both valid", __func__, 1);
845 boxGetGeometry(box, NULL, NULL, &w, &h);
890 l_float32 min_overlap,
894l_int32 i, j, n, w, h, area1, area2, val;
896l_float32 overlap_ratio, area_ratio;
897BOX *box1, *box2, *box3;
901 if (pnamap) *pnamap = NULL;
903 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
905 return (
BOXA *)ERROR_PTR(
"invalid op", __func__, NULL);
907 n = boxaGetCount(boxas);
909 return boxaCreate(1);
911 L_WARNING(
"range is 0\n", __func__);
912 return boxaCopy(boxas,
L_COPY);
916 namap = numaMakeConstant(-1, n);
917 for (i = 0; i < n; i++) {
918 if ((box1 = boxaGetValidBox(boxas, i,
L_CLONE)) == NULL)
920 boxGetGeometry(box1, NULL, NULL, &w, &h);
926 for (j = i + 1; j < i + 1 + range && j < n; j++) {
927 if ((box2 = boxaGetValidBox(boxas, j,
L_CLONE)) == NULL)
930 if (overlap_area > 0) {
931 boxGetGeometry(box2, NULL, NULL, &w, &h);
935 }
else if (area1 >= area2) {
936 overlap_ratio = (l_float32)overlap_area / (l_float32)area2;
937 area_ratio = (l_float32)area2 / (l_float32)area1;
938 if (overlap_ratio >= min_overlap &&
939 area_ratio <= max_ratio) {
940 numaSetValue(namap, j, i);
943 overlap_ratio = (l_float32)overlap_area / (l_float32)area1;
944 area_ratio = (l_float32)area1 / (l_float32)area2;
945 if (overlap_ratio >= min_overlap &&
946 area_ratio <= max_ratio) {
947 numaSetValue(namap, i, j);
956 boxat = boxaCopy(boxas,
L_COPY);
959 for (i = 0; i < n; i++) {
960 numaGetIValue(namap, i, &val);
962 box1 = boxaGetBox(boxas, i,
L_CLONE);
963 box2 = boxaGetBox(boxas, val,
L_CLONE);
965 boxaReplaceBox(boxat, val, box3);
973 boxad = boxaCreate(n);
974 for (i = 0; i < n; i++) {
975 numaGetIValue(namap, i, &val);
977 box1 = boxaGetBox(boxat, i,
L_COPY);
1020l_int32 l1, t1, w1, h1, r1, b1, l2, t2, w2, h2, r2, b2, valid1, valid2;
1022 if (!ph_ovl && !pv_ovl)
1023 return ERROR_INT(
"nothing to do", __func__, 1);
1024 if (ph_ovl) *ph_ovl = 0;
1025 if (pv_ovl) *pv_ovl = 0;
1027 return ERROR_INT(
"boxes not both defined", __func__, 1);
1028 boxIsValid(box1, &valid1);
1029 boxIsValid(box2, &valid2);
1030 if (!valid1 || !valid2)
1031 return ERROR_INT(
"boxes not both valid", __func__, 1);
1034 boxGetGeometry(box1, &l1, NULL, &w1, NULL);
1035 boxGetGeometry(box2, &l2, NULL, &w2, NULL);
1044 boxGetGeometry(box1, NULL, &t1, NULL, &h1);
1045 boxGetGeometry(box2, NULL, &t2, NULL, &h2);
1091l_int32 h_ovl, v_ovl, valid1, valid2;
1093 if (ph_sep) *ph_sep = 0;
1094 if (pv_sep) *pv_sep = 0;
1095 if (!ph_sep || !pv_sep)
1096 return ERROR_INT(
"&h_sep and &v_sep not both defined", __func__, 1);
1098 return ERROR_INT(
"boxes not both defined", __func__, 1);
1099 boxIsValid(box1, &valid1);
1100 boxIsValid(box2, &valid2);
1101 if (!valid1 || !valid2)
1102 return ERROR_INT(
"boxes not both valid", __func__, 1);
1106 *ph_sep = -h_ovl + 1;
1108 *pv_sep = -v_ovl + 1;
1134l_int32 w1, h1, w2, h2, size1, size2, valid1, valid2;
1137 return ERROR_INT(
"&rel not defined", __func__, 1);
1140 return ERROR_INT(
"boxes not both defined", __func__, 1);
1141 boxIsValid(box1, &valid1);
1142 boxIsValid(box2, &valid2);
1143 if (!valid1 || !valid2)
1144 return ERROR_INT(
"boxes not both valid", __func__, 1);
1148 return ERROR_INT(
"invalid compare type", __func__, 1);
1150 boxGetGeometry(box1, NULL, NULL, &w1, &h1);
1151 boxGetGeometry(box2, NULL, NULL, &w2, &h2);
1153 *prel = (w1 > w2) ? 1 : ((w1 == w2) ? 0 : -1);
1155 *prel = (h1 > h2) ? 1 : ((h1 == h2) ? 0 : -1);
1157 size1 = L_MAX(w1, h1);
1158 size2 = L_MAX(w2, h2);
1159 *prel = (size1 > size2) ? 1 : ((size1 == size2) ? 0 : -1);
1163 *prel = (size1 > size2) ? 1 : ((size1 == size2) ? 0 : -1);
1167 *prel = (size1 > size2) ? 1 : ((size1 == size2) ? 0 : -1);
1187l_int32 bx, by, bw, bh;
1190 return ERROR_INT(
"&contains not defined", __func__, 1);
1193 return ERROR_INT(
"&box not defined", __func__, 1);
1194 boxGetGeometry(box, &bx, &by, &bw, &bh);
1195 if (x >= bx && x < bx + bw && y >= by && y < by + bh)
1219l_int32 i, n, minindex;
1220l_float32 delx, dely, dist, mindist, cx, cy;
1224 return (
BOX *)ERROR_PTR(
"boxa not defined", __func__, NULL);
1225 if ((n = boxaGetCount(boxa)) == 0)
1226 return (
BOX *)ERROR_PTR(
"n = 0", __func__, NULL);
1228 mindist = 1000000000.;
1230 for (i = 0; i < n; i++) {
1231 if ((box = boxaGetValidBox(boxa, i,
L_CLONE)) == NULL)
1234 delx = (l_float32)(cx - x);
1235 dely = (l_float32)(cy - y);
1236 dist = delx * delx + dely * dely;
1237 if (dist < mindist) {
1244 return boxaGetBox(boxa, minindex,
L_COPY);
1270l_int32 i, n, minindex;
1271l_float32 dist, mindist, cx, cy;
1275 return (
BOX *)ERROR_PTR(
"boxa not defined", __func__, NULL);
1276 if ((n = boxaGetCount(boxa)) == 0)
1277 return (
BOX *)ERROR_PTR(
"n = 0", __func__, NULL);
1278 if (y >= 0 && x >= 0)
1279 return (
BOX *)ERROR_PTR(
"either x or y must be < 0", __func__, NULL);
1281 return (
BOX *)ERROR_PTR(
"either x or y must be >= 0", __func__, NULL);
1283 mindist = 1000000000.;
1285 for (i = 0; i < n; i++) {
1286 if ((box = boxaGetValidBox(boxa, i,
L_CLONE)) == NULL)
1290 dist = L_ABS(cx - (l_float32)x);
1292 dist = L_ABS(cy - (l_float32)y);
1293 if (dist < mindist) {
1300 return boxaGetBox(boxa, minindex,
L_COPY);
1323 l_int32 dist_select,
1328l_int32 i, n, index, dist;
1332 if (pnaaindex) *pnaaindex = NULL;
1333 if (pnaadist) *pnaadist = NULL;
1335 return ERROR_INT(
"&naaindex not defined", __func__, 1);
1337 return ERROR_INT(
"&naadist not defined", __func__, 1);
1339 return ERROR_INT(
"boxa not defined", __func__, 1);
1341 n = boxaGetCount(boxa);
1342 naai = numaaCreate(n);
1343 naad = numaaCreate(n);
1346 for (i = 0; i < n; i++) {
1347 nai = numaCreate(4);
1348 nad = numaCreate(4);
1350 range, &index, &dist);
1351 numaAddNumber(nai, index);
1352 numaAddNumber(nad, dist);
1354 range, &index, &dist);
1355 numaAddNumber(nai, index);
1356 numaAddNumber(nad, dist);
1358 range, &index, &dist);
1359 numaAddNumber(nai, index);
1360 numaAddNumber(nad, dist);
1362 range, &index, &dist);
1363 numaAddNumber(nai, index);
1364 numaAddNumber(nad, dist);
1404 l_int32 dist_select,
1409l_int32 j, jmin, jmax, n, mindist, dist, index;
1410l_int32 x, y, w, h, bx, by, bw, bh;
1412 if (pindex) *pindex = -1;
1413 if (pdist) *pdist = 100000;
1415 return ERROR_INT(
"&index not defined", __func__, 1);
1417 return ERROR_INT(
"&dist not defined", __func__, 1);
1419 return ERROR_INT(
"boxa not defined", __func__, 1);
1422 return ERROR_INT(
"invalid dir", __func__, 1);
1424 return ERROR_INT(
"invalid dist_select", __func__, 1);
1425 n = boxaGetCount(boxa);
1426 if (i < 0 || i >= n)
1427 return ERROR_INT(
"invalid box index", __func__, 1);
1429 jmin = (range <= 0) ? 0 : L_MAX(0, i - range);
1430 jmax = (range <= 0) ? n - 1 : L_MIN(n -1, i + range);
1431 boxaGetBoxGeometry(boxa, i, &x, &y, &w, &h);
1435 for (j = jmin; j <= jmax; j++) {
1436 if (j == i)
continue;
1437 boxaGetBoxGeometry(boxa, j, &bx, &by, &bw, &bh);
1444 if (dist < mindist) {
1451 for (j = jmin; j <= jmax; j++) {
1452 if (j == i)
continue;
1453 boxaGetBoxGeometry(boxa, j, &bx, &by, &bw, &bh);
1460 if (dist < mindist) {
1497 ovlp = c2 + s2 - 1 - c1;
1499 ovlp = c1 + s1 - 1 - c2;
1500 return (ovlp < 0) ? 0 : 1;
1523 dist = c1 - (c2 + s2 - 1);
1525 dist = c2 - (c1 + s1 - 1);
1547 return ERROR_INT(
"&cx, &cy not both defined", __func__, 1);
1549 return ERROR_INT(
"box not defined", __func__, 1);
1550 boxGetGeometry(box, &x, &y, &w, &h);
1551 if (w == 0 || h == 0)
return 1;
1552 *pcx = (l_float32)(x + 0.5 * w);
1553 *pcy = (l_float32)(y + 0.5 * h);
1588l_int32 bx, by, bw, bh, xp, yp, xt, yt, i, n;
1597 if (!px1 || !py1 || !px2 || !py2)
1598 return ERROR_INT(
"&x1, &y1, &x2, &y2 not all defined", __func__, 1);
1600 return ERROR_INT(
"&n not defined", __func__, 1);
1602 return ERROR_INT(
"box not defined", __func__, 1);
1603 boxGetGeometry(box, &bx, &by, &bw, &bh);
1604 if (bw == 0 || bh == 0)
return 1;
1607 if (y >= by && y < by + bh) {
1615 if (slope > 1000000.0) {
1616 if (x >= bx && x < bx + bw) {
1626 invslope = 1.0 / slope;
1627 xp = (l_int32)(x + invslope * (y - by));
1628 if (xp >= bx && xp < bx + bw)
1629 ptaAddPt(pta, xp, by);
1630 xp = (l_int32)(x + invslope * (y - by - bh + 1));
1631 if (xp >= bx && xp < bx + bw)
1632 ptaAddPt(pta, xp, by + bh - 1);
1635 yp = (l_int32)(y + slope * (x - bx));
1636 if (yp >= by && yp < by + bh)
1637 ptaAddPt(pta, bx, yp);
1638 yp = (l_int32)(y + slope * (x - bx - bw + 1));
1639 if (yp >= by && yp < by + bh)
1640 ptaAddPt(pta, bx + bw - 1, yp);
1643 n = ptaGetCount(pta);
1645 ptaGetIPt(pta, 0, px1, py1);
1648 for (i = 1; i < n; i++) {
1649 ptaGetIPt(pta, i, &xt, &yt);
1650 if ((*px1 != xt) || (*py1 != yt)) {
1686 return (
BOX *)ERROR_PTR(
"box not defined", __func__, NULL);
1687 if (box->
x >= wi || box->
y >= hi ||
1688 box->
x + box->
w <= 0 || box->
y + box->
h <= 0)
1689 return (
BOX *)ERROR_PTR(
"box outside rectangle", __func__, NULL);
1691 boxd = boxCopy(box);
1700 if (boxd->
x + boxd->
w > wi)
1701 boxd->
w = wi - boxd->
x;
1702 if (boxd->
y + boxd->
h > hi)
1703 boxd->
h = hi - boxd->
y;
1747 if (pxstart) *pxstart = 0;
1748 if (pystart) *pystart = 0;
1749 if (pxend) *pxend = w;
1750 if (pyend) *pyend = h;
1753 if (!pxstart || !pystart || !pxend || !pyend)
1754 return ERROR_INT(
"invalid ptr input", __func__, 1);
1758 return ERROR_INT(
"box outside image", __func__, 1);
1759 boxGetGeometry(boxc, pxstart, pystart, &bw, &bh);
1764 if (bw == 0 || bh == 0)
1765 return ERROR_INT(
"invalid clipping box", __func__, 1);
1766 *pxend = *pxstart + bw;
1767 *pyend = *pystart + bh;
1802 return (
BOX *)ERROR_PTR(
"boxs not defined", __func__, NULL);
1804 boxd = boxCopy(boxs);
1806 boxGetGeometry(boxs, &x, &y, &w, &h);
1807 if (w == 0 || h == 0)
1810 boxSetGeometry(boxd, loc, -1, w + x - loc, -1);
1812 boxSetGeometry(boxd, -1, -1, loc - x + 1, -1);
1814 boxSetGeometry(boxd, -1, loc, -1, h + y - loc);
1816 boxSetGeometry(boxd, -1, -1, -1, loc - y + 1);
1849 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
1851 n = boxaGetCount(boxas);
1852 boxad = boxaCreate(n);
1853 for (i = 0; i < n; i++) {
1854 box1 = boxaGetBox(boxas, i,
L_COPY);
1855 box2 =
boxAdjustSides(NULL, box1, delleft, delright, deltop, delbot);
1857 boxGetGeometry(box1, &x, &y, NULL, NULL);
1858 box2 = boxCreate(x, y, 1, 1);
1896 return ERROR_INT(
"boxa not defined", __func__, 1);
1898 if ((box = boxaGetBox(boxa, index,
L_CLONE)) == NULL)
1899 return ERROR_INT(
"invalid index", __func__, 1);
1939l_int32 x, y, w, h, xl, xr, yt, yb, wnew, hnew;
1942 return (
BOX *)ERROR_PTR(
"boxs not defined", __func__, NULL);
1944 boxGetGeometry(boxs, &x, &y, &w, &h);
1945 xl = L_MAX(0, x + delleft);
1946 yt = L_MAX(0, y + deltop);
1947 xr = x + w + delright;
1948 yb = y + h + delbot;
1952 if (wnew < 1 || hnew < 1)
1953 return (
BOX *)ERROR_PTR(
"boxd has 0 area", __func__, NULL);
1955 return boxCreate(xl, yt, wnew, hnew);
1957 boxSetGeometry(boxd, xl, yt, wnew, hnew);
1992 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
1993 if (boxad && (boxas != boxad))
1994 return (
BOXA *)ERROR_PTR(
"not in-place", __func__, NULL);
1997 return (
BOXA *)ERROR_PTR(
"invalid side", __func__, NULL);
1999 return (
BOXA *)ERROR_PTR(
"val < 0", __func__, NULL);
2002 boxad = boxaCopy(boxas,
L_COPY);
2003 n = boxaGetCount(boxad);
2004 for (i = 0; i < n; i++) {
2005 box = boxaGetBox(boxad, i,
L_CLONE);
2035l_int32 x, y, w, h, diff;
2038 return ERROR_INT(
"box not defined", __func__, 1);
2041 return ERROR_INT(
"invalid side", __func__, 1);
2043 return ERROR_INT(
"val < 0", __func__, 1);
2045 boxGetGeometry(boxs, &x, &y, &w, &h);
2048 if (L_ABS(diff) >= thresh)
2049 boxSetGeometry(boxs, val, y, w + diff, h);
2051 diff = x + w -1 - val;
2052 if (L_ABS(diff) >= thresh)
2053 boxSetGeometry(boxs, x, y, val - x + 1, h);
2056 if (L_ABS(diff) >= thresh)
2057 boxSetGeometry(boxs, x, val, w, h + diff);
2059 diff = y + h - 1 - val;
2060 if (L_ABS(diff) >= thresh)
2061 boxSetGeometry(boxs, x, y, w, val - y + 1);
2096l_int32 x, y, w, h, n, i, diff;
2100 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
2101 if (boxad && (boxas != boxad))
2102 return (
BOXA *)ERROR_PTR(
"not in-place", __func__, NULL);
2105 return (
BOXA *)ERROR_PTR(
"invalid sides", __func__, NULL);
2107 return (
BOXA *)ERROR_PTR(
"target < 1", __func__, NULL);
2110 boxad = boxaCopy(boxas,
L_COPY);
2111 n = boxaGetCount(boxad);
2112 for (i = 0; i < n; i++) {
2113 if ((box = boxaGetValidBox(boxad, i,
L_CLONE)) == NULL)
2115 boxGetGeometry(box, &x, &y, &w, &h);
2118 if (L_ABS(diff) >= thresh)
2119 boxSetGeometry(box, L_MAX(0, x + diff), y, target, h);
2121 if (L_ABS(diff) >= thresh)
2122 boxSetGeometry(box, x, y, target, h);
2124 if (L_ABS(diff) >= thresh)
2125 boxSetGeometry(box, L_MAX(0, x + diff/2), y, target, h);
2162l_int32 x, y, w, h, n, i, diff;
2166 return (
BOXA *)ERROR_PTR(
"boxas not defined", __func__, NULL);
2167 if (boxad && (boxas != boxad))
2168 return (
BOXA *)ERROR_PTR(
"not in-place", __func__, NULL);
2171 return (
BOXA *)ERROR_PTR(
"invalid sides", __func__, NULL);
2173 return (
BOXA *)ERROR_PTR(
"target < 1", __func__, NULL);
2176 boxad = boxaCopy(boxas,
L_COPY);
2177 n = boxaGetCount(boxad);
2178 for (i = 0; i < n; i++) {
2179 if ((box = boxaGetValidBox(boxad, i,
L_CLONE)) == NULL)
2181 boxGetGeometry(box, &x, &y, &w, &h);
2184 if (L_ABS(diff) >= thresh)
2185 boxSetGeometry(box, x, L_MAX(0, y + diff), w, target);
2187 if (L_ABS(diff) >= thresh)
2188 boxSetGeometry(box, x, y, w, target);
2190 if (L_ABS(diff) >= thresh)
2191 boxSetGeometry(box, x, L_MAX(0, y + diff/2), w, target);
2214 return ERROR_INT(
"&same not defined", __func__, 1);
2217 return ERROR_INT(
"boxes not both defined", __func__, 1);
2218 if (box1->
x == box2->
x && box1->
y == box2->
y &&
2219 box1->
w == box2->
w && box1->
h == box2->
h)
2260l_int32 i, j, n, jstart, jend, found, samebox;
2265 if (pnaindex) *pnaindex = NULL;
2267 return ERROR_INT(
"&same not defined", __func__, 1);
2269 if (!boxa1 || !boxa2)
2270 return ERROR_INT(
"boxa1 and boxa2 not both defined", __func__, 1);
2271 n = boxaGetCount(boxa1);
2272 if (n != boxaGetCount(boxa2))
2275 if ((countarray = (l_int32 *)LEPT_CALLOC(n,
sizeof(l_int32))) == NULL)
2276 return ERROR_INT(
"calloc fail for countarray", __func__, 1);
2277 na = numaMakeConstant(0.0, n);
2279 for (i = 0; i < n; i++) {
2280 box1 = boxaGetBox(boxa1, i,
L_CLONE);
2281 jstart = L_MAX(0, i - maxdist);
2282 jend = L_MIN(n-1, i + maxdist);
2284 for (j = jstart; j <= jend; j++) {
2285 box2 = boxaGetBox(boxa2, j,
L_CLONE);
2287 if (samebox && countarray[j] == 0) {
2289 numaReplaceNumber(na, i, j);
2299 LEPT_FREE(countarray);
2309 LEPT_FREE(countarray);
2339l_int32 l1, l2, r1, r2, t1, t2, b1, b2, valid1, valid2;
2342 return ERROR_INT(
"&similar not defined", __func__, 1);
2345 return ERROR_INT(
"boxes not both defined", __func__, 1);
2346 boxIsValid(box1, &valid1);
2347 boxIsValid(box2, &valid2);
2348 if (!valid1 || !valid2)
2349 return ERROR_INT(
"boxes not both valid", __func__, 1);
2351 boxGetSideLocations(box1, &l1, &r1, &t1, &b1);
2352 boxGetSideLocations(box2, &l2, &r2, &t2, &b2);
2353 if (L_ABS(l1 - l2) > leftdiff)
2355 if (L_ABS(r1 - r2) > rightdiff)
2357 if (L_ABS(t1 - t2) > topdiff)
2359 if (L_ABS(b1 - b2) > botdiff)
2398l_int32 i, n1, n2, match, mismatch;
2401 if (psimilar) *psimilar = 0;
2402 if (pnasim) *pnasim = NULL;
2403 if (!boxa1 || !boxa2)
2404 return ERROR_INT(
"boxa1 and boxa2 not both defined", __func__, 1);
2406 return ERROR_INT(
"&similar not defined", __func__, 1);
2407 n1 = boxaGetCount(boxa1);
2408 n2 = boxaGetCount(boxa2);
2410 L_ERROR(
"boxa counts differ: %d vs %d\n", __func__, n1, n2);
2413 if (pnasim) *pnasim = numaCreate(n1);
2416 for (i = 0; i < n1; i++) {
2417 box1 = boxaGetBox(boxa1, i,
L_CLONE);
2418 box2 = boxaGetBox(boxa2, i,
L_CLONE);
2419 boxSimilar(box1, box2, leftdiff, rightdiff, topdiff, botdiff,
2424 numaAddNumber(*pnasim, match);
2427 if (!debug && pnasim == NULL)
2430 L_INFO(
"box %d not similar\n", __func__, i);
2434 if (!mismatch) *psimilar = 1;
2469 return ERROR_INT(
"boxad not defined", __func__, 1);
2470 if (!boxas || ((n = boxaGetCount(boxas)) == 0))
2475 if (iend < 0 || iend >= n)
2478 return ERROR_INT(
"istart > iend; nothing to add", __func__, 1);
2480 for (i = istart; i <= iend; i++) {
2481 box = boxaGetBox(boxas, i,
L_CLONE);
2516 return ERROR_INT(
"baad not defined", __func__, 1);
2522 n = boxaaGetCount(baas);
2523 if (iend < 0 || iend >= n)
2526 return ERROR_INT(
"istart > iend; nothing to add", __func__, 1);
2528 for (i = istart; i <= iend; i++) {
2529 boxa = boxaaGetBoxa(baas, i,
L_CLONE);
2530 boxaaAddBoxa(baad, boxa,
L_INSERT);
2563 if (pboxae) *pboxae = NULL;
2564 if (pboxao) *pboxao = NULL;
2565 if (!pboxae || !pboxao)
2566 return ERROR_INT(
"&boxae and &boxao not both defined", __func__, 1);
2568 return ERROR_INT(
"boxa not defined", __func__, 1);
2570 n = boxaGetCount(boxa);
2571 *pboxae = boxaCreate(n);
2572 *pboxao = boxaCreate(n);
2573 if (fillflag == 0) {
2575 for (i = 0; i < n; i++) {
2576 box = boxaGetBox(boxa, i,
L_COPY);
2578 boxaAddBox(*pboxae, box,
L_INSERT);
2580 boxaAddBox(*pboxao, box,
L_INSERT);
2583 for (i = 0; i < n; i++) {
2584 box = boxaGetBox(boxa, i,
L_COPY);
2585 box1 = boxCreate(0, 0, 0, 0);
2587 boxaAddBox(*pboxae, box,
L_INSERT);
2588 boxaAddBox(*pboxao, box1,
L_INSERT);
2590 boxaAddBox(*pboxae, box1,
L_INSERT);
2591 boxaAddBox(*pboxao, box,
L_INSERT);
2621l_int32 i, n, ne, no;
2625 if (!boxae || !boxao)
2626 return (
BOXA *)ERROR_PTR(
"boxae and boxao not defined", __func__, NULL);
2627 ne = boxaGetCount(boxae);
2628 no = boxaGetCount(boxao);
2629 if (ne < no || ne > no + 1)
2630 return (
BOXA *)ERROR_PTR(
"boxa sizes invalid", __func__, NULL);
2632 boxad = boxaCreate(ne);
2633 if (fillflag == 0) {
2635 for (i = 0; i < n; i++) {
2637 box = boxaGetBox(boxae, i / 2,
L_COPY);
2639 box = boxaGetBox(boxao, i / 2,
L_COPY);
2643 for (i = 0; i < ne; i++) {
2645 box = boxaGetBox(boxae, i,
L_COPY);
2647 box = boxaGetBox(boxao, i,
L_COPY);
BOX * boxaGetNearestToLine(BOXA *boxa, l_int32 x, l_int32 y)
boxaGetNearestToLine()
BOXA * boxaContainedInBox(BOXA *boxas, BOX *box)
boxaContainedInBox()
l_ok boxEqual(BOX *box1, BOX *box2, l_int32 *psame)
boxEqual()
l_ok boxCompareSize(BOX *box1, BOX *box2, l_int32 type, l_int32 *prel)
boxCompareSize()
BOXA * boxaIntersectsBox(BOXA *boxas, BOX *box)
boxaIntersectsBox()
BOX * boxOverlapRegion(BOX *box1, BOX *box2)
boxOverlapRegion()
BOXA * boxaAdjustWidthToTarget(BOXA *boxad, BOXA *boxas, l_int32 sides, l_int32 target, l_int32 thresh)
boxaAdjustWidthToTarget()
l_ok boxaGetNearestByDirection(BOXA *boxa, l_int32 i, l_int32 dir, l_int32 dist_select, l_int32 range, l_int32 *pindex, l_int32 *pdist)
boxaGetNearestByDirection()
l_ok boxIntersectByLine(const BOX *box, l_int32 x, l_int32 y, l_float32 slope, l_int32 *px1, l_int32 *py1, l_int32 *px2, l_int32 *py2, l_int32 *pn)
boxIntersectByLine()
l_ok boxaEqual(BOXA *boxa1, BOXA *boxa2, l_int32 maxdist, NUMA **pnaindex, l_int32 *psame)
boxaEqual()
l_ok boxaAdjustBoxSides(BOXA *boxa, l_int32 index, l_int32 delleft, l_int32 delright, l_int32 deltop, l_int32 delbot)
boxaAdjustBoxSides()
l_ok boxaJoin(BOXA *boxad, BOXA *boxas, l_int32 istart, l_int32 iend)
boxaJoin()
l_ok boxaCombineOverlapsInPair(BOXA *boxas1, BOXA *boxas2, BOXA **pboxad1, BOXA **pboxad2, PIXA *pixadb)
boxaCombineOverlapsInPair()
l_ok boxGetCenter(const BOX *box, l_float32 *pcx, l_float32 *pcy)
boxGetCenter()
l_ok boxOverlapDistance(BOX *box1, BOX *box2, l_int32 *ph_ovl, l_int32 *pv_ovl)
boxOverlapDistance()
l_ok boxSimilar(BOX *box1, BOX *box2, l_int32 leftdiff, l_int32 rightdiff, l_int32 topdiff, l_int32 botdiff, l_int32 *psimilar)
boxSimilar()
l_ok boxIntersects(BOX *box1, BOX *box2, l_int32 *presult)
boxIntersects()
BOXA * boxaCombineOverlaps(BOXA *boxas, PIXA *pixadb)
boxaCombineOverlaps()
l_ok boxaContainedInBoxa(BOXA *boxa1, BOXA *boxa2, l_int32 *pcontained)
boxaContainedInBoxa()
BOX * boxAdjustSides(BOX *boxd, BOX *boxs, l_int32 delleft, l_int32 delright, l_int32 deltop, l_int32 delbot)
boxAdjustSides()
BOXA * boxaClipToBox(BOXA *boxas, BOX *box)
boxaClipToBox()
l_ok boxaFindNearestBoxes(BOXA *boxa, l_int32 dist_select, l_int32 range, NUMAA **pnaaindex, NUMAA **pnaadist)
boxaFindNearestBoxes()
BOXA * boxaAdjustSides(BOXA *boxas, l_int32 delleft, l_int32 delright, l_int32 deltop, l_int32 delbot)
boxaAdjustSides()
l_ok boxaSimilar(BOXA *boxa1, BOXA *boxa2, l_int32 leftdiff, l_int32 rightdiff, l_int32 topdiff, l_int32 botdiff, l_int32 debug, l_int32 *psimilar, NUMA **pnasim)
boxaSimilar()
BOXA * boxaHandleOverlaps(BOXA *boxas, l_int32 op, l_int32 range, l_float32 min_overlap, l_float32 max_ratio, NUMA **pnamap)
boxaHandleOverlaps()
BOX * boxRelocateOneSide(BOX *boxd, BOX *boxs, l_int32 loc, l_int32 sideflag)
boxRelocateOneSide()
BOX * boxBoundingRegion(BOX *box1, BOX *box2)
boxBoundingRegion()
l_ok boxaContainedInBoxCount(BOXA *boxa, BOX *box, l_int32 *pcount)
boxaContainedInBoxCount()
l_ok boxOverlapArea(BOX *box1, BOX *box2, l_int32 *parea)
boxOverlapArea()
l_ok boxaIntersectsBoxCount(BOXA *boxa, BOX *box, l_int32 *pcount)
boxaIntersectsBoxCount()
BOX * boxaGetNearestToPt(BOXA *boxa, l_int32 x, l_int32 y)
boxaGetNearestToPt()
l_ok boxContains(BOX *box1, BOX *box2, l_int32 *presult)
boxContains()
l_ok boxSetSide(BOX *boxs, l_int32 side, l_int32 val, l_int32 thresh)
boxSetSide()
static l_int32 boxHasOverlapInXorY(l_int32 c1, l_int32 s1, l_int32 c2, l_int32 s2)
boxHasOverlapInXorY()
l_ok boxContainsPt(BOX *box, l_float32 x, l_float32 y, l_int32 *pcontains)
boxContainsPt()
BOXA * boxaMergeEvenOdd(BOXA *boxae, BOXA *boxao, l_int32 fillflag)
boxaMergeEvenOdd()
BOXA * boxaAdjustHeightToTarget(BOXA *boxad, BOXA *boxas, l_int32 sides, l_int32 target, l_int32 thresh)
boxaAdjustHeightToTarget()
l_ok boxSeparationDistance(BOX *box1, BOX *box2, l_int32 *ph_sep, l_int32 *pv_sep)
boxSeparationDistance()
l_ok boxaaJoin(BOXAA *baad, BOXAA *baas, l_int32 istart, l_int32 iend)
boxaaJoin()
BOX * boxClipToRectangle(BOX *box, l_int32 wi, l_int32 hi)
boxClipToRectangle()
static l_int32 boxGetDistanceInXorY(l_int32 c1, l_int32 s1, l_int32 c2, l_int32 s2)
boxGetDistanceInXorY()
l_ok boxClipToRectangleParams(BOX *box, l_int32 w, l_int32 h, l_int32 *pxstart, l_int32 *pystart, l_int32 *pxend, l_int32 *pyend, l_int32 *pbw, l_int32 *pbh)
boxClipToRectangleParams()
l_ok boxOverlapFraction(BOX *box1, BOX *box2, l_float32 *pfract)
boxOverlapFraction()
l_ok boxaSplitEvenOdd(BOXA *boxa, l_int32 fillflag, BOXA **pboxae, BOXA **pboxao)
boxaSplitEvenOdd()
BOXA * boxaSetSide(BOXA *boxad, BOXA *boxas, l_int32 side, l_int32 val, l_int32 thresh)
boxaSetSide()
@ L_SORT_BY_MAX_DIMENSION
@ L_ADJUST_LEFT_AND_RIGHT