- idx = arith_get_prob(c, m->cum_prob);
-
- val = m->idx2sym[idx];
- model_update(m, idx);
-
- arith_normalise(c);
-
- return val;
-}
-
-static void pixctx_reset(PixContext *ctx)
-{
- int i, j, k;
-
- for (i = 0; i < ctx->cache_size; i++)
- ctx->cache[i] = i;
-
- model_reset(&ctx->cache_model);
- model_reset(&ctx->full_model);
-
- for (i = 0; i < 4; i++)
- for (j = 0; j < sec_order_sizes[i]; j++)
- for (k = 0; k < 4; k++)
- model_reset(&ctx->sec_models[i][j][k]);
-}
-
-static av_cold void pixctx_init(PixContext *ctx, int cache_size)
-{
- int i, j, k;
-
- ctx->cache_size = cache_size + 4;
- ctx->num_syms = cache_size;
-
- for (i = 0; i < ctx->cache_size; i++)
- ctx->cache[i] = i;
-
- model_init(&ctx->cache_model, ctx->num_syms + 1, THRESH_LOW);
- model_init(&ctx->full_model, 256, THRESH_HIGH);
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < sec_order_sizes[i]; j++) {
- for (k = 0; k < 4; k++) {
- model_init(&ctx->sec_models[i][j][k], 2 + i,
- i ? THRESH_LOW : THRESH_ADAPTIVE);
- }
- }
- }
-}
-
-static int decode_top_left_pixel(ArithCoder *acoder, PixContext *pctx)
-{
- int i, val, pix;
-
- val = arith_get_model_sym(acoder, &pctx->cache_model);
- if (val < pctx->num_syms) {
- pix = pctx->cache[val];
- } else {
- pix = arith_get_model_sym(acoder, &pctx->full_model);
- for (i = 0; i < pctx->cache_size - 1; i++)
- if (pctx->cache[i] == pix)
- break;
- val = i;
- }
- if (val) {
- for (i = val; i > 0; i--)
- pctx->cache[i] = pctx->cache[i - 1];
- pctx->cache[0] = pix;
- }
-
- return pix;
-}
-
-static int decode_pixel(ArithCoder *acoder, PixContext *pctx,
- uint8_t *ngb, int num_ngb)
-{
- int i, val, pix;
-
- val = arith_get_model_sym(acoder, &pctx->cache_model);
- if (val < pctx->num_syms) {
- int idx, j;
-
-
- idx = 0;
- for (i = 0; i < pctx->cache_size; i++) {
- for (j = 0; j < num_ngb; j++)
- if (pctx->cache[i] == ngb[j])
- break;
- if (j == num_ngb) {
- if (idx == val)
- break;
- idx++;
- }
- }
- val = FFMIN(i, pctx->cache_size - 1);
- pix = pctx->cache[val];
- } else {
- pix = arith_get_model_sym(acoder, &pctx->full_model);
- for (i = 0; i < pctx->cache_size - 1; i++)
- if (pctx->cache[i] == pix)
- break;
- val = i;
- }
- if (val) {
- for (i = val; i > 0; i--)
- pctx->cache[i] = pctx->cache[i - 1];
- pctx->cache[0] = pix;
- }
-
- return pix;
-}
-
-static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx,
- uint8_t *src, int stride, int x, int y,
- int has_right)
-{
- uint8_t neighbours[4];
- uint8_t ref_pix[4];
- int nlen;
- int layer = 0, sub;
- int pix;
- int i, j;
-
- if (!y) {
- memset(neighbours, src[-1], 4);
- } else {
- neighbours[TOP] = src[-stride];
- if (!x) {
- neighbours[TOP_LEFT] = neighbours[LEFT] = neighbours[TOP];
- } else {
- neighbours[TOP_LEFT] = src[-stride - 1];
- neighbours[ LEFT] = src[-1];
- }
- if (has_right)
- neighbours[TOP_RIGHT] = src[-stride + 1];
- else
- neighbours[TOP_RIGHT] = neighbours[TOP];
- }
-
- sub = 0;
- if (x >= 2 && src[-2] == neighbours[LEFT])
- sub = 1;
- if (y >= 2 && src[-2 * stride] == neighbours[TOP])
- sub |= 2;
-
- nlen = 1;
- ref_pix[0] = neighbours[0];
- for (i = 1; i < 4; i++) {
- for (j = 0; j < nlen; j++)
- if (ref_pix[j] == neighbours[i])
- break;
- if (j == nlen)
- ref_pix[nlen++] = neighbours[i];
- }
-
- switch (nlen) {
- case 1:
- case 4:
- layer = 0;
- break;
- case 2:
- if (neighbours[TOP] == neighbours[TOP_LEFT]) {
- if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
- layer = 3;
- else if (neighbours[LEFT] == neighbours[TOP_LEFT])
- layer = 2;
- else
- layer = 4;
- } else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) {
- if (neighbours[LEFT] == neighbours[TOP_LEFT])
- layer = 1;
- else
- layer = 5;
- } else if (neighbours[LEFT] == neighbours[TOP_LEFT]) {
- layer = 6;
- } else {
- layer = 0;
- }
- break;
- case 3:
- if (neighbours[TOP] == neighbours[TOP_LEFT])
- layer = 0;
- else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
- layer = 1;
- else if (neighbours[LEFT] == neighbours[TOP_LEFT])
- layer = 2;
- else if (neighbours[TOP_RIGHT] == neighbours[TOP])
- layer = 3;
- else if (neighbours[TOP] == neighbours[LEFT])
- layer = 4;
- else
- layer = 5;
- break;
- }
-
- pix = arith_get_model_sym(acoder, &pctx->sec_models[nlen - 1][layer][sub]);
- if (pix < nlen)
- return ref_pix[pix];
- else
- return decode_pixel(acoder, pctx, ref_pix, nlen);
-}
-
-static int decode_region(MSS1Context *ctx, ArithCoder *acoder, uint8_t *dst,
- int x, int y, int width, int height, int stride,
- PixContext *pctx)
-{
- int i, j;
-
- dst += x + y * stride;
-
- dst[0] = decode_top_left_pixel(acoder, pctx);
- for (j = 0; j < height; j++) {
- for (i = 0; i < width; i++) {
- if (!i && !j)
- continue;
-
- dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride,
- i, j, width - i - 1);
- }
- dst += stride;
- }
-
- return 0;
-}
-
-static int decode_region_masked(MSS1Context *ctx, ArithCoder *acoder,
- uint8_t *dst, int stride, uint8_t *mask,
- int mask_stride, int x, int y,
- int width, int height,
- PixContext *pctx)
-{
- int i, j;
-
- dst += x + y * stride;
- mask += x + y * mask_stride;
-
- if (mask[0] == 0xFF)
- dst[0] = decode_top_left_pixel(acoder, pctx);
- for (j = 0; j < height; j++) {
- for (i = 0; i < width; i++) {
- if (!i && !j || mask[i] != 0xFF)
- continue;
-
- dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride,
- i, j, width - i - 1);
- }
- dst += stride;
- mask += mask_stride;
- }
-
- return 0;
-}
-
-static av_cold void codec_init(MSS1Context *ctx)
-{
- model_init(&ctx->intra_region, 2, THRESH_ADAPTIVE);
- model_init(&ctx->inter_region, 2, THRESH_ADAPTIVE);
- model_init(&ctx->split_mode, 3, THRESH_HIGH);
- model_init(&ctx->edge_mode, 2, THRESH_HIGH);
- model_init(&ctx->pivot, 3, THRESH_LOW);
- pixctx_init(&ctx->intra_pix_ctx, 8);
- pixctx_init(&ctx->inter_pix_ctx, 2);
- ctx->corrupted = 1;
-}
-
-static void codec_reset(MSS1Context *ctx)