예제 #1
0
static void
MakePtrasFromPixa(PIXA     *pixa,
                  L_PTRA  **ppapix,
                  L_PTRA  **ppabox,
                  l_int32   copyflag)
{
l_int32  i, n;
BOX     *box;
PIX     *pix;
L_PTRA  *papix, *pabox;

    n = pixaGetCount(pixa);
    papix = ptraCreate(n);
    pabox = ptraCreate(n);
    for (i = 0; i < n; i++) {
        pix = pixaGetPix(pixa, i, copyflag);
        box = pixaGetBox(pixa, i, copyflag);
        ptraAdd(papix, pix);
        ptraAdd(pabox, box);
    }

    *ppapix = papix;
    *ppabox = pabox;
    return;
}
예제 #2
0
static void
CopyPtras(L_PTRA   *papixs,
          L_PTRA   *paboxs,
          L_PTRA  **ppapixd,
          L_PTRA  **ppaboxd)
{
l_int32  i, imax;
BOX     *box;
PIX     *pix;

    ptraGetMaxIndex(papixs, &imax);
    *ppapixd = ptraCreate(imax + 1);
    *ppaboxd = ptraCreate(imax + 1);
    for (i = 0; i <= imax; i++) {
        pix = pixCopy(NULL, (PIX *)ptraGetPtrToItem(papixs, i));
        box = boxCopy((BOX *)ptraGetPtrToItem(paboxs, i));
        ptraAdd(*ppapixd, pix);
        ptraAdd(*ppaboxd, box);
    }
    return;
}
예제 #3
0
/*!
 *  ptraaFlattenToPtra()
 *
 *      Input:  ptraa
 *      Return: ptra, or null on error
 *
 *  Notes:
 *      (1) This 'flattens' the ptraa to a ptra, taking the items in
 *          each ptra, in order, starting with the first ptra, etc.
 *      (2) As a side-effect, the ptra are all removed from the ptraa
 *          and destroyed, leaving an empty ptraa.
 */
L_PTRA *
ptraaFlattenToPtra(L_PTRAA *paa) {
    l_int32 i, n;
    L_PTRA *pat, *pad;

    PROCNAME("ptraaFlattenToPtra");

    if (!paa)
        return (L_PTRA *) ERROR_PTR("paa not defined", procName, NULL);

    pad = ptraCreate(0);
    ptraaGetSize(paa, &n);
    for (i = 0; i < n; i++) {
        pat = ptraaGetPtra(paa, i, L_REMOVE);
        if (!pat) continue;
        ptraJoin(pad, pat);
        ptraDestroy(&pat, FALSE, FALSE);  /* they're all empty */
    }

    return pad;
}
예제 #4
0
파일: pixalloc.c 프로젝트: chewi/leptonica
/*!
 * \brief   pmsCreate()
 *
 * \param[in]    minsize of data chunk that can be supplied by pms
 * \param[in]    smallest bytes of the smallest pre-allocated data chunk.
 * \param[in]    numalloc array with the number of data chunks for each
 *                        size that are in the memory store
 * \param[in]    logfile use for debugging; null otherwise
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) This computes the size of the block of memory required
 *          and allocates it.  Each chunk starts on a 32-bit word boundary.
 *          The chunk sizes are in powers of 2, starting at %smallest,
 *          and the number of levels and chunks at each level is
 *          specified by %numalloc.
 *      (2) This is intended to manage the image data for a small number
 *          of relatively large pix.  The system malloc is expected to
 *          handle very large numbers of small chunks efficiently.
 *      (3) Important: set the allocators and call this function
 *          before any pix have been allocated.  Destroy all the pix
 *          in the normal way before calling pmsDestroy().
 *      (4) The pms struct is stored in a static global, so this function
 *          is not thread-safe.  When used, there must be only one thread
 *          per process.
 * </pre>
 */
l_ok
pmsCreate(size_t       minsize,
          size_t       smallest,
          NUMA        *numalloc,
          const char  *logfile)
{
l_int32           nlevels, i, j, nbytes;
l_int32          *alloca;
l_float32         nchunks;
l_uint32         *baseptr, *data;
l_uint32        **firstptr;
size_t           *sizes;
L_PIX_MEM_STORE  *pms;
L_PTRA           *pa;
L_PTRAA          *paa;

    PROCNAME("createPMS");

    if (!numalloc)
        return ERROR_INT("numalloc not defined", procName, 1);
    numaGetSum(numalloc, &nchunks);
    if (nchunks > 1000.0)
        L_WARNING("There are %.0f chunks\n", procName, nchunks);

    if ((pms = (L_PIX_MEM_STORE *)LEPT_CALLOC(1, sizeof(L_PIX_MEM_STORE)))
        == NULL)
        return ERROR_INT("pms not made", procName, 1);
    CustomPMS = pms;

        /* Make sure that minsize and smallest are multiples of 32 bit words */
    if (minsize % 4 != 0)
        minsize -= minsize % 4;
    pms->minsize = minsize;
    nlevels = numaGetCount(numalloc);
    pms->nlevels = nlevels;

    if ((sizes = (size_t *)LEPT_CALLOC(nlevels, sizeof(size_t))) == NULL)
        return ERROR_INT("sizes not made", procName, 1);
    pms->sizes = sizes;
    if (smallest % 4 != 0)
        smallest += 4 - (smallest % 4);
    pms->smallest = smallest;
    for (i = 0; i < nlevels; i++)
        sizes[i] = smallest * (1 << i);
    pms->largest = sizes[nlevels - 1];

    alloca = numaGetIArray(numalloc);
    pms->allocarray = alloca;
    if ((paa = ptraaCreate(nlevels)) == NULL)
        return ERROR_INT("paa not made", procName, 1);
    pms->paa = paa;

    for (i = 0, nbytes = 0; i < nlevels; i++)
        nbytes += alloca[i] * sizes[i];
    pms->nbytes = nbytes;

    if ((baseptr = (l_uint32 *)LEPT_CALLOC(nbytes / 4, sizeof(l_uint32)))
        == NULL)
        return ERROR_INT("calloc fail for baseptr", procName, 1);
    pms->baseptr = baseptr;
    pms->maxptr = baseptr + nbytes / 4;  /* just beyond the memory store */
    if ((firstptr = (l_uint32 **)LEPT_CALLOC(nlevels, sizeof(l_uint32 *)))
        == NULL)
        return ERROR_INT("calloc fail for firstptr", procName, 1);
    pms->firstptr = firstptr;

    data = baseptr;
    for (i = 0; i < nlevels; i++) {
        if ((pa = ptraCreate(alloca[i])) == NULL)
            return ERROR_INT("pa not made", procName, 1);
        ptraaInsertPtra(paa, i, pa);
        firstptr[i] = data;
        for (j = 0; j < alloca[i]; j++) {
            ptraAdd(pa, data);
            data += sizes[i] / 4;
        }
    }

    if (logfile) {
        pms->memused = (l_int32 *)LEPT_CALLOC(nlevels, sizeof(l_int32));
        pms->meminuse = (l_int32 *)LEPT_CALLOC(nlevels, sizeof(l_int32));
        pms->memmax = (l_int32 *)LEPT_CALLOC(nlevels, sizeof(l_int32));
        pms->memempty = (l_int32 *)LEPT_CALLOC(nlevels, sizeof(l_int32));
        pms->logfile = stringNew(logfile);
    }

    return 0;
}
예제 #5
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;
}