Browse Source

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>
tags/n3.1
Michael Niedermayer 9 years ago
parent
commit
deaf58abf2
1 changed files with 37 additions and 15 deletions
  1. +37
    -15
      libavcodec/mjpegdec.c

+ 37
- 15
libavcodec/mjpegdec.c View File

@@ -1375,11 +1375,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) {
@@ -1390,15 +1386,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];
@@ -1419,12 +1410,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;
}
@@ -1432,6 +1417,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)
{
@@ -2174,6 +2194,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,


Loading…
Cancel
Save