Skip to content

Commit 8b286cc

Browse files
njhollinghurstnaushir
authored andcommitted
image: dng: Add support for 16-bit Bayer formats
Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
1 parent aa849e6 commit 8b286cc

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

image/dng.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,18 @@ static const std::map<PixelFormat, BayerFormat> bayer_formats =
4444
{ formats::SGRBG12_CSI2P, { "GRBG-12", 12, TIFF_GRBG } },
4545
{ formats::SBGGR12_CSI2P, { "BGGR-12", 12, TIFF_BGGR } },
4646
{ formats::SGBRG12_CSI2P, { "GBRG-12", 12, TIFF_GBRG } },
47+
{ formats::SRGGB16, { "RGGB-16", 16, TIFF_RGGB } },
48+
{ formats::SGRBG16, { "GRBG-16", 16, TIFF_GRBG } },
49+
{ formats::SBGGR16, { "BGGR-16", 16, TIFF_BGGR } },
50+
{ formats::SGBRG16, { "GBRG-16", 16, TIFF_GBRG } },
4751
};
4852

49-
static void unpack_10bit(uint8_t *src, StreamInfo const &info, uint16_t *dest)
53+
static void unpack_10bit(uint8_t const *src, StreamInfo const &info, uint16_t *dest)
5054
{
5155
unsigned int w_align = info.width & ~3;
5256
for (unsigned int y = 0; y < info.height; y++, src += info.stride)
5357
{
54-
uint8_t *ptr = src;
58+
uint8_t const *ptr = src;
5559
unsigned int x;
5660
for (x = 0; x < w_align; x += 4, ptr += 5)
5761
{
@@ -65,12 +69,12 @@ static void unpack_10bit(uint8_t *src, StreamInfo const &info, uint16_t *dest)
6569
}
6670
}
6771

68-
static void unpack_12bit(uint8_t *src, StreamInfo const &info, uint16_t *dest)
72+
static void unpack_12bit(uint8_t const *src, StreamInfo const &info, uint16_t *dest)
6973
{
7074
unsigned int w_align = info.width & ~1;
7175
for (unsigned int y = 0; y < info.height; y++, src += info.stride)
7276
{
73-
uint8_t *ptr = src;
77+
uint8_t const *ptr = src;
7478
unsigned int x;
7579
for (x = 0; x < w_align; x += 2, ptr += 3)
7680
{
@@ -82,6 +86,18 @@ static void unpack_12bit(uint8_t *src, StreamInfo const &info, uint16_t *dest)
8286
}
8387
}
8488

89+
static void unpack_16bit(uint8_t const *src, StreamInfo const &info, uint16_t *dest)
90+
{
91+
/* Assume the pixels in memory are already in native byte order */
92+
unsigned int w = info.width;
93+
for (unsigned int y = 0; y < info.height; y++)
94+
{
95+
memcpy(dest, src, 2 * w);
96+
dest += w;
97+
src += info.stride;
98+
}
99+
}
100+
85101
struct Matrix
86102
{
87103
Matrix(float m0, float m1, float m2,
@@ -144,14 +160,13 @@ void dng_save(std::vector<libcamera::Span<uint8_t>> const &mem, StreamInfo const
144160

145161
std::vector<uint16_t> buf(info.width * info.height);
146162
if (bayer_format.bits == 10)
147-
unpack_10bit((uint8_t *)mem[0].data(), info, &buf[0]);
163+
unpack_10bit(mem[0].data(), info, &buf[0]);
148164
else if (bayer_format.bits == 12)
149-
unpack_12bit((uint8_t *)mem[0].data(), info, &buf[0]);
165+
unpack_12bit(mem[0].data(), info, &buf[0]);
150166
else
151-
throw std::runtime_error("unsupported bit depth " + std::to_string(bayer_format.bits));
167+
unpack_16bit(mem[0].data(), info, &buf[0]);
152168

153169
// We need to fish out some metadata values for the DNG.
154-
155170
float black = 4096 * (1 << bayer_format.bits) / 65536.0;
156171
float black_levels[] = { black, black, black, black };
157172
auto bl = metadata.get(controls::SensorBlackLevels);

0 commit comments

Comments
 (0)