jacklicn / leptonica

Automatically exported from code.google.com/p/leptonica
0 stars 0 forks source link

Support reading BMP files from FIFO like streams #84

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Currently the only thing preventing BMP files from being read from pipes is the 
use of fseek to seek to the start of the image data. The attached patch 
implements two new functions in utils.c: l_isFIFO and l_skipBytes for 
respectively detecting whether a stream is non-seekable and skipping a number 
of bytes even for non-seekable streams.

Original issue reported on code.google.com by poiza...@gmail.com on 24 Sep 2013 at 1:22

Attachments:

GoogleCodeExporter commented 9 years ago
Version of patch with more sensical paths in diff.

Another thing is that I wasn't sure about which convention to use for boolean 
types - I have just used int as the type. Also I wasn't sure about the naming 
convention to use for function names, is there any rule for when the l_ prefix 
is used?

Original comment by poiza...@gmail.com on 24 Sep 2013 at 1:37

Attachments:

GoogleCodeExporter commented 9 years ago
... and without tabs

Original comment by poiza...@gmail.com on 25 Sep 2013 at 12:35

Attachments:

GoogleCodeExporter commented 9 years ago
Thank you for this patch.  As an alternative approach, I recently added a 
function to bbuffer.c.  Can this be used to do what you want with BMP file 
reading?

/*!
 *  bbufferReadStdin()
 *
 *      Input:  &data (<return> binary data read in)
 *              &nbytes (<return>)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      (1) This can be used to capture data piped in from stdin.
 *          For example, you can read an image from stdin into memory
 *          using shell redirection, with one of these:
 *             cat <imagefile> | readprog
 *             readprog < <imagefile>
 *          where readprog is:
 *             bbufferReadStdin(&data, &nbytes);  // l_uint8*, size_t
 *             Pix *pix = pixReadMem(data, nbytes);
 */
l_int32
bbufferReadStdin(l_uint8  **pdata,
                 size_t    *pnbytes)
{
l_int32   navail, nadd, nread;
BBUFFER  *bb;

    PROCNAME("bbufferReadStdin");

    if (!pdata)
        return ERROR_INT("&data not defined", procName, 1);
    if (!pnbytes)
        return ERROR_INT("&nbytes not defined", procName, 1);

    bb = bbufferCreate(NULL, 4096);
    while (1) {
        navail = bb->nalloc - bb->n;
        if (navail < 4096) {
             nadd = L_MAX(bb->nalloc, 4096);
             bbufferExtendArray(bb, nadd);
        }
        nread = fread((void *)(bb->array + bb->n), 1, 4096, stdin);
        bb->n += nread;
        if (nread != 4096) break;
    }

    *pdata = bb->array;
    *pnbytes = bb->n;
    bb->array = NULL;
    bbufferDestroy(&bb);
    return 0;
}

Original comment by dan.bloo...@gmail.com on 4 Oct 2013 at 10:03

GoogleCodeExporter commented 9 years ago
Also, with respect to naming conventions, the l_ prefix is not used in a 
systematic way.  Generally, I use it for static functions not used outside the 
file, and for avoiding name collisions (e.g., L_BYTEA, L_DNA, l_BinaryRead()).

I wrote a syntax guide for leptonica developers and will try to find it, but 
you seem to have figured it out already.

Original comment by dan.bloo...@gmail.com on 4 Oct 2013 at 10:24

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Reading it to memory won't help much as leptonica currently can't read bmp 
files from memory on Windows. Also i'm working with some very large images 
(houndreds of MB), so:
1. virtual address space exhaustion is a big problem (unfortunately it has to 
run on 32 bit), so it's not always possible to keep more than one decompressed 
copy of the images in question in memory at a time.
2. making copies of the data takes a non-negligible amount of time.

Original comment by poiza...@gmail.com on 7 Oct 2013 at 12:02

GoogleCodeExporter commented 9 years ago
Oh btw. I just realized that I had left a debug statement behind. The fprint at 
line 110 wasn't supposed to be left in:

fprintf(stderr, "Actual fseek error code: %d\n", fseek(fp, 0, SEEK_END));

Original comment by poiza...@gmail.com on 15 Oct 2013 at 12:55

GoogleCodeExporter commented 9 years ago
1.70 is out.  You can get it at leptonica.org/download.html

A Pix can now be made from (data, nbytes) of bmp encoded (but not compressed) 
data.  So if you must read the bmp data from a pipe, you can call 
bbufferReadStdin() followed by pixReadMemBmp().  In your case, with large 
files, you may want to slightly modify pixReadMemBmp() to delete the data after 
writing to a tempfile and before reading back, so that you don't have 2 copies 
in memory at any time.

Original comment by dan.bloo...@gmail.com on 23 Jan 2014 at 9:59