Files
pdf/engine/src/image/decoder/sample_decoder.cpp
T

82 lines
3.1 KiB
C++
Raw Normal View History

2026-08-01 16:19:11 +05:30
#include "sample_decoder.hpp"
#include <algorithm>
namespace pdfengine {
std::vector<uint8_t> SampleDecoder::unpackSamples(const std::vector<uint8_t>& rawBytes,
int width,
int height,
int components,
int bitsPerComponent) {
if (rawBytes.empty() || width <= 0 || height <= 0 || components <= 0) {
return {};
}
if (bitsPerComponent == 8) {
return rawBytes;
}
const size_t expectedSamples = static_cast<size_t>(width) * height * components;
std::vector<uint8_t> unpacked;
unpacked.reserve(expectedSamples);
if (bitsPerComponent == 1) {
for (int y = 0; y < height; ++y) {
int samplesInRow = width * components;
int bytesInRow = (samplesInRow + 7) / 8;
size_t rowOffset = static_cast<size_t>(y) * bytesInRow;
if (rowOffset >= rawBytes.size()) break;
for (int s = 0; s < samplesInRow; ++s) {
size_t byteIdx = rowOffset + (s / 8);
if (byteIdx >= rawBytes.size()) break;
uint8_t b = rawBytes[byteIdx];
uint8_t bit = (b >> (7 - (s % 8))) & 1;
unpacked.push_back(bit ? 255 : 0);
}
}
} else if (bitsPerComponent == 2) {
for (int y = 0; y < height; ++y) {
int samplesInRow = width * components;
int bytesInRow = (samplesInRow + 3) / 4;
size_t rowOffset = static_cast<size_t>(y) * bytesInRow;
if (rowOffset >= rawBytes.size()) break;
for (int s = 0; s < samplesInRow; ++s) {
size_t byteIdx = rowOffset + (s / 4);
if (byteIdx >= rawBytes.size()) break;
uint8_t b = rawBytes[byteIdx];
uint8_t val = (b >> (6 - 2 * (s % 4))) & 0x03;
unpacked.push_back(static_cast<uint8_t>(val * 85)); // 0x03 -> 255
}
}
} else if (bitsPerComponent == 4) {
for (int y = 0; y < height; ++y) {
int samplesInRow = width * components;
int bytesInRow = (samplesInRow + 1) / 2;
size_t rowOffset = static_cast<size_t>(y) * bytesInRow;
if (rowOffset >= rawBytes.size()) break;
for (int s = 0; s < samplesInRow; ++s) {
size_t byteIdx = rowOffset + (s / 2);
if (byteIdx >= rawBytes.size()) break;
uint8_t b = rawBytes[byteIdx];
uint8_t val = (s % 2 == 0) ? ((b >> 4) & 0x0F) : (b & 0x0F);
unpacked.push_back(static_cast<uint8_t>(val * 17)); // 0x0F -> 255
}
}
} else if (bitsPerComponent == 16) {
// Take upper 8 bits of each 16-bit sample
for (size_t i = 0; i + 1 < rawBytes.size() && unpacked.size() < expectedSamples; i += 2) {
unpacked.push_back(rawBytes[i]);
}
} else {
// Fallback pass-through
return rawBytes;
}
return unpacked;
}
} // namespace pdfengine