diff mbox series

[FFmpeg-devel,3/3] avcodec/pngenc: write eXIf chunks

Message ID 20240213212456.167386-4-leo.izen@gmail.com
State New
Headers show
Series EXIF overhaul | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 fail Make fate failed
andriy/make_x86 success Make finished
andriy/make_fate_x86 fail Make fate failed

Commit Message

Leo Izen Feb. 13, 2024, 9:24 p.m. UTC
Write EXIF metadata exposed AV_FRAME_DATA_EXIF as an eXIf chunk
to PNG files, if present.

Signed-off-by: Leo Izen <leo.izen@gmail.com>
---
 libavcodec/pngenc.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Michael Niedermayer Feb. 14, 2024, 6:38 p.m. UTC | #1
On Tue, Feb 13, 2024 at 04:24:56PM -0500, Leo Izen wrote:
> Write EXIF metadata exposed AV_FRAME_DATA_EXIF as an eXIf chunk
> to PNG files, if present.
> 
> Signed-off-by: Leo Izen <leo.izen@gmail.com>
> ---
>  libavcodec/pngenc.c | 4 ++++
>  1 file changed, 4 insertions(+)

This seems to break:

--- ./tests/ref/fate/cover-art-mp3-id3v2-remux	2024-02-14 19:33:50.756012174 +0100
+++ tests/data/fate/cover-art-mp3-id3v2-remux	2024-02-14 19:36:59.150052682 +0100
@@ -1,5 +1,5 @@
-94946f0efd5f9bb0061ac1fbff7d731f *tests/data/fate/cover-art-mp3-id3v2-remux.mp3
-399346 tests/data/fate/cover-art-mp3-id3v2-remux.mp3
+0643e306430fbadeb1c89da6ab36a303 *tests/data/fate/cover-art-mp3-id3v2-remux.mp3
+399414 tests/data/fate/cover-art-mp3-id3v2-remux.mp3
 #tb 0: 1/14112000
 #media_type 0: audio
 #codec_id 0: mp3
@@ -23,7 +23,7 @@
 0,    -353590,    -353590,   368640,      417, 0x15848290, S=1,       10
 1,          0,          0,        0,   208350, 0x291b44d1
 2,          0,          0,        0,    15760, 0x71d5c418
-3,          0,          0,        0,   165671, 0x7c1c8070
+3,          0,          0,        0,   165739, 0x2e108b69
 0,      15050,      15050,   368640,      418, 0x46f684a4
 0,     383690,     383690,   368640,      418, 0x46f684a4
 0,     752330,     752330,   368640,      418, 0x46f684a4
Test cover-art-mp3-id3v2-remux failed. Look at tests/data/fate/cover-art-mp3-id3v2-remux.err for details.
tests/Makefile:318: recipe for target 'fate-cover-art-mp3-id3v2-remux' failed
make: *** [fate-cover-art-mp3-id3v2-remux] Error 1

[...]
Andreas Rheinhardt Feb. 14, 2024, 6:53 p.m. UTC | #2
Leo Izen:
> Write EXIF metadata exposed AV_FRAME_DATA_EXIF as an eXIf chunk
> to PNG files, if present.
> 
> Signed-off-by: Leo Izen <leo.izen@gmail.com>
> ---
>  libavcodec/pngenc.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
> index 50689cb50c..a302c879da 100644
> --- a/libavcodec/pngenc.c
> +++ b/libavcodec/pngenc.c
> @@ -413,6 +413,10 @@ static int encode_headers(AVCodecContext *avctx, const AVFrame *pict)
>          }
>      }
>  
> +    side_data = av_frame_get_side_data(pict, AV_FRAME_DATA_EXIF);
> +    if (side_data)
> +        png_write_chunk(&s->bytestream, MKTAG('e', 'X', 'I', 'f'), side_data->data, FFMIN(side_data->size, INT_MAX));
> +
>      side_data = av_frame_get_side_data(pict, AV_FRAME_DATA_ICC_PROFILE);
>      if ((ret = png_write_iccp(s, side_data)))
>          return ret;

If I see this correctly, then these patches can lead to a situation
where an input packet has rotation metadata in exif which gets exported
twice -- as displaymatrix and as exif metadata side data. If the user
changes the displaymatrix (e.g. applies the transformation to the image
data and removes the displaymatrix side data before reencoding), the
exif data (that the user would probably not be aware of) would still be
there and get propagated into the output, corrupting it.

- Andreas
Leo Izen Feb. 15, 2024, 8:19 a.m. UTC | #3
On 2/14/24 13:53, Andreas Rheinhardt wrote:
> Leo Izen:
>> Write EXIF metadata exposed AV_FRAME_DATA_EXIF as an eXIf chunk
>> to PNG files, if present.
>>
>> Signed-off-by: Leo Izen <leo.izen@gmail.com>
>> ---
>>   libavcodec/pngenc.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
>> index 50689cb50c..a302c879da 100644
>> --- a/libavcodec/pngenc.c
>> +++ b/libavcodec/pngenc.c
>> @@ -413,6 +413,10 @@ static int encode_headers(AVCodecContext *avctx, const AVFrame *pict)
>>           }
>>       }
>>   
>> +    side_data = av_frame_get_side_data(pict, AV_FRAME_DATA_EXIF);
>> +    if (side_data)
>> +        png_write_chunk(&s->bytestream, MKTAG('e', 'X', 'I', 'f'), side_data->data, FFMIN(side_data->size, INT_MAX));
>> +
>>       side_data = av_frame_get_side_data(pict, AV_FRAME_DATA_ICC_PROFILE);
>>       if ((ret = png_write_iccp(s, side_data)))
>>           return ret;
> 
> If I see this correctly, then these patches can lead to a situation
> where an input packet has rotation metadata in exif which gets exported
> twice -- as displaymatrix and as exif metadata side data. If the user
> changes the displaymatrix (e.g. applies the transformation to the image
> data and removes the displaymatrix side data before reencoding), the
> exif data (that the user would probably not be aware of) would still be
> there and get propagated into the output, corrupting it.
> 

Hm. This is true, but it's also currently how the mjpeg decoder 
functions (i.e. it attaches displaymatrix side data).

There are no encoders that currently save EXIF metadata, so there's no 
precedent.

How do you suggest this be reconciled?

- Leo Izen (Traneptora)
diff mbox series

Patch

diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index 50689cb50c..a302c879da 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -413,6 +413,10 @@  static int encode_headers(AVCodecContext *avctx, const AVFrame *pict)
         }
     }
 
+    side_data = av_frame_get_side_data(pict, AV_FRAME_DATA_EXIF);
+    if (side_data)
+        png_write_chunk(&s->bytestream, MKTAG('e', 'X', 'I', 'f'), side_data->data, FFMIN(side_data->size, INT_MAX));
+
     side_data = av_frame_get_side_data(pict, AV_FRAME_DATA_ICC_PROFILE);
     if ((ret = png_write_iccp(s, side_data)))
         return ret;