| From 500f1e9eaeca29b255d0364e1383d70ade1d1177 Mon Sep 17 00:00:00 2001 |
| From: Martin Jansa <martin.jansa@gmail.com> |
| 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<PixelFormat, BayerFormat> 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<libcamera::Span<uint8_t>> 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<uint16_t> 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<uint16_t> buf(info.width * info.height); |
| + if (bayer_format.packed) |
| { |
| switch (bayer_format.bits) |
| { |
| @@ -444,9 +306,8 @@ void dng_save(std::vector<libcamera::Span<uint8_t>> 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<libcamera::Span<uint8_t>> 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"); |
| } |
| |