Skip to content

Commit

Permalink
Do not overflow/underflow intermediate predictions
Browse files Browse the repository at this point in the history
  • Loading branch information
kmilos committed Jan 8, 2022
1 parent 8e0c81d commit bb1526a
Showing 1 changed file with 26 additions and 23 deletions.
49 changes: 26 additions & 23 deletions src/librawspeed/decompressors/LJpegDecompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,9 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
h);

auto ht = getHuffmanTables<N_COMP>();
auto pred = getInitialPredictors<N_COMP>();
uint16_t* predNext = pred.data();
auto predInit = getInitialPredictors<N_COMP>();
uint16_t* predNext = predInit.data();
std::array<int32_t, N_COMP> pred;

BitPumpJPEG bitStream(input);

Expand All @@ -191,7 +192,9 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
for (unsigned row = 0; row < h; ++row) {
unsigned col = 0;

copy_n(predNext, N_COMP, pred.data());
for (int i = 0; i != N_COMP; ++i) {
pred[i] = predNext[i];
}
// the predictor for the next line is the start of this line
predNext = &img(row, col);
// the predictor mode is always horizontal on the first line
Expand All @@ -206,30 +209,30 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
img(row, col + i) =
uint16_t(pred[i] + ht[i]->decodeDifference(bitStream));
if (col < N_COMP * (fullBlocks - 1)) {
int predA = img(row, col + i);
int predB = predMode > 1 ? img(row - 1, col + N_COMP + i) : 0;
int predC = predMode > 1 ? img(row - 1, col + i) : 0;
int32_t predA = img(row, col + i);
int32_t predB = predMode > 1 ? img(row - 1, col + N_COMP + i) : 0;
int32_t predC = predMode > 1 ? img(row - 1, col + i) : 0;
switch (predMode) {
case 1:
pred[i] = uint16_t(predA);
pred[i] = predA;
break;
case 2:
pred[i] = uint16_t(predB);
pred[i] = predB;
break;
case 3:
pred[i] = uint16_t(predC);
pred[i] = predC;
break;
case 4:
pred[i] = uint16_t(predA + predB - predC);
pred[i] = predA + predB - predC;
break;
case 5:
pred[i] = uint16_t(predA + ((predB - predC) >> 1));
pred[i] = predA + ((predB - predC) >> 1);
break;
case 6:
pred[i] = uint16_t(predB + ((predA - predC) >> 1));
pred[i] = predB + ((predA - predC) >> 1);
break;
case 7:
pred[i] = uint16_t((predA + predB) >> 1);
pred[i] = (predA + predB) >> 1;
break;
default:
ThrowRDE("Unsupported predictor mode: %u", predMode);
Expand All @@ -250,30 +253,30 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
unsigned c = 0;
for (; c < trailingPixels; ++c) {
// Continue predictor update skipped at last full block
int predA = img(row, col - N_COMP + c);
int predB = predMode > 1 ? img(row - 1, col + c) : 0;
int predC = predMode > 1 ? img(row - 1, col - N_COMP + c) : 0;
int32_t predA = img(row, col - N_COMP + c);
int32_t predB = predMode > 1 ? img(row - 1, col + c) : 0;
int32_t predC = predMode > 1 ? img(row - 1, col - N_COMP + c) : 0;
switch (predMode) {
case 1:
pred[c] = uint16_t(predA);
pred[c] = predA;
break;
case 2:
pred[c] = uint16_t(predB);
pred[c] = predB;
break;
case 3:
pred[c] = uint16_t(predC);
pred[c] = predC;
break;
case 4:
pred[c] = uint16_t(predA + predB - predC);
pred[c] = predA + predB - predC;
break;
case 5:
pred[c] = uint16_t(predA + ((predB - predC) >> 1));
pred[c] = predA + ((predB - predC) >> 1);
break;
case 6:
pred[c] = uint16_t(predB + ((predA - predC) >> 1));
pred[c] = predB + ((predA - predC) >> 1);
break;
case 7:
pred[c] = uint16_t((predA + predB) >> 1);
pred[c] = (predA + predB) >> 1;
break;
default:
ThrowRDE("Unsupported predictor mode: %u", predMode);
Expand Down

0 comments on commit bb1526a

Please sign in to comment.