2 * Copyright (c) 2012 Konstantin Shishkov
4 * This file is part of Libav.
6 * Libav 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.
11 * Libav 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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Libav; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * Common functions for Microsoft Screen 1 and 2
28 #include "libavutil/intfloat.h"
29 #include "libavutil/intreadwrite.h"
39 static const int sec_order_sizes
[4] = { 1, 7, 6, 1 };
41 enum ContextDirection
{
48 static int model_calc_threshold(Model
*m
)
52 thr
= 2 * m
->weights
[m
->num_syms
] - 1;
53 thr
= ((thr
>> 1) + 4 * m
->cum_prob
[0]) / thr
;
55 return FFMIN(thr
, 0x3FFF);
58 static void model_reset(Model
*m
)
62 for (i
= 0; i
<= m
->num_syms
; i
++) {
64 m
->cum_prob
[i
] = m
->num_syms
- i
;
67 for (i
= 0; i
< m
->num_syms
; i
++)
68 m
->idx2sym
[i
+ 1] = i
;
71 static av_cold
void model_init(Model
*m
, int num_syms
, int thr_weight
)
73 m
->num_syms
= num_syms
;
74 m
->thr_weight
= thr_weight
;
75 m
->threshold
= num_syms
* thr_weight
;
78 static void model_rescale_weights(Model
*m
)
83 if (m
->thr_weight
== THRESH_ADAPTIVE
)
84 m
->threshold
= model_calc_threshold(m
);
85 while (m
->cum_prob
[0] > m
->threshold
) {
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
];
95 void ff_mss12_model_update(Model
*m
, int val
)
99 if (m
->weights
[val
] == m
->weights
[val
- 1]) {
100 for (i
= val
; m
->weights
[i
- 1] == m
->weights
[val
]; i
--);
104 sym1
= m
->idx2sym
[val
];
105 sym2
= m
->idx2sym
[i
];
107 m
->idx2sym
[val
] = sym2
;
108 m
->idx2sym
[i
] = sym1
;
114 for (i
= val
- 1; i
>= 0; i
--)
116 model_rescale_weights(m
);
119 static void pixctx_reset(PixContext
*ctx
)
123 if (!ctx
->special_initial_cache
)
124 for (i
= 0; i
< ctx
->cache_size
; i
++)
132 model_reset(&ctx
->cache_model
);
133 model_reset(&ctx
->full_model
);
135 for (i
= 0; i
< 15; i
++)
136 for (j
= 0; j
< 4; j
++)
137 model_reset(&ctx
->sec_models
[i
][j
]);
140 static av_cold
void pixctx_init(PixContext
*ctx
, int cache_size
,
141 int full_model_syms
, int special_initial_cache
)
145 ctx
->cache_size
= cache_size
+ 4;
146 ctx
->num_syms
= cache_size
;
147 ctx
->special_initial_cache
= special_initial_cache
;
149 model_init(&ctx
->cache_model
, ctx
->num_syms
+ 1, THRESH_LOW
);
150 model_init(&ctx
->full_model
, full_model_syms
, THRESH_HIGH
);
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
,
156 i
? THRESH_LOW
: THRESH_ADAPTIVE
);
159 static av_always_inline
int decode_pixel(ArithCoder
*acoder
, PixContext
*pctx
,
160 uint8_t *ngb
, int num_ngb
, int any_ngb
)
164 val
= acoder
->get_model_sym(acoder
, &pctx
->cache_model
);
165 if (val
< pctx
->num_syms
) {
170 for (i
= 0; i
< pctx
->cache_size
; i
++) {
171 for (j
= 0; j
< num_ngb
; j
++)
172 if (pctx
->cache
[i
] == ngb
[j
])
180 val
= FFMIN(i
, pctx
->cache_size
- 1);
182 pix
= pctx
->cache
[val
];
184 pix
= acoder
->get_model_sym(acoder
, &pctx
->full_model
);
185 for (i
= 0; i
< pctx
->cache_size
- 1; i
++)
186 if (pctx
->cache
[i
] == pix
)
191 for (i
= val
; i
> 0; i
--)
192 pctx
->cache
[i
] = pctx
->cache
[i
- 1];
193 pctx
->cache
[0] = pix
;
199 static int decode_pixel_in_context(ArithCoder
*acoder
, PixContext
*pctx
,
200 uint8_t *src
, ptrdiff_t stride
, int x
, int y
,
203 uint8_t neighbours
[4];
211 memset(neighbours
, src
[-1], 4);
213 neighbours
[TOP
] = src
[-stride
];
215 neighbours
[TOP_LEFT
] = neighbours
[LEFT
] = neighbours
[TOP
];
217 neighbours
[TOP_LEFT
] = src
[-stride
- 1];
218 neighbours
[ LEFT
] = src
[-1];
221 neighbours
[TOP_RIGHT
] = src
[-stride
+ 1];
223 neighbours
[TOP_RIGHT
] = neighbours
[TOP
];
227 if (x
>= 2 && src
[-2] == neighbours
[LEFT
])
229 if (y
>= 2 && src
[-2 * stride
] == neighbours
[TOP
])
233 ref_pix
[0] = neighbours
[0];
234 for (i
= 1; i
< 4; i
++) {
235 for (j
= 0; j
< nlen
; j
++)
236 if (ref_pix
[j
] == neighbours
[i
])
239 ref_pix
[nlen
++] = neighbours
[i
];
247 if (neighbours
[TOP
] == neighbours
[TOP_LEFT
]) {
248 if (neighbours
[TOP_RIGHT
] == neighbours
[TOP_LEFT
])
250 else if (neighbours
[LEFT
] == neighbours
[TOP_LEFT
])
254 } else if (neighbours
[TOP_RIGHT
] == neighbours
[TOP_LEFT
]) {
255 if (neighbours
[LEFT
] == neighbours
[TOP_LEFT
])
259 } else if (neighbours
[LEFT
] == neighbours
[TOP_LEFT
]) {
266 if (neighbours
[TOP
] == neighbours
[TOP_LEFT
])
268 else if (neighbours
[TOP_RIGHT
] == neighbours
[TOP_LEFT
])
270 else if (neighbours
[LEFT
] == neighbours
[TOP_LEFT
])
272 else if (neighbours
[TOP_RIGHT
] == neighbours
[TOP
])
274 else if (neighbours
[TOP
] == neighbours
[LEFT
])
284 pix
= acoder
->get_model_sym(acoder
,
285 &pctx
->sec_models
[layer
][sub
]);
289 return decode_pixel(acoder
, pctx
, ref_pix
, nlen
, 1);
292 static int decode_region(ArithCoder
*acoder
, uint8_t *dst
, uint8_t *rgb_pic
,
293 int x
, int y
, int width
, int height
, ptrdiff_t stride
,
294 ptrdiff_t rgb_stride
, PixContext
*pctx
,
298 uint8_t *rgb_dst
= rgb_pic
+ x
* 3 + y
* rgb_stride
;
300 dst
+= x
+ y
* stride
;
302 for (j
= 0; j
< height
; j
++) {
303 for (i
= 0; i
< width
; i
++) {
305 p
= decode_pixel(acoder
, pctx
, NULL
, 0, 0);
307 p
= decode_pixel_in_context(acoder
, pctx
, dst
+ i
, stride
,
308 i
, j
, width
- i
- 1);
312 AV_WB24(rgb_dst
+ i
* 3, pal
[p
]);
315 rgb_dst
+= rgb_stride
;
321 static void copy_rectangles(MSS12Context
const *c
,
322 int x
, int y
, int width
, int height
)
327 for (j
= y
; j
< y
+ height
; j
++) {
328 memcpy(c
->rgb_pic
+ j
* c
->rgb_stride
+ x
* 3,
329 c
->last_rgb_pic
+ j
* c
->rgb_stride
+ x
* 3,
331 memcpy(c
->pal_pic
+ j
* c
->pal_stride
+ x
,
332 c
->last_pal_pic
+ j
* c
->pal_stride
+ x
,
337 static int motion_compensation(MSS12Context
const *c
,
338 int x
, int y
, int width
, int height
)
340 if (x
+ c
->mvX
< 0 || x
+ c
->mvX
+ width
> c
->avctx
->width
||
341 y
+ c
->mvY
< 0 || y
+ c
->mvY
+ height
> c
->avctx
->height
||
345 uint8_t *dst
= c
->pal_pic
+ x
+ y
* c
->pal_stride
;
346 uint8_t *rgb_dst
= c
->rgb_pic
+ x
* 3 + y
* c
->rgb_stride
;
352 if (c
->last_rgb_pic
) {
353 src
= c
->last_pal_pic
+ x
+ y
* c
->pal_stride
;
354 rgb_src
= c
->last_rgb_pic
+ x
* 3 + y
* c
->rgb_stride
;
356 src
= c
->pal_pic
+ x
+ y
* c
->pal_stride
;
357 rgb_src
= c
->rgb_pic
+ x
* 3 + y
* c
->rgb_stride
;
359 for (j
= 0; j
< height
; j
++) {
360 memmove(dst
, src
, width
);
361 memmove(rgb_dst
, rgb_src
, width
* 3);
362 dst
+= c
->pal_stride
;
363 src
+= c
->pal_stride
;
364 rgb_dst
+= c
->rgb_stride
;
365 rgb_src
+= c
->rgb_stride
;
371 static int decode_region_masked(MSS12Context
const *c
, ArithCoder
*acoder
,
372 uint8_t *dst
, ptrdiff_t stride
, uint8_t *mask
,
373 ptrdiff_t mask_stride
, int x
, int y
,
374 int width
, int height
,
378 uint8_t *rgb_dst
= c
->rgb_pic
+ x
* 3 + y
* c
->rgb_stride
;
380 dst
+= x
+ y
* stride
;
381 mask
+= x
+ y
* mask_stride
;
383 for (j
= 0; j
< height
; j
++) {
384 for (i
= 0; i
< width
; i
++) {
385 if (c
->avctx
->err_recognition
& AV_EF_EXPLODE
&&
386 ( c
->rgb_pic
&& mask
[i
] != 0x01 && mask
[i
] != 0x02 && mask
[i
] != 0x04 ||
387 !c
->rgb_pic
&& mask
[i
] != 0x80 && mask
[i
] != 0xFF))
390 if (mask
[i
] == 0x02) {
391 copy_rectangles(c
, x
+ i
, y
+ j
, 1, 1);
392 } else if (mask
[i
] == 0x04) {
393 if (motion_compensation(c
, x
+ i
, y
+ j
, 1, 1))
395 } else if (mask
[i
] != 0x80) {
397 p
= decode_pixel(acoder
, pctx
, NULL
, 0, 0);
399 p
= decode_pixel_in_context(acoder
, pctx
, dst
+ i
, stride
,
400 i
, j
, width
- i
- 1);
403 AV_WB24(rgb_dst
+ i
* 3, c
->pal
[p
]);
408 rgb_dst
+= c
->rgb_stride
;
414 static av_cold
void slicecontext_init(SliceContext
*sc
,
415 int version
, int full_model_syms
)
417 model_init(&sc
->intra_region
, 2, THRESH_ADAPTIVE
);
418 model_init(&sc
->inter_region
, 2, THRESH_ADAPTIVE
);
419 model_init(&sc
->split_mode
, 3, THRESH_HIGH
);
420 model_init(&sc
->edge_mode
, 2, THRESH_HIGH
);
421 model_init(&sc
->pivot
, 3, THRESH_LOW
);
423 pixctx_init(&sc
->intra_pix_ctx
, 8, full_model_syms
, 0);
425 pixctx_init(&sc
->inter_pix_ctx
, version
? 3 : 2,
426 full_model_syms
, version
? 1 : 0);
429 void ff_mss12_slicecontext_reset(SliceContext
*sc
)
431 model_reset(&sc
->intra_region
);
432 model_reset(&sc
->inter_region
);
433 model_reset(&sc
->split_mode
);
434 model_reset(&sc
->edge_mode
);
435 model_reset(&sc
->pivot
);
436 pixctx_reset(&sc
->intra_pix_ctx
);
437 pixctx_reset(&sc
->inter_pix_ctx
);
440 static int decode_pivot(SliceContext
*sc
, ArithCoder
*acoder
, int base
)
444 inv
= acoder
->get_model_sym(acoder
, &sc
->edge_mode
);
445 val
= acoder
->get_model_sym(acoder
, &sc
->pivot
) + 1;
448 if ((base
+ 1) / 2 - 2 <= 0)
451 val
= acoder
->get_number(acoder
, (base
+ 1) / 2 - 2) + 3;
457 return inv
? base
- val
: val
;
460 static int decode_region_intra(SliceContext
*sc
, ArithCoder
*acoder
,
461 int x
, int y
, int width
, int height
)
463 MSS12Context
const *c
= sc
->c
;
466 mode
= acoder
->get_model_sym(acoder
, &sc
->intra_region
);
469 int i
, j
, pix
, rgb_pix
;
470 ptrdiff_t stride
= c
->pal_stride
;
471 ptrdiff_t rgb_stride
= c
->rgb_stride
;
472 uint8_t *dst
= c
->pal_pic
+ x
+ y
* stride
;
473 uint8_t *rgb_dst
= c
->rgb_pic
+ x
* 3 + y
* rgb_stride
;
475 pix
= decode_pixel(acoder
, &sc
->intra_pix_ctx
, NULL
, 0, 0);
476 rgb_pix
= c
->pal
[pix
];
477 for (i
= 0; i
< height
; i
++, dst
+= stride
, rgb_dst
+= rgb_stride
) {
478 memset(dst
, pix
, width
);
480 for (j
= 0; j
< width
* 3; j
+= 3)
481 AV_WB24(rgb_dst
+ j
, rgb_pix
);
484 return decode_region(acoder
, c
->pal_pic
, c
->rgb_pic
,
485 x
, y
, width
, height
, c
->pal_stride
, c
->rgb_stride
,
486 &sc
->intra_pix_ctx
, &c
->pal
[0]);
492 static int decode_region_inter(SliceContext
*sc
, ArithCoder
*acoder
,
493 int x
, int y
, int width
, int height
)
495 MSS12Context
const *c
= sc
->c
;
498 mode
= acoder
->get_model_sym(acoder
, &sc
->inter_region
);
501 mode
= decode_pixel(acoder
, &sc
->inter_pix_ctx
, NULL
, 0, 0);
503 if (c
->avctx
->err_recognition
& AV_EF_EXPLODE
&&
504 ( c
->rgb_pic
&& mode
!= 0x01 && mode
!= 0x02 && mode
!= 0x04 ||
505 !c
->rgb_pic
&& mode
!= 0x80 && mode
!= 0xFF))
509 copy_rectangles(c
, x
, y
, width
, height
);
510 else if (mode
== 0x04)
511 return motion_compensation(c
, x
, y
, width
, height
);
512 else if (mode
!= 0x80)
513 return decode_region_intra(sc
, acoder
, x
, y
, width
, height
);
515 if (decode_region(acoder
, c
->mask
, NULL
,
516 x
, y
, width
, height
, c
->mask_stride
, 0,
517 &sc
->inter_pix_ctx
, &c
->pal
[0]) < 0)
519 return decode_region_masked(c
, acoder
, c
->pal_pic
,
520 c
->pal_stride
, c
->mask
,
529 int ff_mss12_decode_rect(SliceContext
*sc
, ArithCoder
*acoder
,
530 int x
, int y
, int width
, int height
)
534 mode
= acoder
->get_model_sym(acoder
, &sc
->split_mode
);
538 if ((pivot
= decode_pivot(sc
, acoder
, height
)) < 1)
540 if (ff_mss12_decode_rect(sc
, acoder
, x
, y
, width
, pivot
))
542 if (ff_mss12_decode_rect(sc
, acoder
, x
, y
+ pivot
, width
, height
- pivot
))
546 if ((pivot
= decode_pivot(sc
, acoder
, width
)) < 1)
548 if (ff_mss12_decode_rect(sc
, acoder
, x
, y
, pivot
, height
))
550 if (ff_mss12_decode_rect(sc
, acoder
, x
+ pivot
, y
, width
- pivot
, height
))
555 return decode_region_intra(sc
, acoder
, x
, y
, width
, height
);
557 return decode_region_inter(sc
, acoder
, x
, y
, width
, height
);
565 av_cold
int ff_mss12_decode_init(MSS12Context
*c
, int version
,
566 SliceContext
* sc1
, SliceContext
*sc2
)
568 AVCodecContext
*avctx
= c
->avctx
;
571 if (avctx
->extradata_size
< 52 + 256 * 3) {
572 av_log(avctx
, AV_LOG_ERROR
, "Insufficient extradata size %d\n",
573 avctx
->extradata_size
);
574 return AVERROR_INVALIDDATA
;
577 if (AV_RB32(avctx
->extradata
) < avctx
->extradata_size
) {
578 av_log(avctx
, AV_LOG_ERROR
,
579 "Insufficient extradata size: expected %"PRIu32
" got %d\n",
580 AV_RB32(avctx
->extradata
),
581 avctx
->extradata_size
);
582 return AVERROR_INVALIDDATA
;
585 avctx
->coded_width
= AV_RB32(avctx
->extradata
+ 20);
586 avctx
->coded_height
= AV_RB32(avctx
->extradata
+ 24);
587 if (avctx
->coded_width
> 4096 || avctx
->coded_height
> 4096) {
588 av_log(avctx
, AV_LOG_ERROR
, "Frame dimensions %dx%d too large",
589 avctx
->coded_width
, avctx
->coded_height
);
590 return AVERROR_INVALIDDATA
;
592 if (avctx
->width
|| avctx
->height
) {
593 if (avctx
->width
<= 0 || avctx
->width
> avctx
->coded_width
||
594 avctx
->height
<= 0 || avctx
->height
> avctx
->coded_height
) {
595 av_log(avctx
, AV_LOG_ERROR
, "Invalid display dimensions\n");
596 return AVERROR_INVALIDDATA
;
599 avctx
->width
= avctx
->coded_width
;
600 avctx
->height
= avctx
->coded_height
;
603 av_log(avctx
, AV_LOG_DEBUG
, "Encoder version %"PRIu32
".%"PRIu32
"\n",
604 AV_RB32(avctx
->extradata
+ 4), AV_RB32(avctx
->extradata
+ 8));
605 if (version
!= AV_RB32(avctx
->extradata
+ 4) > 1) {
606 av_log(avctx
, AV_LOG_ERROR
,
607 "Header version doesn't match codec tag\n");
611 c
->free_colours
= AV_RB32(avctx
->extradata
+ 48);
612 if ((unsigned)c
->free_colours
> 256) {
613 av_log(avctx
, AV_LOG_ERROR
,
614 "Incorrect number of changeable palette entries: %d\n",
616 return AVERROR_INVALIDDATA
;
618 av_log(avctx
, AV_LOG_DEBUG
, "%d free colour(s)\n", c
->free_colours
);
620 av_log(avctx
, AV_LOG_DEBUG
, "Display dimensions %"PRIu32
"x%"PRIu32
"\n",
621 AV_RB32(avctx
->extradata
+ 12), AV_RB32(avctx
->extradata
+ 16));
622 av_log(avctx
, AV_LOG_DEBUG
, "Coded dimensions %dx%d\n",
623 avctx
->coded_width
, avctx
->coded_height
);
624 av_log(avctx
, AV_LOG_DEBUG
, "%g frames per second\n",
625 av_int2float(AV_RB32(avctx
->extradata
+ 28)));
626 av_log(avctx
, AV_LOG_DEBUG
, "Bitrate %"PRIu32
" bps\n",
627 AV_RB32(avctx
->extradata
+ 32));
628 av_log(avctx
, AV_LOG_DEBUG
, "Max. lead time %g ms\n",
629 av_int2float(AV_RB32(avctx
->extradata
+ 36)));
630 av_log(avctx
, AV_LOG_DEBUG
, "Max. lag time %g ms\n",
631 av_int2float(AV_RB32(avctx
->extradata
+ 40)));
632 av_log(avctx
, AV_LOG_DEBUG
, "Max. seek time %g ms\n",
633 av_int2float(AV_RB32(avctx
->extradata
+ 44)));
636 if (avctx
->extradata_size
< 60 + 256 * 3) {
637 av_log(avctx
, AV_LOG_ERROR
,
638 "Insufficient extradata size %d for v2\n",
639 avctx
->extradata_size
);
640 return AVERROR_INVALIDDATA
;
643 c
->slice_split
= AV_RB32(avctx
->extradata
+ 52);
644 av_log(avctx
, AV_LOG_DEBUG
, "Slice split %d\n", c
->slice_split
);
646 c
->full_model_syms
= AV_RB32(avctx
->extradata
+ 56);
647 if (c
->full_model_syms
< 2 || c
->full_model_syms
> 256) {
648 av_log(avctx
, AV_LOG_ERROR
,
649 "Incorrect number of used colours %d\n",
651 return AVERROR_INVALIDDATA
;
653 av_log(avctx
, AV_LOG_DEBUG
, "Used colours %d\n",
657 c
->full_model_syms
= 256;
660 for (i
= 0; i
< 256; i
++)
661 c
->pal
[i
] = AV_RB24(avctx
->extradata
+ 52 +
662 (version
? 8 : 0) + i
* 3);
664 c
->mask_stride
= FFALIGN(avctx
->width
, 16);
665 c
->mask
= av_malloc(c
->mask_stride
* avctx
->height
);
667 av_log(avctx
, AV_LOG_ERROR
, "Cannot allocate mask plane\n");
668 return AVERROR(ENOMEM
);
672 slicecontext_init(sc1
, version
, c
->full_model_syms
);
673 if (c
->slice_split
) {
675 slicecontext_init(sc2
, version
, c
->full_model_syms
);
682 av_cold
int ff_mss12_decode_end(MSS12Context
*c
)