Commit 6d856b25 authored by Paul B Mahol's avatar Paul B Mahol

avcodec/scpr: add support for older version

Signed-off-by: 's avatarPaul B Mahol <onemda@gmail.com>
parent 7e9ba78f
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
typedef struct RangeCoder { typedef struct RangeCoder {
unsigned code; unsigned code;
unsigned range; unsigned range;
unsigned code1;
} RangeCoder; } RangeCoder;
typedef struct PixelModel { typedef struct PixelModel {
...@@ -60,10 +61,14 @@ typedef struct SCPRContext { ...@@ -60,10 +61,14 @@ typedef struct SCPRContext {
unsigned *blocks; unsigned *blocks;
unsigned cbits; unsigned cbits;
int cxshift; int cxshift;
int (*get_freq)(RangeCoder *rc, unsigned total_freq, unsigned *freq);
void (*decode)(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq);
} SCPRContext; } SCPRContext;
static void init_rangecoder(RangeCoder *rc, GetByteContext *gb) static void init_rangecoder(RangeCoder *rc, GetByteContext *gb)
{ {
rc->code1 = 0;
rc->range = 0xFFFFFFFFU; rc->range = 0xFFFFFFFFU;
rc->code = bytestream2_get_be32(gb); rc->code = bytestream2_get_be32(gb);
} }
...@@ -152,6 +157,31 @@ static int get_freq(RangeCoder *rc, unsigned total_freq, unsigned *freq) ...@@ -152,6 +157,31 @@ static int get_freq(RangeCoder *rc, unsigned total_freq, unsigned *freq)
return 0; return 0;
} }
static void decode0(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq)
{
int t = rc->range * (uint64_t)cumFreq / total_freq;
rc->code1 += t + 1;
rc->range = rc->range * (uint64_t)(freq + cumFreq) / total_freq - (t + 1);
while (rc->range < TOP && bytestream2_get_bytes_left(gb) > 0) {
unsigned byte = bytestream2_get_byte(gb);
rc->code = (rc->code << 8) | byte;
rc->code1 <<= 8;
rc->range <<= 8;
}
}
static int get_freq0(RangeCoder *rc, unsigned total_freq, unsigned *freq)
{
if (rc->range == 0)
return AVERROR_INVALIDDATA;
*freq = total_freq * (uint64_t)(rc->code - rc->code1) / rc->range;
return 0;
}
static int decode_value(SCPRContext *s, unsigned *cnt, unsigned maxc, unsigned step, unsigned *rval) static int decode_value(SCPRContext *s, unsigned *cnt, unsigned maxc, unsigned step, unsigned *rval)
{ {
GetByteContext *gb = &s->gb; GetByteContext *gb = &s->gb;
...@@ -161,7 +191,7 @@ static int decode_value(SCPRContext *s, unsigned *cnt, unsigned maxc, unsigned s ...@@ -161,7 +191,7 @@ static int decode_value(SCPRContext *s, unsigned *cnt, unsigned maxc, unsigned s
unsigned c = 0, cumfr = 0, cnt_c = 0; unsigned c = 0, cumfr = 0, cnt_c = 0;
int i, ret; int i, ret;
if ((ret = get_freq(rc, totfr, &value)) < 0) if ((ret = s->get_freq(rc, totfr, &value)) < 0)
return ret; return ret;
while (c < maxc) { while (c < maxc) {
...@@ -172,7 +202,7 @@ static int decode_value(SCPRContext *s, unsigned *cnt, unsigned maxc, unsigned s ...@@ -172,7 +202,7 @@ static int decode_value(SCPRContext *s, unsigned *cnt, unsigned maxc, unsigned s
break; break;
c++; c++;
} }
decode(gb, rc, cumfr, cnt_c, totfr); s->decode(gb, rc, cumfr, cnt_c, totfr);
cnt[c] = cnt_c + step; cnt[c] = cnt_c + step;
totfr += step; totfr += step;
...@@ -199,7 +229,7 @@ static int decode_unit(SCPRContext *s, PixelModel *pixel, unsigned step, unsigne ...@@ -199,7 +229,7 @@ static int decode_unit(SCPRContext *s, PixelModel *pixel, unsigned step, unsigne
unsigned value, x = 0, cumfr = 0, cnt_x = 0; unsigned value, x = 0, cumfr = 0, cnt_x = 0;
int i, j, ret, c, cnt_c; int i, j, ret, c, cnt_c;
if ((ret = get_freq(rc, totfr, &value)) < 0) if ((ret = s->get_freq(rc, totfr, &value)) < 0)
return ret; return ret;
while (x < 16) { while (x < 16) {
...@@ -221,7 +251,7 @@ static int decode_unit(SCPRContext *s, PixelModel *pixel, unsigned step, unsigne ...@@ -221,7 +251,7 @@ static int decode_unit(SCPRContext *s, PixelModel *pixel, unsigned step, unsigne
break; break;
c++; c++;
} }
decode(gb, rc, cumfr, cnt_c, totfr); s->decode(gb, rc, cumfr, cnt_c, totfr);
pixel->freq[c] = cnt_c + step; pixel->freq[c] = cnt_c + step;
pixel->lookup[x] = cnt_x + step; pixel->lookup[x] = cnt_x + step;
totfr += step; totfr += step;
...@@ -695,7 +725,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ...@@ -695,7 +725,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
type = bytestream2_peek_byte(gb); type = bytestream2_peek_byte(gb);
if (type == 18) { if (type == 2) {
s->get_freq = get_freq0;
s->decode = decode0;
frame->key_frame = 1;
ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0],
s->current_frame->linesize[0] / 4);
} else if (type == 18) {
s->get_freq = get_freq;
s->decode = decode;
frame->key_frame = 1; frame->key_frame = 1;
ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0], ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0],
s->current_frame->linesize[0] / 4); s->current_frame->linesize[0] / 4);
...@@ -785,6 +823,9 @@ static av_cold int decode_init(AVCodecContext *avctx) ...@@ -785,6 +823,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
s->get_freq = get_freq0;
s->decode = decode0;
s->cxshift = avctx->bits_per_coded_sample == 16 ? 0 : 2; s->cxshift = avctx->bits_per_coded_sample == 16 ? 0 : 2;
s->cbits = avctx->bits_per_coded_sample == 16 ? 0x1F : 0xFF; s->cbits = avctx->bits_per_coded_sample == 16 ? 0x1F : 0xFF;
s->nbx = (avctx->width + 15) / 16; s->nbx = (avctx->width + 15) / 16;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment