Marcin Zablocki Marcin Zablocki - 1 month ago 15
C Question

libccv - how to read image from bytes in memory

I'm trying to use libccv with Python (I've created wrapper using SWIG). My scenario is the following:


  1. I have in-memory image

  2. I want to pass this image (bytes) to C function, wrapped for Python with SWIG.

  3. C code will process the image with
    libccv
    functions



Python code:

bytes = open("input.jpg","rb").read()
result = ccvwrapper.use_ccv(bytes, 800, 600)


C code:

int use_ccv(char *bytes, int width, int height){
int status = 0;
ccv_enable_default_cache();
ccv_dense_matrix_t* image = 0;
ccv_read(bytes, &image, CCV_IO_ANY_RAW, width, height, width * 3);

if (image != 0)
{
//process the image
ccv_matrix_free(image);
status = 1;
}
ccv_drain_cache();

return status;
}


I've tried a few combinations of
type, rows, cols, scanline
parameters of
ccv_read
but every time I got either SIGSEV or the
image
variable was
0
.

I don't want to use
ccv_read
function overload, which takes file path, because I don't want to introduce overhead of writing the image to disk.

What is the proper way of reading the image from memory using libccv?

Answer Source

I've figured it out, the trick was to use fmemopen() function, to open memory as stream, which further can be read by APIs, which accept FILE* pointers.

Full code:

int* swt(char *bytes, int array_length, int width, int height){
    ccv_dense_matrix_t* image = 0;

    FILE *stream;
    stream = fmemopen(bytes, array_length, "r");
    if(stream != NULL){
        int type = CCV_IO_JPEG_FILE | CCV_IO_GRAY;
        int ctype = (type & 0xF00) ? CCV_8U | ((type & 0xF00) >> 8) : 0;
        _ccv_read_jpeg_fd(stream, &image, ctype);
    }
    if (image != 0){
       // here we have access to image in libccv format, so any processing can be done
    }
}

Usage from Python (after building the C code with SWIG):

import ccvwrapper
bytes = open("test_input.jpg", "rb").read()
results = ccvwrapper.swt(bytes, len(bytes), 1024, 1360) # width:1024, height:1360

I've explained all of the details in a blog post: http://zablo.net/blog/post/stroke-width-transform-swt-python