From patchwork Thu Mar 28 14:08:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thilo Borgmann X-Patchwork-Id: 47588 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:9f96:b0:1a3:b6bb:3029 with SMTP id mm22csp1350265pzb; Thu, 28 Mar 2024 07:10:25 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUD3AfwenvCoGotSrPmEV+7OKmmdb0dAsPt3pZP08xGK9Rvy8Y/7bmzqq8V98OeEI8doyMbAcndfvT+IEroxIIC8z3FPAiEZJoTcQ== X-Google-Smtp-Source: AGHT+IHUd0ks4r83YG/IbVSc0gvtH/8SvBvX8F0nBAAzAvJLrMcXvhsc0QwffyI2t9UafVlOw3dl X-Received: by 2002:a50:9fca:0:b0:56b:b03b:2a85 with SMTP id c68-20020a509fca000000b0056bb03b2a85mr2055527edf.0.1711635025074; Thu, 28 Mar 2024 07:10:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1711635025; cv=none; d=google.com; s=arc-20160816; b=OzM5Ya9YvpHMu7Xu2Ornq8bSUbvm+uyw7smdfAmgTJktd+AAUv9lIZvcgG8xleXjAU 2/gYupfjqZBPoxYuOn7n5g3BbywehJsJszsmleY8w87s1JdcZInjQ8eyBNWB4SLz3hqq d5dHKoPMRqTnrpAWWFZK2ABS6sEEvv3ZqzMZB2yAmS7gUb0/EVNNmqoBrhZ6GNO+ABKk FYmhF/iaL4keVx0fU6Z5zSCYHuHGuQ33roj6GJYotuKMcieWJXNc02W5zGdO5l5oVl8Y IjgPXO0ZIKkUo9cDuXsNyF62dtN4DffbXDmPgabe+NL0M9LyEov/4oysu+bYCO0miuDw iYsg== 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=1n+Mbrwg8B4J2fAqTU3/HzcnWafV0Vf/c4N1cmKrbtA=; fh=uZWItAgYCSLFS5Zum7Ip+PilGyWYOeCwun+We0BTHAs=; b=cp6SwyQN1n3kTALEzrAI88rSSALiOebUKTt8wq8imHQ+gVZWQFF68B8UUP3ldeF/Ft YIH4UC7qq4Zbf6f/yxafUj2a+ayhKRV9qGTunqkUNJqFgpvoEj7qBhFHylJDBOZ0li75 Tcvcz/vQcPaEsS8DZ3etrONl2NVqfX2nJKXyXXCIq6TKdFI0drX6x6O8fYCYGaFCqIWP p3xoiG6Fbp7cnvY4wdAo2+qkwZF7kqzz0OiImkC40ggFB8R6g2eEOy7ssyVkABmWHhUz 5qYW9qvOQR4ebbaL44gudw2ujEthaRk7yShD1r8YU6QeoGnRlWIBTbe5uoxbDSllYP3k HzWw==; 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 h29-20020a50cddd000000b00568c3a5394fsi814501edj.537.2024.03.28.07.10.24; Thu, 28 Mar 2024 07:10:25 -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 6E2ED68D72D; Thu, 28 Mar 2024 16:09:17 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from shout02.mail.de (shout02.mail.de [62.201.172.25]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F2C9468D70F for ; Thu, 28 Mar 2024 16:09:11 +0200 (EET) Received: from postfix02.mail.de (postfix02.bt.mail.de [10.0.121.126]) by shout02.mail.de (Postfix) with ESMTP id E740A240DEB for ; Thu, 28 Mar 2024 15:09:00 +0100 (CET) Received: from smtp01.mail.de (smtp02.bt.mail.de [10.0.121.212]) by postfix02.mail.de (Postfix) with ESMTP id CEFE4A03C3 for ; Thu, 28 Mar 2024 15:09:00 +0100 (CET) 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 A58CE240CE5 for ; Thu, 28 Mar 2024 15:09:00 +0100 (CET) To: ffmpeg-devel@ffmpeg.org Date: Thu, 28 Mar 2024 15:08:58 +0100 Message-Id: <20240328140858.2521-9-thilo.borgmann@mail.de> In-Reply-To: <20240328140858.2521-1-thilo.borgmann@mail.de> References: <20240328140858.2521-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: 3623 X-purgate-ID: 154282::1711634940-FED2B878-4DF86717/0/0 Subject: [FFmpeg-devel] [PATCH v11 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: WO3wxlKQpdlP --- libavcodec/webp.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 832ede52fc..b9feaa5bf0 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/imgutils.h" @@ -216,6 +216,7 @@ typedef struct WebPContext { int alpha_data_size; /* alpha chunk data size */ int has_exif; /* set after an EXIF chunk has been processed */ int has_iccp; /* set after an ICCP chunk has been processed */ + 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 */ @@ -1463,6 +1464,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 }; @@ -1494,6 +1496,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_thread_release_ext_buffer(&s->canvas_frame); break; case MKTAG('V', 'P', '8', ' '): @@ -1679,12 +1682,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",