Exemplo n.º 1
0
PIX *
PixTest2(PIX          *pixs,
         l_int32       size,
         l_float32     factor,
         l_int32       nx,
         l_int32       ny,
         L_REGPARAMS  *rp)
{
l_int32  w, h;
PIX     *pixth, *pixd, *pixt;
PIXA    *pixa;

    pixth = pixd = NULL;
    pixGetDimensions(pixs, &w, &h, NULL);

        /* Get speed */
    startTimer();
    pixSauvolaBinarizeTiled(pixs, size, factor, nx, ny, NULL, &pixd);
    fprintf(stderr, "Speed: %d x %d tiles,  %7.3f Mpix/sec\n",
            nx, ny, (w * h / 1000000.) / stopTimer());
    pixDestroy(&pixd);

        /* Get results */
    pixSauvolaBinarizeTiled(pixs, size, factor, nx, ny, &pixth, &pixd);
    regTestWritePixAndCheck(rp, pixth, IFF_JFIF_JPEG);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);
    if (rp->index < 5 && rp->display) {
        pixa = pixaCreate(0);
        pixSaveTiled(pixth, pixa, 1, 1, 30, 8);
        pixSaveTiled(pixd, pixa, 1, 0, 30, 8);
        pixt = pixaDisplay(pixa, 0, 0);
        pixDisplayWithTitle(pixt, 100, 400, NULL, rp->display);
        pixDestroy(&pixt);
        pixaDestroy(&pixa);
    }

    pixDestroy(&pixth);
    return pixd;
}
Exemplo n.º 2
0
/*!
 *  wshedCreate()
 *
 *      Input:  pixs  (8 bpp source)
 *              pixm  (1 bpp 'marker' seed)
 *              mindepth (minimum depth; anything less is not saved)
 *              debugflag (1 for debug output)
 *      Return: WShed, or null on error
 *
 *  Notes:
 *      (1) It is not necessary for the fg pixels in the seed image
 *          be at minima, or that they be isolated.  We extract a
 *          single pixel from each connected component, and a seed
 *          anywhere in a watershed will eventually label the watershed
 *          when the filling level reaches it.
 *      (2) Set mindepth to some value to ignore noise in pixs that
 *          can create small local minima.  Any watershed shallower
 *          than mindepth, even if it has a seed, will not be saved;
 *          It will either be incorporated in another watershed or
 *          eliminated.
 */
L_WSHED *
wshedCreate(PIX     *pixs,
            PIX     *pixm,
            l_int32  mindepth,
            l_int32  debugflag)
{
l_int32   w, h;
L_WSHED  *wshed;

    PROCNAME("wshedCreate");

    if (!pixs)
        return (L_WSHED *)ERROR_PTR("pixs is not defined", procName, NULL);
    if (pixGetDepth(pixs) != 8)
        return (L_WSHED *)ERROR_PTR("pixs is not 8 bpp", procName, NULL);
    if (!pixm)
        return (L_WSHED *)ERROR_PTR("pixm is not defined", procName, NULL);
    if (pixGetDepth(pixm) != 1)
        return (L_WSHED *)ERROR_PTR("pixm is not 1 bpp", procName, NULL);
    pixGetDimensions(pixs, &w, &h, NULL);
    if (pixGetWidth(pixm) != w || pixGetHeight(pixm) != h)
        return (L_WSHED *)ERROR_PTR("pixs/m sizes are unequal", procName, NULL);

    if ((wshed = (L_WSHED *)CALLOC(1, sizeof(L_WSHED))) == NULL)
        return (L_WSHED *)ERROR_PTR("wshed not made", procName, NULL);

    wshed->pixs = pixClone(pixs);
    wshed->pixm = pixClone(pixm);
    wshed->mindepth = L_MAX(1, mindepth);
    wshed->pixlab = pixCreate(w, h, 32);
    pixSetAllArbitrary(wshed->pixlab, MAX_LABEL_VALUE);
    wshed->pixt = pixCreate(w, h, 1);
    wshed->lines8 = pixGetLinePtrs(pixs, NULL);
    wshed->linem1 = pixGetLinePtrs(pixm, NULL);
    wshed->linelab32 = pixGetLinePtrs(wshed->pixlab, NULL);
    wshed->linet1 = pixGetLinePtrs(wshed->pixt, NULL);
    wshed->debug = debugflag;
    return wshed;
}
Exemplo n.º 3
0
jint Java_com_googlecode_leptonica_android_WriteFile_nativeWriteBytes8(JNIEnv *env, jclass clazz,
                                                                       jint nativePix,
                                                                       jbyteArray data) {
  LOGV(__FUNCTION__);

  l_int32 w, h, d;
  PIX *pix = (PIX *) nativePix;
  pixGetDimensions(pix, &w, &h, &d);

  l_uint8 **lineptrs = pixSetupByteProcessing(pix, NULL, NULL);
  jbyte *data_buffer = env->GetByteArrayElements(data, NULL);
  l_uint8 *byte_buffer = (l_uint8 *) data_buffer;

  for (int i = 0; i < h; i++) {
    memcpy((byte_buffer + (i * w)), lineptrs[i], w);
  }

  env->ReleaseByteArrayElements(data, data_buffer, 0);
  pixCleanupByteProcessing(pix, lineptrs);

  return (jint) (w * h);
}
Exemplo n.º 4
0
/*!
 *  pixaCreateFromPix()
 *
 *      Input:  pixs  (with individual components on a lattice)
 *              n   (number of components)
 *              cellw   (width of each cell)
 *              cellh   (height of each cell)
 *      Return: pixa, or null on error
 *
 *  Note: for bpp = 1, we truncate each retrieved pix to
 *        the ON pixels, which we assume for now start at (0,0)
 */
PIXA *
pixaCreateFromPix(PIX     *pixs,
                  l_int32  n,
                  l_int32  cellw,
                  l_int32  cellh)
{
l_int32  w, h, d, nw, nh, i, j, index;
PIX     *pix, *pixt;
PIXA    *pixa;

    PROCNAME("pixaCreateFromPix");

    if (!pixs)
        return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
    if (n <= 0)
        return (PIXA *)ERROR_PTR("n must be > 0", procName, NULL);

    if ((pixa = pixaCreate(n)) == NULL)
        return (PIXA *)ERROR_PTR("pixa not made", procName, NULL);
    pixGetDimensions(pixs, &w, &h, &d);
    if ((pixt = pixCreate(cellw, cellh, d)) == NULL)
        return (PIXA *)ERROR_PTR("pixt not made", procName, NULL);

    nw = (w + cellw - 1) / cellw;
    nh = (h + cellh - 1) / cellh;
    for (i = 0, index = 0; i < nh; i++) {
        for (j = 0; j < nw && index < n; j++, index++) {
            pixRasterop(pixt, 0, 0, cellw, cellh, PIX_SRC, pixs,
                   j * cellw, i * cellh);
            if (d == 1 && !pixClipToForeground(pixt, &pix, NULL))
                pixaAddPix(pixa, pix, L_INSERT);
            else
                pixaAddPix(pixa, pixt, L_COPY);
        }
    }

    pixDestroy(&pixt);
    return pixa;
}
/*!
 *  pixFinalAccumulateThreshold()
 *
 *      Input:  pixs (32 bpp)
 *              offset (same as used for initialization)
 *              threshold (values less than this are set in the destination)
 *      Return: pixd (1 bpp), or null on error
 *
 *  Notes:
 *      (1) The offset must be >= 0 and should not exceed 0x40000000.
 *      (2) The offset is subtracted from the src 32 bpp image
 */
PIX *
pixFinalAccumulateThreshold(PIX      *pixs,
                            l_uint32  offset,
                            l_uint32  threshold)
{
l_int32    i, j, w, h, wpls, wpld, val;
l_uint32  *datas, *datad, *lines, *lined;
PIX       *pixd;

    PROCNAME("pixFinalAccumulateThreshold");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    if (pixGetDepth(pixs) != 32)
        return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
    if (offset > 0x40000000)
        offset = 0x40000000;

    pixGetDimensions(pixs, &w, &h, NULL);
    if ((pixd = pixCreate(w, h, 1)) == NULL)
        return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
    pixCopyResolution(pixd, pixs);  /* but how did pixs get it initially? */
    datas = pixGetData(pixs);
    datad = pixGetData(pixd);
    wpls = pixGetWpl(pixs);
    wpld = pixGetWpl(pixd);
    for (i = 0; i < h; i++) {
        lines = datas + i * wpls;
        lined = datad + i * wpld;
        for (j = 0; j < w; j++) {
            val = lines[j] - offset;
            if (val >= threshold) {
                SET_DATA_BIT(lined, j);
            }
        }
    }

    return pixd;
}
Exemplo n.º 6
0
/*!
 * \brief   nextOnPixelInRaster()
 *
 * \param[in]    pixs 1 bpp
 * \param[in]    xstart, ystart  starting point for search
 * \param[out]   px, py  coord value of next ON pixel
 * \return  1 if a pixel is found; 0 otherwise or on error
 */
l_int32
nextOnPixelInRaster(PIX      *pixs,
                    l_int32   xstart,
                    l_int32   ystart,
                    l_int32  *px,
                    l_int32  *py)
{
    l_int32    w, h, d, wpl;
    l_uint32  *data;

    PROCNAME("nextOnPixelInRaster");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 0);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 1)
        return ERROR_INT("pixs not 1 bpp", procName, 0);

    wpl = pixGetWpl(pixs);
    data = pixGetData(pixs);
    return nextOnPixelInRasterLow(data, w, h, wpl, xstart, ystart, px, py);
}
Exemplo n.º 7
0
/*!
 *  pixBilinearGray()
 *
 *      Input:  pixs (8 bpp)
 *              vc  (vector of 8 coefficients for bilinear transformation)
 *              grayval (0 to bring in BLACK, 255 for WHITE)
 *      Return: pixd, or null on error
 */
PIX *
pixBilinearGray(PIX *pixs,
                l_float32 *vc,
                l_uint8 grayval) {
    l_int32 i, j, w, h, wpls, wpld, val;
    l_uint32 *datas, *datad, *lined;
    l_float32 x, y;
    PIX *pixd;

    PROCNAME("pixBilinearGray");

    if (!pixs)
        return (PIX *) ERROR_PTR("pixs not defined", procName, NULL);
    pixGetDimensions(pixs, &w, &h, NULL);
    if (pixGetDepth(pixs) != 8)
        return (PIX *) ERROR_PTR("pixs must be 8 bpp", procName, NULL);
    if (!vc)
        return (PIX *) ERROR_PTR("vc not defined", procName, NULL);

    datas = pixGetData(pixs);
    wpls = pixGetWpl(pixs);
    pixd = pixCreateTemplate(pixs);
    pixSetAllArbitrary(pixd, grayval);
    datad = pixGetData(pixd);
    wpld = pixGetWpl(pixd);

    /* Iterate over destination pixels */
    for (i = 0; i < h; i++) {
        lined = datad + i * wpld;
        for (j = 0; j < w; j++) {
            /* Compute float src pixel location corresponding to (i,j) */
            bilinearXformPt(vc, j, i, &x, &y);
            linearInterpolatePixelGray(datas, wpls, w, h, x, y, grayval, &val);
            SET_DATA_BYTE(lined, j, val);
        }
    }

    return pixd;
}
Exemplo n.º 8
0
/*!
 *  pixThresholdToValue()
 *
 *      Input:  pixd (<optional>; if not null, must be equal to pixs)
 *              pixs (8, 16, 32 bpp)
 *              threshval
 *              setval
 *      Return: pixd always
 *
 *  Notes:
 *    - operation can be in-place (pixs == pixd) or to a new pixd
 *    - if setval > threshval, sets pixels with a value >= threshval to setval
 *    - if setval < threshval, sets pixels with a value <= threshval to setval
 *    - if setval == threshval, no-op
 */
PIX *
pixThresholdToValue(PIX      *pixd,
                    PIX      *pixs,
                    l_int32   threshval,
                    l_int32   setval)
{
l_int32    w, h, d, wpld;
l_uint32  *datad;

    PROCNAME("pixThresholdToValue");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
    d = pixGetDepth(pixs);
    if (d != 8 && d != 16 && d != 32)
        return (PIX *)ERROR_PTR("pixs not 8, 16 or 32 bpp", procName, pixd);
    if (pixd && (pixs != pixd))
        return (PIX *)ERROR_PTR("pixd exists and is not pixs", procName, pixd);
    if (threshval < 0 || setval < 0)
        return (PIX *)ERROR_PTR("threshval & setval not < 0", procName, pixd);
    if (d == 8 && setval > 255)
        return (PIX *)ERROR_PTR("setval > 255 for 8 bpp", procName, pixd);
    if (d == 16 && setval > 0xffff)
        return (PIX *)ERROR_PTR("setval > 0xffff for 16 bpp", procName, pixd);

    if (!pixd)
        pixd = pixCopy(NULL, pixs);
    if (setval == threshval) {
        L_WARNING("setval == threshval; no operation", procName);
        return pixd;
    }

    datad = pixGetData(pixd);
    pixGetDimensions(pixd, &w, &h, NULL);
    wpld = pixGetWpl(pixd);

    thresholdToValueLow(datad, w, h, d, wpld, threshval, setval);
    return pixd;
}
Exemplo n.º 9
0
/*!
 *  regTestCompareSimilarPix()
 *
 *      Input:  rp (regtest parameters)
 *              pix1, pix2 (to be tested for equality)
 *              mindiff (minimum pixel difference to be counted; > 0)
 *              maxfract (maximum fraction of pixels allowed to have
 *                        diff greater than or equal to mindiff)
 *              printstats (use 1 to print normalized histogram to stderr)
 *      Return: 0 if OK, 1 on error (a failure in similarity comparison
 *              is not an error)
 *
 *  Notes:
 *      (1) This function compares two pix for equality.  If not in compare
 *          mode, on failure it writes to stderr.
 *      (2) To identify two images as 'similar', select @maxfract to be
 *          the upper bound for what you expect.  Typical values might
 *          be @mindiff = 15 and @maxfract = 0.01.
 *      (3) Normally, use @printstats = 0.  In debugging mode, to see
 *          the relation between @mindiff and the minimum value of
 *          @maxfract for success, set this to 1.
 */
l_int32
regTestCompareSimilarPix(L_REGPARAMS  *rp,
                         PIX          *pix1,
                         PIX          *pix2,
                         l_int32       mindiff,
                         l_float32     maxfract,
                         l_int32       printstats)
{
l_int32  w, h, factor, similar;

    PROCNAME("regTestCompareSimilarPix");

    if (!rp)
        return ERROR_INT("rp not defined", procName, 1);
    if (!pix1 || !pix2) {
        rp->success = FALSE;
        return ERROR_INT("pix1 and pix2 not both defined", procName, 1);
    }

    rp->index++;
    pixGetDimensions(pix1, &w, &h, NULL);
    factor = L_MAX(w, h) / 400;
    factor = L_MAX(1, L_MIN(factor, 4));   /* between 1 and 4 */
    pixTestForSimilarity(pix1, pix2, factor, mindiff, maxfract, 0.0,
                         &similar, printstats);

        /* Record on failure */
    if (!similar) {
        if (rp->fp) {
            fprintf(rp->fp,
                    "Failure in %s_reg: pix similarity comp for index %d\n",
                    rp->testname, rp->index);
        }
        fprintf(stderr, "Failure in %s_reg: pix similarity comp for index %d\n",
                rp->testname, rp->index);
        rp->success = FALSE;
    }
    return 0;
}
Exemplo n.º 10
0
/*!
 *  pixaGetPixDimensions()
 *
 *      Input:  pixa
 *              index  (to the index-th box)
 *              &w, &h, &d (<optional return>; each can be null)
 *      Return: 0 if OK, 1 on error
 */
l_int32
pixaGetPixDimensions(PIXA     *pixa,
                     l_int32   index,
                     l_int32  *pw,
                     l_int32  *ph,
                     l_int32  *pd)
{
PIX  *pix;

    PROCNAME("pixaGetPixDimensions");

    if (!pixa)
        return ERROR_INT("pixa not defined", procName, 1);
    if (index < 0 || index >= pixa->n)
        return ERROR_INT("index not valid", procName, 1);

    if ((pix = pixaGetPix(pixa, index, L_CLONE)) == NULL)
        return ERROR_INT("pix not found!", procName, 1);
    pixGetDimensions(pix, pw, ph, pd);
    pixDestroy(&pix);
    return 0;
}
Exemplo n.º 11
0
/*!
 *  pixSetPadBits()
 *
 *      Input:  pix (1, 2, 4, 8, 16, 32 bpp)
 *              val  (0 or 1)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      (1) The pad bits are the bits that expand each scanline to a
 *          multiple of 32 bits.  They are usually not used in
 *          image processing operations.  When boundary conditions
 *          are important, as in seedfill, they must be set properly.
 *      (2) This sets the value of the pad bits (if any) in the last
 *          32-bit word in each scanline.
 *      (3) For 32 bpp pix, there are no pad bits, so this is a no-op.
 */
LEPTONICA_REAL_EXPORT l_int32
pixSetPadBits(PIX     *pix,
              l_int32  val)
{
l_int32    i, w, h, d, wpl, endbits, fullwords;
l_uint32   mask;
l_uint32  *data, *pword;

    PROCNAME("pixSetPadBits");

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

    pixGetDimensions(pix, &w, &h, &d);
    if (d == 32)  /* no padding exists for 32 bpp */
        return 0;  

    data = pixGetData(pix);
    wpl = pixGetWpl(pix);
    endbits = 32 - ((w * d) % 32);
    if (endbits == 32)  /* no partial word */
        return 0;
    fullwords = w * d / 32;

    mask = rmask32[endbits];
    if (val == 0)
        mask = ~mask;

    for (i = 0; i < h; i++) {
        pword = data + i * wpl + fullwords;
        if (val == 0) /* clear */
            *pword = *pword & mask;
        else  /* set */
            *pword = *pword | mask;
    }

    return 0;
}
Exemplo n.º 12
0
/*!
 *  localSearchForBackground()
 *
 *      Input:  &x, &y (starting position for search; return found position)
 *              maxrad (max distance to search from starting location)
 *      Return: 0 if bg pixel found; 1 if not found
 */
static l_int32
localSearchForBackground(PIX  *pix,
                         l_int32  *px,
                         l_int32  *py,
                         l_int32  maxrad)
{
l_int32   x, y, w, h, r, i, j;
l_uint32  val;

    x = *px;
    y = *py;
    pixGetPixel(pix, x, y, &val);
    if (val == 0) return 0;

        /* For each value of r, restrict the search to the boundary
         * pixels in a square centered on (x,y), clipping to the
         * image boundaries if necessary.  */
    pixGetDimensions(pix, &w, &h, NULL);
    for (r = 1; r < maxrad; r++) {
        for (i = -r; i <= r; i++) {
            if (y + i < 0 || y + i >= h)
                continue;
            for (j = -r; j <= r; j++) {
                if (x + j < 0 || x + j >= w)
                    continue;
                if (L_ABS(i) != r && L_ABS(j) != r)  /* not on "r ring" */
                    continue;
                pixGetPixel(pix, x + j, y + i, &val);
                if (val == 0) {
                    *px = x + j;
                    *py = y + i;
                    return 0;
                }
            }
        }
    }
    return 1;
}
Exemplo n.º 13
0
PIXA *MakeBootnum2(void)
{
char     *fname;
l_int32   i, n, w, h;
BOX      *box;
PIX      *pix;
PIXA     *pixa;
L_RECOG  *recog;
SARRAY   *sa;

        /* Phase 1: generate recog from the digit data */
    recog = recogCreate(20, 32, L_USE_ALL, 120, 1);
    sa = getSortedPathnamesInDirectory("recog/bootnums", "png", 0, 0);
    n = sarrayGetCount(sa);
    for (i = 0; i < n; i++) {
            /* Read each pix: grayscale, multi-character, labelled */
        fname = sarrayGetString(sa, i, L_NOCOPY);
        if ((pix = pixRead(fname)) == NULL) {
            fprintf(stderr, "Can't read %s\n", fname);
            continue;
        }

            /* Convert to a set of 1 bpp, single character, labelled */
        pixGetDimensions(pix, &w, &h, NULL);
        box = boxCreate(0, 0, w, h);
        recogTrainLabelled(recog, pix, box, NULL, 1, 0);
        pixDestroy(&pix);
        boxDestroy(&box);
    }
    recogTrainingFinished(recog, 1);
    sarrayDestroy(&sa);

        /* Phase 2: generate pixa consisting of 1 bpp, single character pix */
    recogWritePixa("/tmp/lept/recog/digits/bootnum2.pa", recog);
    pixa = pixaRead("/tmp/lept/recog/digits/bootnum2.pa");
    recogDestroy(&recog);
    return pixa;
}
Exemplo n.º 14
0
/*!
 *  pixMultConstantGray()
 *
 *      Input:  pixs (8, 16 or 32 bpp)
 *              val  (>= 0.0; amount to multiply by each pixel)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) In-place operation; val must be >= 0.
 *      (2) No clipping for 32 bpp.
 *      (3) For 8 and 16 bpp, the result is clipped to 0xff and 0xffff, rsp.
 */
l_int32
pixMultConstantGray(PIX       *pixs,
                    l_float32  val)
{
l_int32    w, h, d, wpl;
l_uint32  *data;

    PROCNAME("pixMultConstantGray");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 8 && d != 16 && d != 32)
        return ERROR_INT("pixs not 8, 16 or 32 bpp", procName, 1);
    if (val < 0.0)
        return ERROR_INT("val < 0.0", procName, 1);

    data = pixGetData(pixs);
    wpl = pixGetWpl(pixs);
    multConstantGrayLow(data, w, h, d, wpl, val);

    return 0;
}
Exemplo n.º 15
0
jlong Java_com_googlecode_leptonica_android_ReadFile_nativeReadBytes8(JNIEnv *env, jclass clazz,
                                                                      jbyteArray data, jint w,
                                                                      jint h) {
    PIX *pix = pixCreateNoInit((l_int32) w, (l_int32) h, 8);
    l_uint8 **lineptrs = pixSetupByteProcessing(pix, NULL, NULL);
    jbyte *data_buffer = env->GetByteArrayElements(data, NULL);
    l_uint8 *byte_buffer = (l_uint8 *) data_buffer;

    for (int i = 0; i < h; i++) {
        memcpy(lineptrs[i], (byte_buffer + (i * w)), w);
    }

    env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT);
    pixCleanupByteProcessing(pix, lineptrs);

    l_int32 d;

    pixGetDimensions(pix, &w, &h, &d);

    LOGI("Created image with w=%d, h=%d, d=%d", w, h, d);

    return (jlong) pix;
}
Exemplo n.º 16
0
// NOTE: Opposite to SetImage for raw images, SetImage for Pix clones its
// input, so the source pix may be pixDestroyed immediately after.
void ImageThresholder::SetImage(const Pix* pix) {
  image_data_ = NULL;
  if (pix_ != NULL)
    pixDestroy(&pix_);
  Pix* src = const_cast<Pix*>(pix);
  int depth;
  pixGetDimensions(src, &image_width_, &image_height_, &depth);
  // Convert the image as necessary so it is one of binary, plain RGB, or
  // 8 bit with no colormap.
  if (depth > 1 && depth < 8) {
    pix_ = pixConvertTo8(src, false);
  } else if (pixGetColormap(src)) {
    pix_ = pixRemoveColormap(src, REMOVE_CMAP_BASED_ON_SRC);
  } else {
    pix_ = pixClone(src);
  }
  depth = pixGetDepth(pix_);
  image_bytespp_ = depth / 8;
  image_bytespl_ = pixGetWpl(pix_) * sizeof(l_uint32);
  scale_ = 1;
  estimated_res_ = yres_ = pixGetYRes(src);
  Init();
}
Exemplo n.º 17
0
jint Java_com_googlecode_leptonica_android_Rotate_nativeRotate(JNIEnv *env, jclass clazz,
                                                               jint nativePix, jfloat degrees,
                                                               jboolean quality, jboolean resize) {
  PIX *pixd;
  PIX *pixs = (PIX *) nativePix;

  l_float32 deg2rad = 3.1415926535 / 180.0;
  l_float32 radians = degrees * deg2rad;
  l_int32 w, h, bpp, type;

  pixGetDimensions(pixs, &w, &h, &bpp);

  if (bpp == 1 && quality == JNI_TRUE) {
    pixd = pixRotateBinaryNice(pixs, radians, L_BRING_IN_WHITE);
  } else {
    type = quality == JNI_TRUE ? L_ROTATE_AREA_MAP : L_ROTATE_SAMPLING;
    w = (resize == JNI_TRUE) ? w : 0;
    h = (resize == JNI_TRUE) ? h : 0;
    pixd = pixRotate(pixs, radians, type, L_BRING_IN_WHITE, w, h);
  }

  return (jint) pixd;
}
Exemplo n.º 18
0
/*!
 *  pixRotateAMColorCorner()
 *
 *      Input:  pixs
 *              angle (radians; clockwise is positive)
 *              colorval (e.g., 0 to bring in BLACK, 0xffffff00 for WHITE)
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) Rotates the image about the UL corner.
 *      (2) A positive angle gives a clockwise rotation.
 *      (3) Specify the color to be brought in from outside the image.
 */
PIX *
pixRotateAMColorCorner(PIX       *pixs,
                       l_float32  angle,
                       l_uint32   fillval)
{
l_int32    w, h, wpls, wpld;
l_uint32  *datas, *datad;
PIX       *pix1, *pix2, *pixd;

    PROCNAME("pixRotateAMColorCorner");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    if (pixGetDepth(pixs) != 32)
        return (PIX *)ERROR_PTR("pixs must be 32 bpp", procName, NULL);

    if (L_ABS(angle) < MIN_ANGLE_TO_ROTATE)
        return pixClone(pixs);

    pixGetDimensions(pixs, &w, &h, NULL);
    datas = pixGetData(pixs);
    wpls = pixGetWpl(pixs);
    pixd = pixCreateTemplate(pixs);
    datad = pixGetData(pixd);
    wpld = pixGetWpl(pixd);

    rotateAMColorCornerLow(datad, w, h, wpld, datas, wpls, angle, fillval);
    if (pixGetSpp(pixs) == 4) {
        pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
        pix2 = pixRotateAMGrayCorner(pix1, angle, 255);  /* bring in opaque */
        pixSetRGBComponent(pixd, pix2, L_ALPHA_CHANNEL);
        pixDestroy(&pix1);
        pixDestroy(&pix2);
    }

    return pixd;
}
Exemplo n.º 19
0
/*!
 *  pixMultConstAccumulate() 
 *
 *      Input:  pixs (32 bpp)
 *              factor
 *              offset (same as used for initialization)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      (1) The offset must be >= 0 and should not exceed 0x40000000.
 *      (2) This multiplies each pixel, relative to offset, by the input factor
 *      (3) The result is returned with the offset back in place.
 */
l_int32
pixMultConstAccumulate(PIX       *pixs,
                       l_float32  factor,
                       l_uint32   offset)
{
l_int32    w, h, wpl;
l_uint32  *data;

    PROCNAME("pixMultConstAccumulate");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (pixGetDepth(pixs) != 32)
        return ERROR_INT("pixs not 32 bpp", procName, 1);
    if (offset > 0x40000000)
        offset = 0x40000000;

    pixGetDimensions(pixs, &w, &h, NULL);
    data = pixGetData(pixs);
    wpl = pixGetWpl(pixs);

    multConstAccumulateLow(data, w, h, wpl, factor, offset);
    return 0;
}
Exemplo n.º 20
0
/*!
 *  pixQuadtreeVariance()
 *
 *      Input:  pixs (8 bpp, no colormap)
 *              nlevels (in quadtree)
 *             *pix_ma (input mean accumulator; can be null)
 *             *dpix_msa (input mean square accumulator; can be null)
 *             *pfpixa_v (<optional return> variance values in quadtree)
 *             *pfpixa_rv (<optional return> root variance values in quadtree)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) The returned fpixav and fpixarv have @nlevels of fpix,
 *          each containing at the respective levels the variance
 *          and root variance values.
 */
l_int32
pixQuadtreeVariance(PIX *pixs,
                    l_int32 nlevels,
                    PIX *pix_ma,
                    DPIX *dpix_msa,
                    FPIXA **pfpixa_v,
                    FPIXA **pfpixa_rv) {
    l_int32 i, j, w, h, size, n;
    l_float32 var, rvar;
    BOX *box;
    BOXA *boxa;
    BOXAA *baa;
    FPIX *fpixv, *fpixrv;
    PIX *pix_mac;  /* copy of mean accumulator */
    DPIX *dpix_msac;  /* msa clone */

    PROCNAME("pixQuadtreeVariance");

    if (!pfpixa_v && !pfpixa_rv)
        return ERROR_INT("neither &fpixav nor &fpixarv defined", procName, 1);
    if (pfpixa_v) *pfpixa_v = NULL;
    if (pfpixa_rv) *pfpixa_rv = NULL;
    if (!pixs || pixGetDepth(pixs) != 8)
        return ERROR_INT("pixs not defined or not 8 bpp", procName, 1);
    pixGetDimensions(pixs, &w, &h, NULL);
    if (nlevels > quadtreeMaxLevels(w, h))
        return ERROR_INT("nlevels too large for image", procName, 1);

    if (!pix_ma)
        pix_mac = pixBlockconvAccum(pixs);
    else
        pix_mac = pixClone(pix_ma);
    if (!pix_mac)
        return ERROR_INT("pix_mac not made", procName, 1);
    if (!dpix_msa)
        dpix_msac = pixMeanSquareAccum(pixs);
    else
        dpix_msac = dpixClone(dpix_msa);
    if (!dpix_msac)
        return ERROR_INT("dpix_msac not made", procName, 1);

    if ((baa = boxaaQuadtreeRegions(w, h, nlevels)) == NULL) {
        pixDestroy(&pix_mac);
        dpixDestroy(&dpix_msac);
        return ERROR_INT("baa not made", procName, 1);
    }

    if (pfpixa_v) *pfpixa_v = fpixaCreate(nlevels);
    if (pfpixa_rv) *pfpixa_rv = fpixaCreate(nlevels);
    for (i = 0; i < nlevels; i++) {
        boxa = boxaaGetBoxa(baa, i, L_CLONE);
        size = 1 << i;
        n = boxaGetCount(boxa);  /* n == size * size */
        if (pfpixa_v) fpixv = fpixCreate(size, size);
        if (pfpixa_rv) fpixrv = fpixCreate(size, size);
        for (j = 0; j < n; j++) {
            box = boxaGetBox(boxa, j, L_CLONE);
            pixVarianceInRectangle(pixs, box, pix_mac, dpix_msac, &var, &rvar);
            if (pfpixa_v) fpixSetPixel(fpixv, j % size, j / size, var);
            if (pfpixa_rv) fpixSetPixel(fpixrv, j % size, j / size, rvar);
            boxDestroy(&box);
        }
        if (pfpixa_v) fpixaAddFPix(*pfpixa_v, fpixv, L_INSERT);
        if (pfpixa_rv) fpixaAddFPix(*pfpixa_rv, fpixrv, L_INSERT);
        boxaDestroy(&boxa);
    }

    pixDestroy(&pix_mac);
    dpixDestroy(&dpix_msac);
    boxaaDestroy(&baa);
    return 0;
}
Exemplo n.º 21
0
int main(int    argc,
         char **argv)
{
l_uint8      *data;
l_int32       w, h, n1, n2, n, i, minval, maxval;
l_int32       ncolors, rval, gval, bval, equal;
l_int32      *rmap, *gmap, *bmap;
l_uint32      color;
l_float32     gamma;
BOX          *box;
FILE         *fp;
PIX          *pix1, *pix2, *pix3, *pix4, *pix5, *pix6;
PIX          *pixs, *pixb, *pixg, *pixc, *pixd;
PIX          *pixg2, *pixcs1, *pixcs2, *pixd1, *pixd2;
PIXA         *pixa, *pixa2, *pixa3;
PIXCMAP      *cmap, *cmap2;
RGBA_QUAD    *cta;
L_REGPARAMS  *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    /* ------------------------ (1) ----------------------------*/
        /* Blend with a white background */
    pix1 = pixRead("books_logo.png");
    pixDisplayWithTitle(pix1, 100, 0, NULL, rp->display);
    pix2 = pixAlphaBlendUniform(pix1, 0xffffff00);
    pixDisplayWithTitle(pix2, 100, 150, NULL, rp->display);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 0 */
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 1 */

        /* Generate an alpha layer based on the white background */
    pix3 = pixSetAlphaOverWhite(pix2);
    pixSetSpp(pix3, 3);
    pixWrite("/tmp/alphaops.2.png", pix3, IFF_PNG);  /* without alpha */
    regTestCheckFile(rp, "/tmp/alphaops.2.png");   /* 2 */
    pixSetSpp(pix3, 4);
    regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 3, with alpha */
    pixDisplayWithTitle(pix3, 100, 300, NULL, rp->display);

        /* Render on a light yellow background */
    pix4 = pixAlphaBlendUniform(pix3, 0xffffe000);
    regTestWritePixAndCheck(rp, pix4, IFF_PNG);  /* 4 */
    pixDisplayWithTitle(pix4, 100, 450, NULL, rp->display);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);
    pixDestroy(&pix4);

    /* ------------------------ (2) ----------------------------*/
    lept_rmdir("alpha");
    lept_mkdir("alpha");
        /* Make the transparency (alpha) layer.
         * pixs is the mask.  We turn it into a transparency (alpha)
         * layer by converting to 8 bpp.  A small convolution fuzzes
         * the mask edges so that you don't see the pixels. */
    pixs = pixRead("feyn-fract.tif");
    pixGetDimensions(pixs, &w, &h, NULL);
    pixg = pixConvert1To8(NULL, pixs, 0, 255);
    pixg2 = pixBlockconvGray(pixg, NULL, 1, 1);
    regTestWritePixAndCheck(rp, pixg2, IFF_JFIF_JPEG);  /* 5 */
    pixDisplayWithTitle(pixg2, 0, 0, "alpha", rp->display);

        /* Make the viewable image.
         * pixc is the image that we see where the alpha layer is
         * opaque -- i.e., greater than 0.  Scale it to the same
         * size as the mask.  To visualize what this will look like
         * when displayed over a black background, create the black
         * background image, pixb, and do the blending with pixcs1
         * explicitly using the alpha layer pixg2. */
    pixc = pixRead("tetons.jpg");
    pixcs1 = pixScaleToSize(pixc, w, h);
    regTestWritePixAndCheck(rp, pixcs1, IFF_JFIF_JPEG);  /* 6 */
    pixDisplayWithTitle(pixcs1, 300, 0, "viewable", rp->display);
    pixb = pixCreateTemplate(pixcs1);  /* black */
    pixd1 = pixBlendWithGrayMask(pixb, pixcs1, pixg2, 0, 0);
    regTestWritePixAndCheck(rp, pixd1, IFF_JFIF_JPEG);  /* 7 */
    pixDisplayWithTitle(pixd1, 600, 0, "alpha-blended 1", rp->display);

        /* Embed the alpha layer pixg2 into the color image pixc.
         * Write it out as is.  Then clean pixcs1 (to 0) under the fully
         * transparent part of the alpha layer, and write that result
         * out as well. */
    pixSetRGBComponent(pixcs1, pixg2, L_ALPHA_CHANNEL);
    pixWrite("/tmp/alpha/pixcs1.png", pixcs1, IFF_PNG);
    pixcs2 = pixSetUnderTransparency(pixcs1, 0, 0);
    pixWrite("/tmp/alpha/pixcs2.png", pixcs2, IFF_PNG);

        /* What will this look like over a black background?
         * Do the blending explicitly and display.  It should
         * look identical to the blended result pixd1 before cleaning. */
    pixd2 = pixBlendWithGrayMask(pixb, pixcs2, pixg2, 0, 0);
    regTestWritePixAndCheck(rp, pixd2, IFF_JFIF_JPEG);  /* 8 */
    pixDisplayWithTitle(pixd2, 0, 400, "alpha blended 2", rp->display);

        /* Read the two images back, ignoring the transparency layer.
         * The uncleaned image will come back identical to pixcs1.
         * However, the cleaned image will be black wherever
         * the alpha layer was fully transparent.  It will
         * look the same when viewed through the alpha layer,
         * but have much better compression. */
    pix1 = pixRead("/tmp/alpha/pixcs1.png");  /* just pixcs1 */
    pix2 = pixRead("/tmp/alpha/pixcs2.png");  /* cleaned under transparent */
    n1 = nbytesInFile("/tmp/alpha/pixcs1.png");
    n2 = nbytesInFile("/tmp/alpha/pixcs2.png");
    fprintf(stderr, " Original: %d bytes\n Cleaned: %d bytes\n", n1, n2);
    regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 9 */
    regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 10 */
    pixDisplayWithTitle(pix1, 300, 400, "without alpha", rp->display);
    pixDisplayWithTitle(pix2, 600, 400, "cleaned under transparent",
                        rp->display);

    pixa = pixaCreate(0);
    pixSaveTiled(pixg2, pixa, 1.0, 1, 20, 32);
    pixSaveTiled(pixcs1, pixa, 1.0, 1, 20, 0);
    pixSaveTiled(pix1, pixa, 1.0, 0, 20, 0);
    pixSaveTiled(pixd1, pixa, 1.0, 1, 20, 0);
    pixSaveTiled(pixd2, pixa, 1.0, 0, 20, 0);
    pixSaveTiled(pix2, pixa, 1.0, 1, 20, 0);
    pixd = pixaDisplay(pixa, 0, 0);
    regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG);  /* 11 */
    pixDisplayWithTitle(pixd, 200, 200, "composite", rp->display);
    pixWrite("/tmp/alpha/alpha.png", pixd, IFF_JFIF_JPEG);
    pixDestroy(&pixd);
    pixaDestroy(&pixa);
    pixDestroy(&pixs);
    pixDestroy(&pixb);
    pixDestroy(&pixg);
    pixDestroy(&pixg2);
    pixDestroy(&pixc);
    pixDestroy(&pixcs1);
    pixDestroy(&pixcs2);
    pixDestroy(&pixd);
    pixDestroy(&pixd1);
    pixDestroy(&pixd2);
    pixDestroy(&pix1);
    pixDestroy(&pix2);

    /* ------------------------ (3) ----------------------------*/
    color = 0xffffa000;
    gamma = 1.0;
    minval = 0;
    maxval = 200;
    box = boxCreate(0, 85, 600, 100);
    pixa = pixaCreate(6);
    pix1 = pixRead("blend-green1.jpg");
    pixaAddPix(pixa, pix1, L_INSERT);
    pix1 = pixRead("blend-green2.png");
    pixaAddPix(pixa, pix1, L_INSERT);
    pix1 = pixRead("blend-green3.png");
    pixaAddPix(pixa, pix1, L_INSERT);
    pix1 = pixRead("blend-orange.jpg");
    pixaAddPix(pixa, pix1, L_INSERT);
    pix1 = pixRead("blend-yellow.jpg");
    pixaAddPix(pixa, pix1, L_INSERT);
    pix1 = pixRead("blend-red.png");
    pixaAddPix(pixa, pix1, L_INSERT);
    n = pixaGetCount(pixa);
    pixa2 = pixaCreate(n);
    pixa3 = pixaCreate(n);
    for (i = 0; i < n; i++) {
        pix1 = pixaGetPix(pixa, i, L_CLONE);
        pix2 = DoBlendTest(pix1, box, color, gamma, minval, maxval, 1);
        regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 12, 14, ... 22 */
        pixDisplayWithTitle(pix2, 150 * i, 0, NULL, rp->display);
        pixaAddPix(pixa2, pix2, L_INSERT);
        pix2 = DoBlendTest(pix1, box, color, gamma, minval, maxval, 2);
        regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 13, 15, ... 23 */
        pixDisplayWithTitle(pix2, 150 * i, 200, NULL, rp->display);
        pixaAddPix(pixa3, pix2, L_INSERT);
        pixDestroy(&pix1);
    }
    if (rp->display) {
        pixaConvertToPdf(pixa2, 0, 0.75, L_FLATE_ENCODE, 0, "blend 1 test",
                         "/tmp/alpha/blending1.pdf");
        pixaConvertToPdf(pixa3, 0, 0.75, L_FLATE_ENCODE, 0, "blend 2 test",
                         "/tmp/alpha/blending2.pdf");
    }
    pixaDestroy(&pixa);
    pixaDestroy(&pixa2);
    pixaDestroy(&pixa3);
    boxDestroy(&box);

    /* ------------------------ (4) ----------------------------*/
        /* Use one image as the alpha component for a second image */
    pix1 = pixRead("test24.jpg");
    pix2 = pixRead("marge.jpg");
    pix3 = pixScale(pix2, 1.9, 2.2);
    pix4 = pixConvertTo8(pix3, 0);
    pixSetRGBComponent(pix1, pix4, L_ALPHA_CHANNEL);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 24 */
    pixDisplayWithTitle(pix1, 600, 0, NULL, rp->display);

        /* Set the alpha value in a colormap to bval */
    pix5 = pixOctreeColorQuant(pix1, 128, 0);
    cmap = pixGetColormap(pix5);
    pixcmapToArrays(cmap, &rmap, &gmap, &bmap, NULL);
    n = pixcmapGetCount(cmap);
    for (i = 0; i < n; i++) {
        pixcmapGetColor(cmap, i, &rval, &gval, &bval);
        cta = (RGBA_QUAD *)cmap->array;
        cta[i].alpha = bval;
    }

        /* Test binary serialization/deserialization of colormap with alpha */
    pixcmapSerializeToMemory(cmap, 4, &ncolors, &data);
    cmap2 = pixcmapDeserializeFromMemory(data, 4, ncolors);
    CmapEqual(cmap, cmap2, &equal);
    regTestCompareValues(rp, TRUE, equal, 0.0);  /* 25 */
    pixcmapDestroy(&cmap2);
    lept_free(data);

        /* Test ascii serialization/deserialization of colormap with alpha */
    fp = fopenWriteStream("/tmp/alpha/cmap.4", "w");
    pixcmapWriteStream(fp, cmap);
    fclose(fp);
    fp = fopenReadStream("/tmp/alpha/cmap.4");
    cmap2 = pixcmapReadStream(fp);
    fclose(fp);
    CmapEqual(cmap, cmap2, &equal);
    regTestCompareValues(rp, TRUE, equal, 0.0);  /* 26 */
    pixcmapDestroy(&cmap2);

        /* Test r/w for cmapped pix with non-opaque alpha */
    pixDisplayWithTitle(pix5, 900, 0, NULL, rp->display);
    regTestWritePixAndCheck(rp, pix5, IFF_PNG);  /* 27 */
    pixWrite("/tmp/alpha/fourcomp.png", pix5, IFF_PNG);
    pix6 = pixRead("/tmp/alpha/fourcomp.png");
    regTestComparePix(rp, pix5, pix6);  /* 28 */
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);
    pixDestroy(&pix4);
    pixDestroy(&pix5);
    pixDestroy(&pix6);
    lept_free(rmap);
    lept_free(gmap);
    lept_free(bmap);
    return regTestCleanup(rp);
}
Exemplo n.º 22
0
int main(int argc,
         char **argv) {
    char dilateseq[BUF_SIZE], erodeseq[BUF_SIZE];
    char openseq[BUF_SIZE], closeseq[BUF_SIZE];
    char wtophatseq[BUF_SIZE], btophatseq[BUF_SIZE];
    char *filein;
    l_int32 w, h, d;
    PIX *pixs, *pixt, *pixt2, *pixt3, *pixt3a, *pixt4;
    PIX *pixg, *pixd, *pixd1, *pixd2, *pixd3;
    PIXACC *pacc;
    PIXCMAP *cmap;
    static char mainName[] = "graymorph1_reg";

    if (argc != 2)
        return ERROR_INT(" Syntax:  graymorph1_reg filein", mainName, 1);

    filein = argv[1];
    if ((pixs = pixRead(filein)) == NULL)
        return ERROR_INT("pixs not made", mainName, 1);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 8)
        return ERROR_INT("pixs not 8 bpp", mainName, 1);

    /* -------- Test gray morph, including interpreter ------------ */
    pixd = pixDilateGray(pixs, WSIZE, HSIZE);
    sprintf(dilateseq, "D%d.%d", WSIZE, HSIZE);
    pixg = pixGrayMorphSequence(pixs, dilateseq, HORIZ_SEP, 0);
    pixCompare(pixd, pixg, "results are the same", "results are different");
    pixDestroy(&pixg);
    pixDestroy(&pixd);

    pixd = pixErodeGray(pixs, WSIZE, HSIZE);
    sprintf(erodeseq, "E%d.%d", WSIZE, HSIZE);
    pixg = pixGrayMorphSequence(pixs, erodeseq, HORIZ_SEP, 100);
    pixCompare(pixd, pixg, "results are the same", "results are different");
    pixDestroy(&pixg);
    pixDestroy(&pixd);

    pixd = pixOpenGray(pixs, WSIZE, HSIZE);
    sprintf(openseq, "O%d.%d", WSIZE, HSIZE);
    pixg = pixGrayMorphSequence(pixs, openseq, HORIZ_SEP, 200);
    pixCompare(pixd, pixg, "results are the same", "results are different");
    pixDestroy(&pixg);
    pixDestroy(&pixd);

    pixd = pixCloseGray(pixs, WSIZE, HSIZE);
    sprintf(closeseq, "C%d.%d", WSIZE, HSIZE);
    pixg = pixGrayMorphSequence(pixs, closeseq, HORIZ_SEP, 300);
    pixCompare(pixd, pixg, "results are the same", "results are different");
    pixDestroy(&pixg);
    pixDestroy(&pixd);

    pixd = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_WHITE);
    sprintf(wtophatseq, "Tw%d.%d", WSIZE, HSIZE);
    pixg = pixGrayMorphSequence(pixs, wtophatseq, HORIZ_SEP, 400);
    pixCompare(pixd, pixg, "results are the same", "results are different");
    pixDestroy(&pixg);
    pixDestroy(&pixd);

    pixd = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_BLACK);
    sprintf(btophatseq, "Tb%d.%d", WSIZE, HSIZE);
    pixg = pixGrayMorphSequence(pixs, btophatseq, HORIZ_SEP, 500);
    pixCompare(pixd, pixg, "results are the same", "results are different");
    pixDestroy(&pixg);

    /* ------------- Test erode/dilate duality -------------- */
    pixd = pixDilateGray(pixs, WSIZE, HSIZE);
    pixInvert(pixs, pixs);
    pixd2 = pixErodeGray(pixs, WSIZE, HSIZE);
    pixInvert(pixd2, pixd2);
    pixCompare(pixd, pixd2, "results are the same", "results are different");
    pixDestroy(&pixd);
    pixDestroy(&pixd2);

    /* ------------- Test open/close duality -------------- */
    pixd = pixOpenGray(pixs, WSIZE, HSIZE);
    pixInvert(pixs, pixs);
    pixd2 = pixCloseGray(pixs, WSIZE, HSIZE);
    pixInvert(pixd2, pixd2);
    pixCompare(pixd, pixd2, "results are the same", "results are different");
    pixDestroy(&pixd);
    pixDestroy(&pixd2);

    /* ------------- Test tophat duality -------------- */
    pixd = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_WHITE);
    pixInvert(pixs, pixs);
    pixd2 = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_BLACK);
    pixCompare(pixd, pixd2, "Correct: images are duals",
               "Error: images are not duals");
    pixDestroy(&pixd);
    pixDestroy(&pixd2);
    pixInvert(pixs, pixs);

    pixd = pixGrayMorphSequence(pixs, "Tw9.5", HORIZ_SEP, 100);
    pixInvert(pixs, pixs);
    pixd2 = pixGrayMorphSequence(pixs, "Tb9.5", HORIZ_SEP, 300);
    pixCompare(pixd, pixd2, "Correct: images are duals",
               "Error: images are not duals");
    pixDestroy(&pixd);
    pixDestroy(&pixd2);

    /* ------------- Test opening/closing for large sels -------------- */
    pixd = pixGrayMorphSequence(pixs,
                                "C9.9 + C19.19 + C29.29 + C39.39 + C49.49", HORIZ_SEP, 100);
    pixDestroy(&pixd);
    pixd = pixGrayMorphSequence(pixs,
                                "O9.9 + O19.19 + O29.29 + O39.39 + O49.49", HORIZ_SEP, 400);
    pixDestroy(&pixd);

    /* ---------- Closing plus white tophat result ------------ *
     *            Parameters: wsize, hsize = 9, 29             *
     * ---------------------------------------------------------*/
    pixd = pixCloseGray(pixs, 9, 9);
    pixd1 = pixTophat(pixd, 9, 9, L_TOPHAT_WHITE);
    pixd2 = pixGrayMorphSequence(pixs, "C9.9 + TW9.9", HORIZ_SEP, 0);
    pixCompare(pixd1, pixd2, "correct: same", "wrong: different");
    pixd3 = pixMaxDynamicRange(pixd1, L_LINEAR_SCALE);
    pixDisplayWrite(pixd3, 1);
    pixDestroy(&pixd);
    pixDestroy(&pixd1);
    pixDestroy(&pixd2);
    pixDestroy(&pixd3);
    pixd = pixCloseGray(pixs, 29, 29);
    pixd1 = pixTophat(pixd, 29, 29, L_TOPHAT_WHITE);
    pixd2 = pixGrayMorphSequence(pixs, "C29.29 + Tw29.29", HORIZ_SEP, 0);
    pixCompare(pixd1, pixd2, "correct: same", "wrong: different");
    pixd3 = pixMaxDynamicRange(pixd1, L_LINEAR_SCALE);
    pixDisplayWrite(pixd3, 1);
    pixDestroy(&pixd);
    pixDestroy(&pixd1);
    pixDestroy(&pixd2);
    pixDestroy(&pixd3);

    /* --------- hdome with parameter height = 100 ------------*/
    pixd = pixHDome(pixs, 100, 4);
    pixd2 = pixMaxDynamicRange(pixd, L_LINEAR_SCALE);
    pixDisplayWrite(pixd2, 1);
    pixDestroy(&pixd2);

    /* ----- Contrast enhancement with morph parameters 9, 9 -------*/
    pixd1 = pixInitAccumulate(w, h, 0x8000);
    pixAccumulate(pixd1, pixs, L_ARITH_ADD);
    pixMultConstAccumulate(pixd1, 3., 0x8000);
    pixd2 = pixOpenGray(pixs, 9, 9);
    pixAccumulate(pixd1, pixd2, L_ARITH_SUBTRACT);
    pixDestroy(&pixd2);
    pixd2 = pixCloseGray(pixs, 9, 9);
    pixAccumulate(pixd1, pixd2, L_ARITH_SUBTRACT);
    pixDestroy(&pixd2);
    pixd = pixFinalAccumulate(pixd1, 0x8000, 8);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd1);

    /* Do the same thing with the Pixacc */
    pacc = pixaccCreate(w, h, 1);
    pixaccAdd(pacc, pixs);
    pixaccMultConst(pacc, 3.);
    pixd1 = pixOpenGray(pixs, 9, 9);
    pixaccSubtract(pacc, pixd1);
    pixDestroy(&pixd1);
    pixd1 = pixCloseGray(pixs, 9, 9);
    pixaccSubtract(pacc, pixd1);
    pixDestroy(&pixd1);
    pixd2 = pixaccFinal(pacc, 8);
    pixaccDestroy(&pacc);
    pixDisplayWrite(pixd2, 1);

    pixCompare(pixd, pixd2, "Correct: same", "Wrong: different");
    pixDestroy(&pixd);
    pixDestroy(&pixd2);


    /* ----  Tophat result on feynman stamp, to extract diagrams ----- */
    pixDestroy(&pixs);
    pixs = pixRead("feynman-stamp.jpg");

    /* Make output image to hold five intermediate images */
    w = pixGetWidth(pixs);
    h = pixGetHeight(pixs);
    pixd = pixCreate(5 * w + 18, h + 6, 32);  /* composite output image */
    pixSetAllArbitrary(pixd, 0x0000ff00);  /* set to blue */

    /* Paste in the input image */
    pixt = pixRemoveColormap(pixs, REMOVE_CMAP_TO_FULL_COLOR);
    pixRasterop(pixd, 3, 3, w, h, PIX_SRC, pixt, 0, 0);  /* 1st one */
/*    pixWrite("/tmp/junkgray.jpg", pixt, IFF_JFIF_JPEG); */
    pixDestroy(&pixt);

    /* Paste in the grayscale version */
    cmap = pixGetColormap(pixs);
    if (cmap)
        pixt = pixRemoveColormap(pixs, REMOVE_CMAP_TO_GRAYSCALE);
    else
        pixt = pixConvertRGBToGray(pixs, 0.33, 0.34, 0.33);
    pixt2 = pixConvertTo32(pixt);  /* 8 --> 32 bpp */
    pixRasterop(pixd, w + 6, 3, w, h, PIX_SRC, pixt2, 0, 0);  /* 2nd one */
    pixDestroy(&pixt2);

    /* Paste in a log dynamic range scaled version of the white tophat */
    pixt2 = pixTophat(pixt, 3, 3, L_TOPHAT_WHITE);
    pixt3a = pixMaxDynamicRange(pixt2, L_LOG_SCALE);
    pixt3 = pixConvertTo32(pixt3a);
    pixRasterop(pixd, 2 * w + 9, 3, w, h, PIX_SRC, pixt3, 0, 0);  /* 3rd */
/*    pixWrite("/tmp/junktophat.jpg", pixt2, IFF_JFIF_JPEG); */
    pixDestroy(&pixt3);
    pixDestroy(&pixt3a);
    pixDestroy(&pixt);

    /* Stretch the range and threshold to binary; paste it in */
    pixt3a = pixGammaTRC(NULL, pixt2, 1.0, 0, 80);
    pixt3 = pixThresholdToBinary(pixt3a, 70);
    pixt4 = pixConvertTo32(pixt3);
    pixRasterop(pixd, 3 * w + 12, 3, w, h, PIX_SRC, pixt4, 0, 0);  /* 4th */
/*    pixWrite("/tmp/junkbin.png", pixt3, IFF_PNG); */
    pixDestroy(&pixt2);
    pixDestroy(&pixt3a);
    pixDestroy(&pixt4);

    /* Invert; this is the final result */
    pixInvert(pixt3, pixt3);
    pixt4 = pixConvertTo32(pixt3);
    pixRasterop(pixd, 4 * w + 15, 3, w, h, PIX_SRC, pixt4, 0, 0);  /* 5th */
    pixWrite("/tmp/junkbininvert.png", pixt3, IFF_PNG);
    pixDisplayWrite(pixd, 1);
/*    pixWrite("/tmp/junkall.jpg", pixd, IFF_JFIF_JPEG); */
    pixDestroy(&pixt3);
    pixDestroy(&pixt4);
    pixDestroy(&pixd);

    pixDisplayMultiple("/tmp/display/file*");
    pixDestroy(&pixs);
    return 0;
}
Exemplo n.º 23
0
/*!
 * \brief   pixToGif()
 *
 * \param[in]    pix 1, 2, 4, 8, 16 or 32 bpp
 * \param[in]    gif  opened gif stream
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) This encodes the pix to the gif stream. The stream is not
 *          closes by this function.
 *      (2) It is static to make this function private.
 * </pre>
 */
static l_int32
pixToGif(PIX *pix, GifFileType *gif)
{
char            *text;
l_int32          wpl, i, j, w, h, d, ncolor, rval, gval, bval;
l_int32          gif_ncolor = 0;
l_uint32        *data, *line;
PIX             *pixd;
PIXCMAP         *cmap;
ColorMapObject  *gif_cmap;
GifByteType     *gif_line;
#if (GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || GIFLIB_MAJOR > 5
int              giferr;
#endif  /* 5.1 and beyond */

    PROCNAME("pixToGif");

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

    d = pixGetDepth(pix);
    if (d == 32) {
        pixd = pixConvertRGBToColormap(pix, 1);
    } else if (d > 1) {
        pixd = pixConvertTo8(pix, TRUE);
    } else {  /* d == 1; make sure there's a colormap */
        pixd = pixClone(pix);
        if (!pixGetColormap(pixd)) {
            cmap = pixcmapCreate(1);
            pixcmapAddColor(cmap, 255, 255, 255);
            pixcmapAddColor(cmap, 0, 0, 0);
            pixSetColormap(pixd, cmap);
        }
    }

    if (!pixd)
        return ERROR_INT("failed to convert image to indexed", procName, 1);
    d = pixGetDepth(pixd);

    if ((cmap = pixGetColormap(pixd)) == NULL) {
        pixDestroy(&pixd);
        return ERROR_INT("cmap is missing", procName, 1);
    }

        /* 'Round' the number of gif colors up to a power of 2 */
    ncolor = pixcmapGetCount(cmap);
    for (i = 0; i <= 8; i++) {
        if ((1 << i) >= ncolor) {
            gif_ncolor = (1 << i);
            break;
        }
    }
    if (gif_ncolor < 1) {
        pixDestroy(&pixd);
        return ERROR_INT("number of colors is invalid", procName, 1);
    }

        /* Save the cmap colors in a gif_cmap */
    if ((gif_cmap = GifMakeMapObject(gif_ncolor, NULL)) == NULL) {
        pixDestroy(&pixd);
        return ERROR_INT("failed to create GIF color map", procName, 1);
    }
    for (i = 0; i < gif_ncolor; i++) {
        rval = gval = bval = 0;
        if (ncolor > 0) {
            if (pixcmapGetColor(cmap, i, &rval, &gval, &bval) != 0) {
                pixDestroy(&pixd);
                GifFreeMapObject(gif_cmap);
                return ERROR_INT("failed to get color from color map",
                                 procName, 1);
            }
            ncolor--;
        }
        gif_cmap->Colors[i].Red = rval;
        gif_cmap->Colors[i].Green = gval;
        gif_cmap->Colors[i].Blue = bval;
    }

    pixGetDimensions(pixd, &w, &h, NULL);
    if (EGifPutScreenDesc(gif, w, h, gif_cmap->BitsPerPixel, 0, gif_cmap)
        != GIF_OK) {
        pixDestroy(&pixd);
        GifFreeMapObject(gif_cmap);
        return ERROR_INT("failed to write screen description", procName, 1);
    }
    GifFreeMapObject(gif_cmap); /* not needed after this point */

    if (EGifPutImageDesc(gif, 0, 0, w, h, FALSE, NULL) != GIF_OK) {
        pixDestroy(&pixd);
        return ERROR_INT("failed to image screen description", procName, 1);
    }

    data = pixGetData(pixd);
    wpl = pixGetWpl(pixd);
    if (d != 1 && d != 2 && d != 4 && d != 8) {
        pixDestroy(&pixd);
        return ERROR_INT("image depth is not in {1, 2, 4, 8}", procName, 1);
    }

    if ((gif_line = (GifByteType *)LEPT_CALLOC(sizeof(GifByteType), w))
        == NULL) {
        pixDestroy(&pixd);
        return ERROR_INT("mem alloc fail for data line", procName, 1);
    }

    for (i = 0; i < h; i++) {
        line = data + i * wpl;
            /* Gif's way of setting the raster line up for compression */
        for (j = 0; j < w; j++) {
            switch(d)
            {
            case 8:
                gif_line[j] = GET_DATA_BYTE(line, j);
                break;
            case 4:
                gif_line[j] = GET_DATA_QBIT(line, j);
                break;
            case 2:
                gif_line[j] = GET_DATA_DIBIT(line, j);
                break;
            case 1:
                gif_line[j] = GET_DATA_BIT(line, j);
                break;
            }
        }

            /* Compress and save the line */
        if (EGifPutLine(gif, gif_line, w) != GIF_OK) {
            LEPT_FREE(gif_line);
            pixDestroy(&pixd);
            return ERROR_INT("failed to write data line into GIF", procName, 1);
        }
    }

        /* Write a text comment.  This must be placed after writing the
         * data (!!)  Note that because libgif does not provide a function
         * for reading comments from file, you will need another way
         * to read comments. */
    if ((text = pixGetText(pix)) != NULL) {
        if (EGifPutComment(gif, text) != GIF_OK)
            L_WARNING("gif comment not written\n", procName);
    }

    LEPT_FREE(gif_line);
    pixDestroy(&pixd);
    return 0;
}
Exemplo n.º 24
0
int main(int    argc,
         char **argv)
{
char         filename[BUF_SIZE];
char        *dirin, *rootname, *fname;
l_int32      i, j, w, h, firstpage, npages, nfiles, ncomp;
l_int32      index, ival, rval, gval, bval;
BOX         *box;
BOXA        *boxa;
BOXAA       *baa;
JBDATA      *data;
JBCLASSER   *classer;
NUMA        *nai;
NUMAA       *naa;
SARRAY      *safiles;
PIX         *pixs, *pixt1, *pixt2, *pixd;
PIXCMAP     *cmap;
static char  mainName[] = "wordsinorder";

    if (argc != 3 && argc != 5)
        return ERROR_INT(
            " Syntax: wordsinorder dirin rootname [firstpage, npages]",
            mainName, 1);

    dirin = argv[1];
    rootname = argv[2];

    if (argc == 3) {
        firstpage = 0;
        npages = 0;
    }
    else {
        firstpage = atoi(argv[3]);
        npages = atoi(argv[4]);
    }

        /* Compute the word bounding boxes at 2x reduction, along with
         * the textlines that they are in. */
    safiles = getSortedPathnamesInDirectory(dirin, NULL, firstpage, npages);
    nfiles = sarrayGetCount(safiles);
    baa = boxaaCreate(nfiles);
    naa = numaaCreate(nfiles);
    for (i = 0; i < nfiles; i++) {
        fname = sarrayGetString(safiles, i, 0);
        if ((pixs = pixRead(fname)) == NULL) {
            L_WARNING("image file %d not read\n", mainName, i);
            continue;
        }
        pixGetWordBoxesInTextlines(pixs, 2, MIN_WORD_WIDTH, MIN_WORD_HEIGHT,
                                   MAX_WORD_WIDTH, MAX_WORD_HEIGHT,
                                   &boxa, &nai);
        boxaaAddBoxa(baa, boxa, L_INSERT);
        numaaAddNuma(naa, nai, L_INSERT);

#if  RENDER_PAGES
            /* Show the results on a 2x reduced image, where each
             * word is outlined and the color of the box depends on the
             * computed textline. */
        pixt1 = pixReduceRankBinary2(pixs, 2, NULL);
        pixGetDimensions(pixt1, &w, &h, NULL);
        pixd = pixCreate(w, h, 8);
        cmap = pixcmapCreateRandom(8, 1, 1);  /* first color is black */
        pixSetColormap(pixd, cmap);

        pixt2 = pixUnpackBinary(pixt1, 8, 1);
        pixRasterop(pixd, 0, 0, w, h, PIX_SRC | PIX_DST, pixt2, 0, 0);
        ncomp = boxaGetCount(boxa);
        for (j = 0; j < ncomp; j++) {
            box = boxaGetBox(boxa, j, L_CLONE);
            numaGetIValue(nai, j, &ival);
            index = 1 + (ival % 254);  /* omit black and white */
            pixcmapGetColor(cmap, index, &rval, &gval, &bval);
            pixRenderBoxArb(pixd, box, 2, rval, gval, bval);
            boxDestroy(&box);
        }

        snprintf(filename, BUF_SIZE, "%s.%05d", rootname, i);
        fprintf(stderr, "filename: %s\n", filename);
        pixWrite(filename, pixd, IFF_PNG);
        pixDestroy(&pixt1);
        pixDestroy(&pixt2);
        pixDestroy(&pixs);
        pixDestroy(&pixd);
#endif  /* RENDER_PAGES */
    }

    boxaaDestroy(&baa);
    numaaDestroy(&naa);
    sarrayDestroy(&safiles);
    return 0;
}
Exemplo n.º 25
0
int main(int argc,
         char **argv) {
    l_int32 w, h, wd, hd;
    l_float32 deg2rad, angle, conf;
    PIX *pixs, *pixb1, *pixb2, *pixr, *pixf, *pixd, *pixc;
    PIXA *pixa;
    L_REGPARAMS *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    deg2rad = 3.1415926535 / 180.;

    pixa = pixaCreate(0);
    pixs = pixRead("feyn.tif");
    pixSetOrClearBorder(pixs, 100, 250, 100, 0, PIX_CLR);
    pixb1 = pixReduceRankBinaryCascade(pixs, 2, 2, 0, 0);
    regTestWritePixAndCheck(rp, pixb1, IFF_PNG);  /* 0 */
    pixDisplayWithTitle(pixb1, 0, 100, NULL, rp->display);

    /* Add a border and locate and deskew a 40 degree rotation */
    pixb2 = pixAddBorder(pixb1, BORDER, 0);
    pixGetDimensions(pixb2, &w, &h, NULL);
    pixSaveTiled(pixb2, pixa, 0.5, 1, 20, 8);
    pixr = pixRotateBySampling(pixb2, w / 2, h / 2,
                               deg2rad * 40., L_BRING_IN_WHITE);
    regTestWritePixAndCheck(rp, pixr, IFF_PNG);  /* 1 */
    pixSaveTiled(pixr, pixa, 0.5, 0, 20, 0);
    pixFindSkewSweepAndSearchScorePivot(pixr, &angle, &conf, NULL, 1, 1,
                                        0.0, 45.0, 2.0, 0.03,
                                        L_SHEAR_ABOUT_CENTER);
    fprintf(stderr, "Should be 40 degrees: angle = %7.3f, conf = %7.3f\n",
            angle, conf);
    pixf = pixRotateBySampling(pixr, w / 2, h / 2,
                               deg2rad * angle, L_BRING_IN_WHITE);
    pixd = pixRemoveBorder(pixf, BORDER);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 2 */
    pixSaveTiled(pixd, pixa, 0.5, 0, 20, 0);
    pixDestroy(&pixr);
    pixDestroy(&pixf);
    pixDestroy(&pixd);

    /* Do a rotation larger than 90 degrees using embedding;
     * Use 2 sets of measurements at 90 degrees to scan the
     * full range of possible rotation angles. */
    pixGetDimensions(pixb1, &w, &h, NULL);
    pixr = pixRotate(pixb1, deg2rad * 37., L_ROTATE_SAMPLING,
                     L_BRING_IN_WHITE, w, h);
    regTestWritePixAndCheck(rp, pixr, IFF_PNG);  /* 3 */
    pixSaveTiled(pixr, pixa, 0.5, 1, 20, 0);
    startTimer();
    pixFindSkewOrthogonalRange(pixr, &angle, &conf, 2, 1,
                               47.0, 1.0, 0.03, 0.0);
    fprintf(stderr, "Orth search time: %7.3f sec\n", stopTimer());
    fprintf(stderr, "Should be about -128 degrees: angle = %7.3f\n", angle);
    pixd = pixRotate(pixr, deg2rad * angle, L_ROTATE_SAMPLING,
                     L_BRING_IN_WHITE, w, h);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 4 */
    pixGetDimensions(pixd, &wd, &hd, NULL);
    pixc = pixCreate(w, h, 1);
    pixRasterop(pixc, 0, 0, w, h, PIX_SRC, pixd, (wd - w) / 2, (hd - h) / 2);
    regTestWritePixAndCheck(rp, pixc, IFF_PNG);  /* 5 */
    pixSaveTiled(pixc, pixa, 0.5, 0, 20, 0);
    pixDestroy(&pixr);
    pixDestroy(&pixf);
    pixDestroy(&pixd);
    pixDestroy(&pixc);

    pixd = pixaDisplay(pixa, 0, 0);
    regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 6 */
    pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
    pixDestroy(&pixd);

    pixDestroy(&pixs);
    pixDestroy(&pixb1);
    pixDestroy(&pixb2);
    pixaDestroy(&pixa);
    return regTestCleanup(rp);
}
Exemplo n.º 26
0
int main(int    argc,
         char **argv)
{
char          dilateseq[512], erodeseq[512];
char          openseq[512], closeseq[512];
char          wtophatseq[512], btophatseq[512];
l_int32       w, h;
PIX          *pixs, *pix1, *pix2, *pix3, *pix4, *pix5;
PIXA         *pixa;
PIXACC       *pacc;
PIXCMAP      *cmap;
L_REGPARAMS  *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    pixs = pixRead("aneurisms8.jpg");
    pixa = pixaCreate(0);

    /* =========================================================== */

    /* -------- Test gray morph, including interpreter ------------ */
    pix1 = pixDilateGray(pixs, WSIZE, HSIZE);
    sprintf(dilateseq, "D%d.%d", WSIZE, HSIZE);
    pix2 = pixGrayMorphSequence(pixs, dilateseq, 0, 0);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 0 */
    regTestComparePix(rp, pix1, pix2);  /* 1 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);

    pix1 = pixErodeGray(pixs, WSIZE, HSIZE);
    sprintf(erodeseq, "E%d.%d", WSIZE, HSIZE);
    pix2 = pixGrayMorphSequence(pixs, erodeseq, 0, 100);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 2 */
    regTestComparePix(rp, pix1, pix2);  /* 3 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);

    pix1 = pixOpenGray(pixs, WSIZE, HSIZE);
    sprintf(openseq, "O%d.%d", WSIZE, HSIZE);
    pix2 = pixGrayMorphSequence(pixs, openseq, 0, 200);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 4 */
    regTestComparePix(rp, pix1, pix2);  /* 5 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);

    pix1 = pixCloseGray(pixs, WSIZE, HSIZE);
    sprintf(closeseq, "C%d.%d", WSIZE, HSIZE);
    pix2 = pixGrayMorphSequence(pixs, closeseq, 0, 300);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 6 */
    regTestComparePix(rp, pix1, pix2);  /* 7 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);

    pix1 = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_WHITE);
    sprintf(wtophatseq, "Tw%d.%d", WSIZE, HSIZE);
    pix2 = pixGrayMorphSequence(pixs, wtophatseq, 0, 400);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 8 */
    regTestComparePix(rp, pix1, pix2);  /* 9 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);

    pix1 = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_BLACK);
    sprintf(btophatseq, "Tb%d.%d", WSIZE, HSIZE);
    pix2 = pixGrayMorphSequence(pixs, btophatseq, 0, 500);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 10 */
    regTestComparePix(rp, pix1, pix2);  /* 11 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);

    /* ------------- Test erode/dilate duality -------------- */
    pix1 = pixDilateGray(pixs, WSIZE, HSIZE);
    pix2 = pixInvert(NULL, pixs);
    pix3 = pixErodeGray(pix2, WSIZE, HSIZE);
    pixInvert(pix3, pix3);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 12 */
    regTestComparePix(rp, pix1, pix3);  /* 13 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

    /* ------------- Test open/close duality -------------- */
    pix1 = pixOpenGray(pixs, WSIZE, HSIZE);
    pix2 = pixInvert(NULL, pixs);
    pix3 = pixCloseGray(pix2, WSIZE, HSIZE);
    pixInvert(pix3, pix3);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 14 */
    regTestComparePix(rp, pix1, pix3);  /* 15 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

    /* ------------- Test tophat duality -------------- */
    pix1 = pixTophat(pixs, WSIZE, HSIZE, L_TOPHAT_WHITE);
    pix2 = pixInvert(NULL, pixs);
    pix3 = pixTophat(pix2, WSIZE, HSIZE, L_TOPHAT_BLACK);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 16 */
    regTestComparePix(rp, pix1, pix3);  /* 17 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

    pix1 = pixGrayMorphSequence(pixs, "Tw9.5", 0, 100);
    pix2 = pixInvert(NULL, pixs);
    pix3 = pixGrayMorphSequence(pix2, "Tb9.5", 0, 300);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 18 */
    regTestComparePix(rp, pix1, pix3);  /* 19 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);
    pixDestroy(&pix3);


    /* ------------- Test opening/closing for large sels -------------- */
    pix1 = pixGrayMorphSequence(pixs,
            "C9.9 + C19.19 + C29.29 + C39.39 + C49.49", 0, 100);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 20 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pix1 = pixGrayMorphSequence(pixs,
            "O9.9 + O19.19 + O29.29 + O39.39 + O49.49", 0, 400);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 21 */
    pixaAddPix(pixa, pix1, L_INSERT);

    pix1 = pixaDisplayTiledInColumns(pixa, 4, 1.0, 20, 2);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 22 */
    pixDisplayWithTitle(pix1, 0, 0, NULL, rp->display);
    pixaDestroy(&pixa);
    pixDestroy(&pix1);

    /* =========================================================== */

    pixa = pixaCreate(0);
    /* ---------- Closing plus white tophat result ------------ *
     *            Parameters: wsize, hsize = 9, 29             *
     * ---------------------------------------------------------*/
    pix1 = pixCloseGray(pixs, 9, 9);
    pix2 = pixTophat(pix1, 9, 9, L_TOPHAT_WHITE);
    pix3 = pixGrayMorphSequence(pixs, "C9.9 + TW9.9", 0, 0);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 23 */
    regTestComparePix(rp, pix2, pix3);  /* 24 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pix1 = pixMaxDynamicRange(pix2, L_LINEAR_SCALE);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 25 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

    pix1 = pixCloseGray(pixs, 29, 29);
    pix2 = pixTophat(pix1, 29, 29, L_TOPHAT_WHITE);
    pix3 = pixGrayMorphSequence(pixs, "C29.29 + Tw29.29", 0, 0);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 26 */
    regTestComparePix(rp, pix2, pix3);  /* 27 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pix1 = pixMaxDynamicRange(pix2, L_LINEAR_SCALE);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 28 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

    /* --------- hdome with parameter height = 100 ------------*/
    pix1 = pixHDome(pixs, 100, 4);
    pix2 = pixMaxDynamicRange(pix1, L_LINEAR_SCALE);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 29 */
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 30 */
    pixaAddPix(pixa, pix1, L_INSERT);
    pixaAddPix(pixa, pix2, L_INSERT);

    /* ----- Contrast enhancement with morph parameters 9, 9 -------*/
    pixGetDimensions(pixs, &w, &h, NULL);
    pix1 = pixInitAccumulate(w, h, 0x8000);
    pixAccumulate(pix1, pixs, L_ARITH_ADD);
    pixMultConstAccumulate(pix1, 3., 0x8000);
    pix2 = pixOpenGray(pixs, 9, 9);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 31 */
    pixaAddPix(pixa, pix2, L_INSERT);
    pixAccumulate(pix1, pix2, L_ARITH_SUBTRACT);

    pix2 = pixCloseGray(pixs, 9, 9);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 32 */
    pixaAddPix(pixa, pix2, L_INSERT);
    pixAccumulate(pix1, pix2, L_ARITH_SUBTRACT);
    pix2 = pixFinalAccumulate(pix1, 0x8000, 8);
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 33 */
    pixaAddPix(pixa, pix2, L_INSERT);
    pixDestroy(&pix1);

        /* Do the same thing with the Pixacc */
    pacc = pixaccCreate(w, h, 1);
    pixaccAdd(pacc, pixs);
    pixaccMultConst(pacc, 3.);
    pix1 = pixOpenGray(pixs, 9, 9);
    pixaccSubtract(pacc, pix1);
    pixDestroy(&pix1);
    pix1 = pixCloseGray(pixs, 9, 9);
    pixaccSubtract(pacc, pix1);
    pixDestroy(&pix1);
    pix1 = pixaccFinal(pacc, 8);
    pixaccDestroy(&pacc);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 34 */
    pixaAddPix(pixa, pix1, L_INSERT);
    regTestComparePix(rp, pix1, pix2);  /* 35 */

    pix1 = pixaDisplayTiledInColumns(pixa, 4, 1.0, 20, 2);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 36 */
    pixDisplayWithTitle(pix1, 1100, 0, NULL, rp->display);
    pixaDestroy(&pixa);
    pixDestroy(&pix1);
    pixDestroy(&pixs);

    /* =========================================================== */

    pixa = pixaCreate(0);

    /* ----  Tophat result on feynman stamp, to extract diagrams ----- */
    pixs = pixRead("feynman-stamp.jpg");
    pixGetDimensions(pixs, &w, &h, NULL);

        /* Make output image to hold five intermediate images */
    pix1 = pixCreate(5 * w + 18, h + 6, 32);  /* composite output image */
    pixSetAllArbitrary(pix1, 0x0000ff00);  /* set to blue */

        /* Paste in the input image */
    pix2 = pixRemoveColormap(pixs, REMOVE_CMAP_TO_FULL_COLOR);
    pixRasterop(pix1, 3, 3, w, h, PIX_SRC, pix2, 0, 0);  /* 1st one */
    regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 37 */
    pixaAddPix(pixa, pix2, L_INSERT);

        /* Paste in the grayscale version */
    cmap = pixGetColormap(pixs);
    if (cmap)
        pix2 = pixRemoveColormap(pixs, REMOVE_CMAP_TO_GRAYSCALE);
    else
        pix2 = pixConvertRGBToGray(pixs, 0.33, 0.34, 0.33);
    pix3 = pixConvertTo32(pix2);  /* 8 --> 32 bpp */
    pixRasterop(pix1, w + 6, 3, w, h, PIX_SRC, pix3, 0, 0);  /* 2nd one */
    regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 38 */
    pixaAddPix(pixa, pix3, L_INSERT);

         /* Paste in a log dynamic range scaled version of the white tophat */
    pix3 = pixTophat(pix2, 3, 3, L_TOPHAT_WHITE);
    pix4 = pixMaxDynamicRange(pix3, L_LOG_SCALE);
    pix5 = pixConvertTo32(pix4);
    pixRasterop(pix1, 2 * w + 9, 3, w, h, PIX_SRC, pix5, 0, 0);  /* 3rd */
    regTestWritePixAndCheck(rp, pix5, IFF_PNG);  /* 39 */
    pixaAddPix(pixa, pix5, L_INSERT);
    pixDestroy(&pix2);
    pixDestroy(&pix4);

        /* Stretch the range and threshold to binary; paste it in */
    pix2 = pixGammaTRC(NULL, pix3, 1.0, 0, 80);
    pix4 = pixThresholdToBinary(pix2, 70);
    pix5 = pixConvertTo32(pix4);
    pixRasterop(pix1, 3 * w + 12, 3, w, h, PIX_SRC, pix5, 0, 0);  /* 4th */
    regTestWritePixAndCheck(rp, pix5, IFF_PNG);  /* 40 */
    pixaAddPix(pixa, pix5, L_INSERT);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Invert; this is the final result */
    pixInvert(pix4, pix4);
    pix5 = pixConvertTo32(pix4);
    pixRasterop(pix1, 4 * w + 15, 3, w, h, PIX_SRC, pix5, 0, 0);  /* 5th */
    regTestWritePixAndCheck(rp, pix5, IFF_PNG);  /* 41 */
    pixaAddPix(pixa, pix5, L_INSERT);
    pixDestroy(&pix1);
    pixDestroy(&pix4);

    pix1 = pixaDisplayTiledInRows(pixa, 32, 1700, 1.0, 0, 20, 2);
    regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 42 */
    pixDisplayWithTitle(pix1, 0, 800, NULL, rp->display);
    pixaDestroy(&pixa);
    pixDestroy(&pix1);
    pixDestroy(&pixs);

    return regTestCleanup(rp);
}
Exemplo n.º 27
0
int main(int argc,
         char **argv) {
    char *infile;
    l_int32 w, d, threshval, ival, newval;
    l_uint32 val;
    PIX *pixs, *pixg, *pixg2;
    PIX *pix1, *pix2;
    PIXA *pixa;
    static char mainName[] = "binarize_set";

    if (argc != 2)
        return ERROR_INT(" Syntax: binarize_set infile", mainName, 1);
    infile = argv[1];

    pixa = pixaCreate(5);
    pixs = pixRead(infile);
    pixGetDimensions(pixs, &w, NULL, &d);
    pixSaveTiled(pixs, pixa, 1.0, 1, 50, 32);
    pixDisplay(pixs, 100, 0);

#if ALL
    /* 1. Standard background normalization with a global threshold.  */
    pixg = pixConvertTo8(pixs, 0);
    pix1 = pixBackgroundNorm(pixg, NULL, NULL, 10, 15, 100, 50, 255, 2, 2);
    pix2 = pixThresholdToBinary(pix1, 160);
    pixWrite("/tmp/binar1.png", pix2, IFF_PNG);
    pixDisplay(pix2, 100, 0);
    pixSaveTiled(pix2, pixa, 1.0, 1, 50, 32);
    pixDestroy(&pixg);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
#endif

#if ALL
    /* 2. Background normalization followed by Otsu thresholding.  Otsu
     * binarization attempts to split the image into two roughly equal
     * sets of pixels, and it does a very poor job when there are large
     * amounts of dark background.  By doing a background normalization
     * first (to get the background near 255), we remove this problem.
     * Then we use a modified Otsu to estimate the best global
     * threshold on the normalized image.  */
    pixg = pixConvertTo8(pixs, 0);
    pix1 = pixOtsuThreshOnBackgroundNorm(pixg, NULL, 10, 15, 100,
                                         50, 255, 2, 2, 0.10, &threshval);
    fprintf(stderr, "thresh val = %d\n", threshval);
    pixSaveTiled(pix1, pixa, 1.0, 1, 50, 32);
    pixWrite("/tmp/binar2.png", pix1, IFF_PNG);
    pixDisplay(pix1, 100, 200);
    pixDestroy(&pixg);
    pixDestroy(&pix1);
#endif

#if ALL
    /* 3. Background normalization with Otsu threshold estimation and
     * masking for threshold selection.  */
    pixg = pixConvertTo8(pixs, 0);
    pix1 = pixMaskedThreshOnBackgroundNorm(pixg, NULL, 10, 15, 100,
                                           50, 2, 2, 0.10, &threshval);
    fprintf(stderr, "thresh val = %d\n", threshval);
    pixSaveTiled(pix1, pixa, 1.0, 1, 50, 32);
    pixWrite("/tmp/binar3.png", pix1, IFF_PNG);
    pixDisplay(pix1, 100, 400);
    pixDestroy(&pixg);
    pixDestroy(&pix1);
#endif

#if ALL
    /* 4. Background normalization followed by Sauvola binarization */
    if (d == 32)
        pixg = pixConvertRGBToGray(pixs, 0.2, 0.7, 0.1);
    else
        pixg = pixConvertTo8(pixs, 0);
    pixg2 = pixContrastNorm(NULL, pixg, 20, 20, 130, 2, 2);
    pixSauvolaBinarizeTiled(pixg2, 25, 0.40, 1, 1, NULL, &pix1);
    pixSaveTiled(pix1, pixa, 1.0, 1, 50, 32);
    pixWrite("/tmp/binar4.png", pix1, IFF_PNG);
    pixDisplay(pix1, 100, 600);
    pixDestroy(&pixg);
    pixDestroy(&pixg2);
    pixDestroy(&pix1);
#endif

#if ALL
    /* 5. Contrast normalization followed by background normalization, and
     * thresholding. */
    if (d == 32)
        pixg = pixConvertRGBToGray(pixs, 0.2, 0.7, 0.1);
    else
        pixg = pixConvertTo8(pixs, 0);

    pixOtsuAdaptiveThreshold(pixg, 5000, 5000, 0, 0, 0.1, &pix1, NULL);
    pixGetPixel(pix1, 0, 0, &val);
    ival = (l_int32) val;
    newval = ival + (l_int32)(0.6 * (110 - ival));
    fprintf(stderr, "th1 = %d, th2 = %d\n", ival, newval);
    pixDestroy(&pix1);

    pixContrastNorm(pixg, pixg, 50, 50, 130, 2, 2);
    pixg2 = pixBackgroundNorm(pixg, NULL, NULL, 20, 20, 70, 40, 200, 2, 2);

    ival = L_MIN(ival, 110);
    pix1 = pixThresholdToBinary(pixg2, ival);
    pixSaveTiled(pix1, pixa, 1.0, 1, 50, 32);
    pixWrite("/tmp/binar5.png", pix1, IFF_PNG);
    pixDisplay(pix1, 100, 800);
    pixDestroy(&pixg);
    pixDestroy(&pixg2);
    pixDestroy(&pix1);
#endif

    pix1 = pixaDisplayTiledInRows(pixa, 32, w + 100, 1.0, 0, 30, 2);
    pixWrite("/tmp/binar6.png", pix1, IFF_PNG);
    pixDisplay(pix1, 1000, 0);
    pixDestroy(&pix1);
    pixaDestroy(&pixa);

    pixDestroy(&pixs);
    return 0;
}
Exemplo n.º 28
0
/*!
 *  pixVarianceInRectangle()
 *
 *      Input:  pix (8 bpp)
 *              box (region to compute variance and/or root variance)
 *              pix_ma (mean accumulator)
 *              dpix_msa (mean square accumulator)
 *              &var (<optional return> variance)
 *              &rvar (<optional return> root variance)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This function is intended to be used for many rectangles
 *          on the same image.  It can find the variance and/or the
 *          square root of the variance within a rectangle in O(1),
 *          independent of the size of the rectangle.
 */
l_int32
pixVarianceInRectangle(PIX *pixs,
                       BOX *box,
                       PIX *pix_ma,
                       DPIX *dpix_msa,
                       l_float32 *pvar,
                       l_float32 *prvar) {
    l_int32 w, h, bx, by, bw, bh;
    l_uint32 val00, val01, val10, val11;
    l_float64 dval00, dval01, dval10, dval11, mval, msval, var, norm;
    BOX *boxc;

    PROCNAME("pixVarianceInRectangle");

    if (!pvar && !prvar)
        return ERROR_INT("neither &var nor &rvar defined", procName, 1);
    if (pvar) *pvar = 0.0;
    if (prvar) *prvar = 0.0;
    if (!pixs || pixGetDepth(pixs) != 8)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!box)
        return ERROR_INT("box not defined", procName, 1);
    if (!pix_ma)
        return ERROR_INT("pix_ma not defined", procName, 1);
    if (!dpix_msa)
        return ERROR_INT("dpix_msa not defined", procName, 1);

    /* Clip rectangle to image */
    pixGetDimensions(pixs, &w, &h, NULL);
    boxc = boxClipToRectangle(box, w, h);
    boxGetGeometry(boxc, &bx, &by, &bw, &bh);
    boxDestroy(&boxc);

    if (bw == 0 || bh == 0)
        return ERROR_INT("no pixels in box", procName, 1);

    /* Use up to 4 points in the accumulators */
    norm = 1.0 / (bw * bh);
    if (bx > 0 && by > 0) {
        pixGetPixel(pix_ma, bx + bw - 1, by + bh - 1, &val11);
        pixGetPixel(pix_ma, bx + bw - 1, by - 1, &val10);
        pixGetPixel(pix_ma, bx - 1, by + bh - 1, &val01);
        pixGetPixel(pix_ma, bx - 1, by - 1, &val00);
        dpixGetPixel(dpix_msa, bx + bw - 1, by + bh - 1, &dval11);
        dpixGetPixel(dpix_msa, bx + bw - 1, by - 1, &dval10);
        dpixGetPixel(dpix_msa, bx - 1, by + bh - 1, &dval01);
        dpixGetPixel(dpix_msa, bx - 1, by - 1, &dval00);
        mval = norm * (val11 - val01 + val00 - val10);
        msval = norm * (dval11 - dval01 + dval00 - dval10);
        var = (msval - mval * mval);
        if (pvar) *pvar = (l_float32) var;
        if (prvar) *prvar = (l_float32)(sqrt(var));
    } else if (by > 0) {  /* bx == 0 */
        pixGetPixel(pix_ma, bw - 1, by + bh - 1, &val11);
        pixGetPixel(pix_ma, bw - 1, by - 1, &val10);
        dpixGetPixel(dpix_msa, bw - 1, by + bh - 1, &dval11);
        dpixGetPixel(dpix_msa, bw - 1, by - 1, &dval10);
        mval = norm * (val11 - val10);
        msval = norm * (dval11 - dval10);
        var = (msval - mval * mval);
        if (pvar) *pvar = (l_float32) var;
        if (prvar) *prvar = (l_float32)(sqrt(var));
    } else if (bx > 0) {  /* by == 0 */
        pixGetPixel(pix_ma, bx + bw - 1, bh - 1, &val11);
        pixGetPixel(pix_ma, bx - 1, bh - 1, &val01);
        dpixGetPixel(dpix_msa, bx + bw - 1, bh - 1, &dval11);
        dpixGetPixel(dpix_msa, bx - 1, bh - 1, &dval01);
        mval = norm * (val11 - val01);
        msval = norm * (dval11 - dval01);
        var = (msval - mval * mval);
        if (pvar) *pvar = (l_float32) var;
        if (prvar) *prvar = (l_float32)(sqrt(var));
    } else {  /* bx == 0 && by == 0 */
        pixGetPixel(pix_ma, bw - 1, bh - 1, &val11);
        dpixGetPixel(dpix_msa, bw - 1, bh - 1, &dval11);
        mval = norm * val11;
        msval = norm * dval11;
        var = (msval - mval * mval);
        if (pvar) *pvar = (l_float32) var;
        if (prvar) *prvar = (l_float32)(sqrt(var));
    }

    return 0;
}
Exemplo n.º 29
0
/*!
 *  pixWriteMemWebP()
 *
 *      Input:  &encdata (<return> webp encoded data of pixs)
 *              &encsize (<return> size of webp encoded data)
 *              pixs (any depth, cmapped OK)
 *              quality (0 - 100; default ~80)
 *              lossless (use 1 for lossless; 0 for lossy)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) Lossless and lossy encoding are entirely different in webp.
 *          @quality applies to lossy, and is ignored for lossless.
 *      (2) The input image is converted to RGB if necessary.  If spp == 3,
 *          we set the alpha channel to fully opaque (255), and
 *          WebPEncodeRGBA() then removes the alpha chunk when encoding,
 *          setting the internal header field has_alpha to 0.
 */
l_int32
pixWriteMemWebP(l_uint8  **pencdata,
                size_t    *pencsize,
                PIX       *pixs,
                l_int32    quality,
                l_int32    lossless)
{
l_int32    w, h, d, wpl, stride;
l_uint32  *data;
PIX       *pix1, *pix2;

    PROCNAME("pixWriteMemWebP");

    if (!pencdata)
        return ERROR_INT("&encdata not defined", procName, 1);
    *pencdata = NULL;
    if (!pencsize)
        return ERROR_INT("&encsize not defined", procName, 1);
    *pencsize = 0;
    if (!pixs)
        return ERROR_INT("&pixs not defined", procName, 1);
    if (lossless == 0 && (quality < 0 || quality > 100))
        return ERROR_INT("quality not in [0 ... 100]", procName, 1);

    if ((pix1 = pixRemoveColormap(pixs, REMOVE_CMAP_TO_FULL_COLOR)) == NULL)
        return ERROR_INT("failure to remove color map", procName, 1);

        /* Convert to rgb if not 32 bpp; pix2 must not be a clone of pixs. */
    if (pixGetDepth(pix1) != 32)
        pix2 = pixConvertTo32(pix1);
    else
        pix2 = pixCopy(NULL, pix1);
    pixDestroy(&pix1);
    pixGetDimensions(pix2, &w, &h, &d);
    if (w <= 0 || h <= 0 || d != 32) {
        pixDestroy(&pix2);
        return ERROR_INT("pix2 not 32 bpp or of 0 size", procName, 1);
    }

        /* If spp == 3, need to set alpha layer to opaque (all 1s). */
    if (pixGetSpp(pix2) == 3)
        pixSetComponentArbitrary(pix2, L_ALPHA_CHANNEL, 255);

        /* Webp encoder assumes big-endian byte order for RGBA components */
    pixEndianByteSwap(pix2);
    wpl = pixGetWpl(pix2);
    data = pixGetData(pix2);
    stride = wpl * 4;
    if (lossless) {
        *pencsize = WebPEncodeLosslessRGBA((uint8_t *)data, w, h,
                                           stride, pencdata);
    } else {
        *pencsize = WebPEncodeRGBA((uint8_t *)data, w, h, stride,
                                   quality, pencdata);
    }
    pixDestroy(&pix2);

    if (*pencsize == 0) {
        free(pencdata);
        *pencdata = NULL;
        return ERROR_INT("webp encoding failed", procName, 1);
    }

    return 0;
}
Exemplo n.º 30
0
int main(int    argc,
         char **argv)
{
l_int32       i, j, k, w, h, w2, w4, w8, w16, w32, wpl;
l_int32       count1, count2, count3;
l_uint32      val32, val1, val2;
l_uint32     *data1, *line1, *data2, *line2;
void        **lines1, **linet1, **linet2;
PIX          *pixs, *pix1, *pix2;
L_REGPARAMS  *rp;

    if (regTestSetup(argc, argv, &rp))
        return 1;

    pixs = pixRead("feyn-fract.tif");
    pixGetDimensions(pixs, &w, &h, NULL);
    data1 = pixGetData(pixs);
    wpl = pixGetWpl(pixs);
    lines1 = pixGetLinePtrs(pixs, NULL);

        /* Get timing for the 3 different methods */
    startTimer();
    for (k = 0; k < 10; k++) {
        count1 = 0;
        for (i = 0; i < h; i++) {
            for (j = 0; j < w; j++) {
                if (GET_DATA_BIT(lines1[i], j))
                    count1++;
            }
        }
    }
    fprintf(stderr, "Time with line ptrs     = %5.3f sec, count1 = %d\n",
            stopTimer(), count1);

    startTimer();
    for (k = 0; k < 10; k++) {
        count2 = 0;
        for (i = 0; i < h; i++) {
            line1 = data1 + i * wpl;
            for (j = 0; j < w; j++) {
               if (l_getDataBit(line1, j))
                    count2++;
            }
        }
    }
    fprintf(stderr, "Time with l_get*        = %5.3f sec, count2 = %d\n",
            stopTimer(), count2);

    startTimer();
    for (k = 0; k < 10; k++) {
        count3 = 0;
        for (i = 0; i < h; i++) {
            for (j = 0; j < w; j++) {
                pixGetPixel(pixs, j, i, &val32);
                count3 += val32;
            }
        }
    }
    fprintf(stderr, "Time with pixGetPixel() = %5.3f sec, count3 = %d\n",
            stopTimer(), count3);

    pix1 = pixCreateTemplate(pixs);
    linet1 = pixGetLinePtrs(pix1, NULL);
    pix2 = pixCreateTemplate(pixs);
    data2 = pixGetData(pix2);
    linet2 = pixGetLinePtrs(pix2, NULL);

        /* ------------------------------------------------- */
        /*           Test different methods for 1 bpp        */
        /* ------------------------------------------------- */
    count1 = 0;
    for (i = 0; i < h; i++) {
        for (j = 0; j < w; j++) {
            val1 = GET_DATA_BIT(lines1[i], j);
            count1 += val1;
            if (val1) SET_DATA_BIT(linet1[i], j);
        }
    }
    count2 = 0;
    for (i = 0; i < h; i++) {
        line1 = data1 + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w; j++) {
            val2 = l_getDataBit(line1, j);
            count2 += val2;
            if (val2) l_setDataBit(line2, j);
        }
    }
    CompareResults(pixs, pix1, pix2, count1, count2, "1 bpp", rp);

        /* ------------------------------------------------- */
        /*           Test different methods for 2 bpp        */
        /* ------------------------------------------------- */
    count1 = 0;
    w2 = w / 2;
    for (i = 0; i < h; i++) {
        for (j = 0; j < w2; j++) {
            val1 = GET_DATA_DIBIT(lines1[i], j);
            count1 += val1;
            val1 += 0xbbbbbbbc;
            SET_DATA_DIBIT(linet1[i], j, val1);
        }
    }
    count2 = 0;
    for (i = 0; i < h; i++) {
        line1 = data1 + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w2; j++) {
            val2 = l_getDataDibit(line1, j);
            count2 += val2;
            val2 += 0xbbbbbbbc;
            l_setDataDibit(line2, j, val2);
        }
    }
    CompareResults(pixs, pix1, pix2, count1, count2, "2 bpp", rp);

        /* ------------------------------------------------- */
        /*           Test different methods for 4 bpp        */
        /* ------------------------------------------------- */
    count1 = 0;
    w4 = w / 4;
    for (i = 0; i < h; i++) {
        for (j = 0; j < w4; j++) {
            val1 = GET_DATA_QBIT(lines1[i], j);
            count1 += val1;
            val1 += 0xbbbbbbb0;
            SET_DATA_QBIT(linet1[i], j, val1);
        }
    }
    count2 = 0;
    for (i = 0; i < h; i++) {
        line1 = data1 + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w4; j++) {
            val2 = l_getDataQbit(line1, j);
            count2 += val2;
            val2 += 0xbbbbbbb0;
            l_setDataQbit(line2, j, val2);
        }
    }
    CompareResults(pixs, pix1, pix2, count1, count2, "4 bpp", rp);

        /* ------------------------------------------------- */
        /*           Test different methods for 8 bpp        */
        /* ------------------------------------------------- */
    count1 = 0;
    w8 = w / 8;
    for (i = 0; i < h; i++) {
        for (j = 0; j < w8; j++) {
            val1 = GET_DATA_BYTE(lines1[i], j);
            count1 += val1;
            val1 += 0xbbbbbb00;
            SET_DATA_BYTE(linet1[i], j, val1);
        }
    }
    count2 = 0;
    for (i = 0; i < h; i++) {
        line1 = data1 + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w8; j++) {
            val2 = l_getDataByte(line1, j);
            count2 += val2;
            val2 += 0xbbbbbb00;
            l_setDataByte(line2, j, val2);
        }
    }
    CompareResults(pixs, pix1, pix2, count1, count2, "8 bpp", rp);

        /* ------------------------------------------------- */
        /*          Test different methods for 16 bpp        */
        /* ------------------------------------------------- */
    count1 = 0;
    w16 = w / 16;
    for (i = 0; i < h; i++) {
        for (j = 0; j < w16; j++) {
            val1 = GET_DATA_TWO_BYTES(lines1[i], j);
            count1 += val1;
            val1 += 0xbbbb0000;
            SET_DATA_TWO_BYTES(linet1[i], j, val1);
        }
    }
    count2 = 0;
    for (i = 0; i < h; i++) {
        line1 = data1 + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w16; j++) {
            val2 = l_getDataTwoBytes(line1, j);
            count2 += val2;
            val2 += 0xbbbb0000;
            l_setDataTwoBytes(line2, j, val2);
        }
    }
    CompareResults(pixs, pix1, pix2, count1, count2, "16 bpp", rp);

        /* ------------------------------------------------- */
        /*          Test different methods for 32 bpp        */
        /* ------------------------------------------------- */
    count1 = 0;
    w32 = w / 32;
    for (i = 0; i < h; i++) {
        for (j = 0; j < w32; j++) {
            val1 = GET_DATA_FOUR_BYTES(lines1[i], j);
            count1 += val1 & 0xfff;
            SET_DATA_FOUR_BYTES(linet1[i], j, val1);
        }
    }
    count2 = 0;
    for (i = 0; i < h; i++) {
        line1 = data1 + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w32; j++) {
            val2 = l_getDataFourBytes(line1, j);
            count2 += val2 & 0xfff;
            l_setDataFourBytes(line2, j, val2);
        }
    }
    CompareResults(pixs, pix1, pix2, count1, count2, "32 bpp", rp);
    pixDestroy(&pixs);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    lept_free(lines1);
    lept_free(linet1);
    lept_free(linet2);
    return regTestCleanup(rp);
}