[vlc-commits] [Git][videolan/vlc][master] 3 commits: codec: png: read tiff orientation
Rémi Denis-Courmont (@Courmisch)
gitlab at videolan.org
Tue Feb 8 20:53:14 UTC 2022
Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC
Commits:
826ace68 by Francois Cartegnie at 2022-02-08T20:39:28+00:00
codec: png: read tiff orientation
- - - - -
89635373 by Francois Cartegnie at 2022-02-08T20:39:28+00:00
codec: png: write orientation
- - - - -
bee4c192 by Francois Cartegnie at 2022-02-08T20:39:28+00:00
codec: jpeg: write orientation
- - - - -
2 changed files:
- modules/codec/jpeg.c
- modules/codec/png.c
Changes:
=====================================
modules/codec/jpeg.c
=====================================
@@ -691,6 +691,21 @@ static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
jpeg_start_compress(&p_sys->p_jpeg, TRUE);
+ unsigned char exif[] = "Exif\x00\x00"
+ "\x4d\x4d\x00\x2a" /* TIFF BE header */
+ "\x00\x00\x00\x08" /* IFD0 offset */
+ "\x00\x01" /* IFD0 tags count */
+ "\x01\x12" /* tagtype */
+ "\x00\x03" /* value type (x03 == short) */
+ "\x00\x00\x00\x01" /* value count */
+ "\xFF\xFF\x00\x00" /* value if <= 4 bytes or value offset */
+ "\x00\x00\x00\x00" /* 0 last IFD */
+ "\x00\x00\x00\x00" /* 0 last IFD offset */
+ ;
+ exif[24] = 0x00;
+ exif[25] = ORIENT_TO_EXIF(p_pic->format.orientation);
+ jpeg_write_marker(&p_sys->p_jpeg, JPEG_APP0 + 1, exif, sizeof(exif) - 1);
+
/* Encode picture */
p_row_pointers = vlc_alloc(p_pic->i_planes, sizeof(JSAMPARRAY));
if (p_row_pointers == NULL)
=====================================
modules/codec/png.c
=====================================
@@ -30,6 +30,7 @@
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_codec.h>
+#include <vlc_rand.h>
#include <png.h>
/* PNG_SYS_COMMON_MEMBERS:
@@ -181,6 +182,53 @@ static void user_warning( png_structp p_png, png_const_charp warning_msg )
msg_Warn( p_sys->p_obj, "%s", warning_msg );
}
+#ifdef PNG_TEXT_SUPPORTED
+static void process_text_chunk( decoder_t *p_dec, const png_textp chunk )
+{
+ if( chunk->compression != PNG_ITXT_COMPRESSION_NONE ||
+ memcmp( chunk->key, "XML:com.adobe.xmp", 17 ) ||
+ chunk->itxt_length < 20 )
+ return;
+
+ const char *exifxmp = (const char *) chunk->text;
+ const char *orient = strnstr( exifxmp, ":Orientation>", chunk->itxt_length );
+ if(orient && orient - exifxmp > 14)
+ p_dec->fmt_out.video.orientation = ORIENT_FROM_EXIF( orient[13] - '0' );
+}
+
+static int make_xmp_packet( const video_format_t *fmt, png_textp chunk )
+{
+ unsigned char id[9];
+ vlc_rand_bytes(id, 8);
+ for(int i=0; i<8; i++)
+ id[i] = (id[i] % 26) + 'A';
+ id[8] = '\0';
+ int len = asprintf( &chunk->text,
+ "<?xpacket begin='' id='%s'?>"
+ "<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='VLC " VERSION "'>"
+ "<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+ "<rdf:Description rdf:about='' xmlns:tiff='http://ns.adobe.com/tiff/1.0/'>"
+ "<tiff:Orientation>%" PRIu8 "</tiff:Orientation>"
+ "</rdf:Description>"
+ "</rdf:RDF>"
+ "</x:xmpmeta>"
+ "<?xpacket end='r'?>", id, ORIENT_TO_EXIF(fmt->orientation) );
+ if(len == 0)
+ {
+ free(chunk->text);
+ chunk->text = NULL;
+ }
+ chunk->itxt_length = (len <= 0) ? 0 : len;
+ chunk->compression = PNG_ITXT_COMPRESSION_NONE;
+ chunk->key = len > 0 ? strdup( "XML:com.adobe.xmp" ) : NULL;
+ chunk->lang_key = NULL;
+ chunk->lang = NULL;
+ chunk->text_length = 0;
+ return len > 0 ? VLC_SUCCESS : VLC_EGENERIC;
+}
+
+#endif
+
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************
@@ -255,6 +303,14 @@ static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
p_dec->fmt_out.video.i_sar_num = 1;
p_dec->fmt_out.video.i_sar_den = 1;
+#ifdef PNG_TEXT_SUPPORTED
+ png_textp textp;
+ int numtextp;
+ if( png_get_text( p_png, p_info, &textp, &numtextp ) > 0 )
+ for( int ii=0; ii<numtextp; ii++ )
+ process_text_chunk( p_dec, &textp[ii] );
+#endif
+
if( i_color_type == PNG_COLOR_TYPE_PALETTE )
png_set_palette_to_rgb( p_png );
@@ -403,7 +459,19 @@ static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );
if( p_sys->b_error ) goto error;
- png_write_info( p_png, p_info );
+#ifdef PNG_TEXT_SUPPORTED
+ png_text text;
+ if( make_xmp_packet( &p_pic->format, &text ) == VLC_SUCCESS )
+ {
+ png_set_text( p_png, p_info, &text, 1 );
+ png_write_info( p_png, p_info );
+ free( text.key );
+ free( text.text );
+ }
+ else
+#endif
+ png_write_info( p_png, p_info );
+
if( p_sys->b_error ) goto error;
/* Encode picture */
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/55eaaa320a805173eb7b0fe7297993ad9a47f640...bee4c1924ed6c27374c293c5d3b0c83ca07c4bab
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/55eaaa320a805173eb7b0fe7297993ad9a47f640...bee4c1924ed6c27374c293c5d3b0c83ca07c4bab
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list