From patchwork Fri Jun 21 10:43:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thilo Borgmann X-Patchwork-Id: 50040 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:ae71:0:b0:482:c625:d099 with SMTP id w17csp435957vqz; Fri, 21 Jun 2024 03:52:48 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXqIdEtM2nY12NQI0if0FQMqm3eMndmZIdtSCx3SbbTTYlyxsyCoDuKsf1vrSK5zPlhQj9twwEEGVT7DYnZwkT+QcZGv6o6TQ2yGw== X-Google-Smtp-Source: AGHT+IH8apNTUaiQK8MbSStsmNwa8b1azIXbFuAIXu2loF1jrJk2Tkf9YE5G3BSnTfQrzPPpcKll X-Received: by 2002:a17:907:a587:b0:a6f:ac90:754d with SMTP id a640c23a62f3a-a6fac907737mr518672466b.29.1718967168403; Fri, 21 Jun 2024 03:52:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1718967168; cv=none; d=google.com; s=arc-20160816; b=xWvo1NOcqr6DQG2lniFT3tIj1D/k4j9iTQTWxmpeNkhO7YX6Jqz52eaEYQe6P3A1bo k266KFzIAwYK3ohbZk8udFOcKjkAZTGotSqgML8OatT62Mp3jrpvCHt2bpoKU1rS1j+H M3yWj7H51CMzn7ShnfJsws5xb/6kFtVSd051ULZ91JnACfMyf0scXr6fkqjTaP34eE5N IjudLNGbbuwOHJjhXCK3UBRpsFh02e0yrWQRdT6oeZ9340eeNZKHEDE0OqPEN6xvQXJB kLEVcFVNwdTJ1ezx8Ro1YMkVJE56LbtZXxzYynQTx2lIpzwtPEG+SET5qFNYeMKPHWAD W9NA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to:from :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:delivered-to; bh=I/j2lyMxvD8r+Diw0mULo2XNuw1P79kmJez9LqHunyk=; fh=uZWItAgYCSLFS5Zum7Ip+PilGyWYOeCwun+We0BTHAs=; b=bNl86fsbB1FbIXr+Z5lZ8Alw0OzFruniS7TuDw3Sj08H+FEGzirtFMYMW43d1nW3gG SRR1eKZ9oWq8DqQeVlL0UJtFCQ/e3zi3KaOSpFyttL2/NvFPdrfAwxoehcDdQfQKSFJd XrmGCKcw+4QdFIFeBmXkPbgGFQ1CiUtWtTrknnspkigpGsMdkxey2b48RKn51Eg97u9r Q7R6J/cR1ePisRRUXKOznLM7xn7xL2k6+7NRYReaBz/4C8lMCgl9mt88nzyFyEWP73/l VmYUoz8i365lPNeFLuDUzaqeQRbOnBc+J5VQQPri5Dhjp3EJmzdQuL5OQ6scHa8C0bfc GTZg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id a640c23a62f3a-a6fcf5aed44si74287766b.1000.2024.06.21.03.52.48; Fri, 21 Jun 2024 03:52:48 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D7F7868D89C; Fri, 21 Jun 2024 13:43:43 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from shout01.mail.de (shout01.mail.de [62.201.172.24]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4247E68D7EA for ; Fri, 21 Jun 2024 13:43:36 +0300 (EEST) Received: from postfix03.mail.de (postfix03.bt.mail.de [10.0.121.127]) by shout01.mail.de (Postfix) with ESMTP id 9A004240E99 for ; Fri, 21 Jun 2024 12:43:27 +0200 (CEST) Received: from smtp01.mail.de (smtp04.bt.mail.de [10.0.121.214]) by postfix03.mail.de (Postfix) with ESMTP id 8225280209 for ; Fri, 21 Jun 2024 12:43:27 +0200 (CEST) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp01.mail.de (Postfix) with ESMTPSA id 4D789240C94 for ; Fri, 21 Jun 2024 12:43:27 +0200 (CEST) To: ffmpeg-devel@ffmpeg.org Date: Fri, 21 Jun 2024 12:43:23 +0200 Message-Id: <20240621104323.92453-9-thilo.borgmann@mail.de> In-Reply-To: <20240621104323.92453-1-thilo.borgmann@mail.de> References: <20240621104323.92453-1-thilo.borgmann@mail.de> MIME-Version: 1.0 X-purgate: clean X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate-type: clean X-purgate-Ad: Categorized by eleven eXpurgate (R) http://www.eleven.de X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate: clean X-purgate-size: 3692 X-purgate-ID: 154282::1718966607-E17EB338-B98ADB1E/0/0 Subject: [FFmpeg-devel] [PATCH v13 8/8] avcodec/webp: export XMP metadata X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Thilo Borgmann via ffmpeg-devel From: Thilo Borgmann Reply-To: FFmpeg development discussions and patches Cc: Thilo Borgmann Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: Bh5OQaOiacdv From: Thilo Borgmann via ffmpeg-devel --- libavcodec/webp.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/libavcodec/webp.c b/libavcodec/webp.c index bacf605ff2..c8be673060 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -38,8 +38,8 @@ * @author Josef Zlomek, Pexeso Inc. * Animation * - * Unimplemented: - * - XMP metadata + * @author Thilo Borgmann + * XMP metadata */ #include "libavutil/common.h" @@ -220,6 +220,7 @@ typedef struct WebPContext { int has_exif; /* set after an EXIF chunk has been processed */ int has_iccp; /* set after an ICCP chunk has been processed */ int duration; /* frame duration in an animation */ + int has_xmp; /* set after an XMP chunk has been processed */ int width; /* image width */ int height; /* image height */ int vp8x_flags; /* global flags from VP8X chunk */ @@ -1469,6 +1470,7 @@ static int webp_decode_frame_common(AVCodecContext *avctx, uint8_t *data, int si // reset metadata bit for each packet s->has_exif = 0; s->has_iccp = 0; + s->has_xmp = 0; while (bytestream2_get_bytes_left(&gb) > 8) { char chunk_str[5] = { 0 }; @@ -1500,6 +1502,7 @@ static int webp_decode_frame_common(AVCodecContext *avctx, uint8_t *data, int si s->canvas_height = 0; s->has_exif = 0; s->has_iccp = 0; + s->has_xmp = 0; ff_progress_frame_unref(&s->canvas_frame); break; case MKTAG('V', 'P', '8', ' '): @@ -1682,12 +1685,39 @@ exif_end: } s->vp8x_flags |= VP8X_FLAG_ANIMATION; break; - case MKTAG('X', 'M', 'P', ' '): - AV_WL32(chunk_str, chunk_type); - av_log(avctx, AV_LOG_WARNING, "skipping unsupported chunk: %s\n", - chunk_str); + case MKTAG('X', 'M', 'P', ' '): { + GetByteContext xmp_gb; + AVDictionary **xmp_metadata = NULL; + uint8_t *buffer; + int xmp_offset = bytestream2_tell(&gb); + + if (s->has_xmp) { + av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra XMP chunk\n"); + goto xmp_end; + } + if (!(s->vp8x_flags & VP8X_FLAG_XMP_METADATA)) + av_log(avctx, AV_LOG_WARNING, + "XMP chunk present, but XMP bit not set in the " + "VP8X header\n"); + + // there are at least chunk_size bytes left to read + buffer = av_malloc(chunk_size + 1); + if (!buffer) { + return AVERROR(ENOMEM); + } + + s->has_xmp = 1; + bytestream2_init(&xmp_gb, data + xmp_offset, size - xmp_offset); + bytestream2_get_buffer(&xmp_gb, buffer, chunk_size); + buffer[chunk_size] = '\0'; + + xmp_metadata = (s->vp8x_flags & VP8X_FLAG_ANIMATION) ? &p->metadata : &s->frame->metadata; + av_dict_set(xmp_metadata, "xmp", buffer, AV_DICT_DONT_STRDUP_VAL); + +xmp_end: bytestream2_skip(&gb, chunk_size); break; + } default: AV_WL32(chunk_str, chunk_type); av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",