Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem to copy exif data of image made with Canon EOS 650D #2

Open
chriamue opened this issue May 25, 2021 · 4 comments
Open

Problem to copy exif data of image made with Canon EOS 650D #2

chriamue opened this issue May 25, 2021 · 4 comments

Comments

@chriamue
Copy link

While trying to integrate img-parts into my project I observed a problem processing images of one camera.
In the following example I take the image
IMG_0818
extract the exif data and save it to large.jpg.

I observe the tool, which is based on libexif

exif -v
0.6.21

reports the exif data is corrupt.

exif large.jpg
Corrupt data
The data provided does not follow the specification.
ExifLoader: The data supplied does not seem to contain EXIF data.

Also many other programs like filebrowser nemo can not view the exif data.
The tool exiftool still can read the exif data.

exiftool large.jpg
ExifTool Version Number         : 11.88
File Name                       : large.jpg
Directory                       : .
File Size                       : 5.9 MB
File Modification Date/Time     : 2021:05:25 06:57:57+02:00
File Access Date/Time           : 2021:05:25 06:57:59+02:00
File Inode Change Date/Time     : 2021:05:25 06:57:57+02:00
File Permissions                : rw-rw-r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
Rating                          : 0
Image Width                     : 5184
Image Height                    : 3456
...

If I use the image https://github.com/paolobarbolini/img-parts/blob/main/tests/images/P1133897_sRGB.jpg as
source for the image data or the other way around as source for the exif data,
the resulting images are both readable with exif.

Here is the code with Cargo.toml dependencies: img-parts = { git = "https://github.com/paolobarbolini/img-parts"}

#[cfg(test)]
mod tests {
    use img_parts::jpeg::Jpeg;
    use img_parts::{ImageEXIF, ImageICC};

    #[test]
    fn large_jpg() {
        replace_exif(
            "IMG_0818.JPG".into(),
            "IMG_0818.JPG".into(),
            "large.jpg".into(),
        );
    }

    #[test]
    fn normal_large_jpg() {
        replace_exif(
            "P1133897_sRGB.jpg".into(),
            "IMG_3911.JPG".into(),
            "normal_large.jpg".into(),
        );
    }

    #[test]
    fn large_normal_jpg() {
        replace_exif(
            "IMG_3911.JPG".into(),
            "P1133897_sRGB.jpg".into(),
            "large_normal.jpg".into(),
        );
    }

    fn replace_exif(image: String, exif_image: String, out_file: String) {
        let buf = std::fs::read(image).expect("image read");
        let buf_exif = std::fs::read(exif_image).expect("image read");
        let (iccp, exif) = img_parts::DynImage::from_bytes(buf_exif.clone().into())
            .expect("image loaded")
            .map_or((None, None), |dimg| (dimg.icc_profile(), dimg.exif()));
        let mut out_file = std::fs::File::create(out_file).expect("create output file");

        let mut jpeg = Jpeg::from_bytes(buf.into()).unwrap();
        jpeg.set_icc_profile(iccp);
        jpeg.set_exif(Some(exif.unwrap()));
        jpeg.encoder().write_to(&mut out_file).unwrap();
    }
}
@chriamue
Copy link
Author

chriamue commented May 26, 2021

Same problem when I run the example:

examples/image-rs$ cargo run IMG_0818.JPG out.jpg
examples/image-rs$ exif out.jpg
Corrupt data
The data provided does not follow the specification.
ExifLoader: The data supplied does not seem to contain EXIF data.

Here is a diff made with exiftool:

img-parts/examples/image-rs$ exiftool IMG_0818.JPG > img.txt
img-parts/examples/image-rs$ exiftool out.jpg > out.txt
img-parts/examples/image-rs$ diff img.txt out.txt
2c2
< File Name                       : IMG_0818.JPG
---
> File Name                       : out.jpg
4,7c4,7
< File Size                       : 5.9 MB
< File Modification Date/Time     : 2021:05:26 12:16:06+02:00
< File Access Date/Time           : 2021:05:26 12:16:42+02:00
< File Inode Change Date/Time     : 2021:05:26 12:16:06+02:00
---
> File Size                       : 36 kB
> File Modification Date/Time     : 2021:05:26 12:17:27+02:00
> File Access Date/Time           : 2021:05:26 12:18:16+02:00
> File Inode Change Date/Time     : 2021:05:26 12:17:27+02:00
11a12,18
> JFIF Version                    : 1.02
> Image Width                     : 256
> Image Height                    : 170
> Encoding Process                : Baseline DCT, Huffman coding
> Bits Per Sample                 : 8
> Color Components                : 3
> Y Cb Cr Sub Sampling            : YCbCr4:4:4 (1 1)
286c293
< Thumbnail Offset                : 10936
---
> Thumbnail Offset                : 11042
288,294d294
< Rating                          : 0
< Image Width                     : 5184
< Image Height                    : 3456
< Encoding Process                : Baseline DCT, Huffman coding
< Bits Per Sample                 : 8
< Color Components                : 3
< Y Cb Cr Sub Sampling            : YCbCr4:2:2 (2 1)
302c302
< Image Size                      : 5184x3456
---
> Image Size                      : 256x170
304c304
< Megapixels                      : 17.9
---
> Megapixels                      : 0.044

I just see 'JFIF Version' Tag is new and 'Thumbnail Offset' and 'Y Cb Cr Sub Sampling' changed.

@paolobarbolini
Copy link
Owner

Thanks for the issue. I haven't yet had time to look into this. I hope to get to it this weekend.

@chriamue
Copy link
Author

Hi, thank you for the response. Libexif could make a fix, I can read the exif data in the images now.
It looks like the image data is stored before the exif data, which is not very common.
libexif/libexif#67 (comment)

@paolobarbolini
Copy link
Owner

paolobarbolini commented Jun 4, 2021

I think I found the issue. Your jpeg contains two EXIF segments, which should be concatenated before reading. This can be seen by running

cargo run --example list-chunks 119443336-bc932200-bd29-11eb-94bf-0fc4b6aea471.JPG 

---------------------------------
| i   | marker | total length |
---------------------------------
| 0   | E1     | 25434        |
| 1   | E1     | 2562         |
| 2   | DB     | 134          |
| 3   | C0     | 19           |
| 4   | C4     | 420          |
| 5   | DA     | 6144145      |

I had already implemented this kind of flattening for ICCP segments, but didn't consider that the same could be necessary for EXIF.

I'll commit a fix later in the day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants