From patchwork Thu Aug 27 10:50:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 28136 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id B0272BDDFC for ; Thu, 27 Aug 2026 10:51:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6125D684AE; Thu, 27 Aug 2026 12:51:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vR5xoRj6"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 24C0E68487 for ; Thu, 27 Aug 2026 12:51:27 +0200 (CEST) Received: from neptunite.hamster-moth.ts.net (unknown [IPv6:2400:2411:160:2f00:306c:5b5b:3c7f:eabd]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 903ADC1; Thu, 27 Aug 2026 12:49:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1787827800; bh=ANkI6m1mn4QEmtkEsIpMdABg4JfnT3xfJK0XI6ZekSQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vR5xoRj6nfxuJB2qfF5qaEp7hu/m/YIDfIpcbQGaUwNtDV4UrShM3NzbX6xEtjCGH Uo79IkYfNb6m+Z7bBonFbM8Z3MvdOX/IXmpTiuVOKDox4iJE5lYbeNRrEhumDZ2q8u y38r0jTHSV31dG0BxtLgVAHRuRMx+r/9IdgG3TWY= From: Paul Elder To: laurent.pinchart@ideasonboard.com Cc: Paul Elder , michael.riesch@collabora.com, xuhf@rock-chips.com, stefan.klug@ideasonboard.com, kieran.bingham@ideasonboard.com, dan.scally@ideasonboard.com, jacopo.mondi@ideasonboard.com, nicolas.dufresne@collabora.com, mehdi.djait@linux.intel.com, libcamera-devel@lists.libcamera.org Subject: [PATCH v3 16/20] utils: tuning: libtuning: image: Enable images missing some metadata Date: Thu, 27 Aug 2026 19:50:09 +0900 Message-ID: <20260827105018.2781166-17-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20260827105018.2781166-1-paul.elder@ideasonboard.com> References: <20260827105018.2781166-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Some pipeline handlers, like the rkisp2 pipeline handler, are capable of taking raw images but cannot set: - exposure time - gain - black level yet as they have not been implemented for raw mode yet. Arguably black mode will never be supported in raw mode as it bypasses the ISP completely and black level subtraction is in the ISP. This prevents the images from being used for tuning in the current libtuning-based tuning scripts as it requires exposure time and iso and black level, so modify libtuning to allow images with no exposure time and iso and black level. Signed-off-by: Paul Elder --- No change in v2 --- utils/tuning/libtuning/image.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/utils/tuning/libtuning/image.py b/utils/tuning/libtuning/image.py index ecd334bdc67f..b1ada0d0867c 100644 --- a/utils/tuning/libtuning/image.py +++ b/utils/tuning/libtuning/image.py @@ -70,12 +70,27 @@ class Image: white = metadata[f'Exif.{subimage}.WhiteLevel'].value self.sigbits = int(white).bit_length() self.fmt = (self.sigbits - 4) // 2 - self.exposure = int(metadata[f'Exif.{photo}.ExposureTime'].value * 1000000) - self.againQ8 = metadata[f'Exif.{photo}.ISOSpeedRatings'].value * 256 / 100 - self.againQ8_norm = self.againQ8 / 256 + + self.exposure = None + exposure_key = f'Exif.{photo}.ExposureTime' + if exposure_key in metadata: + self.exposure = int(metadata[exposure_key].value * 1000000) + + self.againQ8 = None + self.againQ8_norm = None + iso_key = f'Exif.{photo}.ISOSpeedRatings' + if iso_key in metadata: + self.againQ8 = metadata[iso_key].value * 256 / 100 + self.againQ8_norm = self.againQ8 / 256 + + self.blacklevel = 0 + self.blacklevel_16 = 0 + bl_key = f'Exif.{subimage}.BlackLevel' + if bl_key in metadata: + self.blacklevel = int(metadata[bl_key].value[0]) + self.blacklevel_16 = self.blacklevel << (16 - self.sigbits) + self.camName = metadata['Exif.Image.Model'].value - self.blacklevel = int(metadata[f'Exif.{subimage}.BlackLevel'].value[0]) - self.blacklevel_16 = self.blacklevel << (16 - self.sigbits) # Channel order depending on bayer pattern # The key is the order given by exif, where 0 is R, 1 is G, and 2 is B