@@ -173,7 +173,10 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
173
173
174
174
auto ht = getHuffmanTables<N_COMP>();
175
175
auto pred = getInitialPredictors<N_COMP>();
176
- uint16_t * predNext = pred.data ();
176
+ std::array<uint16_t , N_COMP> predNext;
177
+ for (int i = 0 ; i != N_COMP; ++i) {
178
+ predNext[i] = uint16_t (pred);
179
+ }
177
180
178
181
BitPumpJPEG bitStream (input);
179
182
@@ -191,9 +194,9 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
191
194
for (unsigned row = 0 ; row < h; ++row) {
192
195
unsigned col = 0 ;
193
196
194
- copy_n (predNext, N_COMP, pred. data ());
195
- // the predictor for the next line is the start of this line
196
- predNext = & img (row, col);
197
+ for ( int i = 0 ; i != N_COMP; ++i) {
198
+ pred[i] = predNext[i];
199
+ }
197
200
// the predictor mode is always horizontal on the first line
198
201
uint32_t predMode = row == 0 ? 1 : predictorMode;
199
202
@@ -204,32 +207,32 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
204
207
for (; col < N_COMP * fullBlocks; col += N_COMP) {
205
208
for (int i = 0 ; i != N_COMP; ++i) {
206
209
img (row, col + i) =
207
- uint16_t (pred[i] + ht[i]->decodeDifference (bitStream));
210
+ uint16_t (pred[i] + uint16_t ( ht[i]->decodeDifference (bitStream) ));
208
211
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 ;
212
215
switch (predMode) {
213
216
case 1 :
214
- pred[i] = uint16_t ( predA) ;
217
+ pred[i] = predA;
215
218
break ;
216
219
case 2 :
217
- pred[i] = uint16_t ( predB) ;
220
+ pred[i] = predB;
218
221
break ;
219
222
case 3 :
220
- pred[i] = uint16_t ( predC) ;
223
+ pred[i] = predC;
221
224
break ;
222
225
case 4 :
223
- pred[i] = uint16_t ( predA + predB - predC) ;
226
+ pred[i] = predA + predB - predC;
224
227
break ;
225
228
case 5 :
226
- pred[i] = uint16_t ( predA + ((predB - predC) >> 1 ) );
229
+ pred[i] = predA + ((predB - predC) >> 1 );
227
230
break ;
228
231
case 6 :
229
- pred[i] = uint16_t ( predB + ((predA - predC) >> 1 ) );
232
+ pred[i] = predB + ((predA - predC) >> 1 );
230
233
break ;
231
234
case 7 :
232
- pred[i] = uint16_t (( predA + predB) >> 1 ) ;
235
+ pred[i] = ( predA + predB) >> 1 ;
233
236
break ;
234
237
default :
235
238
ThrowRDE (" Unsupported predictor mode: %u" , predMode);
@@ -238,6 +241,11 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
238
241
}
239
242
}
240
243
244
+ // the predictor for the next line is the start of this decoded line
245
+ for (int i = 0 ; i != N_COMP; ++i) {
246
+ predNext[i] = img (row, i);
247
+ }
248
+
241
249
// Sometimes we also need to consume one more block, and produce part of it.
242
250
if /* constexpr*/ (WeirdWidth) {
243
251
// FIXME: evaluate i-cache implications due to this being compile-time.
@@ -250,36 +258,36 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
250
258
unsigned c = 0 ;
251
259
for (; c < trailingPixels; ++c) {
252
260
// 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 ;
261
+ int32_t predA = img (row, col - N_COMP + c);
262
+ int32_t predB = predMode > 1 ? img (row - 1 , col + c) : 0 ;
263
+ int32_t predC = predMode > 1 ? img (row - 1 , col - N_COMP + c) : 0 ;
256
264
switch (predMode) {
257
265
case 1 :
258
- pred[c] = uint16_t ( predA) ;
266
+ pred[c] = predA;
259
267
break ;
260
268
case 2 :
261
- pred[c] = uint16_t ( predB) ;
269
+ pred[c] = predB;
262
270
break ;
263
271
case 3 :
264
- pred[c] = uint16_t ( predC) ;
272
+ pred[c] = predC;
265
273
break ;
266
274
case 4 :
267
- pred[c] = uint16_t ( predA + predB - predC) ;
275
+ pred[c] = predA + predB - predC;
268
276
break ;
269
277
case 5 :
270
- pred[c] = uint16_t ( predA + ((predB - predC) >> 1 ) );
278
+ pred[c] = predA + ((predB - predC) >> 1 );
271
279
break ;
272
280
case 6 :
273
- pred[c] = uint16_t ( predB + ((predA - predC) >> 1 ) );
281
+ pred[c] = predB + ((predA - predC) >> 1 );
274
282
break ;
275
283
case 7 :
276
- pred[c] = uint16_t (( predA + predB) >> 1 ) ;
284
+ pred[c] = ( predA + predB) >> 1 ;
277
285
break ;
278
286
default :
279
287
ThrowRDE (" Unsupported predictor mode: %u" , predMode);
280
288
}
281
289
img (row, col + c) =
282
- uint16_t (pred[c] + ht[c]->decodeDifference (bitStream));
290
+ uint16_t (pred[c] + uint16_t ( ht[c]->decodeDifference (bitStream) ));
283
291
}
284
292
// Discard the rest of the block.
285
293
assert (c < N_COMP);
0 commit comments