Esempio n. 1
0
MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_bitmap_crop
    (mdjvu_bitmap_t b, int32 left, int32 top, int32 w, int32 h)
{
    if (left == 0 && top == 0 && w == BMP->width && h == BMP->height)
    {
        return mdjvu_bitmap_clone(b);
    }
    else
    {
        mdjvu_bitmap_t result;
        int32 i = top, count = h;
        unsigned char *buf;

        assert(left >= 0);
        assert(left + w <= BMP->width);
        assert(top >= 0);
        assert(top + h <= BMP->height);

        result = mdjvu_bitmap_create(w, h);
        buf = (unsigned char *) malloc(BMP->width);
        while (count--)
        {
            mdjvu_bitmap_unpack_row(b, buf, i);
            mdjvu_bitmap_pack_row(result, buf + left, i - top);
            i++;
        }
        free(buf);
        return result;
    }
}
Esempio n. 2
0
MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_bitmap_clone(mdjvu_bitmap_t b)
{
    mdjvu_bitmap_t result = mdjvu_bitmap_create(BMP->width, BMP->height);

    /* Using the fact that the 2d arrays by 2d_array() are really 1d ones */
    memcpy(((Bitmap *) result)->data[0], BMP->data[0], ROW_SIZE * BMP->height);
    return result;
}
Esempio n. 3
0
/* This function does the same as interpret_runs_in_a_line(),
 *    but on a rectangle.
 * Returns the rendered result.
 * Also clears it in pixels[][].
 * `map' is cleared.
 */
static mdjvu_bitmap_t interpret_runs(int32 min_x, int32 max_x,
                                     int32 min_y, int32 max_y,
                                     unsigned char **map,
                                     unsigned char **pixels)
{
    int32 w = max_x - min_x + 1;
    int32 h = max_y - min_y + 1;
    unsigned char *line_buf = (unsigned char *) malloc(w);
    mdjvu_bitmap_t bmp = mdjvu_bitmap_create(w, h);
    int32 y;
    for (y = min_y; y <= max_y; y++)
    {
        interpret_runs_in_a_line(min_x, max_x, map[y], line_buf, pixels[y]);
        mdjvu_bitmap_pack_row(bmp, line_buf, y - min_y);
    }
    free(line_buf);
    return bmp;
}
Esempio n. 4
0
MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_get_erosion_mask(mdjvu_bitmap_t bmp)
{
    int32 w = mdjvu_bitmap_get_width(bmp);
    int32 h = mdjvu_bitmap_get_height(bmp);
    mdjvu_bitmap_t result = mdjvu_bitmap_create(w, h);
    int32 i;
    unsigned char *u, *t, *l, *r;

    if (h < 3) return result;

    u = (unsigned char *) malloc(w); /* upper row */
    t = (unsigned char *) malloc(w); /* this row */
    l = (unsigned char *) malloc(w); /* lower row */
    r = (unsigned char *) malloc(w); /* result */

    mdjvu_bitmap_unpack_row_0_or_1(bmp, t, 0);
    mdjvu_bitmap_unpack_row_0_or_1(bmp, l, 1);
    for (i = 1; i < h - 1; i++)
    {
        unsigned char *tmp = u;
        u = t;
        t = l;
        l = tmp;

        mdjvu_bitmap_unpack_row_0_or_1(bmp, l, i + 1);

        get_erosion_candidates_in_a_row(r, u, t, l, w);
        mdjvu_bitmap_pack_row(result, r, i);
    }

    free(u);
    free(t);
    free(l);
    free(r);

    return result;
}
Esempio n. 5
0
static mdjvu_bitmap_t load_tiff(const char *path, int32 *presolution, mdjvu_error_t *perr, uint32 idx)
{
    uint16 photometric;
    uint32 w, h;
    uint16 bits_per_sample = 0, samples_per_pixel = 0;
    float dpi;
    mdjvu_bitmap_t result;
    tsize_t scanline_size;
    unsigned char *scanline;
    uint32 i;

    TIFF *tiff = TIFFOpen(path, "r");
    for ( i=0; tiff != NULL && i<idx; i++ )
    {
        if (!TIFFReadDirectory(tiff))
            break;
    }

    *perr = NULL;
    if (!tiff || i<idx)
    {
        *perr = mdjvu_get_error(mdjvu_error_fopen_read);
        return NULL;
    }

    /* test if bitonal */
    TIFFGetFieldDefaulted(tiff, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
    TIFFGetFieldDefaulted(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
    if (bits_per_sample != 1 || samples_per_pixel != 1)
    {
        *perr = mdjvu_get_error(mdjvu_error_corrupted_tiff);
        TIFFClose(tiff);
        return NULL;
    }

    /* photometric */
    photometric = PHOTOMETRIC_MINISWHITE;
    TIFFGetFieldDefaulted(tiff, TIFFTAG_PHOTOMETRIC, &photometric);

    /* image size */
    if (!TIFFGetFieldDefaulted(tiff, TIFFTAG_IMAGEWIDTH, &w)
     || !TIFFGetFieldDefaulted(tiff, TIFFTAG_IMAGELENGTH, &h))
    {
        *perr = mdjvu_get_error(mdjvu_error_corrupted_tiff);
        TIFFClose(tiff);
        return NULL;
    }

    /* get the resolution */
    if (presolution && TIFFGetFieldDefaulted(tiff, TIFFTAG_XRESOLUTION, &dpi))
    {
        *presolution = (int32) dpi;
    }

    result = mdjvu_bitmap_create(w, h);

    scanline_size = TIFFScanlineSize(tiff);

    if (scanline_size < mdjvu_bitmap_get_packed_row_size(result))
    {
        *perr = mdjvu_get_error(mdjvu_error_corrupted_tiff);
        TIFFClose(tiff);
        mdjvu_bitmap_destroy(result);
        return NULL;
    }

    scanline = (unsigned char *) malloc(scanline_size);

    for (i = 0; i < h; i++)
    {
        if (TIFFReadScanline(tiff, (tdata_t)scanline, i, 0) < 0)
        {
            *perr = mdjvu_get_error(mdjvu_error_corrupted_tiff);
            TIFFClose(tiff);
            free(scanline);
            mdjvu_bitmap_destroy(result);
            return NULL;
        }

        if (photometric != PHOTOMETRIC_MINISWHITE)
        {
            /* invert the row */
            int32 k;
            int32 s = (int32) scanline_size;
            for (k = 0; k < s; k++)
                scanline[k] = ~scanline[k];
        }

        /* clear the padding bits */
        if (scanline_size & 7)
            scanline[scanline_size - 1] &= ~(0xFF >> (scanline_size & 7));

        memcpy(mdjvu_bitmap_access_packed_row(result, i),
               scanline,
               mdjvu_bitmap_get_packed_row_size(result));
    }

    free(scanline);

    TIFFClose(tiff);
    return result;
}
Esempio n. 6
0
MDJVU_IMPLEMENT mdjvu_bitmap_t mdjvu_average(mdjvu_bitmap_t *bitmaps,
                                             int32 n,
                                             int32 *cx, int32 *cy)
{
    int32 i;
    int32 min_x = 0, min_y = 0, max_x_plus_1 = 0, max_y_plus_1 = 0;
    int32 *buf;
    int32 buf_w, buf_h;
    unsigned char *row;
    int32 tmp_x, tmp_y;
    int32 threshold = n / 2;
    mdjvu_bitmap_t result;

    if (n == 1)
    {
        return mdjvu_bitmap_clone(bitmaps[0]);
    }

    for (i = 0; i < n; i++)
    {
        int32 w = mdjvu_bitmap_get_width(bitmaps[i]);
        int32 h = mdjvu_bitmap_get_height(bitmaps[i]);
        int32 ncx = cx[i] / MDJVU_CENTER_QUANT;
        int32 ncy = cy[i] / MDJVU_CENTER_QUANT;
        
        assert(ncx >= 0 && ncx < w);
        assert(ncy >= 0 && ncy < h);

        if (-ncx < min_x) min_x = -ncx;
        if (-ncy < min_y) min_y = -ncy;
        if (w-ncx > max_x_plus_1) max_x_plus_1 = w-ncx;
        if (h-ncy > max_y_plus_1) max_y_plus_1 = h-ncy;
    }

    buf_w = max_x_plus_1 - min_x;
    buf_h = max_y_plus_1 - min_y;
    buf = (int32 *) calloc(buf_w * buf_h, sizeof(int32));
    row = (unsigned char *) malloc(buf_w);

    /* Now adding the bitmaps to the buffer */
    for (i = 0; i < n; i++)
    {
        int32 w = mdjvu_bitmap_get_width(bitmaps[i]);
        int32 h = mdjvu_bitmap_get_height(bitmaps[i]);
        int32 sx = min_x + cx[i] / MDJVU_CENTER_QUANT, sy = min_y + cy[i] / MDJVU_CENTER_QUANT;
        int32 x, y;

        for (y = 0; y < h; y++)
        {
            int32 *buf_row = buf + buf_w * (y - sy);
            mdjvu_bitmap_unpack_row(bitmaps[i], row, y);
            for (x = 0; x < w; x++)
            {
                if (row[x])
                    buf_row[x - sx]++;
            }
        }
    }

    result = mdjvu_bitmap_create(buf_w, buf_h);
    for (i = 0; i < buf_h; i++)
    {
        int32 j;
        for (j = 0; j < buf_w; j++)
        {
            row[j] = ( buf[i * buf_w + j] > threshold ? 1 : 0 );
        }
        mdjvu_bitmap_pack_row(result, row, i);
    }

    mdjvu_bitmap_remove_margins(result, &tmp_x, &tmp_y);

    free(row);
    free(buf);

    return result;
}