[libcamera-devel] [PATCH v3] utils: raspberrypi: ctt: dng_load_image: Work with DNG files from Picamera2
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Wed Aug 3 13:33:34 CEST 2022
On Wed, Aug 03, 2022 at 02:30:38PM +0300, Laurent Pinchart wrote:
> Hi William,
>
> Thank you for the patch.
>
> On Wed, Aug 03, 2022 at 09:25:39AM +0100, William Vinnicombe via libcamera-devel wrote:
> > From: William Vinnicombe <william.vinnicombe at raspberrypi.com>
> >
> > The DNG specification is based on the TIFF file format and recommends
> > storing the raw image data in a SubIFD and the Exif tags in an Exif IFD.
> > Other options are allowed, even if not recommended, such as storing both
> > the raw image data and the Exif data in IFD0, as done by the TIFF/EP
> > specification.
> >
> > libcamera-apps use pyexiv2 to produce DNG files, following the DNG
> > recommendation, while applications based on picamera2 use PiDNG, which
> > adopts the TIFF/EP structure. Why it does so is not currently clear (see
> > https://github.com/schoolpost/PiDNG/issues/65 for discussions on this
> > topic), but as files based on the DNG and TIFF/EP variants exist in the
> > wild, both need to be supported by ctt.
> >
> > Add code to identify which tags are being used, and then load the
> > metadata from the correct tags.
> >
> > Signed-off-by: William Vinnicombe <william.vinnicombe at raspberrypi.com>
> > Reviewed-by: David Plowman <david.plowman at raspberrypi.com>
> > Reviewed-by: Naushir Patuck <naush at raspberrypi.com>
>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
>
> > ---
> > utils/raspberrypi/ctt/ctt_image_load.py | 32 +++++++++++++++++++------
> > 1 file changed, 25 insertions(+), 7 deletions(-)
> >
> > diff --git a/utils/raspberrypi/ctt/ctt_image_load.py b/utils/raspberrypi/ctt/ctt_image_load.py
> > index 934db123..7f8ba72a 100644
> > --- a/utils/raspberrypi/ctt/ctt_image_load.py
> > +++ b/utils/raspberrypi/ctt/ctt_image_load.py
> > @@ -301,17 +301,35 @@ def dng_load_image(Cam, im_str):
> > metadata.read()
> >
> > Img.ver = 100 # random value
> > - Img.w = metadata['Exif.SubImage1.ImageWidth'].value
> > + """
> > + The DNG and TIFF/EP specifications use different IFDs to store the raw
> > + image data and the Exif tags. DNG stores them in a SubIFD and in an Exif
> > + IFD respectively (named "SubImage1" and "Photo" by pyexiv2), while
> > + TIFF/EP stores them both in IFD0 (name "Image"). Both are used in "DNG"
> > + files, with libcamera-apps following the DNG recommendation and
> > + applications based on picamera2 following TIFF/EP.
> > +
> > + This code detects which tags are being used, and therefore extracts the
> > + correct values.
> > + """
> > + try:
> > + Img.w = metadata['Exif.SubImage1.ImageWidth'].value
> > + subimage = "SubImage1"
> > + photo = "Photo"
> > + except KeyError:
> > + Img.w = metadata['Exif.Image.ImageWidth'].value
> > + subimage = "Image"
> > + photo = "Image"
> > Img.pad = 0
> > - Img.h = metadata['Exif.SubImage1.ImageLength'].value
> > - white = metadata['Exif.SubImage1.WhiteLevel'].value
> > + Img.h = metadata[f'Exif.{subimage}.ImageLength'].value
> > + white = metadata[f'Exif.{subimage}.WhiteLevel'].value
> > Img.sigbits = int(white).bit_length()
> > Img.fmt = (Img.sigbits - 4) // 2
> > - Img.exposure = int(metadata['Exif.Photo.ExposureTime'].value*1000000)
> > - Img.againQ8 = metadata['Exif.Photo.ISOSpeedRatings'].value*256/100
> > + Img.exposure = int(metadata[f'Exif.{photo}.ExposureTime'].value*1000000)
> > + Img.againQ8 = metadata[f'Exif.{photo}.ISOSpeedRatings'].value*256/100
Actually, checkstyle.py reports
--------------------------------------------------------------------------------------------------------------------
31444bed873fbafa1bfa66d76f34044ace09f7d5 utils: raspberrypi: ctt: dng_load_image: Work with DNG files from Picamera2
--------------------------------------------------------------------------------------------------------------------
--- utils/raspberrypi/ctt/ctt_image_load.py
+++ utils/raspberrypi/ctt/ctt_image_load.py
#328: : E226 missing whitespace around arithmetic operator
+ Img.exposure = int(metadata[f'Exif.{photo}.ExposureTime'].value*1000000)
#329: : E226 missing whitespace around arithmetic operator
+ Img.againQ8 = metadata[f'Exif.{photo}.ISOSpeedRatings'].value*256/100
#329: : E226 missing whitespace around arithmetic operator
+ Img.againQ8 = metadata[f'Exif.{photo}.ISOSpeedRatings'].value*256/100
---
3 potential issues detected, please review
I'll fix this by adding the missing spaces.
Could you install the libcamera git post-commit hook that runs
checkstyle.py automatically ?
$ cp utils/hooks/post-commit .git/hooks/
> > Img.againQ8_norm = Img.againQ8 / 256
> > Img.camName = metadata['Exif.Image.Model'].value
> > - Img.blacklevel = int(metadata['Exif.SubImage1.BlackLevel'].value[0])
> > + Img.blacklevel = int(metadata[f'Exif.{subimage}.BlackLevel'].value[0])
> > Img.blacklevel_16 = Img.blacklevel << (16 - Img.sigbits)
> > bayer_case = {
> > '0 1 1 2': (0, (0, 1, 2, 3)),
> > @@ -319,7 +337,7 @@ def dng_load_image(Cam, im_str):
> > '2 1 1 0': (2, (3, 2, 1, 0)),
> > '1 0 2 1': (3, (1, 0, 3, 2))
> > }
> > - cfa_pattern = metadata['Exif.SubImage1.CFAPattern'].value
> > + cfa_pattern = metadata[f'Exif.{subimage}.CFAPattern'].value
> > Img.pattern = bayer_case[cfa_pattern][0]
> > Img.order = bayer_case[cfa_pattern][1]
> >
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list