FFmpeg  4.3.8
mss12.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Konstantin Shishkov
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * Common functions for Microsoft Screen 1 and 2
24  */
25 
26 #include <inttypes.h>
27 
28 #include "libavutil/intfloat.h"
29 #include "libavutil/intreadwrite.h"
30 #include "avcodec.h"
31 #include "mss12.h"
32 
33 enum SplitMode {
37 };
38 
39 static const int sec_order_sizes[4] = { 1, 7, 6, 1 };
40 
42  TOP_LEFT = 0,
43  TOP,
46 };
47 
49 {
50  int thr;
51 
52  thr = 2 * m->weights[m->num_syms] - 1;
53  thr = ((thr >> 1) + 4 * m->cum_prob[0]) / thr;
54 
55  return FFMIN(thr, 0x3FFF);
56 }
57 
58 static void model_reset(Model *m)
59 {
60  int i;
61 
62  for (i = 0; i <= m->num_syms; i++) {
63  m->weights[i] = 1;
64  m->cum_prob[i] = m->num_syms - i;
65  }
66  m->weights[0] = 0;
67  for (i = 0; i < m->num_syms; i++)
68  m->idx2sym[i + 1] = i;
69 }
70 
71 static av_cold void model_init(Model *m, int num_syms, int thr_weight)
72 {
73  m->num_syms = num_syms;
74  m->thr_weight = thr_weight;
75  m->threshold = num_syms * thr_weight;
76 }
77 
79 {
80  int i;
81  int cum_prob;
82 
83  if (m->thr_weight == THRESH_ADAPTIVE)
85  while (m->cum_prob[0] > m->threshold) {
86  cum_prob = 0;
87  for (i = m->num_syms; i >= 0; i--) {
88  m->cum_prob[i] = cum_prob;
89  m->weights[i] = (m->weights[i] + 1) >> 1;
90  cum_prob += m->weights[i];
91  }
92  }
93 }
94 
96 {
97  int i;
98 
99  if (m->weights[val] == m->weights[val - 1]) {
100  for (i = val; m->weights[i - 1] == m->weights[val]; i--);
101  if (i != val) {
102  int sym1, sym2;
103 
104  sym1 = m->idx2sym[val];
105  sym2 = m->idx2sym[i];
106 
107  m->idx2sym[val] = sym2;
108  m->idx2sym[i] = sym1;
109 
110  val = i;
111  }
112  }
113  m->weights[val]++;
114  for (i = val - 1; i >= 0; i--)
115  m->cum_prob[i]++;
117 }
118 
120 {
121  int i, j;
122 
123  if (!ctx->special_initial_cache)
124  for (i = 0; i < ctx->cache_size; i++)
125  ctx->cache[i] = i;
126  else {
127  ctx->cache[0] = 1;
128  ctx->cache[1] = 2;
129  ctx->cache[2] = 4;
130  }
131 
132  model_reset(&ctx->cache_model);
133  model_reset(&ctx->full_model);
134 
135  for (i = 0; i < 15; i++)
136  for (j = 0; j < 4; j++)
137  model_reset(&ctx->sec_models[i][j]);
138 }
139 
140 static av_cold void pixctx_init(PixContext *ctx, int cache_size,
141  int full_model_syms, int special_initial_cache)
142 {
143  int i, j, k, idx;
144 
145  ctx->cache_size = cache_size + 4;
146  ctx->num_syms = cache_size;
147  ctx->special_initial_cache = special_initial_cache;
148 
149  model_init(&ctx->cache_model, ctx->num_syms + 1, THRESH_LOW);
150  model_init(&ctx->full_model, full_model_syms, THRESH_HIGH);
151 
152  for (i = 0, idx = 0; i < 4; i++)
153  for (j = 0; j < sec_order_sizes[i]; j++, idx++)
154  for (k = 0; k < 4; k++)
155  model_init(&ctx->sec_models[idx][k], 2 + i,
157 }
158 
160  uint8_t *ngb, int num_ngb, int any_ngb)
161 {
162  int i, val, pix;
163 
164  if (acoder->overread > MAX_OVERREAD)
165  return AVERROR_INVALIDDATA;
166  val = acoder->get_model_sym(acoder, &pctx->cache_model);
167  if (val < pctx->num_syms) {
168  if (any_ngb) {
169  int idx, j;
170 
171  idx = 0;
172  for (i = 0; i < pctx->cache_size; i++) {
173  for (j = 0; j < num_ngb; j++)
174  if (pctx->cache[i] == ngb[j])
175  break;
176  if (j == num_ngb) {
177  if (idx == val)
178  break;
179  idx++;
180  }
181  }
182  val = FFMIN(i, pctx->cache_size - 1);
183  }
184  pix = pctx->cache[val];
185  } else {
186  pix = acoder->get_model_sym(acoder, &pctx->full_model);
187  for (i = 0; i < pctx->cache_size - 1; i++)
188  if (pctx->cache[i] == pix)
189  break;
190  val = i;
191  }
192  if (val) {
193  for (i = val; i > 0; i--)
194  pctx->cache[i] = pctx->cache[i - 1];
195  pctx->cache[0] = pix;
196  }
197 
198  return pix;
199 }
200 
202  uint8_t *src, ptrdiff_t stride, int x, int y,
203  int has_right)
204 {
205  uint8_t neighbours[4];
206  uint8_t ref_pix[4];
207  int nlen;
208  int layer = 0, sub;
209  int pix;
210  int i, j;
211 
212  if (!y) {
213  memset(neighbours, src[-1], 4);
214  } else {
215  neighbours[TOP] = src[-stride];
216  if (!x) {
217  neighbours[TOP_LEFT] = neighbours[LEFT] = neighbours[TOP];
218  } else {
219  neighbours[TOP_LEFT] = src[-stride - 1];
220  neighbours[ LEFT] = src[-1];
221  }
222  if (has_right)
223  neighbours[TOP_RIGHT] = src[-stride + 1];
224  else
225  neighbours[TOP_RIGHT] = neighbours[TOP];
226  }
227 
228  sub = 0;
229  if (x >= 2 && src[-2] == neighbours[LEFT])
230  sub = 1;
231  if (y >= 2 && src[-2 * stride] == neighbours[TOP])
232  sub |= 2;
233 
234  nlen = 1;
235  ref_pix[0] = neighbours[0];
236  for (i = 1; i < 4; i++) {
237  for (j = 0; j < nlen; j++)
238  if (ref_pix[j] == neighbours[i])
239  break;
240  if (j == nlen)
241  ref_pix[nlen++] = neighbours[i];
242  }
243 
244  switch (nlen) {
245  case 1:
246  layer = 0;
247  break;
248  case 2:
249  if (neighbours[TOP] == neighbours[TOP_LEFT]) {
250  if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
251  layer = 1;
252  else if (neighbours[LEFT] == neighbours[TOP_LEFT])
253  layer = 2;
254  else
255  layer = 3;
256  } else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) {
257  if (neighbours[LEFT] == neighbours[TOP_LEFT])
258  layer = 4;
259  else
260  layer = 5;
261  } else if (neighbours[LEFT] == neighbours[TOP_LEFT]) {
262  layer = 6;
263  } else {
264  layer = 7;
265  }
266  break;
267  case 3:
268  if (neighbours[TOP] == neighbours[TOP_LEFT])
269  layer = 8;
270  else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
271  layer = 9;
272  else if (neighbours[LEFT] == neighbours[TOP_LEFT])
273  layer = 10;
274  else if (neighbours[TOP_RIGHT] == neighbours[TOP])
275  layer = 11;
276  else if (neighbours[TOP] == neighbours[LEFT])
277  layer = 12;
278  else
279  layer = 13;
280  break;
281  case 4:
282  layer = 14;
283  break;
284  }
285 
286  pix = acoder->get_model_sym(acoder,
287  &pctx->sec_models[layer][sub]);
288  if (pix < nlen)
289  return ref_pix[pix];
290  else
291  return decode_pixel(acoder, pctx, ref_pix, nlen, 1);
292 }
293 
294 static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic,
295  int x, int y, int width, int height, ptrdiff_t stride,
296  ptrdiff_t rgb_stride, PixContext *pctx,
297  const uint32_t *pal)
298 {
299  int i, j, p;
300  uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride;
301 
302  dst += x + y * stride;
303 
304  for (j = 0; j < height; j++) {
305  for (i = 0; i < width; i++) {
306  if (!i && !j)
307  p = decode_pixel(acoder, pctx, NULL, 0, 0);
308  else
309  p = decode_pixel_in_context(acoder, pctx, dst + i, stride,
310  i, j, width - i - 1);
311  if (p < 0)
312  return p;
313  dst[i] = p;
314 
315  if (rgb_pic)
316  AV_WB24(rgb_dst + i * 3, pal[p]);
317  }
318  dst += stride;
319  rgb_dst += rgb_stride;
320  }
321 
322  return 0;
323 }
324 
325 static void copy_rectangles(MSS12Context const *c,
326  int x, int y, int width, int height)
327 {
328  int j;
329 
330  if (c->last_rgb_pic)
331  for (j = y; j < y + height; j++) {
332  memcpy(c->rgb_pic + j * c->rgb_stride + x * 3,
333  c->last_rgb_pic + j * c->rgb_stride + x * 3,
334  width * 3);
335  memcpy(c->pal_pic + j * c->pal_stride + x,
336  c->last_pal_pic + j * c->pal_stride + x,
337  width);
338  }
339 }
340 
342  int x, int y, int width, int height)
343 {
344  if (x + c->mvX < 0 || x + c->mvX + width > c->avctx->width ||
345  y + c->mvY < 0 || y + c->mvY + height > c->avctx->height ||
346  !c->rgb_pic)
347  return -1;
348  else {
349  uint8_t *dst = c->pal_pic + x + y * c->pal_stride;
350  uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * c->rgb_stride;
351  uint8_t *src;
352  uint8_t *rgb_src;
353  int j;
354  x += c->mvX;
355  y += c->mvY;
356  if (c->last_rgb_pic) {
357  src = c->last_pal_pic + x + y * c->pal_stride;
358  rgb_src = c->last_rgb_pic + x * 3 + y * c->rgb_stride;
359  } else {
360  src = c->pal_pic + x + y * c->pal_stride;
361  rgb_src = c->rgb_pic + x * 3 + y * c->rgb_stride;
362  }
363  for (j = 0; j < height; j++) {
364  memmove(dst, src, width);
365  memmove(rgb_dst, rgb_src, width * 3);
366  dst += c->pal_stride;
367  src += c->pal_stride;
368  rgb_dst += c->rgb_stride;
369  rgb_src += c->rgb_stride;
370  }
371  }
372  return 0;
373 }
374 
375 static int decode_region_masked(MSS12Context const *c, ArithCoder *acoder,
376  uint8_t *dst, ptrdiff_t stride, uint8_t *mask,
377  ptrdiff_t mask_stride, int x, int y,
378  int width, int height,
379  PixContext *pctx)
380 {
381  int i, j, p;
382  uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * c->rgb_stride;
383 
384  dst += x + y * stride;
385  mask += x + y * mask_stride;
386 
387  for (j = 0; j < height; j++) {
388  for (i = 0; i < width; i++) {
389  if (c->avctx->err_recognition & AV_EF_EXPLODE &&
390  ( c->rgb_pic && mask[i] != 0x01 && mask[i] != 0x02 && mask[i] != 0x04 ||
391  !c->rgb_pic && mask[i] != 0x80 && mask[i] != 0xFF))
392  return -1;
393 
394  if (mask[i] == 0x02) {
395  copy_rectangles(c, x + i, y + j, 1, 1);
396  } else if (mask[i] == 0x04) {
397  if (motion_compensation(c, x + i, y + j, 1, 1))
398  return -1;
399  } else if (mask[i] != 0x80) {
400  if (!i && !j)
401  p = decode_pixel(acoder, pctx, NULL, 0, 0);
402  else
403  p = decode_pixel_in_context(acoder, pctx, dst + i, stride,
404  i, j, width - i - 1);
405  if (p < 0)
406  return p;
407  dst[i] = p;
408  if (c->rgb_pic)
409  AV_WB24(rgb_dst + i * 3, c->pal[p]);
410  }
411  }
412  dst += stride;
413  mask += mask_stride;
414  rgb_dst += c->rgb_stride;
415  }
416 
417  return 0;
418 }
419 
421  int version, int full_model_syms)
422 {
426  model_init(&sc->edge_mode, 2, THRESH_HIGH);
427  model_init(&sc->pivot, 3, THRESH_LOW);
428 
429  pixctx_init(&sc->intra_pix_ctx, 8, full_model_syms, 0);
430 
431  pixctx_init(&sc->inter_pix_ctx, version ? 3 : 2,
432  full_model_syms, version ? 1 : 0);
433 }
434 
436 {
439  model_reset(&sc->split_mode);
440  model_reset(&sc->edge_mode);
441  model_reset(&sc->pivot);
444 }
445 
446 static int decode_pivot(SliceContext *sc, ArithCoder *acoder, int base)
447 {
448  int val, inv;
449 
450  inv = acoder->get_model_sym(acoder, &sc->edge_mode);
451  val = acoder->get_model_sym(acoder, &sc->pivot) + 1;
452 
453  if (val > 2) {
454  if ((base + 1) / 2 - 2 <= 0)
455  return -1;
456 
457  val = acoder->get_number(acoder, (base + 1) / 2 - 2) + 3;
458  }
459 
460  if ((unsigned)val >= base)
461  return -1;
462 
463  return inv ? base - val : val;
464 }
465 
467  int x, int y, int width, int height)
468 {
469  MSS12Context const *c = sc->c;
470  int mode;
471 
472  mode = acoder->get_model_sym(acoder, &sc->intra_region);
473 
474  if (!mode) {
475  int i, j, pix, rgb_pix;
476  ptrdiff_t stride = c->pal_stride;
477  ptrdiff_t rgb_stride = c->rgb_stride;
478  uint8_t *dst = c->pal_pic + x + y * stride;
479  uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride;
480 
481  pix = decode_pixel(acoder, &sc->intra_pix_ctx, NULL, 0, 0);
482  if (pix < 0)
483  return pix;
484  rgb_pix = c->pal[pix];
485  for (i = 0; i < height; i++, dst += stride, rgb_dst += rgb_stride) {
486  memset(dst, pix, width);
487  if (c->rgb_pic)
488  for (j = 0; j < width * 3; j += 3)
489  AV_WB24(rgb_dst + j, rgb_pix);
490  }
491  } else {
492  return decode_region(acoder, c->pal_pic, c->rgb_pic,
493  x, y, width, height, c->pal_stride, c->rgb_stride,
494  &sc->intra_pix_ctx, &c->pal[0]);
495  }
496 
497  return 0;
498 }
499 
501  int x, int y, int width, int height)
502 {
503  MSS12Context const *c = sc->c;
504  int mode;
505 
506  mode = acoder->get_model_sym(acoder, &sc->inter_region);
507 
508  if (!mode) {
509  mode = decode_pixel(acoder, &sc->inter_pix_ctx, NULL, 0, 0);
510  if (mode < 0)
511  return mode;
512 
513  if (c->avctx->err_recognition & AV_EF_EXPLODE &&
514  ( c->rgb_pic && mode != 0x01 && mode != 0x02 && mode != 0x04 ||
515  !c->rgb_pic && mode != 0x80 && mode != 0xFF))
516  return -1;
517 
518  if (mode == 0x02)
519  copy_rectangles(c, x, y, width, height);
520  else if (mode == 0x04)
521  return motion_compensation(c, x, y, width, height);
522  else if (mode != 0x80)
523  return decode_region_intra(sc, acoder, x, y, width, height);
524  } else {
525  if (decode_region(acoder, c->mask, NULL,
526  x, y, width, height, c->mask_stride, 0,
527  &sc->inter_pix_ctx, &c->pal[0]) < 0)
528  return -1;
529  return decode_region_masked(c, acoder, c->pal_pic,
530  c->pal_stride, c->mask,
531  c->mask_stride,
532  x, y, width, height,
533  &sc->intra_pix_ctx);
534  }
535 
536  return 0;
537 }
538 
540  int x, int y, int width, int height)
541 {
542  int mode, pivot;
543  if (acoder->overread > MAX_OVERREAD)
544  return AVERROR_INVALIDDATA;
545 
546  mode = acoder->get_model_sym(acoder, &sc->split_mode);
547 
548  switch (mode) {
549  case SPLIT_VERT:
550  if ((pivot = decode_pivot(sc, acoder, height)) < 1)
551  return -1;
552  if (ff_mss12_decode_rect(sc, acoder, x, y, width, pivot))
553  return -1;
554  if (ff_mss12_decode_rect(sc, acoder, x, y + pivot, width, height - pivot))
555  return -1;
556  break;
557  case SPLIT_HOR:
558  if ((pivot = decode_pivot(sc, acoder, width)) < 1)
559  return -1;
560  if (ff_mss12_decode_rect(sc, acoder, x, y, pivot, height))
561  return -1;
562  if (ff_mss12_decode_rect(sc, acoder, x + pivot, y, width - pivot, height))
563  return -1;
564  break;
565  case SPLIT_NONE:
566  if (sc->c->keyframe)
567  return decode_region_intra(sc, acoder, x, y, width, height);
568  else
569  return decode_region_inter(sc, acoder, x, y, width, height);
570  default:
571  return -1;
572  }
573 
574  return 0;
575 }
576 
578  SliceContext* sc1, SliceContext *sc2)
579 {
580  AVCodecContext *avctx = c->avctx;
581  int i;
582 
583  if (avctx->extradata_size < 52 + 256 * 3) {
584  av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d\n",
585  avctx->extradata_size);
586  return AVERROR_INVALIDDATA;
587  }
588 
589  if (AV_RB32(avctx->extradata) < avctx->extradata_size) {
590  av_log(avctx, AV_LOG_ERROR,
591  "Insufficient extradata size: expected %"PRIu32" got %d\n",
592  AV_RB32(avctx->extradata),
593  avctx->extradata_size);
594  return AVERROR_INVALIDDATA;
595  }
596 
597  avctx->coded_width = FFMAX(AV_RB32(avctx->extradata + 20), avctx->width);
598  avctx->coded_height = FFMAX(AV_RB32(avctx->extradata + 24), avctx->height);
599  if (avctx->coded_width > 4096 || avctx->coded_height > 4096) {
600  av_log(avctx, AV_LOG_ERROR, "Frame dimensions %dx%d too large",
601  avctx->coded_width, avctx->coded_height);
602  return AVERROR_INVALIDDATA;
603  }
604  if (avctx->coded_width < 1 || avctx->coded_height < 1) {
605  av_log(avctx, AV_LOG_ERROR, "Frame dimensions %dx%d too small",
606  avctx->coded_width, avctx->coded_height);
607  return AVERROR_INVALIDDATA;
608  }
609 
610  av_log(avctx, AV_LOG_DEBUG, "Encoder version %"PRIu32".%"PRIu32"\n",
611  AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8));
612  if (version != AV_RB32(avctx->extradata + 4) > 1) {
613  av_log(avctx, AV_LOG_ERROR,
614  "Header version doesn't match codec tag\n");
615  return -1;
616  }
617 
618  c->free_colours = AV_RB32(avctx->extradata + 48);
619  if ((unsigned)c->free_colours > 256) {
620  av_log(avctx, AV_LOG_ERROR,
621  "Incorrect number of changeable palette entries: %d\n",
622  c->free_colours);
623  return AVERROR_INVALIDDATA;
624  }
625  av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours);
626 
627  av_log(avctx, AV_LOG_DEBUG, "Display dimensions %"PRIu32"x%"PRIu32"\n",
628  AV_RB32(avctx->extradata + 12), AV_RB32(avctx->extradata + 16));
629  av_log(avctx, AV_LOG_DEBUG, "Coded dimensions %dx%d\n",
630  avctx->coded_width, avctx->coded_height);
631  av_log(avctx, AV_LOG_DEBUG, "%g frames per second\n",
632  av_int2float(AV_RB32(avctx->extradata + 28)));
633  av_log(avctx, AV_LOG_DEBUG, "Bitrate %"PRIu32" bps\n",
634  AV_RB32(avctx->extradata + 32));
635  av_log(avctx, AV_LOG_DEBUG, "Max. lead time %g ms\n",
636  av_int2float(AV_RB32(avctx->extradata + 36)));
637  av_log(avctx, AV_LOG_DEBUG, "Max. lag time %g ms\n",
638  av_int2float(AV_RB32(avctx->extradata + 40)));
639  av_log(avctx, AV_LOG_DEBUG, "Max. seek time %g ms\n",
640  av_int2float(AV_RB32(avctx->extradata + 44)));
641 
642  if (version) {
643  if (avctx->extradata_size < 60 + 256 * 3) {
644  av_log(avctx, AV_LOG_ERROR,
645  "Insufficient extradata size %d for v2\n",
646  avctx->extradata_size);
647  return AVERROR_INVALIDDATA;
648  }
649 
650  c->slice_split = AV_RB32(avctx->extradata + 52);
651  av_log(avctx, AV_LOG_DEBUG, "Slice split %d\n", c->slice_split);
652 
653  c->full_model_syms = AV_RB32(avctx->extradata + 56);
654  if (c->full_model_syms < 2 || c->full_model_syms > 256) {
655  av_log(avctx, AV_LOG_ERROR,
656  "Incorrect number of used colours %d\n",
657  c->full_model_syms);
658  return AVERROR_INVALIDDATA;
659  }
660  av_log(avctx, AV_LOG_DEBUG, "Used colours %d\n",
661  c->full_model_syms);
662  } else {
663  c->slice_split = 0;
664  c->full_model_syms = 256;
665  }
666 
667  for (i = 0; i < 256; i++)
668  c->pal[i] = 0xFFU << 24 | AV_RB24(avctx->extradata + 52 +
669  (version ? 8 : 0) + i * 3);
670 
671  c->mask_stride = FFALIGN(avctx->width, 16);
672  c->mask = av_malloc_array(c->mask_stride, avctx->height);
673  if (!c->mask) {
674  av_log(avctx, AV_LOG_ERROR, "Cannot allocate mask plane\n");
675  return AVERROR(ENOMEM);
676  }
677 
678  sc1->c = c;
679  slicecontext_init(sc1, version, c->full_model_syms);
680  if (c->slice_split) {
681  sc2->c = c;
682  slicecontext_init(sc2, version, c->full_model_syms);
683  }
684  c->corrupted = 1;
685 
686  return 0;
687 }
688 
690 {
691  av_freep(&c->mask);
692 
693  return 0;
694 }
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
version
Definition: libkvazaar.c:292
PixContext inter_pix_ctx
Definition: mss12.h:74
int overread
Definition: mss12.h:50
int(* get_number)(struct ArithCoder *c, int n)
Definition: mss12.h:57
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:714
av_cold int ff_mss12_decode_init(MSS12Context *c, int version, SliceContext *sc1, SliceContext *sc2)
Definition: mss12.c:577
int(* get_model_sym)(struct ArithCoder *c, Model *m)
Definition: mss12.h:56
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
Definition: mss12.h:40
int corrupted
Definition: mss12.h:91
static void pixctx_reset(PixContext *ctx)
Definition: mss12.c:119
#define AV_RB24
Definition: intreadwrite.h:64
static int decode_region_inter(SliceContext *sc, ArithCoder *acoder, int x, int y, int width, int height)
Definition: mss12.c:500
int16_t weights[MODEL_MAX_SYMS+1]
Definition: mss12.h:42
uint8_t * rgb_pic
Definition: mss12.h:85
int stride
Definition: mace.c:144
int thr_weight
Definition: mss12.h:45
int ff_mss12_decode_rect(SliceContext *sc, ArithCoder *acoder, int x, int y, int width, int height)
Definition: mss12.c:539
uint8_t base
Definition: vp3data.h:202
static const int sec_order_sizes[4]
Definition: mss12.c:39
int slice_split
Definition: mss12.h:92
uint32_t pal[256]
Definition: mss12.h:79
uint8_t
uint8_t * last_pal_pic
Definition: mss12.h:81
#define av_cold
Definition: attributes.h:88
int keyframe
Definition: mss12.h:89
#define AV_RB32
Definition: intreadwrite.h:130
ptrdiff_t rgb_stride
Definition: mss12.h:87
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:627
Model inter_region
Definition: mss12.h:72
#define height
#define FFALIGN(x, a)
Definition: macros.h:48
Model full_model
Definition: mss12.h:63
#define av_log(a,...)
Model sec_models[15][4]
Definition: mss12.h:64
static av_cold void slicecontext_init(SliceContext *sc, int version, int full_model_syms)
Definition: mss12.c:420
#define src
Definition: vp8dsp.c:254
static int decode_region_intra(SliceContext *sc, ArithCoder *acoder, int x, int y, int width, int height)
Definition: mss12.c:466
Model pivot
Definition: mss12.h:73
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static const uint16_t mask[17]
Definition: lzw.c:38
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
static void model_rescale_weights(Model *m)
Definition: mss12.c:78
int full_model_syms
Definition: mss12.h:93
int mvY
Definition: mss12.h:90
int cache_size
Definition: mss12.h:61
#define FFMAX(a, b)
Definition: common.h:94
AVCodecContext * avctx
Definition: mss12.h:78
Model edge_mode
Definition: mss12.h:73
static int decode_pivot(SliceContext *sc, ArithCoder *acoder, int base)
Definition: mss12.c:446
static av_cold void pixctx_init(PixContext *ctx, int cache_size, int full_model_syms, int special_initial_cache)
Definition: mss12.c:140
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition: avcodec.h:1655
#define FFMIN(a, b)
Definition: common.h:96
static int model_calc_threshold(Model *m)
Definition: mss12.c:48
#define width
PixContext intra_pix_ctx
Definition: mss12.h:74
Definition: mss12.c:45
static int motion_compensation(MSS12Context const *c, int x, int y, int width, int height)
Definition: mss12.c:341
int width
picture width / height.
Definition: avcodec.h:699
Definition: mss12.c:43
AVFormatContext * ctx
Definition: movenc.c:48
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
ptrdiff_t pal_stride
Definition: mss12.h:82
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: avcodec.h:1666
struct MSS12Context * c
Definition: mss12.h:71
av_cold int ff_mss12_decode_end(MSS12Context *c)
Definition: mss12.c:689
Libavcodec external API header.
ContextDirection
Definition: mss12.c:41
uint8_t * mask
Definition: mss12.h:83
main external API structure.
Definition: avcodec.h:526
int num_syms
Definition: mss12.h:44
Model cache_model
Definition: mss12.h:63
#define THRESH_ADAPTIVE
Definition: mss12.h:36
int extradata_size
Definition: avcodec.h:628
int coded_height
Definition: avcodec.h:714
uint8_t idx2sym[MODEL_MAX_SYMS+1]
Definition: mss12.h:43
static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, uint8_t *src, ptrdiff_t stride, int x, int y, int has_right)
Definition: mss12.c:201
#define MAX_OVERREAD
Definition: lagarithrac.h:51
int special_initial_cache
Definition: mss12.h:65
Definition: mss12.c:42
static av_cold void model_init(Model *m, int num_syms, int thr_weight)
Definition: mss12.c:71
Model split_mode
Definition: mss12.h:73
static void model_reset(Model *m)
Definition: mss12.c:58
void ff_mss12_slicecontext_reset(SliceContext *sc)
Definition: mss12.c:435
static double c[64]
static av_always_inline int decode_pixel(ArithCoder *acoder, PixContext *pctx, uint8_t *ngb, int num_ngb, int any_ngb)
Definition: mss12.c:159
int threshold
Definition: mss12.h:45
static int decode_region_masked(MSS12Context const *c, ArithCoder *acoder, uint8_t *dst, ptrdiff_t stride, uint8_t *mask, ptrdiff_t mask_stride, int x, int y, int width, int height, PixContext *pctx)
Definition: mss12.c:375
void ff_mss12_model_update(Model *m, int val)
Definition: mss12.c:95
int free_colours
Definition: mss12.h:88
ptrdiff_t mask_stride
Definition: mss12.h:84
uint8_t * last_rgb_pic
Definition: mss12.h:86
static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, int x, int y, int width, int height, ptrdiff_t stride, ptrdiff_t rgb_stride, PixContext *pctx, const uint32_t *pal)
Definition: mss12.c:294
Model intra_region
Definition: mss12.h:72
#define THRESH_HIGH
Definition: mss12.h:38
#define av_freep(p)
#define av_always_inline
Definition: attributes.h:45
SplitMode
Definition: mss12.c:33
#define av_malloc_array(a, b)
int mvX
Definition: mss12.h:90
uint8_t cache[12]
Definition: mss12.h:62
#define THRESH_LOW
Definition: mss12.h:37
static double val(void *priv, double ch)
Definition: aeval.c:76
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
int num_syms
Definition: mss12.h:61
uint8_t * pal_pic
Definition: mss12.h:80
static void copy_rectangles(MSS12Context const *c, int x, int y, int width, int height)
Definition: mss12.c:325
int16_t cum_prob[MODEL_MAX_SYMS+1]
Definition: mss12.h:41
Common header for Microsoft Screen 1 and 2.