summaryrefslogtreecommitdiff
path: root/libavcodec/vc1dsp.c
diff options
context:
space:
mode:
authorAlberto Delmás <adelmas@gmail.com>2011-08-17 14:24:42 +0200
committerAnton Khirnov <anton@khirnov.net>2011-08-23 11:18:35 +0200
commit45ecda855405f102bcc5d8fbadc5f2376e8e9c42 (patch)
treee40dee592918dbe35b68dc943d15da93e294101c /libavcodec/vc1dsp.c
parent3be5a943514f4528056d91afb8347b3dc51f21d6 (diff)
Windows Media Image decoder (WMVP/WVP2)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Diffstat (limited to 'libavcodec/vc1dsp.c')
-rw-r--r--libavcodec/vc1dsp.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index 7d0e406677..4dd56727c7 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -713,6 +713,66 @@ static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
}
}
+#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
+
+static void sprite_h_c(uint8_t *dst, const uint8_t *src, int offset, int advance, int count)
+{
+ while (count--) {
+ int a = src[(offset >> 16) ];
+ int b = src[(offset >> 16) + 1];
+ *dst++ = a + ((b - a) * (offset&0xFFFF) >> 16);
+ offset += advance;
+ }
+}
+
+static av_always_inline void sprite_v_template(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
+ int two_sprites, const uint8_t *src2a, const uint8_t *src2b, int offset2,
+ int alpha, int scaled, int width)
+{
+ int a1, b1, a2, b2;
+ while (width--) {
+ a1 = *src1a++;
+ if (scaled) {
+ b1 = *src1b++;
+ a1 = a1 + ((b1 - a1) * offset1 >> 16);
+ }
+ if (two_sprites) {
+ a2 = *src2a++;
+ if (scaled > 1) {
+ b2 = *src2b++;
+ a2 = a2 + ((b2 - a2) * offset2 >> 16);
+ }
+ a1 = a1 + ((a2 - a1) * alpha >> 16);
+ }
+ *dst++ = a1;
+ }
+}
+
+static void sprite_v_single_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset, int width)
+{
+ sprite_v_template(dst, src1a, src1b, offset, 0, NULL, NULL, 0, 0, 1, width);
+}
+
+static void sprite_v_double_noscale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src2a, int alpha, int width)
+{
+ sprite_v_template(dst, src1a, NULL, 0, 1, src2a, NULL, 0, alpha, 0, width);
+}
+
+static void sprite_v_double_onescale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
+ const uint8_t *src2a, int alpha, int width)
+{
+ sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, NULL, 0, alpha, 1, width);
+}
+
+static void sprite_v_double_twoscale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
+ const uint8_t *src2a, const uint8_t *src2b, int offset2,
+ int alpha, int width)
+{
+ sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, src2b, offset2, alpha, 2, width);
+}
+
+#endif
+
av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;
dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c;
@@ -770,6 +830,14 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;
dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;
+#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
+ dsp->sprite_h = sprite_h_c;
+ dsp->sprite_v_single = sprite_v_single_c;
+ dsp->sprite_v_double_noscale = sprite_v_double_noscale_c;
+ dsp->sprite_v_double_onescale = sprite_v_double_onescale_c;
+ dsp->sprite_v_double_twoscale = sprite_v_double_twoscale_c;
+#endif
+
if (HAVE_ALTIVEC)
ff_vc1dsp_init_altivec(dsp);
if (HAVE_MMX)