251#include <config_auto.h>
255#include "allheaders.h"
259static const l_int32 INITIAL_PTR_ARRAYSIZE = 20;
263static const l_int32 NMAX_HOLES = 150;
278static const l_int32 xpostab[] = {-1, -1, 0, 1, 1, 1, 0, -1};
279static const l_int32 ypostab[] = {0, -1, -1, -1, 0, 1, 1, 1};
280static const l_int32 qpostab[] = {6, 6, 0, 0, 2, 2, 4, 4};
293 l_int32 xs, l_int32 ys);
295 l_int32 wpl, l_int32 px, l_int32 py,
296 l_int32 *pqpos, l_int32 *pnpx,
299 l_int32 spy, l_int32 *pxs, l_int32 *pys);
325 n = INITIAL_PTR_ARRAYSIZE;
329 ccba->
pix = pixClone(pixs);
330 ccba->
w = pixGetWidth(pixs);
331 ccba->
h = pixGetHeight(pixs);
335 if ((ccba->
ccb = (
CCBORD **)LEPT_CALLOC(n,
sizeof(
CCBORD *))) == NULL) {
337 return (
CCBORDA *)ERROR_PTR(
"ccba ptrs not made", __func__, NULL);
356 L_WARNING(
"ptr address is NULL!\n", __func__);
360 if ((ccba = *pccba) == NULL)
363 pixDestroy(&ccba->
pix);
364 for (i = 0; i < ccba->
n; i++)
366 LEPT_FREE(ccba->
ccb);
386 if (pixs && pixGetDepth(pixs) != 1)
387 return (
CCBORD *)ERROR_PTR(
"pixs defined and not 1bpp", __func__, NULL);
392 ccb->
pix = pixClone(pixs);
393 boxa = boxaCreate(1);
395 start = ptaCreate(1);
397 local = ptaaCreate(1);
415 L_WARNING(
"ptr address is NULL!\n", __func__);
419 if ((ccb = *pccb) == NULL)
424 pixDestroy(&ccb->
pix);
426 boxaDestroy(&ccb->
boxa);
428 ptaDestroy(&ccb->
start);
430 ptaaDestroy(&ccb->
local);
432 ptaaDestroy(&ccb->
global);
434 numaaDestroy(&ccb->
step);
462 return ERROR_INT(
"ccba not defined", __func__, 1);
464 return ERROR_INT(
"ccb not defined", __func__, 1);
469 return ERROR_INT(
"extension failed", __func__, 1);
487 return ERROR_INT(
"ccba not defined", __func__, 1);
489 if ((ccba->
ccb = (
CCBORD **)reallocNew((
void **)&ccba->
ccb,
492 return ERROR_INT(
"new ptr array not returned", __func__, 1);
514 return ERROR_INT(
"ccba not defined", __func__, 0);
539 return (
CCBORD *)ERROR_PTR(
"ccba not defined", __func__, NULL);
540 if (index < 0 || index >= ccba->
n)
541 return (
CCBORD *)ERROR_PTR(
"index out of bounds", __func__, NULL);
543 ccb = ccba->
ccb[index];
571 return (
CCBORDA *)ERROR_PTR(
"pixs not defined", __func__, NULL);
572 if (pixGetDepth(pixs) != 1)
573 return (
CCBORDA *)ERROR_PTR(
"pixs not binary", __func__, NULL);
575 if ((boxa = pixConnComp(pixs, &pixa, 8)) == NULL)
576 return (
CCBORDA *)ERROR_PTR(
"boxa not made", __func__, NULL);
577 n = boxaGetCount(boxa);
582 return (
CCBORDA *)ERROR_PTR(
"ccba not made", __func__, NULL);
584 for (i = 0; i < n; i++) {
585 if ((pix = pixaGetPix(pixa, i,
L_CLONE)) == NULL) {
589 return (
CCBORDA *)ERROR_PTR(
"pix not found", __func__, NULL);
591 if ((box = pixaGetBox(pixa, i,
L_CLONE)) == NULL) {
596 return (
CCBORDA *)ERROR_PTR(
"box not found", __func__, NULL);
605 return (
CCBORDA *)ERROR_PTR(
"ccb not made", __func__, NULL);
647l_int32 allzero, i, x, xh, w, nh;
658 return (
CCBORD *)ERROR_PTR(
"pixs not defined", __func__, NULL);
660 return (
CCBORD *)ERROR_PTR(
"box not defined", __func__, NULL);
661 if (pixGetDepth(pixs) != 1)
662 return (
CCBORD *)ERROR_PTR(
"pixs not binary", __func__, NULL);
664 pixZero(pixs, &allzero);
666 return (
CCBORD *)ERROR_PTR(
"pixs all 0", __func__, NULL);
669 return (
CCBORD *)ERROR_PTR(
"ccb not made", __func__, NULL);
675 if ((pixh = pixHolesByFilling(pixs, 4)) == NULL) {
677 return (
CCBORD *)ERROR_PTR(
"pixh not made", __func__, NULL);
679 pixZero(pixh, &allzero);
686 if ((boxa = pixConnComp(pixh, &pixa, 4)) == NULL) {
689 return (
CCBORD *)ERROR_PTR(
"boxa not made", __func__, NULL);
691 nh = boxaGetCount(boxa);
704 w = pixGetWidth(pixs);
705 for (i = 0; i < nh; i++) {
706 boxt = boxaGetBox(boxa, i,
L_CLONE);
707 pixt = pixaGetPix(pixa, i,
L_CLONE);
709 for (x = 0; x < boxt->
w; x++) {
710 pixGetPixel(pixt, x, 0, &val);
717 L_WARNING(
"no hole pixel found!\n", __func__);
720 for (x = xh + boxt->
x; x < w; x++) {
721 pixGetPixel(pixs, x, ys, &val);
727 boxe = boxCreate(boxt->
x - 1, boxt->
y - 1, boxt->
w + 2, boxt->
h + 2);
729 boxPrintStreamInfo(stderr, box);
730 boxPrintStreamInfo(stderr, boxe);
731 lept_stderr(
"xs = %d, ys = %d\n", xs, ys);
764 return (
PTAA *)ERROR_PTR(
"pixs not defined", __func__, NULL);
765 if (pixGetDepth(pixs) != 1)
766 return (
PTAA *)ERROR_PTR(
"pixs not binary", __func__, NULL);
768 boxa = pixConnComp(pixs, &pixa, 8);
769 n = boxaGetCount(boxa);
773 return (
PTAA *)ERROR_PTR(
"pixs empty", __func__, NULL);
776 ptaa = ptaaCreate(n);
777 for (i = 0; i < n; i++) {
778 box = boxaGetBox(boxa, i,
L_CLONE);
779 pix = pixaGetPix(pixa, i,
L_CLONE);
814l_int32 allzero, x, y;
820 return (
PTA *)ERROR_PTR(
"pixs not defined", __func__, NULL);
821 if (pixGetDepth(pixs) != 1)
822 return (
PTA *)ERROR_PTR(
"pixs not binary", __func__, NULL);
824 pixZero(pixs, &allzero);
826 return (
PTA *)ERROR_PTR(
"pixs all 0", __func__, NULL);
829 return (
PTA *)ERROR_PTR(
"ccb not made", __func__, NULL);
831 boxt = boxCreate(0, 0, pixGetWidth(pixs), pixGetHeight(pixs));
833 boxt = boxClone(box);
837 if ((ptaloc = ptaaGetPta(ccb->
local, 0,
L_CLONE)) == NULL) {
840 return (
PTA *)ERROR_PTR(
"ptaloc not made", __func__, NULL);
845 boxGetGeometry(box, &x, &y, NULL, NULL);
846 ptad = ptaTransform(ptaloc, x, y, 1.0, 1.0);
848 ptad = ptaClone(ptaloc);
886l_int32 fpx, fpy, spx, spy, qpos;
887l_int32 px, py, npx, npy;
894 return ERROR_INT(
"ccb not defined", __func__, 1);
896 return ERROR_INT(
"pixs not defined", __func__, 1);
898 return ERROR_INT(
"box not defined", __func__, 1);
901 if ((pixb = pixAddBorder(pixs, 1, 0)) == NULL)
902 return ERROR_INT(
"pixs not made", __func__, 1);
903 if (!nextOnPixelInRaster(pixb, 1, 1, &px, &py)) {
905 return ERROR_INT(
"no start pixel found", __func__, 1);
913 ptaAddPt(ccb->
start, px - 1, py - 1);
917 ptaAddPt(pta, px - 1, py - 1);
918 pixGetDimensions(pixb, &w, &h, NULL);
919 data = pixGetData(pixb);
920 wpl = pixGetWpl(pixb);
930 ptaAddPt(pta, npx - 1, npy - 1);
936 if (px == fpx && py == fpy && npx == spx && npy == spy)
938 ptaAddPt(pta, npx - 1, npy - 1);
974l_int32 fpx, fpy, spx, spy, qpos;
975l_int32 px, py, npx, npy;
981 return ERROR_INT(
"ccb not defined", __func__, 1);
983 return ERROR_INT(
"pixs not defined", __func__, 1);
985 return ERROR_INT(
"box not defined", __func__, 1);
994 ptaAddPt(ccb->
start, xs, ys);
998 ptaAddPt(pta, xs, ys);
1000 w = pixGetWidth(pixs);
1001 h = pixGetHeight(pixs);
1002 data = pixGetData(pixs);
1003 wpl = pixGetWpl(pixs);
1008 return ERROR_INT(
"isolated hole border point!", __func__, 1);
1012 ptaAddPt(pta, npx, npy);
1018 if (px == fpx && py == fpy && npx == spx && npy == spy)
1020 ptaAddPt(pta, npx, npy);
1058l_int32 qpos, i, pos, npx, npy, val;
1062 for (i = 1; i < 8; i++) {
1063 pos = (qpos + i) % 8;
1064 npx = px + xpostab[pos];
1065 npy = py + ypostab[pos];
1066 if (npx < 0 || npx >= w || npy < 0 || npy >= h)
1068 line = data + npy * wpl;
1073 *pqpos = qpostab[pos];
1116 }
else if (dx * dy == -1) {
1119 }
else if (dx == 0) {
1151l_int32 ncc, nb, n, i, j, k, xul, yul, x, y;
1157 return ERROR_INT(
"ccba not defined", __func__, 1);
1160 for (i = 0; i < ncc; i++) {
1164 boxaGetBoxGeometry(ccb->
boxa, 0, &xul, &yul, NULL, NULL);
1168 nb = ptaaGetCount(ptaal);
1170 ptaaDestroy(&ccb->
global);
1171 if ((ptaag = ptaaCreate(nb)) == NULL) {
1173 return ERROR_INT(
"ptaag not made", __func__, 1);
1178 for (j = 0; j < nb; j++) {
1179 ptal = ptaaGetPta(ptaal, j,
L_CLONE);
1180 n = ptaGetCount(ptal);
1181 ptag = ptaCreate(n);
1183 for (k = 0; k < n; k++) {
1184 ptaGetIPt(ptal, k, &x, &y);
1185 ptaAddPt(ptag, x + xul, y + yul);
1221l_int32 ncc, nb, n, i, j, k;
1222l_int32 px, py, cx, cy, stepdir;
1223l_int32 dirtab[][3] = {{1, 2, 3}, {0, -1, 4}, {7, 6, 5}};
1231 return ERROR_INT(
"ccba not defined", __func__, 1);
1234 for (i = 0; i < ncc; i++) {
1239 nb = ptaaGetCount(ptaal);
1241 numaaDestroy(&ccb->
step);
1242 if ((naa = numaaCreate(nb)) == NULL) {
1244 return ERROR_INT(
"naa not made", __func__, 1);
1249 for (j = 0; j < nb; j++) {
1250 ptal = ptaaGetPta(ptaal, j,
L_CLONE);
1251 n = ptaGetCount(ptal);
1256 ptaGetIPt(ptal, 0, &px, &py);
1257 for (k = 1; k < n; k++) {
1258 ptaGetIPt(ptal, k, &cx, &cy);
1259 stepdir = dirtab[1 + cy - py][1 + cx - px];
1260 numaAddNumber(na, stepdir);
1295l_int32 ncc, nb, n, i, j, k;
1296l_int32 xul, yul, xstart, ystart, x, y, stepdir;
1305 return ERROR_INT(
"ccba not defined", __func__, 1);
1306 if (coordtype != CCB_GLOBAL_COORDS && coordtype != CCB_LOCAL_COORDS)
1307 return ERROR_INT(
"coordtype not valid", __func__, 1);
1310 for (i = 0; i < ncc; i++) {
1312 if ((naa = ccb->
step) == NULL) {
1314 return ERROR_INT(
"step numaa not found", __func__, 1);
1315 }
if ((boxa = ccb->
boxa) == NULL) {
1317 return ERROR_INT(
"boxa not found", __func__, 1);
1318 }
if ((ptas = ccb->
start) == NULL) {
1320 return ERROR_INT(
"start pta not found", __func__, 1);
1325 if (coordtype == CCB_LOCAL_COORDS) {
1330 if (boxaGetBoxGeometry(boxa, 0, &xul, &yul, NULL, NULL)) {
1332 return ERROR_INT(
"bounding rectangle not found", __func__, 1);
1337 nb = numaaGetCount(naa);
1338 if ((ptaan = ptaaCreate(nb)) == NULL) {
1340 return ERROR_INT(
"ptaan not made", __func__, 1);
1342 if (coordtype == CCB_LOCAL_COORDS) {
1344 ptaaDestroy(&ccb->
local);
1348 ptaaDestroy(&ccb->
global);
1353 for (j = 0; j < nb; j++) {
1354 na = numaaGetNuma(naa, j,
L_CLONE);
1355 n = numaGetCount(na);
1356 if ((ptan = ptaCreate(n + 1)) == NULL) {
1359 return ERROR_INT(
"ptan not made", __func__, 1);
1362 ptaGetIPt(ptas, j, &xstart, &ystart);
1365 ptaAddPt(ptan, x, y);
1366 for (k = 0; k < n; k++) {
1367 numaGetIValue(na, k, &stepdir);
1368 x += xpostab[stepdir];
1369 y += ypostab[stepdir];
1370 ptaAddPt(ptan, x, y);
1404l_int32 ncc, npt, i, j, xul, yul, x, y, delx, dely;
1405l_int32 xp, yp, delxp, delyp;
1410 return ERROR_INT(
"ccba not defined", __func__, 1);
1414 return ERROR_INT(
"no ccb", __func__, 1);
1420 for (i = 0; i < ncc; i++) {
1424 if (boxaGetBoxGeometry(ccb->
boxa, 0, &xul, &yul, NULL, NULL)) {
1426 return ERROR_INT(
"bounding rectangle not found", __func__, 1);
1431 npt = ptaGetCount(ptal);
1434 if ((ptag = ptaCreate(npt)) == NULL) {
1436 return ERROR_INT(
"ptag not made", __func__, 1);
1441 if (ptsflag == CCB_SAVE_ALL_PTS) {
1442 for (j = 0; j < npt; j++) {
1443 ptaGetIPt(ptal, j, &x, &y);
1444 ptaAddPt(ptag, x + xul, y + yul);
1447 ptaGetIPt(ptal, 0, &xp, &yp);
1448 ptaAddPt(ptag, xp + xul, yp + yul);
1450 ptaGetIPt(ptal, 1, &x, &y);
1451 ptaAddPt(ptag, x + xul, y + yul);
1452 }
else if (npt > 2) {
1453 ptaGetIPt(ptal, 1, &x, &y);
1458 for (j = 2; j < npt; j++) {
1459 ptaGetIPt(ptal, j, &x, &y);
1462 if (delx != delxp || dely != delyp)
1463 ptaAddPt(ptag, xp + xul, yp + yul);
1469 ptaAddPt(ptag, xp + xul, yp + yul);
1522l_int32 i, j, k, ncc, nb, ncut, npt, dir, len, state, lostholes;
1523l_int32 x, y, xl, yl, xf, yf;
1527PTA *pta, *ptac, *ptah;
1537 return ERROR_INT(
"ccba not defined", __func__, 1);
1541 for (i = 0; i < ncc; i++) {
1543 if ((ptaa = ccb->
local) == NULL) {
1544 L_WARNING(
"local pixel loc array not found\n", __func__);
1547 nb = ptaaGetCount(ptaa);
1552 ptas = ptaCreate(0);
1556 pta = ptaaGetPta(ptaa, 0,
L_CLONE);
1557 if (nb == 1 || nb > NMAX_HOLES + 1) {
1558 ptaJoin(ptas, pta, 0, -1);
1567 ptaap = ptaaCreate(nb - 1);
1568 ptaf = ptaCreate(nb - 1);
1569 ptal = ptaCreate(nb - 1);
1570 for (j = 1; j < nb; j++) {
1571 boxinner = boxaGetBox(boxa, j,
L_CLONE);
1586 ncut = ptaGetCount(ptac);
1588 ptaAddPt(ptaf, -1, -1);
1589 ptaAddPt(ptal, -1, -1);
1591 ptaGetIPt(ptac, 0, &x, &y);
1592 ptaAddPt(ptaf, x, y);
1593 ptaGetIPt(ptac, ncut - 1, &x, &y);
1594 ptaAddPt(ptal, x, y);
1596 boxDestroy(&boxinner);
1600 npt = ptaGetCount(pta);
1601 for (k = 0; k < npt; k++) {
1602 ptaGetIPt(pta, k, &x, &y);
1605 ptaAddPt(ptas, x, y);
1608 state = L_NOT_FOUND;
1609 for (j = 0; j < nb - 1; j++) {
1610 ptaGetIPt(ptal, j, &xl, &yl);
1611 if (x == xl && y == yl) {
1613 ptap = ptaaGetPta(ptaap, j,
L_CLONE);
1614 ptarp = ptaReverse(ptap, 1);
1616 ptaGetIPt(ptaf, j, &xf, &yf);
1618 ptah = ptaaGetPta(ptaa, j + 1,
L_CLONE);
1619 ptahc = ptaCyclicPerm(ptah, xf, yf);
1621 ptaJoin(ptas, ptarp, 0, -1);
1622 ptaJoin(ptas, ptahc, 0, -1);
1623 ptaJoin(ptas, ptap, 0, -1);
1631 if (state == L_NOT_FOUND)
1632 ptaAddPt(ptas, x, y);
1636 ptaaDestroy(&ptaap);
1644 L_INFO(
"***** %d lost holes *****\n", __func__, lostholes);
1682l_int32 w, h, nc, x, y, xl, yl, xmid, ymid;
1687 return (
PTA *)ERROR_PTR(
"pix not defined", __func__, NULL);
1689 return (
PTA *)ERROR_PTR(
"pta not defined", __func__, NULL);
1691 return (
PTA *)ERROR_PTR(
"boxinner not defined", __func__, NULL);
1693 pixGetDimensions(pix, &w, &h, NULL);
1694 ptac = ptaCreate(4);
1695 xmid = boxinner->
x + boxinner->
w / 2;
1696 ymid = boxinner->
y + boxinner->
h / 2;
1699 for (y = ymid; y >= 0; y--) {
1700 pixGetPixel(pix, xmid, y, &val);
1702 ptaAddPt(ptac, xmid, y);
1706 for (y = y - 1; y >= 0; y--) {
1707 pixGetPixel(pix, xmid, y, &val);
1709 ptaAddPt(ptac, xmid, y);
1713 nc = ptaGetCount(ptac);
1714 ptaGetIPt(ptac, nc - 1, &xl, &yl);
1715 if (ptaContainsPt(pta, xl, yl)) {
1723 for (y = ymid; y < h; y++) {
1724 pixGetPixel(pix, xmid, y, &val);
1726 ptaAddPt(ptac, xmid, y);
1730 for (y = y + 1; y < h; y++) {
1731 pixGetPixel(pix, xmid, y, &val);
1733 ptaAddPt(ptac, xmid, y);
1737 nc = ptaGetCount(ptac);
1738 ptaGetIPt(ptac, nc - 1, &xl, &yl);
1739 if (ptaContainsPt(pta, xl, yl)) {
1747 for (x = xmid; x >= 0; x--) {
1748 pixGetPixel(pix, x, ymid, &val);
1750 ptaAddPt(ptac, x, ymid);
1754 for (x = x - 1; x >= 0; x--) {
1755 pixGetPixel(pix, x, ymid, &val);
1757 ptaAddPt(ptac, x, ymid);
1761 nc = ptaGetCount(ptac);
1762 ptaGetIPt(ptac, nc - 1, &xl, &yl);
1763 if (ptaContainsPt(pta, xl, yl)) {
1771 for (x = xmid; x < w; x++) {
1772 pixGetPixel(pix, x, ymid, &val);
1774 ptaAddPt(ptac, x, ymid);
1778 for (x = x + 1; x < w; x++) {
1779 pixGetPixel(pix, x, ymid, &val);
1781 ptaAddPt(ptac, x, ymid);
1785 nc = ptaGetCount(ptac);
1786 ptaGetIPt(ptac, nc - 1, &xl, &yl);
1787 if (ptaContainsPt(pta, xl, yl)) {
1820l_int32 ncc, nb, n, i, j, k, x, y;
1827 return (
PIX *)ERROR_PTR(
"ccba not defined", __func__, NULL);
1829 if ((pixd = pixCreate(ccba->
w, ccba->
h, 1)) == NULL)
1830 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
1832 for (i = 0; i < ncc; i++) {
1834 if ((ptaa = ccb->
global) == NULL) {
1835 L_WARNING(
"global pixel loc array not found", __func__);
1839 nb = ptaaGetCount(ptaa);
1840 for (j = 0; j < nb; j++) {
1841 pta = ptaaGetPta(ptaa, j,
L_CLONE);
1842 n = ptaGetCount(pta);
1843 for (k = 0; k < n; k++) {
1844 ptaGetIPt(pta, k, &x, &y);
1845 pixSetPixel(pixd, x, y, 1);
1872l_int32 ncc, npt, i, j, x, y;
1878 return (
PIX *)ERROR_PTR(
"ccba not defined", __func__, NULL);
1880 if ((pixd = pixCreate(ccba->
w, ccba->
h, 1)) == NULL)
1881 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
1883 for (i = 0; i < ncc; i++) {
1885 if ((ptag = ccb->
spglobal) == NULL) {
1886 L_WARNING(
"spglobal pixel loc array not found\n", __func__);
1890 npt = ptaGetCount(ptag);
1891 for (j = 0; j < npt; j++) {
1892 ptaGetIPt(ptag, j, &x, &y);
1893 pixSetPixel(pixd, x, y, 1);
1961l_int32 ncc, i, nb, n, j, k, x, y, xul, yul, xoff, yoff, w, h;
1962l_int32 fpx, fpy, spx, spy, xs, ys;
1966PIX *pixd, *pixt, *pixh;
1971 return (
PIX *)ERROR_PTR(
"ccba not defined", __func__, NULL);
1973 if ((pixd = pixCreate(ccba->
w, ccba->
h, 1)) == NULL)
1974 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
1976 for (i = 0; i < ncc; i++) {
1978 if ((boxa = ccb->
boxa) == NULL) {
1981 return (
PIX *)ERROR_PTR(
"boxa not found", __func__, NULL);
1985 if ((ptaa = ccb->
local) == NULL) {
1986 L_WARNING(
"local chain array not found\n", __func__);
1991 nb = ptaaGetCount(ptaa);
1992 for (j = 0; j < nb; j++) {
1993 if ((box = boxaGetBox(boxa, j,
L_CLONE)) == NULL) {
1996 return (
PIX *)ERROR_PTR(
"b. box not found", __func__, NULL);
1999 boxGetGeometry(box, &xul, &yul, &w, &h);
2002 boxGetGeometry(box, &xoff, &yoff, &w, &h);
2010 if ((pixt = pixCreate(w, h, 1)) == NULL) {
2013 return (
PIX *)ERROR_PTR(
"pixt not made", __func__, NULL);
2015 pta = ptaaGetPta(ptaa, j,
L_CLONE);
2016 n = ptaGetCount(pta);
2017 for (k = 0; k < n; k++) {
2018 ptaGetIPt(pta, k, &x, &y);
2019 pixSetPixel(pixt, x - xoff, y - yoff, 1);
2035 if ((pixh = pixFillClosedBorders(pixt, 4)) == NULL) {
2039 return (
PIX *)ERROR_PTR(
"pixh not made", __func__, NULL);
2047 pixh = pixCreateTemplate(pixt);
2048 pixSetPixel(pixh, xs, ys, 1);
2049 pixInvert(pixt, pixt);
2050 pixSeedfillBinary(pixh, pixh, pixt, 4);
2054 pixRasterop(pixd, xul + xoff, yul + yoff, w, h,
PIX_XOR,
2090l_int32 ncc, nb, n, i, j, k, x, y, xul, yul, w, h;
2091l_int32 fpx, fpy, spx, spy, xs, ys;
2094PIX *pixd, *pixc, *pixs;
2099 return (
PIX *)ERROR_PTR(
"ccba not defined", __func__, NULL);
2101 if ((pixd = pixCreate(ccba->
w, ccba->
h, 1)) == NULL)
2102 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
2104 for (i = 0; i < ncc; i++) {
2108 if ((boxa = ccb->
boxa) == NULL) {
2111 return (
PIX *)ERROR_PTR(
"boxa not found", __func__, NULL);
2113 if (boxaGetBoxGeometry(boxa, 0, &xul, &yul, &w, &h)) {
2116 return (
PIX *)ERROR_PTR(
"b. box not found", __func__, NULL);
2118 pixc = pixCreate(w + 2, h + 2, 1);
2119 pixs = pixCreateTemplate(pixc);
2121 if ((ptaa = ccb->
local) == NULL) {
2125 L_WARNING(
"local chain array not found\n", __func__);
2128 nb = ptaaGetCount(ptaa);
2129 for (j = 0; j < nb; j++) {
2130 pta = ptaaGetPta(ptaa, j,
L_CLONE);
2131 n = ptaGetCount(pta);
2134 for (k = 0; k < n; k++) {
2135 ptaGetIPt(pta, k, &x, &y);
2136 pixSetPixel(pixc, x + 1, y + 1, 1);
2140 }
else if (k == 1) {
2151 pixSetPixel(pixs, xs, ys, 1);
2157 pixInvert(pixc, pixc);
2158 pixSeedfillBinary(pixs, pixs, pixc, 4);
2159 pixInvert(pixs, pixs);
2162 pixRasterop(pixd, xul, yul, w, h,
PIX_XOR, pixs, 1, 1);
2189 return ERROR_INT(
"filename not defined", __func__, 1);
2191 return ERROR_INT(
"ccba not defined", __func__, 1);
2193 if ((fp = fopenWriteStream(filename,
"wb+")) == NULL)
2194 return ERROR_INT_1(
"stream not opened", filename, __func__, 1);
2197 return ERROR_INT_1(
"ccba not written to stream", filename, __func__, 1);
2238l_uint8 *datain, *dataout;
2239l_int32 i, j, k, bx, by, bw, bh, val, startx, starty;
2242size_t inbytes, outbytes;
2250 return ERROR_INT(
"no libz: can't write data", __func__, 1);
2254 return ERROR_INT(
"stream not open", __func__, 1);
2256 return ERROR_INT(
"ccba not defined", __func__, 1);
2258 if ((bbuf = bbufferCreate(NULL, 1000)) == NULL)
2259 return ERROR_INT(
"bbuf not made", __func__, 1);
2262 snprintf(strbuf,
sizeof(strbuf),
"ccba: %7d cc\n", ncc);
2263 bbufferRead(bbuf, (l_uint8 *)strbuf, 18);
2264 w = pixGetWidth(ccba->
pix);
2265 h = pixGetHeight(ccba->
pix);
2266 bbufferRead(bbuf, (l_uint8 *)&w, 4);
2267 bbufferRead(bbuf, (l_uint8 *)&h, 4);
2268 for (i = 0; i < ncc; i++) {
2270 if (boxaGetBoxGeometry(ccb->
boxa, 0, &bx, &by, &bw, &bh)) {
2271 bbufferDestroy(&bbuf);
2273 return ERROR_INT(
"bounding box not found", __func__, 1);
2275 bbufferRead(bbuf, (l_uint8 *)&bx, 4);
2276 bbufferRead(bbuf, (l_uint8 *)&by, 4);
2277 bbufferRead(bbuf, (l_uint8 *)&bw, 4);
2278 bbufferRead(bbuf, (l_uint8 *)&bh, 4);
2279 if ((naa = ccb->
step) == NULL) {
2283 nb = numaaGetCount(naa);
2284 bbufferRead(bbuf, (l_uint8 *)&nb, 4);
2286 for (j = 0; j < nb; j++) {
2287 ptaGetIPt(pta, j, &startx, &starty);
2288 bbufferRead(bbuf, (l_uint8 *)&startx, 4);
2289 bbufferRead(bbuf, (l_uint8 *)&starty, 4);
2290 na = numaaGetNuma(naa, j,
L_CLONE);
2291 n = numaGetCount(na);
2292 for (k = 0; k < n; k++) {
2293 numaGetIValue(na, k, &val);
2295 bval = (l_uint8)val << 4;
2297 bval |= (l_uint8)val;
2299 bbufferRead(bbuf, (l_uint8 *)&bval, 1);
2303 bbufferRead(bbuf, (l_uint8 *)&bval, 1);
2307 bbufferRead(bbuf, (l_uint8 *)&bval, 1);
2314 datain = bbufferDestroyAndSaveData(&bbuf, &inbytes);
2315 dataout = zlibCompress(datain, inbytes, &outbytes);
2316 fwrite(dataout, 1, outbytes, fp);
2339 return (
CCBORDA *)ERROR_PTR(
"filename not defined", __func__, NULL);
2341 if ((fp = fopenReadStream(filename)) == NULL)
2342 return (
CCBORDA *)ERROR_PTR_1(
"stream not opened",
2343 filename, __func__, NULL);
2348 return (
CCBORDA *)ERROR_PTR_1(
"ccba not returned",
2349 filename, __func__, NULL);
2383l_uint8 *datain, *dataout;
2384l_int32 i, j, startx, starty;
2385l_int32 offset, nib1, nib2;
2387l_uint32 width, height, w, h, xoff, yoff;
2388size_t inbytes, outbytes;
2396 return (
CCBORDA *)ERROR_PTR(
"no libz: can't read data", __func__, NULL);
2400 return (
CCBORDA *)ERROR_PTR(
"stream not open", __func__, NULL);
2402 if ((datain = l_binaryReadStream(fp, &inbytes)) == NULL)
2403 return (
CCBORDA *)ERROR_PTR(
"data not read from file", __func__, NULL);
2404 dataout = zlibUncompress(datain, inbytes, &outbytes);
2407 return (
CCBORDA *)ERROR_PTR(
"dataout not made", __func__, NULL);
2410 memcpy(strbuf, dataout, offset);
2412 if (memcmp(strbuf,
"ccba:", 5) != 0) {
2414 return (
CCBORDA *)ERROR_PTR(
"file not type ccba", __func__, NULL);
2416 sscanf(strbuf,
"ccba: %7d cc\n", &ncc);
2418 if ((ccba =
ccbaCreate(NULL, ncc)) == NULL) {
2420 return (
CCBORDA *)ERROR_PTR(
"ccba not made", __func__, NULL);
2423 memcpy(&width, dataout + offset, 4);
2425 memcpy(&height, dataout + offset, 4);
2431 for (i = 0; i < ncc; i++) {
2435 memcpy(&xoff, dataout + offset, 4);
2437 memcpy(&yoff, dataout + offset, 4);
2439 memcpy(&w, dataout + offset, 4);
2441 memcpy(&h, dataout + offset, 4);
2443 box = boxCreate(xoff, yoff, w, h);
2448 memcpy(&nb, dataout + offset, 4);
2451 step = numaaCreate(nb);
2454 for (j = 0; j < nb; j++) {
2455 memcpy(&startx, dataout + offset, 4);
2457 memcpy(&starty, dataout + offset, 4);
2459 ptaAddPt(ccb->
start, startx, starty);
2465 bval = *(dataout + offset);
2470 numaAddNumber(na, nib1);
2474 numaAddNumber(na, nib2);
2504 return ERROR_INT(
"filename not defined", __func__, 1);
2506 return ERROR_INT(
"ccba not defined", __func__, 1);
2509 return ERROR_INT(
"svgstr not made", __func__, 1);
2511 l_binaryWrite(filename,
"w", svgstr, strlen(svgstr));
2530char line0[] =
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
2531char line1[] =
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20000303 Stylable//EN\" \"http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd\">";
2532char line2[] =
"<svg>";
2533char line3[] =
"<polygon style=\"stroke-width:1;stroke:black;\" points=\"";
2534char line4[] =
"\" />";
2535char line5[] =
"</svg>";
2537l_int32 i, j, ncc, npt, x, y;
2543 return (
char *)ERROR_PTR(
"ccba not defined", __func__, NULL);
2545 sa = sarrayCreate(0);
2546 sarrayAddString(sa, line0,
L_COPY);
2547 sarrayAddString(sa, line1,
L_COPY);
2548 sarrayAddString(sa, line2,
L_COPY);
2550 for (i = 0; i < ncc; i++) {
2553 return (
char *)ERROR_PTR(
"ccb not found", __func__, NULL);
2555 if ((pta = ccb->
spglobal) == NULL) {
2558 return (
char *)ERROR_PTR(
"spglobal not made", __func__, NULL);
2560 sarrayAddString(sa, line3,
L_COPY);
2561 npt = ptaGetCount(pta);
2562 for (j = 0; j < npt; j++) {
2563 ptaGetIPt(pta, j, &x, &y);
2564 snprintf(smallbuf,
sizeof(smallbuf),
"%0d,%0d", x, y);
2565 sarrayAddString(sa, smallbuf,
L_COPY);
2567 sarrayAddString(sa, line4,
L_COPY);
2570 sarrayAddString(sa, line5,
L_COPY);
2571 sarrayAddString(sa, space,
L_COPY);
2573 svgstr = sarrayToString(sa, 1);
#define GET_DATA_BIT(pdata, n)
PTAA * pixGetOuterBordersPtaa(PIX *pixs)
pixGetOuterBordersPtaa()
PIX * ccbaDisplayImage2(CCBORDA *ccba)
ccbaDisplayImage2()
l_ok ccbaWriteSVG(const char *filename, CCBORDA *ccba)
ccbaWriteSVG()
char * ccbaWriteSVGString(CCBORDA *ccba)
ccbaWriteSVGString()
void ccbaDestroy(CCBORDA **pccba)
ccbaDestroy()
CCBORDA * ccbaRead(const char *filename)
ccbaRead()
l_ok pixGetOuterBorder(CCBORD *ccb, PIX *pixs, BOX *box)
pixGetOuterBorder()
l_ok ccbaGenerateSinglePath(CCBORDA *ccba)
ccbaGenerateSinglePath()
static l_int32 findNextBorderPixel(l_int32 w, l_int32 h, l_uint32 *data, l_int32 wpl, l_int32 px, l_int32 py, l_int32 *pqpos, l_int32 *pnpx, l_int32 *pnpy)
findNextBorderPixel()
static CCBORD * ccbaGetCcb(CCBORDA *ccba, l_int32 index)
ccbaGetCcb()
PIX * ccbaDisplayBorder(CCBORDA *ccba)
ccbaDisplayBorder()
l_ok ccbaWrite(const char *filename, CCBORDA *ccba)
ccbaWrite()
PIX * ccbaDisplaySPBorder(CCBORDA *ccba)
ccbaDisplaySPBorder()
static l_int32 ccbaGetCount(CCBORDA *ccba)
ccbaGetCount()
l_ok ccbaStepChainsToPixCoords(CCBORDA *ccba, l_int32 coordtype)
ccbaStepChainsToPixCoords()
PIX * ccbaDisplayImage1(CCBORDA *ccba)
ccbaDisplayImage1()
l_ok ccbaGenerateGlobalLocs(CCBORDA *ccba)
ccbaGenerateGlobalLocs()
static CCBORDA * ccbaCreate(PIX *pixs, l_int32 n)
ccbaCreate()
static PTA * pixGetOuterBorderPta(PIX *pixs, BOX *box)
pixGetOuterBorderPta()
static CCBORD * pixGetCCBorders(PIX *pixs, BOX *box)
pixGetCCBorders()
l_ok ccbaGenerateStepChains(CCBORDA *ccba)
ccbaGenerateStepChains()
CCBORDA * ccbaReadStream(FILE *fp)
ccbaReadStream()
CCBORDA * pixGetAllCCBorders(PIX *pixs)
pixGetAllCCBorders()
static l_ok pixGetHoleBorder(CCBORD *ccb, PIX *pixs, BOX *box, l_int32 xs, l_int32 ys)
pixGetHoleBorder()
static void ccbDestroy(CCBORD **pccb)
ccbDestroy()
static l_int32 ccbaExtendArray(CCBORDA *ccba)
ccbaExtendArray()
l_ok ccbaGenerateSPGlobalLocs(CCBORDA *ccba, l_int32 ptsflag)
ccbaGenerateSPGlobalLocs()
static l_ok ccbaAddCcb(CCBORDA *ccba, CCBORD *ccb)
ccbaAddCcb()
l_ok ccbaWriteStream(FILE *fp, CCBORDA *ccba)
ccbaWriteStream()
static CCBORD * ccbCreate(PIX *pixs)
ccbCreate()
static PTA * getCutPathForHole(PIX *pix, PTA *pta, BOX *boxinner, l_int32 *pdir, l_int32 *plen)
getCutPathForHole()
static void locateOutsideSeedPixel(l_int32 fpx, l_int32 fpy, l_int32 spx, l_int32 spy, l_int32 *pxs, l_int32 *pys)
locateOutsideSeedPixel()