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?