示例#1
0
/*!
 * \brief   getRootNameFromArgv0()
 *
 * \param[in]    argv0
 * \return  root name without the '_reg', or NULL on error
 *
 * <pre>
 * Notes:
 *      (1) For example, from psioseg_reg, we want to extract
 *          just 'psioseg' as the root.
 *      (2) In unix with autotools, the executable is not X,
 *          but ./.libs/lt-X.   So in addition to stripping out the
 *          last 4 characters of the tail, we have to check for
 *          the '-' and strip out the "lt-" prefix if we find it.
 * </pre>
 */
static char *
getRootNameFromArgv0(const char  *argv0)
{
l_int32  len;
char    *root;

    PROCNAME("getRootNameFromArgv0");

    splitPathAtDirectory(argv0, NULL, &root);
    if ((len = strlen(root)) <= 4) {
        LEPT_FREE(root);
        return (char *)ERROR_PTR("invalid argv0; too small", procName, NULL);
    }

#ifndef _WIN32
    {
        char    *newroot;
        l_int32  loc;
        if (stringFindSubstr(root, "-", &loc)) {
            newroot = stringNew(root + loc + 1);  /* strip out "lt-" */
            LEPT_FREE(root);
            root = newroot;
            len = strlen(root);
        }
    }
#else
    if (strstr(root, ".exe") != NULL)
        len -= 4;
#endif  /* ! _WIN32 */

    root[len - 4] = '\0';  /* remove the suffix */
    return root;
}
示例#2
0
/*!
 *  barcodeDecode39()
 *
 *      Input:  barstr (of widths, in set {1, 2})
 *              debugflag
 *      Return: data (string of digits), or null if none found or on error
 *
 *  Notes:
 *      (1) Ref:  http://en.wikipedia.org/wiki/Code39
 *                http://morovia.com/education/symbology/code39.asp
 *      (2) Each symbol has 5 black and 4 white bars.
 *          The start and stop codes are 121121211 (the asterisk)
 *      (3) This decoder was contributed by Roger Hyde.
 */
static char *
barcodeDecode39(char    *barstr,
                l_int32  debugflag)
{
char     *data, *vbarstr;
char      code[10];
l_int32   valid, reverse, i, j, len, error, nsymb, start, found;

    PROCNAME("barcodeDecode39");

    if (!barstr)
        return (char *)ERROR_PTR("barstr not defined", procName, NULL);

        /* Verify format; reverse if necessary */
    barcodeVerifyFormat(barstr, L_BF_CODE39, &valid, &reverse);
    if (!valid)
        return (char *)ERROR_PTR("barstr not in code39 format", procName, NULL);
    if (reverse)
        vbarstr = stringReverse(barstr);
    else
        vbarstr = stringNew(barstr);

        /* Verify size */
    len = strlen(vbarstr);
    if ((len + 1) % 10 != 0)
        return (char *)ERROR_PTR("size+1 not divisible by 10: invalid code 39",
                                 procName, NULL);

        /* Decode the symbols */
    nsymb = (len - 19) / 10;
    data = (char *)LEPT_CALLOC(nsymb + 1, sizeof(char));
    memset(code, 0, 10);
    error = FALSE;
    for (i = 0; i < nsymb; i++) {
        start = 10 + 10 * i;
        for (j = 0; j < 9; j++)
            code[j] = vbarstr[start + j];

        if (debugflag)
            fprintf(stderr, "code: %s\n", code);

        found = FALSE;
        for (j = 0; j < C39_START; j++) {
            if (!strcmp(code, Code39[j])) {
                data[i] = Code39Val[j];
                found = TRUE;
                break;
            }
        }
        if (!found) error = TRUE;
    }
    LEPT_FREE(vbarstr);

    if (error) {
        LEPT_FREE(data);
        return (char *)ERROR_PTR("error in decoding", procName, NULL);
    }

    return data;
}
示例#3
0
文件: queue.c 项目: chewi/leptonica
/*!
 * \brief   lqueueDestroy()
 *
 * \param[in,out]   plq to be nulled
 * \param[in]    freeflag TRUE to free each remaining struct in the array
 * \return  void
 *
 * <pre>
 * Notes:
 *      (1) If freeflag is TRUE, frees each struct in the array.
 *      (2) If freeflag is FALSE but there are elements on the array,
 *          gives a warning and destroys the array.  This will
 *          cause a memory leak of all the items that were on the queue.
 *          So if the items require their own destroy function, they
 *          must be destroyed before the queue.  The same applies to the
 *          auxiliary stack, if it is used.
 *      (3) To destroy the L_Queue, we destroy the ptr array, then
 *          the lqueue, and then null the contents of the input ptr.
 * </pre>
 */
void
lqueueDestroy(L_QUEUE  **plq,
              l_int32    freeflag)
{
void     *item;
L_QUEUE  *lq;

    PROCNAME("lqueueDestroy");

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

    if (freeflag) {
        while(lq->nelem > 0) {
            item = lqueueRemove(lq);
            LEPT_FREE(item);
        }
    } else if (lq->nelem > 0) {
        L_WARNING("memory leak of %d items in lqueue!\n", procName, lq->nelem);
    }

    if (lq->array)
        LEPT_FREE(lq->array);
    if (lq->stack)
        lstackDestroy(&lq->stack, freeflag);
    LEPT_FREE(lq);
    *plq = NULL;

    return;
}
/*!
 * \brief   parseStringForNumbers()
 *
 * \param[in]    str string containing numbers; not changed
 * \param[in]    seps string of characters that can be used between ints
 * \return  numa of numbers found, or NULL on error
 *
 * <pre>
 * Notes:
 *     (1) The numbers can be ints or floats.
 * </pre>
 */
NUMA *
parseStringForNumbers(const char  *str,
                      const char  *seps)
{
char      *newstr, *head, *tail;
l_float32  val;
NUMA      *na;

    PROCNAME("parseStringForNumbers");

    if (!str)
        return (NUMA *)ERROR_PTR("str not defined", procName, NULL);

    newstr = stringNew(str);  /* to enforce const-ness of str */
    na = numaCreate(0);
    head = strtokSafe(newstr, seps, &tail);
    val = atof(head);
    numaAddNumber(na, val);
    LEPT_FREE(head);
    while ((head = strtokSafe(NULL, seps, &tail)) != NULL) {
        val = atof(head);
        numaAddNumber(na, val);
        LEPT_FREE(head);
    }

    LEPT_FREE(newstr);
    return na;
}
示例#5
0
/*
 *  captureProtoSignature()
 *
 *      Input:  sa (output from cpp, by line)
 *              start (starting index to search; never a comment line)
 *              stop (index of line on which pattern is completed)
 *              charindex (char index of completing ')' character)
 *      Return: cleanstr (prototype string), or NULL on error
 *
 *  Notes:
 *      (1) Return all characters, ending with a ';' after the ')'
 */
static char *
captureProtoSignature(SARRAY  *sa,
                      l_int32  start,
                      l_int32  stop,
                      l_int32  charindex)
{
char    *str, *newstr, *protostr, *cleanstr;
SARRAY  *sap;
l_int32  i;

    PROCNAME("captureProtoSignature");

    if (!sa)
        return (char *)ERROR_PTR("sa not defined", procName, NULL);

    sap = sarrayCreate(0);
    for (i = start; i < stop; i++) {
        str = sarrayGetString(sa, i, L_COPY);
        sarrayAddString(sap, str, L_INSERT);
    }
    str = sarrayGetString(sa, stop, L_COPY);
    str[charindex + 1] = '\0';
    newstr = stringJoin(str, ";");
    sarrayAddString(sap, newstr, L_INSERT);
    LEPT_FREE(str);
    protostr = sarrayToString(sap, 2);
    sarrayDestroy(&sap);
    cleanstr = cleanProtoSignature(protostr);
    LEPT_FREE(protostr);

    return cleanstr;
}
示例#6
0
/*!
 *  numaDestroy()
 *
 *      Input:  &na (<to be nulled if it exists>)
 *      Return: void
 *
 *  Notes:
 *      (1) Decrements the ref count and, if 0, destroys the numa.
 *      (2) Always nulls the input ptr.
 */
void
numaDestroy(NUMA  **pna)
{
NUMA  *na;

    PROCNAME("numaDestroy");

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

    if ((na = *pna) == NULL)
        return;

        /* Decrement the ref count.  If it is 0, destroy the numa. */
    numaChangeRefcount(na, -1);
    if (numaGetRefcount(na) <= 0) {
        if (na->array)
            LEPT_FREE(na->array);
        LEPT_FREE(na);
    }

    *pna = NULL;
    return;
}
示例#7
0
/*!
 *  recogaDestroy()
 *
 *      Input:  &recoga (<will be set to null before returning>)
 *      Return: void
 *
 *  Notes:
 *      (1) If a recog has a parent, the parent owns it.  To destroy
 *          a recog, it must first be "orphaned".
 */
void
recogaDestroy(L_RECOGA  **precoga)
{
l_int32    i;
L_RECOG   *recog;
L_RECOGA  *recoga;

    PROCNAME("recogaDestroy");

    if (precoga == NULL) {
        L_WARNING("ptr address is null!\n", procName);
        return;
    }

    if ((recoga = *precoga) == NULL)
        return;

    rchaDestroy(&recoga->rcha);
    for (i = 0; i < recoga->n; i++) {
        if ((recog = recoga->recog[i]) == NULL) {
            L_ERROR("recog not found for index %d\n", procName, i);
            continue;
        }
        recog->parent = NULL;  /* orphan it */
        recogDestroy(&recog);
    }
    LEPT_FREE(recoga->recog);
    LEPT_FREE(recoga);
    *precoga = NULL;
    return;
}
示例#8
0
/*!
 * \brief   boxaaQuadtreeRegions()
 *
 * \param[in]    w, h     size of pix that is being quadtree-ized
 * \param[in]    nlevels  number of levels in quadtree
 * \return  baa for quadtree regions at each level, or NULL on error
 *
 * <pre>
 * Notes:
 *      (1) The returned boxaa has %nlevels of boxa, each containing
 *          the set of rectangles at that level.  The rectangle at
 *          level 0 is the entire region; at level 1 the region is
 *          divided into 4 rectangles, and at level n there are n^4
 *          rectangles.
 *      (2) At each level, the rectangles in the boxa are in "raster"
 *          order, with LR (fast scan) and TB (slow scan).
 * </pre>
 */
BOXAA *
boxaaQuadtreeRegions(l_int32  w,
                     l_int32  h,
                     l_int32  nlevels)
{
l_int32   i, j, k, maxpts, nside, nbox, bw, bh;
l_int32  *xstart, *xend, *ystart, *yend;
BOX      *box;
BOXA     *boxa;
BOXAA    *baa;

    PROCNAME("boxaaQuadtreeRegions");

    if (nlevels < 1)
        return (BOXAA *)ERROR_PTR("nlevels must be >= 1", procName, NULL);
    if (w < (1 << (nlevels - 1)))
        return (BOXAA *)ERROR_PTR("w doesn't support nlevels", procName, NULL);
    if (h < (1 << (nlevels - 1)))
        return (BOXAA *)ERROR_PTR("h doesn't support nlevels", procName, NULL);

    baa = boxaaCreate(nlevels);
    maxpts = 1 << (nlevels - 1);
    xstart = (l_int32 *)LEPT_CALLOC(maxpts, sizeof(l_int32));
    xend = (l_int32 *)LEPT_CALLOC(maxpts, sizeof(l_int32));
    ystart = (l_int32 *)LEPT_CALLOC(maxpts, sizeof(l_int32));
    yend = (l_int32 *)LEPT_CALLOC(maxpts, sizeof(l_int32));
    for (k = 0; k < nlevels; k++) {
        nside = 1 << k;  /* number of boxes in each direction */
        for (i = 0; i < nside; i++) {
            xstart[i] = (w - 1) * i / nside;
            if (i > 0) xstart[i]++;
            xend[i] = (w - 1) * (i + 1) / nside;
            ystart[i] = (h - 1) * i / nside;
            if (i > 0) ystart[i]++;
            yend[i] = (h - 1) * (i + 1) / nside;
#if DEBUG_BOXES
            fprintf(stderr,
               "k = %d, xs[%d] = %d, xe[%d] = %d, ys[%d] = %d, ye[%d] = %d\n",
                    k, i, xstart[i], i, xend[i], i, ystart[i], i, yend[i]);
#endif  /* DEBUG_BOXES */
        }
        nbox = 1 << (2 * k);
        boxa = boxaCreate(nbox);
        for (i = 0; i < nside; i++) {
            bh = yend[i] - ystart[i] + 1;
            for (j = 0; j < nside; j++) {
                bw = xend[j] - xstart[j] + 1;
                box = boxCreate(xstart[j], ystart[i], bw, bh);
                boxaAddBox(boxa, box, L_INSERT);
            }
        }
        boxaaAddBoxa(baa, boxa, L_INSERT);
    }

    LEPT_FREE(xstart);
    LEPT_FREE(xend);
    LEPT_FREE(ystart);
    LEPT_FREE(yend);
    return baa;
}
示例#9
0
文件: gifio.c 项目: creatale/node-dv
/*!
 * \brief   pixWriteStreamGif()
 *
 * \param[in]  fp    file stream opened for writing
 * \param[in]  pix   1, 2, 4, 8, 16 or 32 bpp
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) All output gif have colormaps.  If the pix is 32 bpp rgb,
 *          this quantizes the colors and writes out 8 bpp.
 *          If the pix is 16 bpp grayscale, it converts to 8 bpp first.
 * </pre>
 */
l_int32
pixWriteStreamGif(FILE  *fp,
                  PIX   *pix)
{
l_uint8  *filedata;
size_t    filebytes, nbytes;

    PROCNAME("pixWriteStreamGif");

    if (!fp)
        return ERROR_INT("stream not open", procName, 1);
    if (!pix)
        return ERROR_INT("pix not defined", procName, 1);

    pixSetPadBits(pix, 0);
    if (pixWriteMemGif(&filedata, &filebytes, pix) != 0) {
        LEPT_FREE(filedata);
        return ERROR_INT("failure to gif encode pix", procName, 1);
    }

    rewind(fp);
    nbytes = fwrite(filedata, 1, filebytes, fp);
    LEPT_FREE(filedata);
    if (nbytes != filebytes)
        return ERROR_INT("write error", procName, 1);
    return 0;
}
示例#10
0
/*!
 *  ptraaDestroy()
 *
 *      Input:  &paa (<to be nulled>)
 *              freeflag (TRUE to free each remaining item in each ptra)
 *              warnflag (TRUE to warn if any remaining items are not destroyed)
 *      Return: void
 *
 *  Notes:
 *      (1) See ptraDestroy() for use of @freeflag and @warnflag.
 *      (2) To destroy the ptraa, we destroy each ptra, then the ptr array,
 *          then the ptraa, and then null the contents of the input ptr.
 */
void
ptraaDestroy(L_PTRAA  **ppaa,
             l_int32    freeflag,
             l_int32    warnflag)
{
l_int32   i, n;
L_PTRA   *pa;
L_PTRAA  *paa;

    PROCNAME("ptraaDestroy");

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

    ptraaGetSize(paa, &n);
    for (i = 0; i < n; i++) {
        pa = ptraaGetPtra(paa, i, L_REMOVE);
        ptraDestroy(&pa, freeflag, warnflag);
    }

    LEPT_FREE(paa->ptra);
    LEPT_FREE(paa);
    *ppaa = NULL;
    return;
}
示例#11
0
/*!
 * \brief   pmsDestroy()
 *
 * <pre>
 * Notes:
 *      (1) Important: call this function at the end of the program, after
 *          the last pix has been destroyed.
 * </pre>
 */
void
pmsDestroy()
{
L_PIX_MEM_STORE  *pms;

    if ((pms = CustomPMS) == NULL)
        return;

    ptraaDestroy(&pms->paa, FALSE, FALSE);  /* don't touch the ptrs */
    LEPT_FREE(pms->baseptr);  /* free the memory */

    if (pms->logfile) {
        pmsLogInfo();
        LEPT_FREE(pms->logfile);
        LEPT_FREE(pms->memused);
        LEPT_FREE(pms->meminuse);
        LEPT_FREE(pms->memmax);
        LEPT_FREE(pms->memempty);
    }

    LEPT_FREE(pms->sizes);
    LEPT_FREE(pms->allocarray);
    LEPT_FREE(pms->firstptr);
    LEPT_FREE(pms);
    CustomPMS = NULL;
    return;
}
/*!
 * \brief   l_byteaDestroy()
 *
 * \param[in,out]   pba will be set to null before returning
 * \return  void
 *
 * <pre>
 * Notes:
 *      (1) Decrements the ref count and, if 0, destroys the lba.
 *      (2) Always nulls the input ptr.
 *      (3) If the data has been previously removed, the lba will
 *          have been nulled, so this will do nothing.
 * </pre>
 */
void
l_byteaDestroy(L_BYTEA  **pba)
{
L_BYTEA  *ba;

    PROCNAME("l_byteaDestroy");

    if (pba == NULL) {
        L_WARNING("ptr address is null!\n", procName);
        return;
    }

    if ((ba = *pba) == NULL)
        return;

        /* Decrement the ref count.  If it is 0, destroy the lba. */
    ba->refcount--;
    if (ba->refcount <= 0) {
        if (ba->data) LEPT_FREE(ba->data);
        LEPT_FREE(ba);
    }

    *pba = NULL;
    return;
}
示例#13
0
/*!
 *  lstackDestroy()
 *
 *      Input:  &lstack (<to be nulled>)
 *              freeflag (TRUE to free each remaining struct in the array)
 *      Return: void
 *
 *  Notes:
 *      (1) If freeflag is TRUE, frees each struct in the array.
 *      (2) If freeflag is FALSE but there are elements on the array,
 *          gives a warning and destroys the array.  This will
 *          cause a memory leak of all the items that were on the lstack.
 *          So if the items require their own destroy function, they
 *          must be destroyed before the lstack.
 *      (3) To destroy the lstack, we destroy the ptr array, then
 *          the lstack, and then null the contents of the input ptr.
 */
void
lstackDestroy(L_STACK  **plstack,
              l_int32    freeflag)
{
    void     *item;
    L_STACK  *lstack;

    PROCNAME("lstackDestroy");

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

    if (freeflag) {
        while(lstack->n > 0) {
            item = lstackRemove(lstack);
            LEPT_FREE(item);
        }
    } else if (lstack->n > 0) {
        L_WARNING("memory leak of %d items in lstack\n", procName, lstack->n);
    }

    if (lstack->auxstack)
        lstackDestroy(&lstack->auxstack, freeflag);

    if (lstack->array)
        LEPT_FREE(lstack->array);
    LEPT_FREE(lstack);
    *plstack = NULL;
}
示例#14
0
/*!
 *  barcodeDecode2of5()
 *
 *      Input:  barstr (of widths, in set {1, 2})
 *              debugflag
 *      Return: data (string of digits), or null if none found or on error
 *
 *  Notes:
 *      (1) Ref: http://en.wikipedia.org/wiki/Two-out-of-five_code (Note:
 *                 the codes given here are wrong!)
 *               http://morovia.com/education/symbology/code25.asp
 *      (2) This is a very low density encoding for the 10 digits.
 *          Each digit is encoded with 5 black bars, of which 2 are wide
 *          and 3 are narrow.  No information is carried in the spaces
 *          between the bars, which are all equal in width, represented by
 *          a "1" in our encoding.
 *      (3) The mapping from the sequence of five bar widths to the
 *          digit is identical to the mapping used by the interleaved
 *          2 of 5 code.  The start code is 21211, representing two
 *          wide bars and a narrow bar, and the interleaved "1" spaces
 *          are explicit.  The stop code is 21112.  For all codes
 *          (including start and stop), the trailing space "1" is
 *          implicit -- there is no reason to represent it in the
 *          Code2of5[] array.
 */
static char *
barcodeDecode2of5(char    *barstr,
                  l_int32  debugflag)
{
char    *data, *vbarstr;
char     code[10];
l_int32  valid, reverse, i, j, len, error, ndigits, start, found;

    PROCNAME("barcodeDecodeI2of5");

    if (!barstr)
        return (char *)ERROR_PTR("barstr not defined", procName, NULL);

        /* Verify format; reverse if necessary */
    barcodeVerifyFormat(barstr, L_BF_CODE2OF5, &valid, &reverse);
    if (!valid)
        return (char *)ERROR_PTR("barstr not in 2of5 format", procName, NULL);
    if (reverse)
        vbarstr = stringReverse(barstr);
    else
        vbarstr = stringNew(barstr);

        /* Verify size */
    len = strlen(vbarstr);
    if ((len - 11) % 10 != 0)
        return (char *)ERROR_PTR("size not divisible by 10: invalid 2of5 code",
                                 procName, NULL);

    error = FALSE;
    ndigits = (len - 11) / 10;
    data = (char *)LEPT_CALLOC(ndigits + 1, sizeof(char));
    memset(code, 0, 10);
    for (i = 0; i < ndigits; i++) {
        start = 6 + 10 * i;
        for (j = 0; j < 9; j++)
            code[j] = vbarstr[start + j];

        if (debugflag)
            fprintf(stderr, "code: %s\n", code);

        found = FALSE;
        for (j = 0; j < 10; j++) {
            if (!strcmp(code, Code2of5[j])) {
                data[i] = 0x30 + j;
                found = TRUE;
                break;
            }
        }
        if (!found) error = TRUE;
    }
    LEPT_FREE(vbarstr);

    if (error) {
        LEPT_FREE(data);
        return (char *)ERROR_PTR("error in decoding", procName, NULL);
    }

    return data;
}
示例#15
0
/*
 *  pixWriteMixedToPS()
 *
 *      Input:  pixb (<optionall> 1 bpp "mask"; typically for text)
 *              pixc (<optional> 8 or 32 bpp image regions)
 *              scale (relative scale factor for rendering pixb
 *                    relative to pixc; typ. 4.0)
 *              pageno (page number in set; use 1 for new output file)
 *              fileout (output ps file)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This low level function generates the PS string for a mixed
 *          text/image page, and adds it to an existing file if
 *          %pageno > 1.
 *      (2) The two images (pixb and pixc) are typically generated at the
 *          resolution that they will be rendered in the PS file.
 *      (3) pixb is the text component.  In the PostScript world, we think of
 *          it as a mask through which we paint black.
 *      (4) pixc is the (typically halftone) image component.  It is
 *          white in the rest of the page.  To minimize the size of the
 *          PS file, it should be rendered at a resolution that is at
 *          least equal to its actual resolution.
 *      (5) %scale gives the ratio of resolution of pixb to pixc.
 *          Typical resolutions are: 600 ppi for pixb, 150 ppi for pixc;
 *          so %scale = 4.0.  If one of the images is not defined,
 *          the value of %scale is ignored.
 *      (6) We write pixc with DCT compression (jpeg).  This is followed
 *          by painting the text as black through the mask pixb.  If
 *          pixc doesn't exist (alltext), we write the text with the
 *          PS "image" operator instead of the "imagemask" operator,
 *          because ghostscript's ps2pdf is flaky when the latter is used.
 *      (7) The actual output resolution is determined by fitting the
 *          result to a letter-size (8.5 x 11 inch) page.
 */
l_int32
pixWriteMixedToPS(PIX         *pixb,
                  PIX         *pixc,
                  l_float32    scale,
                  l_int32      pageno,
                  const char  *fileout)
{
    char        *tname;
    const char  *op;
    l_int32      resb, resc, endpage, maskop, ret;

    PROCNAME("pixWriteMixedToPS");

    if (!pixb && !pixc)
        return ERROR_INT("pixb and pixc both undefined", procName, 1);
    if (!fileout)
        return ERROR_INT("fileout not defined", procName, 1);

    /* Compute the resolution that fills a letter-size page. */
    if (!pixc) {
        resb = getResLetterPage(pixGetWidth(pixb), pixGetHeight(pixb), 0);
    } else {
        resc = getResLetterPage(pixGetWidth(pixc), pixGetHeight(pixc), 0);
        if (pixb)
            resb = (l_int32)(scale * resc);
    }

    /* Write the jpeg image first */
    if (pixc) {
        tname = l_makeTempFilename(NULL);
        pixWrite(tname, pixc, IFF_JFIF_JPEG);
        endpage = (pixb) ? FALSE : TRUE;
        op = (pageno <= 1) ? "w" : "a";
        ret = convertJpegToPS(tname, fileout, op, 0, 0, resc, 1.0,
                              pageno, endpage);
        lept_rmfile(tname);
        LEPT_FREE(tname);
        if (ret)
            return ERROR_INT("jpeg data not written", procName, 1);
    }

    /* Write the binary data, either directly or, if there is
     * a jpeg image on the page, through the mask. */
    if (pixb) {
        tname = l_makeTempFilename(NULL);
        pixWrite(tname, pixb, IFF_TIFF_G4);
        op = (pageno <= 1 && !pixc) ? "w" : "a";
        maskop = (pixc) ? 1 : 0;
        ret = convertG4ToPS(tname, fileout, op, 0, 0, resb, 1.0,
                            pageno, maskop, 1);
        lept_rmfile(tname);
        LEPT_FREE(tname);
        if (ret)
            return ERROR_INT("tiff data not written", procName, 1);
    }

    return 0;
}
示例#16
0
/*!
 * \brief   pixaFindStrokeWidth()
 *
 * \param[in]    pixa  of 1 bpp images
 * \param[in]    thresh  fractional count threshold relative to distance 1
 * \param[in]    tab8  [optional] table for counting fg pixels; can be NULL
 * \param[in]    debug  1 for debug output; 0 to skip
 * \return  na  array of stroke widths for each pix in %pixa; NULL on error
 *
 * <pre>
 * Notes:
 *      (1) See pixFindStrokeWidth() for details.
 * </pre>
 */
NUMA *
pixaFindStrokeWidth(PIXA     *pixa,
                   l_float32  thresh,
                   l_int32   *tab8,
                   l_int32    debug)
{
l_int32    i, n, same, maxd;
l_int32   *tab;
l_float32  width;
NUMA      *na;
PIX       *pix;

    PROCNAME("pixaFindStrokeWidth");

    if (!pixa)
        return (NUMA *)ERROR_PTR("pixa not defined", procName, NULL);
    pixaVerifyDepth(pixa, &same, &maxd);
    if (maxd > 1)
        return (NUMA *)ERROR_PTR("pix not all 1 bpp", procName, NULL);

    tab = (tab8) ? tab8 : makePixelSumTab8();

    n = pixaGetCount(pixa);
    na = numaCreate(n);
    for (i = 0; i < n; i++) {
        pix = pixaGetPix(pixa, i, L_CLONE);
        pixFindStrokeWidth(pix, thresh, tab8, &width, NULL);
        numaAddNumber(na, width);
        pixDestroy(&pix);
    }

    if (!tab8) LEPT_FREE(tab);
    return na;
}
示例#17
0
/*!
 * \brief   recogStringToIndex()
 *
 * \param[in]    recog
 * \param[in]    text text string for some class
 * \param[out]   pindex index for that class; -1 if not found
 * \return  0 if OK, 1 on error not finding the string is an error
 */
l_int32
recogStringToIndex(L_RECOG  *recog,
                   char     *text,
                   l_int32  *pindex)
{
char    *charstr;
l_int32  i, n, diff;

    PROCNAME("recogStringtoIndex");

    if (!pindex)
        return ERROR_INT("&index not defined", procName, 1);
    *pindex = -1;
    if (!recog)
        return ERROR_INT("recog not defined", procName, 1);
    if (!text)
        return ERROR_INT("text not defined", procName, 1);

        /* Search existing characters */
    n = recog->setsize;
    for (i = 0; i < n; i++) {
        recogGetClassString(recog, i, &charstr);
        if (!charstr) {
            L_ERROR("string not found for index %d\n", procName, i);
            continue;
        }
        diff = strcmp(text, charstr);
        LEPT_FREE(charstr);
        if (diff) continue;
        *pindex = i;
        return 0;
    }

    return 1;  /* not found */
}
示例#18
0
/*!
 * \brief   pixFindStrokeLength()
 *
 * \param[in]    pixs 1 bpp
 * \param[in]    tab8  [optional] table for counting fg pixels; can be NULL
 * \param[out]  *plength  estimated length of the strokes
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) Returns half the number of fg boundary pixels.
 * </pre>
 */
l_int32
pixFindStrokeLength(PIX      *pixs,
                    l_int32  *tab8,
                    l_int32  *plength)
{
l_int32   n;
l_int32  *tab;
PIX      *pix1;

    PROCNAME("pixFindStrokeLength");

    if (!plength)
        return ERROR_INT("&length not defined", procName, 1);
    *plength = 0;
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);

    pix1 = pixExtractBoundary(pixs, 1);
    tab = (tab8) ? tab8 : makePixelSumTab8();
    pixCountPixels(pix1, &n, tab);
    *plength = n / 2;
    if (!tab8) LEPT_FREE(tab);
    pixDestroy(&pix1);
    return 0;
}
示例#19
0
/*!
 *  ptraReplace()
 *
 *      Input:  ptra
 *              index (element to be replaced)
 *              item  (new generic ptr to a struct; can be null)
 *              freeflag (TRUE to free old item; FALSE to return it)
 *      Return: item  (old item, if it exists and is not freed),
 *                     or null on error
 */
void *
ptraReplace(L_PTRA  *pa,
            l_int32  index,
            void    *item,
            l_int32  freeflag)
{
l_int32  imax;
void    *olditem;

    PROCNAME("ptraReplace");

    if (!pa)
        return (void *)ERROR_PTR("pa not defined", procName, NULL);
    ptraGetMaxIndex(pa, &imax);
    if (index < 0 || index > imax)
        return (void *)ERROR_PTR("index not in [0 ... imax]", procName, NULL);

    olditem = pa->array[index];
    pa->array[index] = item;
    if (!item && olditem)
        pa->nactual--;
    else if (item && !olditem)
        pa->nactual++;

    if (freeflag == FALSE)
        return olditem;

    if (olditem)
        LEPT_FREE(olditem);
    return NULL;
}
示例#20
0
/*!
 * \brief   pmsCustomDealloc()
 *
 * \param[in]   data to be freed or returned to the storage
 * \return  void
 */
void
pmsCustomDealloc(void  *data)
{
l_int32           level;
L_PIX_MEM_STORE  *pms;
L_PTRA           *pa;

    PROCNAME("pmsCustomDealloc");

    if ((pms = CustomPMS) == NULL) {
        L_ERROR("pms not defined\n", procName);
        return;
    }

    if (pmsGetLevelForDealloc(data, &level) == 1) {
        L_ERROR("level not found\n", procName);
        return;
    }

    if (level < 0) {  /* no logging; just free the data */
        LEPT_FREE(data);
    } else {  /* return the data to the store */
        pa = ptraaGetPtra(pms->paa, level, L_HANDLE_ONLY);
        ptraAdd(pa, data);
        if (pms->logfile)
            pms->meminuse[level]--;
    }

    return;
}
示例#21
0
/*!
 *  numaCreateFromFArray()
 *
 *      Input:  farray (float)
 *              size (of the array)
 *              copyflag (L_INSERT or L_COPY)
 *      Return: na, or null on error
 *
 *  Notes:
 *      (1) With L_INSERT, ownership of the input array is transferred
 *          to the returned numa, and all @size elements are considered
 *          to be valid.
 */
NUMA *
numaCreateFromFArray(l_float32  *farray,
                     l_int32     size,
                     l_int32     copyflag)
{
l_int32  i;
NUMA    *na;

    PROCNAME("numaCreateFromFArray");

    if (!farray)
        return (NUMA *)ERROR_PTR("farray not defined", procName, NULL);
    if (size <= 0)
        return (NUMA *)ERROR_PTR("size must be > 0", procName, NULL);
    if (copyflag != L_INSERT && copyflag != L_COPY)
        return (NUMA *)ERROR_PTR("invalid copyflag", procName, NULL);

    na = numaCreate(size);
    if (copyflag == L_INSERT) {
        if (na->array) LEPT_FREE(na->array);
        na->array = farray;
        na->n = size;
    } else {  /* just copy the contents */
        for (i = 0; i < size; i++)
            numaAddNumber(na, farray[i]);
    }

    return na;
}
示例#22
0
文件: gplot.c 项目: MaTriXy/tess-two
/*!
 * \brief   gplotMakeOutput()
 *
 * \param[in]    gplot
 * \return  0 if OK; 1 on error
 *
 * <pre>
 * Notes:
 *      (1) This uses gplot and the new arrays to add a plot
 *          to the output, by writing a new data file and appending
 *          the appropriate plot commands to the command file.
 *      (2) This is the only function in this file that requires the
 *          gnuplot executable, to actually generate the plot.
 *      (3) The command file name for unix is canonical (i.e., directory /tmp)
 *          but the temp filename paths in the command file must be correct.
 *      (4) The gnuplot program for windows is wgnuplot.exe.
 * </pre>
 */
l_int32
gplotMakeOutput(GPLOT  *gplot)
{
char     buf[L_BUF_SIZE];
char    *cmdname;
l_int32  ignore;

    PROCNAME("gplotMakeOutput");

    if (!gplot)
        return ERROR_INT("gplot not defined", procName, 1);

    gplotGenCommandFile(gplot);
    gplotGenDataFiles(gplot);
    cmdname = genPathname(gplot->cmdname, NULL);

#ifndef _WIN32
    snprintf(buf, L_BUF_SIZE, "gnuplot %s", cmdname);
#else
    snprintf(buf, L_BUF_SIZE, "wgnuplot %s", cmdname);
#endif  /* _WIN32 */

    ignore = system(buf);  /* gnuplot || wgnuplot */
    LEPT_FREE(cmdname);
    return 0;
}
示例#23
0
文件: jpegio.c 项目: MaTriXy/tess-two
/*!
 * \brief   pixReadMemJpeg()
 *
 * \param[in]    data const; jpeg-encoded
 * \param[in]    size of data
 * \param[in]    cmflag colormap flag 0 means return RGB image if color;
 *                      1 means create a colormap and return
 *                      an 8 bpp colormapped image if color
 * \param[in]    reduction scaling factor: 1, 2, 4 or 8
 * \param[out]   pnwarn [optional] number of warnings
 * \param[in]    hint a bitwise OR of L_JPEG_* values; 0 for default
 * \return  pix, or NULL on error
 *
 * <pre>
 * Notes:
 *      (1) The %size byte of %data must be a null character.
 *      (2) The only hint flag so far is L_JPEG_READ_LUMINANCE,
 *          given in the enum in imageio.h.
 *      (3) See pixReadJpeg() for usage.
 * </pre>
 */
PIX *
pixReadMemJpeg(const l_uint8  *data,
               size_t          size,
               l_int32         cmflag,
               l_int32         reduction,
               l_int32        *pnwarn,
               l_int32         hint)
{
l_int32   ret;
l_uint8  *comment;
FILE     *fp;
PIX      *pix;

    PROCNAME("pixReadMemJpeg");

    if (pnwarn) *pnwarn = 0;
    if (!data)
        return (PIX *)ERROR_PTR("data not defined", procName, NULL);

    if ((fp = fopenReadFromMemory(data, size)) == NULL)
        return (PIX *)ERROR_PTR("stream not opened", procName, NULL);
    pix = pixReadStreamJpeg(fp, cmflag, reduction, pnwarn, hint);
    if (pix) {
        ret = fgetJpegComment(fp, &comment);
        if (!ret && comment) {
            pixSetText(pix, (char *)comment);
            LEPT_FREE(comment);
        }
    }
    fclose(fp);
    if (!pix) L_ERROR("pix not read\n", procName);
    return pix;
}
示例#24
0
/*!
 * \brief   bbufferCreate()
 *
 * \param[in]    indata address in memory [optional]
 * \param[in]    nalloc size of byte array to be alloc'd 0 for default
 * \return  bbuffer, or NULL on error
 *
 * <pre>
 * Notes:
 *      (1) If a buffer address is given, you should read all the data in.
 *      (2) Allocates a bbuffer with associated byte array of
 *          the given size.  If a buffer address is given,
 *          it then reads the number of bytes into the byte array.
 * </pre>
 */
L_BBUFFER *
bbufferCreate(l_uint8  *indata,
              l_int32   nalloc)
{
L_BBUFFER  *bb;

    PROCNAME("bbufferCreate");

    if (nalloc <= 0)
        nalloc = INITIAL_BUFFER_ARRAYSIZE;

    if ((bb = (L_BBUFFER *)LEPT_CALLOC(1, sizeof(L_BBUFFER))) == NULL)
        return (L_BBUFFER *)ERROR_PTR("bb not made", procName, NULL);
    if ((bb->array = (l_uint8 *)LEPT_CALLOC(nalloc, sizeof(l_uint8))) == NULL) {
        LEPT_FREE(bb);
        return (L_BBUFFER *)ERROR_PTR("byte array not made", procName, NULL);
    }
    bb->nalloc = nalloc;
    bb->nwritten = 0;

    if (indata) {
        memcpy((l_uint8 *)bb->array, indata, nalloc);
        bb->n = nalloc;
    } else {
        bb->n = 0;
    }

    return bb;
}
/*!
 * \brief   l_productMat4()
 *
 * \param[in]    mat1  square matrix, as a 1-dimensional size^2 array
 * \param[in]    mat2  square matrix, as a 1-dimensional size^2 array
 * \param[in]    mat3  square matrix, as a 1-dimensional size^2 array
 * \param[in]    mat4  square matrix, as a 1-dimensional size^2 array
 * \param[in]    matd  square matrix; product stored here
 * \param[in]    size  of matrices
 * \return  0 if OK, 1 on error
 */
l_int32
l_productMat4(l_float32  *mat1,
              l_float32  *mat2,
              l_float32  *mat3,
              l_float32  *mat4,
              l_float32  *matd,
              l_int32     size)
{
l_float32  *matt;

    PROCNAME("l_productMat4");

    if (!mat1)
        return ERROR_INT("matrix 1 not defined", procName, 1);
    if (!mat2)
        return ERROR_INT("matrix 2 not defined", procName, 1);
    if (!mat3)
        return ERROR_INT("matrix 3 not defined", procName, 1);
    if (!matd)
        return ERROR_INT("result matrix not defined", procName, 1);

    if ((matt = (l_float32 *)LEPT_CALLOC(size * size, sizeof(l_float32))) == NULL)
        return ERROR_INT("matt not made", procName, 1);
    l_productMat3(mat1, mat2, mat3, matt, size);
    l_productMat2(matt, mat4, matd, size);
    LEPT_FREE(matt);
    return 0;
}
/*!
 * \brief   pixWriteTempfile()
 *
 * \param[in]    dir directory name; use '.' for local dir; no trailing '/'
 * \param[in]    tail [optional] tailname, including extension if any
 * \param[in]    pix
 * \param[in]    format
 * \param[in]    &filename [optional] return actual filename used; use
 *                         null to skip
 * \return  0 if OK; 1 on error
 *
 * <pre>
 * Notes:
 *      (1) This generates a temp filename, writes the pix to it,
 *          and optionally returns the temp filename.
 *      (2) If the filename is returned to a windows program from a DLL,
 *          use lept_free() to free it.
 *      (3) See genTempFilename() for details.  We omit the time and pid
 *          here.
 * </pre>
 */
l_int32
pixWriteTempfile(const char  *dir,
                 const char  *tail,
                 PIX         *pix,
                 l_int32      format,
                 char       **pfilename)
{
char    *filename;
l_int32  ret;

    PROCNAME("pixWriteTempfile");

    if (!dir)
        return ERROR_INT("filename not defined", procName, 1);
    if (!pix)
        return ERROR_INT("pix not defined", procName, 1);

    if ((filename = genTempFilename(dir, tail, 0, 0)) == NULL)
        return ERROR_INT("temp filename not made", procName, 1);

    ret = pixWrite(filename, pix, format);
    if (pfilename)
        *pfilename = filename;
    else
        LEPT_FREE(filename);

    return ret;
}
示例#27
0
/*!
 * \brief   sudokuCompareState()
 *
 * \param[in]    sud1, sud2
 * \param[in]    quads rotation of sud2 input with respect to sud1,
 *                    in units of 90 degrees cw
 * \param[out]   psame 1 if all 4 results are identical; 0 otherwise
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) The input to sud2 has been rotated by %quads relative to the
 *          input to sud1.  Therefore, we must rotate the solution to
 *          sud1 by the same amount before comparing it to the
 *          solution to sud2.
 * </pre>
 */
static l_int32
sudokuCompareState(L_SUDOKU  *sud1,
                   L_SUDOKU  *sud2,
                   l_int32    quads,
                   l_int32   *psame)
{
l_int32   i, same;
l_int32  *array;

    PROCNAME("sudokuCompareState");

    if (!psame)
        return ERROR_INT("&same not defined", procName, 1);
    *psame = 0;
    if (!sud1)
        return ERROR_INT("sud1 not defined", procName, 1);
    if (!sud2)
        return ERROR_INT("sud1 not defined", procName, 1);
    if (quads < 1 || quads > 3)
        return ERROR_INT("valid quads in {1,2,3}", procName, 1);

    same = TRUE;
    if ((array = sudokuRotateArray(sud1->state, quads)) == NULL)
        return ERROR_INT("array not made", procName, 1);
    for (i = 0; i < 81; i++) {
        if (array[i] != sud2->state[i]) {
            same = FALSE;
            break;
        }
    }
    *psame = same;
    LEPT_FREE(array);
    return 0;
}
示例#28
0
    /* postorder DFS */
static void
destroy_helper(node  *n)
{
    if (!n) return;
    destroy_helper(n->left);
    destroy_helper(n->right);
    LEPT_FREE(n);
}
示例#29
0
/*!
 * \brief   pixWriteMemGif()
 *
 * \param[out]   pdata data of gif compressed image
 * \param[out]   psize size of returned data
 * \param[in]    pix
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) See comments in pixReadMemGif()
 *      (2) For Giflib version >= 5.1, this uses the EGifOpen() buffer
 *          interface.  No temp files are required.
 * </pre>
 */
l_int32
pixWriteMemGif(l_uint8  **pdata,
               size_t    *psize,
               PIX       *pix)
{
#if (GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || GIFLIB_MAJOR > 5
int           giferr;
l_int32       result;
GifFileType  *gif;
L_BBUFFER     *buffer;
#else
char         *fname;
#endif  /* 5.1 and beyond */

    PROCNAME("pixWriteMemGif");

    if (!pdata)
        return ERROR_INT("&data not defined", procName, 1 );
    *pdata = NULL;
    if (!psize)
        return ERROR_INT("&size not defined", procName, 1 );
    *psize = 0;
    if (!pix)
        return ERROR_INT("&pix not defined", procName, 1 );

#if (GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || GIFLIB_MAJOR > 5
    if((buffer = bbufferCreate(NULL, 0)) == NULL) {
        return ERROR_INT("failed to create buffer", procName, 1);
    }

    if ((gif = EGifOpen((void*)buffer, gifWriteFunc, NULL)) == NULL) {
        bbufferDestroy(&buffer);
        return ERROR_INT("failed to create GIF image handle", procName, 1);
    }

    result = pixToGif(pix, gif);
    EGifCloseFile(gif, &giferr);

    if(result == 0) {
        *pdata = bbufferDestroyAndSaveData(&buffer, psize);
    } else {
        bbufferDestroy(&buffer);
    }
    return result;
#else
    L_INFO("writing to a temp file, not directly to memory\n", procName);

        /* Write to a temp file */
    fname = l_makeTempFilename(NULL);
    pixWrite(fname, pix, IFF_GIF);

        /* Read back into memory */
    *pdata = l_binaryRead(fname, psize);
    lept_rmfile(fname);
    LEPT_FREE(fname);
    return 0;
#endif
}
示例#30
0
/*!
 * \brief   recogDestroy()
 *
 * \param[in,out]   precog will be set to null before returning
 * \return  void
 */
void
recogDestroy(L_RECOG  **precog)
{
L_RECOG  *recog;

    PROCNAME("recogDestroy");

    if (!precog) {
        L_WARNING("ptr address is null\n", procName);
        return;
    }

    if ((recog = *precog) == NULL) return;

    LEPT_FREE(recog->centtab);
    LEPT_FREE(recog->sumtab);
    sarrayDestroy(&recog->sa_text);
    l_dnaDestroy(&recog->dna_tochar);
    pixaaDestroy(&recog->pixaa_u);
    pixaDestroy(&recog->pixa_u);
    ptaaDestroy(&recog->ptaa_u);
    ptaDestroy(&recog->pta_u);
    numaDestroy(&recog->nasum_u);
    numaaDestroy(&recog->naasum_u);
    pixaaDestroy(&recog->pixaa);
    pixaDestroy(&recog->pixa);
    ptaaDestroy(&recog->ptaa);
    ptaDestroy(&recog->pta);
    numaDestroy(&recog->nasum);
    numaaDestroy(&recog->naasum);
    pixaDestroy(&recog->pixa_tr);
    pixaDestroy(&recog->pixadb_ave);
    pixaDestroy(&recog->pixa_id);
    pixDestroy(&recog->pixdb_ave);
    pixDestroy(&recog->pixdb_range);
    pixaDestroy(&recog->pixadb_boot);
    pixaDestroy(&recog->pixadb_split);
    bmfDestroy(&recog->bmf);
    rchDestroy(&recog->rch);
    rchaDestroy(&recog->rcha);
    recogDestroyDid(recog);
    LEPT_FREE(recog);
    *precog = NULL;
    return;
}