[vlc-devel] [PATCH 03/17] jpeg: read panoramic metadata from the XMP EXIF data
Rémi Denis-Courmont
remi at remlab.net
Mon Nov 14 18:28:49 CET 2016
Le maanantaina 14. marraskuuta 2016, 15.16.12 EET Steve Lhomme a écrit :
> --
> replaces https://patches.videolan.org/patch/14996/
> * no need to know the end of strtof()
> ---
> modules/codec/jpeg.c | 79
> +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78
> insertions(+), 1 deletion(-)
>
> diff --git a/modules/codec/jpeg.c b/modules/codec/jpeg.c
> index 30e095e..b45ca57 100644
> --- a/modules/codec/jpeg.c
> +++ b/modules/codec/jpeg.c
> @@ -247,6 +247,83 @@ de_get32( void * ptr, uint endian ) {
> return val;
> }
>
> +static bool getRDFFloat(const char *psz_rdf, float *out, const char
> *psz_var) +{
> + char *p_start = strcasestr( psz_rdf, psz_var );
> + if (p_start == NULL)
> + return false;
> +
> + size_t varlen = strlen(psz_var);
> + char *p_end = strchr( p_start + varlen, '"');
> + if (unlikely(p_end == NULL || p_end == p_start + 1))
> + return false;
> +
> + *out = strtof( p_start + varlen, NULL );
Restating the obvious here but locale-dependent parsing cannot be right.
> + return true;
> +}
> +
> +#define EXIF_JPEG_MARKER 0xE1
> +#define EXIF_XMP_STRING "http://ns.adobe.com/xap/1.0/\000"
> +
> +/* read XMP metadata for projection according to
> + * https://developers.google.com/streetview/spherical-metadata */
> +static void jpeg_GetProjection( j_decompress_ptr cinfo, video_format_t *fmt
> ) +{
> + jpeg_saved_marker_ptr xmp_marker = NULL;
> + jpeg_saved_marker_ptr cmarker = cinfo->marker_list;
> +
> + while ( cmarker )
> + {
> + if ( cmarker->marker == EXIF_JPEG_MARKER )
> + {
> + if ( !memcmp( cmarker->data, EXIF_XMP_STRING, 29 ) )
> + {
> + xmp_marker = cmarker;
> + break;
> + }
> + }
> + cmarker = cmarker->next;
> + }
> +
> + if (xmp_marker == NULL || xmp_marker->data_length < 32)
> + return;
> + char *psz_rdf = malloc(xmp_marker->data_length - 29);
> + if (unlikely(psz_rdf == NULL))
> + return;
> + memcpy(psz_rdf, xmp_marker->data + 29, xmp_marker->data_length - 29);
> +
> + /* Try to find the string "GSpherical:Spherical" because the v1
> + spherical video spec says the tag must be there. */
> + if ( strcasestr( psz_rdf, "ProjectionType=\"equirectangular\"" ) )
> + fmt->projection_mode = PROJECTION_MODE_EQUIRECTANGULAR;
> +
> + /* pose handling */
> + float value;
> + if (getRDFFloat( psz_rdf, &value, "PoseHeadingDegrees=\"" ))
> + fmt->f_pose_yaw_degrees = value;
> +
> + if (getRDFFloat( psz_rdf, &value, "PosePitchDegrees=\"" ))
> + fmt->f_pose_pitch_degrees = value;
> +
> + if (getRDFFloat( psz_rdf, &value, "PoseRollDegrees=\""))
> + fmt->f_pose_roll_degrees = value;
> +
> + /* initial view */
> + if (getRDFFloat( psz_rdf, &value, "InitialViewHeadingDegrees=\"" ))
> + fmt->f_pose_yaw_degrees = value;
> +
> + if (getRDFFloat( psz_rdf, &value, "InitialViewPitchDegrees=\"" ))
> + fmt->f_pose_pitch_degrees = value;
> +
> + if (getRDFFloat( psz_rdf, &value, "InitialViewRollDegrees=\"" ))
> + fmt->f_pose_roll_degrees = value;
> +
> + if (getRDFFloat( psz_rdf, &value, "InitialHorizontalFOVDegrees=\"" ))
> + fmt->f_pose_fov_degrees = value;
> +
> + free(psz_rdf);
> +}
> +
> /*
> * Look through the meta data in the libjpeg decompress structure to
> determine * if an EXIF Orientation tag is present. If so return its value
> (1-8), @@ -276,7 +353,6 @@ jpeg_GetOrientation( j_decompress_ptr cinfo )
> const char leth[] = { 0x49, 0x49, 0x2a, 0x00 }; /* Little endian TIFF
> header */ const char beth[] = { 0x4d, 0x4d, 0x00, 0x2a }; /* Big endian
> TIFF header */
>
> - #define EXIF_JPEG_MARKER 0xE1
> #define EXIF_IDENT_STRING "Exif\000\000"
> #define EXIF_ORIENT_TAGID 0x112
>
> @@ -453,6 +529,7 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t
> **pp_block) msg_Dbg( p_dec, "Jpeg orientation is %d", i_otag );
> p_dec->fmt_out.video.orientation = ORIENT_FROM_EXIF( i_otag );
> }
> + jpeg_GetProjection( &p_sys->p_jpeg, &p_dec->fmt_out.video );
>
> /* Get a new picture */
> if (decoder_UpdateVideoFormat(p_dec))
--
Rémi Denis-Courmont
https://www.remlab.net/
More information about the vlc-devel
mailing list