[vlc-commits] [Git][videolan/vlc][master] 8 commits: vlc_es: add ICC profile struct
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri Jun 3 11:35:59 UTC 2022
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
ea89d080 by Niklas Haas at 2022-06-03T11:11:46+00:00
vlc_es: add ICC profile struct
We store the ICC profile as part of the (ancillary) data allocation,
using a trailing unsized array. This is because we need to copy it in
and out of various libraries anyway, to avoid having to expose things
like AVBufferRef.
The (as of writing) current ICC specification can be found at
https://www.color.org/specification/ICC.1-2022-05.pdf
- - - - -
d986d36b by Niklas Haas at 2022-06-03T11:11:46+00:00
avcodec: decode ICC profile side data
- - - - -
954c1125 by Niklas Haas at 2022-06-03T11:11:46+00:00
jpeg: decode ICC profiles
This implementation relies on the helper function jpeg_read_icc_profile
which was introduced in libjpeg-turbo v1.5.90. Its absence from other
versions of libjpeg means we may wish to copy this helper function into
our own code in the future. But for now, keep it simple and avoid
unnecessary bloat.
- - - - -
7669876f by Niklas Haas at 2022-06-03T11:11:46+00:00
png: decode ICC profiles
Current libpng always has, and hopefully, always will return
uncompressed ICC profiles, denoted with PNG_COMPRESSION_TYPE_BASE.
- - - - -
c4ae02f6 by Niklas Haas at 2022-06-03T11:11:46+00:00
demux: image: preserve ICC profile metadata
It might be cleaner to somehow enumerate all ancillaries and forward
them to the block. But for now, just do it for ICC profiles
specifically.
- - - - -
ac861b47 by Niklas Haas at 2022-06-03T11:11:46+00:00
rawvideo: support ICC ancillaries
This is mainly designed to enable the use case brought forth by
demux/image.c, which forwards this metadata to the decoded blocks, which
in turn get forwarded through the rawvideo decoder.
- - - - -
489f7045 by Niklas Haas at 2022-06-03T11:11:46+00:00
vout: libplacebo: forward ICC profiles to libplacebo
Straightforward. Since pl_icc_profile_compute_signature is fast, we can
call it on every frame without real worry. This is usually only relevant
for still images anyways.
- - - - -
77bf795c by Niklas Haas at 2022-06-03T11:11:46+00:00
core: add missing include to vlc_ancillary.h
This refernces uint32_t without include, breaking this header if
included before others.
- - - - -
8 changed files:
- include/vlc_ancillary.h
- include/vlc_es.h
- modules/codec/avcodec/video.c
- modules/codec/jpeg.c
- modules/codec/png.c
- modules/codec/rawvideo.c
- modules/demux/image.c
- modules/video_output/libplacebo/display.c
Changes:
=====================================
include/vlc_ancillary.h
=====================================
@@ -21,6 +21,8 @@
#ifndef VLC_ANCILLARY_H
#define VLC_ANCILLARY_H 1
+#include <stdint.h>
+
/**
* \defgroup ancillary Ancillary
* \ingroup input
=====================================
include/vlc_es.h
=====================================
@@ -601,6 +601,18 @@ typedef struct vlc_video_dovi_metadata_t
} nlq[3];
} vlc_video_dovi_metadata_t;
+/**
+ * Embedded ICC profiles
+ */
+
+#define VLC_ANCILLARY_ID_ICC VLC_FOURCC('i','C','C','P')
+
+typedef struct vlc_icc_profile_t
+{
+ size_t size;
+ uint8_t data[]; /* binary profile data, see ICC.1:2022 (or later) */
+} vlc_icc_profile_t;
+
/**
* subtitles format description
*/
=====================================
modules/codec/avcodec/video.c
=====================================
@@ -923,6 +923,17 @@ static int DecodeSidedata( decoder_t *p_dec, const AVFrame *frame, picture_t *p_
}
#endif
+ const AVFrameSideData *p_icc = av_frame_get_side_data( frame, AV_FRAME_DATA_ICC_PROFILE );
+ if( p_icc )
+ {
+ vlc_icc_profile_t *icc;
+ icc = picture_AttachNewAncillary( p_pic, VLC_ANCILLARY_ID_ICC, sizeof(*icc) + p_icc->size );
+ if( !icc )
+ return VLC_ENOMEM;
+ memcpy( icc->data, p_icc->data, p_icc->size );
+ icc->size = p_icc->size;
+ }
+
return 0;
}
=====================================
modules/codec/jpeg.c
=====================================
@@ -519,9 +519,12 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_block)
goto error;
}
+#define ICC_JPEG_MARKER (JPEG_APP0+2)
+
jpeg_create_decompress(&p_sys->p_jpeg);
jpeg_mem_src(&p_sys->p_jpeg, p_block->p_buffer, p_block->i_buffer);
jpeg_save_markers( &p_sys->p_jpeg, EXIF_JPEG_MARKER, 0xffff );
+ jpeg_save_markers( &p_sys->p_jpeg, ICC_JPEG_MARKER, 0xffff );
jpeg_read_header(&p_sys->p_jpeg, TRUE);
p_sys->p_jpeg.out_color_space = JCS_RGB;
@@ -554,6 +557,24 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_block)
goto error;
}
+ /* Read ICC profile */
+#if defined(LIBJPEG_TURBO_VERSION_NUMBER) && LIBJPEG_TURBO_VERSION_NUMBER >= 1005090
+ JOCTET *p_icc;
+ unsigned int icc_len;
+ if (jpeg_read_icc_profile(&p_sys->p_jpeg, &p_icc, &icc_len))
+ {
+ vlc_icc_profile_t *icc;
+ icc = picture_AttachNewAncillary(p_pic, VLC_ANCILLARY_ID_ICC, sizeof(*icc) + icc_len);
+ if (!icc) {
+ free(p_icc);
+ goto error;
+ }
+ memcpy(icc->data, p_icc, icc_len);
+ icc->size = icc_len;
+ free(p_icc);
+ }
+#endif /* LIBJPEG_TURBO_VERSION_NUMBER */
+
/* Decode picture */
p_sys->p_row_pointers = vlc_alloc(p_sys->p_jpeg.output_height, sizeof(JSAMPROW));
if (!p_sys->p_row_pointers)
@@ -583,6 +604,8 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_block)
error:
+ if (p_pic)
+ picture_Release(p_pic);
jpeg_destroy_decompress(&p_sys->p_jpeg);
free(p_sys->p_row_pointers);
=====================================
modules/codec/png.c
=====================================
@@ -345,6 +345,31 @@ static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
p_pic = decoder_NewPicture( p_dec );
if( !p_pic ) goto error;
+ /* Decode ICC profile */
+#ifdef PNG_iCCP_SUPPORTED
+ if (png_get_valid( p_png, p_info, PNG_INFO_iCCP ))
+ {
+ vlc_icc_profile_t *icc;
+ png_charp name;
+ int compression;
+# if PNG_LIBPNG_VER < 10500
+ png_charp iccdata;
+# else
+ png_bytep iccdata;
+# endif
+ png_uint_32 icclen;
+ png_get_iCCP( p_png, p_info, &name, &compression, &iccdata, &icclen);
+ if( compression != PNG_COMPRESSION_TYPE_BASE )
+ goto error; /* impossible with current libpng */
+ icc = picture_AttachNewAncillary( p_pic, VLC_ANCILLARY_ID_ICC, sizeof(*icc) + icclen );
+ if ( !icc )
+ goto error;
+ memcpy( icc->data, iccdata, icclen );
+ icc->size = icclen;
+ }
+#endif
+
+
/* Decode picture */
p_row_pointers = vlc_alloc( i_height, sizeof(png_bytep) );
if( !p_row_pointers )
@@ -368,6 +393,8 @@ static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
error:
+ if( p_pic )
+ picture_Release( p_pic );
free( p_row_pointers );
png_destroy_read_struct( &p_png, &p_info, &p_end_info );
block_Release( p_block );
=====================================
modules/codec/rawvideo.c
=====================================
@@ -254,6 +254,11 @@ static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
return VLCDEC_SUCCESS;
}
+ struct vlc_ancillary *ancillary;
+ ancillary = vlc_frame_GetAncillary( p_block, VLC_ANCILLARY_ID_ICC );
+ if( ancillary )
+ picture_AttachAncillary( p_pic, ancillary );
+
FillPicture( p_dec, p_block, p_pic );
p_pic->date = p_block->i_pts;
=====================================
modules/demux/image.c
=====================================
@@ -180,6 +180,12 @@ static block_t *Decode(demux_t *demux,
}
}
+ // Preserve important metadata
+ struct vlc_ancillary *ancillary;
+ ancillary = picture_GetAncillary(image, VLC_ANCILLARY_ID_ICC);
+ if (ancillary)
+ vlc_frame_AttachAncillary(data, ancillary);
+
picture_Release(image);
return data;
}
=====================================
modules/video_output/libplacebo/display.c
=====================================
@@ -28,6 +28,7 @@
#endif
#include <vlc_common.h>
+#include <vlc_ancillary.h>
#include <vlc_plugin.h>
#include <vlc_vout_display.h>
#include <vlc_fs.h>
@@ -257,6 +258,16 @@ static void PictureRender(vout_display_t *vd, picture_t *pic,
vlc_placebo_DoviMetadata(&img, pic, &sys->dovi_metadata);
#endif
+#if PL_API_VER >= 96
+ struct vlc_ancillary *iccp = picture_GetAncillary(pic, VLC_ANCILLARY_ID_ICC);
+ if (iccp) {
+ vlc_icc_profile_t *icc = vlc_ancillary_GetData(iccp);
+ img.profile.data = icc->data;
+ img.profile.len = icc->size;
+ pl_icc_profile_compute_signature(&img.profile);
+ }
+#endif
+
// Upload the image data for each plane
struct pl_plane_data data[4];
if (!vlc_placebo_PlaneData(pic, data, NULL)) {
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c0b2f318ceb7e235883550008eee148e6f98dc93...77bf795c0dd4015e7475df4a1addf43150649f41
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c0b2f318ceb7e235883550008eee148e6f98dc93...77bf795c0dd4015e7475df4a1addf43150649f41
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list