/*!
 *  pixAddConstantGray()
 *
 *      Input:  pixs (8, 16 or 32 bpp)
 *              val  (amount to add to each pixel)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) In-place operation.
 *      (2) No clipping for 32 bpp.
 *      (3) For 8 and 16 bpp, if val > 0 the result is clipped
 *          to 0xff and 0xffff, rsp.
 *      (4) For 8 and 16 bpp, if val < 0 the result is clipped to 0.
 */
l_int32
pixAddConstantGray(PIX      *pixs,
                   l_int32   val)
{
l_int32    i, j, w, h, d, wpl, pval;
l_uint32  *data, *line;

    PROCNAME("pixAddConstantGray");

    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);

    data = pixGetData(pixs);
    wpl = pixGetWpl(pixs);
    for (i = 0; i < h; i++) {
        line = data + i * wpl;
        if (d == 8) {
            if (val < 0) {
                for (j = 0; j < w; j++) {
                    pval = GET_DATA_BYTE(line, j);
                    pval = L_MAX(0, pval + val);
                    SET_DATA_BYTE(line, j, pval);
                }
            } else {  /* val >= 0 */
                for (j = 0; j < w; j++) {
                    pval = GET_DATA_BYTE(line, j);
                    pval = L_MIN(255, pval + val);
                    SET_DATA_BYTE(line, j, pval);
                }
            }
        } else if (d == 16) {
            if (val < 0) {
                for (j = 0; j < w; j++) {
                    pval = GET_DATA_TWO_BYTES(line, j);
                    pval = L_MAX(0, pval + val);
                    SET_DATA_TWO_BYTES(line, j, pval);
                }
            } else {  /* val >= 0 */
                for (j = 0; j < w; j++) {
                    pval = GET_DATA_TWO_BYTES(line, j);
                    pval = L_MIN(0xffff, pval + val);
                    SET_DATA_TWO_BYTES(line, j, pval);
                }
            }
        } else {  /* d == 32; no check for overflow (< 0 or > 0xffffffff) */
            for (j = 0; j < w; j++)
                *(line + j) += val;
        }
    }

    return 0;
}
Пример #2
0
/*!
 *  addConstantGrayLow()
 */
void
addConstantGrayLow(l_uint32  *data,
                   l_int32    w,
                   l_int32    h,
                   l_int32    d,
                   l_int32    wpl,
                   l_int32    val)
{
    l_int32    i, j, pval;
    l_uint32  *line;

    for (i = 0; i < h; i++) {
        line = data + i * wpl;
        if (d == 8) {
            if (val < 0) {
                for (j = 0; j < w; j++) {
                    pval = GET_DATA_BYTE(line, j);
                    pval = L_MAX(0, pval + val);
                    SET_DATA_BYTE(line, j, pval);
                }
            }
            else {  /* val >= 0 */
                for (j = 0; j < w; j++) {
                    pval = GET_DATA_BYTE(line, j);
                    pval = L_MIN(255, pval + val);
                    SET_DATA_BYTE(line, j, pval);
                }
            }
        }
        else if (d == 16) {
            if (val < 0) {
                for (j = 0; j < w; j++) {
                    pval = GET_DATA_TWO_BYTES(line, j);
                    pval = L_MAX(0, pval + val);
                    SET_DATA_TWO_BYTES(line, j, pval);
                }
            }
            else {  /* val >= 0 */
                for (j = 0; j < w; j++) {
                    pval = GET_DATA_TWO_BYTES(line, j);
                    pval = L_MIN(0xffff, pval + val);
                    SET_DATA_TWO_BYTES(line, j, pval);
                }
            }
        }
        else {  /* d == 32; no check for overflow (< 0 or > 0xffffffff) */
            for (j = 0; j < w; j++)
                *(line + j) += val;
        }
    }
    return;
}
Пример #3
0
/*!
 *  addGrayLow()
 */
void
addGrayLow(l_uint32  *datad,
           l_int32    w,
           l_int32    h,
           l_int32    d,
           l_int32    wpld,
           l_uint32  *datas,
           l_int32    wpls)
{
    l_int32    i, j, val, sum;
    l_uint32  *lines, *lined;


    for (i = 0; i < h; i++) {
        lined = datad + i * wpld;
        lines = datas + i * wpls;
        if (d == 8) {
            for (j = 0; j < w; j++) {
                sum = GET_DATA_BYTE(lines, j) + GET_DATA_BYTE(lined, j);
                val = L_MIN(sum, 255);
                SET_DATA_BYTE(lined, j, val);
            }
        }
        else if (d == 16) {
            for (j = 0; j < w; j++) {
                sum = GET_DATA_TWO_BYTES(lines, j)
                      + GET_DATA_TWO_BYTES(lined, j);
                val = L_MIN(sum, 0xffff);
                SET_DATA_TWO_BYTES(lined, j, val);
            }
        }
        else {   /* d == 32; no clipping */
            for (j = 0; j < w; j++)
                *(lined + j) += *(lines + j);
        }
    }

    return;
}
Пример #4
0
/*!
 *  subtractGrayLow()
 */
void
subtractGrayLow(l_uint32  *datad,
                l_int32    w,
                l_int32    h,
                l_int32    d,
                l_int32    wpld,
                l_uint32  *datas,
                l_int32    wpls)
{
    l_int32    i, j, val, diff;
    l_uint32  *lines, *lined;

    for (i = 0; i < h; i++) {
        lined = datad + i * wpld;
        lines = datas + i * wpls;
        if (d == 8) {
            for (j = 0; j < w; j++) {
                diff = GET_DATA_BYTE(lined, j) - GET_DATA_BYTE(lines, j);
                val = L_MAX(diff, 0);
                SET_DATA_BYTE(lined, j, val);
            }
        }
        else if (d == 16) {
            for (j = 0; j < w; j++) {
                diff = GET_DATA_TWO_BYTES(lined, j)
                       - GET_DATA_TWO_BYTES(lines, j);
                val = L_MAX(diff, 0);
                SET_DATA_TWO_BYTES(lined, j, val);
            }
        }
        else {  /* d == 32; no clipping */
            for (j = 0; j < w; j++)
                *(lined + j) -= *(lines + j);
        }
    }

    return;
}
/*!
 *  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    i, j, w, h, d, wpl, pval;
l_uint32   upval;
l_uint32  *data, *line;

    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);
    for (i = 0; i < h; i++) {
        line = data + i * wpl;
        if (d == 8) {
            for (j = 0; j < w; j++) {
                pval = GET_DATA_BYTE(line, j);
                pval = (l_int32)(val * pval);
                pval = L_MIN(255, pval);
                SET_DATA_BYTE(line, j, pval);
            }
        } else if (d == 16) {
            for (j = 0; j < w; j++) {
                pval = GET_DATA_TWO_BYTES(line, j);
                pval = (l_int32)(val * pval);
                pval = L_MIN(0xffff, pval);
                SET_DATA_TWO_BYTES(line, j, pval);
            }
        } else {  /* d == 32; no clipping */
            for (j = 0; j < w; j++) {
                upval = *(line + j);
                upval = (l_uint32)(val * upval);
                *(line + j) = upval;
            }
        }
    }

    return 0;
}
Пример #6
0
/*!
 *  multConstantGrayLow()
 */
void
multConstantGrayLow(l_uint32  *data,
                    l_int32    w,
                    l_int32    h,
                    l_int32    d,
                    l_int32    wpl,
                    l_float32  val)
{
    l_int32    i, j, pval;
    l_uint32   upval;
    l_uint32  *line;

    for (i = 0; i < h; i++) {
        line = data + i * wpl;
        if (d == 8) {
            for (j = 0; j < w; j++) {
                pval = GET_DATA_BYTE(line, j);
                pval = (l_int32)(val * pval);
                pval = L_MIN(255, pval);
                SET_DATA_BYTE(line, j, pval);
            }
        }
        else if (d == 16) {
            for (j = 0; j < w; j++) {
                pval = GET_DATA_TWO_BYTES(line, j);
                pval = (l_int32)(val * pval);
                pval = L_MIN(0xffff, pval);
                SET_DATA_TWO_BYTES(line, j, pval);
            }
        }
        else {  /* d == 32; no clipping */
            for (j = 0; j < w; j++) {
                upval = *(line + j);
                upval = (l_uint32)(val * upval);
                *(line + j) = upval;
            }
        }
    }
    return;
}
/*!
 *  pixAbsDifference()
 *
 *      Input:  pixs1, pixs2  (both either 8 or 16 bpp gray, or 32 bpp RGB)
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) The depth of pixs1 and pixs2 must be equal.
 *      (2) Clips computation to the min size, aligning the UL corners
 *      (3) For 8 and 16 bpp, assumes one gray component.
 *      (4) For 32 bpp, assumes 3 color components, and ignores the
 *          LSB of each word (the alpha channel)
 *      (5) Computes the absolute value of the difference between
 *          each component value.
 */
PIX *
pixAbsDifference(PIX  *pixs1,
                 PIX  *pixs2)
{
l_int32    i, j, w, h, w2, h2, d, wpls1, wpls2, wpld, val1, val2, diff;
l_int32    rval1, gval1, bval1, rval2, gval2, bval2, rdiff, gdiff, bdiff;
l_uint32  *datas1, *datas2, *datad, *lines1, *lines2, *lined;
PIX       *pixd;

    PROCNAME("pixAbsDifference");

    if (!pixs1)
        return (PIX *)ERROR_PTR("pixs1 not defined", procName, NULL);
    if (!pixs2)
        return (PIX *)ERROR_PTR("pixs2 not defined", procName, NULL);
    d = pixGetDepth(pixs1);
    if (d != pixGetDepth(pixs2))
        return (PIX *)ERROR_PTR("src1 and src2 depths unequal", procName, NULL);
    if (d != 8 && d != 16 && d != 32)
        return (PIX *)ERROR_PTR("depths not in {8, 16, 32}", procName, NULL);

    pixGetDimensions(pixs1, &w, &h, NULL);
    pixGetDimensions(pixs2, &w2, &h2, NULL);
    w = L_MIN(w, w2);
    h = L_MIN(h, h2);
    if ((pixd = pixCreate(w, h, d)) == NULL)
        return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
    pixCopyResolution(pixd, pixs1);
    datas1 = pixGetData(pixs1);
    datas2 = pixGetData(pixs2);
    datad = pixGetData(pixd);
    wpls1 = pixGetWpl(pixs1);
    wpls2 = pixGetWpl(pixs2);
    wpld = pixGetWpl(pixd);
    if (d == 8) {
        for (i = 0; i < h; i++) {
            lines1 = datas1 + i * wpls1;
            lines2 = datas2 + i * wpls2;
            lined = datad + i * wpld;
            for (j = 0; j < w; j++) {
                val1 = GET_DATA_BYTE(lines1, j);
                val2 = GET_DATA_BYTE(lines2, j);
                diff = L_ABS(val1 - val2);
                SET_DATA_BYTE(lined, j, diff);
            }
        }
    } else if (d == 16) {
        for (i = 0; i < h; i++) {
            lines1 = datas1 + i * wpls1;
            lines2 = datas2 + i * wpls2;
            lined = datad + i * wpld;
            for (j = 0; j < w; j++) {
                val1 = GET_DATA_TWO_BYTES(lines1, j);
                val2 = GET_DATA_TWO_BYTES(lines2, j);
                diff = L_ABS(val1 - val2);
                SET_DATA_TWO_BYTES(lined, j, diff);
            }
        }
    } else {  /* d == 32 */
        for (i = 0; i < h; i++) {
            lines1 = datas1 + i * wpls1;
            lines2 = datas2 + i * wpls2;
            lined = datad + i * wpld;
            for (j = 0; j < w; j++) {
                extractRGBValues(lines1[j], &rval1, &gval1, &bval1);
                extractRGBValues(lines2[j], &rval2, &gval2, &bval2);
                rdiff = L_ABS(rval1 - rval2);
                gdiff = L_ABS(gval1 - gval2);
                bdiff = L_ABS(bval1 - bval2);
                composeRGBPixel(rdiff, gdiff, bdiff, lined + j);
            }
        }
    }

    return pixd;
}
Пример #8
0
/*!
 *  pixMinOrMax()
 *
 *      Input:  pixd  (<optional> destination: this can be null,
 *                     equal to pixs1, or different from pixs1)
 *              pixs1 (can be == to pixd)
 *              pixs2
 *              type (L_CHOOSE_MIN, L_CHOOSE_MAX)
 *      Return: pixd always
 *
 *  Notes:
 *      (1) This gives the min or max of two images.
 *      (2) The depth can be 8 or 16 bpp.
 *      (3) There are 3 cases:
 *          -  if pixd == null,   Min(src1, src2) --> new pixd
 *          -  if pixd == pixs1,  Min(src1, src2) --> src1  (in-place)
 *          -  if pixd != pixs1,  Min(src1, src2) --> input pixd
 */
PIX *
pixMinOrMax(PIX     *pixd,
            PIX     *pixs1,
            PIX     *pixs2,
            l_int32  type)
{
l_int32    d, ws, hs, w, h, wpls, wpld, i, j;
l_int32    vals, vald, val;
l_uint32  *datas, *datad, *lines, *lined;

    PROCNAME("pixMinOrMax");

    if (!pixs1)
        return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
    if (!pixs2)
        return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
    if (pixs1 == pixs2)
        return (PIX *)ERROR_PTR("pixs1 and pixs2 must differ", procName, pixd);
    if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX)
        return (PIX *)ERROR_PTR("invalid type", procName, pixd);
    d = pixGetDepth(pixs1);
    if (pixGetDepth(pixs2) != d)
        return (PIX *)ERROR_PTR("depths unequal", procName, pixd);
    if (d != 8 && d != 16)
        return (PIX *)ERROR_PTR("depth not 8 or 16 bpp", procName, pixd);

    if (pixs1 != pixd)
        pixd = pixCopy(pixd, pixs1);

    pixGetDimensions(pixs2, &ws, &hs, NULL);
    pixGetDimensions(pixd, &w, &h, NULL);
    w = L_MIN(w, ws);
    h = L_MIN(h, hs);
    datas = pixGetData(pixs2);
    datad = pixGetData(pixd);
    wpls = pixGetWpl(pixs2);
    wpld = pixGetWpl(pixd);
    for (i = 0; i < h; i++) {
        lines = datas + i * wpls;
        lined = datad + i * wpld;
        if (d == 8) {
            if (type == L_CHOOSE_MIN) {
                for (j = 0; j < w; j++) {
                    vals = GET_DATA_BYTE(lines, j);
                    vald = GET_DATA_BYTE(lined, j);
                    val = L_MIN(vals, vald);
                    SET_DATA_BYTE(lined, j, val);
                }
            } else {  /* type == L_CHOOSE_MAX */
                for (j = 0; j < w; j++) {
                    vals = GET_DATA_BYTE(lines, j);
                    vald = GET_DATA_BYTE(lined, j);
                    val = L_MAX(vals, vald);
                    SET_DATA_BYTE(lined, j, val);
                }
            }
        } else {  /* d == 16 */
            if (type == L_CHOOSE_MIN) {
                for (j = 0; j < w; j++) {
                    vals = GET_DATA_TWO_BYTES(lines, j);
                    vald = GET_DATA_TWO_BYTES(lined, j);
                    val = L_MIN(vals, vald);
                    SET_DATA_TWO_BYTES(lined, j, val);
                }
            } else {  /* type == L_CHOOSE_MAX */
                for (j = 0; j < w; j++) {
                    vals = GET_DATA_TWO_BYTES(lines, j);
                    vald = GET_DATA_TWO_BYTES(lined, j);
                    val = L_MAX(vals, vald);
                    SET_DATA_TWO_BYTES(lined, j, val);
                }
            }
        }
    }

    return pixd;
}
Пример #9
0
main(int    argc,
     char **argv)
{
l_int32      x, y, i, j, k, w, h, w2, w4, w8, w16, w32, wpl, nerrors;
l_int32      count1, count2, count3, ret, val1, val2;
l_uint32     val32;
l_uint32    *data, *line, *line1, *line2, *data1, *data2;
void       **lines1, **linet1, **linet2;
PIX         *pixs, *pixt1, *pixt2;
static char  mainName[] = "lowaccess_reg";

    pixs = pixRead("feyn.tif");   /* width divisible by 16 */
    pixGetDimensions(pixs, &w, &h, NULL);
    data = 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++) {
            line = data + i * wpl;
            for (j = 0; j < w; j++) {
               if (l_getDataBit(line, 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);

    pixt1 = pixCreateTemplate(pixs);
    data1 = pixGetData(pixt1);
    linet1 = pixGetLinePtrs(pixt1, NULL);
    pixt2 = pixCreateTemplate(pixs);
    data2 = pixGetData(pixt2);
    linet2 = pixGetLinePtrs(pixt2, NULL);

    nerrors = 0;

        /* 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++) {
        line = data + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w; j++) {
            val2 = l_getDataBit(line, j);
            count2 += val2;
            if (val2) l_setDataBit(line2, j);
        }
    }
    ret = compareResults(pixs, pixt1, pixt2, count1, count2, "1 bpp");
    nerrors += ret;

        /* 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++) {
        line = data + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w2; j++) {
            val2 = l_getDataDibit(line, j);
            count2 += val2;
            val2 += 0xbbbbbbbc;
            l_setDataDibit(line2, j, val2);
        }
    }
    ret = compareResults(pixs, pixt1, pixt2, count1, count2, "2 bpp");
    nerrors += ret;

        /* 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++) {
        line = data + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w4; j++) {
            val2 = l_getDataQbit(line, j);
            count2 += val2;
            val2 += 0xbbbbbbb0;
            l_setDataQbit(line2, j, val2);
        }
    }
    ret = compareResults(pixs, pixt1, pixt2, count1, count2, "4 bpp");
    nerrors += ret;

        /* 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++) {
        line = data + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w8; j++) {
            val2 = l_getDataByte(line, j);
            count2 += val2;
            val2 += 0xbbbbbb00;
            l_setDataByte(line2, j, val2);
        }
    }
    ret = compareResults(pixs, pixt1, pixt2, count1, count2, "8 bpp");
    nerrors += ret;

        /* 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++) {
        line = data + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w16; j++) {
            val2 = l_getDataTwoBytes(line, j);
            count2 += val2;
            val2 += 0xbbbb0000;
            l_setDataTwoBytes(line2, j, val2);
        }
    }
    ret = compareResults(pixs, pixt1, pixt2, count1, count2, "16 bpp");
    nerrors += ret;

        /* 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++) {
        line = data + i * wpl;
        line2 = data2 + i * wpl;
        for (j = 0; j < w32; j++) {
            val2 = l_getDataFourBytes(line, j);
            count2 += val2 & 0xfff;
            l_setDataFourBytes(line2, j, val2);
        }
    }
    ret = compareResults(pixs, pixt1, pixt2, count1, count2, "32 bpp");
    nerrors += ret;

    if (!nerrors)
        fprintf(stderr, "****  No errors  ****\n");
    else
        fprintf(stderr, "****  %d errors found!  ****\n", nerrors);

    pixDestroy(&pixs);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    lept_free(lines1);
    lept_free(linet1);
    lept_free(linet2);
    return 0;
}
Пример #10
0
/*!
 *  absDifferenceLow()
 *
 *  Finds the absolute value of the difference of each pixel,
 *  for 8 and 16 bpp gray and for 32 bpp rgb.  For 32 bpp, the
 *  differences are found for each of the RGB components
 *  separately, and the LSB component is ignored.
 *  The results are written into datad.
 */
void
absDifferenceLow(l_uint32  *datad,
                 l_int32    w,
                 l_int32    h,
                 l_int32    wpld,
                 l_uint32  *datas1,
                 l_uint32  *datas2,
                 l_int32    d,
                 l_int32    wpls)
{
    l_int32    i, j, val1, val2, diff;
    l_uint32   word1, word2;
    l_uint32  *lines1, *lines2, *lined, *pdword;

    PROCNAME("absDifferenceLow");

    switch (d)
    {
    case 8:
        for (i = 0; i < h; i++) {
            lines1 = datas1 + i * wpls;
            lines2 = datas2 + i * wpls;
            lined = datad + i * wpld;
            for (j = 0; j < w; j++) {
                val1 = GET_DATA_BYTE(lines1, j);
                val2 = GET_DATA_BYTE(lines2, j);
                diff = L_ABS(val1 - val2);
                SET_DATA_BYTE(lined, j, diff);
            }
        }
        break;
    case 16:
        for (i = 0; i < h; i++) {
            lines1 = datas1 + i * wpls;
            lines2 = datas2 + i * wpls;
            lined = datad + i * wpld;
            for (j = 0; j < w; j++) {
                val1 = GET_DATA_TWO_BYTES(lines1, j);
                val2 = GET_DATA_TWO_BYTES(lines2, j);
                diff = L_ABS(val1 - val2);
                SET_DATA_TWO_BYTES(lined, j, diff);
            }
        }
        break;
    case 32:
        for (i = 0; i < h; i++) {
            lines1 = datas1 + i * wpls;
            lines2 = datas2 + i * wpls;
            lined = datad + i * wpld;
            for (j = 0; j < w; j++) {
                word1 = lines1[j];
                word2 = lines2[j];
                pdword = lined + j;
                val1 = GET_DATA_BYTE(&word1, COLOR_RED);
                val2 = GET_DATA_BYTE(&word2, COLOR_RED);
                diff = L_ABS(val1 - val2);
                SET_DATA_BYTE(pdword, COLOR_RED, diff);
                val1 = GET_DATA_BYTE(&word1, COLOR_GREEN);
                val2 = GET_DATA_BYTE(&word2, COLOR_GREEN);
                diff = L_ABS(val1 - val2);
                SET_DATA_BYTE(pdword, COLOR_GREEN, diff);
                val1 = GET_DATA_BYTE(&word1, COLOR_BLUE);
                val2 = GET_DATA_BYTE(&word2, COLOR_BLUE);
                diff = L_ABS(val1 - val2);
                SET_DATA_BYTE(pdword, COLOR_BLUE, diff);
            }
        }
        break;
    default:
        L_ERROR("source depth must be 8, 16 or 32 bpp", procName);
        break;
    }

    return;
}
/*!
 *  pixMinOrMax()
 *
 *      Input:  pixd  (<optional> destination: this can be null,
 *                     equal to pixs1, or different from pixs1)
 *              pixs1 (can be == to pixd)
 *              pixs2
 *              type (L_CHOOSE_MIN, L_CHOOSE_MAX)
 *      Return: pixd always
 *
 *  Notes:
 *      (1) This gives the min or max of two images, component-wise.
 *      (2) The depth can be 8 or 16 bpp for 1 component, and 32 bpp
 *          for a 3 component image.  For 32 bpp, ignore the LSB
 *          of each word (the alpha channel)
 *      (3) There are 3 cases:
 *          -  if pixd == null,   Min(src1, src2) --> new pixd
 *          -  if pixd == pixs1,  Min(src1, src2) --> src1  (in-place)
 *          -  if pixd != pixs1,  Min(src1, src2) --> input pixd
 */
PIX *
pixMinOrMax(PIX     *pixd,
            PIX     *pixs1,
            PIX     *pixs2,
            l_int32  type)
{
l_int32    d, ws, hs, w, h, wpls, wpld, i, j, vals, vald, val;
l_int32    rval1, gval1, bval1, rval2, gval2, bval2, rval, gval, bval;
l_uint32  *datas, *datad, *lines, *lined;

    PROCNAME("pixMinOrMax");

    if (!pixs1)
        return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
    if (!pixs2)
        return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
    if (pixs1 == pixs2)
        return (PIX *)ERROR_PTR("pixs1 and pixs2 must differ", procName, pixd);
    if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX)
        return (PIX *)ERROR_PTR("invalid type", procName, pixd);
    d = pixGetDepth(pixs1);
    if (pixGetDepth(pixs2) != d)
        return (PIX *)ERROR_PTR("depths unequal", procName, pixd);
    if (d != 8 && d != 16 && d != 32)
        return (PIX *)ERROR_PTR("depth not 8, 16 or 32 bpp", procName, pixd);

    if (pixs1 != pixd)
        pixd = pixCopy(pixd, pixs1);

    pixGetDimensions(pixs2, &ws, &hs, NULL);
    pixGetDimensions(pixd, &w, &h, NULL);
    w = L_MIN(w, ws);
    h = L_MIN(h, hs);
    datas = pixGetData(pixs2);
    datad = pixGetData(pixd);
    wpls = pixGetWpl(pixs2);
    wpld = pixGetWpl(pixd);
    for (i = 0; i < h; i++) {
        lines = datas + i * wpls;
        lined = datad + i * wpld;
        if (d == 8) {
            for (j = 0; j < w; j++) {
                vals = GET_DATA_BYTE(lines, j);
                vald = GET_DATA_BYTE(lined, j);
                if (type == L_CHOOSE_MIN)
                    val = L_MIN(vals, vald);
                else  /* type == L_CHOOSE_MAX */
                    val = L_MAX(vals, vald);
                SET_DATA_BYTE(lined, j, val);
            }
        } else if (d == 16) {
            for (j = 0; j < w; j++) {
                vals = GET_DATA_TWO_BYTES(lines, j);
                vald = GET_DATA_TWO_BYTES(lined, j);
                if (type == L_CHOOSE_MIN)
                    val = L_MIN(vals, vald);
                else  /* type == L_CHOOSE_MAX */
                    val = L_MAX(vals, vald);
                SET_DATA_TWO_BYTES(lined, j, val);
            }
        } else {  /* d == 32 */
            for (j = 0; j < w; j++) {
                extractRGBValues(lines[j], &rval1, &gval1, &bval1);
                extractRGBValues(lined[j], &rval2, &gval2, &bval2);
                if (type == L_CHOOSE_MIN) {
                    rval = L_MIN(rval1, rval2);
                    gval = L_MIN(gval1, gval2);
                    bval = L_MIN(bval1, bval2);
                } else {  /* type == L_CHOOSE_MAX */
                    rval = L_MAX(rval1, rval2);
                    gval = L_MAX(gval1, gval2);
                    bval = L_MAX(bval1, bval2);
                }
                composeRGBPixel(rval, gval, bval, lined + j);
            }
        }
    }

    return pixd;
}
Пример #12
0
/*!
 * \brief   pixWriteStreamPnm()
 *
 * \param[in]    fp file stream opened for write
 * \param[in]    pix
 * \return  0 if OK; 1 on error
 *
 * <pre>
 * Notes:
 *      (1) This writes "raw" packed format only:
 *          1 bpp --\> pbm (P4)
 *          2, 4, 8, 16 bpp, no colormap or grayscale colormap --\> pgm (P5)
 *          2, 4, 8 bpp with color-valued colormap, or rgb --\> rgb ppm (P6)
 *      (2) 24 bpp rgb are not supported in leptonica, but this will
 *          write them out as a packed array of bytes (3 to a pixel).
 * </pre>
 */
l_int32
pixWriteStreamPnm(FILE  *fp,
                  PIX   *pix)
{
l_uint8    val8;
l_uint8    pel[4];
l_uint16   val16;
l_int32    h, w, d, ds, i, j, wpls, bpl, filebpl, writeerror, maxval;
l_uint32  *pword, *datas, *lines;
PIX       *pixs;

    PROCNAME("pixWriteStreamPnm");

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

    pixGetDimensions(pix, &w, &h, &d);
    if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 24 && d != 32)
        return ERROR_INT("d not in {1,2,4,8,16,24,32}", procName, 1);

        /* If a colormap exists, remove and convert to grayscale or rgb */
    if (pixGetColormap(pix) != NULL)
        pixs = pixRemoveColormap(pix, REMOVE_CMAP_BASED_ON_SRC);
    else
        pixs = pixClone(pix);
    ds =  pixGetDepth(pixs);
    datas = pixGetData(pixs);
    wpls = pixGetWpl(pixs);

    writeerror = 0;
    if (ds == 1) {  /* binary */
        fprintf(fp, "P4\n# Raw PBM file written by leptonica "
                    "(www.leptonica.com)\n%d %d\n", w, h);

        bpl = (w + 7) / 8;
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            for (j = 0; j < bpl; j++) {
                val8 = GET_DATA_BYTE(lines, j);
                fwrite(&val8, 1, 1, fp);
            }
        }
    } else if (ds == 2 || ds == 4 || ds == 8 || ds == 16) {  /* grayscale */
        maxval = (1 << ds) - 1;
        fprintf(fp, "P5\n# Raw PGM file written by leptonica "
                    "(www.leptonica.com)\n%d %d\n%d\n", w, h, maxval);

        if (ds != 16) {
            for (i = 0; i < h; i++) {
                lines = datas + i * wpls;
                for (j = 0; j < w; j++) {
                    if (ds == 2)
                        val8 = GET_DATA_DIBIT(lines, j);
                    else if (ds == 4)
                        val8 = GET_DATA_QBIT(lines, j);
                    else  /* ds == 8 */
                        val8 = GET_DATA_BYTE(lines, j);
                    fwrite(&val8, 1, 1, fp);
                }
            }
        } else {  /* ds == 16 */
            for (i = 0; i < h; i++) {
                lines = datas + i * wpls;
                for (j = 0; j < w; j++) {
                    val16 = GET_DATA_TWO_BYTES(lines, j);
                    fwrite(&val16, 2, 1, fp);
                }
            }
        }
    } else {  /* rgb color */
        fprintf(fp, "P6\n# Raw PPM file written by leptonica "
                    "(www.leptonica.com)\n%d %d\n255\n", w, h);

        if (d == 24) {   /* packed, 3 bytes to a pixel */
            filebpl = 3 * w;
            for (i = 0; i < h; i++) {  /* write out each raster line */
                lines = datas + i * wpls;
                if (fwrite(lines, 1, filebpl, fp) != filebpl)
                    writeerror = 1;
            }
        } else {  /* 32 bpp rgb */
            for (i = 0; i < h; i++) {
                lines = datas + i * wpls;
                for (j = 0; j < wpls; j++) {
                    pword = lines + j;
                    pel[0] = GET_DATA_BYTE(pword, COLOR_RED);
                    pel[1] = GET_DATA_BYTE(pword, COLOR_GREEN);
                    pel[2] = GET_DATA_BYTE(pword, COLOR_BLUE);
                    if (fwrite(pel, 1, 3, fp) != 3)
                        writeerror = 1;
                }
            }
        }
    }

    pixDestroy(&pixs);
    if (writeerror)
        return ERROR_INT("image write fail", procName, 1);
    return 0;
}
Пример #13
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;
}
Пример #14
0
/*!
 *  pixConvertToDPix()
 *
 *      Input:  pix (1, 2, 4, 8, 16 or 32 bpp)
 *              ncomps (number of components: 3 for RGB, 1 otherwise)
 *              shiftflag (L_NO_SHIFTING or L_WITH_SHIFTING)
 *      Return: dpix, 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.
 *      (3) Set @shiftflag to L_WITH_SHIFTING to move the DC of the
 *          the DFT to the center of pix.
 */
DPIX *
pixConvertToDPix(PIX     *pixs,
                 l_int32  ncomps,
				 l_int32  shiftflag)
{
	l_int32     w, h, d;
	l_int32     i, j, val, wplt, wpld;
	l_uint32    uval;
	l_uint32   *datat, *linet;
	l_float64  *datad, *lined;
	PIX        *pixt;
	DPIX       *dpixd;
	
    PROCNAME("pixConvertToDPix");
	
    if (!pixs)
        return (DPIX *)ERROR_PTR("pixs not defined", procName, NULL);
	if (shiftflag != L_NO_SHIFTING && shiftflag != L_WITH_SHIFTING)
        return (DPIX *)ERROR_PTR("invalid shiftflag", 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 ((dpixd = dpixCreate(w, h)) == NULL)
        return (DPIX *)ERROR_PTR("dpixd not made", procName, NULL);
    datat = pixGetData(pixt);
    wplt = pixGetWpl(pixt);
    datad = dpixGetData(dpixd);
    wpld = dpixGetWpl(dpixd);
    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] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val;
            }
        }
        else if (d == 2) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_DIBIT(linet, j);
                lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val;
            }
        }
        else if (d == 4) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_QBIT(linet, j);
                lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val;
            }
        }
        else if (d == 8) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_BYTE(linet, j);
                lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val;
            }
        }
        else if (d == 16) {
            for (j = 0; j < w; j++) {
                val = GET_DATA_TWO_BYTES(linet, j);
                lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val;
            }
        }
        else if (d == 32) {
            for (j = 0; j < w; j++) {
                uval = GET_DATA_FOUR_BYTES(linet, j);
                lined[j] = shiftflag ? (l_float64)(uval * pow(-1, i + j)) : (l_float64)uval;
            }
        }
    }
	
    pixDestroy(&pixt);
    return dpixd;
}
Пример #15
0
/*!
 *  thresholdToValueLow()
 */
void
thresholdToValueLow(l_uint32  *datad,
                    l_int32    w,
                    l_int32    h,
                    l_int32    d,
                    l_int32    wpld,
                    l_int32    threshval,
                    l_int32    setval)
{
    l_int32    i, j, setabove;
    l_uint32  *lined;

    if (setval > threshval)
        setabove = TRUE;
    else
        setabove = FALSE;

    for (i = 0; i < h; i++) {
        lined = datad + i * wpld;
        if (setabove == TRUE) {
            if (d == 8) {
                for (j = 0; j < w; j++) {
                    if (GET_DATA_BYTE(lined, j) - threshval >= 0)
                        SET_DATA_BYTE(lined, j, setval);
                }
            }
            else if (d == 16) {
                for (j = 0; j < w; j++) {
                    if (GET_DATA_TWO_BYTES(lined, j) - threshval >= 0)
                        SET_DATA_TWO_BYTES(lined, j, setval);
                }
            }
            else {  /* d == 32 */
                for (j = 0; j < w; j++) {
                    if (*(lined + j) >= threshval)
                        *(lined + j) = setval;
                }
            }
        }
        else  { /* set if below or at threshold */
            if (d == 8) {
                for (j = 0; j < w; j++) {
                    if (GET_DATA_BYTE(lined, j) - threshval <= 0)
                        SET_DATA_BYTE(lined, j, setval);
                }
            }
            else if (d == 16) {
                for (j = 0; j < w; j++) {
                    if (GET_DATA_TWO_BYTES(lined, j) - threshval <= 0)
                        SET_DATA_TWO_BYTES(lined, j, setval);
                }
            }
            else {  /* d == 32 */
                for (j = 0; j < w; j++) {
                    if (*(lined + j) <= threshval)
                        *(lined + j) = setval;
                }
            }
        }
    }
    return;
}
Пример #16
0
/*!
 *  accumulateLow()
 */
void
accumulateLow(l_uint32  *datad,
              l_int32    w,
              l_int32    h,
              l_int32    wpld,
              l_uint32  *datas,
              l_int32    d,
              l_int32    wpls,
              l_int32    op)
{
    l_int32    i, j;
    l_uint32  *lines, *lined;

    switch (d)
    {
    case 1:
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            if (op == L_ARITH_ADD) {
                for (j = 0; j < w; j++)
                    lined[j] += GET_DATA_BIT(lines, j);
            }
            else {  /* op == L_ARITH_SUBTRACT */
                for (j = 0; j < w; j++)
                    lined[j] -= GET_DATA_BIT(lines, j);
            }
        }
        break;
    case 8:
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            if (op == L_ARITH_ADD) {
                for (j = 0; j < w; j++)
                    lined[j] += GET_DATA_BYTE(lines, j);
            }
            else {  /* op == L_ARITH_SUBTRACT */
                for (j = 0; j < w; j++)
                    lined[j] -= GET_DATA_BYTE(lines, j);
            }
        }
        break;
    case 16:
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            if (op == L_ARITH_ADD) {
                for (j = 0; j < w; j++)
                    lined[j] += GET_DATA_TWO_BYTES(lines, j);
            }
            else {  /* op == L_ARITH_SUBTRACT */
                for (j = 0; j < w; j++)
                    lined[j] -= GET_DATA_TWO_BYTES(lines, j);
            }
        }
        break;
    case 32:
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            if (op == L_ARITH_ADD) {
                for (j = 0; j < w; j++)
                    lined[j] += lines[j];
            }
            else {  /* op == L_ARITH_SUBTRACT */
                for (j = 0; j < w; j++)
                    lined[j] -= lines[j];
            }
        }
        break;
    }
    return;
}
/*!
 *  pixSubtractGray()
 *
 *      Input:  pixd (<optional>; this can be null, equal to pixs1, or
 *                    different from pixs1)
 *              pixs1 (can be == to pixd)
 *              pixs2
 *      Return: pixd always
 *
 *  Notes:
 *      (1) Arithmetic subtraction of two 8, 16 or 32 bpp images.
 *      (2) Source pixs2 is always subtracted from source pixs1.
 *      (3) Do explicit clipping to 0.
 *      (4) Alignment is to UL corner.
 *      (5) There are 3 cases.  The result can go to a new dest,
 *          in-place to pixs1, or to an existing input dest:
 *          (a) pixd == null   (src1 - src2) --> new pixd
 *          (b) pixd == pixs1  (src1 - src2) --> src1  (in-place)
 *          (d) pixd != pixs1  (src1 - src2) --> input pixd
 *      (6) pixs2 must be different from both pixd and pixs1.
 */
PIX *
pixSubtractGray(PIX  *pixd,
                PIX  *pixs1,
                PIX  *pixs2)
{
l_int32    i, j, w, h, ws, hs, d, wpls, wpld, val, diff;
l_uint32  *datas, *datad, *lines, *lined;

    PROCNAME("pixSubtractGray");

    if (!pixs1)
        return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
    if (!pixs2)
        return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
    if (pixs2 == pixs1)
        return (PIX *)ERROR_PTR("pixs2 and pixs1 must differ", procName, pixd);
    if (pixs2 == pixd)
        return (PIX *)ERROR_PTR("pixs2 and pixd must differ", procName, pixd);
    d = pixGetDepth(pixs1);
    if (d != 8 && d != 16 && d != 32)
        return (PIX *)ERROR_PTR("pix are not 8, 16 or 32 bpp", procName, pixd);
    if (pixGetDepth(pixs2) != d)
        return (PIX *)ERROR_PTR("depths differ (pixs1, pixs2)", procName, pixd);
    if (pixd && (pixGetDepth(pixd) != d))
        return (PIX *)ERROR_PTR("depths differ (pixs1, pixd)", procName, pixd);

    if (!pixSizesEqual(pixs1, pixs2))
        L_WARNING("pixs1 and pixs2 not equal in size\n", procName);
    if (pixd && !pixSizesEqual(pixs1, pixd))
        L_WARNING("pixs1 and pixd not equal in size\n", procName);

    if (pixs1 != pixd)
        pixd = pixCopy(pixd, pixs1);

        /* pixd - pixs2 ==> pixd  */
    datas = pixGetData(pixs2);
    datad = pixGetData(pixd);
    wpls = pixGetWpl(pixs2);
    wpld = pixGetWpl(pixd);
    pixGetDimensions(pixs2, &ws, &hs, NULL);
    pixGetDimensions(pixd, &w, &h, NULL);
    w = L_MIN(ws, w);
    h = L_MIN(hs, h);
    for (i = 0; i < h; i++) {
        lined = datad + i * wpld;
        lines = datas + i * wpls;
        if (d == 8) {
            for (j = 0; j < w; j++) {
                diff = GET_DATA_BYTE(lined, j) - GET_DATA_BYTE(lines, j);
                val = L_MAX(diff, 0);
                SET_DATA_BYTE(lined, j, val);
            }
        } else if (d == 16) {
            for (j = 0; j < w; j++) {
                diff = GET_DATA_TWO_BYTES(lined, j)
                       - GET_DATA_TWO_BYTES(lines, j);
                val = L_MAX(diff, 0);
                SET_DATA_TWO_BYTES(lined, j, val);
            }
        } else {  /* d == 32; no clipping */
            for (j = 0; j < w; j++)
                *(lined + j) -= *(lines + j);
        }
    }

    return pixd;
}
/*!
 *  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    i, j, w, h, d, wpld, setabove;
l_uint32  *datad, *lined;

    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\n", procName);
        return pixd;
    }

    datad = pixGetData(pixd);
    pixGetDimensions(pixd, &w, &h, NULL);
    wpld = pixGetWpl(pixd);
    if (setval > threshval)
        setabove = TRUE;
    else
        setabove = FALSE;

    for (i = 0; i < h; i++) {
        lined = datad + i * wpld;
        if (setabove == TRUE) {
            if (d == 8) {
                for (j = 0; j < w; j++) {
                    if (GET_DATA_BYTE(lined, j) - threshval >= 0)
                        SET_DATA_BYTE(lined, j, setval);
                }
            } else if (d == 16) {
                for (j = 0; j < w; j++) {
                    if (GET_DATA_TWO_BYTES(lined, j) - threshval >= 0)
                        SET_DATA_TWO_BYTES(lined, j, setval);
                }
            } else {  /* d == 32 */
                for (j = 0; j < w; j++) {
                    if (*(lined + j) >= threshval)
                        *(lined + j) = setval;
                }
            }
        } else { /* set if below or at threshold */
            if (d == 8) {
                for (j = 0; j < w; j++) {
                    if (GET_DATA_BYTE(lined, j) - threshval <= 0)
                        SET_DATA_BYTE(lined, j, setval);
                }
            } else if (d == 16) {
                for (j = 0; j < w; j++) {
                    if (GET_DATA_TWO_BYTES(lined, j) - threshval <= 0)
                        SET_DATA_TWO_BYTES(lined, j, setval);
                }
            } else {  /* d == 32 */
                for (j = 0; j < w; j++) {
                    if (*(lined + j) <= threshval)
                        *(lined + j) = setval;
                }
            }
        }
    }

    return pixd;
}
/*!
 *  pixAccumulate()
 *
 *      Input:  pixd (32 bpp)
 *              pixs (1, 8, 16 or 32 bpp)
 *              op  (L_ARITH_ADD or L_ARITH_SUBTRACT)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      (1) This adds or subtracts each pixs value from pixd.
 *      (2) This clips to the minimum of pixs and pixd, so they
 *          do not need to be the same size.
 *      (3) The alignment is to the origin (UL corner) of pixs & pixd.
 */
l_int32
pixAccumulate(PIX     *pixd,
              PIX     *pixs,
              l_int32  op)
{
l_int32    i, j, w, h, d, wd, hd, wpls, wpld;
l_uint32  *datas, *datad, *lines, *lined;


    PROCNAME("pixAccumulate");

    if (!pixd || (pixGetDepth(pixd) != 32))
        return ERROR_INT("pixd not defined or not 32 bpp", procName, 1);
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    d = pixGetDepth(pixs);
    if (d != 1 && d != 8 && d != 16 && d != 32)
        return ERROR_INT("pixs not 1, 8, 16 or 32 bpp", procName, 1);
    if (op != L_ARITH_ADD && op != L_ARITH_SUBTRACT)
        return ERROR_INT("op must be in {L_ARITH_ADD, L_ARITH_SUBTRACT}",
                         procName, 1);

    datas = pixGetData(pixs);
    datad = pixGetData(pixd);
    wpls = pixGetWpl(pixs);
    wpld = pixGetWpl(pixd);
    pixGetDimensions(pixs, &w, &h, NULL);
    pixGetDimensions(pixd, &wd, &hd, NULL);
    w = L_MIN(w, wd);
    h = L_MIN(h, hd);
    if (d == 1) {
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            if (op == L_ARITH_ADD) {
                for (j = 0; j < w; j++)
                    lined[j] += GET_DATA_BIT(lines, j);
            } else {  /* op == L_ARITH_SUBTRACT */
                for (j = 0; j < w; j++)
                    lined[j] -= GET_DATA_BIT(lines, j);
            }
        }
    } else if (d == 8) {
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            if (op == L_ARITH_ADD) {
                for (j = 0; j < w; j++)
                    lined[j] += GET_DATA_BYTE(lines, j);
            } else {  /* op == L_ARITH_SUBTRACT */
                for (j = 0; j < w; j++)
                    lined[j] -= GET_DATA_BYTE(lines, j);
            }
        }
    } else if (d == 16) {
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            if (op == L_ARITH_ADD) {
                for (j = 0; j < w; j++)
                    lined[j] += GET_DATA_TWO_BYTES(lines, j);
            } else {  /* op == L_ARITH_SUBTRACT */
                for (j = 0; j < w; j++)
                    lined[j] -= GET_DATA_TWO_BYTES(lines, j);
            }
        }
    } else {  /* d == 32 */
        for (i = 0; i < h; i++) {
            lines = datas + i * wpls;
            lined = datad + i * wpld;
            if (op == L_ARITH_ADD) {
                for (j = 0; j < w; j++)
                    lined[j] += lines[j];
            } else {  /* op == L_ARITH_SUBTRACT */
                for (j = 0; j < w; j++)
                    lined[j] -= lines[j];
            }
        }
    }

    return 0;
}
Пример #20
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);
}
Пример #21
0
/*!
 *  pixRotateBySampling()
 *
 *      Input:  pixs (1, 2, 4, 8, 16, 32 bpp rgb; can be cmapped)
 *              xcen (x value of center of rotation)
 *              ycen (y value of center of rotation)
 *              angle (radians; clockwise is positive)
 *              incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) For very small rotations, just return a clone.
 *      (2) Rotation brings either white or black pixels in
 *          from outside the image.
 *      (3) Colormaps are retained.
 */
PIX *
pixRotateBySampling(PIX *pixs,
                    l_int32 xcen,
                    l_int32 ycen,
                    l_float32 angle,
                    l_int32 incolor) {
    l_int32 w, h, d, i, j, x, y, xdif, ydif, wm1, hm1, wpld;
    l_uint32 val;
    l_float32 sina, cosa;
    l_uint32 *datad, *lined;
    void **lines;
    PIX *pixd;

    PROCNAME("pixRotateBySampling");

    if (!pixs)
        return (PIX *) ERROR_PTR("pixs not defined", procName, NULL);
    if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
        return (PIX *) ERROR_PTR("invalid incolor", procName, NULL);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
        return (PIX *) ERROR_PTR("invalid depth", procName, NULL);

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

    if ((pixd = pixCreateTemplateNoInit(pixs)) == NULL)
        return (PIX *) ERROR_PTR("pixd not made", procName, NULL);
    pixSetBlackOrWhite(pixd, incolor);

    sina = sin(angle);
    cosa = cos(angle);
    datad = pixGetData(pixd);
    wpld = pixGetWpl(pixd);
    wm1 = w - 1;
    hm1 = h - 1;
    lines = pixGetLinePtrs(pixs, NULL);

    /* Treat 1 bpp case specially */
    if (d == 1) {
        for (i = 0; i < h; i++) {  /* scan over pixd */
            lined = datad + i * wpld;
            ydif = ycen - i;
            for (j = 0; j < w; j++) {
                xdif = xcen - j;
                x = xcen + (l_int32)(-xdif * cosa - ydif * sina);
                if (x < 0 || x > wm1) continue;
                y = ycen + (l_int32)(-ydif * cosa + xdif * sina);
                if (y < 0 || y > hm1) continue;
                if (incolor == L_BRING_IN_WHITE) {
                    if (GET_DATA_BIT(lines[y], x))
                        SET_DATA_BIT(lined, j);
                } else {
                    if (!GET_DATA_BIT(lines[y], x))
                        CLEAR_DATA_BIT(lined, j);
                }
            }
        }
        FREE(lines);
        return pixd;
    }

    for (i = 0; i < h; i++) {  /* scan over pixd */
        lined = datad + i * wpld;
        ydif = ycen - i;
        for (j = 0; j < w; j++) {
            xdif = xcen - j;
            x = xcen + (l_int32)(-xdif * cosa - ydif * sina);
            if (x < 0 || x > wm1) continue;
            y = ycen + (l_int32)(-ydif * cosa + xdif * sina);
            if (y < 0 || y > hm1) continue;
            switch (d) {
                case 8:
                    val = GET_DATA_BYTE(lines[y], x);
                    SET_DATA_BYTE(lined, j, val);
                    break;
                case 32:
                    val = GET_DATA_FOUR_BYTES(lines[y], x);
                    SET_DATA_FOUR_BYTES(lined, j, val);
                    break;
                case 2:
                    val = GET_DATA_DIBIT(lines[y], x);
                    SET_DATA_DIBIT(lined, j, val);
                    break;
                case 4:
                    val = GET_DATA_QBIT(lines[y], x);
                    SET_DATA_QBIT(lined, j, val);
                    break;
                case 16:
                    val = GET_DATA_TWO_BYTES(lines[y], x);
                    SET_DATA_TWO_BYTES(lined, j, val);
                    break;
                default:
                    return (PIX *) ERROR_PTR("invalid depth", procName, NULL);
            }
        }
    }

    FREE(lines);
    return pixd;
}