From 500f1e9eaeca29b255d0364e1383d70ade1d1177 Mon Sep 17 00:00:00 2001 From: Martin Jansa Date: Tue, 30 Jan 2024 12:02:09 +0000 Subject: [PATCH] Revert "Support compressed pixel formats when saving DNGs" This reverts commit a85aed7603a0b69a6685d3f81ee860246d5b1621. This requires rpi specific fork of libcamera to provide e.g. formats::RGGB16_PISP_COMP1 added in: https://github.com/raspberrypi/libcamera/commit/fb3cb844f2117f30d3eeece99d6ce4d02624e492 but not included in libcamera from meta-oe: https://git.openembedded.org/meta-openembedded/commit/?id=711c6fbce39df685225bca081c5f42bae2de658b See https://github.com/raspberrypi/rpicam-apps/issues/627 Upstream-Status: Pending --- image/dng.cpp | 205 ++++++++------------------------------------------ 1 file changed, 33 insertions(+), 172 deletions(-) diff --git a/image/dng.cpp b/image/dng.cpp index 7692f92..fc10439 100644 --- a/image/dng.cpp +++ b/image/dng.cpp @@ -33,47 +33,40 @@ struct BayerFormat int bits; char const *order; bool packed; - bool compressed; }; static const std::map bayer_formats = { - { formats::SRGGB10_CSI2P, { "RGGB-10", 10, TIFF_RGGB, true, false } }, - { formats::SGRBG10_CSI2P, { "GRBG-10", 10, TIFF_GRBG, true, false } }, - { formats::SBGGR10_CSI2P, { "BGGR-10", 10, TIFF_BGGR, true, false } }, - { formats::SGBRG10_CSI2P, { "GBRG-10", 10, TIFF_GBRG, true, false } }, - - { formats::SRGGB10, { "RGGB-10", 10, TIFF_RGGB, false, false } }, - { formats::SGRBG10, { "GRBG-10", 10, TIFF_GRBG, false, false } }, - { formats::SBGGR10, { "BGGR-10", 10, TIFF_BGGR, false, false } }, - { formats::SGBRG10, { "GBRG-10", 10, TIFF_GBRG, false, false } }, - - { formats::SRGGB12_CSI2P, { "RGGB-12", 12, TIFF_RGGB, true, false } }, - { formats::SGRBG12_CSI2P, { "GRBG-12", 12, TIFF_GRBG, true, false } }, - { formats::SBGGR12_CSI2P, { "BGGR-12", 12, TIFF_BGGR, true, false } }, - { formats::SGBRG12_CSI2P, { "GBRG-12", 12, TIFF_GBRG, true, false } }, - - { formats::SRGGB12, { "RGGB-12", 12, TIFF_RGGB, false, false } }, - { formats::SGRBG12, { "GRBG-12", 12, TIFF_GRBG, false, false } }, - { formats::SBGGR12, { "BGGR-12", 12, TIFF_BGGR, false, false } }, - { formats::SGBRG12, { "GBRG-12", 12, TIFF_GBRG, false, false } }, - - { formats::SRGGB16, { "RGGB-16", 16, TIFF_RGGB, false, false } }, - { formats::SGRBG16, { "GRBG-16", 16, TIFF_GRBG, false, false } }, - { formats::SBGGR16, { "BGGR-16", 16, TIFF_BGGR, false, false } }, - { formats::SGBRG16, { "GBRG-16", 16, TIFF_GBRG, false, false } }, - - { formats::R10_CSI2P, { "BGGR-10", 10, TIFF_BGGR, true, false } }, - { formats::R10, { "BGGR-10", 10, TIFF_BGGR, false, false } }, + { formats::SRGGB10_CSI2P, { "RGGB-10", 10, TIFF_RGGB, true } }, + { formats::SGRBG10_CSI2P, { "GRBG-10", 10, TIFF_GRBG, true } }, + { formats::SBGGR10_CSI2P, { "BGGR-10", 10, TIFF_BGGR, true } }, + { formats::SGBRG10_CSI2P, { "GBRG-10", 10, TIFF_GBRG, true } }, + + { formats::SRGGB10, { "RGGB-10", 10, TIFF_RGGB, false } }, + { formats::SGRBG10, { "GRBG-10", 10, TIFF_GRBG, false } }, + { formats::SBGGR10, { "BGGR-10", 10, TIFF_BGGR, false } }, + { formats::SGBRG10, { "GBRG-10", 10, TIFF_GBRG, false } }, + + { formats::SRGGB12_CSI2P, { "RGGB-12", 12, TIFF_RGGB, true } }, + { formats::SGRBG12_CSI2P, { "GRBG-12", 12, TIFF_GRBG, true } }, + { formats::SBGGR12_CSI2P, { "BGGR-12", 12, TIFF_BGGR, true } }, + { formats::SGBRG12_CSI2P, { "GBRG-12", 12, TIFF_GBRG, true } }, + + { formats::SRGGB12, { "RGGB-12", 12, TIFF_RGGB, false } }, + { formats::SGRBG12, { "GRBG-12", 12, TIFF_GRBG, false } }, + { formats::SBGGR12, { "BGGR-12", 12, TIFF_BGGR, false } }, + { formats::SGBRG12, { "GBRG-12", 12, TIFF_GBRG, false } }, + + { formats::SRGGB16, { "RGGB-16", 16, TIFF_RGGB, false } }, + { formats::SGRBG16, { "GRBG-16", 16, TIFF_GRBG, false } }, + { formats::SBGGR16, { "BGGR-16", 16, TIFF_BGGR, false } }, + { formats::SGBRG16, { "GBRG-16", 16, TIFF_GBRG, false } }, + + { formats::R10_CSI2P, { "BGGR-10", 10, TIFF_BGGR, true } }, + { formats::R10, { "BGGR-10", 10, TIFF_BGGR, false } }, // Currently not in the main libcamera branch //{ formats::R12_CSI2P, { "BGGR-12", 12, TIFF_BGGR, true } }, - { formats::R12, { "BGGR-12", 12, TIFF_BGGR, false, false } }, - - /* PiSP compressed formats. */ - { formats::RGGB16_PISP_COMP1, { "RGGB-16-PISP", 16, TIFF_RGGB, false, true } }, - { formats::GRBG16_PISP_COMP1, { "GRBG-16-PISP", 16, TIFF_GRBG, false, true } }, - { formats::GBRG16_PISP_COMP1, { "GBRG-16-PISP", 16, TIFF_GBRG, false, true } }, - { formats::BGGR16_PISP_COMP1, { "BGGR-16-PISP", 16, TIFF_BGGR, false, true } }, + { formats::R12, { "BGGR-12", 12, TIFF_BGGR, false } }, }; static void unpack_10bit(uint8_t const *src, StreamInfo const &info, uint16_t *dest) @@ -124,129 +117,6 @@ static void unpack_16bit(uint8_t const *src, StreamInfo const &info, uint16_t *d } } -// We always use these compression parameters. -#define COMPRESS_OFFSET 2048 -#define COMPRESS_MODE 1 - -static uint16_t postprocess(uint16_t a) -{ - if (COMPRESS_MODE & 2) - { - if (COMPRESS_MODE == 3 && a < 0x4000) - a = a >> 2; - else if (a < 0x1000) - a = a >> 4; - else if (a < 0x1800) - a = (a - 0x800) >> 3; - else if (a < 0x3000) - a = (a - 0x1000) >> 2; - else if (a < 0x6000) - a = (a - 0x2000) >> 1; - else if (a < 0xC000) - a = (a - 0x4000); - else - a = 2 * (a - 0x8000); - } - - return std::min(0xFFFF, a + COMPRESS_OFFSET); -} - -static uint16_t dequantize(uint16_t q, int qmode) -{ - switch (qmode) - { - case 0: - return (q < 320) ? 16 * q : 32 * (q - 160); - - case 1: - return 64 * q; - - case 2: - return 128 * q; - - default: - return (q < 94) ? 256 * q : std::min(0xFFFF, 512 * (q - 47)); - } -} - -static void subBlockFunction(uint16_t *d, uint32_t w) -{ - int q[4]; - - int qmode = (w & 3); - if (qmode < 3) - { - int field0 = (w >> 2) & 511; - int field1 = (w >> 11) & 127; - int field2 = (w >> 18) & 127; - int field3 = (w >> 25) & 127; - if (qmode == 2 && field0 >= 384) - { - q[1] = field0; - q[2] = field1 + 384; - } - else - { - q[1] = (field1 >= 64) ? field0 : field0 + 64 - field1; - q[2] = (field1 >= 64) ? field0 + field1 - 64 : field0; - } - int p1 = std::max(0, q[1] - 64); - if (qmode == 2) - p1 = std::min(384, p1); - int p2 = std::max(0, q[2] - 64); - if (qmode == 2) - p2 = std::min(384, p2); - q[0] = p1 + field2; - q[3] = p2 + field3; - } - else - { - int pack0 = (w >> 2) & 32767; - int pack1 = (w >> 17) & 32767; - q[0] = (pack0 & 15) + 16 * ((pack0 >> 8) / 11); - q[1] = (pack0 >> 4) % 176; - q[2] = (pack1 & 15) + 16 * ((pack1 >> 8) / 11); - q[3] = (pack1 >> 4) % 176; - } - - d[0] = dequantize(q[0], qmode); - d[2] = dequantize(q[1], qmode); - d[4] = dequantize(q[2], qmode); - d[6] = dequantize(q[3], qmode); -} - -static void uncompress(uint8_t const *src, StreamInfo const &info, uint16_t *dest) -{ - // In all cases, the *decompressed* image must be a multiple of 8 columns wide. - unsigned int buf_stride_pixels = (info.width + 7) & ~7; - for (unsigned int y = 0; y < info.height; ++y) - { - uint16_t *dp = dest + y * buf_stride_pixels; - uint8_t const *sp = src + y * info.stride; - - for (unsigned int x = 0; x < info.width; x+=8) - { - if (COMPRESS_MODE & 1) - { - uint32_t w0 = 0, w1 = 0; - for (int b = 0; b < 4; ++b) - w0 |= (*sp++) << (b * 8); - for (int b = 0; b < 4; ++b) - w1 |= (*sp++) << (b * 8); - subBlockFunction(dp, w0); - subBlockFunction(dp + 1, w1); - for (int i = 0; i < 8; ++i, ++dp) - *dp = postprocess(*dp); - } - else - { - for (int i = 0; i < 8; ++i) - *dp++ = postprocess((*sp++) << 8); - } - } - } -} - struct Matrix { Matrix(float m0, float m1, float m2, @@ -307,16 +177,8 @@ void dng_save(std::vector> const &mem, StreamInfo const BayerFormat const &bayer_format = it->second; LOG(1, "Bayer format is " << bayer_format.name); - // Decompression will require a buffer that's 8 pixels aligned. - unsigned int buf_stride_pixels = info.width; - unsigned int buf_stride_pixels_padded = (buf_stride_pixels + 7) & ~7; - std::vector buf(buf_stride_pixels_padded * info.height); - if (bayer_format.compressed) - { - uncompress(mem[0].data(), info, &buf[0]); - buf_stride_pixels = buf_stride_pixels_padded; - } - else if (bayer_format.packed) + std::vector buf(info.width * info.height); + if (bayer_format.packed) { switch (bayer_format.bits) { @@ -444,9 +306,8 @@ void dng_save(std::vector> const &mem, StreamInfo const { for (unsigned int x = 0; x < (info.width >> 4); x++) { - unsigned int off = (y * buf_stride_pixels + x) << 4; - uint32_t grey = - buf[off] + buf[off + 1] + buf[off + buf_stride_pixels] + buf[off + buf_stride_pixels + 1]; + unsigned int off = (y * info.width + x) << 4; + uint32_t grey = buf[off] + buf[off + 1] + buf[off + info.width] + buf[off + info.width + 1]; grey = (grey << 14) >> bayer_format.bits; grey = sqrt((double)grey); // simple "gamma correction" thumb_buf[3 * x] = thumb_buf[3 * x + 1] = thumb_buf[3 * x + 2] = grey; @@ -478,7 +339,7 @@ void dng_save(std::vector> const &mem, StreamInfo const for (unsigned int y = 0; y < info.height; y++) { - if (TIFFWriteScanline(tif, &buf[buf_stride_pixels * y], y, 0) != 1) + if (TIFFWriteScanline(tif, &buf[info.width * y], y, 0) != 1) throw std::runtime_error("error writing DNG image data"); }