/* Reconstruction without compaction */
static PIXA *
ReconstructPixa1(L_PTRA  *papix,
                 L_PTRA  *pabox)
{
l_int32  i, imax, nactual;
BOX     *box;
PIX     *pix;
PIXA    *pixat;

    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "Before removal:  imax = %4d, actual = %4d\n",
            imax, nactual);

    pixat = pixaCreate(imax + 1);
    for (i = 0; i <= imax; i++) {
        pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
        box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
        if (pix) pixaAddPix(pixat, pix, L_INSERT);
        if (box) pixaAddBox(pixat, box, L_INSERT);
    }

    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "After removal:   imax = %4d, actual = %4d\n\n",
            imax, nactual);

    return pixat;
}
    /* Reconstruction with compaction */
static PIXA *
ReconstructPixa2(L_PTRA  *papix,
                 L_PTRA  *pabox)
{
l_int32  i, imax, nactual;
BOX     *box;
PIX     *pix;
PIXA    *pixat;

    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "Before removal:    imax = %4d, actual = %4d\n",
            imax, nactual);

        /* Remove half */
    pixat = pixaCreate(imax + 1);
    for (i = 0; i <= imax; i++) {
        if (i % 2 == 0) {
            pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
            box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
            if (pix) pixaAddPix(pixat, pix, L_INSERT);
            if (box) pixaAddBox(pixat, box, L_INSERT);
        }
    }

        /* Compact */
    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "Before compaction: imax = %4d, actual = %4d\n",
            imax, nactual);
    ptraCompactArray(papix);
    ptraCompactArray(pabox);
    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "After compaction:  imax = %4d, actual = %4d\n",
            imax, nactual);

        /* Remove the rest (and test compaction with removal) */
    while (1) {
        ptraGetActualCount(papix, &nactual);
        if (nactual == 0) break;

        pix = (PIX *)ptraRemove(papix, 0, L_COMPACTION);
        box = (BOX *)ptraRemove(pabox, 0, L_COMPACTION);
        pixaAddPix(pixat, pix, L_INSERT);
        pixaAddBox(pixat, box, L_INSERT);
    }

    ptraGetMaxIndex(papix, &imax);
    ptraGetActualCount(papix, &nactual);
    fprintf(stderr, "After removal:     imax = %4d, actual = %4d\n\n",
            imax, nactual);

    return pixat;
}
Exemple #3
0
/*!
 *  ptraDestroy()
 *
 *      Input:  &ptra (<to be nulled>)
 *              freeflag (TRUE to free each remaining item in the array)
 *              warnflag (TRUE to warn if any remaining items are not destroyed)
 *      Return: void
 *
 *  Notes:
 *      (1) If @freeflag == TRUE, frees each item in the array.
 *      (2) If @freeflag == FALSE and warnflag == TRUE, and there are
 *          items on the array, this gives a warning and destroys the array.
 *          If these items are not owned elsewhere, this will cause
 *          a memory leak of all the items that were on the array.
 *          So if the items are not owned elsewhere and require their
 *          own destroy function, they must be destroyed before the ptra.
 *      (3) If warnflag == FALSE, no warnings will be issued.  This is
 *          useful if the items are owned elsewhere, such as a
 *          PixMemoryStore().
 *      (4) To destroy the ptra, we destroy the ptr array, then
 *          the ptra, and then null the contents of the input ptr.
 */
void
ptraDestroy(L_PTRA **ppa,
            l_int32 freeflag,
            l_int32 warnflag) {
    l_int32 i, nactual;
    void *item;
    L_PTRA *pa;

    PROCNAME("ptraDestroy");

    if (ppa == NULL) {
        L_WARNING("ptr address is NULL\n", procName);
        return;
    }
    if ((pa = *ppa) == NULL)
        return;

    ptraGetActualCount(pa, &nactual);
    if (nactual > 0) {
        if (freeflag) {
            for (i = 0; i <= pa->imax; i++) {
                if ((item = ptraRemove(pa, i, L_NO_COMPACTION)) != NULL)
                    FREE(item);
            }
        } else if (warnflag) {
            L_WARNING("potential memory leak of %d items in ptra\n",
                      procName, nactual);
        }
    }

    FREE(pa->array);
    FREE(pa);
    *ppa = NULL;
    return;
}
Exemple #4
0
/*!
 *  ptraRemoveLast()
 *
 *      Input:  ptra
 *      Return: item, or null on error or if the array is empty
 */
void *
ptraRemoveLast(L_PTRA *pa) {
    l_int32 imax;

    PROCNAME("ptraRemoveLast");

    if (!pa)
        return (void *) ERROR_PTR("pa not defined", procName, NULL);

    /* Remove the last item in the array.  No compaction is required. */
    ptraGetMaxIndex(pa, &imax);
    if (imax >= 0)
        return ptraRemove(pa, imax, L_NO_COMPACTION);
    else  /* empty */
        return NULL;
}
Exemple #5
0
/*!
 *  ptraJoin()
 *
 *      Input:  ptra1 (add to this one)
 *              ptra2 (appended to ptra1, and emptied of items; can be null)
 *      Return: 0 if OK, 1 on error
 */
l_int32
ptraJoin(L_PTRA *pa1,
         L_PTRA *pa2) {
    l_int32 i, imax;
    void *item;

    PROCNAME("ptraJoin");

    if (!pa1)
        return ERROR_INT("pa1 not defined", procName, 1);
    if (!pa2)
        return 0;

    ptraGetMaxIndex(pa2, &imax);
    for (i = 0; i <= imax; i++) {
        item = ptraRemove(pa2, i, L_NO_COMPACTION);
        ptraAdd(pa1, item);
    }

    return 0;
}
Exemple #6
0
/*!
 *  ptraSwap()
 *
 *      Input:  ptra
 *              index1
 *              index2
 *      Return: 0 if OK, 1 on error
 */
l_int32
ptraSwap(L_PTRA *pa,
         l_int32 index1,
         l_int32 index2) {
    l_int32 imax;
    void *item;

    PROCNAME("ptraSwap");

    if (!pa)
        return ERROR_INT("pa not defined", procName, 1);
    if (index1 == index2)
        return 0;
    ptraGetMaxIndex(pa, &imax);
    if (index1 < 0 || index1 > imax || index2 < 0 || index2 > imax)
        return ERROR_INT("invalid index: not in [0 ... imax]", procName, 1);

    item = ptraRemove(pa, index1, L_NO_COMPACTION);
    item = ptraReplace(pa, index2, item, FALSE);
    ptraInsert(pa, index1, item, L_MIN_DOWNSHIFT);
    return 0;
}
int main(int    argc,
         char **argv)
{
l_int32      i, n, w, h, nactual, imax;
BOX         *box;
BOXA        *boxa;
PIX         *pixs, *pixd, *pix;
PIXA        *pixas, *pixat, *pixac;
L_PTRA      *papix, *pabox, *papix2, *pabox2;
static char  mainName[] = "ptra1_reg";

    if (argc != 1)
        return ERROR_INT(" Syntax: ptra1_reg", mainName, 1);

    setLeptDebugOK(1);
    pixac = pixaCreate(0);

    if ((pixs = pixRead("lucasta.1.300.tif")) == NULL)
        return ERROR_INT("pixs not made", mainName, 1);
    pixGetDimensions(pixs, &w, &h, NULL);
    boxa = pixConnComp(pixs, &pixas, 8);
    pixDestroy(&pixs);
    boxaDestroy(&boxa);
    n = pixaGetCount(pixas);

        /* Fill ptras with clones and reconstruct */
    fprintf(stderr, "Fill with clones and reconstruct\n");
    MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
    pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
    ptraDestroy(&papix, 0, 1);
    ptraDestroy(&pabox, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 1);

        /* Remove every other one for the first half;
         * with compaction at each removal */
    fprintf(stderr, "Remove every other in 1st half, with compaction\n");
    MakePtrasFromPixa(pixas, &papix, &pabox, L_COPY);
    for (i = 0; i < n / 2; i++) {
        if (i % 2 == 0) {
            pix = (PIX *)ptraRemove(papix, i, L_COMPACTION);
            box = (BOX *)ptraRemove(pabox, i, L_COMPACTION);
            pixDestroy(&pix);
            boxDestroy(&box);
        }
    }
    pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
    ptraDestroy(&papix, 0, 1);
    ptraDestroy(&pabox, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 0);

        /* Remove every other one for the entire set,
         * but without compaction at each removal */
    fprintf(stderr,
            "Remove every other in 1st half, without & then with compaction\n");
    MakePtrasFromPixa(pixas, &papix, &pabox, L_COPY);
    for (i = 0; i < n; i++) {
        if (i % 2 == 0) {
            pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
            box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
            pixDestroy(&pix);
            boxDestroy(&box);
        }
    }
    ptraCompactArray(papix);  /* now do the compaction */
    ptraCompactArray(pabox);
    pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
    ptraDestroy(&papix, 0, 1);
    ptraDestroy(&pabox, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 0);

        /* Fill ptras using insert at head, and reconstruct */
    fprintf(stderr, "Insert at head and reconstruct\n");
    papix = ptraCreate(n);
    pabox = ptraCreate(n);
    for (i = 0; i < n; i++) {
        pix = pixaGetPix(pixas, i, L_CLONE);
        box = pixaGetBox(pixas, i, L_CLONE);
        ptraInsert(papix, 0, pix, L_MIN_DOWNSHIFT);
        ptraInsert(pabox, 0, box, L_FULL_DOWNSHIFT);
    }
    pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
    ptraDestroy(&papix, 0, 1);
    ptraDestroy(&pabox, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 1);

        /* Reverse the arrays by swapping */
    fprintf(stderr, "Reverse by swapping\n");
    MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
    for (i = 0; i < n / 2; i++) {
        ptraSwap(papix, i, n - i - 1);
        ptraSwap(pabox, i, n - i - 1);
    }
    ptraCompactArray(papix);  /* already compact; shouldn't do anything */
    ptraCompactArray(pabox);
    pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
    ptraDestroy(&papix, 0, 1);
    ptraDestroy(&pabox, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 0);

        /* Remove at the top of the array and push the hole to the end
         * by neighbor swapping (!).  This is O(n^2), so it's not a
         * recommended way to copy a ptra. [joke]  */
    fprintf(stderr,
            "Remove at top, pushing hole to end by swapping -- O(n^2)\n");
    MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
    papix2 = ptraCreate(0);
    pabox2 = ptraCreate(0);
    while (1) {
        ptraGetActualCount(papix, &nactual);
        if (nactual == 0) break;
        ptraGetMaxIndex(papix, &imax);
        pix = (PIX *)ptraRemove(papix, 0, L_NO_COMPACTION);
        box = (BOX *)ptraRemove(pabox, 0, L_NO_COMPACTION);
        ptraAdd(papix2, pix);
        ptraAdd(pabox2, box);
        for (i = 1; i <= imax; i++) {
           ptraSwap(papix, i - 1, i);
           ptraSwap(pabox, i - 1, i);
        }
    }
    ptraCompactArray(papix);  /* should be empty */
    ptraCompactArray(pabox);  /* ditto */
    pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
    ptraDestroy(&papix, 0, 1);
    ptraDestroy(&pabox, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 1);  /* nothing there */
    pixat = ReconstructPixa(papix2, pabox2, CHOOSE_RECON);
    ptraDestroy(&papix2, 0, 1);
    ptraDestroy(&pabox2, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 0);

        /* Remove and insert one position above, allowing minimum downshift.
         * If you specify L_AUTO_DOWNSHIFT, because there is only 1 hole,
         * it will do a full downshift at each insert.  This is a
         * situation where the heuristic (expected number of holes)
         * fails to do the optimal thing. */
    fprintf(stderr, "Remove and insert one position above (min downshift)\n");
    MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
    for (i = 1; i < n; i++) {
        pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
        box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
        ptraInsert(papix, i - 1, pix, L_MIN_DOWNSHIFT);
        ptraInsert(pabox, i - 1, box, L_MIN_DOWNSHIFT);
    }
    pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
    ptraDestroy(&papix, 0, 1);
    ptraDestroy(&pabox, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 1);

        /* Remove and insert one position above, but this time
         * forcing a full downshift at each step.  */
    fprintf(stderr, "Remove and insert one position above (full downshift)\n");
    MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
    for (i = 1; i < n; i++) {
        pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
        box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
        ptraInsert(papix, i - 1, pix, L_AUTO_DOWNSHIFT);
        ptraInsert(pabox, i - 1, box, L_AUTO_DOWNSHIFT);
    }
/*    ptraCompactArray(papix);
    ptraCompactArray(pabox); */
    pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
    ptraDestroy(&papix, 0, 1);
    ptraDestroy(&pabox, 0, 1);
    DisplayResult(pixac, &pixat, w, h, 0);

    pixd = pixaDisplay(pixac, 0, 0);
    pixDisplay(pixd, 100, 100);
    pixWrite("/tmp/junkptra1.png", pixd, IFF_PNG);
    pixDestroy(&pixd);
    pixaDestroy(&pixac);
    pixaDestroy(&pixas);
    return 0;
}