Skip to content

Commit bb1526a

Browse files
committed
Do not overflow/underflow intermediate predictions
1 parent 8e0c81d commit bb1526a

1 file changed

Lines changed: 26 additions & 23 deletions

File tree

src/librawspeed/decompressors/LJpegDecompressor.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,9 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
172172
h);
173173

174174
auto ht = getHuffmanTables<N_COMP>();
175-
auto pred = getInitialPredictors<N_COMP>();
176-
uint16_t* predNext = pred.data();
175+
auto predInit = getInitialPredictors<N_COMP>();
176+
uint16_t* predNext = predInit.data();
177+
std::array<int32_t, N_COMP> pred;
177178

178179
BitPumpJPEG bitStream(input);
179180

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

194-
copy_n(predNext, N_COMP, pred.data());
195+
for (int i = 0; i != N_COMP; ++i) {
196+
pred[i] = predNext[i];
197+
}
195198
// the predictor for the next line is the start of this line
196199
predNext = &img(row, col);
197200
// the predictor mode is always horizontal on the first line
@@ -206,30 +209,30 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
206209
img(row, col + i) =
207210
uint16_t(pred[i] + ht[i]->decodeDifference(bitStream));
208211
if (col < N_COMP * (fullBlocks - 1)) {
209-
int predA = img(row, col + i);
210-
int predB = predMode > 1 ? img(row - 1, col + N_COMP + i) : 0;
211-
int predC = predMode > 1 ? img(row - 1, col + i) : 0;
212+
int32_t predA = img(row, col + i);
213+
int32_t predB = predMode > 1 ? img(row - 1, col + N_COMP + i) : 0;
214+
int32_t predC = predMode > 1 ? img(row - 1, col + i) : 0;
212215
switch (predMode) {
213216
case 1:
214-
pred[i] = uint16_t(predA);
217+
pred[i] = predA;
215218
break;
216219
case 2:
217-
pred[i] = uint16_t(predB);
220+
pred[i] = predB;
218221
break;
219222
case 3:
220-
pred[i] = uint16_t(predC);
223+
pred[i] = predC;
221224
break;
222225
case 4:
223-
pred[i] = uint16_t(predA + predB - predC);
226+
pred[i] = predA + predB - predC;
224227
break;
225228
case 5:
226-
pred[i] = uint16_t(predA + ((predB - predC) >> 1));
229+
pred[i] = predA + ((predB - predC) >> 1);
227230
break;
228231
case 6:
229-
pred[i] = uint16_t(predB + ((predA - predC) >> 1));
232+
pred[i] = predB + ((predA - predC) >> 1);
230233
break;
231234
case 7:
232-
pred[i] = uint16_t((predA + predB) >> 1);
235+
pred[i] = (predA + predB) >> 1;
233236
break;
234237
default:
235238
ThrowRDE("Unsupported predictor mode: %u", predMode);
@@ -250,30 +253,30 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
250253
unsigned c = 0;
251254
for (; c < trailingPixels; ++c) {
252255
// Continue predictor update skipped at last full block
253-
int predA = img(row, col - N_COMP + c);
254-
int predB = predMode > 1 ? img(row - 1, col + c) : 0;
255-
int predC = predMode > 1 ? img(row - 1, col - N_COMP + c) : 0;
256+
int32_t predA = img(row, col - N_COMP + c);
257+
int32_t predB = predMode > 1 ? img(row - 1, col + c) : 0;
258+
int32_t predC = predMode > 1 ? img(row - 1, col - N_COMP + c) : 0;
256259
switch (predMode) {
257260
case 1:
258-
pred[c] = uint16_t(predA);
261+
pred[c] = predA;
259262
break;
260263
case 2:
261-
pred[c] = uint16_t(predB);
264+
pred[c] = predB;
262265
break;
263266
case 3:
264-
pred[c] = uint16_t(predC);
267+
pred[c] = predC;
265268
break;
266269
case 4:
267-
pred[c] = uint16_t(predA + predB - predC);
270+
pred[c] = predA + predB - predC;
268271
break;
269272
case 5:
270-
pred[c] = uint16_t(predA + ((predB - predC) >> 1));
273+
pred[c] = predA + ((predB - predC) >> 1);
271274
break;
272275
case 6:
273-
pred[c] = uint16_t(predB + ((predA - predC) >> 1));
276+
pred[c] = predB + ((predA - predC) >> 1);
274277
break;
275278
case 7:
276-
pred[c] = uint16_t((predA + predB) >> 1);
279+
pred[c] = (predA + predB) >> 1;
277280
break;
278281
default:
279282
ThrowRDE("Unsupported predictor mode: %u", predMode);

0 commit comments

Comments
 (0)