X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpeg12.c;h=7c140529ec8dc708c286941f5c759e14e745ddb4;hb=31fe3c4d23aab8b43614b1ea825603080775677e;hp=e8a4048222bf83de919a89c3f9f40635c3d0ac17;hpb=1c417bad613dafe77e266f57bbbdf5165c701a54;p=ffmpeg diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index e8a4048222b..7c140529ec8 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -243,3 +243,98 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, return END_NOT_FOUND; } +#define MAX_INDEX (64 - 1) + +int ff_mpeg1_decode_block_intra(GetBitContext *gb, + const uint16_t *quant_matrix, + uint8_t *const scantable, int last_dc[3], + int16_t *block, int index, int qscale) +{ + int dc, diff, i = 0, component; + RLTable *rl = &ff_rl_mpeg1; + + /* DC coefficient */ + component = index <= 3 ? 0 : index - 4 + 1; + + diff = decode_dc(gb, component); + if (diff >= 0xffff) + return AVERROR_INVALIDDATA; + + dc = last_dc[component]; + dc += diff; + last_dc[component] = dc; + + block[0] = dc * quant_matrix[0]; + + { + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + if (((int32_t)GET_CACHE(re, gb)) <= (int32_t)0xBFFFFFFF) + goto end; + + /* now quantify & encode AC coefficients */ + while (1) { + int level, run, j; + + GET_RL_VLC(level, run, re, gb, rl->rl_vlc[0], + TEX_VLC_BITS, 2, 0); + + if (level != 0) { + i += run; + if (i > MAX_INDEX) + break; + + j = scantable[i]; + level = (level * qscale * quant_matrix[j]) >> 4; + level = (level - 1) | 1; + level = (level ^ SHOW_SBITS(re, gb, 1)) - + SHOW_SBITS(re, gb, 1); + SKIP_BITS(re, gb, 1); + } else { + /* escape */ + run = SHOW_UBITS(re, gb, 6) + 1; + LAST_SKIP_BITS(re, gb, 6); + UPDATE_CACHE(re, gb); + level = SHOW_SBITS(re, gb, 8); + SKIP_BITS(re, gb, 8); + + if (level == -128) { + level = SHOW_UBITS(re, gb, 8) - 256; + SKIP_BITS(re, gb, 8); + } else if (level == 0) { + level = SHOW_UBITS(re, gb, 8); + SKIP_BITS(re, gb, 8); + } + + i += run; + if (i > MAX_INDEX) + break; + + j = scantable[i]; + if (level < 0) { + level = -level; + level = (level * qscale * quant_matrix[j]) >> 4; + level = (level - 1) | 1; + level = -level; + } else { + level = (level * qscale * quant_matrix[j]) >> 4; + level = (level - 1) | 1; + } + } + + block[j] = level; + if (((int32_t)GET_CACHE(re, gb)) <= (int32_t)0xBFFFFFFF) + break; + + UPDATE_CACHE(re, gb); + } +end: + LAST_SKIP_BITS(re, gb, 2); + CLOSE_READER(re, gb); + } + + if (i > MAX_INDEX) + i = AVERROR_INVALIDDATA; + + return i; +}