diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2016-05-02 12:45:14 +0200 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2016-05-02 23:59:14 +0200 |
commit | 342b6d371895cd036a626d6dc8cf17650e8ffc0a (patch) | |
tree | 7ac24b39511a8acf2efd61b550ba645e5342a65a | |
parent | 74b8c4a60bb9af340773b82b7c64833af15ae612 (diff) | |
download | ffmpeg-342b6d371895cd036a626d6dc8cf17650e8ffc0a.tar.gz |
avcodec/mjpegdec: Do not try to detect last scan but apply idct after all scans for progressive jpeg
Fixes: IMG-20160418-WA0002.jpg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit deaf58abf236e09fc9b97db29f1edd064e4b5ad4)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavcodec/mjpegdec.c | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 22a852d4a5..d69474f439 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1342,11 +1342,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int mb_x, mb_y; int EOBRUN = 0; int c = s->comp_index[0]; - uint8_t *data = s->picture_ptr->data[c]; - int linesize = s->linesize[c]; - int last_scan = 0; int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]]; - int bytes_per_pixel = 1 + (s->bits > 8); av_assert0(ss>=0 && Ah>=0 && Al>=0); if (se < ss || se > 63) { @@ -1357,15 +1353,10 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, // s->coefs_finished is a bitmask for coefficients coded // ss and se are parameters telling start and end coefficients s->coefs_finished[c] |= (2ULL << se) - (1ULL << ss); - last_scan = !Al && !~s->coefs_finished[c]; - - if (s->interlaced && s->bottom_field) - data += linesize >> 1; s->restart_count = 0; for (mb_y = 0; mb_y < s->mb_height; mb_y++) { - uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres); int block_idx = mb_y * s->block_stride[c]; int16_t (*block)[64] = &s->blocks[c][block_idx]; uint8_t *last_nnz = &s->last_nnz[c][block_idx]; @@ -1386,12 +1377,6 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, return AVERROR_INVALIDDATA; } - if (last_scan) { - s->idsp.idct_put(ptr, linesize, *block); - if (s->bits & 7) - shift_output(s, ptr, linesize); - ptr += bytes_per_pixel*8 >> s->avctx->lowres; - } if (handle_rstn(s, 0)) EOBRUN = 0; } @@ -1399,6 +1384,41 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, return 0; } +static void mjpeg_idct_scan_progressive_ac(MJpegDecodeContext *s) +{ + int mb_x, mb_y; + int c; + const int bytes_per_pixel = 1 + (s->bits > 8); + const int block_size = s->lossless ? 1 : 8; + + for (c = 0; c < s->nb_components; c++) { + uint8_t *data = s->picture_ptr->data[c]; + int linesize = s->linesize[c]; + int h = s->h_max / s->h_count[c]; + int v = s->v_max / s->v_count[c]; + int mb_width = (s->width + h * block_size - 1) / (h * block_size); + int mb_height = (s->height + v * block_size - 1) / (v * block_size); + + if (~s->coefs_finished[c]) + av_log(s->avctx, AV_LOG_WARNING, "component %d is incomplete\n", c); + + if (s->interlaced && s->bottom_field) + data += linesize >> 1; + + for (mb_y = 0; mb_y < mb_height; mb_y++) { + uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres); + int block_idx = mb_y * s->block_stride[c]; + int16_t (*block)[64] = &s->blocks[c][block_idx]; + for (mb_x = 0; mb_x < mb_width; mb_x++, block++) { + s->idsp.idct_put(ptr, linesize, *block); + if (s->bits & 7) + shift_output(s, ptr, linesize); + ptr += bytes_per_pixel*8 >> s->avctx->lowres; + } + } + } +} + int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, int mb_bitmask_size, const AVFrame *reference) { @@ -2081,6 +2101,8 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, break; case EOI: eoi_parser: + if (avctx->skip_frame != AVDISCARD_ALL && s->progressive && s->cur_scan && s->got_picture) + mjpeg_idct_scan_progressive_ac(s); s->cur_scan = 0; if (!s->got_picture) { av_log(avctx, AV_LOG_WARNING, |