Skip to content

Commit a4dcf1a

Browse files
committed
support 16+ bits YUV file
1 parent 7b00bc4 commit a4dcf1a

6 files changed

Lines changed: 127 additions & 57 deletions

File tree

YUViewLib/src/video/yuv/PixelFormatYUV.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ PixelFormatYUV::PixelFormatYUV(const std::string &name)
174174
auto bitdepthStr = sm.str(3);
175175
size_t sz;
176176
int bitDepth = std::stoi(bitdepthStr, &sz);
177-
if (sz > 0 && bitDepth >= 8 && bitDepth <= 16)
177+
if (sz > 0 && bitDepth >= 8 && bitDepth <= 32)
178178
newFormat.bitsPerSample = bitDepth;
179179
}
180180

@@ -317,7 +317,7 @@ bool PixelFormatYUV::canConvertToRGB(Size imageSize, std::string *whyNot) const
317317
// Check the bit depth
318318
const int bps = this->bitsPerSample;
319319
bool canConvert = true;
320-
if (bps < 8 || bps > 16)
320+
if (bps < 8 || bps > 32)
321321
{
322322
if (whyNot)
323323
{
@@ -382,14 +382,14 @@ int64_t PixelFormatYUV::bytesPerFrame(const Size &frameSize) const
382382
}
383383

384384
int64_t bytes = 0;
385+
const auto bytesPerSample = get_min_standard_bytes(this->bitsPerSample); // Round to bytes
385386

386387
if (this->planar || !this->bytePacking)
387388
{
388389
// Add the bytes of the 3 (or 4) planes.
389390
// This also works for packed formats without byte packing. For these formats the number of
390391
// bytes are identical to the not packed formats, the bytes are just sorted in another way.
391392

392-
const auto bytesPerSample = (this->bitsPerSample + 7) / 8; // Round to bytes
393393
bytes += frameSize.width * frameSize.height * bytesPerSample; // Luma plane
394394
if (this->subsampling == Subsampling::YUV_444)
395395
bytes += frameSize.width * frameSize.height * bytesPerSample * 2; // U/V planes
@@ -426,17 +426,16 @@ int64_t PixelFormatYUV::bytesPerFrame(const Size &frameSize) const
426426
if (this->subsampling == Subsampling::YUV_422)
427427
{
428428
// All packing orders have 4 values per packed value (which has 2 Y samples)
429-
const auto bitsPerPixel = this->bitsPerSample * 4;
430-
return ((bitsPerPixel + 7) / 8) * (frameSize.width / 2) * frameSize.height;
429+
return 4 * bytesPerSample * (frameSize.width / 2) * frameSize.height;
431430
}
432431
// This is a packed format. The added number of bytes might be lower because of the packing.
433432
if (this->subsampling == Subsampling::YUV_444)
434433
{
435-
auto bitsPerPixel = this->bitsPerSample * 3;
434+
auto channels = 3;
436435
if (this->packingOrder == PackingOrder::AYUV || this->packingOrder == PackingOrder::YUVA ||
437436
this->packingOrder == PackingOrder::VUYA)
438-
bitsPerPixel += this->bitsPerSample;
439-
return ((bitsPerPixel + 7) / 8) * frameSize.width * frameSize.height;
437+
channels += 1;
438+
return channels * bytesPerSample * frameSize.width * frameSize.height;
440439
}
441440
// else if (subsampling == Subsampling::YUV_422 || subsampling == Subsampling::YUV_440)
442441
//{

YUViewLib/src/video/yuv/PixelFormatYUV.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ constexpr EnumMapper<PlaneOrder, 4> PlaneOrderMapper(std::make_pair(PlaneOrder::
184184
std::make_pair(PlaneOrder::YUVA, "YUVA"sv),
185185
std::make_pair(PlaneOrder::YVUA, "YVUA"sv));
186186

187-
const auto BitDepthList = std::vector<unsigned>({8, 9, 10, 12, 14, 16});
187+
const auto BitDepthList = std::vector<unsigned>({8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32});
188188

189189
// This class defines a specific YUV format with all properties like pixels per sample, subsampling
190190
// of chroma components and so on.
@@ -263,4 +263,21 @@ class PixelFormatYUV
263263
bool bytePacking{};
264264
};
265265

266+
inline uint64_t get_min_standard_bytes(uint64_t x) {
267+
if (x == 0)
268+
return 0;
269+
270+
if (x >= UINT64_MAX / 8) {
271+
return UINT64_MAX;
272+
}
273+
274+
x--;
275+
276+
for (int current_shift = 1; current_shift < 64; current_shift <<= 1) {
277+
x |= x >> current_shift;
278+
}
279+
280+
return (x + 8) >> 3;
281+
}
282+
266283
} // namespace video::yuv

YUViewLib/src/video/yuv/PixelFormatYUVGuess.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ Subsampling findSubsamplingTypeIndicatorInName(std::string name)
6363
std::vector<unsigned> getDetectionBitDepthList(unsigned forceAsFirst)
6464
{
6565
std::vector<unsigned> bitDepthList;
66-
if (forceAsFirst >= 8 && forceAsFirst <= 16)
66+
if (forceAsFirst >= 8 && forceAsFirst <= 32)
6767
bitDepthList.push_back(forceAsFirst);
6868

69-
for (auto bitDepth : {10u, 12u, 14u, 16u, 8u})
69+
for (auto bitDepth : BitDepthList)
7070
{
7171
if (!vectorContains(bitDepthList, bitDepth))
7272
bitDepthList.push_back(bitDepth);

0 commit comments

Comments
 (0)