/*!
 *  fpixScaleByInteger()
 *
 *      Input:  fpixs (low resolution, subsampled)
 *              factor (scaling factor)
 *      Return: fpixd (interpolated result), or null on error
 *
 *  Notes:
 *      (1) The width wd of fpixd is related to ws of fpixs by:
 *              wd = factor * (ws - 1)   (and ditto for the height)
 *          We avoid special-casing boundary pixels by constructing
 *          fpixd by inserting (factor - 1) interpolated pixels between
 *          each pixel in fpixs, but not including the rightmost
 *          column or bottommost row of pixels in fpixs.
 *          (Those pixels could be included, which would make fpixd
 *          larger in width and height by 1.)
 */
FPIX *
fpixScaleByInteger(FPIX    *fpixs,
                   l_int32  factor)
{
l_int32     i, j, k, m, ws, hs, wd, hd, wpls, wpld;
l_float32   val0, val1, val2, val3;
l_float32  *datas, *datad, *lines, *lined, *fract;
FPIX       *fpixd;

    PROCNAME("fpixScaleByInteger");

    if (!fpixs)
        return (FPIX *)ERROR_PTR("fpixs not defined", procName, NULL);

    fpixGetDimensions(fpixs, &ws, &hs);
    wd = factor * (ws - 1);
    hd = factor * (hs - 1);
    fpixd = fpixCreate(wd, hd);
    datas = fpixGetData(fpixs);
    datad = fpixGetData(fpixd);
    wpls = fpixGetWpl(fpixs);
    wpld = fpixGetWpl(fpixd);
    fract = (l_float32 *)CALLOC(factor, sizeof(l_float32));
    for (i = 0; i < factor; i++)
        fract[i] = i / (l_float32)factor;
    for (i = 0; i < hs - 1; i++) {
        lines = datas + i * wpls;
        for (j = 0; j < ws - 1; j++) {
            val0 = lines[j];
            val1 = lines[j + 1];
            val2 = lines[wpls + j];
            val3 = lines[wpls + j + 1];
            for (k = 0; k < factor; k++) {  /* rows of sub-block */
                lined = datad + (i * factor + k) * wpld;
                for (m = 0; m < factor; m++) {  /* cols of sub-block */
                     *(lined + j * factor + m) =
                            val0 * (1.0 - fract[m]) * (1.0 - fract[k]) +
                            val1 * fract[m] * (1.0 - fract[k]) +
                            val2 * (1.0 - fract[m]) * fract[k] +
                            val3 * fract[m] * fract[k];
                }
            }
        }
    }

    FREE(fract);
    return fpixd;
}
Exemple #2
0
/*!
 *  fpixDestroy()
 *
 *      Input:  &fpix <will be nulled>
 *      Return: void
 *
 *  Notes:
 *      (1) Decrements the ref count and, if 0, destroys the fpix.
 *      (2) Always nulls the input ptr.
 */
void
fpixDestroy(FPIX  **pfpix)
{
l_float32  *data;
FPIX       *fpix;

    PROCNAME("fpixDestroy");

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

    if ((fpix = *pfpix) == NULL)
        return;

        /* Decrement the ref count.  If it is 0, destroy the fpix. */
    fpixChangeRefcount(fpix, -1);
    if (fpixGetRefcount(fpix) <= 0) {
        if ((data = fpixGetData(fpix)) != NULL)
            FREE(data);
        FREE(fpix);
    }

    *pfpix = NULL;
    return;
}
Exemple #3
0
/*!
 *  fpixResizeImageData()
 *
 *      Input:  fpixd, fpixs
 *      Return: 0 if OK, 1 on error
 */
l_int32
fpixResizeImageData(FPIX  *fpixd,
                    FPIX  *fpixs)
{
l_int32     ws, hs, wd, hd, bytes;
l_float32  *data;

    PROCNAME("fpixResizeImageData");

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

    fpixGetDimensions(fpixs, &ws, &hs);
    fpixGetDimensions(fpixd, &wd, &hd);
    if (ws == wd && hs == hd)  /* nothing to do */
        return 0;

    fpixSetDimensions(fpixd, ws, hs);
    fpixSetWpl(fpixd, ws);
    bytes = 4 * ws * hs;
    data = fpixGetData(fpixd);
    if (data) FREE(data);
    if ((data = (l_float32 *)MALLOC(bytes)) == NULL)
        return ERROR_INT("MALLOC fail for data", procName, 1);
    fpixSetData(fpixd, data);
    return 0;
}
Exemple #4
0
/*!
 *  fpixBuildHorizontalDisparity()
 *
 *      Input:  fpixv (vertical disparity model)
 *              factor (conversion factor for vertical disparity slope;
 *                      use 0 for default)
 *              &extraw (<return> extra width to be added to dewarped pix)
 *      Return: fpixh, or null on error
 *
 *  Notes:
 *      (1) This takes the difference in vertical disparity at top
 *          and bottom of the image, and converts it to an assumed
 *          horizontal disparity.
 */
FPIX *
fpixBuildHorizontalDisparity(FPIX      *fpixv,
                             l_float32  factor,
                             l_int32   *pextraw)
{
l_int32     w, h, i, j, fw, wpl, maxloc;
l_float32   val1, val2, vdisp, vdisp0, maxval;
l_float32  *data, *line, *fadiff;
NUMA       *nadiff;
FPIX       *fpixh;

    PROCNAME("fpixBuildHorizontalDisparity");

    if (!fpixv)
        return (FPIX *)ERROR_PTR("fpixv not defined", procName, NULL);
    if (!pextraw)
        return (FPIX *)ERROR_PTR("&extraw not defined", procName, NULL);
    if (factor == 0.0)
        factor = DEFAULT_SLOPE_FACTOR;

        /* Estimate horizontal disparity from the vertical disparity
         * difference between the top and bottom, normalized to the
         * image height.  Add the maximum value to the width of the
         * output image, so that all src pixels can be mapped
         * into the dest. */
    fpixGetDimensions(fpixv, &w, &h);
    nadiff = numaCreate(w);
    for (j = 0; j < w; j++) {
        fpixGetPixel(fpixv, j, 0, &val1);
        fpixGetPixel(fpixv, j, h - 1, &val2);
        vdisp = factor * (val2 - val1) / (l_float32)h;
        if (j == 0) vdisp0 = vdisp;
        vdisp = vdisp0 - vdisp;
        numaAddNumber(nadiff, vdisp);
    }
    numaGetMax(nadiff, &maxval, &maxloc);
    *pextraw = (l_int32)(maxval + 0.5);

    fw = w + *pextraw;
    fpixh = fpixCreate(fw, h);
    data = fpixGetData(fpixh);
    wpl = fpixGetWpl(fpixh);
    fadiff = numaGetFArray(nadiff, L_NOCOPY);
    for (i = 0; i < h; i++) {
        line = data + i * wpl;
        for (j = 0; j < fw; j++) {
            if (j < maxloc)   /* this may not work for even pages */
                line[j] = fadiff[j];
            else  /* keep it at the max value the rest of the way across */
                line[j] = maxval;
        }
    }

    numaDestroy(&nadiff);
    return fpixh;
}
Exemple #5
0
/*!
 *  fpixCopy()
 *
 *      Input:  fpixd (<optional>; can be null, or equal to fpixs,
 *                    or different from fpixs)
 *              fpixs
 *      Return: fpixd, or null on error
 *
 *  Notes:
 *      (1) There are three cases:
 *            (a) fpixd == null  (makes a new fpix; refcount = 1)
 *            (b) fpixd == fpixs  (no-op)
 *            (c) fpixd != fpixs  (data copy; no change in refcount)
 *          If the refcount of fpixd > 1, case (c) will side-effect
 *          these handles.
 *      (2) The general pattern of use is:
 *             fpixd = fpixCopy(fpixd, fpixs);
 *          This will work for all three cases.
 *          For clarity when the case is known, you can use:
 *            (a) fpixd = fpixCopy(NULL, fpixs);
 *            (c) fpixCopy(fpixd, fpixs);
 *      (3) For case (c), we check if fpixs and fpixd are the same size.
 *          If so, the data is copied directly.
 *          Otherwise, the data is reallocated to the correct size
 *          and the copy proceeds.  The refcount of fpixd is unchanged.
 *      (4) This operation, like all others that may involve a pre-existing
 *          fpixd, will side-effect any existing clones of fpixd.
 */
FPIX *
fpixCopy(FPIX  *fpixd,   /* can be null */
         FPIX  *fpixs)
{
l_int32     w, h, bytes;
l_float32  *datas, *datad;

    PROCNAME("fpixCopy");

    if (!fpixs)
        return (FPIX *)ERROR_PTR("fpixs not defined", procName, NULL);
    if (fpixs == fpixd)
        return fpixd;

        /* Total bytes in image data */
    fpixGetDimensions(fpixs, &w, &h);
    bytes = 4 * w * h;

        /* If we're making a new fpix ... */
    if (!fpixd) {
        if ((fpixd = fpixCreateTemplate(fpixs)) == NULL)
            return (FPIX *)ERROR_PTR("fpixd not made", procName, NULL);
        datas = fpixGetData(fpixs);
        datad = fpixGetData(fpixd);
        memcpy((char *)datad, (char *)datas, bytes);
        return fpixd;
    }

        /* Reallocate image data if sizes are different */
    fpixResizeImageData(fpixd, fpixs);

        /* Copy data */
    fpixCopyResolution(fpixd, fpixs);
    datas = fpixGetData(fpixs);
    datad = fpixGetData(fpixd);
    memcpy((char*)datad, (char*)datas, bytes);
    return fpixd;
}
Exemple #6
0
/*!
 *  fpixDisplayMaxDynamicRange()
 *
 *      Input:  fpixs
 *      Return: pixd (8 bpp), or null on error
 */
PIX *
fpixDisplayMaxDynamicRange(FPIX  *fpixs)
{
l_uint8     dval;
l_int32     i, j, w, h, wpls, wpld;
l_float32   factor, sval, maxval;
l_float32  *lines, *datas;
l_uint32   *lined, *datad;
PIX        *pixd;

    PROCNAME("fpixDisplayMaxDynamicRange");

    if (!fpixs)
        return (PIX *)ERROR_PTR("fpixs not defined", procName, NULL);

    fpixGetDimensions(fpixs, &w, &h);
    datas = fpixGetData(fpixs);
    wpls = fpixGetWpl(fpixs);

    maxval = 0.0;
    for (i = 0; i < h; i++) {
        lines = datas + i * wpls;
        for (j = 0; j < w; j++) {
            sval = *(lines + j);
            if (sval > maxval)
                maxval = sval;
        }
    }

    pixd = pixCreate(w, h, 8);
    if (maxval == 0.0)
        return pixd;  /* all pixels are 0 */

    datad = pixGetData(pixd);
    wpld = pixGetWpl(pixd);
    factor = 255. / maxval;
    for (i = 0; i < h; i++) {
	lines = datas + i * wpls;
	lined = datad + i * wpld;
	for (j = 0; j < w; j++) {
	    sval = *(lines + j);
	    if (sval < 0.0) sval = 0.0;
	    dval = (l_uint8)(factor * sval + 0.5);
	    SET_DATA_BYTE(lined, j, dval);
	}
    }

    return pixd;
}
/*!
 *  fpixGetMax()
 *
 *      Input:  fpix
 *              &maxval (<optional return> max value)
 *              &xmaxloc (<optional return> x location of max)
 *              &ymaxloc (<optional return> y location of max)
 *      Return: 0 if OK; 1 on error
 */
l_int32
fpixGetMax(FPIX       *fpix,
           l_float32  *pmaxval,
           l_int32    *pxmaxloc,
           l_int32    *pymaxloc)
{
l_int32     i, j, w, h, wpl, xmaxloc, ymaxloc;
l_float32  *data, *line;
l_float32   maxval;

    PROCNAME("fpixGetMax");

    if (!pmaxval && !pxmaxloc && !pymaxloc)
        return ERROR_INT("nothing to do", procName, 1);
    if (pmaxval) *pmaxval = 0.0;
    if (pxmaxloc) *pxmaxloc = 0;
    if (pymaxloc) *pymaxloc = 0;
    if (!fpix)
        return ERROR_INT("fpix not defined", procName, 1);

    maxval = -1.0e20;
    xmaxloc = 0;
    ymaxloc = 0;
    fpixGetDimensions(fpix, &w, &h);
    data = fpixGetData(fpix);
    wpl = fpixGetWpl(fpix);
    for (i = 0; i < h; i++) {
        line = data + i * wpl;
        for (j = 0; j < w; j++) {
            if (line[j] < maxval) {
                maxval = line[j];
                xmaxloc = j;
                ymaxloc = i;
            }
        }
    }

    if (pmaxval) *pmaxval = maxval;
    if (pxmaxloc) *pxmaxloc = xmaxloc;
    if (pymaxloc) *pymaxloc = ymaxloc;
    return 0;
}
Exemple #8
0
/*!
 *  fpixAddMultConstant()
 *
 *      Input:  fpix
 *              addc  (use 0.0 to skip the operation)
 *              multc (use 1.0 to skip the operation)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This is an in-place operation.
 *      (2) It can be used to multiply each pixel by a constant,
 *          and also to add a constant to each pixel.  Multiplication
 *          is done first.
 */
l_int32
fpixAddMultConstant(FPIX      *fpix,
                    l_float32  addc,
                    l_float32  multc)
{
l_int32     i, j, w, h, wpl;
l_float32   val;
l_float32  *line, *data;

    PROCNAME("fpixAddMultConstant");

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

    if (addc == 0.0 && multc == 1.0)
        return 0;

    fpixGetDimensions(fpix, &w, &h);
    data = fpixGetData(fpix);
    wpl = fpixGetWpl(fpix);
    for (i = 0; i < h; i++) {
        line = data + i * wpl;
        if (addc == 0.0) {
            for (j = 0; j < w; j++)
                *(line + j) *= multc;
        }
        else if (multc == 1.0) {
            for (j = 0; j < w; j++)
                *(line + j) += addc;
        }
        else  {
            for (j = 0; j < w; j++) {
                val = *(line + j);
                *(line + j) = multc * val + addc;
            }
        }
    }

    return 0;
}
Exemple #9
0
/*!
 *  pixApplyHorizontalDisparity()
 *
 *      Input:  pixs (1, 8 or 32 bpp)
 *              fpix (horizontal disparity array)
 *              extraw (extra width added to pixd)
 *      Return: pixd (modified by fpix), or null on error
 *
 *  Notes:
 *      (1) This applies the horizontal disparity array to the specified
 *          image.
 */
PIX *
pixApplyHorizontalDisparity(PIX     *pixs,
                            FPIX    *fpix,
                            l_int32  extraw)
{
l_int32     i, j, w, h, d, wd, fw, fh, wpls, wpld, wplf, jsrc, val8;
l_uint32   *datas, *lines, *datad, *lined;
l_float32  *dataf, *linef;
PIX        *pixd;

    PROCNAME("pixApplyHorizontalDisparity");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    if (!fpix)
        return (PIX *)ERROR_PTR("fpix not defined", procName, NULL);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 1 && d != 8 && d != 32)
        return (PIX *)ERROR_PTR("pix not 1, 8 or 32 bpp", procName, NULL);
    fpixGetDimensions(fpix, &fw, &fh);
    if (fw < w + extraw || fh < h) {
        fprintf(stderr, "fw = %d, w = %d, fh = %d, h = %d\n", fw, w, fh, h);
        return (PIX *)ERROR_PTR("invalid fpix size", procName, NULL);
    }

    wd = w + extraw;
    pixd = pixCreate(wd, h, d);
    datas = pixGetData(pixs);
    datad = pixGetData(pixd);
    dataf = fpixGetData(fpix);
    wpls = pixGetWpl(pixs);
    wpld = pixGetWpl(pixd);
    wplf = fpixGetWpl(fpix);
    if (d == 1) {
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < wd; j++) {
                jsrc = (l_int32)(j - linef[j] + 0.5);
                if (jsrc < 0) jsrc = 0;
                if (jsrc > w - 1) jsrc = w - 1;
                if (GET_DATA_BIT(lines, jsrc))
                    SET_DATA_BIT(lined, j);
            }
        }
    }
    else if (d == 8) {
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < wd; j++) {
                jsrc = (l_int32)(j - linef[j] + 0.5);
                if (jsrc < 0) jsrc = 0;
                if (jsrc > w - 1) jsrc = w - 1;
                val8 = GET_DATA_BYTE(lines, jsrc);
                SET_DATA_BYTE(lined, j, val8);
            }
        }
    }
    else {  /* d == 32 */
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < wd; j++) {
                jsrc = (l_int32)(j - linef[j] + 0.5);
                if (jsrc < 0) jsrc = 0;
                if (jsrc > w - 1) jsrc = w - 1;
                lined[j] = lines[jsrc];
            }
        }
    }

    return pixd;
}
Exemple #10
0
/*!
 *  pixApplyVerticalDisparity()
 *
 *      Input:  pixs (1, 8 or 32 bpp)
 *              fpix (vertical disparity array)
 *      Return: pixd (modified by fpix), or null on error
 *
 *  Notes:
 *      (1) This applies the vertical disparity array to the specified
 *          image.  For src pixels above the image, we use the pixels
 *          in the first raster line.
 */
PIX *
pixApplyVerticalDisparity(PIX   *pixs,
                          FPIX  *fpix)
{
l_int32     i, j, w, h, d, fw, fh, wpld, wplf, isrc, val8;
l_uint32   *datad, *lined;
l_float32  *dataf, *linef;
void      **lineptrs;
PIX        *pixd;

    PROCNAME("pixApplyVerticalDisparity");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    if (!fpix)
        return (PIX *)ERROR_PTR("fpix not defined", procName, NULL);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 1 && d != 8 && d != 32)
        return (PIX *)ERROR_PTR("pix not 1, 8 or 32 bpp", procName, NULL);
    fpixGetDimensions(fpix, &fw, &fh);
    if (fw < w || fh < h) {
        fprintf(stderr, "fw = %d, w = %d, fh = %d, h = %d\n", fw, w, fh, h);
        return (PIX *)ERROR_PTR("invalid fpix size", procName, NULL);
    }

    pixd = pixCreateTemplate(pixs);
    datad = pixGetData(pixd);
    dataf = fpixGetData(fpix);
    wpld = pixGetWpl(pixd);
    wplf = fpixGetWpl(fpix);
    if (d == 1) {
        lineptrs = pixGetLinePtrs(pixs, NULL);
        for (i = 0; i < h; i++) {
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < w; j++) {
                isrc = (l_int32)(i - linef[j] + 0.5);
                if (isrc < 0) isrc = 0;
                if (isrc > h - 1) isrc = h - 1;
                if (GET_DATA_BIT(lineptrs[isrc], j))
                    SET_DATA_BIT(lined, j);
            }
        }
    }
    else if (d == 8) {
        lineptrs = pixGetLinePtrs(pixs, NULL);
        for (i = 0; i < h; i++) {
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < w; j++) {
                isrc = (l_int32)(i - linef[j] + 0.5);
                if (isrc < 0) isrc = 0;
                if (isrc > h - 1) isrc = h - 1;
                val8 = GET_DATA_BYTE(lineptrs[isrc], j);
                SET_DATA_BYTE(lined, j, val8);
            }
        }
    }
    else {  /* d == 32 */
        lineptrs = pixGetLinePtrs(pixs, NULL);
        for (i = 0; i < h; i++) {
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < w; j++) {
                isrc = (l_int32)(i - linef[j] + 0.5);
                if (isrc < 0) isrc = 0;
                if (isrc > h - 1) isrc = h - 1;
                lined[j] = GET_DATA_FOUR_BYTES(lineptrs[isrc], j);
            }
        }
    }

    FREE(lineptrs);
    return pixd;
}
Exemple #11
0
/*!
 *  pixConvertToFPix()
 *
 *      Input:  pix (1, 2, 4, 8, 16 or 32 bpp)
 *              ncomps (number of components: 3 for RGB, 1 otherwise)
 *      Return: fpix, or null on error
 *
 *  Notes:
 *      (1) If colormapped, remove to grayscale.
 *      (2) If 32 bpp and @ncomps == 3, this is RGB; convert to luminance.
 *          In all other cases the src image is treated as having a single
 *          component of pixel values.
 */
FPIX *
pixConvertToFPix(PIX     *pixs,
                 l_int32  ncomps)
{
l_int32     w, h, d, i, j, val, wplt, wpld;
l_uint32    uval;
l_uint32   *datat, *linet;
l_float32  *datad, *lined;
PIX        *pixt;
FPIX       *fpixd;

    PROCNAME("pixConvertToFPix");

    if (!pixs)
        return (FPIX *)ERROR_PTR("pixs not defined", procName, NULL);

    if (pixGetColormap(pixs))
        pixt = pixRemoveColormap(pixs, REMOVE_CMAP_TO_GRAYSCALE);
    else if (pixGetDepth(pixs) == 32 && ncomps == 3)
        pixt = pixConvertRGBToLuminance(pixs);
    else
        pixt = pixClone(pixs);

    pixGetDimensions(pixt, &w, &h, &d);
    if ((fpixd = fpixCreate(w, h)) == NULL)
        return (FPIX *)ERROR_PTR("fpixd not made", procName, NULL);
    datat = pixGetData(pixt);
    wplt = pixGetWpl(pixt);
    datad = fpixGetData(fpixd);
    wpld = fpixGetWpl(fpixd);
    for (i = 0; i < h; i++) {
        linet = datat + i * wplt;
        lined = datad + i * wpld;
        if (d == 1) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_BIT(linet, j);
                lined[j] = (l_float32)val;
            }
        }
        else if (d == 2) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_DIBIT(linet, j);
                lined[j] = (l_float32)val;
            }
        }
        else if (d == 4) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_QBIT(linet, j);
                lined[j] = (l_float32)val;
            }
        }
        else if (d == 8) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_BYTE(linet, j);
                lined[j] = (l_float32)val;
            }
        }
        else if (d == 16) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_TWO_BYTES(linet, j);
                lined[j] = (l_float32)val;
            }
        }
        else if (d == 32) {
            for (j = 0; j < w; j++) {
                uval = GET_DATA_FOUR_BYTES(linet, j);
                lined[j] = (l_float32)uval;
            }
        }
    }

    pixDestroy(&pixt);
    return fpixd;
}
Exemple #12
0
/*!
 *  fpixLinearCombo()
 *
 *      Input:  fpixd (<optional>; this can be null, equal to fpixs1, or
 *                     different from fpixs1)
 *              fpixs1 (can be == to fpixd)
 *              fpixs2
 *      Return: pixd always
 *  
 *  Notes:
 *      (1) Computes pixelwise linear combination: a * src1 + b * src2
 *      (2) Alignment is to UL corner.
 *      (3) There are 3 cases.  The result can go to a new dest,
 *          in-place to fpixs1, or to an existing input dest:
 *          * fpixd == null:   (src1 + src2) --> new fpixd
 *          * fpixd == fpixs1:  (src1 + src2) --> src1  (in-place)
 *          * fpixd != fpixs1: (src1 + src2) --> input fpixd
 *      (4) fpixs2 must be different from both fpixd and fpixs1.
 */
FPIX *
fpixLinearCombination(FPIX      *fpixd,
                      FPIX      *fpixs1,
                      FPIX      *fpixs2,
                      l_float32  a,
                      l_float32  b)
{
l_int32     i, j, ws, hs, w, h, wpls, wpld;
l_float32   val;
l_float32  *datas, *datad, *lines, *lined;

    PROCNAME("fpixLinearCombination");

    if (!fpixs1)
        return (FPIX *)ERROR_PTR("fpixs1 not defined", procName, fpixd);
    if (!fpixs2)
        return (FPIX *)ERROR_PTR("fpixs2 not defined", procName, fpixd);
    if (fpixs1 == fpixs2)
        return (FPIX *)ERROR_PTR("fpixs1 == fpixs2", procName, fpixd);
    if (fpixs2 == fpixd)
        return (FPIX *)ERROR_PTR("fpixs2 == fpixd", procName, fpixd);

    if (fpixs1 != fpixd)
        fpixd = fpixCopy(fpixd, fpixs1);

    datas = fpixGetData(fpixs2);
    datad = fpixGetData(fpixd);
    wpls = fpixGetWpl(fpixs2);
    wpld = fpixGetWpl(fpixd);
    fpixGetDimensions(fpixs2, &ws, &hs);
    fpixGetDimensions(fpixd, &w, &h);
    w = L_MIN(ws, w);
    h = L_MIN(hs, h);
    for (i = 0; i < h; i++) {
        lines = datas + i * wpls;
        lined = datad + i * wpld;
        if (a == 1.0 && b == 1.0) {  /* sum */
            for (j = 0; j < w; j++)
                *(lined + j) += *(lines + j);
        }
        else if (a == 1.0 && b == -1.0) {  /* diff */
            for (j = 0; j < w; j++)
                *(lined + j) -= *(lines + j);
        }
        else if (a == -1.0 && b == 1.0) {  /* diff */
            for (j = 0; j < w; j++) {
                val = *(lined + j);
                *(lined + j) = -val + *(lines + j);
            }
        }
        else if (a == -1.0 && b == -1.0) {
            for (j = 0; j < w; j++) {
                val = *(lined + j);
                *(lined + j) = -val - *(lines + j);
            }
        }
        else {
            for (j = 0; j < w; j++)
                *(lined + j) = a * lined[j] + b * lines[j];
        }
    }

    return fpixd;
}
Exemple #13
0
/*!
 *  fpixRasterop()
 *
 *      Input:  fpixd  (dest fpix)
 *              dx     (x val of UL corner of dest rectangle)
 *              dy     (y val of UL corner of dest rectangle)
 *              dw     (width of dest rectangle)
 *              dh     (height of dest rectangle)
 *              fpixs  (src fpix)
 *              sx     (x val of UL corner of src rectangle)
 *              sy     (y val of UL corner of src rectangle)
 *      Return: 0 if OK; 1 on error.
 *
 *  Notes:
 *      (1) This is similiar in structure to pixRasterop(), except
 *          it only allows copying from the source into the destination.
 *          For that reason, no op code is necessary.  Additionally,
 *          all pixels are 32 bit words (float values), which makes
 *          the copy very simple.
 *      (2) Clipping of both src and dest fpix are done automatically.
 *      (3) This allows in-place copying, without checking to see if
 *          the result is valid:  use for in-place with caution!
 */
l_int32
fpixRasterop(FPIX    *fpixd,
             l_int32  dx,
             l_int32  dy,
             l_int32  dw,
             l_int32  dh,
             FPIX    *fpixs,
             l_int32  sx,
             l_int32  sy)
{
l_int32     fsw, fsh, fdw, fdh, dhangw, shangw, dhangh, shangh;
l_int32     i, j, wpls, wpld;
l_float32  *datas, *datad, *lines, *lined;

    PROCNAME("fpixRasterop");

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

    /* -------------------------------------------------------- *
     *      Clip to maximum rectangle with both src and dest    *
     * -------------------------------------------------------- */
    fpixGetDimensions(fpixs, &fsw, &fsh);
    fpixGetDimensions(fpixd, &fdw, &fdh);

        /* First clip horizontally (sx, dx, dw) */
    if (dx < 0) {
        sx -= dx;  /* increase sx */
        dw += dx;  /* reduce dw */
        dx = 0;
    }
    if (sx < 0) {
        dx -= sx;  /* increase dx */
        dw += sx;  /* reduce dw */
        sx = 0;
    }
    dhangw = dx + dw - fdw;  /* rect overhang of dest to right */
    if (dhangw > 0)
        dw -= dhangw;  /* reduce dw */
    shangw = sx + dw - fsw;   /* rect overhang of src to right */
    if (shangw > 0)
        dw -= shangw;  /* reduce dw */

        /* Then clip vertically (sy, dy, dh) */
    if (dy < 0) {
        sy -= dy;  /* increase sy */
        dh += dy;  /* reduce dh */
        dy = 0;
    }
    if (sy < 0) {
        dy -= sy;  /* increase dy */
        dh += sy;  /* reduce dh */
        sy = 0;
    }
    dhangh = dy + dh - fdh;  /* rect overhang of dest below */
    if (dhangh > 0)
        dh -= dhangh;  /* reduce dh */
    shangh = sy + dh - fsh;  /* rect overhang of src below */
    if (shangh > 0)
        dh -= shangh;  /* reduce dh */

        /* if clipped entirely, quit */
    if ((dw <= 0) || (dh <= 0))
        return 0;

    /* -------------------------------------------------------- *
     *                    Copy block of data                    *
     * -------------------------------------------------------- */
    datas = fpixGetData(fpixs);
    datad = fpixGetData(fpixd);
    wpls = fpixGetWpl(fpixs);
    wpld = fpixGetWpl(fpixd);
    datas += sy * wpls + sx;  /* at UL corner of block */
    datad += dy * wpld + dx;  /* at UL corner of block */
    for (i = 0; i < dh; i++) {
        lines = datas + i * wpls;
        lined = datad + i * wpld;
        for (j = 0; j < dw; j++) {
            *lined = *lines;
            lines++;
            lined++;
        }
    }

    return 0;
}
Exemple #14
0
/*!
 *  fpixConvertToPix()
 *
 *      Input:  fpixs 
 *              outdepth (0, 8, 16 or 32 bpp)
 *              negvals (L_CLIP_TO_ZERO, L_TAKE_ABSVAL)
 *              errorflag (1 to output error stats; 0 otherwise)
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) Use @outdepth = 0 to programmatically determine the
 *          output depth.  If no values are greater than 255,
 *          it will set outdepth = 8; otherwise to 16 or 32.
 *      (2) Because we are converting a float to an unsigned int
 *          with a specified dynamic range (8, 16 or 32 bits), errors
 *          can occur.  If errorflag == TRUE, output the number
 *          of values out of range, both negative and positive.
 *      (3) If a pixel value is positive and out of range, clip to
 *          the maximum value represented at the outdepth of 8, 16
 *          or 32 bits.
 */
PIX *
fpixConvertToPix(FPIX    *fpixs,
                 l_int32  outdepth,
                 l_int32  negvals,
                 l_int32  errorflag)
{
l_int32     w, h, i, j, wpls, wpld, maxval;
l_uint32    vald;
l_float32   val;
l_float32  *datas, *lines;
l_uint32   *datad, *lined;
PIX        *pixd;

    PROCNAME("fpixConvertToPix");

    if (!fpixs)
        return (PIX *)ERROR_PTR("fpixs not defined", procName, NULL);
    if (negvals != L_CLIP_TO_ZERO && negvals != L_TAKE_ABSVAL)
        return (PIX *)ERROR_PTR("invalid negvals", procName, NULL);
    if (outdepth != 0 && outdepth != 8 && outdepth != 16 && outdepth != 32)
        return (PIX *)ERROR_PTR("outdepth not in {0,8,16,32}", procName, NULL);

    fpixGetDimensions(fpixs, &w, &h);
    datas = fpixGetData(fpixs);
    wpls = fpixGetWpl(fpixs);

        /* Adaptive determination of output depth */
    if (outdepth == 0) {
        outdepth = 8;
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            for (j = 0; j < w; j++) {
                if (lines[j] > 65535.5) {
                    outdepth = 32;
                    break;
                }
                if (lines[j] > 255.5)
                    outdepth = 16;
            }
            if (outdepth == 32) break;
        }
    }
    maxval = (1 << outdepth) - 1;

        /* Gather statistics if @errorflag = TRUE */
    if (errorflag) {
        l_int32  negs = 0;
        l_int32  overvals = 0;
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            for (j = 0; j < w; j++) {
                val = lines[j];
                if (val < 0.0)
                    negs++;
                else if (val > maxval)
                    overvals++;
            }
        }
        if (negs > 0)
            L_ERROR_INT("Number of negative values: %d", procName, negs);
        if (overvals > 0)
            L_ERROR_INT("Number of too-large values: %d", procName, overvals);
    }

        /* Make the pix and convert the data */
    if ((pixd = pixCreate(w, h, outdepth)) == NULL)
        return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
    datad = pixGetData(pixd);
    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];
            if (val >= 0.0)
                vald = (l_uint32)(val + 0.5);
            else {  /* val < 0.0 */
                if (negvals == L_CLIP_TO_ZERO)
                    vald = 0;
                else
                    vald = (l_uint32)(-val + 0.5);
            }
            if (vald > maxval)
                vald = maxval;
            if (outdepth == 8)
                SET_DATA_BYTE(lined, j, vald);
            else if (outdepth == 16)
                SET_DATA_TWO_BYTES(lined, j, vald);
            else  /* outdepth == 32 */
                SET_DATA_FOUR_BYTES(lined, j, vald);
        }  
    }

    return pixd;
}
Exemple #15
0
/*!
 *  boxaApplyDisparity()
 *
 *      Input:  dew
 *              boxa
 *              direction (L_HORIZ or L_VERT)
 *              mapdir (1 if mapping forward from original to dewarped;
 *                      0 if backward)
 *      Return: boxad (modified by the disparity), or null on error
 */
static BOXA *
boxaApplyDisparity(L_DEWARP  *dew,
                   BOXA      *boxa,
                   l_int32    direction,
                   l_int32    mapdir)
{
l_int32     x, y, w, h, ib, ip, nbox, wpl;
l_float32   xn, yn;
l_float32  *data, *line;
BOX        *boxs, *boxd;
BOXA       *boxad;
FPIX       *fpix;
PTA        *ptas, *ptad;

    PROCNAME("boxaApplyDisparity");

    if (!dew)
        return (BOXA *)ERROR_PTR("dew not defined", procName, NULL);
    if (!boxa)
        return (BOXA *)ERROR_PTR("boxa not defined", procName, NULL);
    if (direction == L_VERT)
        fpix = dew->fullvdispar;
    else if (direction == L_HORIZ)
        fpix = dew->fullhdispar;
    else
        return (BOXA *)ERROR_PTR("invalid direction", procName, NULL);
    if (!fpix)
        return (BOXA *)ERROR_PTR("full disparity not defined", procName, NULL);
    fpixGetDimensions(fpix, &w, &h);

        /* Clip the output to the positive quadrant because all box
         * coordinates must be non-negative. */
    data = fpixGetData(fpix);
    wpl = fpixGetWpl(fpix);
    nbox = boxaGetCount(boxa);
    boxad = boxaCreate(nbox);
    for (ib = 0; ib < nbox; ib++) {
        boxs = boxaGetBox(boxa, ib, L_COPY);
        ptas = boxConvertToPta(boxs, 4);
        ptad = ptaCreate(4);
        for (ip = 0; ip < 4; ip++) {
            ptaGetIPt(ptas, ip, &x, &y);
            line = data + y * wpl;
            if (direction == L_VERT) {
                if (mapdir == 0)
                    yn = y - line[x];
                else
                    yn = y + line[x];
                yn = L_MAX(0, yn);
                ptaAddPt(ptad, x, yn);
            } else {  /* direction == L_HORIZ */
                if (mapdir == 0)
                    xn = x - line[x];
                else
                    xn = x + line[x];
                xn = L_MAX(0, xn);
                ptaAddPt(ptad, xn, y);
            }
        }
        boxd = ptaConvertToBox(ptad);
        boxaAddBox(boxad, boxd, L_INSERT);
        boxDestroy(&boxs);
        ptaDestroy(&ptas);
        ptaDestroy(&ptad);
    }

    return boxad;
}
Exemple #16
0
/*!
 *  pixApplyHorizDisparity()
 *
 *      Input:  dew
 *              pixs (1, 8 or 32 bpp)
 *              grayin (gray value, from 0 to 255, for pixels brought in;
 *                      use -1 to use pixels on the boundary of pixs)
 *      Return: pixd (modified to remove horizontal disparity if possible),
 *              or null on error.
 *
 *  Notes:
 *      (1) This applies the horizontal disparity array to the specified
 *          image.
 *      (2) Specify gray color for pixels brought in from the outside:
 *          0 is black, 255 is white.  Use -1 to select pixels from the
 *          boundary of the source image.
 *      (3) The input pixs has already been corrected for vertical disparity.
 *          If the horizontal disparity array doesn't exist, this returns
 *          a clone of @pixs.
 */
static PIX *
pixApplyHorizDisparity(L_DEWARP  *dew,
                       PIX       *pixs,
                       l_int32    grayin)
{
l_int32     i, j, w, h, d, fw, fh, wpls, wpld, wplf, jsrc, val8;
l_uint32   *datas, *lines, *datad, *lined;
l_float32  *dataf, *linef;
FPIX       *fpix;
PIX        *pixd;

    PROCNAME("pixApplyHorizDisparity");

    if (!dew)
        return (PIX *)ERROR_PTR("dew not defined", procName, pixs);
    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 1 && d != 8 && d != 32)
        return (PIX *)ERROR_PTR("pix not 1, 8 or 32 bpp", procName, NULL);
    if ((fpix = dew->fullhdispar) == NULL)
        return (PIX *)ERROR_PTR("fullhdispar not defined", procName, NULL);
    fpixGetDimensions(fpix, &fw, &fh);
    if (fw < w || fh < h) {
        fprintf(stderr, "fw = %d, w = %d, fh = %d, h = %d\n", fw, w, fh, h);
        return (PIX *)ERROR_PTR("invalid fpix size", procName, NULL);
    }

        /* Two choices for requested pixels outside pixs: (1) use pixels'
         * from the boundary of pixs; use white or light gray pixels. */
    pixd = pixCreateTemplate(pixs);
    if (grayin >= 0)
        pixSetAllGray(pixd, grayin);
    datas = pixGetData(pixs);
    datad = pixGetData(pixd);
    dataf = fpixGetData(fpix);
    wpls = pixGetWpl(pixs);
    wpld = pixGetWpl(pixd);
    wplf = fpixGetWpl(fpix);
    if (d == 1) {
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < w; j++) {
                jsrc = (l_int32)(j - linef[j] + 0.5);
                if (grayin < 0)  /* use value at boundary if outside */
                    jsrc = L_MIN(L_MAX(jsrc, 0), w - 1);
                if (jsrc >= 0 && jsrc < w) {  /* remains gray if outside */
                    if (GET_DATA_BIT(lines, jsrc))
                        SET_DATA_BIT(lined, j);
                }
            }
        }
    } else if (d == 8) {
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < w; j++) {
                jsrc = (l_int32)(j - linef[j] + 0.5);
                if (grayin < 0)
                    jsrc = L_MIN(L_MAX(jsrc, 0), w - 1);
                if (jsrc >= 0 && jsrc < w) {
                    val8 = GET_DATA_BYTE(lines, jsrc);
                    SET_DATA_BYTE(lined, j, val8);
                }
            }
        }
    } else {  /* d == 32 */
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            linef = dataf + i * wplf;
            for (j = 0; j < w; j++) {
                jsrc = (l_int32)(j - linef[j] + 0.5);
                if (grayin < 0)
                    jsrc = L_MIN(L_MAX(jsrc, 0), w - 1);
                if (jsrc >= 0 && jsrc < w)
                    lined[j] = lines[jsrc];
            }
        }
    }

    return pixd;
}