[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