image-rs / jpeg-decoder

JPEG decoder written in Rust
Apache License 2.0
147 stars 88 forks source link

question: exif support? #42

Open liamstask opened 8 years ago

liamstask commented 8 years ago

I've been doing some testing with this library, which seems great, and have a couple questions:

kaksmet commented 8 years ago

It would be great to receive a PR for getting exif data. Exposing a Vec<u8> sounds good to me, I have plans to do the same with embedded icc profiles.

As for your other question, do you only want to change the exif data segment or do you also need to reencode the image?

liamstask commented 8 years ago

thanks for the quick response. and great - i will try to put a PR together and submit it.

for the 2nd question, yes I'd only want to modify the exif segment, and then write it back out along with the unmodified image data.

kaksmet commented 8 years ago

For just modifying the exif data, I would split the file at the beginning and end of the exif data segment and then just swap in the modified exif data.

However if you only change the values in the exif data and don't add/remove anything you could just modify it in-place.

liamstask commented 8 years ago

Hm, the issues I see in that case are:

kaksmet commented 8 years ago

the decoder interface would need to return the offsets for the exif data, in addition to the Vec of the data itself - maybe this is OK?

The easiest way to find the offset of a JPEG segment is to use something like immeta's find_marker function, searching for a APP1 marker (which has a value of 0xE1). Right at the start of the segment is it's length as a big-endian u16 (which includes the size of itself, so you'll want to subtract 2 from it).

in order to write the exif segment back out, my application code would need to know the format/layout of a jpeg segment. I suppose application code can do that, but would be better handled by a jpeg encoder lib, if possible.

To start a APP1 segment (which is used to store exif data) you write 0xFF, 0xE1, followed by the data length as a big-endian u16. Then you just append your exif data.

https://www.media.mit.edu/pia/Research/deepview/exif.html is a great resource for understanding how exif is stored in a JPEG file.

liamstask commented 8 years ago

In terms of find_marker(), the issue is not finding the marker, but rather that it would be wasteful for user code to search for the marker again, since it would have already been discovered in parse_app(). It would be preferable to return the offset here if possible, to avoid searching again from the beginning.

And as I mentioned previously, it would be no problem for application code to create a jpeg segment, just that it's a bit of a layering mismatch. I'll probably just stick with that for now, though - thanks :)

lovasoa commented 4 years ago

related: https://github.com/image-rs/image/issues/1045