0

I can see it is possible to load and write JPEG metadata via libjpeg C API.

However, it is asynchronous. Any good approach to simply copy JPEG metadata from source JPEG to destination JPEG?

This is how I would approach it. But it looks a bit clumsy to me.

j_compress_ptr cinfo_out; // global variable

// basically getchar() on JPEG
int jpeg_getc(j_decompress_ptr cinfo) {
    struct jpeg_source_mgr *datasrc = cinfo->src;
    // no bytes in buffer
    if (datasrc->bytes_in_buffer == 0) {
        if (!(*datasrc->fill_input_buffer)(cinfo))
            return -1; // return error
    }
    // read char
    datasrc->bytes_in_buffer--;
    return GETJOCTET(*datasrc->next_input_byte++);
}

// called asynchronously during libjpeg decompression
int jpeg_handle_marker(j_decompress_ptr cinfo_in) {

    // get length
    int length = (jpeg_getc(cinfo) << 8) + jpeg_getc(cinfo) - 2;

    // copy
    unsigned char *p = new unsigned char[length + 1];
    int c, i = 0;
    while (i < length) {
        if ((c = jpeg_getc(cinfo)) == -1) return FALSE;
        p[i++] = (unsigned char)c;
    }
    p[length] = 0; // last byte to 0

    // write markers
    int offset = 0;
    for (int i = 0; i < num_markers; i++) {
        jpeg_write_marker(
            cinfo_out,
            cinfo_in->unread_marker,
            (const JOCTET *)p,
            length
        );
    }
    return TRUE;
}

// setup asynchronous routines
void set_marker_handlers(j_decompress_ptr cinfo_in) {
    jpeg_set_marker_processor(cinfo_in, JPEG_COM, jpeg_handle_marker);
    for (int i = 0; i <= 15; i++)
        jpeg_set_marker_processor(cinfo_in, JPEG_APP0+i, jpeg_handle_marker);
}

Does anybody have a better idea?

Martin Benes
  • 265
  • 10

0 Answers0