[Scummvm-git-logs] scummvm master -> 4fd00b7aa3a38df90bcdc0f743ec89faecca8328
Scorpeg
noreply at scummvm.org
Thu Oct 22 10:06:36 UTC 2026
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
4fd00b7aa3 VIDEO: Add WMV3/VC-1 support and extract shared MSMPEG4 code
Commit: 4fd00b7aa3a38df90bcdc0f743ec89faecca8328
https://github.com/scummvm/scummvm/commit/4fd00b7aa3a38df90bcdc0f743ec89faecca8328
Author: Scorp (scorp at mrs.mn)
Date: 2026-10-22T13:04:53+03:00
Commit Message:
VIDEO: Add WMV3/VC-1 support and extract shared MSMPEG4 code
Changed paths:
A image/codecs/msmpeg4_vc1.cpp
A image/codecs/msmpeg4_vc1.h
A image/codecs/vc1.cpp
A image/codecs/vc1.h
configure
engines/testbed/configure.engine
image/codecs/codec.cpp
image/codecs/msmpeg4.cpp
image/module.mk
diff --git a/configure b/configure
index ff45575dde9..1eea0444a49 100755
--- a/configure
+++ b/configure
@@ -315,6 +315,7 @@ _fmtowns_pc98_audio=auto
_sid_audio=auto
_svq1=auto
_truemotion1=auto
+_vc1=auto
_unp64=auto
_vgmtrans_audio=auto
_xan=auto
@@ -368,6 +369,7 @@ add_component tinygl "TinyGL" "_tinygl" "USE_TINYGL"
add_component truemotion1 "TrueMotion 1" "_truemotion1" "USE_TRUEMOTION1"
add_component universaltracker "External Tracker Libraries" "_universaltracker" "USE_UNIVERSALTRACKER"
add_component unp64 "UNP64" "_unp64" "USE_UNP64"
+add_component vc1 "VC-1 / WMV3" "_vc1" "USE_VC1"
add_component vgmtrans_audio "VGMTrans Soundfont audio" "_vgmtrans_audio" "USE_VGMTRANS_AUDIO"
add_component xan "XAN" "_xan" "USE_XAN"
diff --git a/engines/testbed/configure.engine b/engines/testbed/configure.engine
index de7f7a95619..fe21f935748 100644
--- a/engines/testbed/configure.engine
+++ b/engines/testbed/configure.engine
@@ -1,3 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
-add_engine testbed "TestBed: the Testing framework" no "" "" "" "imgui midi universaltracker cdtoons indeo3 indeo45 vpx mpc hnm jyv1 mpeg2 msmpeg4 qdm2 svq1 truemotion1 xan tinygl"
+add_engine testbed "TestBed: the Testing framework" no "" "" "" "imgui midi universaltracker cdtoons indeo3 indeo45 vpx mpc hnm jyv1 mpeg2 msmpeg4 qdm2 svq1 truemotion1 vc1 xan tinygl"
diff --git a/image/codecs/codec.cpp b/image/codecs/codec.cpp
index 3447e6dce4e..6a7b69acc46 100644
--- a/image/codecs/codec.cpp
+++ b/image/codecs/codec.cpp
@@ -43,6 +43,9 @@
#include "image/codecs/svq1.h"
#include "image/codecs/truemotion1.h"
#include "image/codecs/xan.h"
+#ifdef USE_VC1
+#include "image/codecs/vc1.h"
+#endif
#include "common/endian.h"
#include "common/system.h"
@@ -99,6 +102,24 @@ Codec *createBitmapCodec(uint32 tag, uint32 streamTag, int width, int height, in
break;
#endif
+ case MKTAG('W', 'M', 'V', '3'):
+ case MKTAG('w', 'm', 'v', '3'):
+#ifdef USE_VC1
+ return new WMV3Decoder(width, height);
+#else
+ missingCodec = "WMV3";
+ break;
+#endif
+ case MKTAG('W', 'V', 'C', '1'):
+ case MKTAG('w', 'v', 'c', '1'):
+ case MKTAG('W', 'M', 'V', 'A'):
+#ifdef USE_VC1
+ return new WMV3Decoder(width, height, true);
+#else
+ missingCodec = "VC-1";
+ break;
+#endif
+
case MKTAG('I','V','3','2'):
#ifdef USE_INDEO3
return new Indeo3Decoder(width, height, bitsPerPixel);
@@ -212,6 +233,24 @@ Codec *createQuickTimeCodec(uint32 tag, int width, int height, int bitsPerPixel)
case MKTAG('r','a','w',' '):
// Used my L-Zone-mac (Director game)
return new BitmapRawDecoder(width, height, bitsPerPixel, true, true);
+ case MKTAG('W', 'M', 'V', '3'):
+ case MKTAG('w', 'm', 'v', '3'):
+#ifdef USE_VC1
+ return new WMV3Decoder(width, height);
+#else
+ missingCodec = "WMV3";
+ break;
+#endif
+ case MKTAG('W', 'V', 'C', '1'):
+ case MKTAG('w', 'v', 'c', '1'):
+ case MKTAG('W', 'M', 'V', 'A'):
+#ifdef USE_VC1
+ return new WMV3Decoder(width, height, true);
+#else
+ missingCodec = "VC-1";
+ break;
+#endif
+
case MKTAG('I','V','3','2'):
#ifdef USE_INDEO3
// Indeo 3: Used by Team Xtreme: Operation Weather Disaster (Spanish)
diff --git a/image/codecs/msmpeg4.cpp b/image/codecs/msmpeg4.cpp
index bf68b045134..a7c19575338 100644
--- a/image/codecs/msmpeg4.cpp
+++ b/image/codecs/msmpeg4.cpp
@@ -33,6 +33,7 @@
*/
#include "image/codecs/msmpeg4.h"
+#include "image/codecs/msmpeg4_vc1.h"
#include "common/endian.h"
#include "common/memstream.h"
@@ -422,27 +423,6 @@ const INT8 intra_run[102] = {
15, 16, 17, 18, 19, 20,
};
-
-/* intra picture macro block coded block pattern */
-const UINT16 table_mb_intra[64][2] = {
-{ 0x1, 1 },{ 0x17, 6 },{ 0x9, 5 },{ 0x5, 5 },
-{ 0x6, 5 },{ 0x47, 9 },{ 0x20, 7 },{ 0x10, 7 },
-{ 0x2, 5 },{ 0x7c, 9 },{ 0x3a, 7 },{ 0x1d, 7 },
-{ 0x2, 6 },{ 0xec, 9 },{ 0x77, 8 },{ 0x0, 8 },
-{ 0x3, 5 },{ 0xb7, 9 },{ 0x2c, 7 },{ 0x13, 7 },
-{ 0x1, 6 },{ 0x168, 10 },{ 0x46, 8 },{ 0x3f, 8 },
-{ 0x1e, 6 },{ 0x712, 13 },{ 0xb5, 9 },{ 0x42, 8 },
-{ 0x22, 7 },{ 0x1c5, 11 },{ 0x11e, 10 },{ 0x87, 9 },
-{ 0x6, 4 },{ 0x3, 9 },{ 0x1e, 7 },{ 0x1c, 6 },
-{ 0x12, 7 },{ 0x388, 12 },{ 0x44, 9 },{ 0x70, 9 },
-{ 0x1f, 6 },{ 0x23e, 11 },{ 0x39, 8 },{ 0x8e, 9 },
-{ 0x1, 7 },{ 0x1c6, 11 },{ 0xb6, 9 },{ 0x45, 9 },
-{ 0x14, 6 },{ 0x23f, 11 },{ 0x7d, 9 },{ 0x18, 9 },
-{ 0x7, 7 },{ 0x1c7, 11 },{ 0x86, 9 },{ 0x19, 9 },
-{ 0x15, 6 },{ 0x1db, 10 },{ 0x2, 9 },{ 0x46, 9 },
-{ 0xd, 8 },{ 0x713, 13 },{ 0x1da, 10 },{ 0x169, 10 },
-};
-
/* non intra picture macro block coded block pattern + mb type */
const UINT32 table_mb_non_intra[128][2] = {
{ 0x40, 7 },{ 0x13c9, 13 },{ 0x9fd, 12 },{ 0x1fc, 15 },
@@ -479,142 +459,6 @@ const UINT32 table_mb_non_intra[128][2] = {
{ 0x5, 5 },{ 0xb, 10 },{ 0x9c, 8 },{ 0xe, 10 },
};
-/* dc table 0 */
-
-static const UINT32 table0_dc_lum[120][2] = {
-{ 0x1, 1 },{ 0x1, 2 },{ 0x1, 4 },{ 0x1, 5 },
-{ 0x5, 5 },{ 0x7, 5 },{ 0x8, 6 },{ 0xc, 6 },
-{ 0x0, 7 },{ 0x2, 7 },{ 0x12, 7 },{ 0x1a, 7 },
-{ 0x3, 8 },{ 0x7, 8 },{ 0x27, 8 },{ 0x37, 8 },
-{ 0x5, 9 },{ 0x4c, 9 },{ 0x6c, 9 },{ 0x6d, 9 },
-{ 0x8, 10 },{ 0x19, 10 },{ 0x9b, 10 },{ 0x1b, 10 },
-{ 0x9a, 10 },{ 0x13, 11 },{ 0x34, 11 },{ 0x35, 11 },
-{ 0x61, 12 },{ 0x48, 13 },{ 0xc4, 13 },{ 0x4a, 13 },
-{ 0xc6, 13 },{ 0xc7, 13 },{ 0x92, 14 },{ 0x18b, 14 },
-{ 0x93, 14 },{ 0x183, 14 },{ 0x182, 14 },{ 0x96, 14 },
-{ 0x97, 14 },{ 0x180, 14 },{ 0x314, 15 },{ 0x315, 15 },
-{ 0x605, 16 },{ 0x604, 16 },{ 0x606, 16 },{ 0xc0e, 17 },
-{ 0x303cd, 23 },{ 0x303c9, 23 },{ 0x303c8, 23 },{ 0x303ca, 23 },
-{ 0x303cb, 23 },{ 0x303cc, 23 },{ 0x303ce, 23 },{ 0x303cf, 23 },
-{ 0x303d0, 23 },{ 0x303d1, 23 },{ 0x303d2, 23 },{ 0x303d3, 23 },
-{ 0x303d4, 23 },{ 0x303d5, 23 },{ 0x303d6, 23 },{ 0x303d7, 23 },
-{ 0x303d8, 23 },{ 0x303d9, 23 },{ 0x303da, 23 },{ 0x303db, 23 },
-{ 0x303dc, 23 },{ 0x303dd, 23 },{ 0x303de, 23 },{ 0x303df, 23 },
-{ 0x303e0, 23 },{ 0x303e1, 23 },{ 0x303e2, 23 },{ 0x303e3, 23 },
-{ 0x303e4, 23 },{ 0x303e5, 23 },{ 0x303e6, 23 },{ 0x303e7, 23 },
-{ 0x303e8, 23 },{ 0x303e9, 23 },{ 0x303ea, 23 },{ 0x303eb, 23 },
-{ 0x303ec, 23 },{ 0x303ed, 23 },{ 0x303ee, 23 },{ 0x303ef, 23 },
-{ 0x303f0, 23 },{ 0x303f1, 23 },{ 0x303f2, 23 },{ 0x303f3, 23 },
-{ 0x303f4, 23 },{ 0x303f5, 23 },{ 0x303f6, 23 },{ 0x303f7, 23 },
-{ 0x303f8, 23 },{ 0x303f9, 23 },{ 0x303fa, 23 },{ 0x303fb, 23 },
-{ 0x303fc, 23 },{ 0x303fd, 23 },{ 0x303fe, 23 },{ 0x303ff, 23 },
-{ 0x60780, 24 },{ 0x60781, 24 },{ 0x60782, 24 },{ 0x60783, 24 },
-{ 0x60784, 24 },{ 0x60785, 24 },{ 0x60786, 24 },{ 0x60787, 24 },
-{ 0x60788, 24 },{ 0x60789, 24 },{ 0x6078a, 24 },{ 0x6078b, 24 },
-{ 0x6078c, 24 },{ 0x6078d, 24 },{ 0x6078e, 24 },{ 0x6078f, 24 },
-};
-
-static const UINT32 table0_dc_chroma[120][2] = {
-{ 0x0, 2 },{ 0x1, 2 },{ 0x5, 3 },{ 0x9, 4 },
-{ 0xd, 4 },{ 0x11, 5 },{ 0x1d, 5 },{ 0x1f, 5 },
-{ 0x21, 6 },{ 0x31, 6 },{ 0x38, 6 },{ 0x33, 6 },
-{ 0x39, 6 },{ 0x3d, 6 },{ 0x61, 7 },{ 0x79, 7 },
-{ 0x80, 8 },{ 0xc8, 8 },{ 0xca, 8 },{ 0xf0, 8 },
-{ 0x81, 8 },{ 0xc0, 8 },{ 0xc9, 8 },{ 0x107, 9 },
-{ 0x106, 9 },{ 0x196, 9 },{ 0x183, 9 },{ 0x1e3, 9 },
-{ 0x1e2, 9 },{ 0x20a, 10 },{ 0x20b, 10 },{ 0x609, 11 },
-{ 0x412, 11 },{ 0x413, 11 },{ 0x60b, 11 },{ 0x411, 11 },
-{ 0x60a, 11 },{ 0x65f, 11 },{ 0x410, 11 },{ 0x65d, 11 },
-{ 0x65e, 11 },{ 0xcb8, 12 },{ 0xc10, 12 },{ 0xcb9, 12 },
-{ 0x1823, 13 },{ 0x3045, 14 },{ 0x6089, 15 },{ 0xc110, 16 },
-{ 0x304448, 22 },{ 0x304449, 22 },{ 0x30444a, 22 },{ 0x30444b, 22 },
-{ 0x30444c, 22 },{ 0x30444d, 22 },{ 0x30444e, 22 },{ 0x30444f, 22 },
-{ 0x304450, 22 },{ 0x304451, 22 },{ 0x304452, 22 },{ 0x304453, 22 },
-{ 0x304454, 22 },{ 0x304455, 22 },{ 0x304456, 22 },{ 0x304457, 22 },
-{ 0x304458, 22 },{ 0x304459, 22 },{ 0x30445a, 22 },{ 0x30445b, 22 },
-{ 0x30445c, 22 },{ 0x30445d, 22 },{ 0x30445e, 22 },{ 0x30445f, 22 },
-{ 0x304460, 22 },{ 0x304461, 22 },{ 0x304462, 22 },{ 0x304463, 22 },
-{ 0x304464, 22 },{ 0x304465, 22 },{ 0x304466, 22 },{ 0x304467, 22 },
-{ 0x304468, 22 },{ 0x304469, 22 },{ 0x30446a, 22 },{ 0x30446b, 22 },
-{ 0x30446c, 22 },{ 0x30446d, 22 },{ 0x30446e, 22 },{ 0x30446f, 22 },
-{ 0x304470, 22 },{ 0x304471, 22 },{ 0x304472, 22 },{ 0x304473, 22 },
-{ 0x304474, 22 },{ 0x304475, 22 },{ 0x304476, 22 },{ 0x304477, 22 },
-{ 0x304478, 22 },{ 0x304479, 22 },{ 0x30447a, 22 },{ 0x30447b, 22 },
-{ 0x30447c, 22 },{ 0x30447d, 22 },{ 0x30447e, 22 },{ 0x30447f, 22 },
-{ 0x608880, 23 },{ 0x608881, 23 },{ 0x608882, 23 },{ 0x608883, 23 },
-{ 0x608884, 23 },{ 0x608885, 23 },{ 0x608886, 23 },{ 0x608887, 23 },
-{ 0x608888, 23 },{ 0x608889, 23 },{ 0x60888a, 23 },{ 0x60888b, 23 },
-{ 0x60888c, 23 },{ 0x60888d, 23 },{ 0x60888e, 23 },{ 0x60888f, 23 },
-};
-
-/* dc table 1 */
-
-const UINT32 table1_dc_lum[120][2] = {
-{ 0x2, 2 },{ 0x3, 2 },{ 0x3, 3 },{ 0x2, 4 },
-{ 0x5, 4 },{ 0x1, 5 },{ 0x3, 5 },{ 0x8, 5 },
-{ 0x0, 6 },{ 0x5, 6 },{ 0xd, 6 },{ 0xf, 6 },
-{ 0x13, 6 },{ 0x8, 7 },{ 0x18, 7 },{ 0x1c, 7 },
-{ 0x24, 7 },{ 0x4, 8 },{ 0x6, 8 },{ 0x12, 8 },
-{ 0x32, 8 },{ 0x3b, 8 },{ 0x4a, 8 },{ 0x4b, 8 },
-{ 0xb, 9 },{ 0x26, 9 },{ 0x27, 9 },{ 0x66, 9 },
-{ 0x74, 9 },{ 0x75, 9 },{ 0x14, 10 },{ 0x1c, 10 },
-{ 0x1f, 10 },{ 0x1d, 10 },{ 0x2b, 11 },{ 0x3d, 11 },
-{ 0x19d, 11 },{ 0x19f, 11 },{ 0x54, 12 },{ 0x339, 12 },
-{ 0x338, 12 },{ 0x33d, 12 },{ 0xab, 13 },{ 0xf1, 13 },
-{ 0x678, 13 },{ 0xf2, 13 },{ 0x1e0, 14 },{ 0x1e1, 14 },
-{ 0x154, 14 },{ 0xcf2, 14 },{ 0x3cc, 15 },{ 0x2ab, 15 },
-{ 0x19e7, 15 },{ 0x3ce, 15 },{ 0x19e6, 15 },{ 0x554, 16 },
-{ 0x79f, 16 },{ 0x555, 16 },{ 0xf3d, 17 },{ 0xf37, 17 },
-{ 0xf3c, 17 },{ 0xf35, 17 },{ 0x1e6d, 18 },{ 0x1e68, 18 },
-{ 0x3cd8, 19 },{ 0x3cd3, 19 },{ 0x3cd9, 19 },{ 0x79a4, 20 },
-{ 0xf34ba, 25 },{ 0xf34b4, 25 },{ 0xf34b5, 25 },{ 0xf34b6, 25 },
-{ 0xf34b7, 25 },{ 0xf34b8, 25 },{ 0xf34b9, 25 },{ 0xf34bb, 25 },
-{ 0xf34bc, 25 },{ 0xf34bd, 25 },{ 0xf34be, 25 },{ 0xf34bf, 25 },
-{ 0x1e6940, 26 },{ 0x1e6941, 26 },{ 0x1e6942, 26 },{ 0x1e6943, 26 },
-{ 0x1e6944, 26 },{ 0x1e6945, 26 },{ 0x1e6946, 26 },{ 0x1e6947, 26 },
-{ 0x1e6948, 26 },{ 0x1e6949, 26 },{ 0x1e694a, 26 },{ 0x1e694b, 26 },
-{ 0x1e694c, 26 },{ 0x1e694d, 26 },{ 0x1e694e, 26 },{ 0x1e694f, 26 },
-{ 0x1e6950, 26 },{ 0x1e6951, 26 },{ 0x1e6952, 26 },{ 0x1e6953, 26 },
-{ 0x1e6954, 26 },{ 0x1e6955, 26 },{ 0x1e6956, 26 },{ 0x1e6957, 26 },
-{ 0x1e6958, 26 },{ 0x1e6959, 26 },{ 0x1e695a, 26 },{ 0x1e695b, 26 },
-{ 0x1e695c, 26 },{ 0x1e695d, 26 },{ 0x1e695e, 26 },{ 0x1e695f, 26 },
-{ 0x1e6960, 26 },{ 0x1e6961, 26 },{ 0x1e6962, 26 },{ 0x1e6963, 26 },
-{ 0x1e6964, 26 },{ 0x1e6965, 26 },{ 0x1e6966, 26 },{ 0x1e6967, 26 },
-};
-
-const UINT32 table1_dc_chroma[120][2] = {
-{ 0x0, 2 },{ 0x1, 2 },{ 0x4, 3 },{ 0x7, 3 },
-{ 0xb, 4 },{ 0xd, 4 },{ 0x15, 5 },{ 0x28, 6 },
-{ 0x30, 6 },{ 0x32, 6 },{ 0x52, 7 },{ 0x62, 7 },
-{ 0x66, 7 },{ 0xa6, 8 },{ 0xc6, 8 },{ 0xcf, 8 },
-{ 0x14f, 9 },{ 0x18e, 9 },{ 0x19c, 9 },{ 0x29d, 10 },
-{ 0x33a, 10 },{ 0x538, 11 },{ 0x63c, 11 },{ 0x63e, 11 },
-{ 0x63f, 11 },{ 0x676, 11 },{ 0xa73, 12 },{ 0xc7a, 12 },
-{ 0xcef, 12 },{ 0x14e5, 13 },{ 0x19dd, 13 },{ 0x29c8, 14 },
-{ 0x29c9, 14 },{ 0x63dd, 15 },{ 0x33b8, 14 },{ 0x33b9, 14 },
-{ 0xc7b6, 16 },{ 0x63d8, 15 },{ 0x63df, 15 },{ 0xc7b3, 16 },
-{ 0xc7b4, 16 },{ 0xc7b5, 16 },{ 0x63de, 15 },{ 0xc7b7, 16 },
-{ 0xc7b8, 16 },{ 0xc7b9, 16 },{ 0x18f65, 17 },{ 0x31ec8, 18 },
-{ 0xc7b248, 24 },{ 0xc7b249, 24 },{ 0xc7b24a, 24 },{ 0xc7b24b, 24 },
-{ 0xc7b24c, 24 },{ 0xc7b24d, 24 },{ 0xc7b24e, 24 },{ 0xc7b24f, 24 },
-{ 0xc7b250, 24 },{ 0xc7b251, 24 },{ 0xc7b252, 24 },{ 0xc7b253, 24 },
-{ 0xc7b254, 24 },{ 0xc7b255, 24 },{ 0xc7b256, 24 },{ 0xc7b257, 24 },
-{ 0xc7b258, 24 },{ 0xc7b259, 24 },{ 0xc7b25a, 24 },{ 0xc7b25b, 24 },
-{ 0xc7b25c, 24 },{ 0xc7b25d, 24 },{ 0xc7b25e, 24 },{ 0xc7b25f, 24 },
-{ 0xc7b260, 24 },{ 0xc7b261, 24 },{ 0xc7b262, 24 },{ 0xc7b263, 24 },
-{ 0xc7b264, 24 },{ 0xc7b265, 24 },{ 0xc7b266, 24 },{ 0xc7b267, 24 },
-{ 0xc7b268, 24 },{ 0xc7b269, 24 },{ 0xc7b26a, 24 },{ 0xc7b26b, 24 },
-{ 0xc7b26c, 24 },{ 0xc7b26d, 24 },{ 0xc7b26e, 24 },{ 0xc7b26f, 24 },
-{ 0xc7b270, 24 },{ 0xc7b271, 24 },{ 0xc7b272, 24 },{ 0xc7b273, 24 },
-{ 0xc7b274, 24 },{ 0xc7b275, 24 },{ 0xc7b276, 24 },{ 0xc7b277, 24 },
-{ 0xc7b278, 24 },{ 0xc7b279, 24 },{ 0xc7b27a, 24 },{ 0xc7b27b, 24 },
-{ 0xc7b27c, 24 },{ 0xc7b27d, 24 },{ 0xc7b27e, 24 },{ 0xc7b27f, 24 },
-{ 0x18f6480, 25 },{ 0x18f6481, 25 },{ 0x18f6482, 25 },{ 0x18f6483, 25 },
-{ 0x18f6484, 25 },{ 0x18f6485, 25 },{ 0x18f6486, 25 },{ 0x18f6487, 25 },
-{ 0x18f6488, 25 },{ 0x18f6489, 25 },{ 0x18f648a, 25 },{ 0x18f648b, 25 },
-{ 0x18f648c, 25 },{ 0x18f648d, 25 },{ 0x18f648e, 25 },{ 0x18f648f, 25 },
-};
-
/* vlc table 0, for intra luma */
static const UINT16 table0_vlc[133][2] = {
@@ -3323,12 +3167,12 @@ static void initMsmpeg4Tables() {
MVTable *mv = &mv_tables[i];
initVlc(&mv->vlc, 9, mv->n + 1, mv->table_mv_bits, 1, 1, mv->table_mv_code, 2, 2);
}
- initVlc(&gDcLumVlc[0], 9, 120, &table0_dc_lum[0][1], 8, 4, &table0_dc_lum[0][0], 8, 4);
- initVlc(&gDcChromaVlc[0], 9, 120, &table0_dc_chroma[0][1], 8, 4, &table0_dc_chroma[0][0], 8, 4);
- initVlc(&gDcLumVlc[1], 9, 120, &table1_dc_lum[0][1], 8, 4, &table1_dc_lum[0][0], 8, 4);
- initVlc(&gDcChromaVlc[1], 9, 120, &table1_dc_chroma[0][1], 8, 4, &table1_dc_chroma[0][0], 8, 4);
+ initVlc(&gDcLumVlc[0], 9, 120, &MSMPEG4VC1::ff_msmp4_dc_tables[0][0][0][1], 8, 4, &MSMPEG4VC1::ff_msmp4_dc_tables[0][0][0][0], 8, 4);
+ initVlc(&gDcChromaVlc[0], 9, 120, &MSMPEG4VC1::ff_msmp4_dc_tables[0][1][0][1], 8, 4, &MSMPEG4VC1::ff_msmp4_dc_tables[0][1][0][0], 8, 4);
+ initVlc(&gDcLumVlc[1], 9, 120, &MSMPEG4VC1::ff_msmp4_dc_tables[1][0][0][1], 8, 4, &MSMPEG4VC1::ff_msmp4_dc_tables[1][0][0][0], 8, 4);
+ initVlc(&gDcChromaVlc[1], 9, 120, &MSMPEG4VC1::ff_msmp4_dc_tables[1][1][0][1], 8, 4, &MSMPEG4VC1::ff_msmp4_dc_tables[1][1][0][0], 8, 4);
initVlc(&gMbNonIntraVlc, 9, 128, &table_mb_non_intra[0][1], 8, 4, &table_mb_non_intra[0][0], 8, 4);
- initVlc(&gMbIntraVlc, 9, 64, &table_mb_intra[0][1], 4, 2, &table_mb_intra[0][0], 4, 2);
+ initVlc(&gMbIntraVlc, 9, 64, &MSMPEG4VC1::ff_msmp4_mb_i_table[0][1], 4, 2, &MSMPEG4VC1::ff_msmp4_mb_i_table[0][0], 4, 2);
}
} // End of namespace
@@ -3931,22 +3775,7 @@ void MSMPEG4Decoder::frameEnd() {
}
static void putPixels(byte *dst, const byte *src, int pitch, int h, int mode, bool noRounding) {
- for (int y = 0; y < h; ++y) {
- for (int x = 0; x < 8; ++x) {
- int value;
- if (mode == 0)
- value = src[x];
- else if (mode == 1)
- value = noRounding ? ((src[x] + src[x + 1]) >> 1) : ((src[x] + src[x + 1] + 1) >> 1);
- else if (mode == 2)
- value = noRounding ? ((src[x] + src[x + pitch]) >> 1) : ((src[x] + src[x + pitch] + 1) >> 1);
- else
- value = noRounding ? ((src[x] + src[x + 1] + src[x + pitch] + src[x + pitch + 1] + 1) >> 2) : ((src[x] + src[x + 1] + src[x + pitch] + src[x + pitch + 1] + 2) >> 2);
- dst[x] = value;
- }
- dst += pitch;
- src += pitch;
- }
+ putHalfPixels<8>(dst, src, pitch, h, mode, noRounding);
}
static void motionCompensatePlane(byte *dst, const byte *ref, int dstPitch, int refPitch, int dstX, int dstY,
diff --git a/image/codecs/msmpeg4_vc1.cpp b/image/codecs/msmpeg4_vc1.cpp
new file mode 100644
index 00000000000..623aa8096d1
--- /dev/null
+++ b/image/codecs/msmpeg4_vc1.cpp
@@ -0,0 +1,137 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * Shared Microsoft MPEG-4 and VC-1 decoding tables.
+ *
+ * These tables are a ScummVM port of libavcodec/msmpeg4_vc1_data.c
+ * from FFmpeg revision c23123630e6a7e645c199599b8ade3fe7e9ab3db:
+ * https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/c23123630e6a7e645c199599b8ade3fe7e9ab3db
+ * The original code was Copyright (c) 2001 Fabrice Bellard and
+ * (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>, distributed under
+ * the GNU LGPL version 2.1 or later. The shared tables contain the DC
+ * differential codes and intra-picture macroblock coded block patterns.
+ */
+
+#include "image/codecs/msmpeg4_vc1.h"
+
+namespace Image {
+namespace MSMPEG4VC1 {
+
+/* intra picture macro block coded block pattern */
+const uint16 ff_msmp4_mb_i_table[64][2] = {
+ {0x1, 1}, {0x17, 6}, {0x9, 5}, {0x5, 5}, {0x6, 5}, {0x47, 9}, {0x20, 7}, {0x10, 7},
+ {0x2, 5}, {0x7c, 9}, {0x3a, 7}, {0x1d, 7}, {0x2, 6}, {0xec, 9}, {0x77, 8}, {0x0, 8},
+ {0x3, 5}, {0xb7, 9}, {0x2c, 7}, {0x13, 7}, {0x1, 6}, {0x168, 10}, {0x46, 8}, {0x3f, 8},
+ {0x1e, 6}, {0x712, 13}, {0xb5, 9}, {0x42, 8}, {0x22, 7}, {0x1c5, 11}, {0x11e, 10}, {0x87, 9},
+ {0x6, 4}, {0x3, 9}, {0x1e, 7}, {0x1c, 6}, {0x12, 7}, {0x388, 12}, {0x44, 9}, {0x70, 9},
+ {0x1f, 6}, {0x23e, 11}, {0x39, 8}, {0x8e, 9}, {0x1, 7}, {0x1c6, 11}, {0xb6, 9}, {0x45, 9},
+ {0x14, 6}, {0x23f, 11}, {0x7d, 9}, {0x18, 9}, {0x7, 7}, {0x1c7, 11}, {0x86, 9}, {0x19, 9},
+ {0x15, 6}, {0x1db, 10}, {0x2, 9}, {0x46, 9}, {0xd, 8}, {0x713, 13}, {0x1da, 10}, {0x169, 10},
+};
+const uint32 ff_msmp4_dc_tables[2][2][120][2] = {
+ /* dc table 0 */
+ { {
+ {0x1, 1}, {0x1, 2}, {0x1, 4}, {0x1, 5}, {0x5, 5}, {0x7, 5}, {0x8, 6},
+ {0xc, 6}, {0x0, 7}, {0x2, 7}, {0x12, 7}, {0x1a, 7}, {0x3, 8}, {0x7, 8},
+ {0x27, 8}, {0x37, 8}, {0x5, 9}, {0x4c, 9}, {0x6c, 9}, {0x6d, 9}, {0x8, 10},
+ {0x19, 10}, {0x9b, 10}, {0x1b, 10}, {0x9a, 10}, {0x13, 11}, {0x34, 11}, {0x35, 11},
+ {0x61, 12}, {0x48, 13}, {0xc4, 13}, {0x4a, 13}, {0xc6, 13}, {0xc7, 13}, {0x92, 14},
+ {0x18b, 14}, {0x93, 14}, {0x183, 14}, {0x182, 14}, {0x96, 14}, {0x97, 14}, {0x180, 14},
+ {0x314, 15}, {0x315, 15}, {0x605, 16}, {0x604, 16}, {0x606, 16}, {0xc0e, 17}, {0x303cd, 23},
+ {0x303c9, 23}, {0x303c8, 23}, {0x303ca, 23}, {0x303cb, 23}, {0x303cc, 23}, {0x303ce, 23}, {0x303cf, 23},
+ {0x303d0, 23}, {0x303d1, 23}, {0x303d2, 23}, {0x303d3, 23}, {0x303d4, 23}, {0x303d5, 23}, {0x303d6, 23},
+ {0x303d7, 23}, {0x303d8, 23}, {0x303d9, 23}, {0x303da, 23}, {0x303db, 23}, {0x303dc, 23}, {0x303dd, 23},
+ {0x303de, 23}, {0x303df, 23}, {0x303e0, 23}, {0x303e1, 23}, {0x303e2, 23}, {0x303e3, 23}, {0x303e4, 23},
+ {0x303e5, 23}, {0x303e6, 23}, {0x303e7, 23}, {0x303e8, 23}, {0x303e9, 23}, {0x303ea, 23}, {0x303eb, 23},
+ {0x303ec, 23}, {0x303ed, 23}, {0x303ee, 23}, {0x303ef, 23}, {0x303f0, 23}, {0x303f1, 23}, {0x303f2, 23},
+ {0x303f3, 23}, {0x303f4, 23}, {0x303f5, 23}, {0x303f6, 23}, {0x303f7, 23}, {0x303f8, 23}, {0x303f9, 23},
+ {0x303fa, 23}, {0x303fb, 23}, {0x303fc, 23}, {0x303fd, 23}, {0x303fe, 23}, {0x303ff, 23}, {0x60780, 24},
+ {0x60781, 24}, {0x60782, 24}, {0x60783, 24}, {0x60784, 24}, {0x60785, 24}, {0x60786, 24}, {0x60787, 24},
+ {0x60788, 24}, {0x60789, 24}, {0x6078a, 24}, {0x6078b, 24}, {0x6078c, 24}, {0x6078d, 24}, {0x6078e, 24},
+ {0x6078f, 24},
+ },
+ {
+ {0x0, 2}, {0x1, 2}, {0x5, 3}, {0x9, 4}, {0xd, 4}, {0x11, 5}, {0x1d, 5},
+ {0x1f, 5}, {0x21, 6}, {0x31, 6}, {0x38, 6}, {0x33, 6}, {0x39, 6}, {0x3d, 6},
+ {0x61, 7}, {0x79, 7}, {0x80, 8}, {0xc8, 8}, {0xca, 8}, {0xf0, 8}, {0x81, 8},
+ {0xc0, 8}, {0xc9, 8}, {0x107, 9}, {0x106, 9}, {0x196, 9}, {0x183, 9}, {0x1e3, 9},
+ {0x1e2, 9}, {0x20a, 10}, {0x20b, 10}, {0x609, 11}, {0x412, 11}, {0x413, 11}, {0x60b, 11},
+ {0x411, 11}, {0x60a, 11}, {0x65f, 11}, {0x410, 11}, {0x65d, 11}, {0x65e, 11}, {0xcb8, 12},
+ {0xc10, 12}, {0xcb9, 12}, {0x1823, 13}, {0x3045, 14}, {0x6089, 15}, {0xc110, 16}, {0x304448, 22},
+ {0x304449, 22}, {0x30444a, 22}, {0x30444b, 22}, {0x30444c, 22}, {0x30444d, 22}, {0x30444e, 22}, {0x30444f, 22},
+ {0x304450, 22}, {0x304451, 22}, {0x304452, 22}, {0x304453, 22}, {0x304454, 22}, {0x304455, 22}, {0x304456, 22},
+ {0x304457, 22}, {0x304458, 22}, {0x304459, 22}, {0x30445a, 22}, {0x30445b, 22}, {0x30445c, 22}, {0x30445d, 22},
+ {0x30445e, 22}, {0x30445f, 22}, {0x304460, 22}, {0x304461, 22}, {0x304462, 22}, {0x304463, 22}, {0x304464, 22},
+ {0x304465, 22}, {0x304466, 22}, {0x304467, 22}, {0x304468, 22}, {0x304469, 22}, {0x30446a, 22}, {0x30446b, 22},
+ {0x30446c, 22}, {0x30446d, 22}, {0x30446e, 22}, {0x30446f, 22}, {0x304470, 22}, {0x304471, 22}, {0x304472, 22},
+ {0x304473, 22}, {0x304474, 22}, {0x304475, 22}, {0x304476, 22}, {0x304477, 22}, {0x304478, 22}, {0x304479, 22},
+ {0x30447a, 22}, {0x30447b, 22}, {0x30447c, 22}, {0x30447d, 22}, {0x30447e, 22}, {0x30447f, 22}, {0x608880, 23},
+ {0x608881, 23}, {0x608882, 23}, {0x608883, 23}, {0x608884, 23}, {0x608885, 23}, {0x608886, 23}, {0x608887, 23},
+ {0x608888, 23}, {0x608889, 23}, {0x60888a, 23}, {0x60888b, 23}, {0x60888c, 23}, {0x60888d, 23}, {0x60888e, 23},
+ {0x60888f, 23},
+ }},
+ /* dc table 1 */
+ { {
+ {0x2, 2}, {0x3, 2}, {0x3, 3}, {0x2, 4}, {0x5, 4}, {0x1, 5}, {0x3, 5},
+ {0x8, 5}, {0x0, 6}, {0x5, 6}, {0xd, 6}, {0xf, 6}, {0x13, 6}, {0x8, 7},
+ {0x18, 7}, {0x1c, 7}, {0x24, 7}, {0x4, 8}, {0x6, 8}, {0x12, 8}, {0x32, 8},
+ {0x3b, 8}, {0x4a, 8}, {0x4b, 8}, {0xb, 9}, {0x26, 9}, {0x27, 9}, {0x66, 9},
+ {0x74, 9}, {0x75, 9}, {0x14, 10}, {0x1c, 10}, {0x1f, 10}, {0x1d, 10}, {0x2b, 11},
+ {0x3d, 11}, {0x19d, 11}, {0x19f, 11}, {0x54, 12}, {0x339, 12}, {0x338, 12}, {0x33d, 12},
+ {0xab, 13}, {0xf1, 13}, {0x678, 13}, {0xf2, 13}, {0x1e0, 14}, {0x1e1, 14}, {0x154, 14},
+ {0xcf2, 14}, {0x3cc, 15}, {0x2ab, 15}, {0x19e7, 15}, {0x3ce, 15}, {0x19e6, 15}, {0x554, 16},
+ {0x79f, 16}, {0x555, 16}, {0xf3d, 17}, {0xf37, 17}, {0xf3c, 17}, {0xf35, 17}, {0x1e6d, 18},
+ {0x1e68, 18}, {0x3cd8, 19}, {0x3cd3, 19}, {0x3cd9, 19}, {0x79a4, 20}, {0xf34ba, 25}, {0xf34b4, 25},
+ {0xf34b5, 25}, {0xf34b6, 25}, {0xf34b7, 25}, {0xf34b8, 25}, {0xf34b9, 25}, {0xf34bb, 25}, {0xf34bc, 25},
+ {0xf34bd, 25}, {0xf34be, 25}, {0xf34bf, 25}, {0x1e6940, 26}, {0x1e6941, 26}, {0x1e6942, 26}, {0x1e6943, 26},
+ {0x1e6944, 26}, {0x1e6945, 26}, {0x1e6946, 26}, {0x1e6947, 26}, {0x1e6948, 26}, {0x1e6949, 26}, {0x1e694a, 26},
+ {0x1e694b, 26}, {0x1e694c, 26}, {0x1e694d, 26}, {0x1e694e, 26}, {0x1e694f, 26}, {0x1e6950, 26}, {0x1e6951, 26},
+ {0x1e6952, 26}, {0x1e6953, 26}, {0x1e6954, 26}, {0x1e6955, 26}, {0x1e6956, 26}, {0x1e6957, 26}, {0x1e6958, 26},
+ {0x1e6959, 26}, {0x1e695a, 26}, {0x1e695b, 26}, {0x1e695c, 26}, {0x1e695d, 26}, {0x1e695e, 26}, {0x1e695f, 26},
+ {0x1e6960, 26}, {0x1e6961, 26}, {0x1e6962, 26}, {0x1e6963, 26}, {0x1e6964, 26}, {0x1e6965, 26}, {0x1e6966, 26},
+ {0x1e6967, 26},
+ },
+ {
+ {0x0, 2}, {0x1, 2}, {0x4, 3}, {0x7, 3}, {0xb, 4}, {0xd, 4},
+ {0x15, 5}, {0x28, 6}, {0x30, 6}, {0x32, 6}, {0x52, 7}, {0x62, 7},
+ {0x66, 7}, {0xa6, 8}, {0xc6, 8}, {0xcf, 8}, {0x14f, 9}, {0x18e, 9},
+ {0x19c, 9}, {0x29d, 10}, {0x33a, 10}, {0x538, 11}, {0x63c, 11}, {0x63e, 11},
+ {0x63f, 11}, {0x676, 11}, {0xa73, 12}, {0xc7a, 12}, {0xcef, 12}, {0x14e5, 13},
+ {0x19dd, 13}, {0x29c8, 14}, {0x29c9, 14}, {0x63dd, 15}, {0x33b8, 14}, {0x33b9, 14},
+ {0xc7b6, 16}, {0x63d8, 15}, {0x63df, 15}, {0xc7b3, 16}, {0xc7b4, 16}, {0xc7b5, 16},
+ {0x63de, 15}, {0xc7b7, 16}, {0xc7b8, 16}, {0xc7b9, 16}, {0x18f65, 17}, {0x31ec8, 18},
+ {0xc7b248, 24}, {0xc7b249, 24}, {0xc7b24a, 24}, {0xc7b24b, 24}, {0xc7b24c, 24}, {0xc7b24d, 24},
+ {0xc7b24e, 24}, {0xc7b24f, 24}, {0xc7b250, 24}, {0xc7b251, 24}, {0xc7b252, 24}, {0xc7b253, 24},
+ {0xc7b254, 24}, {0xc7b255, 24}, {0xc7b256, 24}, {0xc7b257, 24}, {0xc7b258, 24}, {0xc7b259, 24},
+ {0xc7b25a, 24}, {0xc7b25b, 24}, {0xc7b25c, 24}, {0xc7b25d, 24}, {0xc7b25e, 24}, {0xc7b25f, 24},
+ {0xc7b260, 24}, {0xc7b261, 24}, {0xc7b262, 24}, {0xc7b263, 24}, {0xc7b264, 24}, {0xc7b265, 24},
+ {0xc7b266, 24}, {0xc7b267, 24}, {0xc7b268, 24}, {0xc7b269, 24}, {0xc7b26a, 24}, {0xc7b26b, 24},
+ {0xc7b26c, 24}, {0xc7b26d, 24}, {0xc7b26e, 24}, {0xc7b26f, 24}, {0xc7b270, 24}, {0xc7b271, 24},
+ {0xc7b272, 24}, {0xc7b273, 24}, {0xc7b274, 24}, {0xc7b275, 24}, {0xc7b276, 24}, {0xc7b277, 24},
+ {0xc7b278, 24}, {0xc7b279, 24}, {0xc7b27a, 24}, {0xc7b27b, 24}, {0xc7b27c, 24}, {0xc7b27d, 24},
+ {0xc7b27e, 24}, {0xc7b27f, 24}, {0x18f6480, 25}, {0x18f6481, 25}, {0x18f6482, 25}, {0x18f6483, 25},
+ {0x18f6484, 25}, {0x18f6485, 25}, {0x18f6486, 25}, {0x18f6487, 25}, {0x18f6488, 25}, {0x18f6489, 25},
+ {0x18f648a, 25}, {0x18f648b, 25}, {0x18f648c, 25}, {0x18f648d, 25}, {0x18f648e, 25}, {0x18f648f, 25},
+ }}};
+
+} // namespace MSMPEG4VC1
+} // namespace Image
diff --git a/image/codecs/msmpeg4_vc1.h b/image/codecs/msmpeg4_vc1.h
new file mode 100644
index 00000000000..7f7582320d0
--- /dev/null
+++ b/image/codecs/msmpeg4_vc1.h
@@ -0,0 +1,63 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef IMAGE_CODECS_MSMPEG4_VC1_H
+#define IMAGE_CODECS_MSMPEG4_VC1_H
+
+#include "common/scummsys.h"
+
+namespace Image {
+namespace MSMPEG4VC1 {
+
+extern const uint16 ff_msmp4_mb_i_table[64][2];
+extern const uint32 ff_msmp4_dc_tables[2][2][120][2];
+
+} // namespace MSMPEG4VC1
+/**
+ * Half-pixel interpolation shared by the MSMPEG4 and VC-1 decoders.
+ * Extracted from the MSMPEG4 port of FFmpeg revision 2cb1773ddc
+ * (Copyright (c) 2000, 2001 Gerard Lantau, GPL version 2 or later).
+ * mode selects copy (0), horizontal (1), vertical (2), or both (3).
+ * When averaging, interpolation rounding and destination rounding are separate:
+ * the destination average always rounds up, including noRounding interpolation.
+ */
+template<int width>
+inline void putHalfPixels(byte *dst, const byte *src, ptrdiff_t pitch, int height,
+ int mode, bool noRounding, bool average = false) {
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ int value = src[x];
+ if (mode == 1)
+ value = (src[x] + src[x + 1] + !noRounding) >> 1;
+ else if (mode == 2)
+ value = (src[x] + src[x + pitch] + !noRounding) >> 1;
+ else if (mode == 3)
+ value = (src[x] + src[x + 1] + src[x + pitch] + src[x + pitch + 1] + (noRounding ? 1 : 2)) >> 2;
+ dst[x] = average ? (dst[x] + value + 1) >> 1 : value;
+ }
+ dst += pitch;
+ src += pitch;
+ }
+}
+
+} // namespace Image
+
+#endif
diff --git a/image/codecs/vc1.cpp b/image/codecs/vc1.cpp
new file mode 100644
index 00000000000..d447d7bbaea
--- /dev/null
+++ b/image/codecs/vc1.cpp
@@ -0,0 +1,15103 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * WMV3 and VC-1 software video decoder.
+ *
+ * This decoder is a ScummVM port of the FFmpeg WMV3/VC-1 decoder path
+ * used by libavcodec revision c23123630e6a7e645c199599b8ade3fe7e9ab3db:
+ * https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/c23123630e6a7e645c199599b8ade3fe7e9ab3db
+ * The original code was Copyright
+ * (c) 2005 Anonymous, Alex Beregszaszi and Michael Niedermayer,
+ * (c) 2006-2007 Konstantin Shishkov,
+ * (c) 2011 Mashiat Sarker Shakkhar,
+ * (c) 2000-2002 Fabrice Bellard,
+ * (c) 2001-2003 BERO <bero at geocities.co.jp>,
+ * (c) 2001-2012 Michael Niedermayer <michaelni at gmx.at> et al,
+ * (c) 2010 Loren Merritt,
+ * (c) 2011 Oskar Arvidsson and
+ * (c) 2012 Ronald S. Bultje and distributed under the GNU LGPL
+ * version 2.1 or later. The migrated path includes sequence and picture
+ * headers, bitplanes, VLC tables, prediction, motion compensation, inverse
+ * transforms, overlap and loop filtering, IntraX8, error concealment,
+ * reference-frame ordering, and YUV420 output.
+ */
+
+#include "image/codecs/vc1.h"
+#include "common/array.h"
+#include "common/endian.h"
+#include "common/memstream.h"
+#include "common/ptr.h"
+#include "common/rational.h"
+#include "common/stream.h"
+#include "common/textconsole.h"
+#include "common/util.h"
+#include "graphics/yuv_to_rgb.h"
+#include "image/codecs/msmpeg4_vc1.h"
+#include <limits.h>
+
+namespace Image {
+
+typedef void (*ChromaFunc)(uint8 *dst, const uint8 *src, ptrdiff_t stride, int height, int x, int y);
+
+typedef void (*vc1op_pixels_func)(uint8 *block /*align width (8 or 16)*/, const uint8 *pixels /*align 1*/,
+ ptrdiff_t line_size, int round);
+
+typedef struct WMV3DSP {
+ /* vc1 functions */
+ void (*vc1_inv_trans_8x8)(int16 *b);
+ void (*vc1_inv_trans_8x4)(uint8 *dest, ptrdiff_t stride, int16 *block);
+ void (*vc1_inv_trans_4x8)(uint8 *dest, ptrdiff_t stride, int16 *block);
+ void (*vc1_inv_trans_4x4)(uint8 *dest, ptrdiff_t stride, int16 *block);
+ void (*vc1_inv_trans_8x8_dc)(uint8 *dest, ptrdiff_t stride, int16 *block);
+ void (*vc1_inv_trans_8x4_dc)(uint8 *dest, ptrdiff_t stride, int16 *block);
+ void (*vc1_inv_trans_4x8_dc)(uint8 *dest, ptrdiff_t stride, int16 *block);
+ void (*vc1_inv_trans_4x4_dc)(uint8 *dest, ptrdiff_t stride, int16 *block);
+ void (*vc1_v_overlap)(uint8 *src, ptrdiff_t stride);
+ void (*vc1_h_overlap)(uint8 *src, ptrdiff_t stride);
+ void (*vc1_v_s_overlap)(int16 *top, int16 *bottom);
+ void (*vc1_h_s_overlap)(int16 *left, int16 *right, ptrdiff_t left_stride, ptrdiff_t right_stride, int flags);
+ void (*vc1_v_loop_filter4)(uint8 *src, ptrdiff_t stride, int pq);
+ void (*vc1_h_loop_filter4)(uint8 *src, ptrdiff_t stride, int pq);
+ void (*vc1_v_loop_filter8)(uint8 *src, ptrdiff_t stride, int pq);
+ void (*vc1_h_loop_filter8)(uint8 *src, ptrdiff_t stride, int pq);
+ void (*vc1_v_loop_filter16)(uint8 *src, ptrdiff_t stride, int pq);
+ void (*vc1_h_loop_filter16)(uint8 *src, ptrdiff_t stride, int pq);
+
+ /* put 8x8 block with bicubic interpolation and quarterpel precision
+ * last argument is actually round value instead of height
+ */
+ vc1op_pixels_func put_vc1_mspel_pixels_tab[2][16];
+ vc1op_pixels_func avg_vc1_mspel_pixels_tab[2][16];
+
+ /* This is really one func used in VC-1 decoding */
+ ChromaFunc put_no_rnd_vc1_chroma_pixels_tab[3];
+ ChromaFunc avg_no_rnd_vc1_chroma_pixels_tab[3];
+
+} WMV3DSP;
+
+void initWMV3DSP(WMV3DSP *dsp);
+
+namespace VC1 {
+// Bitstream and VLC support
+
+struct Bits {
+ Common::BitStream8MSB *stream;
+ int size_in_bits;
+};
+inline unsigned get_bits(Bits *b, int n) {
+ return b->stream->getBits(n);
+}
+inline unsigned get_bits1(Bits *b) {
+ return b->stream->getBit();
+}
+inline int get_bits_count(const Bits *b) {
+ return b->stream->pos();
+}
+inline int get_bits_left(const Bits *b) {
+ return b->size_in_bits - get_bits_count(b);
+}
+inline void skip_bits(Bits *b, int n) {
+ b->stream->skip(n);
+}
+inline int get_unary(Bits *b, int stop, int max) {
+ int i = 0;
+ while (i < max && get_bits1(b) != (unsigned)stop)
+ ++i;
+ return i;
+}
+
+inline int decode012(Bits *b) {
+ return get_bits1(b) ? 1 + get_bits1(b) : 0;
+}
+inline int decode210(Bits *b) {
+ return get_bits1(b) ? 0 : 2 - get_bits1(b);
+}
+struct VLC {
+ struct Node {
+ int child[2];
+ int symbol;
+ Node() : child{-1, -1}, symbol(-1) {}
+ };
+ Common::Array<Node> nodes;
+};
+const VLC *makeVLC(int count, const void *lengths, int lengthStride, int lengthSize, const void *codes, int codeStride,
+ int codeSize);
+int get_vlc2(Bits *b, const VLC *table);
+void initTables();
+inline int av_clip(int a, int low, int high) {
+ return CLIP(a, low, high);
+}
+inline int av_clip_uint8(int a) {
+ return CLIP(a, 0, 255);
+}
+inline int av_clip_uintp2(int a, int p) {
+ return CLIP(a, 0, (1 << p) - 1);
+}
+struct Crop {
+ uint8 operator[](int x) const { return av_clip_uint8(x); }
+};
+inline int mid_pred(int a, int b, int c) {
+ if (a > b)
+ SWAP(a, b);
+ return MAX(a, MIN(b, c));
+}
+#define FFALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+enum PictureType { AV_PICTURE_TYPE_I = 1, AV_PICTURE_TYPE_P = 2, AV_PICTURE_TYPE_B = 3, AV_PICTURE_TYPE_BI = 7 };
+
+enum Profile { PROFILE_SIMPLE = 0, PROFILE_MAIN = 1, PROFILE_ADVANCED = 3 };
+
+enum MacroblockType { MB_TYPE_INTRA = 1, MB_TYPE_16x16 = 8, MB_TYPE_SKIP = 131072 };
+
+enum ErrorStatus { ER_MB_ERROR = 14, ER_MB_END = 112 };
+
+static const int CONFIG_GRAY = 0;
+static const int AV_CODEC_FLAG_GRAY = 8192;
+static const int AVDISCARD_NONKEY = 32;
+
+// Decoder state and picture storage
+
+struct Settings {
+ int error_concealment = 3;
+ int flags;
+ int skip_loop_filter;
+ int coded_width;
+ int coded_height;
+};
+struct Planes {
+ uint8 *data[3];
+ int linesize[3];
+ int pict_type;
+ int width;
+ int height;
+ int format;
+ int decode_error_flags;
+};
+struct Picture {
+ Planes *f;
+ uint8 *data[3];
+ int linesize[3];
+ int16 (*motion_val[2])[2];
+ int8 *ref_index[2];
+ uint32 *mb_type;
+ int8 *qscale_table;
+ Picture *ptr;
+ int field_picture;
+ int interlaced;
+};
+typedef void (*PixelOp)(uint8 *, const uint8 *, ptrdiff_t, int);
+typedef void (*QpelOp)(uint8 *, const uint8 *, ptrdiff_t);
+struct QpelDSP {
+ QpelOp put_qpel_pixels_tab[2][16], put_no_rnd_qpel_pixels_tab[2][16], avg_qpel_pixels_tab[2][16];
+};
+void initQpel(QpelDSP *);
+struct HalfDSP {
+ PixelOp put_pixels_tab[2][4], put_no_rnd_pixels_tab[2][4], avg_pixels_tab[2][4], avg_no_rnd_pixels_tab[4];
+};
+struct ChromaDSP {
+ ChromaFunc put_h264_chroma_pixels_tab[3], avg_h264_chroma_pixels_tab[3];
+};
+struct BlockDSP {
+ void (*clear_block)(int16 *);
+ void (*clear_blocks)(int16 *);
+};
+struct ClampDSP {
+ void (*put_pixels_clamped)(const int16 *, uint8 *, ptrdiff_t);
+ void (*put_signed_pixels_clamped)(const int16 *, uint8 *, ptrdiff_t);
+ void (*add_pixels_clamped)(const int16 *, uint8 *, ptrdiff_t);
+};
+struct EdgeDSP {
+ void (*emulated_edge_mc)(uint8 *, const uint8 *, ptrdiff_t, ptrdiff_t, int, int, int, int, int, int);
+};
+inline int median4(int a, int b, int c, int d) {
+ if (a < b) {
+ if (c < d)
+ return (MIN(b, d) + MAX(a, c)) / 2;
+ return (MIN(b, c) + MAX(a, d)) / 2;
+ }
+ if (c < d)
+ return (MIN(a, d) + MAX(b, c)) / 2;
+ return (MIN(a, c) + MAX(b, d)) / 2;
+}
+
+typedef struct ERContext {
+ Settings *avctx;
+
+ int (*sad)(void *unused, const uint8 *blk1, const uint8 *blk2, ptrdiff_t stride, int h);
+
+ int *mb_index2xy;
+ int mb_num;
+ int mb_width, mb_height;
+ ptrdiff_t mb_stride;
+ ptrdiff_t b8_stride;
+
+ int error_count;
+ int error_occurred;
+ uint8 *error_status_table;
+ uint8 *er_temp_buffer;
+ int16 *dc_val[3];
+ uint8 *mbskip_table;
+ uint8 *mbintra_table;
+ int mv[2][4][2];
+
+ Picture cur_pic;
+ Picture last_pic;
+ Picture next_pic;
+
+ int8 *ref_index[2];
+ int16 (*motion_val_base[2])[2];
+
+ uint16 pp_time;
+ uint16 pb_time;
+ int quarter_sample;
+ int partitioned_frame;
+
+ void (*decode_mb)(void *opaque, int ref, int mv_dir, int mv_type, int (*mv)[2][4][2], int mb_x, int mb_y,
+ int mb_intra, int mb_skipped);
+ void *opaque;
+} ERContext;
+
+void ff_er_add_slice(ERContext *, int, int, int, int, int);
+void ff_er_frame_start(ERContext *);
+void ff_er_frame_end(ERContext *, int *);
+struct PictureState;
+void initializeER(PictureState *);
+struct PictureState {
+ Settings *avctx;
+ int ac_pred;
+ int b8_stride;
+ int chroma_x_shift;
+ int end_mb_y;
+ int first_slice_line;
+ int h_edge_pos;
+ int height;
+ int width;
+ int low_delay;
+ int linesize;
+ int mb_height;
+ int mb_intra;
+ int mb_stride;
+ int mb_width;
+ int mb_x;
+ int mb_y;
+ int mspel;
+ int pict_type;
+ int quarter_sample;
+ int start_mb_y;
+ int uvlinesize;
+ int v_edge_pos;
+ int y_dc_scale;
+ int16 (*ac_val)[16];
+ int16 *dc_val;
+ uint8 *coded_block;
+ uint8 *mbskip_table;
+ int block_index[6];
+ int block_wrap[6];
+ int mv[2][4][2];
+ uint8 *dest[3];
+ Picture cur_pic;
+ Picture last_pic;
+ Picture next_pic;
+ BlockDSP bdsp;
+ ClampDSP idsp;
+ HalfDSP hdsp;
+ QpelDSP qdsp;
+ EdgeDSP vdsp;
+ struct {
+ uint8 *edge_emu_buffer;
+ } sc;
+ ERContext er;
+};
+struct IntraX8Context;
+int ff_intrax8_decode_picture(IntraX8Context *, Picture *, Bits *, int *, int *, int, int, int, int);
+void ff_init_block_index(PictureState *s);
+void ff_update_block_index(PictureState *s, int bits, int lowres, int chroma);
+#define B_FRACTION_DEN 256
+#define AC_VLC_BITS 9
+
+/** Sequence quantizer mode */
+//@{
+enum QuantMode {
+ QUANT_FRAME_IMPLICIT, ///< Implicitly specified at frame level
+ QUANT_FRAME_EXPLICIT, ///< Explicitly specified at frame level
+ QUANT_NON_UNIFORM, ///< Non-uniform quant used for all frames
+ QUANT_UNIFORM ///< Uniform quant used for all frames
+};
+//@}
+
+/** Where quant can be changed */
+//@{
+enum DQProfile { DQPROFILE_FOUR_EDGES, DQPROFILE_DOUBLE_EDGES, DQPROFILE_SINGLE_EDGE, DQPROFILE_ALL_MBS };
+//@}
+
+/** @name Where quant can be changed
+ */
+//@{
+enum DQSingleEdge { DQSINGLE_BEDGE_LEFT, DQSINGLE_BEDGE_TOP, DQSINGLE_BEDGE_RIGHT, DQSINGLE_BEDGE_BOTTOM };
+//@}
+
+/** Which pair of edges is quantized with ALTPQUANT */
+//@{
+enum DQDoubleEdge {
+ DQDOUBLE_BEDGE_TOPLEFT,
+ DQDOUBLE_BEDGE_TOPRIGHT,
+ DQDOUBLE_BEDGE_BOTTOMRIGHT,
+ DQDOUBLE_BEDGE_BOTTOMLEFT
+};
+//@}
+
+/** MV modes for P-frames */
+//@{
+enum MVModes { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV, MV_PMODE_INTENSITY_COMP };
+//@}
+
+/** MBMODE for interlaced frame P-picture */
+//@{
+enum MBModesIntfr {
+ MV_PMODE_INTFR_1MV,
+ MV_PMODE_INTFR_2MV_FIELD,
+ MV_PMODE_INTFR_2MV,
+ MV_PMODE_INTFR_4MV_FIELD,
+ MV_PMODE_INTFR_4MV,
+ MV_PMODE_INTFR_INTRA,
+};
+//@}
+
+/** @name MV types for B-frames */
+//@{
+enum BMVTypes { BMV_TYPE_BACKWARD, BMV_TYPE_FORWARD, BMV_TYPE_INTERPOLATED, BMV_TYPE_DIRECT };
+//@}
+
+/** @name Block types for P/B-frames */
+//@{
+enum TransformTypes {
+ TT_8X8,
+ TT_8X4_BOTTOM,
+ TT_8X4_TOP,
+ TT_8X4, // both halves
+ TT_4X8_RIGHT,
+ TT_4X8_LEFT,
+ TT_4X8, // both halves
+ TT_4X4
+};
+//@}
+
+enum CodingSet {
+ CS_HIGH_MOT_INTRA = 0,
+ CS_HIGH_MOT_INTER,
+ CS_LOW_MOT_INTRA,
+ CS_LOW_MOT_INTER,
+ CS_MID_RATE_INTRA,
+ CS_MID_RATE_INTER,
+ CS_HIGH_RATE_INTRA,
+ CS_HIGH_RATE_INTER
+};
+
+/** @name Overlap conditions for Advanced Profile */
+//@{
+enum COTypes { CONDOVER_NONE = 0, CONDOVER_ALL, CONDOVER_SELECT };
+//@}
+
+/**
+ * FCM Frame Coding Mode
+ * @note some content might be marked interlaced
+ * but have fcm set to 0 as well (e.g. HD-DVD)
+ */
+enum FrameCodingMode {
+ PROGRESSIVE = 0, ///< in the bitstream is reported as 00b
+ ILACE_FRAME, ///< in the bitstream is reported as 10b
+ ILACE_FIELD ///< in the bitstream is reported as 11b
+};
+
+/**
+ * Imode types
+ * @{
+ */
+enum Imode { IMODE_RAW, IMODE_NORM2, IMODE_DIFF2, IMODE_NORM6, IMODE_DIFF6, IMODE_ROWSKIP, IMODE_COLSKIP };
+/** @} */ // imode defines
+
+/** The VC1 Context
+ * @todo Change size wherever another size is more efficient
+ * Many members are only used for Advanced Profile
+ */
+// VC-1 picture context
+
+struct VC1Context : VC1Header {
+ PictureState s;
+ Bits gb;
+ IntraX8Context *x8;
+ ChromaDSP h264chroma;
+ WMV3DSP vc1dsp;
+
+ /** Simple/Main Profile sequence header */
+ //@{
+ ///< at frame level
+ int reserved; ///< reserved
+ //@}
+
+ /** Advanced Profile */
+ //@{
+ ///< Decoder parameters
+ //@}
+
+ /** Sequence header data for all Profiles
+ * TODO: choose between ints, uint8_ts and monobit flags
+ */
+ //@{
+ //@}
+
+ /** Frame decoding info for all profiles */
+ //@{
+ uint8 mv_mode; ///< MV coding mode
+ uint8 mv_mode2; ///< Secondary MV coding mode (B-frames)
+ int k_x; ///< Number of bits for MVs (depends on MV range)
+ int k_y; ///< Number of bits for MVs (depends on MV range)
+ int range_x, range_y; ///< MV range
+ uint8 pq, altpq; ///< Current/alternate frame quantizer scale
+ uint8 zz_8x8[4][64]; ///< Zigzag table for TT_8x8, permuted for IDCT
+ int left_blk_sh, top_blk_sh; ///< Either 3 or 0, positions of l/t in blk[]
+ /** pquant parameters */
+ //@{
+ uint8 dquantfrm;
+ uint8 dqprofile;
+ uint8 dqsbedge;
+ uint8 dqbilevel;
+ //@}
+ int dc_table_index;
+ /** AC coding set indexes
+ * @see 8.1.1.10, p(1)10
+ */
+ //@{
+ int c_ac_table_index; ///< Chroma index from ACFRM element
+ int y_ac_table_index; ///< Luma index from AC2FRM element
+ //@}
+ int esc3_level_length;
+ int esc3_run_length;
+ int ttfrm; ///< Transform type info present at frame level
+ uint8 ttmbf; ///< Transform type flag
+ int *ttblk_base, *ttblk; ///< Transform type at the block level
+ int codingset; ///< index of current table set from 11.8 to use for luma block decoding
+ int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding
+ int pqindex; ///< raw pqindex used in coding set selection
+ int a_avail, c_avail;
+ uint8 *mb_type_base, *mb_type;
+
+ /** Luma compensation parameters */
+ //@{
+ uint8 lumscale;
+ uint8 lumshift;
+ //@}
+ int16 bfraction; ///< Relative position % anchors=> how to scale MVs
+ uint8 halfpq; ///< Uniform quant over image and qp+.5
+ uint8 respic; ///< Frame-level flag for resized images
+ int buffer_fullness; ///< HRD info
+ /** Ranges:
+ * -# 0 -> [-64n 63.f] x [-32, 31.f]
+ * -# 1 -> [-128, 127.f] x [-64, 63.f]
+ * -# 2 -> [-512, 511.f] x [-128, 127.f]
+ * -# 3 -> [-1024, 1023.f] x [-256, 255.f]
+ */
+ uint8 mvrange; ///< Extended MV range flag
+ uint8 pquantizer; ///< Uniform (over sequence) quantizer in use
+ const VLC *cbpcy_vlc; ///< CBPCY VLC table
+ int tt_index; ///< Index for Transform Type tables (to decode TTMB)
+ int mv_table_index;
+ uint8 *mv_type_mb_plane; ///< bitplane for mv_type == (4MV)
+ uint8 *direct_mb_plane; ///< bitplane for "direct" MBs
+ uint8 *forward_mb_plane; ///< bitplane for "forward" MBs
+ int mv_type_is_raw; ///< mv type mb plane is not coded
+ int dmb_is_raw; ///< direct mb plane is raw
+ int fmb_is_raw; ///< forward mb plane is raw
+ int skip_is_raw; ///< skip mb plane is not coded
+ uint8 last_luty[2][256], last_lutuv[2][256]; ///< lookup tables used for intensity compensation
+ uint8 aux_luty[2][256], aux_lutuv[2][256]; ///< lookup tables used for intensity compensation
+ uint8 next_luty[2][256], next_lutuv[2][256]; ///< lookup tables used for intensity compensation
+ uint8 (*curr_luty)[256], (*curr_lutuv)[256];
+ int last_use_ic, *curr_use_ic, next_use_ic, aux_use_ic;
+ int last_interlaced, next_interlaced; ///< whether last_pic, next_pic is interlaced
+ int rnd; ///< rounding control
+ int cbptab;
+
+ /** Frame decoding info for S/M profiles only */
+ //@{
+ uint8 rangeredfrm; ///< out_sample = CLIP((in_sample-128)*2+128)
+ uint8 interpfrm;
+ //@}
+
+ /** Frame decoding info for Advanced profile */
+ //@{
+ int fcm;
+ uint8 numpanscanwin;
+ uint8 tfcntr;
+ uint8 rptfrm, tff, rff;
+ uint8 uvsamp;
+ uint8 postproc;
+ uint8 bit_rate_exponent;
+ uint8 buffer_size_exponent;
+ uint8 *acpred_plane; ///< AC prediction flags bitplane
+ int acpred_is_raw;
+ uint8 *over_flags_plane; ///< Overflags bitplane
+ int overflg_is_raw;
+ uint8 condover;
+ //@}
+
+ /** Frame decoding info for interlaced picture */
+ uint8 dmvrange; ///< Extended differential MV range flag
+ int fourmvswitch;
+ int intcomp;
+ uint8 lumscale2; ///< for interlaced field P picture
+ uint8 lumshift2;
+ const VLC *mbmode_vlc;
+ const VLC *imv_vlc;
+ const VLC *twomvbp_vlc;
+ const VLC *fourmvbp_vlc;
+ uint8 twomvbp;
+ uint8 fourmvbp;
+ uint8 *fieldtx_plane;
+ int fieldtx_is_raw;
+ uint8 zzi_8x8[64];
+ uint8 *blk_mv_type_base, *blk_mv_type; ///< 0: frame MV, 1: field MV (interlaced frame)
+ uint8 *mv_f_base, *mv_f[2]; ///< 0: MV obtained from same field, 1: opposite field
+ uint8 *mv_f_next_base, *mv_f_next[2];
+ int field_mode; ///< 1 for interlaced field pictures
+ int fptype;
+ int second_field;
+ int refdist; ///< distance of the current picture from reference
+ int numref; ///< number of past field pictures used as reference
+ // 0 corresponds to 1 and 1 corresponds to 2 references
+ int reffield; ///< if numref = 0 (1 reference) then reffield decides which
+ // field to use among the two fields from previous frame
+ int intcompfield; ///< which of the two fields to be intensity compensated
+ // 0: both fields, 1: bottom field, 2: top field
+ int cur_field_type; ///< 0: top, 1: bottom
+ int ref_field_type[2]; ///< forward and backward reference field type (top or bottom)
+ int blocks_off, mb_off;
+ int bmvtype;
+ int frfd, brfd; ///< reference frame distance (forward or backward)
+ int first_pic_header_flag;
+ int pic_header_flag;
+ int mbmodetab;
+ int icbptab;
+ int imvtab;
+ int twomvbptab;
+ int fourmvbptab;
+
+ int new_sprite, two_sprites;
+ int p_frame_skipped;
+ int bi_type;
+ int x8_type;
+
+ int16 (*block)[6][64];
+ int n_allocated_blks, cur_blk_idx, left_blk_idx, topleft_blk_idx, top_blk_idx;
+ uint32 *cbp_base, *cbp;
+ uint8 *is_intra_base, *is_intra;
+ int16 (*luma_mv_base)[2], (*luma_mv)[2];
+ uint8 bfraction_lut_index; ///< Index for BFRACTION value (see Table 40, reproduced into ff_vc1_bfraction_lut[])
+
+ int end_mb_x; ///< Horizontal macroblock limit (used only by mss2)
+
+ int parse_only; ///< Context is used within parser
+
+ int16 blocks[6][64];
+};
+
+void ff_vc1_decode_blocks(VC1Context *v);
+
+void ff_vc1_i_overlap_filter(VC1Context *v);
+void ff_vc1_p_overlap_filter(VC1Context *v);
+void ff_vc1_i_loop_filter(VC1Context *v);
+void ff_vc1_p_loop_filter(VC1Context *v);
+void ff_vc1_p_intfr_loop_filter(VC1Context *v);
+void ff_vc1_b_intfi_loop_filter(VC1Context *v);
+
+void ff_vc1_mc_1mv(VC1Context *v, int dir);
+void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg);
+void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir);
+void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg);
+
+void ff_vc1_interp_mc(VC1Context *v);
+
+void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8 *is_intra,
+ int pred_flag, int dir);
+void ff_vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, int mvn, int r_x, int r_y, int dir);
+void ff_vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mvtype);
+void ff_vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag);
+
+static inline int scale_mv(int value, int bfrac, int inv, int qs) {
+ int n = bfrac;
+
+#if B_FRACTION_DEN == 256
+ if (inv)
+ n -= 256;
+ if (!qs)
+ return 2 * ((value * n + 255) >> 9);
+ return (value * n + 128) >> 8;
+#else
+ if (inv)
+ n -= B_FRACTION_DEN;
+ if (!qs)
+ return 2 * ((value * n + B_FRACTION_DEN - 1) / (2 * B_FRACTION_DEN));
+ return (value * n + B_FRACTION_DEN / 2) / B_FRACTION_DEN;
+#endif
+}
+
+int ff_vc1_parse_frame_header(VC1Context *, Bits *);
+int ff_vc1_parse_frame_header_adv(VC1Context *, Bits *);
+void ff_simple_idct_int16_8bit(int16 *);
+void ff_simple_idct_add_int16_8bit(uint8 *, ptrdiff_t, int16 *);
+void ff_simple_idct84_add(uint8 *, ptrdiff_t, int16 *);
+void ff_simple_idct48_add(uint8 *, ptrdiff_t, int16 *);
+void ff_simple_idct44_add(uint8 *, ptrdiff_t, int16 *);
+void initSupport(PictureState *, ChromaDSP *);
+
+/** Table for conversion between TTBLK and TTMB */
+extern const int ff_vc1_ttblk_to_tt[3][8];
+
+extern const int ff_vc1_ttfrm_to_tt[4];
+
+/** MV P mode - the 5th element is only used for mode 1 */
+extern const uint8 ff_vc1_mv_pmode_table[2][5];
+extern const uint8 ff_vc1_mv_pmode_table2[2][4];
+
+extern const int ff_vc1_fps_nr[7], ff_vc1_fps_dr[2];
+extern const uint8 ff_vc1_pquant_table[3][32];
+
+/* MBMODE table for interlaced frame P-picture */
+extern const uint8 ff_vc1_mbmode_intfrp[2][15][4];
+
+/** @name VC-1 VLC tables
+ * @todo TODO move this into the context
+ */
+//@{
+extern const VLC *ff_vc1_imode_vlc;
+extern const VLC *ff_vc1_norm2_vlc;
+extern const VLC *ff_vc1_norm6_vlc;
+extern const VLC *ff_vc1_ttmb_vlc[3];
+extern const VLC *ff_vc1_mv_diff_vlc[4];
+extern const VLC *ff_vc1_cbpcy_p_vlc[4];
+extern const VLC *ff_vc1_icbpcy_vlc[8];
+extern const VLC *ff_vc1_4mv_block_pattern_vlc[4];
+extern const VLC *ff_vc1_2mv_block_pattern_vlc[4];
+extern const VLC *ff_vc1_ttblk_vlc[3];
+extern const VLC *ff_vc1_subblkpat_vlc[3];
+extern const VLC *ff_vc1_intfr_4mv_mbmode_vlc[4];
+extern const VLC *ff_vc1_intfr_non4mv_mbmode_vlc[4];
+extern const VLC *ff_vc1_if_mmv_mbmode_vlc[8];
+extern const VLC *ff_vc1_if_1mv_mbmode_vlc[8];
+extern const VLC *ff_vc1_1ref_mvdata_vlc[4];
+extern const VLC *ff_vc1_2ref_mvdata_vlc[8];
+
+extern const VLC *ff_vc1_ac_coeff_table[8];
+
+//@}
+
+/* pre-computed scales for all bfractions and base=256 */
+extern const int16 ff_vc1_bfraction_lut[23];
+
+// Same as H.264
+extern const VC1Ratio ff_vc1_pixel_aspect[16];
+
+extern const uint8 ff_wmv3_dc_scale_table[32];
+
+/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
+
+/* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */
+extern const uint8 ff_vc1_simple_progressive_4x4_zz[16];
+extern const uint8 ff_vc1_adv_progressive_8x4_zz[32];
+extern const uint8 ff_vc1_adv_progressive_4x8_zz[32];
+extern const uint8 ff_vc1_adv_interlaced_8x8_zz[64];
+extern const uint8 ff_vc1_adv_interlaced_8x4_zz[32];
+extern const uint8 ff_vc1_adv_interlaced_4x8_zz[32];
+extern const uint8 ff_vc1_adv_interlaced_4x4_zz[16];
+
+/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
+extern const int32 ff_vc1_dqscale[63];
+
+/* P Interlaced field picture MV predictor scaling values (Table 114) */
+extern const uint16 ff_vc1_field_mvpred_scales[2][7][4];
+/* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */
+extern const uint16 ff_vc1_b_field_mvpred_scales[7][4];
+
+#define AC_MODES 8
+
+extern const int ff_vc1_ac_sizes[AC_MODES];
+extern const VLC *ff_msmp4_mb_i_vlc;
+extern const VLC *ff_msmp4_dc_vlc[2 /* dc_table_index */][2 /* 0: luma, 1: chroma */];
+
+/* intra picture macroblock coded block pattern */
+using MSMPEG4VC1::ff_msmp4_mb_i_table;
+
+#define WMV1_SCANTABLE_COUNT 4
+
+extern const uint8 ff_wmv1_scantable[WMV1_SCANTABLE_COUNT][64];
+
+using MSMPEG4VC1::ff_msmp4_dc_tables;
+
+struct X8IDCT {
+ void (*idct_add)(uint8 *, ptrdiff_t, int16 *);
+};
+typedef struct IntraX8DSPContext {
+ void (*v_loop_filter)(uint8 *src, ptrdiff_t stride, int qscale);
+ void (*h_loop_filter)(uint8 *src, ptrdiff_t stride, int qscale);
+
+ void (*spatial_compensation[12])(const uint8 *src, uint8 *dst, ptrdiff_t stride);
+ void (*setup_spatial_compensation)(const uint8 *src, uint8 *dst, ptrdiff_t stride, int *range, int *sum, int edges);
+} IntraX8DSPContext;
+
+void ff_intrax8dsp_init(IntraX8DSPContext *dsp);
+
+typedef struct IntraX8Context {
+ const VLC *j_ac_vlc_table[4]; // they point to the static j_mb_vlc.table
+ const VLC *j_orient_vlc_table;
+ const VLC *j_dc_vlc_table[3];
+
+ int use_quant_matrix;
+
+ // set by ff_intrax8_common_init
+ uint8 *prediction_table; // 2 * (mb_w * 2)
+ uint8 permutated_scantable[3][64];
+ X8IDCT idsp;
+ Settings *avctx;
+ int16 *block;
+
+ // set by the caller codec
+ IntraX8DSPContext dsp;
+ BlockDSP bdsp;
+ int quant;
+ int dquant;
+ int qsum;
+ int loopfilter;
+ Planes *frame;
+ Bits *gb;
+
+ // calculated per frame
+ int quant_dc_chroma;
+ int divide_quant_dc_luma;
+ int divide_quant_dc_chroma;
+ uint8 *dest[3];
+ uint8 scratchpad[42]; // size of the block is fixed (8x8 plus padding)
+
+ // changed per block
+ int edges;
+ int flat_dc;
+ int predicted_dc;
+ int raw_orient;
+ int chroma_orient;
+ int orient;
+ int est_run;
+
+ // block props
+ int mb_x, mb_y;
+ int mb_width, mb_height;
+} IntraX8Context;
+
+int initX8(IntraX8Context *, int16 *, int, int);
+void endX8(IntraX8Context *);
+
+// Packet decoder lifecycle
+
+class Decoder {
+public:
+ Decoder(int width, int height, bool advanced);
+ ~Decoder();
+ bool initialize(const uint8 *data, uint32 size);
+ const Picture *decode(const uint8 *data, uint32 size);
+ const Picture *drain();
+ bool failed() const { return _failed; }
+ int width() const { return _v->width; }
+ int height() const { return _v->height; }
+
+private:
+ VC1Context *_v;
+ Settings _settings;
+ Common::Array<uint8 *> _allocations;
+ Picture _pictures[3];
+ Planes _planes[3];
+ bool _advanced, _ready, _failed, _pending;
+ template<class T> T *allocate(uint32 n) {
+ uint8 *p = new uint8[sizeof(T) * n]();
+ _allocations.push_back(p);
+ return reinterpret_cast<T *>(p);
+ }
+ void allocatePictures();
+ void initializePictureLayout();
+ void allocatePredictors();
+ void allocateReferencePictures();
+ void initializeConcealment();
+ void initializeTransforms();
+
+ void clearPictures();
+ bool readHeader(const uint8 *, uint32, bool);
+ bool decodePacket(const uint8 *, uint32, const Picture *&);
+};
+
+/* which indexes point to last=1 entries in tables */
+static const int vc1_last_decode_table[AC_MODES] = {119, 99, 85, 81, 67, 58, 126, 109};
+
+static const uint8 vc1_index_decode_table[AC_MODES][185][2] = {
+ {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12},
+ {0, 13}, {0, 14}, {0, 15}, {0, 16}, {0, 17}, {0, 18}, {0, 19}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5},
+ {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {1, 12}, {1, 13}, {1, 14}, {1, 15}, {2, 1}, {2, 2},
+ {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10}, {2, 11}, {2, 12}, {3, 1}, {3, 2},
+ {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, {3, 9}, {3, 10}, {3, 11}, {4, 1}, {4, 2}, {4, 3},
+ {4, 4}, {4, 5}, {4, 6}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}, {6, 1}, {6, 2}, {6, 3}, {6, 4},
+ {7, 1}, {7, 2}, {7, 3}, {7, 4}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {9, 1}, {9, 2}, {9, 3}, {9, 4},
+ {10, 1}, {10, 2}, {10, 3}, {11, 1}, {11, 2}, {11, 3}, {12, 1}, {12, 2}, {12, 3}, {13, 1}, {13, 2}, {13, 3},
+ {14, 1}, {14, 2}, {14, 3}, {15, 1}, {15, 2}, {15, 3}, {16, 1}, {16, 2}, {17, 1}, {17, 2}, {18, 1}, {19, 1},
+ {20, 1}, {21, 1}, {22, 1}, {23, 1}, {24, 1}, {25, 1}, {26, 1}, {27, 1}, {28, 1}, {29, 1}, {30, 1}, {0, 1},
+ {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 1}, {2, 2},
+ {2, 3}, {2, 4}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {4, 1}, {4, 2}, {4, 3}, {5, 1}, {5, 2}, {6, 1},
+ {6, 2}, {7, 1}, {7, 2}, {8, 1}, {8, 2}, {9, 1}, {9, 2}, {10, 1}, {10, 2}, {11, 1}, {11, 2}, {12, 1},
+ {12, 2}, {13, 1}, {13, 2}, {14, 1}, {14, 2}, {15, 1}, {15, 2}, {16, 1}, {17, 1}, {18, 1}, {19, 1}, {20, 1},
+ {21, 1}, {22, 1}, {23, 1}, {24, 1}, {25, 1}, {26, 1}, {27, 1}, {28, 1}, {29, 1}, {30, 1}, {31, 1}, {32, 1},
+ {33, 1}, {34, 1}, {35, 1}, {36, 1}, {37, 1}},
+ {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12},
+ {0, 13}, {0, 14}, {0, 15}, {0, 16}, {0, 17}, {0, 18}, {0, 19}, {0, 20}, {0, 21}, {0, 22}, {0, 23}, {1, 1},
+ {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {2, 1}, {2, 2},
+ {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6},
+ {3, 7}, {4, 1}, {4, 2}, {4, 3}, {4, 4}, {4, 5}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}, {6, 1},
+ {6, 2}, {6, 3}, {6, 4}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {8, 1}, {8, 2}, {8, 3}, {9, 1}, {9, 2},
+ {9, 3}, {10, 1}, {10, 2}, {10, 3}, {11, 1}, {11, 2}, {11, 3}, {12, 1}, {12, 2}, {13, 1}, {13, 2}, {14, 1},
+ {14, 2}, {15, 1}, {15, 2}, {16, 1}, {16, 2}, {17, 1}, {18, 1}, {19, 1}, {20, 1}, {21, 1}, {22, 1}, {23, 1},
+ {24, 1}, {25, 1}, {26, 1}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9},
+ {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {3, 1}, {3, 2}, {3, 3},
+ {3, 4}, {4, 1}, {4, 2}, {4, 3}, {5, 1}, {5, 2}, {5, 3}, {6, 1}, {6, 2}, {6, 3}, {7, 1}, {7, 2},
+ {8, 1}, {8, 2}, {9, 1}, {9, 2}, {10, 1}, {10, 2}, {11, 1}, {11, 2}, {12, 1}, {12, 2}, {13, 1}, {13, 2},
+ {14, 1}, {14, 2}, {15, 1}, {16, 1}, {17, 1}, {18, 1}, {19, 1}, {20, 1}, {21, 1}, {22, 1}, {23, 1}, {24, 1},
+ {25, 1}, {26, 1}, {27, 1}, {28, 1}, {29, 1}, {30, 1}, {31, 1}, {32, 1}, {33, 1}, {34, 1}, {35, 1}, {36, 1}},
+ {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12},
+ {0, 13}, {0, 14}, {0, 15}, {0, 16}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8},
+ {1, 9}, {1, 10}, {1, 11}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {3, 1},
+ {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {4, 1}, {4, 2}, {4, 3}, {4, 4}, {4, 5}, {5, 1},
+ {5, 2}, {5, 3}, {5, 4}, {6, 1}, {6, 2}, {6, 3}, {6, 4}, {7, 1}, {7, 2}, {7, 3}, {8, 1}, {8, 2},
+ {8, 3}, {9, 1}, {9, 2}, {9, 3}, {10, 1}, {10, 2}, {10, 3}, {11, 1}, {11, 2}, {11, 3}, {12, 1}, {12, 2},
+ {12, 3}, {13, 1}, {13, 2}, {13, 3}, {14, 1}, {14, 2}, {15, 1}, {15, 2}, {16, 1}, {17, 1}, {18, 1}, {19, 1},
+ {20, 1}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 2}, {2, 3},
+ {3, 1}, {3, 2}, {3, 3}, {4, 1}, {4, 2}, {5, 1}, {5, 2}, {6, 1}, {6, 2}, {7, 1}, {7, 2}, {8, 1},
+ {8, 2}, {9, 1}, {9, 2}, {10, 1}, {10, 2}, {11, 1}, {11, 2}, {12, 1}, {12, 2}, {13, 1}, {13, 2}, {14, 1},
+ {15, 1}, {16, 1}, {17, 1}, {18, 1}, {19, 1}, {20, 1}, {21, 1}, {22, 1}, {23, 1}, {24, 1}, {25, 1}, {26, 1}},
+ {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12},
+ {0, 13}, {0, 14}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {2, 1},
+ {2, 2}, {2, 3}, {2, 4}, {2, 5}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {4, 1}, {4, 2}, {4, 3}, {4, 4},
+ {5, 1}, {5, 2}, {5, 3}, {5, 4}, {6, 1}, {6, 2}, {6, 3}, {7, 1}, {7, 2}, {7, 3}, {8, 1}, {8, 2},
+ {8, 3}, {9, 1}, {9, 2}, {9, 3}, {10, 1}, {10, 2}, {10, 3}, {11, 1}, {11, 2}, {11, 3}, {12, 1}, {12, 2},
+ {12, 3}, {13, 1}, {13, 2}, {14, 1}, {14, 2}, {15, 1}, {15, 2}, {16, 1}, {17, 1}, {18, 1}, {19, 1}, {20, 1},
+ {21, 1}, {22, 1}, {23, 1}, {24, 1}, {25, 1}, {26, 1}, {27, 1}, {28, 1}, {29, 1}, {0, 1}, {0, 2}, {0, 3},
+ {0, 4}, {0, 5}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 2}, {2, 3}, {3, 1}, {3, 2}, {3, 3},
+ {4, 1}, {4, 2}, {5, 1}, {5, 2}, {6, 1}, {6, 2}, {7, 1}, {7, 2}, {8, 1}, {8, 2}, {9, 1}, {9, 2},
+ {10, 1}, {10, 2}, {11, 1}, {11, 2}, {12, 1}, {12, 2}, {13, 1}, {13, 2}, {14, 1}, {14, 2}, {15, 1}, {15, 2},
+ {16, 1}, {17, 1}, {18, 1}, {19, 1}, {20, 1}, {21, 1}, {22, 1}, {23, 1}, {24, 1}, {25, 1}, {26, 1}, {27, 1},
+ {28, 1}, {29, 1}, {30, 1}, {31, 1}, {32, 1}, {33, 1}, {34, 1}, {35, 1}, {36, 1}, {37, 1}, {38, 1}, {39, 1},
+ {40, 1}, {41, 1}, {42, 1}, {43, 1}},
+ {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12},
+ {0, 13}, {0, 14}, {0, 15}, {0, 16}, {0, 17}, {0, 18}, {0, 19}, {0, 20}, {0, 21}, {0, 22}, {0, 23}, {0, 24},
+ {0, 25}, {0, 26}, {0, 27}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9},
+ {1, 10}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {4, 1}, {4, 2},
+ {4, 3}, {5, 1}, {5, 2}, {5, 3}, {6, 1}, {6, 2}, {6, 3}, {7, 1}, {7, 2}, {7, 3}, {8, 1}, {8, 2},
+ {9, 1}, {9, 2}, {10, 1}, {11, 1}, {12, 1}, {13, 1}, {14, 1}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5},
+ {0, 6}, {0, 7}, {0, 8}, {1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2}, {3, 1}, {3, 2}, {4, 1}, {4, 2},
+ {5, 1}, {5, 2}, {6, 1}, {6, 2}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1}, {12, 1}, {13, 1}, {14, 1},
+ {15, 1}, {16, 1}, {17, 1}, {18, 1}, {19, 1}, {20, 1}},
+ {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12},
+ {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {3, 1}, {3, 2},
+ {3, 3}, {4, 1}, {4, 2}, {4, 3}, {5, 1}, {5, 2}, {5, 3}, {6, 1}, {6, 2}, {6, 3}, {7, 1}, {7, 2},
+ {8, 1}, {8, 2}, {9, 1}, {9, 2}, {10, 1}, {10, 2}, {11, 1}, {12, 1}, {13, 1}, {14, 1}, {15, 1}, {16, 1},
+ {17, 1}, {18, 1}, {19, 1}, {20, 1}, {21, 1}, {22, 1}, {23, 1}, {24, 1}, {25, 1}, {26, 1}, {0, 1}, {0, 2},
+ {0, 3}, {1, 1}, {1, 2}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1},
+ {11, 1}, {12, 1}, {13, 1}, {14, 1}, {15, 1}, {16, 1}, {17, 1}, {18, 1}, {19, 1}, {20, 1}, {21, 1}, {22, 1},
+ {23, 1}, {24, 1}, {25, 1}, {26, 1}, {27, 1}, {28, 1}, {29, 1}, {30, 1}, {31, 1}, {32, 1}, {33, 1}, {34, 1},
+ {35, 1}, {36, 1}, {37, 1}, {38, 1}, {39, 1}, {40, 1}},
+ {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12},
+ {0, 13}, {0, 14}, {0, 15}, {0, 16}, {0, 17}, {0, 18}, {0, 19}, {0, 20}, {0, 21}, {0, 22}, {0, 23}, {0, 24},
+ {0, 25}, {0, 26}, {0, 27}, {0, 28}, {0, 29}, {0, 30}, {0, 31}, {0, 32}, {0, 33}, {0, 34}, {0, 35}, {0, 36},
+ {0, 37}, {0, 38}, {0, 39}, {0, 40}, {0, 41}, {0, 42}, {0, 43}, {0, 44}, {0, 45}, {0, 46}, {0, 47}, {0, 48},
+ {0, 49}, {0, 50}, {0, 51}, {0, 52}, {0, 53}, {0, 54}, {0, 55}, {0, 56}, {1, 1}, {1, 2}, {1, 3}, {1, 4},
+ {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {1, 12}, {1, 13}, {1, 14}, {1, 15}, {1, 16},
+ {1, 17}, {1, 18}, {1, 19}, {1, 20}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8},
+ {2, 9}, {2, 10}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {4, 1}, {4, 2}, {4, 3},
+ {4, 4}, {4, 5}, {4, 6}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}, {6, 1}, {6, 2}, {6, 3}, {6, 4},
+ {7, 1}, {7, 2}, {7, 3}, {8, 1}, {8, 2}, {8, 3}, {9, 1}, {9, 2}, {9, 3}, {10, 1}, {10, 2}, {11, 1},
+ {11, 2}, {12, 1}, {12, 2}, {13, 1}, {13, 2}, {14, 1}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {1, 1}, {1, 2},
+ {1, 3}, {2, 1}, {2, 2}, {2, 3}, {3, 1}, {3, 2}, {4, 1}, {4, 2}, {5, 1}, {5, 2}, {6, 1}, {6, 2},
+ {7, 1}, {7, 2}, {8, 1}, {8, 2}, {9, 1}, {9, 2}, {10, 1}, {10, 2}, {11, 1}, {11, 2}, {12, 1}, {12, 2},
+ {13, 1}, {13, 2}, {14, 1}, {14, 2}, {15, 1}, {16, 1}},
+ {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12},
+ {0, 13}, {0, 14}, {0, 15}, {0, 16}, {0, 17}, {0, 18}, {0, 19}, {0, 20}, {0, 21}, {0, 22}, {0, 23}, {0, 24},
+ {0, 25}, {0, 26}, {0, 27}, {0, 28}, {0, 29}, {0, 30}, {0, 31}, {0, 32}, {1, 1}, {1, 2}, {1, 3}, {1, 4},
+ {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {1, 12}, {1, 13}, {2, 1}, {2, 2}, {2, 3},
+ {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {4, 1},
+ {4, 2}, {4, 3}, {4, 4}, {4, 5}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {6, 1}, {6, 2}, {6, 3}, {6, 4},
+ {7, 1}, {7, 2}, {7, 3}, {8, 1}, {8, 2}, {8, 3}, {9, 1}, {9, 2}, {9, 3}, {10, 1}, {10, 2}, {11, 1},
+ {11, 2}, {12, 1}, {12, 2}, {13, 1}, {13, 2}, {14, 1}, {14, 2}, {15, 1}, {15, 2}, {16, 1}, {16, 2}, {17, 1},
+ {17, 2}, {18, 1}, {18, 2}, {19, 1}, {19, 2}, {20, 1}, {20, 2}, {21, 1}, {21, 2}, {22, 1}, {22, 2}, {23, 1},
+ {24, 1}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2}, {2, 3}, {3, 1},
+ {3, 2}, {3, 3}, {4, 1}, {4, 2}, {5, 1}, {5, 2}, {6, 1}, {6, 2}, {7, 1}, {7, 2}, {8, 1}, {8, 2},
+ {9, 1}, {9, 2}, {10, 1}, {10, 2}, {11, 1}, {11, 2}, {12, 1}, {12, 2}, {13, 1}, {13, 2}, {14, 1}, {14, 2},
+ {15, 1}, {15, 2}, {16, 1}, {16, 2}, {17, 1}, {17, 2}, {18, 1}, {18, 2}, {19, 1}, {19, 2}, {20, 1}, {20, 2},
+ {21, 1}, {21, 2}, {22, 1}, {22, 2}, {23, 1}, {23, 2}, {24, 1}, {24, 2}, {25, 1}, {25, 2}, {26, 1}, {26, 2},
+ {27, 1}, {27, 2}, {28, 1}, {28, 2}, {29, 1}, {30, 1}}};
+
+static const uint8 vc1_delta_level_table[AC_MODES][31] = {
+ {19, 15, 12, 11, 6, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {23, 11, 8, 7, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {16, 11, 8, 7, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1},
+ {14, 9, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {27, 10, 5, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1},
+ {12, 6, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {56, 20, 10, 7, 6, 5, 4, 3, 3, 3, 2, 2, 2, 2, 1},
+ {32, 13, 8, 6, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1}};
+
+static const uint8 vc1_last_delta_level_table[AC_MODES][44] = {
+ {6, 5, 4, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {9, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {5, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {8, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1},
+ {4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1}};
+
+static const uint8 vc1_delta_run_table[AC_MODES][57] = {
+ {255, 30, 17, 15, 9, 5, 4, 3, 3, 3, 3, 3, 2, 1, 1, 1, 0, 0, 0, 0},
+ {255, 26, 16, 11, 7, 5, 3, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {255, 20, 15, 13, 6, 4, 3, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0},
+ {255, 29, 15, 12, 5, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+ {255, 14, 9, 7, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {255, 26, 10, 6, 2, 1, 1, 0, 0, 0, 0, 0, 0},
+ {255, 14, 13, 9, 6, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {255, 24, 22, 9, 6, 4, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+
+static const uint8 vc1_last_delta_run_table[AC_MODES][10] = {{255, 37, 15, 4, 3, 1, 0},
+ {255, 36, 14, 6, 3, 1, 0, 0, 0, 0},
+ {255, 26, 13, 3, 1},
+ {255, 43, 15, 3, 1, 0},
+ {255, 20, 6, 1, 0, 0, 0, 0, 0},
+ {255, 40, 1, 0},
+ {255, 16, 14, 2, 0},
+ {255, 30, 28, 3, 0}};
+
+/* BitPlane IMODE - such a small table... */
+// Static coding tables
+
+static const uint8 vc1_imode_codes[7] = {0, 2, 1, 3, 1, 2, 3};
+static const uint8 vc1_imode_bits[7] = {4, 2, 3, 2, 4, 3, 3};
+
+/* Normal-2 imode */
+static const uint8 vc1_norm2_codes[4] = {0, 4, 5, 3};
+static const uint8 vc1_norm2_bits[4] = {1, 3, 3, 2};
+
+static const uint16 vc1_norm6_codes[64] = {
+ 0x001, 0x002, 0x003, 0x000, 0x004, 0x001, 0x002, 0x047, 0x005, 0x003, 0x004, 0x04B, 0x005, 0x04D, 0x04E, 0x30E,
+ 0x006, 0x006, 0x007, 0x053, 0x008, 0x055, 0x056, 0x30D, 0x009, 0x059, 0x05A, 0x30C, 0x05C, 0x30B, 0x30A, 0x037,
+ 0x007, 0x00A, 0x00B, 0x043, 0x00C, 0x045, 0x046, 0x309, 0x00D, 0x049, 0x04A, 0x308, 0x04C, 0x307, 0x306, 0x036,
+ 0x00E, 0x051, 0x052, 0x305, 0x054, 0x304, 0x303, 0x035, 0x058, 0x302, 0x301, 0x034, 0x300, 0x033, 0x032, 0x007,
+};
+
+static const uint8 vc1_norm6_bits[64] = {
+ 1, 4, 4, 8, 4, 8, 8, 10, 4, 8, 8, 10, 8, 10, 10, 13, 4, 8, 8, 10, 8, 10,
+ 10, 13, 8, 10, 10, 13, 10, 13, 13, 9, 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13,
+ 10, 13, 13, 9, 8, 10, 10, 13, 10, 13, 13, 9, 10, 13, 13, 9, 13, 9, 9, 6,
+};
+
+/* 4MV Block pattern VLC tables */
+static const uint8 vc1_4mv_block_pattern_codes[4][16] = {{14, 58, 59, 25, 12, 26, 15, 15, 13, 24, 27, 0, 28, 1, 2, 2},
+ {8, 18, 19, 4, 20, 5, 30, 11, 21, 31, 6, 12, 7, 13, 14, 0},
+ {15, 6, 7, 2, 8, 3, 28, 9, 10, 29, 4, 11, 5, 12, 13, 0},
+ {0, 11, 12, 4, 13, 5, 30, 16, 14, 31, 6, 17, 7, 18, 19, 10}};
+static const uint8 vc1_4mv_block_pattern_bits[4][16] = {{5, 6, 6, 5, 5, 5, 5, 4, 5, 5, 5, 3, 5, 3, 3, 2},
+ {4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2},
+ {4, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3},
+ {2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4}};
+
+/* 2MV Block pattern VLC tables */
+static const uint8 vc1_2mv_block_pattern_codes[4][4] = {{2, 1, 0, 3}, {1, 0, 2, 3}, {2, 0, 3, 1}, {1, 3, 2, 0}};
+
+static const uint8 vc1_2mv_block_pattern_bits[4][4] = {{2, 2, 2, 2}, {1, 2, 3, 3}, {3, 2, 3, 1}, {1, 3, 3, 2}};
+
+/* Interlaced frame picture 4MV MBMODE VLC tables (p. 246, p. 360) */
+static const uint16 vc1_intfr_4mv_mbmode_codes[4][15] = {
+ {22, 17, 0, 47, 32, 10, 1, 3, 67, 133, 132, 92, 19, 93, 18},
+ {3, 45, 0, 7, 23, 6, 1, 2, 10, 39, 44, 8, 18, 77, 76},
+ {15, 6, 28, 9, 41, 6, 2, 15, 14, 8, 40, 29, 0, 21, 11},
+ {7, 198, 1, 2, 193, 13, 25, 0, 97, 1599, 98, 398, 798, 192, 1598}};
+
+static const uint8 vc1_intfr_4mv_mbmode_bits[4][15] = {{5, 5, 2, 6, 6, 4, 2, 2, 7, 8, 8, 7, 5, 7, 5},
+ {3, 6, 3, 3, 5, 3, 3, 3, 4, 6, 6, 4, 5, 7, 7},
+ {4, 3, 5, 5, 7, 4, 2, 5, 5, 5, 7, 5, 2, 6, 5},
+ {4, 9, 1, 3, 9, 5, 6, 2, 8, 12, 8, 10, 11, 9, 12}};
+
+/* Interlaced frame picture NON-4MV MBMODE VLC tables (p. 363) */
+static const uint8 vc1_intfr_non4mv_mbmode_codes[4][9] = {{9, 22, 0, 17, 16, 10, 1, 3, 23},
+ {7, 0, 5, 2, 1, 1, 6, 3, 4},
+ {1, 0, 10, 23, 44, 8, 3, 9, 45},
+ {7, 97, 1, 2, 49, 13, 25, 0, 96}};
+
+static const uint8 vc1_intfr_non4mv_mbmode_bits[4][9] = {
+ {4, 5, 2, 5, 5, 4, 2, 2, 5}, {3, 4, 6, 2, 3, 2, 3, 5, 6}, {2, 2, 4, 5, 6, 4, 2, 4, 6}, {4, 8, 1, 3, 7, 5, 6, 2, 8}};
+
+/* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */
+/* mixed-MV */
+static const uint8 vc1_if_mmv_mbmode_codes[8][8] = {{16, 17, 3, 3, 0, 5, 9, 2}, {8, 9, 3, 6, 7, 0, 5, 2},
+ {16, 17, 5, 3, 0, 3, 9, 2}, {56, 57, 15, 4, 5, 6, 29, 0},
+ {52, 53, 27, 14, 15, 2, 12, 0}, {56, 57, 29, 5, 6, 0, 15, 4},
+ {16, 17, 6, 7, 0, 1, 9, 5}, {56, 57, 0, 5, 6, 29, 4, 15}};
+static const uint8 vc1_if_mmv_mbmode_bits[8][8] = {
+ {6, 6, 2, 3, 2, 4, 5, 2}, {5, 5, 3, 3, 3, 2, 4, 2}, {6, 6, 4, 3, 2, 2, 5, 2}, {6, 6, 4, 3, 3, 3, 5, 1},
+ {6, 6, 5, 4, 4, 2, 4, 1}, {6, 6, 5, 3, 3, 1, 4, 3}, {5, 5, 3, 3, 2, 2, 4, 3}, {6, 6, 1, 3, 3, 5, 3, 4}};
+
+/* 1MV */
+static const uint8 vc1_if_1mv_mbmode_codes[8][6] = {{0, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1}, {16, 17, 3, 0, 9, 5},
+ {20, 21, 3, 11, 0, 4}, {4, 5, 2, 3, 3, 0}, {4, 5, 3, 2, 0, 3},
+ {0, 1, 1, 1, 1, 1}, {16, 17, 9, 5, 3, 0}};
+static const uint8 vc1_if_1mv_mbmode_bits[8][6] = {{5, 5, 1, 3, 2, 4}, {5, 5, 1, 2, 3, 4}, {5, 5, 2, 1, 4, 3},
+ {5, 5, 2, 4, 1, 3}, {4, 4, 2, 3, 2, 2}, {4, 4, 3, 2, 2, 2},
+ {5, 5, 3, 4, 1, 2}, {5, 5, 4, 3, 2, 1}};
+
+/* Interlaced frame/field picture MVDATA VLC tables */
+
+/* 1-reference tables */
+static const uint32 vc1_1ref_mvdata_codes[4][72] =
+ {/* uint32 may be too big */
+ {0x00005, 0x0000C, 0x0001E, 0x00012, 0x0000C, 0x00034, 0x00075, 0x00070, 0x00000, 0x00008, 0x0001B, 0x00008,
+ 0x0001D, 0x0007C, 0x000D6, 0x001DE, 0x001AF, 0x00005, 0x0001B, 0x00026, 0x0001E, 0x00012, 0x00076, 0x0004D,
+ 0x001F6, 0x001F4, 0x00039, 0x0007F, 0x00027, 0x0006A, 0x00071, 0x00035, 0x00071, 0x00068, 0x001DC, 0x00027,
+ 0x00073, 0x000FF, 0x000E8, 0x000E9, 0x0007E, 0x001F9, 0x001F5, 0x001FD, 0x0003E, 0x001CA, 0x003F9, 0x0004C,
+ 0x00069, 0x001FA, 0x001DF, 0x001F7, 0x00070, 0x001DD, 0x00E4D, 0x00727, 0x00392, 0x001C8, 0x001CB, 0x003F8,
+ 0x001AE, 0x001F8, 0x001FB, 0x0E4CE, 0x0E4CF, 0x07260, 0x07261, 0x07262, 0x07263, 0x07264, 0x07265, 0x07266},
+ {0x00007, 0x00001, 0x00007, 0x00016, 0x00001, 0x00045, 0x00018, 0x002B6, 0x00006, 0x00004, 0x00017, 0x00010,
+ 0x00029, 0x0002C, 0x0015A, 0x00066, 0x0019E, 0x00009, 0x00028, 0x00017, 0x00000, 0x0002A, 0x00004, 0x0005B,
+ 0x000B5, 0x000CE, 0x00006, 0x00044, 0x0000F, 0x00046, 0x0000E, 0x000AC, 0x00032, 0x00037, 0x011EB, 0x0000A,
+ 0x0001A, 0x0011F, 0x00016, 0x00014, 0x0002B, 0x00168, 0x00055, 0x023D5, 0x00057, 0x0002F, 0x00036, 0x0002E,
+ 0x00169, 0x00054, 0x0047B, 0x0019F, 0x02B7D, 0x0008E, 0x00ADE, 0x00479, 0x0056E, 0x008F4, 0x015BF, 0x00478,
+ 0x023D4, 0x0ADF1, 0x056F9, 0xADF0E, 0xADF0F, 0x56F80, 0x56F81, 0x56F82, 0x56F83, 0x56F84, 0x56F85, 0x56F86},
+ {0x00002, 0x00006, 0x00007, 0x0000D, 0x00007, 0x00030, 0x000FF, 0x001F0, 0x00002, 0x00000, 0x00005, 0x00019,
+ 0x0001E, 0x00007, 0x00063, 0x000FD, 0x00023, 0x0000E, 0x0001B, 0x0001A, 0x00006, 0x00009, 0x00018, 0x000C5,
+ 0x00033, 0x001F1, 0x00002, 0x003FB, 0x001F3, 0x00022, 0x001FC, 0x00042, 0x00623, 0x00083, 0x00620, 0x0007D,
+ 0x00040, 0x00043, 0x003E4, 0x003E5, 0x00191, 0x00FE9, 0x00105, 0x00208, 0x000FC, 0x00624, 0x00622, 0x00190,
+ 0x00626, 0x007F5, 0x00C4B, 0x01FD0, 0x0104D, 0x00065, 0x00C42, 0x000C9, 0x00627, 0x00C43, 0x00C4A, 0x0104E,
+ 0x01FD1, 0x0104F, 0x00412, 0x104CE, 0x104CF, 0x08260, 0x08261, 0x08262, 0x08263, 0x08264, 0x08265, 0x08266},
+ {0x0000D, 0x00001, 0x00004, 0x00000, 0x00017, 0x00005, 0x0007F, 0x0004D, 0x00003, 0x00011, 0x0003E, 0x0003B,
+ 0x00017, 0x00067, 0x0004A, 0x000C3, 0x000F2, 0x0000A, 0x0002C, 0x00032, 0x0003D, 0x00015, 0x00028, 0x00093,
+ 0x000CC, 0x00096, 0x00003, 0x00075, 0x00020, 0x0002D, 0x00021, 0x00029, 0x00090, 0x001D0, 0x001FB, 0x0001C,
+ 0x0004C, 0x00060, 0x00009, 0x00008, 0x0002D, 0x0009F, 0x001FA, 0x0013D, 0x00031, 0x000FC, 0x00058, 0x00092,
+ 0x000F0, 0x000F1, 0x000CD, 0x00185, 0x00165, 0x0004E, 0x00091, 0x000E9, 0x00184, 0x001D1, 0x001E6, 0x00097,
+ 0x001E7, 0x000B3, 0x0013C, 0x0164E, 0x0164F, 0x00B20, 0x00B21, 0x00B22, 0x00B23, 0x00B24, 0x00B25, 0x00B26}};
+
+static const uint8 vc1_1ref_mvdata_bits[4][72] = {
+ {3, 4, 5, 5, 5, 6, 7, 7, 2, 4, 5, 5, 6, 7, 8, 9, 9, 4, 6, 6, 6, 6, 7, 8,
+ 9, 9, 6, 8, 7, 7, 7, 7, 8, 8, 9, 6, 8, 8, 8, 8, 8, 9, 9, 9, 7, 10, 10, 8,
+ 8, 9, 9, 9, 8, 9, 13, 12, 11, 10, 10, 10, 9, 9, 9, 17, 17, 16, 16, 16, 16, 16, 16, 16},
+ {3, 3, 4, 5, 5, 7, 8, 10, 3, 4, 5, 5, 6, 7, 9, 10, 12, 4, 6, 6, 5, 6, 6, 8,
+ 9, 11, 4, 7, 7, 7, 7, 8, 9, 9, 13, 5, 8, 9, 8, 8, 9, 10, 10, 14, 7, 9, 9, 9,
+ 10, 10, 11, 12, 14, 8, 12, 11, 11, 12, 13, 11, 14, 16, 15, 20, 20, 19, 19, 19, 19, 19, 19, 19},
+ {3, 4, 4, 4, 5, 6, 8, 9, 2, 4, 5, 5, 5, 6, 7, 8, 8, 4, 7, 7, 6, 6, 7, 8,
+ 8, 9, 5, 10, 9, 8, 9, 9, 11, 10, 11, 7, 9, 9, 10, 10, 11, 12, 11, 12, 8, 11, 11, 11,
+ 11, 11, 12, 13, 15, 9, 12, 10, 11, 12, 12, 15, 13, 15, 13, 19, 19, 18, 18, 18, 18, 18, 18, 18},
+ {4, 4, 4, 4, 5, 5, 7, 7, 3, 5, 6, 6, 6, 7, 7, 8, 8, 4, 6, 6, 6, 6, 7, 8,
+ 8, 8, 4, 7, 6, 6, 6, 7, 8, 9, 9, 5, 7, 7, 6, 6, 7, 8, 9, 9, 6, 8, 8, 8,
+ 8, 8, 8, 9, 10, 7, 8, 8, 9, 9, 9, 8, 9, 9, 9, 14, 14, 13, 13, 13, 13, 13, 13, 13}};
+
+/* 2-reference tables */
+static const uint32 vc1_2ref_mvdata_codes[8][126] =
+ {/* table 132 - table 139 */
+ {0x0000C, 0x0001C, 0x0000B, 0x00000, 0x0000E, 0x0002A, 0x00050, 0x00368, 0x00002, 0x0001A, 0x00004, 0x0003A,
+ 0x0001D, 0x0006C, 0x000EF, 0x001BC, 0x0015F, 0x0000F, 0x00003, 0x0001C, 0x0000D, 0x0000B, 0x0003E, 0x000A7,
+ 0x00146, 0x00199, 0x00006, 0x0001F, 0x00004, 0x0003C, 0x00007, 0x001BE, 0x0008B, 0x0002C, 0x007B3, 0x00005,
+ 0x000DB, 0x00056, 0x000EC, 0x00052, 0x001BD, 0x00078, 0x000CF, 0x00573, 0x00009, 0x00023, 0x000ED, 0x00018,
+ 0x00006, 0x00044, 0x000F5, 0x00079, 0x006D2, 0x0006E, 0x0002B, 0x0015D, 0x00017, 0x0037F, 0x00144, 0x000CE,
+ 0x00028, 0x000AB, 0x00010, 0x001B5, 0x000F7, 0x000A6, 0x0007B, 0x00028, 0x001ED, 0x001E9, 0x006FD, 0x00004,
+ 0x000F5, 0x00029, 0x0028A, 0x0028B, 0x0028F, 0x00DF9, 0x00335, 0x01E85, 0x000EE, 0x002BD, 0x0002B, 0x003D8,
+ 0x003D1, 0x00198, 0x001E9, 0x0051D, 0x000B4, 0x0003F, 0x00455, 0x0022B, 0x00229, 0x00451, 0x00578, 0x007B2,
+ 0x00570, 0x00155, 0x00032, 0x003D0, 0x00054, 0x006D3, 0x00571, 0x00454, 0x00334, 0x01BF1, 0x000B7, 0x00029,
+ 0x01E84, 0x0016C, 0x0019B, 0x01BF0, 0x00579, 0x00F43, 0x000B5, 0x008A1, 0x0002A, 0x0016D, 0x008A0, 0x007A0,
+ 0x003D1, 0x00AE5, 0x00154, 0x00AE4, 0x00A39, 0x00A38},
+ {0x00003, 0x00009, 0x00016, 0x00010, 0x000D7, 0x00335, 0x00574, 0x00555, 0x00000, 0x0001D, 0x00009, 0x00017,
+ 0x0002C, 0x000AD, 0x00374, 0x006B3, 0x00577, 0x0000F, 0x00018, 0x0000A, 0x0002E, 0x00022, 0x0017C, 0x00E7B,
+ 0x01B89, 0x015D8, 0x00008, 0x00034, 0x0006D, 0x00023, 0x001C2, 0x00376, 0x002D3, 0x01C4A, 0x0330A, 0x00014,
+ 0x0006A, 0x00072, 0x0006C, 0x000E3, 0x0019B, 0x0073F, 0x01CF0, 0x00B41, 0x00032, 0x000E6, 0x000E0, 0x000CF,
+ 0x000AB, 0x0019C, 0x002AB, 0x00E2B, 0x015D9, 0x0006F, 0x001C3, 0x000AF, 0x000BF, 0x000AC, 0x0017D, 0x006E3,
+ 0x00E29, 0x01984, 0x00054, 0x000B5, 0x0017A, 0x001AD, 0x00199, 0x00178, 0x00358, 0x002D2, 0x01C4B, 0x0005B,
+ 0x002A8, 0x00331, 0x00388, 0x0038B, 0x00370, 0x00713, 0x00CC3, 0x01CF1, 0x001B9, 0x005EF, 0x00738, 0x002F2,
+ 0x0033B, 0x002B9, 0x006EB, 0x00570, 0x00E24, 0x0039D, 0x005A2, 0x005A3, 0x00E7D, 0x005EE, 0x00739, 0x00554,
+ 0x00AA5, 0x00AA4, 0x00377, 0x01CF5, 0x00BCE, 0x00E79, 0x00660, 0x00674, 0x006EA, 0x00E7C, 0x00D65, 0x002F6,
+ 0x015DA, 0x01B88, 0x005A1, 0x01CF4, 0x005E6, 0x00E28, 0x00575, 0x00D64, 0x00334, 0x0330B, 0x015DB, 0x00B40,
+ 0x00BCF, 0x00DC5, 0x00E2A, 0x00675, 0x00571, 0x00553},
+ {0x00004, 0x00002, 0x00010, 0x00003, 0x00017, 0x00045, 0x0003E, 0x0007E, 0x00003, 0x00002, 0x00028, 0x0001E,
+ 0x00015, 0x00047, 0x00002, 0x0014D, 0x00060, 0x0000B, 0x00026, 0x00024, 0x00014, 0x00032, 0x0006F, 0x000C3,
+ 0x00531, 0x006E5, 0x00015, 0x0003F, 0x0002D, 0x00001, 0x0013E, 0x000DD, 0x000F6, 0x00305, 0x00331, 0x0000E,
+ 0x00003, 0x00034, 0x00033, 0x0001A, 0x0014A, 0x000C5, 0x000F4, 0x006E4, 0x00001, 0x0003C, 0x0007D, 0x0008D,
+ 0x0009D, 0x00031, 0x0006E, 0x00296, 0x000CD, 0x00025, 0x00149, 0x00032, 0x00089, 0x00036, 0x00088, 0x0006F,
+ 0x00003, 0x0031D, 0x0000E, 0x001AA, 0x0027E, 0x00061, 0x0014E, 0x0014F, 0x00067, 0x000FF, 0x00183, 0x00036,
+ 0x00357, 0x000F5, 0x000C6, 0x000C2, 0x00299, 0x00119, 0x00231, 0x00350, 0x0002C, 0x0018F, 0x00530, 0x00297,
+ 0x00004, 0x001B8, 0x000C0, 0x0027A, 0x00311, 0x0009C, 0x00621, 0x00199, 0x0031C, 0x000F7, 0x003E3, 0x00356,
+ 0x00189, 0x00005, 0x0006B, 0x008C2, 0x00330, 0x004FF, 0x004F0, 0x00351, 0x004F2, 0x001F2, 0x00373, 0x00000,
+ 0x00C41, 0x008C3, 0x009EC, 0x003E2, 0x00304, 0x004F7, 0x004F1, 0x001F0, 0x00148, 0x00C40, 0x009ED, 0x008C0,
+ 0x008C1, 0x004F3, 0x004FE, 0x000FE, 0x001F3, 0x001A9},
+ {0x00000, 0x00004, 0x0002F, 0x00052, 0x00010, 0x000AD, 0x0050B, 0x00190, 0x00003, 0x00016, 0x00007, 0x0000D,
+ 0x000BB, 0x00173, 0x000C9, 0x0050F, 0x0172C, 0x00003, 0x00011, 0x00005, 0x00043, 0x00023, 0x0004B, 0x0032E,
+ 0x02E5B, 0x00482, 0x00009, 0x0002A, 0x00014, 0x0002A, 0x00108, 0x005CA, 0x0065A, 0x02136, 0x02132, 0x0000B,
+ 0x00013, 0x00041, 0x000B8, 0x00174, 0x00100, 0x014DA, 0x0404E, 0x01437, 0x0002B, 0x00085, 0x000A7, 0x000A0,
+ 0x0014C, 0x0029A, 0x0032C, 0x02133, 0x0142A, 0x00051, 0x00284, 0x000AC, 0x00102, 0x00045, 0x00044, 0x0081B,
+ 0x0065E, 0x00CB7, 0x00018, 0x0050C, 0x00212, 0x002E4, 0x00203, 0x00094, 0x00122, 0x0081A, 0x00655, 0x00033,
+ 0x002BA, 0x00246, 0x00242, 0x00A6E, 0x0040C, 0x00808, 0x02134, 0x0404F, 0x00175, 0x00405, 0x00247, 0x0012A,
+ 0x00A14, 0x002BB, 0x00191, 0x0084F, 0x01438, 0x000AF, 0x00B97, 0x00483, 0x0143B, 0x0032B, 0x00243, 0x0142B,
+ 0x00958, 0x029BF, 0x00049, 0x00A6C, 0x014DB, 0x004AD, 0x014DE, 0x0084E, 0x01434, 0x00257, 0x02E5A, 0x00207,
+ 0x01435, 0x01439, 0x00CB6, 0x0143A, 0x00194, 0x00654, 0x02135, 0x0537C, 0x0015C, 0x00240, 0x01012, 0x0537D,
+ 0x00959, 0x01098, 0x01436, 0x0065F, 0x02026, 0x02137},
+ {0x00005, 0x00019, 0x00016, 0x00011, 0x0003E, 0x0005E, 0x000EF, 0x000E2, 0x00000, 0x00039, 0x0002B, 0x00026,
+ 0x00028, 0x00012, 0x000C2, 0x000ED, 0x0011D, 0x0000D, 0x00031, 0x0002A, 0x00025, 0x00020, 0x0005C, 0x001ED,
+ 0x0024D, 0x00770, 0x00006, 0x0007A, 0x00060, 0x0004F, 0x00048, 0x00039, 0x00186, 0x00213, 0x00EC6, 0x0000F,
+ 0x00026, 0x0005F, 0x00075, 0x00070, 0x00027, 0x001DB, 0x003C6, 0x0078F, 0x0003F, 0x000A6, 0x000F0, 0x0003A,
+ 0x00052, 0x0004E, 0x000E3, 0x001D9, 0x0030F, 0x00010, 0x001DD, 0x000A7, 0x000F7, 0x00022, 0x00092, 0x003C4,
+ 0x002EF, 0x00762, 0x00079, 0x0008F, 0x001DA, 0x00087, 0x000E8, 0x000BA, 0x00176, 0x000EE, 0x003B0, 0x00085,
+ 0x00119, 0x0030E, 0x00108, 0x001D2, 0x0010C, 0x00773, 0x00424, 0x00434, 0x00071, 0x005DD, 0x001C1, 0x003A7,
+ 0x00127, 0x0008D, 0x0021B, 0x007B2, 0x001DF, 0x003D8, 0x00764, 0x00EE4, 0x003B3, 0x0074D, 0x001D8, 0x005DC,
+ 0x0084A, 0x00499, 0x003C5, 0x01D8E, 0x00765, 0x00435, 0x00771, 0x001C2, 0x00118, 0x003BC, 0x00381, 0x00387,
+ 0x07B33, 0x01097, 0x01096, 0x01ECD, 0x00E99, 0x00F1C, 0x00F1D, 0x00EE5, 0x0011C, 0x07B32, 0x03D98, 0x01D8F,
+ 0x00E98, 0x00F67, 0x003BD, 0x00380, 0x00498, 0x00386},
+ {0x0000D, 0x00010, 0x0002E, 0x00039, 0x0000D, 0x00074, 0x000ED, 0x000B6, 0x00001, 0x00002, 0x00000, 0x00030,
+ 0x00029, 0x00070, 0x000F3, 0x0008C, 0x00166, 0x00009, 0x00033, 0x00078, 0x00006, 0x000C4, 0x0000B, 0x00163,
+ 0x000CC, 0x005BE, 0x0001F, 0x0002F, 0x00064, 0x00018, 0x000C6, 0x0000A, 0x00162, 0x002C0, 0x00EF3, 0x00007,
+ 0x0000F, 0x000E3, 0x000CA, 0x000B2, 0x0018F, 0x003AE, 0x0075F, 0x00C51, 0x00015, 0x00047, 0x000EE, 0x000E2,
+ 0x000EA, 0x00009, 0x0016A, 0x002C3, 0x0059D, 0x0003D, 0x00008, 0x001D9, 0x00032, 0x0000E, 0x0016E, 0x0032C,
+ 0x0065B, 0x0196B, 0x00002, 0x0000F, 0x001D8, 0x0008D, 0x000B4, 0x001E4, 0x00067, 0x00317, 0x00794, 0x00022,
+ 0x003BE, 0x00315, 0x00034, 0x00037, 0x002DE, 0x0006C, 0x00EFE, 0x0066C, 0x00028, 0x003CB, 0x003AC, 0x00035,
+ 0x0016B, 0x003BD, 0x002C1, 0x0062C, 0x01DFE, 0x0000E, 0x0059E, 0x005BF, 0x000DA, 0x00629, 0x00584, 0x00EB7,
+ 0x00B0A, 0x0066D, 0x0000C, 0x0077E, 0x0059C, 0x00778, 0x0075E, 0x0075A, 0x0062D, 0x00337, 0x00334, 0x00197,
+ 0x01E57, 0x01DE4, 0x0196A, 0x01E56, 0x00C50, 0x00B3F, 0x01E54, 0x00B0B, 0x0018E, 0x001B6, 0x01E55, 0x00CB4,
+ 0x00B3E, 0x00EB6, 0x01DE5, 0x01DFF, 0x00335, 0x001B7},
+ {0x00001, 0x0000B, 0x00019, 0x0006F, 0x0002A, 0x00075, 0x007EB, 0x00163, 0x00001, 0x0000E, 0x0001A, 0x0003E,
+ 0x0001C, 0x0002D, 0x00164, 0x007EC, 0x00165, 0x00004, 0x00006, 0x00036, 0x0007F, 0x000AE, 0x00158, 0x0015C,
+ 0x0056D, 0xFD510, 0x00000, 0x00004, 0x0007B, 0x000F3, 0x0003B, 0x007ED, 0x002B3, 0x002CC, 0x0056E, 0x00018,
+ 0x0003E, 0x00017, 0x0001E, 0x000AF, 0x003F7, 0x0056F, 0x002CD, 0xFD511, 0x00014, 0x000AD, 0x000AA, 0x00014,
+ 0x000A8, 0x00153, 0x000E8, 0x001FE, 0x00DCF, 0x00078, 0x001B8, 0x00152, 0x000FE, 0x002B1, 0x0015D, 0x00160,
+ 0xFD512, 0xFD513, 0x0007A, 0x002B0, 0x001E5, 0x000E9, 0x000FC, 0x006E6, 0x00DC8, 0x00584, 0xFD514, 0x000AB,
+ 0x00DDE, 0x00159, 0x003F4, 0x00DC9, 0x00DCA, 0x001FA, 0xFD515, 0xFD516, 0x000FC, 0x001FF, 0x001E4, 0x000AF,
+ 0x0015A, 0x00167, 0x00DCB, 0x00585, 0xFD517, 0x003F7, 0x03F55, 0xFD518, 0x00DDC, 0x00586, 0x03F56, 0xFD519,
+ 0x03F57, 0xFD51A, 0x001BA, 0x00587, 0x00588, 0x00DDF, 0x002B2, 0xFD51B, 0x00DCE, 0x003F6, 0xFD51C, 0x00FD4,
+ 0xFD51D, 0xFD51E, 0xFD51F, 0x7EA80, 0x7EA81, 0x0056C, 0x7EA82, 0x7EA83, 0x00376, 0x00589, 0x0058A, 0x7EA84,
+ 0x7EA85, 0x00DDD, 0x7EA86, 0x7EA87, 0x0058B, 0x07EA9},
+ {0x00003, 0x0000E, 0x0000F, 0x0007E, 0x00062, 0x000C6, 0x00CD9, 0x0063E, 0x00002, 0x00002, 0x00000, 0x00018,
+ 0x0000C, 0x00069, 0x00039, 0x00707, 0x00C7E, 0x00002, 0x0000D, 0x0001B, 0x0000F, 0x0019A, 0x00647, 0x01A37,
+ 0x346C4, 0x0346D, 0x00001, 0x0001E, 0x0007F, 0x0000A, 0x000E1, 0x00661, 0x00CE4, 0x346C5, 0x346C6, 0x0001D,
+ 0x00030, 0x0000D, 0x000CB, 0x00199, 0x00320, 0x0008E, 0x0652E, 0x346C7, 0x0003E, 0x00039, 0x00035, 0x00033,
+ 0x0019F, 0x001C0, 0x00CDA, 0x346C8, 0x346C9, 0x0000B, 0x000D0, 0x0019E, 0x00022, 0x00038, 0x0018E, 0x0031E,
+ 0x03294, 0x0023C, 0x00032, 0x00012, 0x00013, 0x00071, 0x0019D, 0x00020, 0x00C87, 0x00CC0, 0x346CA, 0x00338,
+ 0x00653, 0x001A2, 0x0032A, 0x00322, 0x00CE7, 0x00084, 0x0011F, 0x346CB, 0x00325, 0x00649, 0x0032B, 0x00077,
+ 0x00648, 0x00642, 0x00C86, 0x00C8C, 0x346CC, 0x0003A, 0x019B7, 0x00043, 0x00327, 0x0008C, 0x0008D, 0x00C8D,
+ 0x346CD, 0x346CE, 0x00337, 0x00CE5, 0x00085, 0x00326, 0x00347, 0x00CA4, 0x00C7F, 0x00D1A, 0x346CF, 0x00328,
+ 0x1A360, 0x1A361, 0x00CD8, 0x0068C, 0x03295, 0x03296, 0x0652F, 0x066D8, 0x00331, 0x00706, 0x0023D, 0x00076,
+ 0x00CC1, 0x00382, 0x00CE6, 0x066D9, 0x066DA, 0x066DB}};
+
+static const uint8 vc1_2ref_mvdata_bits[8][126] = {
+ {4, 5, 5, 5, 6, 7, 8, 10, 2, 5, 5, 6, 6, 7, 8, 9, 10, 4, 5, 6, 6, 7, 8, 9, 10, 11,
+ 4, 6, 6, 7, 7, 9, 9, 10, 12, 5, 8, 8, 8, 8, 9, 9, 10, 12, 5, 7, 8, 7, 7, 8, 9, 9,
+ 11, 7, 9, 10, 9, 10, 10, 10, 10, 12, 6, 9, 9, 9, 9, 9, 10, 10, 11, 7, 10, 10, 11, 11, 11, 12,
+ 12, 14, 8, 11, 10, 11, 11, 11, 11, 12, 12, 8, 12, 11, 11, 12, 12, 12, 12, 13, 8, 12, 11, 11, 12, 12,
+ 12, 13, 12, 9, 14, 13, 11, 13, 12, 13, 12, 13, 9, 13, 13, 12, 12, 13, 13, 13, 13, 13},
+ {3, 4, 5, 6, 8, 10, 11, 11, 2, 5, 5, 6, 7, 8, 10, 11, 11, 4, 5, 5, 6, 7, 9, 12, 13, 13,
+ 4, 6, 7, 7, 9, 10, 11, 13, 14, 5, 7, 7, 7, 8, 9, 11, 13, 13, 6, 8, 8, 8, 8, 9, 10, 12,
+ 13, 7, 9, 8, 8, 8, 9, 11, 12, 13, 7, 9, 9, 9, 9, 9, 10, 11, 13, 8, 10, 10, 10, 10, 10, 11,
+ 12, 13, 9, 11, 11, 10, 10, 10, 11, 11, 12, 10, 12, 12, 12, 11, 11, 11, 12, 12, 10, 13, 12, 12, 11, 11,
+ 11, 12, 12, 10, 13, 13, 12, 13, 11, 12, 11, 12, 10, 14, 13, 13, 12, 12, 12, 11, 11, 11},
+ {4, 4, 5, 5, 6, 7, 8, 9, 2, 5, 6, 6, 6, 7, 7, 9, 9, 4, 6, 6, 6, 7, 8, 9, 11, 12,
+ 5, 7, 7, 7, 9, 9, 10, 11, 12, 5, 7, 7, 7, 7, 9, 9, 10, 12, 5, 8, 8, 8, 8, 8, 9, 10,
+ 10, 6, 9, 8, 8, 8, 8, 9, 9, 11, 6, 10, 10, 9, 9, 9, 9, 10, 10, 7, 11, 10, 9, 9, 10, 9,
+ 10, 11, 7, 10, 11, 10, 10, 10, 9, 10, 11, 8, 12, 11, 11, 10, 11, 11, 10, 10, 8, 12, 12, 11, 11, 11,
+ 11, 10, 11, 8, 13, 12, 12, 11, 11, 11, 11, 10, 9, 13, 12, 12, 12, 11, 11, 10, 10, 10},
+ {3, 4, 6, 7, 7, 9, 11, 11, 2, 5, 5, 6, 8, 9, 10, 11, 13, 3, 5, 5, 7, 8, 9, 12, 14, 13,
+ 4, 6, 6, 7, 9, 11, 13, 14, 14, 5, 7, 7, 8, 9, 9, 13, 15, 13, 6, 8, 8, 8, 9, 10, 12, 14,
+ 13, 7, 10, 9, 9, 9, 9, 12, 13, 14, 7, 11, 10, 10, 10, 10, 11, 12, 13, 8, 11, 12, 12, 12, 11, 12,
+ 14, 15, 9, 11, 12, 11, 12, 11, 11, 12, 13, 9, 12, 13, 13, 12, 12, 13, 14, 14, 9, 12, 13, 13, 13, 12,
+ 13, 12, 14, 10, 13, 13, 14, 13, 11, 13, 14, 15, 10, 12, 13, 15, 14, 13, 13, 13, 14, 14},
+ {4, 5, 5, 5, 6, 7, 8, 8, 2, 6, 6, 6, 6, 6, 8, 9, 10, 4, 6, 6, 6, 6, 7, 9, 10, 11,
+ 4, 7, 7, 7, 7, 7, 9, 10, 12, 5, 7, 7, 7, 7, 7, 9, 10, 11, 6, 8, 8, 7, 7, 7, 8, 9,
+ 10, 6, 9, 8, 8, 7, 8, 10, 10, 11, 7, 9, 9, 8, 8, 8, 9, 9, 10, 8, 10, 10, 9, 9, 9, 11,
+ 11, 11, 8, 11, 10, 10, 9, 9, 10, 11, 10, 10, 12, 12, 11, 11, 10, 11, 12, 11, 10, 13, 12, 11, 11, 10,
+ 10, 11, 11, 11, 15, 13, 13, 13, 12, 12, 12, 12, 10, 15, 14, 13, 12, 12, 11, 11, 11, 11},
+ {4, 5, 6, 6, 6, 7, 8, 8, 2, 4, 5, 6, 6, 7, 8, 8, 9, 4, 6, 7, 7, 8, 8, 9, 10, 11,
+ 5, 6, 7, 7, 8, 8, 9, 10, 12, 5, 7, 8, 8, 8, 9, 10, 11, 12, 5, 7, 8, 8, 8, 8, 9, 10,
+ 11, 6, 8, 9, 8, 8, 9, 10, 11, 13, 5, 8, 9, 8, 8, 9, 9, 10, 11, 6, 10, 10, 9, 9, 10, 10,
+ 12, 13, 6, 10, 10, 9, 9, 10, 10, 11, 13, 7, 11, 11, 11, 11, 11, 12, 12, 13, 7, 11, 11, 11, 11, 11,
+ 11, 12, 12, 9, 13, 13, 13, 13, 12, 12, 13, 12, 9, 12, 13, 12, 12, 12, 13, 13, 12, 12},
+ {3, 5, 6, 8, 9, 10, 12, 12, 1, 5, 6, 7, 8, 9, 12, 12, 12, 4, 6, 7, 8, 9, 12, 12, 14, 21,
+ 4, 6, 8, 9, 9, 12, 13, 13, 14, 6, 9, 8, 8, 9, 13, 14, 13, 21, 6, 9, 9, 8, 9, 10, 11, 12,
+ 13, 8, 10, 10, 11, 11, 12, 12, 21, 21, 8, 11, 10, 11, 11, 12, 13, 14, 21, 9, 13, 10, 11, 13, 13, 12,
+ 21, 21, 9, 12, 10, 11, 12, 12, 13, 14, 21, 11, 15, 21, 13, 14, 15, 21, 15, 21, 10, 14, 14, 13, 13, 21,
+ 13, 13, 21, 13, 21, 21, 21, 20, 20, 14, 20, 20, 11, 14, 14, 20, 20, 13, 20, 20, 14, 16},
+ {2, 5, 6, 8, 9, 10, 13, 13, 2, 4, 5, 6, 8, 9, 10, 13, 14, 3, 5, 7, 8, 10, 12, 15, 20, 16,
+ 4, 6, 8, 8, 10, 12, 13, 20, 20, 7, 8, 8, 9, 10, 11, 12, 16, 20, 7, 8, 8, 8, 10, 11, 13, 20,
+ 20, 8, 10, 10, 10, 10, 11, 12, 15, 14, 8, 9, 9, 9, 10, 10, 13, 13, 20, 11, 12, 11, 11, 11, 13, 12,
+ 13, 20, 11, 12, 11, 11, 12, 12, 13, 13, 20, 10, 14, 11, 11, 12, 12, 13, 20, 20, 11, 13, 12, 11, 12, 13,
+ 14, 14, 20, 11, 19, 19, 13, 13, 15, 15, 16, 16, 11, 13, 14, 11, 13, 12, 13, 16, 16, 16}};
+
+/* P-Picture CBPCY VLC tables */
+// Looks like original tables are not conforming to standard at all. Are they used for old WMV?
+static const uint16 vc1_cbpcy_p_codes[4][64] = {
+ {0, 6, 15, 13, 13, 11, 3, 13, 5, 8, 49, 10, 12, 114, 102, 119, 1, 54, 96, 8, 10, 111,
+ 5, 15, 12, 10, 2, 12, 13, 115, 53, 63, 1, 7, 1, 7, 14, 12, 4, 14, 1, 9, 97, 11,
+ 7, 58, 52, 62, 4, 103, 1, 9, 11, 56, 101, 118, 4, 110, 100, 30, 2, 5, 4, 3},
+ {0, 9, 1, 18, 5, 14, 237, 26, 3, 121, 3, 22, 13, 16, 6, 30, 2, 10, 1, 20, 12, 241,
+ 5, 28, 16, 12, 3, 24, 28, 124, 239, 247, 1, 240, 1, 19, 18, 15, 4, 27, 1, 122, 2, 23,
+ 1, 17, 7, 31, 1, 11, 2, 21, 19, 246, 238, 29, 17, 13, 236, 25, 58, 63, 8, 125},
+ {0, 201, 25, 231, 5, 221, 1, 3, 2, 414, 2, 241, 16, 225, 195, 492, 2, 412, 1, 240, 7, 224,
+ 98, 245, 1, 220, 96, 5, 9, 230, 101, 247, 1, 102, 1, 415, 24, 3, 2, 244, 3, 54, 3, 484,
+ 17, 114, 200, 493, 3, 413, 1, 4, 13, 113, 99, 485, 4, 111, 194, 243, 5, 29, 26, 31},
+ {0, 28, 12, 44, 3, 36, 20, 52, 2, 32, 16, 48, 8, 40, 24, 28, 1, 30, 14, 46, 6, 38,
+ 22, 54, 3, 34, 18, 50, 10, 42, 26, 30, 1, 29, 13, 45, 5, 37, 21, 53, 2, 33, 17, 49,
+ 9, 41, 25, 29, 1, 31, 15, 47, 7, 39, 23, 55, 4, 35, 19, 51, 11, 43, 27, 31}};
+
+static const uint8 vc1_cbpcy_p_bits[4][64] = {
+ {13, 13, 7, 13, 7, 13, 13, 12, 6, 13, 7, 12, 6, 8, 8, 8, 5, 7, 8, 12, 6, 8, 13, 12, 7, 13, 13, 12, 6, 8, 7, 7,
+ 6, 13, 8, 12, 7, 13, 13, 12, 7, 13, 8, 12, 5, 7, 7, 7, 6, 8, 13, 12, 6, 7, 8, 8, 5, 8, 8, 6, 3, 3, 3, 2},
+ {14, 13, 8, 13, 3, 13, 8, 13, 3, 7, 8, 13, 4, 13, 13, 13, 3, 13, 13, 13, 4, 8,
+ 13, 13, 5, 13, 13, 13, 5, 7, 8, 8, 3, 8, 14, 13, 5, 13, 13, 13, 4, 7, 13, 13,
+ 6, 13, 13, 13, 5, 13, 8, 13, 5, 8, 8, 13, 5, 13, 8, 13, 6, 6, 13, 7},
+ {13, 8, 6, 8, 4, 8, 13, 12, 4, 9, 8, 8, 5, 8, 8, 9, 5, 9, 10, 8, 4, 8, 7, 8, 6, 8, 7, 13, 4, 8, 7, 8,
+ 5, 7, 8, 9, 6, 13, 13, 8, 4, 6, 8, 9, 5, 7, 8, 9, 5, 9, 9, 13, 5, 7, 7, 9, 4, 7, 8, 8, 3, 5, 5, 5},
+ {9, 9, 9, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 8, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
+ 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8}};
+
+/* Interlaced CBPCY VLC tables (Table 124 - Table 131) */
+static const uint16 vc1_icbpcy_p_codes[8][63] = {
+ {0x2F1A, 0x2F1B, 0x178C, 0x0090, 0x02A8, 0x02A9, 0x0BC7, 0x0091, 0x02AA, 0x02AB, 0x05E0, 0x004A, 0x0096,
+ 0x0097, 0x00BD, 0x0092, 0x02AC, 0x02AD, 0x05E1, 0x0098, 0x0132, 0x0133, 0x0179, 0x0134, 0x026A, 0x026B,
+ 0x02FC, 0x004E, 0x0040, 0x0041, 0x002B, 0x0093, 0x02AE, 0x02AF, 0x05E2, 0x0136, 0x026E, 0x026F, 0x02FD,
+ 0x009E, 0x013E, 0x013F, 0x017F, 0x0050, 0x0042, 0x0043, 0x002C, 0x0051, 0x00A4, 0x00A5, 0x00BE, 0x0053,
+ 0x0044, 0x0045, 0x002D, 0x0054, 0x0046, 0x0047, 0x002E, 0x0003, 0x0000, 0x0001, 0x0001},
+ {0x0041, 0x0042, 0x0100, 0x0043, 0x0088, 0x0089, 0x0101, 0x0045, 0x008C, 0x008D, 0x0102, 0x0010, 0x0022,
+ 0x0023, 0x0024, 0x0047, 0x0010, 0x0011, 0x0103, 0x0025, 0x0058, 0x0059, 0x005A, 0x005B, 0x005A, 0x005B,
+ 0x005C, 0x000C, 0x0030, 0x0031, 0x0019, 0x0009, 0x0014, 0x0015, 0x002C, 0x005C, 0x005D, 0x005E, 0x005F,
+ 0x0026, 0x005D, 0x005E, 0x005F, 0x000D, 0x0034, 0x0035, 0x001B, 0x0014, 0x0027, 0x002A, 0x002B, 0x000E,
+ 0x0038, 0x0039, 0x001D, 0x000F, 0x003C, 0x003D, 0x001F, 0x0005, 0x0009, 0x0000, 0x0003},
+ {0x0032, 0x0033, 0x001A, 0x0026, 0x00E4, 0x00E5, 0x01E6, 0x0027, 0x00E6, 0x00E7, 0x01E7, 0x000E, 0x0063,
+ 0x006C, 0x0077, 0x0028, 0x00E8, 0x00E9, 0x01E8, 0x007B, 0x00DA, 0x00DB, 0x00EC, 0x00F5, 0x01B8, 0x01B9,
+ 0x01DA, 0x0021, 0x004B, 0x0054, 0x002B, 0x0029, 0x00EA, 0x00EB, 0x01E9, 0x004A, 0x01BA, 0x01BB, 0x01DB,
+ 0x0020, 0x00DE, 0x00DF, 0x00F2, 0x0022, 0x0055, 0x0058, 0x002D, 0x000F, 0x0070, 0x0071, 0x0078, 0x0023,
+ 0x0059, 0x005C, 0x002F, 0x0024, 0x005D, 0x0062, 0x0030, 0x0002, 0x001F, 0x0006, 0x0000},
+ {0x0028, 0x0029, 0x009D, 0x0000, 0x01EA, 0x01EB, 0x01EC, 0x0001, 0x01ED, 0x01EE, 0x01EF, 0x0005, 0x00F0,
+ 0x00F1, 0x003B, 0x0002, 0x01F0, 0x01F1, 0x01F2, 0x003F, 0x015C, 0x015D, 0x0099, 0x0010, 0x03D0, 0x03D1,
+ 0x0130, 0x000F, 0x009E, 0x009F, 0x00FB, 0x0003, 0x01F3, 0x01F4, 0x01F5, 0x0011, 0x03D2, 0x03D3, 0x0131,
+ 0x0009, 0x015E, 0x015F, 0x009C, 0x0010, 0x00A8, 0x00A9, 0x0038, 0x0006, 0x00F2, 0x00F3, 0x004D, 0x0011,
+ 0x00AA, 0x00AB, 0x0039, 0x0012, 0x00AC, 0x00AD, 0x003A, 0x0006, 0x0016, 0x0017, 0x000E},
+ {0x003C, 0x003D, 0x001F, 0x000A, 0x0061, 0x0062, 0x0002, 0x000B, 0x0063, 0x0064, 0x0003, 0x0007, 0x0003,
+ 0x0004, 0x000B, 0x000C, 0x0065, 0x0066, 0x0004, 0x0012, 0x000A, 0x000B, 0x0014, 0x001B, 0x0018, 0x0019,
+ 0x0034, 0x002C, 0x0067, 0x0068, 0x0035, 0x000D, 0x0069, 0x006C, 0x0005, 0x0060, 0x001A, 0x001B, 0x0035,
+ 0x0013, 0x000E, 0x000F, 0x0015, 0x002D, 0x006D, 0x006E, 0x0038, 0x0008, 0x0008, 0x0009, 0x000C, 0x002E,
+ 0x006F, 0x0072, 0x003A, 0x002F, 0x0073, 0x0000, 0x003B, 0x0007, 0x0014, 0x0015, 0x0004},
+ {0x0038, 0x0039, 0x009D, 0x000A, 0x0091, 0x0092, 0x0093, 0x000B, 0x0094, 0x0095, 0x0096, 0x0003, 0x00EE,
+ 0x00EF, 0x0036, 0x000C, 0x0097, 0x0098, 0x0099, 0x0008, 0x01E4, 0x01E5, 0x006A, 0x0018, 0x03CC, 0x03CD,
+ 0x00D6, 0x000E, 0x009E, 0x009F, 0x00F5, 0x000D, 0x009A, 0x009B, 0x009C, 0x0019, 0x03CE, 0x03CF, 0x00D7,
+ 0x0009, 0x01E8, 0x01E9, 0x0090, 0x000F, 0x00E8, 0x00E9, 0x00F6, 0x0005, 0x00F0, 0x00F1, 0x0037, 0x0010,
+ 0x00EA, 0x00EB, 0x00F7, 0x0011, 0x00EC, 0x00ED, 0x0034, 0x0000, 0x003E, 0x003F, 0x0002},
+ {0x003C, 0x003D, 0x01CF, 0x0000, 0x00BF, 0x00E0, 0x01FC, 0x0001, 0x00E1, 0x00E2, 0x01FD, 0x0009, 0x01F1,
+ 0x01F2, 0x01F3, 0x0002, 0x00E3, 0x00E4, 0x01FE, 0x0011, 0x03EE, 0x03EF, 0x03F0, 0x0021, 0x07E2, 0x07E3,
+ 0x07E4, 0x0018, 0x03F7, 0x03FE, 0x03FF, 0x0003, 0x00E5, 0x00E6, 0x0080, 0x002E, 0x07E5, 0x07E6, 0x07E7,
+ 0x0016, 0x03F4, 0x03F5, 0x03F6, 0x0019, 0x0102, 0x0103, 0x0104, 0x000A, 0x01F4, 0x01F5, 0x01F6, 0x001A,
+ 0x0105, 0x0106, 0x0107, 0x001B, 0x0178, 0x0179, 0x01CE, 0x001D, 0x00BD, 0x00BE, 0x01F0},
+ {0x0003, 0x0004, 0x01B6, 0x0004, 0x002E, 0x002F, 0x000E, 0x0005, 0x0030, 0x0031, 0x000F, 0x0003, 0x000A,
+ 0x000B, 0x0014, 0x0006, 0x0032, 0x0033, 0x0010, 0x0005, 0x0030, 0x0031, 0x0032, 0x0009, 0x0066, 0x0067,
+ 0x0068, 0x001D, 0x01B7, 0x01B8, 0x01B9, 0x0007, 0x0034, 0x0035, 0x0011, 0x0016, 0x0069, 0x006A, 0x006B,
+ 0x000A, 0x0036, 0x0037, 0x00D8, 0x001E, 0x01BA, 0x01BB, 0x01BC, 0x0004, 0x0015, 0x0016, 0x0017, 0x001F,
+ 0x01BD, 0x01BE, 0x01BF, 0x0000, 0x0010, 0x0011, 0x0012, 0x001C, 0x00D9, 0x00DA, 0x0013}};
+
+static const uint8 vc1_icbpcy_p_bits[8][63] = {
+ {15, 15, 14, 9, 11, 11, 13, 9, 11, 11, 12, 8, 9, 9, 9, 9, 11, 11, 12, 9, 10, 10, 10, 10, 11, 11, 11, 8, 8, 8, 7, 9,
+ 11, 11, 12, 10, 11, 11, 11, 9, 10, 10, 10, 8, 8, 8, 7, 8, 9, 9, 9, 8, 8, 8, 7, 8, 8, 8, 7, 3, 3, 3, 1},
+ {7, 7, 9, 7, 8, 8, 9, 7, 8, 8, 9, 6, 7, 7, 7, 7, 7, 7, 9, 7, 8, 8, 8, 8, 9, 9, 9, 6, 7, 7, 6, 6,
+ 7, 7, 8, 8, 9, 9, 9, 7, 8, 8, 8, 6, 7, 7, 6, 6, 7, 7, 7, 6, 7, 7, 6, 6, 7, 7, 6, 3, 4, 3, 2},
+ {6, 6, 5, 6, 8, 8, 9, 6, 8, 8, 9, 5, 7, 7, 7, 6, 8, 8, 9, 7, 8, 8, 8, 8, 9, 9, 9, 6, 7, 7, 6, 6,
+ 8, 8, 9, 7, 9, 9, 9, 6, 8, 8, 8, 6, 7, 7, 6, 5, 7, 7, 7, 6, 7, 7, 6, 6, 7, 7, 6, 3, 5, 4, 2},
+ {6, 6, 8, 4, 9, 9, 9, 4, 9, 9, 9, 4, 8, 8, 7, 4, 9, 9, 9, 6, 9, 9, 8, 6, 10, 10, 9, 5, 8, 8, 8, 4,
+ 9, 9, 9, 6, 10, 10, 9, 5, 9, 9, 8, 5, 8, 8, 7, 4, 8, 8, 7, 5, 8, 8, 7, 5, 8, 8, 7, 3, 5, 5, 4},
+ {6, 6, 5, 5, 7, 7, 7, 5, 7, 7, 7, 5, 6, 6, 6, 5, 7, 7, 7, 6, 7, 7, 7, 7, 8, 8, 8, 6, 7, 7, 6, 5,
+ 7, 7, 7, 7, 8, 8, 8, 6, 7, 7, 7, 6, 7, 7, 6, 5, 6, 6, 6, 6, 7, 7, 6, 6, 7, 6, 6, 4, 5, 5, 3},
+ {6, 6, 8, 4, 8, 8, 8, 4, 8, 8, 8, 4, 8, 8, 7, 4, 8, 8, 8, 5, 9, 9, 8, 6, 10, 10, 9, 5, 8, 8, 8, 4,
+ 8, 8, 8, 6, 10, 10, 9, 5, 9, 9, 8, 5, 8, 8, 8, 4, 8, 8, 7, 5, 8, 8, 8, 5, 8, 8, 7, 3, 6, 6, 4},
+ {6, 6, 9, 3, 8, 8, 9, 3, 8, 8, 9, 4, 9, 9, 9, 3, 8, 8, 9, 5, 10, 10, 10, 6, 11, 11, 11, 5, 10, 10, 10, 3,
+ 8, 8, 8, 6, 11, 11, 11, 5, 10, 10, 10, 5, 9, 9, 9, 4, 9, 9, 9, 5, 9, 9, 9, 5, 9, 9, 9, 5, 8, 8, 9},
+ {6, 6, 10, 3, 7, 7, 7, 3, 7, 7, 7, 4, 8, 8, 8, 3, 7, 7, 7, 5, 9, 9, 9, 6, 10, 10, 10, 6, 10, 10, 10, 3,
+ 7, 7, 7, 6, 10, 10, 10, 5, 9, 9, 9, 6, 10, 10, 10, 4, 8, 8, 8, 6, 10, 10, 10, 5, 9, 9, 9, 6, 9, 9, 9}};
+
+/* MacroBlock Transform Type: 7.1.3.11, p89
+ * 8x8:B
+ * 8x4:B:btm 8x4:B:top 8x4:B:both,
+ * 4x8:B:right 4x8:B:left 4x8:B:both
+ * 4x4:B 8x8:MB
+ * 8x4:MB:btm 8x4:MB:top 8x4,MB,both
+ * 4x8,MB,right 4x8,MB,left
+ * 4x4,MB */
+static const uint16 vc1_ttmb_codes[3][16] = {{0x0003, 0x002E, 0x005F, 0x0000, 0x0016, 0x0015, 0x0001, 0x0004, 0x0014,
+ 0x02F1, 0x0179, 0x017B, 0x0BC0, 0x0BC1, 0x05E1, 0x017A},
+ {0x0006, 0x0006, 0x0003, 0x0007, 0x000F, 0x000E, 0x0000, 0x0002, 0x0002,
+ 0x0014, 0x0011, 0x000B, 0x0009, 0x0021, 0x0015, 0x0020},
+ {0x0006, 0x0000, 0x000E, 0x0005, 0x0002, 0x0003, 0x0003, 0x000F, 0x0002,
+ 0x0081, 0x0021, 0x0009, 0x0101, 0x0041, 0x0011, 0x0100}};
+
+static const uint8 vc1_ttmb_bits[3][16] = {{2, 6, 7, 2, 5, 5, 2, 3, 5, 10, 9, 9, 12, 12, 11, 9},
+ {3, 4, 4, 4, 4, 4, 3, 3, 2, 7, 7, 6, 6, 8, 7, 8},
+ {3, 3, 4, 5, 3, 3, 4, 4, 2, 10, 8, 6, 11, 9, 7, 11}};
+
+/* TTBLK (Transform Type per Block) tables */
+static const uint8 vc1_ttblk_codes[3][8] = {
+ {0, 1, 3, 5, 16, 17, 18, 19}, {3, 0, 1, 2, 3, 5, 8, 9}, {1, 0, 1, 4, 6, 7, 10, 11}};
+static const uint8 vc1_ttblk_bits[3][8] = {
+ {2, 2, 2, 3, 5, 5, 5, 5}, {2, 3, 3, 3, 3, 3, 4, 4}, {2, 3, 3, 3, 3, 3, 4, 4}};
+
+/* SUBBLKPAT tables, p93-94, reordered */
+static const uint8 vc1_subblkpat_codes[3][15] = {{14, 12, 7, 11, 9, 26, 2, 10, 27, 8, 0, 6, 1, 15, 1},
+ {14, 0, 8, 15, 10, 4, 23, 13, 5, 9, 25, 3, 24, 22, 1},
+ {5, 6, 2, 2, 8, 0, 28, 3, 1, 3, 29, 1, 19, 18, 15}};
+static const uint8 vc1_subblkpat_bits[3][15] = {{5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 4, 5, 1},
+ {4, 3, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 2},
+ {3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4}};
+
+/* MV differential tables, p265 */
+static const uint16 vc1_mv_diff_codes[4][73] =
+ {
+ {
+ 0, 2, 3, 8, 576, 3, 2, 6, 5, 577, 578, 7, 8, 9, 40, 19, 37, 82, 21,
+ 22, 23, 579, 580, 166, 96, 167, 49, 194, 195, 581, 582, 583, 292, 293, 294, 13, 2, 7,
+ 24, 50, 102, 295, 13, 7, 8, 18, 50, 103, 38, 20, 21, 22, 39, 204, 103, 23, 24,
+ 25, 104, 410, 105, 106, 107, 108, 109, 220, 411, 442, 222, 443, 446, 447, 7 /* 73 elements */
+ },
+ {
+ 0, 4, 5, 3, 4, 3, 4, 5, 20, 6, 21, 44, 45, 46, 3008,
+ 95, 112, 113, 57, 3009, 3010, 116, 117, 3011, 118, 3012, 3013, 3014, 3015, 3016,
+ 3017, 3018, 3019, 3020, 3021, 3022, 1, 4, 15, 160, 161, 41, 6, 11, 42,
+ 162, 43, 119, 56, 57, 58, 163, 236, 237, 3023, 119, 120, 242, 122, 486,
+ 1512, 487, 246, 494, 1513, 495, 1514, 1515, 1516, 1517, 1518, 1519, 31 /* 73 elements */
+ },
+ {
+ 0, 512, 513, 514, 515, 2, 3, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
+ 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 1, 5,
+ 287, 288, 289, 290, 6, 7, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303,
+ 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319 /* 73 elements */
+ },
+ {
+ 0, 1, 1, 2, 3, 4, 1, 5, 4, 3, 5, 8, 6, 9, 10, 11, 12, 7, 104,
+ 14, 105, 4, 10, 15, 11, 6, 14, 8, 106, 107, 108, 15, 109, 9, 55, 10, 1, 2,
+ 1, 2, 3, 12, 6, 2, 6, 7, 28, 7, 15, 8, 5, 18, 29, 152, 77, 24, 25,
+ 26, 39, 108, 13, 109, 55, 56, 57, 116, 11, 153, 234, 235, 118, 119, 15 /* 73 elements */
+ }};
+static const uint8 vc1_mv_diff_bits[4][73] = {
+ {
+ 6, 7, 7, 8, 14, 6, 5, 6, 7, 14, 14, 6, 6, 6, 8, 9, 10, 9, 7, 7, 7, 14, 14, 10, 9,
+ 10, 8, 10, 10, 14, 14, 14, 13, 13, 13, 6, 3, 5, 6, 8, 9, 13, 5, 4, 4, 5, 7, 9, 6, 5,
+ 5, 5, 6, 9, 8, 5, 5, 5, 7, 10, 7, 7, 7, 7, 7, 8, 10, 9, 8, 9, 9, 9, 3 /* 73 elements */
+ },
+ {
+ 5, 7, 7, 6, 6, 5, 5, 6, 7, 5, 7, 8, 8, 8, 14, 9, 9, 9, 8, 14, 14, 9, 9, 14, 9,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 3, 6, 8, 8, 6, 3, 4, 6, 8, 6, 9, 6, 6,
+ 6, 8, 8, 8, 14, 7, 7, 8, 7, 9, 13, 9, 8, 9, 13, 9, 13, 13, 13, 13, 13, 13, 5 /* 73 elements */
+
+ },
+ {
+ 3, 12, 12, 12, 12, 3, 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 1, 5, 11, 11, 11, 11, 4, 4, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 /* 73 elements */
+ },
+ {
+ 15, 11, 15, 15, 15, 15, 12, 15, 12, 11, 12, 12, 15, 12, 12, 12, 12, 15, 15, 12, 15, 10, 11, 12, 11,
+ 10, 11, 10, 15, 15, 15, 11, 15, 10, 14, 10, 4, 4, 5, 7, 8, 9, 5, 3, 4, 5, 6, 8, 5, 4,
+ 3, 5, 6, 8, 7, 5, 5, 5, 6, 7, 9, 7, 6, 6, 6, 7, 10, 8, 8, 8, 7, 7, 4 /* 73 elements */
+ }};
+
+static const uint32 vc1_ac_tables[AC_MODES][186][2] = {
+ {{0x0001, 2}, {0x0005, 3}, {0x000D, 4}, {0x0012, 5}, {0x000E, 6}, {0x0015, 7}, {0x0013, 8}, {0x003F, 8},
+ {0x004B, 9}, {0x011F, 9}, {0x00B8, 10}, {0x03E3, 10}, {0x0172, 11}, {0x024D, 12}, {0x03DA, 12}, {0x02DD, 13},
+ {0x1F55, 13}, {0x05B9, 14}, {0x3EAE, 14}, {0x0000, 4}, {0x0010, 5}, {0x0008, 7}, {0x0020, 8}, {0x0029, 9},
+ {0x01F4, 9}, {0x0233, 10}, {0x01E0, 11}, {0x012A, 12}, {0x03DD, 12}, {0x050A, 13}, {0x1F29, 13}, {0x0A42, 14},
+ {0x1272, 15}, {0x1737, 15}, {0x0003, 5}, {0x0011, 7}, {0x00C4, 8}, {0x004B, 10}, {0x00B4, 11}, {0x07D4, 11},
+ {0x0345, 12}, {0x02D7, 13}, {0x07BF, 13}, {0x0938, 14}, {0x0BBB, 14}, {0x095E, 15}, {0x0013, 5}, {0x0078, 7},
+ {0x0069, 9}, {0x0232, 10}, {0x0461, 11}, {0x03EC, 12}, {0x0520, 13}, {0x1F2A, 13}, {0x3E50, 14}, {0x3E51, 14},
+ {0x1486, 15}, {0x000C, 6}, {0x0024, 9}, {0x0094, 11}, {0x08C0, 12}, {0x0F09, 14}, {0x1EF0, 15}, {0x003D, 6},
+ {0x0053, 9}, {0x01A0, 11}, {0x02D6, 13}, {0x0F08, 14}, {0x0013, 7}, {0x007C, 9}, {0x07C1, 11}, {0x04AC, 14},
+ {0x001B, 7}, {0x00A0, 10}, {0x0344, 12}, {0x0F79, 14}, {0x0079, 7}, {0x03E1, 10}, {0x02D4, 13}, {0x2306, 14},
+ {0x0021, 8}, {0x023C, 10}, {0x0FAE, 12}, {0x23DE, 14}, {0x0035, 8}, {0x0175, 11}, {0x07B3, 13}, {0x00C5, 8},
+ {0x0174, 11}, {0x0785, 13}, {0x0048, 9}, {0x01A3, 11}, {0x049E, 13}, {0x002C, 9}, {0x00FA, 10}, {0x07D6, 11},
+ {0x0092, 10}, {0x05CC, 13}, {0x1EF1, 15}, {0x00A3, 10}, {0x03ED, 12}, {0x093E, 14}, {0x01E2, 11}, {0x1273, 15},
+ {0x07C4, 11}, {0x1487, 15}, {0x0291, 12}, {0x0293, 12}, {0x0F8A, 12}, {0x0509, 13}, {0x0508, 13}, {0x078D, 13},
+ {0x07BE, 13}, {0x078C, 13}, {0x04AE, 14}, {0x0BBA, 14}, {0x2307, 14}, {0x0B9A, 14}, {0x1736, 15}, {0x000E, 4},
+ {0x0045, 7}, {0x01F3, 9}, {0x047A, 11}, {0x05DC, 13}, {0x23DF, 14}, {0x0019, 5}, {0x0028, 9}, {0x0176, 11},
+ {0x049D, 13}, {0x23DD, 14}, {0x0030, 6}, {0x00A2, 10}, {0x02EF, 12}, {0x05B8, 14}, {0x003F, 6}, {0x00A5, 10},
+ {0x03DB, 12}, {0x093F, 14}, {0x0044, 7}, {0x07CB, 11}, {0x095F, 15}, {0x0063, 7}, {0x03C3, 12}, {0x0015, 8},
+ {0x08F6, 12}, {0x0017, 8}, {0x0498, 13}, {0x002C, 8}, {0x07B2, 13}, {0x002F, 8}, {0x1F54, 13}, {0x008D, 8},
+ {0x07BD, 13}, {0x008E, 8}, {0x1182, 13}, {0x00FB, 8}, {0x050B, 13}, {0x002D, 8}, {0x07C0, 11}, {0x0079, 9},
+ {0x1F5F, 13}, {0x007A, 9}, {0x1F56, 13}, {0x0231, 10}, {0x03E4, 10}, {0x01A1, 11}, {0x0143, 11}, {0x01F7, 11},
+ {0x016F, 12}, {0x0292, 12}, {0x02E7, 12}, {0x016C, 12}, {0x016D, 12}, {0x03DC, 12}, {0x0F8B, 12}, {0x0499, 13},
+ {0x03D8, 12}, {0x078E, 13}, {0x02D5, 13}, {0x1F5E, 13}, {0x1F2B, 13}, {0x078F, 13}, {0x04AD, 14}, {0x3EAF, 14},
+ {0x23DC, 14}, {0x004A, 9}},
+ {{0x0000, 3}, {0x0003, 4}, {0x000B, 5}, {0x0014, 6}, {0x003F, 6}, {0x005D, 7}, {0x00A2, 8}, {0x00AC, 9},
+ {0x016E, 9}, {0x020A, 10}, {0x02E2, 10}, {0x0432, 11}, {0x05C9, 11}, {0x0827, 12}, {0x0B54, 12}, {0x04E6, 13},
+ {0x105F, 13}, {0x172A, 13}, {0x20B2, 14}, {0x2D4E, 14}, {0x39F0, 14}, {0x4175, 15}, {0x5A9E, 15}, {0x0004, 4},
+ {0x001E, 5}, {0x0042, 7}, {0x00B6, 8}, {0x0173, 9}, {0x0395, 10}, {0x072E, 11}, {0x0B94, 12}, {0x16A4, 13},
+ {0x20B3, 14}, {0x2E45, 14}, {0x0005, 5}, {0x0040, 7}, {0x0049, 9}, {0x028F, 10}, {0x05CB, 11}, {0x048A, 13},
+ {0x09DD, 14}, {0x73E2, 15}, {0x0018, 5}, {0x0025, 8}, {0x008A, 10}, {0x051B, 11}, {0x0E5F, 12}, {0x09C9, 14},
+ {0x139C, 15}, {0x0029, 6}, {0x004F, 9}, {0x0412, 11}, {0x048D, 13}, {0x2E41, 14}, {0x0038, 6}, {0x010E, 9},
+ {0x05A8, 11}, {0x105C, 13}, {0x39F2, 14}, {0x0058, 7}, {0x021F, 10}, {0x0E7E, 12}, {0x39FF, 14}, {0x0023, 8},
+ {0x02E3, 10}, {0x04E5, 13}, {0x2E40, 14}, {0x00A1, 8}, {0x05BE, 11}, {0x09C8, 14}, {0x0083, 8}, {0x013A, 11},
+ {0x1721, 13}, {0x0044, 9}, {0x0276, 12}, {0x39F6, 14}, {0x008B, 10}, {0x04EF, 13}, {0x5A9B, 15}, {0x0208, 10},
+ {0x1CFE, 13}, {0x0399, 10}, {0x1CB4, 13}, {0x039E, 10}, {0x39F3, 14}, {0x05AB, 11}, {0x73E3, 15}, {0x0737, 11},
+ {0x5A9F, 15}, {0x082D, 12}, {0x0E69, 12}, {0x0E68, 12}, {0x0433, 11}, {0x0B7B, 12}, {0x2DF8, 14}, {0x2E56, 14},
+ {0x2E57, 14}, {0x39F7, 14}, {0x51A5, 15}, {0x0003, 3}, {0x002A, 6}, {0x00E4, 8}, {0x028E, 10}, {0x0735, 11},
+ {0x1058, 13}, {0x1CFA, 13}, {0x2DF9, 14}, {0x4174, 15}, {0x0009, 4}, {0x0054, 8}, {0x0398, 10}, {0x048B, 13},
+ {0x139D, 15}, {0x000D, 4}, {0x00AD, 9}, {0x0826, 12}, {0x2D4C, 14}, {0x0011, 5}, {0x016B, 9}, {0x0B7F, 12},
+ {0x51A4, 15}, {0x0019, 5}, {0x021B, 10}, {0x16FD, 13}, {0x001D, 5}, {0x0394, 10}, {0x28D3, 14}, {0x002B, 6},
+ {0x05BC, 11}, {0x5A9A, 15}, {0x002F, 6}, {0x0247, 12}, {0x0010, 7}, {0x0A35, 12}, {0x003E, 6}, {0x0B7A, 12},
+ {0x0059, 7}, {0x105E, 13}, {0x0026, 8}, {0x09CF, 14}, {0x0055, 8}, {0x1CB5, 13}, {0x0057, 8}, {0x0E5B, 12},
+ {0x00A0, 8}, {0x1468, 13}, {0x0170, 9}, {0x0090, 10}, {0x01CE, 9}, {0x021A, 10}, {0x0218, 10}, {0x0168, 9},
+ {0x021E, 10}, {0x0244, 12}, {0x0736, 11}, {0x0138, 11}, {0x0519, 11}, {0x0E5E, 12}, {0x072C, 11}, {0x0B55, 12},
+ {0x09DC, 14}, {0x20BB, 14}, {0x048C, 13}, {0x1723, 13}, {0x2E44, 14}, {0x16A5, 13}, {0x0518, 11}, {0x39FE, 14},
+ {0x0169, 9}},
+ {{0x0001, 2}, {0x0006, 3}, {0x000F, 4}, {0x0016, 5}, {0x0020, 6}, {0x0018, 7}, {0x0008, 8}, {0x009A, 8},
+ {0x0056, 9}, {0x013E, 9}, {0x00F0, 10}, {0x03A5, 10}, {0x0077, 11}, {0x01EF, 11}, {0x009A, 12}, {0x005D, 13},
+ {0x0001, 4}, {0x0011, 5}, {0x0002, 7}, {0x000B, 8}, {0x0012, 9}, {0x01D6, 9}, {0x027E, 10}, {0x0191, 11},
+ {0x00EA, 12}, {0x03DC, 12}, {0x013B, 13}, {0x0004, 5}, {0x0014, 7}, {0x009E, 8}, {0x0009, 10}, {0x01AC, 11},
+ {0x01E2, 11}, {0x03CA, 12}, {0x005F, 13}, {0x0017, 5}, {0x004E, 7}, {0x005E, 9}, {0x00F3, 10}, {0x01AD, 11},
+ {0x00EC, 12}, {0x05F0, 13}, {0x000E, 6}, {0x00E1, 8}, {0x03A4, 10}, {0x009C, 12}, {0x013D, 13}, {0x003B, 6},
+ {0x001C, 9}, {0x0014, 11}, {0x09BE, 12}, {0x0006, 7}, {0x007A, 9}, {0x0190, 11}, {0x0137, 13}, {0x001B, 7},
+ {0x0008, 10}, {0x075C, 11}, {0x0071, 7}, {0x00D7, 10}, {0x09BF, 12}, {0x0007, 8}, {0x00AF, 10}, {0x04CC, 11},
+ {0x0034, 8}, {0x0265, 10}, {0x009F, 12}, {0x00E0, 8}, {0x0016, 11}, {0x0327, 12}, {0x0015, 9}, {0x017D, 11},
+ {0x0EBB, 12}, {0x0014, 9}, {0x00F6, 10}, {0x01E4, 11}, {0x00CB, 10}, {0x099D, 12}, {0x00CA, 10}, {0x02FC, 12},
+ {0x017F, 11}, {0x04CD, 11}, {0x02FD, 12}, {0x04FE, 11}, {0x013A, 13}, {0x000A, 4}, {0x0042, 7}, {0x01D3, 9},
+ {0x04DD, 11}, {0x0012, 5}, {0x00E8, 8}, {0x004C, 11}, {0x0136, 13}, {0x0039, 6}, {0x0264, 10}, {0x0EBA, 12},
+ {0x0000, 7}, {0x00AE, 10}, {0x099C, 12}, {0x001F, 7}, {0x04DE, 11}, {0x0043, 7}, {0x04DC, 11}, {0x0003, 8},
+ {0x03CB, 12}, {0x0006, 8}, {0x099E, 12}, {0x002A, 8}, {0x05F1, 13}, {0x000F, 8}, {0x09FE, 12}, {0x0033, 8},
+ {0x09FF, 12}, {0x0098, 8}, {0x099F, 12}, {0x00EA, 8}, {0x013C, 13}, {0x002E, 8}, {0x0192, 11}, {0x0136, 9},
+ {0x006A, 9}, {0x0015, 11}, {0x03AF, 10}, {0x01E3, 11}, {0x0074, 11}, {0x00EB, 12}, {0x02F9, 12}, {0x005C, 13},
+ {0x00ED, 12}, {0x03DD, 12}, {0x0326, 12}, {0x005E, 13}, {0x0016, 7}},
+ {{0x0004, 3}, {0x0014, 5}, {0x0017, 7}, {0x007F, 8}, {0x0154, 9}, {0x01F2, 10}, {0x00BF, 11}, {0x0065, 12},
+ {0x0AAA, 12}, {0x0630, 13}, {0x1597, 13}, {0x03B7, 14}, {0x2B22, 14}, {0x0BE6, 15}, {0x000B, 4}, {0x0037, 7},
+ {0x0062, 9}, {0x0007, 11}, {0x0166, 12}, {0x00CE, 13}, {0x1590, 13}, {0x05F6, 14}, {0x0BE7, 15}, {0x0007, 5},
+ {0x006D, 8}, {0x0003, 11}, {0x031F, 12}, {0x05F2, 14}, {0x0002, 6}, {0x0061, 9}, {0x0055, 12}, {0x01DF, 14},
+ {0x001A, 6}, {0x001E, 10}, {0x0AC9, 12}, {0x2B23, 14}, {0x001E, 6}, {0x001F, 10}, {0x0AC3, 12}, {0x2B2B, 14},
+ {0x0006, 7}, {0x0004, 11}, {0x02F8, 13}, {0x0019, 7}, {0x0006, 11}, {0x063D, 13}, {0x0057, 7}, {0x0182, 11},
+ {0x2AA2, 14}, {0x0004, 8}, {0x0180, 11}, {0x059C, 14}, {0x007D, 8}, {0x0164, 12}, {0x076D, 15}, {0x0002, 9},
+ {0x018D, 11}, {0x1581, 13}, {0x00AD, 8}, {0x0060, 12}, {0x0C67, 14}, {0x001C, 9}, {0x00EE, 13}, {0x0003, 9},
+ {0x02CF, 13}, {0x00D9, 9}, {0x1580, 13}, {0x0002, 11}, {0x0183, 11}, {0x0057, 12}, {0x0061, 12}, {0x0031, 11},
+ {0x0066, 12}, {0x0631, 13}, {0x0632, 13}, {0x00AC, 13}, {0x031D, 12}, {0x0076, 12}, {0x003A, 11}, {0x0165, 12},
+ {0x0C66, 14}, {0x0003, 2}, {0x0054, 7}, {0x02AB, 10}, {0x0016, 13}, {0x05F7, 14}, {0x0005, 4}, {0x00F8, 9},
+ {0x0AA9, 12}, {0x005F, 15}, {0x0004, 4}, {0x001C, 10}, {0x1550, 13}, {0x0004, 5}, {0x0077, 11}, {0x076C, 15},
+ {0x000E, 5}, {0x000A, 12}, {0x000C, 5}, {0x0562, 11}, {0x0004, 6}, {0x031C, 12}, {0x0006, 6}, {0x00C8, 13},
+ {0x000D, 6}, {0x01DA, 13}, {0x0007, 6}, {0x00C9, 13}, {0x0001, 7}, {0x002E, 14}, {0x0014, 7}, {0x1596, 13},
+ {0x000A, 7}, {0x0AC2, 12}, {0x0016, 7}, {0x015B, 14}, {0x0015, 7}, {0x015A, 14}, {0x000F, 8}, {0x005E, 15},
+ {0x007E, 8}, {0x00AB, 8}, {0x002D, 9}, {0x00D8, 9}, {0x000B, 9}, {0x0014, 10}, {0x02B3, 10}, {0x01F3, 10},
+ {0x003A, 10}, {0x0000, 10}, {0x0058, 10}, {0x002E, 9}, {0x005E, 10}, {0x0563, 11}, {0x00EC, 12}, {0x0054, 12},
+ {0x0AC1, 12}, {0x1556, 13}, {0x02FA, 13}, {0x0181, 11}, {0x1557, 13}, {0x059D, 14}, {0x2AA3, 14}, {0x2B2A, 14},
+ {0x01DE, 14}, {0x063C, 13}, {0x00CF, 13}, {0x1594, 13}, {0x000D, 9}},
+ {{0x0002, 2}, {0x0006, 3}, {0x000F, 4}, {0x000D, 5}, {0x000C, 5}, {0x0015, 6}, {0x0013, 6}, {0x0012, 6},
+ {0x0017, 7}, {0x001F, 8}, {0x001E, 8}, {0x001D, 8}, {0x0025, 9}, {0x0024, 9}, {0x0023, 9}, {0x0021, 9},
+ {0x0021, 10}, {0x0020, 10}, {0x000F, 10}, {0x000E, 10}, {0x0007, 11}, {0x0006, 11}, {0x0020, 11}, {0x0021, 11},
+ {0x0050, 12}, {0x0051, 12}, {0x0052, 12}, {0x000E, 4}, {0x0014, 6}, {0x0016, 7}, {0x001C, 8}, {0x0020, 9},
+ {0x001F, 9}, {0x000D, 10}, {0x0022, 11}, {0x0053, 12}, {0x0055, 12}, {0x000B, 5}, {0x0015, 7}, {0x001E, 9},
+ {0x000C, 10}, {0x0056, 12}, {0x0011, 6}, {0x001B, 8}, {0x001D, 9}, {0x000B, 10}, {0x0010, 6}, {0x0022, 9},
+ {0x000A, 10}, {0x000D, 6}, {0x001C, 9}, {0x0008, 10}, {0x0012, 7}, {0x001B, 9}, {0x0054, 12}, {0x0014, 7},
+ {0x001A, 9}, {0x0057, 12}, {0x0019, 8}, {0x0009, 10}, {0x0018, 8}, {0x0023, 11}, {0x0017, 8}, {0x0019, 9},
+ {0x0018, 9}, {0x0007, 10}, {0x0058, 12}, {0x0007, 4}, {0x000C, 6}, {0x0016, 8}, {0x0017, 9}, {0x0006, 10},
+ {0x0005, 11}, {0x0004, 11}, {0x0059, 12}, {0x000F, 6}, {0x0016, 9}, {0x0005, 10}, {0x000E, 6}, {0x0004, 10},
+ {0x0011, 7}, {0x0024, 11}, {0x0010, 7}, {0x0025, 11}, {0x0013, 7}, {0x005A, 12}, {0x0015, 8}, {0x005B, 12},
+ {0x0014, 8}, {0x0013, 8}, {0x001A, 8}, {0x0015, 9}, {0x0014, 9}, {0x0013, 9}, {0x0012, 9}, {0x0011, 9},
+ {0x0026, 11}, {0x0027, 11}, {0x005C, 12}, {0x005D, 12}, {0x005E, 12}, {0x005F, 12}, {0x0003, 7}},
+ {{0x0002, 2}, {0x000F, 4}, {0x0015, 6}, {0x0017, 7}, {0x001F, 8}, {0x0025, 9}, {0x0024, 9}, {0x0021, 10},
+ {0x0020, 10}, {0x0007, 11}, {0x0006, 11}, {0x0020, 11}, {0x0006, 3}, {0x0014, 6}, {0x001E, 8}, {0x000F, 10},
+ {0x0021, 11}, {0x0050, 12}, {0x000E, 4}, {0x001D, 8}, {0x000E, 10}, {0x0051, 12}, {0x000D, 5}, {0x0023, 9},
+ {0x000D, 10}, {0x000C, 5}, {0x0022, 9}, {0x0052, 12}, {0x000B, 5}, {0x000C, 10}, {0x0053, 12}, {0x0013, 6},
+ {0x000B, 10}, {0x0054, 12}, {0x0012, 6}, {0x000A, 10}, {0x0011, 6}, {0x0009, 10}, {0x0010, 6}, {0x0008, 10},
+ {0x0016, 7}, {0x0055, 12}, {0x0015, 7}, {0x0014, 7}, {0x001C, 8}, {0x001B, 8}, {0x0021, 9}, {0x0020, 9},
+ {0x001F, 9}, {0x001E, 9}, {0x001D, 9}, {0x001C, 9}, {0x001B, 9}, {0x001A, 9}, {0x0022, 11}, {0x0023, 11},
+ {0x0056, 12}, {0x0057, 12}, {0x0007, 4}, {0x0019, 9}, {0x0005, 11}, {0x000F, 6}, {0x0004, 11}, {0x000E, 6},
+ {0x000D, 6}, {0x000C, 6}, {0x0013, 7}, {0x0012, 7}, {0x0011, 7}, {0x0010, 7}, {0x001A, 8}, {0x0019, 8},
+ {0x0018, 8}, {0x0017, 8}, {0x0016, 8}, {0x0015, 8}, {0x0014, 8}, {0x0013, 8}, {0x0018, 9}, {0x0017, 9},
+ {0x0016, 9}, {0x0015, 9}, {0x0014, 9}, {0x0013, 9}, {0x0012, 9}, {0x0011, 9}, {0x0007, 10}, {0x0006, 10},
+ {0x0005, 10}, {0x0004, 10}, {0x0024, 11}, {0x0025, 11}, {0x0026, 11}, {0x0027, 11}, {0x0058, 12}, {0x0059, 12},
+ {0x005A, 12}, {0x005B, 12}, {0x005C, 12}, {0x005D, 12}, {0x005E, 12}, {0x005F, 12}, {0x0003, 7}},
+ {{0x0000, 2}, {0x0003, 3}, {0x000D, 4}, {0x0005, 4}, {0x001C, 5}, {0x0016, 5}, {0x003F, 6}, {0x003A, 6},
+ {0x002E, 6}, {0x0022, 6}, {0x007B, 7}, {0x0067, 7}, {0x005F, 7}, {0x0047, 7}, {0x0026, 7}, {0x00EF, 8},
+ {0x00CD, 8}, {0x00C1, 8}, {0x00A9, 8}, {0x004F, 8}, {0x01F2, 9}, {0x01DD, 9}, {0x0199, 9}, {0x0185, 9},
+ {0x015D, 9}, {0x011B, 9}, {0x03EF, 10}, {0x03E1, 10}, {0x03C8, 10}, {0x0331, 10}, {0x0303, 10}, {0x02F1, 10},
+ {0x02A0, 10}, {0x0233, 10}, {0x0126, 10}, {0x07C0, 11}, {0x076F, 11}, {0x076C, 11}, {0x0661, 11}, {0x0604, 11},
+ {0x0572, 11}, {0x0551, 11}, {0x046A, 11}, {0x0274, 11}, {0x0F27, 12}, {0x0F24, 12}, {0x0EDB, 12}, {0x0C8E, 12},
+ {0x0C0B, 12}, {0x0C0A, 12}, {0x0AE3, 12}, {0x08D6, 12}, {0x0490, 12}, {0x0495, 12}, {0x1F19, 13}, {0x1DB5, 13},
+ {0x0009, 4}, {0x0010, 5}, {0x0029, 6}, {0x0062, 7}, {0x00F3, 8}, {0x00AD, 8}, {0x01E5, 9}, {0x0179, 9},
+ {0x009C, 9}, {0x03B1, 10}, {0x02AE, 10}, {0x0127, 10}, {0x076E, 11}, {0x0570, 11}, {0x0275, 11}, {0x0F25, 12},
+ {0x0EC0, 12}, {0x0AA0, 12}, {0x08D7, 12}, {0x1E4C, 13}, {0x0008, 5}, {0x0063, 7}, {0x00AF, 8}, {0x017B, 9},
+ {0x03B3, 10}, {0x07DD, 11}, {0x0640, 11}, {0x0F8D, 12}, {0x0BC1, 12}, {0x0491, 12}, {0x0028, 6}, {0x00C3, 8},
+ {0x0151, 9}, {0x02A1, 10}, {0x0573, 11}, {0x0EC3, 12}, {0x1F35, 13}, {0x0065, 7}, {0x01DA, 9}, {0x02AF, 10},
+ {0x0277, 11}, {0x08C9, 12}, {0x1781, 13}, {0x0025, 7}, {0x0118, 9}, {0x0646, 11}, {0x0AA6, 12}, {0x1780, 13},
+ {0x00C9, 8}, {0x0321, 10}, {0x0F9B, 12}, {0x191E, 13}, {0x0048, 8}, {0x07CC, 11}, {0x0AA1, 12}, {0x0180, 9},
+ {0x0465, 11}, {0x1905, 13}, {0x03E2, 10}, {0x0EC1, 12}, {0x3C9B, 14}, {0x02F4, 10}, {0x08C8, 12}, {0x07C1, 11},
+ {0x0928, 13}, {0x05E1, 11}, {0x320D, 14}, {0x0EC2, 12}, {0x6418, 15}, {0x1F34, 13}, {0x0078, 7}, {0x0155, 9},
+ {0x0552, 11}, {0x191F, 13}, {0x00FA, 8}, {0x07DC, 11}, {0x1907, 13}, {0x00AC, 8}, {0x0249, 11}, {0x13B1, 14},
+ {0x01F6, 9}, {0x0AE2, 12}, {0x01DC, 9}, {0x04ED, 12}, {0x0184, 9}, {0x1904, 13}, {0x0156, 9}, {0x09D9, 13},
+ {0x03E7, 10}, {0x0929, 13}, {0x03B2, 10}, {0x3B68, 14}, {0x02F5, 10}, {0x13B0, 14}, {0x0322, 10}, {0x3B69, 14},
+ {0x0234, 10}, {0x7935, 15}, {0x07C7, 11}, {0xC833, 16}, {0x0660, 11}, {0x7934, 15}, {0x024B, 11}, {0xC832, 16},
+ {0x0AA7, 12}, {0x1F18, 13}, {0x007A, 7}},
+ {{0x0002, 2}, {0x0000, 3}, {0x001E, 5}, {0x0004, 5}, {0x0012, 6}, {0x0070, 7}, {0x001A, 7},
+ {0x005F, 8}, {0x0047, 8}, {0x01D3, 9}, {0x00B5, 9}, {0x0057, 9}, {0x03B5, 10}, {0x016D, 10},
+ {0x0162, 10}, {0x07CE, 11}, {0x0719, 11}, {0x0691, 11}, {0x02C6, 11}, {0x0156, 11}, {0x0F92, 12},
+ {0x0D2E, 12}, {0x0D20, 12}, {0x059E, 12}, {0x0468, 12}, {0x02A6, 12}, {0x1DA2, 13}, {0x1C60, 13},
+ {0x1A43, 13}, {0x0B1D, 13}, {0x08C0, 13}, {0x055D, 13}, {0x0003, 3}, {0x000A, 5}, {0x0077, 7},
+ {0x00E5, 8}, {0x01D9, 9}, {0x03E5, 10}, {0x0166, 10}, {0x0694, 11}, {0x0152, 11}, {0x059F, 12},
+ {0x1F3C, 13}, {0x1A4B, 13}, {0x055E, 13}, {0x000C, 4}, {0x007D, 7}, {0x0044, 8}, {0x03E0, 10},
+ {0x0769, 11}, {0x0E31, 12}, {0x1F26, 13}, {0x055C, 13}, {0x001B, 5}, {0x00E2, 8}, {0x03A5, 10},
+ {0x02C9, 11}, {0x1F23, 13}, {0x3B47, 14}, {0x0007, 5}, {0x01D8, 9}, {0x02D8, 11}, {0x1F27, 13},
+ {0x3494, 14}, {0x0035, 6}, {0x03E1, 10}, {0x059C, 12}, {0x38C3, 14}, {0x000C, 6}, {0x0165, 10},
+ {0x1D23, 13}, {0x1638, 14}, {0x0068, 7}, {0x0693, 11}, {0x3A45, 14}, {0x0020, 7}, {0x0F90, 12},
+ {0x7CF6, 15}, {0x00E8, 8}, {0x058F, 12}, {0x2CEF, 15}, {0x0045, 8}, {0x0B3A, 13}, {0x01F1, 9},
+ {0x3B46, 14}, {0x01A7, 9}, {0x1676, 14}, {0x0056, 9}, {0x692A, 15}, {0x038D, 10}, {0xE309, 16},
+ {0x00AA, 10}, {0x1C611, 17}, {0x02DF, 11}, {0xB3B9, 17}, {0x02C8, 11}, {0x38C20, 18}, {0x01B0, 11},
+ {0x16390, 18}, {0x0F9F, 12}, {0x16771, 18}, {0x0ED0, 12}, {0x71843, 19}, {0x0D2A, 12}, {0xF9E8C, 20},
+ {0x0461, 12}, {0xF9E8E, 20}, {0x0B67, 13}, {0x055F, 13}, {0x003F, 6}, {0x006D, 9}, {0x0E90, 12},
+ {0x054E, 13}, {0x0013, 6}, {0x0119, 10}, {0x0B66, 13}, {0x000B, 6}, {0x0235, 11}, {0x7CF5, 15},
+ {0x0075, 7}, {0x0D24, 12}, {0xF9E9, 16}, {0x002E, 7}, {0x1F22, 13}, {0x0021, 7}, {0x054F, 13},
+ {0x0014, 7}, {0x3A44, 14}, {0x00E4, 8}, {0x7CF7, 15}, {0x005E, 8}, {0x7185, 15}, {0x0037, 8},
+ {0x2C73, 15}, {0x01DB, 9}, {0x59DD, 16}, {0x01C7, 9}, {0x692B, 15}, {0x01A6, 9}, {0x58E5, 16},
+ {0x00B4, 9}, {0x1F3D0, 17}, {0x00B0, 9}, {0xB1C9, 17}, {0x03E6, 10}, {0x16770, 18}, {0x016E, 10},
+ {0x3E7A2, 18}, {0x011B, 10}, {0xF9E8D, 20}, {0x00D9, 10}, {0xF9E8F, 20}, {0x00A8, 10}, {0x2C723, 19},
+ {0x0749, 11}, {0xE3084, 20}, {0x0696, 11}, {0x58E45, 20}, {0x02DE, 11}, {0xB1C88, 21}, {0x0231, 11},
+ {0x1C610A, 21}, {0x01B1, 11}, {0x71842D, 23}, {0x0D2B, 12}, {0x38C217, 22}, {0x0D2F, 12}, {0x163913, 22},
+ {0x05B2, 12}, {0x163912, 22}, {0x0469, 12}, {0x71842C, 23}, {0x1A42, 13}, {0x08C1, 13}, {0x0073, 7}}};
+
+const int ff_vc1_ac_sizes[AC_MODES] = {186, 169, 133, 149, 103, 103, 163, 175};
+
+} // namespace VC1
+static inline uint8 clipByte(int value) {
+ return CLIP(value, 0, 255);
+}
+
+static inline uint32 roundAvg32(uint32 a, uint32 b) {
+ return (a | b) - (((a ^ b) & ~0x01010101U) >> 1);
+}
+
+/* Apply overlap transform to horizontal edge */
+// Overlap and loop-filter DSP
+
+static void vc1_v_overlap_c(uint8 *src, ptrdiff_t stride) {
+ int i;
+ int a, b, c, d;
+ int d1, d2;
+ int rnd = 1;
+ for (i = 0; i < 8; i++) {
+ a = src[-2 * stride];
+ b = src[-stride];
+ c = src[0];
+ d = src[stride];
+ d1 = (a - d + 3 + rnd) >> 3;
+ d2 = (a - d + b - c + 4 - rnd) >> 3;
+
+ src[-2 * stride] = a - d1;
+ src[-stride] = clipByte(b - d2);
+ src[0] = clipByte(c + d2);
+ src[stride] = d + d1;
+ src++;
+ rnd = !rnd;
+ }
+}
+
+/* Apply overlap transform to vertical edge */
+static void vc1_h_overlap_c(uint8 *src, ptrdiff_t stride) {
+ int i;
+ int a, b, c, d;
+ int d1, d2;
+ int rnd = 1;
+ for (i = 0; i < 8; i++) {
+ a = src[-2];
+ b = src[-1];
+ c = src[0];
+ d = src[1];
+ d1 = (a - d + 3 + rnd) >> 3;
+ d2 = (a - d + b - c + 4 - rnd) >> 3;
+
+ src[-2] = a - d1;
+ src[-1] = clipByte(b - d2);
+ src[0] = clipByte(c + d2);
+ src[1] = d + d1;
+ src += stride;
+ rnd = !rnd;
+ }
+}
+
+static void vc1_v_s_overlap_c(int16 *top, int16 *bottom) {
+ int i;
+ int a, b, c, d;
+ int d1, d2;
+ int rnd1 = 4, rnd2 = 3;
+ for (i = 0; i < 8; i++) {
+ a = top[48];
+ b = top[56];
+ c = bottom[0];
+ d = bottom[8];
+ d1 = a - d;
+ d2 = a - d + b - c;
+
+ top[48] = ((a * 8) - d1 + rnd1) >> 3;
+ top[56] = ((b * 8) - d2 + rnd2) >> 3;
+ bottom[0] = ((c * 8) + d2 + rnd1) >> 3;
+ bottom[8] = ((d * 8) + d1 + rnd2) >> 3;
+
+ bottom++;
+ top++;
+ rnd2 = 7 - rnd2;
+ rnd1 = 7 - rnd1;
+ }
+}
+
+static void vc1_h_s_overlap_c(int16 *left, int16 *right, ptrdiff_t left_stride, ptrdiff_t right_stride, int flags) {
+ int i;
+ int a, b, c, d;
+ int d1, d2;
+ int rnd1 = flags & 2 ? 3 : 4;
+ int rnd2 = 7 - rnd1;
+ for (i = 0; i < 8; i++) {
+ a = left[6];
+ b = left[7];
+ c = right[0];
+ d = right[1];
+ d1 = a - d;
+ d2 = a - d + b - c;
+
+ left[6] = ((a * 8) - d1 + rnd1) >> 3;
+ left[7] = ((b * 8) - d2 + rnd2) >> 3;
+ right[0] = ((c * 8) + d2 + rnd1) >> 3;
+ right[1] = ((d * 8) + d1 + rnd2) >> 3;
+
+ right += right_stride;
+ left += left_stride;
+ if (flags & 1) {
+ rnd2 = 7 - rnd2;
+ rnd1 = 7 - rnd1;
+ }
+ }
+}
+
+/**
+ * VC-1 in-loop deblocking filter for one line
+ * @param src source block type
+ * @param stride block stride
+ * @param pq block quantizer
+ * @return whether other 3 pairs should be filtered or not
+ * @see 8.6
+ */
+static inline int vc1_filter_line(uint8 *src, ptrdiff_t stride, int pq) {
+ int a0 = (2 * (src[-2 * stride] - src[1 * stride]) - 5 * (src[-1 * stride] - src[0 * stride]) + 4) >> 3;
+ int a0_sign = a0 >> 31; /* Store sign */
+
+ a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = ABS(a0); */
+ if (a0 < pq) {
+ int a1 = ABS((2 * (src[-4 * stride] - src[-1 * stride]) - 5 * (src[-3 * stride] - src[-2 * stride]) + 4) >> 3);
+ int a2 = ABS((2 * (src[0 * stride] - src[3 * stride]) - 5 * (src[1 * stride] - src[2 * stride]) + 4) >> 3);
+ if (a1 < a0 || a2 < a0) {
+ int clip = src[-1 * stride] - src[0 * stride];
+ int clip_sign = clip >> 31;
+
+ clip = ((clip ^ clip_sign) - clip_sign) >> 1;
+ if (clip) {
+ int a3 = MIN(a1, a2);
+ int d = 5 * (a3 - a0);
+ int d_sign = (d >> 31);
+
+ d = ((d ^ d_sign) - d_sign) >> 3;
+ d_sign ^= a0_sign;
+
+ if (d_sign ^ clip_sign)
+ d = 0;
+ else {
+ d = MIN(d, clip);
+ d = (d ^ d_sign) - d_sign; /* Restore sign */
+ src[-1 * stride] = clipByte(src[-1 * stride] - d);
+ src[0 * stride] = clipByte(src[0 * stride] + d);
+ }
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * VC-1 in-loop deblocking filter
+ * @param src source block type
+ * @param step distance between horizontally adjacent elements
+ * @param stride distance between vertically adjacent elements
+ * @param len edge length to filter (4 or 8 pixels)
+ * @param pq block quantizer
+ * @see 8.6
+ */
+static inline void vc1_loop_filter(uint8 *src, ptrdiff_t step, ptrdiff_t stride, int len, int pq) {
+ int i;
+ int filt3;
+
+ for (i = 0; i < len; i += 4) {
+ filt3 = vc1_filter_line(src + 2 * step, stride, pq);
+ if (filt3) {
+ vc1_filter_line(src + 0 * step, stride, pq);
+ vc1_filter_line(src + 1 * step, stride, pq);
+ vc1_filter_line(src + 3 * step, stride, pq);
+ }
+ src += step * 4;
+ }
+}
+
+static void vc1_v_loop_filter4_c(uint8 *src, ptrdiff_t stride, int pq) {
+ vc1_loop_filter(src, 1, stride, 4, pq);
+}
+
+static void vc1_h_loop_filter4_c(uint8 *src, ptrdiff_t stride, int pq) {
+ vc1_loop_filter(src, stride, 1, 4, pq);
+}
+
+static void vc1_v_loop_filter8_c(uint8 *src, ptrdiff_t stride, int pq) {
+ vc1_loop_filter(src, 1, stride, 8, pq);
+}
+
+static void vc1_h_loop_filter8_c(uint8 *src, ptrdiff_t stride, int pq) {
+ vc1_loop_filter(src, stride, 1, 8, pq);
+}
+
+static void vc1_v_loop_filter16_c(uint8 *src, ptrdiff_t stride, int pq) {
+ vc1_loop_filter(src, 1, stride, 16, pq);
+}
+
+static void vc1_h_loop_filter16_c(uint8 *src, ptrdiff_t stride, int pq) {
+ vc1_loop_filter(src, stride, 1, 16, pq);
+}
+
+/* Do inverse transform on 8x8 block */
+// Inverse-transform DSP
+
+static void vc1_inv_trans_8x8_dc_c(uint8 *dest, ptrdiff_t stride, int16 *block) {
+ int i;
+ int dc = block[0];
+
+ dc = (3 * dc + 1) >> 1;
+ dc = (3 * dc + 16) >> 5;
+
+ for (i = 0; i < 8; i++) {
+ dest[0] = clipByte(dest[0] + dc);
+ dest[1] = clipByte(dest[1] + dc);
+ dest[2] = clipByte(dest[2] + dc);
+ dest[3] = clipByte(dest[3] + dc);
+ dest[4] = clipByte(dest[4] + dc);
+ dest[5] = clipByte(dest[5] + dc);
+ dest[6] = clipByte(dest[6] + dc);
+ dest[7] = clipByte(dest[7] + dc);
+ dest += stride;
+ }
+}
+
+static void vc1_inv_trans_8x8_c(int16 block[64]) {
+ int i;
+ int t1, t2, t3, t4, t5, t6, t7, t8;
+ int16 *src, *dst, temp[64];
+
+ src = block;
+ dst = temp;
+ for (i = 0; i < 8; i++) {
+ t1 = 12 * (src[0] + src[32]) + 4;
+ t2 = 12 * (src[0] - src[32]) + 4;
+ t3 = 16 * src[16] + 6 * src[48];
+ t4 = 6 * src[16] - 16 * src[48];
+
+ t5 = t1 + t3;
+ t6 = t2 + t4;
+ t7 = t2 - t4;
+ t8 = t1 - t3;
+
+ t1 = 16 * src[8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
+ t2 = 15 * src[8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
+ t3 = 9 * src[8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
+ t4 = 4 * src[8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
+
+ dst[0] = (t5 + t1) >> 3;
+ dst[1] = (t6 + t2) >> 3;
+ dst[2] = (t7 + t3) >> 3;
+ dst[3] = (t8 + t4) >> 3;
+ dst[4] = (t8 - t4) >> 3;
+ dst[5] = (t7 - t3) >> 3;
+ dst[6] = (t6 - t2) >> 3;
+ dst[7] = (t5 - t1) >> 3;
+
+ src += 1;
+ dst += 8;
+ }
+
+ src = temp;
+ dst = block;
+ for (i = 0; i < 8; i++) {
+ t1 = 12 * (src[0] + src[32]) + 64;
+ t2 = 12 * (src[0] - src[32]) + 64;
+ t3 = 16 * src[16] + 6 * src[48];
+ t4 = 6 * src[16] - 16 * src[48];
+
+ t5 = t1 + t3;
+ t6 = t2 + t4;
+ t7 = t2 - t4;
+ t8 = t1 - t3;
+
+ t1 = 16 * src[8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
+ t2 = 15 * src[8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
+ t3 = 9 * src[8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
+ t4 = 4 * src[8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
+
+ dst[0] = (t5 + t1) >> 7;
+ dst[8] = (t6 + t2) >> 7;
+ dst[16] = (t7 + t3) >> 7;
+ dst[24] = (t8 + t4) >> 7;
+ dst[32] = (t8 - t4 + 1) >> 7;
+ dst[40] = (t7 - t3 + 1) >> 7;
+ dst[48] = (t6 - t2 + 1) >> 7;
+ dst[56] = (t5 - t1 + 1) >> 7;
+
+ src++;
+ dst++;
+ }
+}
+
+/* Do inverse transform on 8x4 part of block */
+static void vc1_inv_trans_8x4_dc_c(uint8 *dest, ptrdiff_t stride, int16 *block) {
+ int i;
+ int dc = block[0];
+
+ dc = (3 * dc + 1) >> 1;
+ dc = (17 * dc + 64) >> 7;
+
+ for (i = 0; i < 4; i++) {
+ dest[0] = clipByte(dest[0] + dc);
+ dest[1] = clipByte(dest[1] + dc);
+ dest[2] = clipByte(dest[2] + dc);
+ dest[3] = clipByte(dest[3] + dc);
+ dest[4] = clipByte(dest[4] + dc);
+ dest[5] = clipByte(dest[5] + dc);
+ dest[6] = clipByte(dest[6] + dc);
+ dest[7] = clipByte(dest[7] + dc);
+ dest += stride;
+ }
+}
+
+static void vc1_inv_trans_8x4_c(uint8 *dest, ptrdiff_t stride, int16 *block) {
+ int i;
+ int t1, t2, t3, t4, t5, t6, t7, t8;
+ int16 *src, *dst;
+
+ src = block;
+ dst = block;
+
+ for (i = 0; i < 4; i++) {
+ t1 = 12 * (src[0] + src[4]) + 4;
+ t2 = 12 * (src[0] - src[4]) + 4;
+ t3 = 16 * src[2] + 6 * src[6];
+ t4 = 6 * src[2] - 16 * src[6];
+
+ t5 = t1 + t3;
+ t6 = t2 + t4;
+ t7 = t2 - t4;
+ t8 = t1 - t3;
+
+ t1 = 16 * src[1] + 15 * src[3] + 9 * src[5] + 4 * src[7];
+ t2 = 15 * src[1] - 4 * src[3] - 16 * src[5] - 9 * src[7];
+ t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7];
+ t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7];
+
+ dst[0] = (t5 + t1) >> 3;
+ dst[1] = (t6 + t2) >> 3;
+ dst[2] = (t7 + t3) >> 3;
+ dst[3] = (t8 + t4) >> 3;
+ dst[4] = (t8 - t4) >> 3;
+ dst[5] = (t7 - t3) >> 3;
+ dst[6] = (t6 - t2) >> 3;
+ dst[7] = (t5 - t1) >> 3;
+
+ src += 8;
+ dst += 8;
+ }
+
+ src = block;
+ for (i = 0; i < 8; i++) {
+ t1 = 17 * (src[0] + src[16]) + 64;
+ t2 = 17 * (src[0] - src[16]) + 64;
+ t3 = 22 * src[8] + 10 * src[24];
+ t4 = 22 * src[24] - 10 * src[8];
+
+ dest[0 * stride] = clipByte(dest[0 * stride] + ((t1 + t3) >> 7));
+ dest[1 * stride] = clipByte(dest[1 * stride] + ((t2 - t4) >> 7));
+ dest[2 * stride] = clipByte(dest[2 * stride] + ((t2 + t4) >> 7));
+ dest[3 * stride] = clipByte(dest[3 * stride] + ((t1 - t3) >> 7));
+
+ src++;
+ dest++;
+ }
+}
+
+/* Do inverse transform on 4x8 parts of block */
+static void vc1_inv_trans_4x8_dc_c(uint8 *dest, ptrdiff_t stride, int16 *block) {
+ int i;
+ int dc = block[0];
+
+ dc = (17 * dc + 4) >> 3;
+ dc = (12 * dc + 64) >> 7;
+
+ for (i = 0; i < 8; i++) {
+ dest[0] = clipByte(dest[0] + dc);
+ dest[1] = clipByte(dest[1] + dc);
+ dest[2] = clipByte(dest[2] + dc);
+ dest[3] = clipByte(dest[3] + dc);
+ dest += stride;
+ }
+}
+
+static void vc1_inv_trans_4x8_c(uint8 *dest, ptrdiff_t stride, int16 *block) {
+ int i;
+ int t1, t2, t3, t4, t5, t6, t7, t8;
+ int16 *src, *dst;
+
+ src = block;
+ dst = block;
+
+ for (i = 0; i < 8; i++) {
+ t1 = 17 * (src[0] + src[2]) + 4;
+ t2 = 17 * (src[0] - src[2]) + 4;
+ t3 = 22 * src[1] + 10 * src[3];
+ t4 = 22 * src[3] - 10 * src[1];
+
+ dst[0] = (t1 + t3) >> 3;
+ dst[1] = (t2 - t4) >> 3;
+ dst[2] = (t2 + t4) >> 3;
+ dst[3] = (t1 - t3) >> 3;
+
+ src += 8;
+ dst += 8;
+ }
+
+ src = block;
+ for (i = 0; i < 4; i++) {
+ t1 = 12 * (src[0] + src[32]) + 64;
+ t2 = 12 * (src[0] - src[32]) + 64;
+ t3 = 16 * src[16] + 6 * src[48];
+ t4 = 6 * src[16] - 16 * src[48];
+
+ t5 = t1 + t3;
+ t6 = t2 + t4;
+ t7 = t2 - t4;
+ t8 = t1 - t3;
+
+ t1 = 16 * src[8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
+ t2 = 15 * src[8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
+ t3 = 9 * src[8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
+ t4 = 4 * src[8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
+
+ dest[0 * stride] = clipByte(dest[0 * stride] + ((t5 + t1) >> 7));
+ dest[1 * stride] = clipByte(dest[1 * stride] + ((t6 + t2) >> 7));
+ dest[2 * stride] = clipByte(dest[2 * stride] + ((t7 + t3) >> 7));
+ dest[3 * stride] = clipByte(dest[3 * stride] + ((t8 + t4) >> 7));
+ dest[4 * stride] = clipByte(dest[4 * stride] + ((t8 - t4 + 1) >> 7));
+ dest[5 * stride] = clipByte(dest[5 * stride] + ((t7 - t3 + 1) >> 7));
+ dest[6 * stride] = clipByte(dest[6 * stride] + ((t6 - t2 + 1) >> 7));
+ dest[7 * stride] = clipByte(dest[7 * stride] + ((t5 - t1 + 1) >> 7));
+
+ src++;
+ dest++;
+ }
+}
+
+/* Do inverse transform on 4x4 part of block */
+static void vc1_inv_trans_4x4_dc_c(uint8 *dest, ptrdiff_t stride, int16 *block) {
+ int i;
+ int dc = block[0];
+
+ dc = (17 * dc + 4) >> 3;
+ dc = (17 * dc + 64) >> 7;
+
+ for (i = 0; i < 4; i++) {
+ dest[0] = clipByte(dest[0] + dc);
+ dest[1] = clipByte(dest[1] + dc);
+ dest[2] = clipByte(dest[2] + dc);
+ dest[3] = clipByte(dest[3] + dc);
+ dest += stride;
+ }
+}
+
+static void vc1_inv_trans_4x4_c(uint8 *dest, ptrdiff_t stride, int16 *block) {
+ int i;
+ int t1, t2, t3, t4;
+ int16 *src, *dst;
+
+ src = block;
+ dst = block;
+ for (i = 0; i < 4; i++) {
+ t1 = 17 * (src[0] + src[2]) + 4;
+ t2 = 17 * (src[0] - src[2]) + 4;
+ t3 = 22 * src[1] + 10 * src[3];
+ t4 = 22 * src[3] - 10 * src[1];
+
+ dst[0] = (t1 + t3) >> 3;
+ dst[1] = (t2 - t4) >> 3;
+ dst[2] = (t2 + t4) >> 3;
+ dst[3] = (t1 - t3) >> 3;
+
+ src += 8;
+ dst += 8;
+ }
+
+ src = block;
+ for (i = 0; i < 4; i++) {
+ t1 = 17 * (src[0] + src[16]) + 64;
+ t2 = 17 * (src[0] - src[16]) + 64;
+ t3 = 22 * src[8] + 10 * src[24];
+ t4 = 22 * src[24] - 10 * src[8];
+
+ dest[0 * stride] = clipByte(dest[0 * stride] + ((t1 + t3) >> 7));
+ dest[1 * stride] = clipByte(dest[1 * stride] + ((t2 - t4) >> 7));
+ dest[2 * stride] = clipByte(dest[2 * stride] + ((t2 + t4) >> 7));
+ dest[3 * stride] = clipByte(dest[3 * stride] + ((t1 - t3) >> 7));
+
+ src++;
+ dest++;
+ }
+}
+
+/* motion compensation functions */
+
+/* Filter in case of 2 filters */
+#define VC1_MSPEL_FILTER_16B(DIR, TYPE) \
+ static inline int vc1_mspel_##DIR##_filter_16bits(const TYPE *src, ptrdiff_t stride, int mode) { \
+ switch (mode) { \
+ case 0: /* no shift - should not occur */ \
+ return 0; \
+ case 1: /* 1/4 shift */ \
+ return -4 * src[-stride] + 53 * src[0] + 18 * src[stride] - 3 * src[stride * 2]; \
+ case 2: /* 1/2 shift */ \
+ return -1 * src[-stride] + 9 * src[0] + 9 * src[stride] - 1 * src[stride * 2]; \
+ case 3: /* 3/4 shift */ \
+ return -3 * src[-stride] + 18 * src[0] + 53 * src[stride] - 4 * src[stride * 2]; \
+ } \
+ return 0; /* should not occur */ \
+ }
+
+VC1_MSPEL_FILTER_16B(ver, uint8)
+VC1_MSPEL_FILTER_16B(hor, int16)
+
+/* Filter used to interpolate fractional pel values */
+static inline int vc1_mspel_filter(const uint8 *src, ptrdiff_t stride, int mode, int r) {
+ switch (mode) {
+ case 0: // no shift
+ return src[0];
+ case 1: // 1/4 shift
+ return (-4 * src[-stride] + 53 * src[0] + 18 * src[stride] - 3 * src[stride * 2] + 32 - r) >> 6;
+ case 2: // 1/2 shift
+ return (-1 * src[-stride] + 9 * src[0] + 9 * src[stride] - 1 * src[stride * 2] + 8 - r) >> 4;
+ case 3: // 3/4 shift
+ return (-3 * src[-stride] + 18 * src[0] + 53 * src[stride] - 4 * src[stride * 2] + 32 - r) >> 6;
+ }
+ return 0; // should not occur
+}
+
+/* Function used to do motion compensation with bicubic interpolation */
+#define VC1_MSPEL_MC(OP, OP4, OPNAME) \
+ static inline void OPNAME##vc1_mspel_mc(uint8 *dst, const uint8 *src, ptrdiff_t stride, int hmode, int vmode, \
+ int rnd) { \
+ int i, j; \
+ \
+ if (vmode) { /* Horizontal filter to apply */ \
+ int r; \
+ \
+ if (hmode) { /* Vertical filter to apply, output to tmp */ \
+ static const int shift_value[] = {0, 5, 1, 5}; \
+ int shift = (shift_value[hmode] + shift_value[vmode]) >> 1; \
+ int16 tmp[11 * 8], *tptr = tmp; \
+ \
+ r = (1 << (shift - 1)) + rnd - 1; \
+ \
+ src -= 1; \
+ for (j = 0; j < 8; j++) { \
+ for (i = 0; i < 11; i++) \
+ tptr[i] = (vc1_mspel_ver_filter_16bits(src + i, stride, vmode) + r) >> shift; \
+ src += stride; \
+ tptr += 11; \
+ } \
+ \
+ r = 64 - rnd; \
+ tptr = tmp + 1; \
+ for (j = 0; j < 8; j++) { \
+ for (i = 0; i < 8; i++) \
+ OP(dst[i], (vc1_mspel_hor_filter_16bits(tptr + i, 1, hmode) + r) >> 7); \
+ dst += stride; \
+ tptr += 11; \
+ } \
+ \
+ return; \
+ } else { /* No horizontal filter, output 8 lines to dst */ \
+ r = 1 - rnd; \
+ \
+ for (j = 0; j < 8; j++) { \
+ for (i = 0; i < 8; i++) \
+ OP(dst[i], vc1_mspel_filter(src + i, stride, vmode, r)); \
+ src += stride; \
+ dst += stride; \
+ } \
+ return; \
+ } \
+ } \
+ \
+ /* Horizontal mode with no vertical mode */ \
+ for (j = 0; j < 8; j++) { \
+ for (i = 0; i < 8; i++) \
+ OP(dst[i], vc1_mspel_filter(src + i, 1, hmode, rnd)); \
+ dst += stride; \
+ src += stride; \
+ } \
+ } \
+ static inline void OPNAME##vc1_mspel_mc_16(uint8 *dst, const uint8 *src, ptrdiff_t stride, int hmode, int vmode, \
+ int rnd) { \
+ int i, j; \
+ \
+ if (vmode) { /* Horizontal filter to apply */ \
+ int r; \
+ \
+ if (hmode) { /* Vertical filter to apply, output to tmp */ \
+ static const int shift_value[] = {0, 5, 1, 5}; \
+ int shift = (shift_value[hmode] + shift_value[vmode]) >> 1; \
+ int16 tmp[19 * 16], *tptr = tmp; \
+ \
+ r = (1 << (shift - 1)) + rnd - 1; \
+ \
+ src -= 1; \
+ for (j = 0; j < 16; j++) { \
+ for (i = 0; i < 19; i++) \
+ tptr[i] = (vc1_mspel_ver_filter_16bits(src + i, stride, vmode) + r) >> shift; \
+ src += stride; \
+ tptr += 19; \
+ } \
+ \
+ r = 64 - rnd; \
+ tptr = tmp + 1; \
+ for (j = 0; j < 16; j++) { \
+ for (i = 0; i < 16; i++) \
+ OP(dst[i], (vc1_mspel_hor_filter_16bits(tptr + i, 1, hmode) + r) >> 7); \
+ dst += stride; \
+ tptr += 19; \
+ } \
+ \
+ return; \
+ } else { /* No horizontal filter, output 8 lines to dst */ \
+ r = 1 - rnd; \
+ \
+ for (j = 0; j < 16; j++) { \
+ for (i = 0; i < 16; i++) \
+ OP(dst[i], vc1_mspel_filter(src + i, stride, vmode, r)); \
+ src += stride; \
+ dst += stride; \
+ } \
+ return; \
+ } \
+ } \
+ \
+ /* Horizontal mode with no vertical mode */ \
+ for (j = 0; j < 16; j++) { \
+ for (i = 0; i < 16; i++) \
+ OP(dst[i], vc1_mspel_filter(src + i, 1, hmode, rnd)); \
+ dst += stride; \
+ src += stride; \
+ } \
+ } \
+ static void OPNAME##pixels8x8_c(uint8 *block, const uint8 *pixels, ptrdiff_t line_size, int rnd) { \
+ int i; \
+ for (i = 0; i < 8; i++) { \
+ OP4(block, READ_UINT32(pixels)); \
+ OP4(block + 4, READ_UINT32(pixels + 4)); \
+ pixels += line_size; \
+ block += line_size; \
+ } \
+ } \
+ static void OPNAME##pixels16x16_c(uint8 *block, const uint8 *pixels, ptrdiff_t line_size, int rnd) { \
+ int i; \
+ for (i = 0; i < 16; i++) { \
+ OP4(block, READ_UINT32(pixels)); \
+ OP4(block + 4, READ_UINT32(pixels + 4)); \
+ OP4(block + 8, READ_UINT32(pixels + 8)); \
+ OP4(block + 12, READ_UINT32(pixels + 12)); \
+ pixels += line_size; \
+ block += line_size; \
+ } \
+ }
+
+#define op_put(a, b) (a) = clipByte(b)
+#define op_avg(a, b) (a) = ((a) + clipByte(b) + 1) >> 1
+#define op4_avg(a, b) WRITE_UINT32(a, roundAvg32(READ_UINT32(a), b))
+#define op4_put(a, b) WRITE_UINT32(a, b)
+
+VC1_MSPEL_MC(op_put, op4_put, put_)
+VC1_MSPEL_MC(op_avg, op4_avg, avg_)
+
+/* pixel functions - really are entry points to vc1_mspel_mc */
+
+#define PUT_VC1_MSPEL(a, b) \
+ static void put_vc1_mspel_mc##a##b##_c(uint8 *dst, const uint8 *src, ptrdiff_t stride, int rnd) { \
+ put_vc1_mspel_mc(dst, src, stride, a, b, rnd); \
+ } \
+ static void avg_vc1_mspel_mc##a##b##_c(uint8 *dst, const uint8 *src, ptrdiff_t stride, int rnd) { \
+ avg_vc1_mspel_mc(dst, src, stride, a, b, rnd); \
+ } \
+ static void put_vc1_mspel_mc##a##b##_16_c(uint8 *dst, const uint8 *src, ptrdiff_t stride, int rnd) { \
+ put_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \
+ } \
+ static void avg_vc1_mspel_mc##a##b##_16_c(uint8 *dst, const uint8 *src, ptrdiff_t stride, int rnd) { \
+ avg_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \
+ }
+
+PUT_VC1_MSPEL(1, 0)
+PUT_VC1_MSPEL(2, 0)
+PUT_VC1_MSPEL(3, 0)
+
+PUT_VC1_MSPEL(0, 1)
+PUT_VC1_MSPEL(1, 1)
+PUT_VC1_MSPEL(2, 1)
+PUT_VC1_MSPEL(3, 1)
+
+PUT_VC1_MSPEL(0, 2)
+PUT_VC1_MSPEL(1, 2)
+PUT_VC1_MSPEL(2, 2)
+PUT_VC1_MSPEL(3, 2)
+
+PUT_VC1_MSPEL(0, 3)
+PUT_VC1_MSPEL(1, 3)
+PUT_VC1_MSPEL(2, 3)
+PUT_VC1_MSPEL(3, 3)
+
+#define chroma_mc(a) ((A * src[a] + B * src[a + 1] + C * src[stride + a] + D * src[stride + a + 1] + 32 - 4) >> 6)
+static void put_no_rnd_vc1_chroma_mc8_c(uint8 *dst /* align 8 */, const uint8 *src /* align 1 */, ptrdiff_t stride,
+ int h, int x, int y) {
+ const int A = (8 - x) * (8 - y);
+ const int B = (x) * (8 - y);
+ const int C = (8 - x) * (y);
+ const int D = (x) * (y);
+ int i;
+
+ assert(x < 8 && y < 8 && x >= 0 && y >= 0);
+
+ for (i = 0; i < h; i++) {
+ dst[0] = chroma_mc(0);
+ dst[1] = chroma_mc(1);
+ dst[2] = chroma_mc(2);
+ dst[3] = chroma_mc(3);
+ dst[4] = chroma_mc(4);
+ dst[5] = chroma_mc(5);
+ dst[6] = chroma_mc(6);
+ dst[7] = chroma_mc(7);
+ dst += stride;
+ src += stride;
+ }
+}
+
+static void put_no_rnd_vc1_chroma_mc4_c(uint8 *dst, const uint8 *src, ptrdiff_t stride, int h, int x, int y) {
+ const int A = (8 - x) * (8 - y);
+ const int B = (x) * (8 - y);
+ const int C = (8 - x) * (y);
+ const int D = (x) * (y);
+ int i;
+
+ assert(x < 8 && y < 8 && x >= 0 && y >= 0);
+
+ for (i = 0; i < h; i++) {
+ dst[0] = chroma_mc(0);
+ dst[1] = chroma_mc(1);
+ dst[2] = chroma_mc(2);
+ dst[3] = chroma_mc(3);
+ dst += stride;
+ src += stride;
+ }
+}
+
+#define avg2(a, b) (((a) + (b) + 1) >> 1)
+static void avg_no_rnd_vc1_chroma_mc8_c(uint8 *dst /* align 8 */, const uint8 *src /* align 1 */, ptrdiff_t stride,
+ int h, int x, int y) {
+ const int A = (8 - x) * (8 - y);
+ const int B = (x) * (8 - y);
+ const int C = (8 - x) * (y);
+ const int D = (x) * (y);
+ int i;
+
+ assert(x < 8 && y < 8 && x >= 0 && y >= 0);
+
+ for (i = 0; i < h; i++) {
+ dst[0] = avg2(dst[0], chroma_mc(0));
+ dst[1] = avg2(dst[1], chroma_mc(1));
+ dst[2] = avg2(dst[2], chroma_mc(2));
+ dst[3] = avg2(dst[3], chroma_mc(3));
+ dst[4] = avg2(dst[4], chroma_mc(4));
+ dst[5] = avg2(dst[5], chroma_mc(5));
+ dst[6] = avg2(dst[6], chroma_mc(6));
+ dst[7] = avg2(dst[7], chroma_mc(7));
+ dst += stride;
+ src += stride;
+ }
+}
+
+static void avg_no_rnd_vc1_chroma_mc4_c(uint8 *dst /* align 8 */, const uint8 *src /* align 1 */, ptrdiff_t stride,
+ int h, int x, int y) {
+ const int A = (8 - x) * (8 - y);
+ const int B = (x) * (8 - y);
+ const int C = (8 - x) * (y);
+ const int D = (x) * (y);
+ int i;
+
+ assert(x < 8 && y < 8 && x >= 0 && y >= 0);
+
+ for (i = 0; i < h; i++) {
+ dst[0] = avg2(dst[0], chroma_mc(0));
+ dst[1] = avg2(dst[1], chroma_mc(1));
+ dst[2] = avg2(dst[2], chroma_mc(2));
+ dst[3] = avg2(dst[3], chroma_mc(3));
+ dst += stride;
+ src += stride;
+ }
+}
+
+#define FN_ASSIGN(X, Y) \
+ dsp->put_vc1_mspel_pixels_tab[1][X + 4 * Y] = put_vc1_mspel_mc##X##Y##_c; \
+ dsp->put_vc1_mspel_pixels_tab[0][X + 4 * Y] = put_vc1_mspel_mc##X##Y##_16_c; \
+ dsp->avg_vc1_mspel_pixels_tab[1][X + 4 * Y] = avg_vc1_mspel_mc##X##Y##_c; \
+ dsp->avg_vc1_mspel_pixels_tab[0][X + 4 * Y] = avg_vc1_mspel_mc##X##Y##_16_c
+
+void initWMV3DSP(WMV3DSP *dsp) {
+ *dsp = WMV3DSP();
+ dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;
+ dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c;
+ dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_c;
+ dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c;
+ dsp->vc1_inv_trans_8x8_dc = vc1_inv_trans_8x8_dc_c;
+ dsp->vc1_inv_trans_4x8_dc = vc1_inv_trans_4x8_dc_c;
+ dsp->vc1_inv_trans_8x4_dc = vc1_inv_trans_8x4_dc_c;
+ dsp->vc1_inv_trans_4x4_dc = vc1_inv_trans_4x4_dc_c;
+
+ dsp->vc1_h_overlap = vc1_h_overlap_c;
+ dsp->vc1_v_overlap = vc1_v_overlap_c;
+ dsp->vc1_h_s_overlap = vc1_h_s_overlap_c;
+ dsp->vc1_v_s_overlap = vc1_v_s_overlap_c;
+
+ dsp->vc1_v_loop_filter4 = vc1_v_loop_filter4_c;
+ dsp->vc1_h_loop_filter4 = vc1_h_loop_filter4_c;
+ dsp->vc1_v_loop_filter8 = vc1_v_loop_filter8_c;
+ dsp->vc1_h_loop_filter8 = vc1_h_loop_filter8_c;
+ dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_c;
+ dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_c;
+
+ dsp->put_vc1_mspel_pixels_tab[0][0] = put_pixels16x16_c;
+ dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_pixels16x16_c;
+ dsp->put_vc1_mspel_pixels_tab[1][0] = put_pixels8x8_c;
+ dsp->avg_vc1_mspel_pixels_tab[1][0] = avg_pixels8x8_c;
+ FN_ASSIGN(0, 1);
+ FN_ASSIGN(0, 2);
+ FN_ASSIGN(0, 3);
+
+ FN_ASSIGN(1, 0);
+ FN_ASSIGN(1, 1);
+ FN_ASSIGN(1, 2);
+ FN_ASSIGN(1, 3);
+
+ FN_ASSIGN(2, 0);
+ FN_ASSIGN(2, 1);
+ FN_ASSIGN(2, 2);
+ FN_ASSIGN(2, 3);
+
+ FN_ASSIGN(3, 0);
+ FN_ASSIGN(3, 1);
+ FN_ASSIGN(3, 2);
+ FN_ASSIGN(3, 3);
+
+ 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;
+ dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = put_no_rnd_vc1_chroma_mc4_c;
+ dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = avg_no_rnd_vc1_chroma_mc4_c;
+}
+
+#undef FN_ASSIGN
+#undef PUT_VC1_MSPEL
+#undef VC1_MSPEL_FILTER_16B
+#undef VC1_MSPEL_MC
+#undef avg2
+#undef chroma_mc
+#undef op4_avg
+#undef op4_put
+#undef op_avg
+#undef op_put
+
+enum { PROFILE_SIMPLE, PROFILE_MAIN, PROFILE_COMPLEX, PROFILE_ADVANCED };
+
+static int setDimensions(VC1Header *v, int width, int height) {
+ if (width <= 0 || height <= 0) {
+ v->width = v->height = 0;
+ return -1;
+ }
+ v->width = width;
+ v->height = height;
+ return 0;
+}
+
+static void validateAspect(VC1Header *v) {
+ const VC1Ratio &sar = v->sample_aspect_ratio;
+ bool valid = sar.den > 0 && sar.num >= 0;
+ if (valid && sar.num && sar.num != sar.den) {
+ int64 scaled = sar.num < sar.den ? (int64)v->width * sar.num / sar.den : (int64)v->height * sar.den / sar.num;
+ valid = scaled > 0;
+ }
+ if (!valid)
+ v->sample_aspect_ratio = VC1Ratio();
+}
+
+static void reduceAspect(VC1Ratio &aspect, int num, int den) {
+ if (den <= 0) {
+ aspect = VC1Ratio();
+ return;
+ }
+ Common::Rational ratio(num, den);
+ aspect.num = ratio.getNumerator();
+ aspect.den = ratio.getDenominator();
+}
+
+static const uint8 ff_wmv2_scantableA[64] = {
+ 0x00, 0x01, 0x02, 0x08, 0x03, 0x09, 0x0A, 0x10, 0x04, 0x0B, 0x11, 0x18, 0x12, 0x0C, 0x05, 0x13,
+ 0x19, 0x0D, 0x14, 0x1A, 0x1B, 0x06, 0x15, 0x1C, 0x0E, 0x16, 0x1D, 0x07, 0x1E, 0x0F, 0x17, 0x1F,
+};
+
+static const uint8 ff_wmv2_scantableB[64] = {
+ 0x00, 0x08, 0x01, 0x10, 0x09, 0x18, 0x11, 0x02, 0x20, 0x0A, 0x19, 0x28, 0x12, 0x30, 0x21, 0x1A,
+ 0x38, 0x29, 0x22, 0x03, 0x31, 0x39, 0x0B, 0x2A, 0x13, 0x32, 0x1B, 0x3A, 0x23, 0x2B, 0x33, 0x3B,
+};
+
+static const uint8 ff_vc1_adv_progressive_8x4_zz[32] = {/* Table 233 */
+ 0, 8, 1, 16, 2, 9, 10, 3, 24, 17, 4, 11, 18, 12, 5, 19,
+ 25, 13, 20, 26, 27, 6, 21, 28, 14, 22, 29, 7, 30, 15, 23, 31};
+
+static const uint8 ff_vc1_adv_progressive_4x8_zz[32] = {/* Table 234 */
+ 0, 1, 8, 2, 9, 16, 17, 24, 10, 32, 25, 18, 40, 3, 33, 26,
+ 48, 11, 56, 41, 34, 49, 57, 42, 19, 50, 27, 58, 35, 43, 51, 59};
+
+static const VC1Ratio ff_vc1_pixel_aspect[16] = {{0, 1}, {1, 1}, {12, 11}, {10, 11}, {16, 11}, {40, 33},
+ {24, 11}, {20, 11}, {32, 11}, {80, 33}, {18, 11}, {15, 11},
+ {64, 33}, {160, 99}, {0, 1}, {0, 1}};
+
+static const int ff_vc1_fps_nr[7] = {24, 25, 30, 50, 60, 48, 72};
+static const int ff_vc1_fps_dr[2] = {1000, 1001};
+
+static int readVC1Advanced(VC1Header *v, Common::BitStream8MSB *gb);
+
+/**
+ * Decode Simple/Main Profiles sequence header
+ * @see Figure 7-8, p16-17
+ * @param v Parsed codec state
+ * @param gb Bit stream containing the codec sequence header
+ * @return Status
+ */
+// Sequence and entry-point headers
+
+int readVC1Sequence(VC1Header *v, Common::BitStream8MSB *gb) {
+
+ v->profile = gb->getBits(2);
+ if (v->profile == PROFILE_COMPLEX) {
+ warning("WMV3 Complex Profile is not fully supported\n");
+ }
+
+ if (v->profile == PROFILE_ADVANCED) {
+ v->zz_8x4 = ff_vc1_adv_progressive_8x4_zz;
+ v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz;
+ return readVC1Advanced(v, gb);
+ } else {
+ v->chromaformat = 1;
+ v->zz_8x4 = ff_wmv2_scantableA;
+ v->zz_4x8 = ff_wmv2_scantableB;
+ v->res_y411 = gb->getBit();
+ v->res_sprite = gb->getBit();
+ if (v->res_y411) {
+ warning("Old interlaced mode is not supported\n");
+ return -1;
+ }
+ }
+
+ // (fps-2)/4 (->30)
+ v->frmrtq_postproc = gb->getBits(3); // common
+ // (bitrate-32kbps)/64kbps
+ v->bitrtq_postproc = gb->getBits(5); // common
+ v->loop_filter = gb->getBit(); // common
+ if (v->loop_filter == 1 && v->profile == PROFILE_SIMPLE) {
+ warning("LOOPFILTER shall not be enabled in Simple Profile\n");
+ }
+
+ v->res_x8 = gb->getBit(); // reserved
+ v->multires = gb->getBit();
+ v->res_fasttx = gb->getBit();
+
+ v->fastuvmc = gb->getBit(); // common
+ if (!v->profile && !v->fastuvmc) {
+ warning("FASTUVMC unavailable in Simple Profile\n");
+ return -1;
+ }
+ v->extended_mv = gb->getBit(); // common
+ if (!v->profile && v->extended_mv) {
+ warning("Extended MVs unavailable in Simple Profile\n");
+ return -1;
+ }
+ v->dquant = gb->getBits(2); // common
+ v->vstransform = gb->getBit(); // common
+
+ v->res_transtab = gb->getBit();
+ if (v->res_transtab) {
+ warning("1 for reserved RES_TRANSTAB is forbidden\n");
+ return -1;
+ }
+
+ v->overlap = gb->getBit(); // common
+
+ v->resync_marker = gb->getBit();
+ v->rangered = gb->getBit();
+ if (v->rangered && v->profile == PROFILE_SIMPLE) {
+ warning("RANGERED should be set to 0 in Simple Profile\n");
+ }
+
+ v->max_b_frames = gb->getBits(3); // common
+ v->quantizer_mode = gb->getBits(2); // common
+
+ v->finterpflag = gb->getBit(); // common
+
+ if (v->res_sprite) {
+ int w = gb->getBits(11);
+ int h = gb->getBits(11);
+ int ret = setDimensions(v, w, h);
+ if (ret < 0) {
+ warning("Failed to set dimensions %d %d\n", w, h);
+ return ret;
+ }
+ gb->skip(5); // frame rate
+ v->res_x8 = gb->getBit();
+ if (gb->getBit()) { // something to do with DC VLC selection
+ warning("Unsupported sprite feature\n");
+ return -1;
+ }
+ gb->skip(3); // slice code
+ v->res_rtm_flag = 0;
+ } else {
+ v->res_rtm_flag = gb->getBit(); // reserved
+ }
+ // TODO: figure out what they mean (always 0x402F)
+ if (gb->pos() > gb->size())
+ return -1;
+ if (!v->res_fasttx)
+ gb->skip(16);
+ return 0;
+}
+
+static int readVC1Advanced(VC1Header *v, Common::BitStream8MSB *gb) {
+ v->res_rtm_flag = 1;
+ v->level = gb->getBits(3);
+ if (v->level >= 5) {
+ warning("Reserved LEVEL %i\n", v->level);
+ }
+ v->chromaformat = gb->getBits(2);
+ if (v->chromaformat != 1) {
+ warning("Only 4:2:0 chroma format supported\n");
+ return -1;
+ }
+
+ // (fps-2)/4 (->30)
+ v->frmrtq_postproc = gb->getBits(3); // common
+ // (bitrate-32kbps)/64kbps
+ v->bitrtq_postproc = gb->getBits(5); // common
+ v->postprocflag = gb->getBit(); // common
+
+ v->max_coded_width = (gb->getBits(12) + 1) << 1;
+ v->max_coded_height = (gb->getBits(12) + 1) << 1;
+ v->broadcast = gb->getBit();
+ v->interlace = gb->getBit();
+ v->tfcntrflag = gb->getBit();
+ v->finterpflag = gb->getBit();
+ gb->skip(1); // reserved
+
+ v->psf = gb->getBit();
+ if (v->psf) { // PsF, 6.1.13
+ warning("Progressive Segmented Frame mode: not supported (yet)\n");
+ return -1;
+ }
+ v->max_b_frames = 7;
+ if (gb->getBit()) { // Display Info - decoding is not affected by it
+ int w, h, ar = 0;
+
+ w = gb->getBits(14) + 1;
+ h = gb->getBits(14) + 1;
+
+ if (gb->getBit())
+ ar = gb->getBits(4);
+ if (ar && ar < 14) {
+ v->sample_aspect_ratio = ff_vc1_pixel_aspect[ar];
+ } else if (ar == 15) {
+ w = gb->getBits(8) + 1;
+ h = gb->getBits(8) + 1;
+ v->sample_aspect_ratio = VC1Ratio(w, h);
+ } else {
+ if (v->width > v->max_coded_width || v->height > v->max_coded_height) {
+ warning("VC-1: Huge resolution");
+ } else
+ reduceAspect(v->sample_aspect_ratio, v->height * w, v->width * h);
+ }
+
+ validateAspect(v);
+
+ if (gb->getBit()) { // framerate stuff
+ if (gb->getBit()) {
+ v->framerate.den = 32;
+ v->framerate.num = gb->getBits(16) + 1;
+ } else {
+ int nr, dr;
+ nr = gb->getBits(8);
+ dr = gb->getBits(4);
+ if (nr > 0 && nr < 8 && dr > 0 && dr < 3) {
+ v->framerate.den = ff_vc1_fps_dr[dr - 1];
+ v->framerate.num = ff_vc1_fps_nr[nr - 1] * 1000;
+ }
+ }
+ }
+
+ if (gb->getBit()) {
+ v->color_prim = gb->getBits(8);
+ v->transfer_char = gb->getBits(8);
+ v->matrix_coef = gb->getBits(8);
+ }
+ }
+
+ v->hrd_param_flag = gb->getBit();
+ if (v->hrd_param_flag) {
+ int i;
+ v->hrd_num_leaky_buckets = gb->getBits(5);
+ gb->skip(4); // bitrate exponent
+ gb->skip(4); // buffer size exponent
+ for (i = 0; i < v->hrd_num_leaky_buckets; i++) {
+ gb->skip(16); // hrd_rate[n]
+ gb->skip(16); // hrd_buffer[n]
+ }
+ }
+ return gb->pos() <= gb->size() ? 0 : -1;
+}
+
+int readVC1Entry(VC1Header *v, Common::BitStream8MSB *gb) {
+ int i;
+ int w, h;
+ int ret;
+
+ v->broken_link = gb->getBit();
+ v->closed_entry = gb->getBit();
+ v->panscanflag = gb->getBit();
+ v->refdist_flag = gb->getBit();
+ v->loop_filter = gb->getBit();
+ v->fastuvmc = gb->getBit();
+ v->extended_mv = gb->getBit();
+ v->dquant = gb->getBits(2);
+ v->vstransform = gb->getBit();
+ v->overlap = gb->getBit();
+ v->quantizer_mode = gb->getBits(2);
+
+ if (v->hrd_param_flag) {
+ for (i = 0; i < v->hrd_num_leaky_buckets; i++) {
+ gb->skip(8); // hrd_full[n]
+ }
+ }
+
+ if (gb->getBit()) {
+ w = (gb->getBits(12) + 1) << 1;
+ h = (gb->getBits(12) + 1) << 1;
+ } else {
+ w = v->max_coded_width;
+ h = v->max_coded_height;
+ }
+ if ((ret = setDimensions(v, w, h)) < 0) {
+ warning("Failed to set dimensions %d %d\n", w, h);
+ return ret;
+ }
+
+ if (v->extended_mv)
+ v->extended_dmv = gb->getBit();
+ if ((v->range_mapy_flag = gb->getBit())) {
+ warning("Luma scaling is not supported, expect wrong picture\n");
+ v->range_mapy = gb->getBits(3);
+ }
+ if ((v->range_mapuv_flag = gb->getBit())) {
+ warning("Chroma scaling is not supported, expect wrong picture\n");
+ v->range_mapuv = gb->getBits(3);
+ }
+
+ return gb->pos() <= gb->size() ? 0 : -1;
+}
+
+enum { IMODE_RAW, IMODE_NORM2, IMODE_DIFF2, IMODE_NORM6, IMODE_DIFF6, IMODE_ROWSKIP, IMODE_COLSKIP };
+
+/* BitPlane IMODE - such a small table... */
+static const uint32 vc1_imode_codes[7] = {0, 2, 1, 3, 1, 2, 3};
+static const uint8 vc1_imode_bits[7] = {4, 2, 3, 2, 4, 3, 3};
+
+/* Normal-2 imode */
+static const uint32 vc1_norm2_codes[4] = {0, 4, 5, 3};
+static const uint8 vc1_norm2_bits[4] = {1, 3, 3, 2};
+
+static const uint32 vc1_norm6_codes[64] = {
+ 0x001, 0x002, 0x003, 0x000, 0x004, 0x001, 0x002, 0x047, 0x005, 0x003, 0x004, 0x04B, 0x005, 0x04D, 0x04E, 0x30E,
+ 0x006, 0x006, 0x007, 0x053, 0x008, 0x055, 0x056, 0x30D, 0x009, 0x059, 0x05A, 0x30C, 0x05C, 0x30B, 0x30A, 0x037,
+ 0x007, 0x00A, 0x00B, 0x043, 0x00C, 0x045, 0x046, 0x309, 0x00D, 0x049, 0x04A, 0x308, 0x04C, 0x307, 0x306, 0x036,
+ 0x00E, 0x051, 0x052, 0x305, 0x054, 0x304, 0x303, 0x035, 0x058, 0x302, 0x301, 0x034, 0x300, 0x033, 0x032, 0x007,
+};
+
+static const uint8 vc1_norm6_bits[64] = {
+ 1, 4, 4, 8, 4, 8, 8, 10, 4, 8, 8, 10, 8, 10, 10, 13, 4, 8, 8, 10, 8, 10,
+ 10, 13, 8, 10, 10, 13, 10, 13, 13, 9, 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13,
+ 10, 13, 13, 9, 8, 10, 10, 13, 10, 13, 13, 9, 10, 13, 13, 9, 13, 9, 9, 6,
+};
+
+static void initCodes(uint16 *table, uint maxBits, const uint32 *codes, const uint8 *lengths, uint count) {
+ for (uint i = 0; i < (1U << maxBits); ++i)
+ table[i] = 0xffff;
+ for (uint i = 0; i < count; ++i) {
+ uint shift = maxBits - lengths[i];
+ uint start = codes[i] << shift;
+ for (uint j = 0; j < (1U << shift); ++j)
+ table[start + j] = (i << 4) | lengths[i];
+ }
+}
+
+static int readCode(Common::BitStream8MSB &bits, const uint16 *table, uint maxBits) {
+ uint16 entry = table[bits.peekBits(maxBits)];
+ if (entry == 0xffff)
+ return -1;
+ bits.skip(entry & 15);
+ if (bits.pos() > bits.size())
+ return -1;
+ return entry >> 4;
+}
+
+// Bitplane decoding
+
+VC1Bitplane::VC1Bitplane() {
+ initCodes(_imode, 4, vc1_imode_codes, vc1_imode_bits, 7);
+ initCodes(_norm2, 3, vc1_norm2_codes, vc1_norm2_bits, 4);
+ initCodes(_norm6, 13, vc1_norm6_codes, vc1_norm6_bits, 64);
+}
+
+static void decode_rowskip(uint8 *plane, int width, int height, int stride, Common::BitStream8MSB *gb) {
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ if (!gb->getBit()) // rowskip
+ memset(plane, 0, width);
+ else
+ for (x = 0; x < width; x++)
+ plane[x] = gb->getBit();
+ plane += stride;
+ }
+}
+
+/** Decode columns by checking if they are skipped
+ * @param plane Buffer to store decoded bits
+ * @param[in] width Width of this buffer
+ * @param[in] height Height of this buffer
+ * @param[in] stride of this buffer
+ * @todo FIXME: Optimize
+ */
+static void decode_colskip(uint8 *plane, int width, int height, int stride, Common::BitStream8MSB *gb) {
+ int x, y;
+
+ for (x = 0; x < width; x++) {
+ if (!gb->getBit()) // colskip
+ for (y = 0; y < height; y++)
+ plane[y * stride] = 0;
+ else
+ for (y = 0; y < height; y++)
+ plane[y * stride] = gb->getBit();
+ plane++;
+ }
+}
+
+/** Decode a bitplane's bits
+ * @param data bitplane where to store the decode bits
+ * @param[out] raw_flag pointer to the flag indicating that this bitplane is not coded explicitly
+ * @param gb Bit stream containing the coded bitplane
+ * @return Status
+ * @todo FIXME: Optimize
+ */
+int VC1Bitplane::decode(uint8 *data, int *raw_flag, int width, int height, int stride,
+ Common::BitStream8MSB *gb) const {
+ if (!data || !raw_flag || width <= 0 || height <= 0 || stride < width)
+ return -1;
+ int imode, x, y, code, offset;
+ uint8 invert, *planep = data;
+ invert = gb->getBit();
+ imode = readCode(*gb, _imode, 4);
+
+ if (imode < 0)
+ return -1;
+ *raw_flag = 0;
+ switch (imode) {
+ case IMODE_RAW:
+ // Data is actually read in the MB layer (same for all tests == "raw")
+ *raw_flag = 1; // invert ignored
+ return gb->pos() <= gb->size() ? invert : -1;
+ case IMODE_DIFF2:
+ case IMODE_NORM2:
+ if ((height * width) & 1) {
+ *planep++ = gb->getBit();
+ y = offset = 1;
+ if (offset == width) {
+ offset = 0;
+ planep += stride - width;
+ }
+ } else
+ y = offset = 0;
+ // decode bitplane as one long line
+ for (; y < height * width; y += 2) {
+ code = readCode(*gb, _norm2, 3);
+ if (code < 0)
+ return -1;
+ *planep++ = code & 1;
+ offset++;
+ if (offset == width) {
+ offset = 0;
+ planep += stride - width;
+ }
+ *planep++ = code >> 1;
+ offset++;
+ if (offset == width) {
+ offset = 0;
+ planep += stride - width;
+ }
+ }
+ break;
+ case IMODE_DIFF6:
+ case IMODE_NORM6:
+ if (!(height % 3) && (width % 3)) { // use 2x3 decoding
+ for (y = 0; y < height; y += 3) {
+ for (x = width & 1; x < width; x += 2) {
+ code = readCode(*gb, _norm6, 13);
+ if (code < 0) {
+ return -1;
+ }
+ planep[x + 0] = (code >> 0) & 1;
+ planep[x + 1] = (code >> 1) & 1;
+ planep[x + 0 + stride] = (code >> 2) & 1;
+ planep[x + 1 + stride] = (code >> 3) & 1;
+ planep[x + 0 + stride * 2] = (code >> 4) & 1;
+ planep[x + 1 + stride * 2] = (code >> 5) & 1;
+ }
+ planep += stride * 3;
+ }
+ if (width & 1)
+ decode_colskip(data, 1, height, stride, gb);
+ } else { // 3x2
+ planep += (height & 1) * stride;
+ for (y = height & 1; y < height; y += 2) {
+ for (x = width % 3; x < width; x += 3) {
+ code = readCode(*gb, _norm6, 13);
+ if (code < 0) {
+ return -1;
+ }
+ planep[x + 0] = (code >> 0) & 1;
+ planep[x + 1] = (code >> 1) & 1;
+ planep[x + 2] = (code >> 2) & 1;
+ planep[x + 0 + stride] = (code >> 3) & 1;
+ planep[x + 1 + stride] = (code >> 4) & 1;
+ planep[x + 2 + stride] = (code >> 5) & 1;
+ }
+ planep += stride * 2;
+ }
+ x = width % 3;
+ if (x)
+ decode_colskip(data, x, height, stride, gb);
+ if (height & 1)
+ decode_rowskip(data + x, width - x, 1, stride, gb);
+ }
+ break;
+ case IMODE_ROWSKIP:
+ decode_rowskip(data, width, height, stride, gb);
+ break;
+ case IMODE_COLSKIP:
+ decode_colskip(data, width, height, stride, gb);
+ break;
+ default:
+ break;
+ }
+
+ /* Applying diff operator */
+ if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6) {
+ planep = data;
+ planep[0] ^= invert;
+ for (x = 1; x < width; x++)
+ planep[x] ^= planep[x - 1];
+ for (y = 1; y < height; y++) {
+ planep += stride;
+ planep[0] ^= planep[-stride];
+ for (x = 1; x < width; x++) {
+ if (planep[x - 1] != planep[x - stride])
+ planep[x] ^= invert;
+ else
+ planep[x] ^= planep[x - 1];
+ }
+ }
+ } else if (invert) {
+ planep = data;
+ for (x = 0; x < stride * height; x++)
+ planep[x] = !planep[x]; // FIXME stride
+ }
+ return gb->pos() <= gb->size() ? (imode << 1) + invert : -1;
+}
+
+namespace VC1 {
+const VLC *ff_msmp4_mb_i_vlc;
+const VLC *ff_msmp4_dc_vlc[2][2];
+/** Table for conversion between TTBLK and TTMB */
+const int ff_vc1_ttblk_to_tt[3][8] = {
+ {TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT},
+ {TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP},
+ {TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP}};
+
+const int ff_vc1_ttfrm_to_tt[4] = {TT_8X8, TT_8X4, TT_4X8, TT_4X4};
+
+/** MV P mode - the 5th element is only used for mode 1 */
+const uint8 ff_vc1_mv_pmode_table[2][5] = {
+ {MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV},
+ {MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN}};
+const uint8 ff_vc1_mv_pmode_table2[2][4] = {
+ {MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV},
+ {MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN}};
+
+/* MBMODE table for interlaced frame P-picture */
+const uint8 ff_vc1_mbmode_intfrp[2][15][4] = {{/* 1: 4-MV, 0: non-4-MV */
+ /* Type, FIELDTX, 1-MV Differential present, Residuals (CBP) present */
+ /* Table 164 - Table 167 */
+ {MV_PMODE_INTFR_1MV, 0, 1, 1},
+ {MV_PMODE_INTFR_1MV, 1, 1, 1},
+ {MV_PMODE_INTFR_1MV, 0, 1, 0},
+ {MV_PMODE_INTFR_1MV, 0, 0, 1},
+ {MV_PMODE_INTFR_1MV, 1, 0, 1},
+ {MV_PMODE_INTFR_2MV_FIELD, 0, 0, 1},
+ {MV_PMODE_INTFR_2MV_FIELD, 1, 0, 1},
+ {MV_PMODE_INTFR_2MV_FIELD, 1, 0, 0},
+ {MV_PMODE_INTFR_INTRA, 0, 0, 0}},
+ {/* Table 160 - Table 163 */
+ {MV_PMODE_INTFR_1MV, 0, 1, 1},
+ {MV_PMODE_INTFR_1MV, 1, 1, 1},
+ {MV_PMODE_INTFR_1MV, 0, 1, 0},
+ {MV_PMODE_INTFR_1MV, 0, 0, 1},
+ {MV_PMODE_INTFR_1MV, 1, 0, 1},
+ {MV_PMODE_INTFR_2MV_FIELD, 0, 0, 1},
+ {MV_PMODE_INTFR_2MV_FIELD, 1, 0, 1},
+ {MV_PMODE_INTFR_2MV_FIELD, 1, 0, 0},
+ {MV_PMODE_INTFR_4MV, 0, 0, 1},
+ {MV_PMODE_INTFR_4MV, 1, 0, 1},
+ {MV_PMODE_INTFR_4MV, 0, 0, 0},
+ {MV_PMODE_INTFR_4MV_FIELD, 0, 0, 1},
+ {MV_PMODE_INTFR_4MV_FIELD, 1, 0, 1},
+ {MV_PMODE_INTFR_4MV_FIELD, 1, 0, 0},
+ {MV_PMODE_INTFR_INTRA, 0, 0, 0}}};
+
+const int ff_vc1_fps_nr[7] = {24, 25, 30, 50, 60, 48, 72}, ff_vc1_fps_dr[2] = {1000, 1001};
+const uint8 ff_vc1_pquant_table[3][32] = {
+ /* Implicit quantizer */
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31},
+ /* Explicit quantizer, pquantizer uniform */
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
+ /* Explicit quantizer, pquantizer non-uniform */
+ {0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31}};
+
+/** @name VC-1 VLC tables
+ * @todo TODO move this into the context
+ */
+//@{
+const VLC *ff_vc1_imode_vlc;
+const VLC *ff_vc1_norm2_vlc;
+const VLC *ff_vc1_norm6_vlc;
+const VLC *ff_vc1_ttmb_vlc[3];
+const VLC *ff_vc1_mv_diff_vlc[4];
+const VLC *ff_vc1_cbpcy_p_vlc[4];
+const VLC *ff_vc1_icbpcy_vlc[8];
+const VLC *ff_vc1_4mv_block_pattern_vlc[4];
+const VLC *ff_vc1_2mv_block_pattern_vlc[4];
+const VLC *ff_vc1_ttblk_vlc[3];
+const VLC *ff_vc1_subblkpat_vlc[3];
+const VLC *ff_vc1_intfr_4mv_mbmode_vlc[4];
+const VLC *ff_vc1_intfr_non4mv_mbmode_vlc[4];
+const VLC *ff_vc1_if_mmv_mbmode_vlc[8];
+const VLC *ff_vc1_if_1mv_mbmode_vlc[8];
+const VLC *ff_vc1_1ref_mvdata_vlc[4];
+const VLC *ff_vc1_2ref_mvdata_vlc[8];
+
+const VLC *ff_vc1_ac_coeff_table[8];
+
+//@}
+
+#if B_FRACTION_DEN == 840 // original bfraction from vc9data.h, not conforming to standard
+/* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */
+const int16 ff_vc1_bfraction_lut[23] = {
+ 420 /*1/2*/,
+ 280 /*1/3*/,
+ 560 /*2/3*/,
+ 210 /*1/4*/,
+ 630 /*3/4*/,
+ 168 /*1/5*/,
+ 336 /*2/5*/,
+ 504 /*3/5*/,
+ 672 /*4/5*/,
+ 140 /*1/6*/,
+ 700 /*5/6*/,
+ 120 /*1/7*/,
+ 240 /*2/7*/,
+ 360 /*3/7*/,
+ 480 /*4/7*/,
+ 600 /*5/7*/,
+ 720 /*6/7*/,
+ 105 /*1/8*/,
+ 315 /*3/8*/,
+ 525 /*5/8*/,
+ 735 /*7/8*/,
+ -1 /*inv.*/,
+ 0 /*BI fm*/
+};
+#else
+/* pre-computed scales for all bfractions and base=256 */
+const int16 ff_vc1_bfraction_lut[23] = {
+ 128 /*1/2*/,
+ 85 /*1/3*/,
+ 170 /*2/3*/,
+ 64 /*1/4*/,
+ 192 /*3/4*/,
+ 51 /*1/5*/,
+ 102 /*2/5*/,
+ 153 /*3/5*/,
+ 204 /*4/5*/,
+ 43 /*1/6*/,
+ 215 /*5/6*/,
+ 37 /*1/7*/,
+ 74 /*2/7*/,
+ 111 /*3/7*/,
+ 148 /*4/7*/,
+ 185 /*5/7*/,
+ 222 /*6/7*/,
+ 32 /*1/8*/,
+ 96 /*3/8*/,
+ 160 /*5/8*/,
+ 224 /*7/8*/,
+ -1 /*inv.*/,
+ 0 /*BI fm*/
+};
+#endif
+
+// Same as H.264
+const VC1Ratio ff_vc1_pixel_aspect[16] = {{0, 1}, {1, 1}, {12, 11}, {10, 11}, {16, 11}, {40, 33},
+ {24, 11}, {20, 11}, {32, 11}, {80, 33}, {18, 11}, {15, 11},
+ {64, 33}, {160, 99}, {0, 1}, {0, 1}};
+
+const uint8 ff_wmv3_dc_scale_table[32] = {0, 2, 4, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
+ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21};
+
+/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
+
+/* Table 232 */
+const uint8 ff_vc1_simple_progressive_4x4_zz[16] = {0, 8, 16, 1, 9, 24, 17, 2, 10, 18, 25, 3, 11, 26, 19, 27};
+
+const uint8 ff_vc1_adv_progressive_8x4_zz[32] = {/* Table 233 */
+ 0, 8, 1, 16, 2, 9, 10, 3, 24, 17, 4, 11, 18, 12, 5, 19,
+ 25, 13, 20, 26, 27, 6, 21, 28, 14, 22, 29, 7, 30, 15, 23, 31};
+
+const uint8 ff_vc1_adv_progressive_4x8_zz[32] = {/* Table 234 */
+ 0, 1, 8, 2, 9, 16, 17, 24, 10, 32, 25, 18, 40, 3, 33, 26,
+ 48, 11, 56, 41, 34, 49, 57, 42, 19, 50, 27, 58, 35, 43, 51, 59};
+
+const uint8 ff_vc1_adv_interlaced_8x8_zz[64] = {/* Table 235 */
+ 0, 8, 1, 16, 24, 9, 2, 32, 40, 48, 56, 17, 10, 3, 25, 18,
+ 11, 4, 33, 41, 49, 57, 26, 34, 42, 50, 58, 19, 12, 5, 27, 20,
+ 13, 6, 35, 28, 21, 14, 7, 15, 22, 29, 36, 43, 51, 59, 60, 52,
+ 44, 37, 30, 23, 31, 38, 45, 53, 61, 62, 54, 46, 39, 47, 55, 63};
+
+const uint8 ff_vc1_adv_interlaced_8x4_zz[32] = {/* Table 236 */
+ 0, 8, 16, 24, 1, 9, 2, 17, 25, 10, 3, 18, 26, 4, 11, 19,
+ 12, 5, 13, 20, 27, 6, 21, 28, 14, 22, 29, 7, 30, 15, 23, 31};
+
+const uint8 ff_vc1_adv_interlaced_4x8_zz[32] = {/* Table 237 */
+ 0, 1, 2, 8, 16, 9, 24, 17, 10, 3, 32, 40, 48, 56, 25, 18,
+ 33, 26, 41, 34, 49, 57, 11, 42, 19, 50, 27, 58, 35, 43, 51, 59};
+
+const uint8 ff_vc1_adv_interlaced_4x4_zz[16] = {/* Table 238 */
+ 0, 8, 16, 24, 1, 9, 17, 2, 25, 10, 18, 3, 26, 11, 19, 27};
+
+/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
+const int32 ff_vc1_dqscale[63] = {
+ 0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000, 0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5,
+ 0x4925, 0x4444, 0x4000, 0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB, 0x28F6, 0x2762,
+ 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000, 0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42,
+ 0x199A, 0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555, 0x14E6, 0x147B, 0x1414, 0x13B1,
+ 0x1352, 0x12F7, 0x129E, 0x1249, 0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1041};
+
+/* P Interlaced field picture MV predictor scaling values (Table 114) */
+const uint16 ff_vc1_field_mvpred_scales[2][7][4] = {
+ // Refdist:
+ // 0 1 2 3 or greater
+ {
+ // current field is first
+ {128, 192, 213, 224}, // SCALEOPP
+ {512, 341, 307, 293}, // SCALESAME1
+ {219, 236, 242, 245}, // SCALESAME2
+ {32, 48, 53, 56}, // SCALEZONE1_X
+ {8, 12, 13, 14}, // SCALEZONE1_Y
+ {37, 20, 14, 11}, // ZONE1OFFSET_X
+ {10, 5, 4, 3} // ZONE1OFFSET_Y
+ },
+ {
+ // current field is second
+ {128, 64, 43, 32}, // SCALEOPP
+ {512, 1024, 1536, 2048}, // SCALESAME1
+ {219, 204, 200, 198}, // SCALESAME2
+ {32, 16, 11, 8}, // SCALEZONE1_X
+ {8, 4, 3, 2}, // SCALEZONE1_Y
+ {37, 52, 56, 58}, // ZONE1OFFSET_X
+ {10, 13, 14, 15} // ZONE1OFFSET_Y
+ }};
+
+/* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */
+const uint16 ff_vc1_b_field_mvpred_scales[7][4] = {
+ // BRFD:
+ // 0 1 2 3 or greater
+ {171, 205, 219, 228}, // SCALESAME
+ {384, 320, 299, 288}, // SCALEOPP1
+ {230, 239, 244, 246}, // SCALEOPP2
+ {43, 51, 55, 57}, // SCALEZONE1_X
+ {11, 13, 14, 14}, // SCALEZONE1_Y
+ {26, 17, 12, 10}, // ZONE1OFFSET_X
+ {7, 4, 3, 3} // ZONE1OFFSET_Y
+};
+
+const uint8 ff_wmv1_scantable[WMV1_SCANTABLE_COUNT][64] = {
+ {
+ 0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, 0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28,
+ 0x30, 0x38, 0x29, 0x21, 0x1A, 0x13, 0x0C, 0x05, 0x06, 0x0D, 0x14, 0x1B, 0x22, 0x31, 0x39, 0x3A,
+ 0x32, 0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, 0x16, 0x1D, 0x24, 0x2B, 0x33, 0x3B, 0x3C, 0x34,
+ 0x2C, 0x25, 0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x35, 0x3D, 0x3E, 0x36, 0x2E, 0x27, 0x2F, 0x37, 0x3F,
+ },
+ {
+ 0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, 0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28,
+ 0x21, 0x30, 0x1A, 0x13, 0x0C, 0x05, 0x06, 0x0D, 0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, 0x2A,
+ 0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, 0x16, 0x1D, 0x24, 0x2B, 0x32, 0x3A, 0x33, 0x3B, 0x2C, 0x25,
+ 0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3C, 0x35, 0x3D, 0x2E, 0x27, 0x2F, 0x36, 0x3E, 0x37, 0x3F,
+ },
+ {
+ 0x00, 0x01, 0x08, 0x02, 0x03, 0x09, 0x10, 0x18, 0x11, 0x0A, 0x04, 0x05, 0x0B, 0x12, 0x19, 0x20,
+ 0x28, 0x30, 0x21, 0x1A, 0x13, 0x0C, 0x06, 0x07, 0x0D, 0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39,
+ 0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x0F, 0x16, 0x1D, 0x24, 0x2B, 0x32, 0x3A, 0x33, 0x2C, 0x25, 0x1E,
+ 0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x3C, 0x35, 0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F,
+ },
+ {
+ 0x00, 0x08, 0x10, 0x01, 0x18, 0x20, 0x28, 0x09, 0x02, 0x03, 0x0A, 0x11, 0x19, 0x30, 0x38, 0x29,
+ 0x21, 0x1A, 0x12, 0x0B, 0x04, 0x05, 0x0C, 0x13, 0x1B, 0x22, 0x31, 0x39, 0x32, 0x2A, 0x23, 0x1C,
+ 0x14, 0x0D, 0x06, 0x07, 0x0E, 0x15, 0x1D, 0x24, 0x2B, 0x33, 0x3A, 0x3B, 0x34, 0x2C, 0x25, 0x1E,
+ 0x16, 0x0F, 0x17, 0x1F, 0x26, 0x2D, 0x3C, 0x35, 0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F,
+ }};
+
+// VLC table initialization
+
+void initTables() {
+
+ ff_vc1_norm2_vlc = makeVLC(4, vc1_norm2_bits, 1, 1, vc1_norm2_codes, 1, 1);
+ ff_vc1_norm6_vlc = makeVLC(64, vc1_norm6_bits, 1, 1, vc1_norm6_codes, 2, 2);
+ ff_vc1_imode_vlc = makeVLC(7, vc1_imode_bits, 1, 1, vc1_imode_codes, 1, 1);
+ for (int i = 0; i < 3; i++) {
+ ff_vc1_ttmb_vlc[i] = makeVLC(16, vc1_ttmb_bits[i], 1, 1, vc1_ttmb_codes[i], 2, 2);
+ ff_vc1_ttblk_vlc[i] = makeVLC(8, vc1_ttblk_bits[i], 1, 1, vc1_ttblk_codes[i], 1, 1);
+ ff_vc1_subblkpat_vlc[i] = makeVLC(15, vc1_subblkpat_bits[i], 1, 1, vc1_subblkpat_codes[i], 1, 1);
+ }
+ for (int i = 0; i < 4; i++) {
+ ff_vc1_4mv_block_pattern_vlc[i] =
+ makeVLC(16, vc1_4mv_block_pattern_bits[i], 1, 1, vc1_4mv_block_pattern_codes[i], 1, 1);
+ ff_vc1_cbpcy_p_vlc[i] = makeVLC(64, vc1_cbpcy_p_bits[i], 1, 1, vc1_cbpcy_p_codes[i], 2, 2);
+ ff_vc1_mv_diff_vlc[i] = makeVLC(73, vc1_mv_diff_bits[i], 1, 1, vc1_mv_diff_codes[i], 2, 2);
+ /* initialize 4MV MBMODE VLC tables for interlaced frame P picture */
+ ff_vc1_intfr_4mv_mbmode_vlc[i] =
+ makeVLC(15, vc1_intfr_4mv_mbmode_bits[i], 1, 1, vc1_intfr_4mv_mbmode_codes[i], 2, 2);
+ /* initialize NON-4MV MBMODE VLC tables for the same */
+ ff_vc1_intfr_non4mv_mbmode_vlc[i] =
+ makeVLC(9, vc1_intfr_non4mv_mbmode_bits[i], 1, 1, vc1_intfr_non4mv_mbmode_codes[i], 1, 1);
+ /* initialize interlaced MVDATA tables (1-Ref) */
+ ff_vc1_1ref_mvdata_vlc[i] = makeVLC(72, vc1_1ref_mvdata_bits[i], 1, 1, vc1_1ref_mvdata_codes[i], 4, 4);
+ /* Initialize 2MV Block pattern VLC tables */
+ ff_vc1_2mv_block_pattern_vlc[i] =
+ makeVLC(4, vc1_2mv_block_pattern_bits[i], 1, 1, vc1_2mv_block_pattern_codes[i], 1, 1);
+ }
+ for (int i = 0; i < 8; i++) {
+ ff_vc1_ac_coeff_table[i] =
+ makeVLC(ff_vc1_ac_sizes[i], &vc1_ac_tables[i][0][1], 8, 4, &vc1_ac_tables[i][0][0], 8, 4);
+ /* initialize interlaced MVDATA tables (2-Ref) */
+ ff_vc1_2ref_mvdata_vlc[i] = makeVLC(126, vc1_2ref_mvdata_bits[i], 1, 1, vc1_2ref_mvdata_codes[i], 4, 4);
+ /* Initialize interlaced CBPCY VLC tables (Table 124 - Table 131) */
+ ff_vc1_icbpcy_vlc[i] = makeVLC(63, vc1_icbpcy_p_bits[i], 1, 1, vc1_icbpcy_p_codes[i], 2, 2);
+ /* Initialize interlaced field picture MBMODE VLC tables */
+ ff_vc1_if_mmv_mbmode_vlc[i] = makeVLC(8, vc1_if_mmv_mbmode_bits[i], 1, 1, vc1_if_mmv_mbmode_codes[i], 1, 1);
+ ff_vc1_if_1mv_mbmode_vlc[i] = makeVLC(6, vc1_if_1mv_mbmode_bits[i], 1, 1, vc1_if_1mv_mbmode_codes[i], 1, 1);
+ }
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ ff_msmp4_dc_vlc[i][j] =
+ makeVLC(120, &ff_msmp4_dc_tables[i][j][0][1], 8, 4, &ff_msmp4_dc_tables[i][j][0][0], 8, 4);
+ ff_msmp4_mb_i_vlc = makeVLC(64, &ff_msmp4_mb_i_table[0][1], 4, 2, &ff_msmp4_mb_i_table[0][0], 4, 2);
+}
+
+// Scalar reconstruction helpers
+
+static uint32 tableValue(const void *p, int size) {
+ if (size == 1)
+ return *(const uint8 *)p;
+ if (size == 2)
+ return READ_UINT16(p);
+ return READ_UINT32(p);
+}
+
+const VLC *makeVLC(int count, const void *lengths, int ls, int lz, const void *codes, int cs, int cz) {
+ VLC *v = new VLC;
+ v->nodes.push_back(VLC::Node());
+ for (int i = 0; i < count; ++i) {
+ int length = tableValue((const uint8 *)lengths + i * ls, lz);
+ if (!length)
+ continue;
+ uint32 code = tableValue((const uint8 *)codes + i * cs, cz);
+ int at = 0;
+ for (int k = length - 1; k >= 0; --k) {
+ int bit = (code >> k) & 1;
+ int next = v->nodes[at].child[bit];
+ if (next < 0) {
+ next = v->nodes.size();
+ v->nodes[at].child[bit] = next;
+ v->nodes.push_back(VLC::Node());
+ }
+ at = next;
+ }
+ assert(v->nodes[at].symbol == -1);
+ v->nodes[at].symbol = i;
+ }
+ return v;
+}
+
+int get_vlc2(Bits *b, const VLC *v) {
+ int at = 0;
+ if (!v)
+ return -1;
+ for (int k = 0; k < 32; ++k) {
+ if (v->nodes[at].symbol >= 0)
+ return v->nodes[at].symbol;
+ if (get_bits_left(b) <= 0)
+ return -1;
+ at = v->nodes[at].child[get_bits1(b)];
+ if (at < 0)
+ return -1;
+ }
+ return -1;
+}
+
+static void clearBlock(int16 *p) {
+ memset(p, 0, 64 * sizeof(*p));
+}
+static void clearBlocks(int16 *p) {
+ memset(p, 0, 6 * 64 * sizeof(*p));
+}
+template<int mode> static void clampBlock(const int16 *b, uint8 *d, ptrdiff_t stride) {
+ for (int y = 0; y < 8; ++y) {
+ for (int x = 0; x < 8; ++x)
+ d[x] = av_clip_uint8(b[y * 8 + x] + (mode == 1 ? 128 : mode == 2 ? d[x] : 0));
+ d += stride;
+ }
+}
+
+template<int width, int xy, bool round, bool average>
+static void halfPixels(uint8 *d, const uint8 *s, ptrdiff_t stride, int h) {
+ putHalfPixels<width>(d, s, stride, h, xy, !round, average);
+}
+
+template<int width, bool average>
+static void chromaPixels(uint8 *d, const uint8 *s, ptrdiff_t stride, int h, int x, int y) {
+ int a = (8 - x) * (8 - y), b = x * (8 - y), c = (8 - x) * y, e = x * y;
+ for (int row = 0; row < h; ++row) {
+ for (int col = 0; col < width; ++col) {
+ int value = (a * s[col] + b * s[col + 1] + c * s[col + stride] + e * s[col + stride + 1] + 32) >> 6;
+ d[col] = average ? (d[col] + value + 1) >> 1 : value;
+ }
+ d += stride;
+ s += stride;
+ }
+}
+
+static void edgePixels(uint8 *dst, const uint8 *src, ptrdiff_t ds, ptrdiff_t ss, int bw, int bh, int x, int y, int w,
+ int h) {
+ for (int row = 0; row < bh; ++row) {
+ int sy = CLIP(y + row, 0, h - 1) - y;
+ for (int col = 0; col < bw; ++col)
+ dst[col] = src[sy * ss + CLIP(x + col, 0, w - 1) - x];
+ dst += ds;
+ }
+}
+
+void initSupport(PictureState *s, ChromaDSP *c) {
+ s->bdsp.clear_block = clearBlock;
+ s->bdsp.clear_blocks = clearBlocks;
+ s->idsp.put_pixels_clamped = clampBlock<0>;
+ s->idsp.put_signed_pixels_clamped = clampBlock<1>;
+ s->idsp.add_pixels_clamped = clampBlock<2>;
+ s->vdsp.emulated_edge_mc = edgePixels;
+#define H(w, i, xy) \
+ s->hdsp.put_pixels_tab[i][xy] = halfPixels<w, xy, true, false>; \
+ s->hdsp.put_no_rnd_pixels_tab[i][xy] = halfPixels<w, xy, false, false>; \
+ s->hdsp.avg_pixels_tab[i][xy] = halfPixels<w, xy, true, true>;
+ H(16, 0, 0)
+ H(16, 0, 1)
+ H(16, 0, 2)
+ H(16, 0, 3)
+ H(8, 1, 0)
+ H(8, 1, 1)
+ H(8, 1, 2)
+ H(8, 1, 3)
+#undef H
+ s->hdsp.avg_no_rnd_pixels_tab[0] = halfPixels<16, 0, false, true>;
+ s->hdsp.avg_no_rnd_pixels_tab[1] = halfPixels<16, 1, false, true>;
+ s->hdsp.avg_no_rnd_pixels_tab[2] = halfPixels<16, 2, false, true>;
+ s->hdsp.avg_no_rnd_pixels_tab[3] = halfPixels<16, 3, false, true>;
+ c->put_h264_chroma_pixels_tab[0] = chromaPixels<8, false>;
+ c->put_h264_chroma_pixels_tab[1] = chromaPixels<4, false>;
+ c->put_h264_chroma_pixels_tab[2] = chromaPixels<2, false>;
+ c->avg_h264_chroma_pixels_tab[0] = chromaPixels<8, true>;
+ c->avg_h264_chroma_pixels_tab[1] = chromaPixels<4, true>;
+ c->avg_h264_chroma_pixels_tab[2] = chromaPixels<2, true>;
+}
+
+void ff_init_block_index(PictureState *s) {
+ const int linesize = s->cur_pic.linesize[0], uvlinesize = s->cur_pic.linesize[1];
+ s->block_index[0] = s->b8_stride * (s->mb_y * 2) - 2 + s->mb_x * 2;
+ s->block_index[1] = s->b8_stride * (s->mb_y * 2) - 1 + s->mb_x * 2;
+ s->block_index[2] = s->b8_stride * (s->mb_y * 2 + 1) - 2 + s->mb_x * 2;
+ s->block_index[3] = s->b8_stride * (s->mb_y * 2 + 1) - 1 + s->mb_x * 2;
+ s->block_index[4] = s->mb_stride * (s->mb_y + 1) + s->b8_stride * s->mb_height * 2 + s->mb_x - 1;
+ s->block_index[5] = s->mb_stride * (s->mb_y + s->mb_height + 2) + s->b8_stride * s->mb_height * 2 + s->mb_x - 1;
+ s->dest[0] = s->cur_pic.data[0] + (s->mb_x - 1) * 16 + s->mb_y * linesize * 16;
+ s->dest[1] = s->cur_pic.data[1] + (s->mb_x - 1) * 8 + s->mb_y * uvlinesize * 8;
+ s->dest[2] = s->cur_pic.data[2] + (s->mb_x - 1) * 8 + s->mb_y * uvlinesize * 8;
+}
+
+void ff_update_block_index(PictureState *s, int, int, int) {
+ for (int i = 0; i < 4; ++i)
+ s->block_index[i] += 2;
+ ++s->block_index[4];
+ ++s->block_index[5];
+ s->dest[0] += 16;
+ s->dest[1] += 8;
+ s->dest[2] += 8;
+}
+
+/**
+ * @file
+ * simpleidct in C.
+ */
+/* Based upon some commented-out C code from mpeg2dec (idct_mmx.c
+ * written by Aaron Holtzman <aholtzma at ess.engr.uvic.ca>). */
+static inline void idctRowCondDC_int16_8bit(int16 *row, int extra_shift) {
+ unsigned a0, a1, a2, a3, b0, b1, b2, b3;
+ // TODO: Add DC-only support for int32 input
+ if (!(READ_UINT32(row + 2) | READ_UINT32(row + 4) | READ_UINT32(row + 6) | row[1])) {
+ uint32 temp;
+ if (3 - extra_shift >= 0) {
+ temp = (row[0] * (1 << (3 - extra_shift))) & 0xffff;
+ } else {
+ temp = ((row[0] + (1 << (extra_shift - 3 - 1))) >> (extra_shift - 3)) & 0xffff;
+ }
+ temp += temp * (1 << 16);
+ WRITE_UINT32(row, temp);
+ WRITE_UINT32(row + 2, temp);
+ WRITE_UINT32(row + 4, temp);
+ WRITE_UINT32(row + 6, temp);
+ return;
+ }
+ a0 = ((unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[0]) + (1 << (11 + extra_shift - 1));
+ a1 = a0;
+ a2 = a0;
+ a3 = a0;
+ a0 += (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[2];
+ a1 += (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[2];
+ a2 -= (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[2];
+ a3 -= (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[2];
+ b0 = ((22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[1]));
+ ((b0) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[3]));
+ b1 = ((19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[1]));
+ ((b1) += (-4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[3]));
+ b2 = ((12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[1]));
+ ((b2) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[3]));
+ b3 = ((4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[1]));
+ ((b3) += (-12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[3]));
+ if (READ_UINT64(row + 4)) {
+ a0 += (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[4] +
+ (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[6];
+ a1 += (unsigned)-16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[4] -
+ (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[6];
+ a2 += (unsigned)-16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[4] +
+ (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[6];
+ a3 += (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[4] -
+ (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * row[6];
+ ((b0) += (12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[5]));
+ ((b0) += (4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[7]));
+ ((b1) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[5]));
+ ((b1) += (-12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[7]));
+ ((b2) += (4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[5]));
+ ((b2) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[7]));
+ ((b3) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[5]));
+ ((b3) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (row[7]));
+ }
+ row[0] = (int)(a0 + b0) >> (11 + extra_shift);
+ row[7] = (int)(a0 - b0) >> (11 + extra_shift);
+ row[1] = (int)(a1 + b1) >> (11 + extra_shift);
+ row[6] = (int)(a1 - b1) >> (11 + extra_shift);
+ row[2] = (int)(a2 + b2) >> (11 + extra_shift);
+ row[5] = (int)(a2 - b2) >> (11 + extra_shift);
+ row[3] = (int)(a3 + b3) >> (11 + extra_shift);
+ row[4] = (int)(a3 - b3) >> (11 + extra_shift);
+}
+
+static inline void idctSparseCol_int16_8bit(int16 *col) {
+ unsigned a0, a1, a2, a3, b0, b1, b2, b3;
+ do {
+ a0 = (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ *
+ (col[8 * 0] + ((1 << (20 - 1)) / 16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/));
+ a1 = a0;
+ a2 = a0;
+ a3 = a0;
+ a0 += (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a1 += (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a2 += (unsigned)-8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a3 += (unsigned)-21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ b0 = ((22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b1 = ((19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b2 = ((12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b3 = ((4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ ((b0) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b1) += (-4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b2) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b3) += (-12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ if (col[8 * 4]) {
+ a0 += (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a1 += (unsigned)-16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a2 += (unsigned)-16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a3 += (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ }
+ if (col[8 * 5]) {
+ ((b0) += (12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b1) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b2) += (4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b3) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ }
+ if (col[8 * 6]) {
+ a0 += (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a1 += (unsigned)-21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a2 += (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a3 += (unsigned)-8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ }
+ if (col[8 * 7]) {
+ ((b0) += (4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b1) += (-12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b2) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b3) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ }
+ } while (0);
+ col[0] = ((int)(a0 + b0) >> 20);
+ col[8] = ((int)(a1 + b1) >> 20);
+ col[16] = ((int)(a2 + b2) >> 20);
+ col[24] = ((int)(a3 + b3) >> 20);
+ col[32] = ((int)(a3 - b3) >> 20);
+ col[40] = ((int)(a2 - b2) >> 20);
+ col[48] = ((int)(a1 - b1) >> 20);
+ col[56] = ((int)(a0 - b0) >> 20);
+}
+
+static inline void idctSparseColPut_int16_8bit(uint8 *dest, ptrdiff_t line_size, int16 *col) {
+ unsigned a0, a1, a2, a3, b0, b1, b2, b3;
+ do {
+ a0 = (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ *
+ (col[8 * 0] + ((1 << (20 - 1)) / 16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/));
+ a1 = a0;
+ a2 = a0;
+ a3 = a0;
+ a0 += (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a1 += (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a2 += (unsigned)-8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a3 += (unsigned)-21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ b0 = ((22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b1 = ((19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b2 = ((12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b3 = ((4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ ((b0) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b1) += (-4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b2) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b3) += (-12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ if (col[8 * 4]) {
+ a0 += (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a1 += (unsigned)-16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a2 += (unsigned)-16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a3 += (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ }
+ if (col[8 * 5]) {
+ ((b0) += (12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b1) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b2) += (4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b3) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ }
+ if (col[8 * 6]) {
+ a0 += (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a1 += (unsigned)-21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a2 += (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a3 += (unsigned)-8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ }
+ if (col[8 * 7]) {
+ ((b0) += (4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b1) += (-12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b2) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b3) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ }
+ } while (0);
+ dest[0] = av_clip_uint8((int)(a0 + b0) >> 20);
+ dest += line_size;
+ dest[0] = av_clip_uint8((int)(a1 + b1) >> 20);
+ dest += line_size;
+ dest[0] = av_clip_uint8((int)(a2 + b2) >> 20);
+ dest += line_size;
+ dest[0] = av_clip_uint8((int)(a3 + b3) >> 20);
+ dest += line_size;
+ dest[0] = av_clip_uint8((int)(a3 - b3) >> 20);
+ dest += line_size;
+ dest[0] = av_clip_uint8((int)(a2 - b2) >> 20);
+ dest += line_size;
+ dest[0] = av_clip_uint8((int)(a1 - b1) >> 20);
+ dest += line_size;
+ dest[0] = av_clip_uint8((int)(a0 - b0) >> 20);
+}
+
+static inline void idctSparseColAdd_int16_8bit(uint8 *dest, ptrdiff_t line_size, int16 *col) {
+ unsigned a0, a1, a2, a3, b0, b1, b2, b3;
+ do {
+ a0 = (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ *
+ (col[8 * 0] + ((1 << (20 - 1)) / 16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/));
+ a1 = a0;
+ a2 = a0;
+ a3 = a0;
+ a0 += (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a1 += (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a2 += (unsigned)-8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ a3 += (unsigned)-21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 2];
+ b0 = ((22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b1 = ((19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b2 = ((12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ b3 = ((4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 1]));
+ ((b0) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b1) += (-4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b2) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ ((b3) += (-12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 3]));
+ if (col[8 * 4]) {
+ a0 += (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a1 += (unsigned)-16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a2 += (unsigned)-16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ a3 += (unsigned)16383 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 4];
+ }
+ if (col[8 * 5]) {
+ ((b0) += (12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b1) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b2) += (4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ ((b3) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 5]));
+ }
+ if (col[8 * 6]) {
+ a0 += (unsigned)8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a1 += (unsigned)-21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a2 += (unsigned)21407 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ a3 += (unsigned)-8867 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/ * col[8 * 6];
+ }
+ if (col[8 * 7]) {
+ ((b0) += (4520 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b1) += (-12873 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b2) += (19266 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ ((b3) += (-22725 /*cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5*/) * (col[8 * 7]));
+ }
+ } while (0);
+ dest[0] = av_clip_uint8(dest[0] + ((int)(a0 + b0) >> 20));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((int)(a1 + b1) >> 20));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((int)(a2 + b2) >> 20));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((int)(a3 + b3) >> 20));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((int)(a3 - b3) >> 20));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((int)(a2 - b2) >> 20));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((int)(a1 - b1) >> 20));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((int)(a0 - b0) >> 20));
+}
+
+void ff_simple_idct_put_int16_8bit(uint8 *dest_, ptrdiff_t line_size, int16 *block_) {
+ int16 *block = (int16 *)block_;
+ uint8 *dest = (uint8 *)dest_;
+ int i;
+ line_size /= sizeof(uint8);
+ for (i = 0; i < 8; i++)
+ idctRowCondDC_int16_8bit(block + i * 8, 0);
+ for (i = 0; i < 8; i++)
+ idctSparseColPut_int16_8bit(dest + i, line_size, block + i);
+}
+
+void ff_simple_idct_add_int16_8bit(uint8 *dest_, ptrdiff_t line_size, int16 *block) {
+ uint8 *dest = (uint8 *)dest_;
+ int i;
+ line_size /= sizeof(uint8);
+ for (i = 0; i < 8; i++)
+ idctRowCondDC_int16_8bit(block + i * 8, 0);
+ for (i = 0; i < 8; i++)
+ idctSparseColAdd_int16_8bit(dest + i, line_size, block + i);
+}
+
+void ff_simple_idct_int16_8bit(int16 *block) {
+ int i;
+ for (i = 0; i < 8; i++)
+ idctRowCondDC_int16_8bit(block + i * 8, 0);
+ for (i = 0; i < 8; i++)
+ idctSparseCol_int16_8bit(block + i);
+}
+
+static inline void idct4col_add(uint8 *dest, ptrdiff_t line_size, const int16 *col) {
+ int c0, c1, c2, c3, a0, a1, a2, a3;
+ a0 = col[8 * 0];
+ a1 = col[8 * 1];
+ a2 = col[8 * 2];
+ a3 = col[8 * 3];
+ c0 = (a0 + a2) * ((int)((0.5) * M_SQRT2 * (1 << 12) + 0.5)) + (1 << ((4 + 1 + 12) - 1));
+ c2 = (a0 - a2) * ((int)((0.5) * M_SQRT2 * (1 << 12) + 0.5)) + (1 << ((4 + 1 + 12) - 1));
+ c1 = a1 * ((int)((0.6532814824) * M_SQRT2 * (1 << 12) + 0.5)) +
+ a3 * ((int)((0.2705980501) * M_SQRT2 * (1 << 12) + 0.5));
+ c3 = a1 * ((int)((0.2705980501) * M_SQRT2 * (1 << 12) + 0.5)) -
+ a3 * ((int)((0.6532814824) * M_SQRT2 * (1 << 12) + 0.5));
+ dest[0] = av_clip_uint8(dest[0] + ((c0 + c1) >> (4 + 1 + 12)));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((c2 + c3) >> (4 + 1 + 12)));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((c2 - c3) >> (4 + 1 + 12)));
+ dest += line_size;
+ dest[0] = av_clip_uint8(dest[0] + ((c0 - c1) >> (4 + 1 + 12)));
+}
+
+static inline void idct4row(int16 *row) {
+ unsigned c0, c1, c2, c3;
+ int a0, a1, a2, a3;
+ a0 = row[0];
+ a1 = row[1];
+ a2 = row[2];
+ a3 = row[3];
+ c0 = (a0 + a2) * ((int)((0.5) * M_SQRT2 * (1 << 15) + 0.5)) + (1 << (11 - 1));
+ c2 = (a0 - a2) * ((int)((0.5) * M_SQRT2 * (1 << 15) + 0.5)) + (1 << (11 - 1));
+ c1 = a1 * ((int)((0.6532814824) * M_SQRT2 * (1 << 15) + 0.5)) +
+ a3 * ((int)((0.2705980501) * M_SQRT2 * (1 << 15) + 0.5));
+ c3 = a1 * ((int)((0.2705980501) * M_SQRT2 * (1 << 15) + 0.5)) -
+ a3 * ((int)((0.6532814824) * M_SQRT2 * (1 << 15) + 0.5));
+ row[0] = (c0 + c1) >> 11;
+ row[1] = (c2 + c3) >> 11;
+ row[2] = (c2 - c3) >> 11;
+ row[3] = (c0 - c1) >> 11;
+}
+
+void ff_simple_idct84_add(uint8 *dest, ptrdiff_t line_size, int16 *block) {
+ int i;
+ /* IDCT8 on each line */
+ for (i = 0; i < 4; i++) {
+ idctRowCondDC_int16_8bit(block + i * 8, 0);
+ }
+ /* IDCT4 and store */
+ for (i = 0; i < 8; i++) {
+ idct4col_add(dest + i, line_size, block + i);
+ }
+}
+
+void ff_simple_idct48_add(uint8 *dest, ptrdiff_t line_size, int16 *block) {
+ int i;
+ /* IDCT4 on each line */
+ for (i = 0; i < 8; i++) {
+ idct4row(block + i * 8);
+ }
+ /* IDCT8 and store */
+ for (i = 0; i < 4; i++) {
+ idctSparseColAdd_int16_8bit(dest + i, line_size, block + i);
+ }
+}
+
+void ff_simple_idct44_add(uint8 *dest, ptrdiff_t line_size, int16 *block) {
+ int i;
+ /* IDCT4 on each line */
+ for (i = 0; i < 4; i++) {
+ idct4row(block + i * 8);
+ }
+ /* IDCT4 and store */
+ for (i = 0; i < 4; i++) {
+ idct4col_add(dest + i, line_size, block + i);
+ }
+}
+
+static void copy_block8(uint8 *d, const uint8 *s, ptrdiff_t ds, ptrdiff_t ss, int h) {
+ for (int y = 0; y < h; ++y) {
+ memcpy(d, s, 8);
+ d += ds;
+ s += ss;
+ }
+}
+
+static void copy_block9(uint8 *d, const uint8 *s, ptrdiff_t ds, ptrdiff_t ss, int h) {
+ for (int y = 0; y < h; ++y) {
+ memcpy(d, s, 9);
+ d += ds;
+ s += ss;
+ }
+}
+
+static void copy_block16(uint8 *d, const uint8 *s, ptrdiff_t ds, ptrdiff_t ss, int h) {
+ for (int y = 0; y < h; ++y) {
+ memcpy(d, s, 16);
+ d += ds;
+ s += ss;
+ }
+}
+
+static void copy_block17(uint8 *d, const uint8 *s, ptrdiff_t ds, ptrdiff_t ss, int h) {
+ for (int y = 0; y < h; ++y) {
+ memcpy(d, s, 17);
+ d += ds;
+ s += ss;
+ }
+}
+
+static void put_pixels8_8_c(uint8 *d, const uint8 *s, ptrdiff_t stride, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 8; ++x) {
+ int val = s[x];
+ d[x] = val;
+ }
+ d += stride;
+ s += stride;
+ }
+}
+
+static void put_pixels8_l2_8(uint8 *d, const uint8 *a, const uint8 *b, int ds, int as, int bs, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 8; ++x) {
+ int val = (a[x] + b[x] + 1) >> 1;
+ d[x] = val;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ }
+}
+
+static void put_pixels8_l4_8(uint8 *d, const uint8 *a, const uint8 *b, const uint8 *c, const uint8 *e, int ds, int as,
+ int bs, int cs, int es, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 8; ++x) {
+ int val = (a[x] + b[x] + c[x] + e[x] + 2) >> 2;
+ d[x] = val;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ c += cs;
+ e += es;
+ }
+}
+
+static void avg_pixels8_8_c(uint8 *d, const uint8 *s, ptrdiff_t stride, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 8; ++x) {
+ int val = s[x];
+ d[x] = (d[x] + val + 1) >> 1;
+ }
+ d += stride;
+ s += stride;
+ }
+}
+
+static void avg_pixels8_l2_8(uint8 *d, const uint8 *a, const uint8 *b, int ds, int as, int bs, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 8; ++x) {
+ int val = (a[x] + b[x] + 1) >> 1;
+ d[x] = (d[x] + val + 1) >> 1;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ }
+}
+
+static void avg_pixels8_l4_8(uint8 *d, const uint8 *a, const uint8 *b, const uint8 *c, const uint8 *e, int ds, int as,
+ int bs, int cs, int es, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 8; ++x) {
+ int val = (a[x] + b[x] + c[x] + e[x] + 2) >> 2;
+ d[x] = (d[x] + val + 1) >> 1;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ c += cs;
+ e += es;
+ }
+}
+
+static void put_no_rnd_pixels8_l2_8(uint8 *d, const uint8 *a, const uint8 *b, int ds, int as, int bs, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 8; ++x) {
+ int val = (a[x] + b[x] + 0) >> 1;
+ d[x] = val;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ }
+}
+
+static void put_no_rnd_pixels8_l4_8(uint8 *d, const uint8 *a, const uint8 *b, const uint8 *c, const uint8 *e, int ds,
+ int as, int bs, int cs, int es, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 8; ++x) {
+ int val = (a[x] + b[x] + c[x] + e[x] + 1) >> 2;
+ d[x] = val;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ c += cs;
+ e += es;
+ }
+}
+
+static void put_pixels16_8_c(uint8 *d, const uint8 *s, ptrdiff_t stride, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 16; ++x) {
+ int val = s[x];
+ d[x] = val;
+ }
+ d += stride;
+ s += stride;
+ }
+}
+
+static void put_pixels16_l2_8(uint8 *d, const uint8 *a, const uint8 *b, int ds, int as, int bs, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 16; ++x) {
+ int val = (a[x] + b[x] + 1) >> 1;
+ d[x] = val;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ }
+}
+
+static void put_pixels16_l4_8(uint8 *d, const uint8 *a, const uint8 *b, const uint8 *c, const uint8 *e, int ds, int as,
+ int bs, int cs, int es, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 16; ++x) {
+ int val = (a[x] + b[x] + c[x] + e[x] + 2) >> 2;
+ d[x] = val;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ c += cs;
+ e += es;
+ }
+}
+
+static void avg_pixels16_8_c(uint8 *d, const uint8 *s, ptrdiff_t stride, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 16; ++x) {
+ int val = s[x];
+ d[x] = (d[x] + val + 1) >> 1;
+ }
+ d += stride;
+ s += stride;
+ }
+}
+
+static void avg_pixels16_l2_8(uint8 *d, const uint8 *a, const uint8 *b, int ds, int as, int bs, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 16; ++x) {
+ int val = (a[x] + b[x] + 1) >> 1;
+ d[x] = (d[x] + val + 1) >> 1;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ }
+}
+
+static void avg_pixels16_l4_8(uint8 *d, const uint8 *a, const uint8 *b, const uint8 *c, const uint8 *e, int ds, int as,
+ int bs, int cs, int es, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 16; ++x) {
+ int val = (a[x] + b[x] + c[x] + e[x] + 2) >> 2;
+ d[x] = (d[x] + val + 1) >> 1;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ c += cs;
+ e += es;
+ }
+}
+
+static void put_no_rnd_pixels16_l2_8(uint8 *d, const uint8 *a, const uint8 *b, int ds, int as, int bs, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 16; ++x) {
+ int val = (a[x] + b[x] + 0) >> 1;
+ d[x] = val;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ }
+}
+
+static void put_no_rnd_pixels16_l4_8(uint8 *d, const uint8 *a, const uint8 *b, const uint8 *c, const uint8 *e, int ds,
+ int as, int bs, int cs, int es, int h) {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < 16; ++x) {
+ int val = (a[x] + b[x] + c[x] + e[x] + 1) >> 2;
+ d[x] = val;
+ }
+ d += ds;
+ a += as;
+ b += bs;
+ c += cs;
+ e += es;
+ }
+}
+#define QPEL_MC(r, OPNAME, RND, OP) \
+ static void OPNAME##mpeg4_qpel8_h_lowpass(uint8 *dst, const uint8 *src, int dstStride, int srcStride, int h) { \
+ const Crop cm; \
+ int i; \
+ \
+ for (i = 0; i < h; i++) { \
+ OP(dst[0], (src[0] + src[1]) * 20 - (src[0] + src[2]) * 6 + (src[1] + src[3]) * 3 - (src[2] + src[4])); \
+ OP(dst[1], (src[1] + src[2]) * 20 - (src[0] + src[3]) * 6 + (src[0] + src[4]) * 3 - (src[1] + src[5])); \
+ OP(dst[2], (src[2] + src[3]) * 20 - (src[1] + src[4]) * 6 + (src[0] + src[5]) * 3 - (src[0] + src[6])); \
+ OP(dst[3], (src[3] + src[4]) * 20 - (src[2] + src[5]) * 6 + (src[1] + src[6]) * 3 - (src[0] + src[7])); \
+ OP(dst[4], (src[4] + src[5]) * 20 - (src[3] + src[6]) * 6 + (src[2] + src[7]) * 3 - (src[1] + src[8])); \
+ OP(dst[5], (src[5] + src[6]) * 20 - (src[4] + src[7]) * 6 + (src[3] + src[8]) * 3 - (src[2] + src[8])); \
+ OP(dst[6], (src[6] + src[7]) * 20 - (src[5] + src[8]) * 6 + (src[4] + src[8]) * 3 - (src[3] + src[7])); \
+ OP(dst[7], (src[7] + src[8]) * 20 - (src[6] + src[8]) * 6 + (src[5] + src[7]) * 3 - (src[4] + src[6])); \
+ dst += dstStride; \
+ src += srcStride; \
+ } \
+ } \
+ \
+ static void OPNAME##mpeg4_qpel8_v_lowpass(uint8 *dst, const uint8 *src, int dstStride, int srcStride) { \
+ const Crop cm; \
+ const int w = 8; \
+ int i; \
+ \
+ for (i = 0; i < w; i++) { \
+ const int src0 = src[0 * srcStride]; \
+ const int src1 = src[1 * srcStride]; \
+ const int src2 = src[2 * srcStride]; \
+ const int src3 = src[3 * srcStride]; \
+ const int src4 = src[4 * srcStride]; \
+ const int src5 = src[5 * srcStride]; \
+ const int src6 = src[6 * srcStride]; \
+ const int src7 = src[7 * srcStride]; \
+ const int src8 = src[8 * srcStride]; \
+ OP(dst[0 * dstStride], (src0 + src1) * 20 - (src0 + src2) * 6 + (src1 + src3) * 3 - (src2 + src4)); \
+ OP(dst[1 * dstStride], (src1 + src2) * 20 - (src0 + src3) * 6 + (src0 + src4) * 3 - (src1 + src5)); \
+ OP(dst[2 * dstStride], (src2 + src3) * 20 - (src1 + src4) * 6 + (src0 + src5) * 3 - (src0 + src6)); \
+ OP(dst[3 * dstStride], (src3 + src4) * 20 - (src2 + src5) * 6 + (src1 + src6) * 3 - (src0 + src7)); \
+ OP(dst[4 * dstStride], (src4 + src5) * 20 - (src3 + src6) * 6 + (src2 + src7) * 3 - (src1 + src8)); \
+ OP(dst[5 * dstStride], (src5 + src6) * 20 - (src4 + src7) * 6 + (src3 + src8) * 3 - (src2 + src8)); \
+ OP(dst[6 * dstStride], (src6 + src7) * 20 - (src5 + src8) * 6 + (src4 + src8) * 3 - (src3 + src7)); \
+ OP(dst[7 * dstStride], (src7 + src8) * 20 - (src6 + src8) * 6 + (src5 + src7) * 3 - (src4 + src6)); \
+ dst++; \
+ src++; \
+ } \
+ } \
+ \
+ static void OPNAME##mpeg4_qpel16_h_lowpass(uint8 *dst, const uint8 *src, int dstStride, int srcStride, int h) { \
+ const Crop cm; \
+ int i; \
+ \
+ for (i = 0; i < h; i++) { \
+ OP(dst[0], (src[0] + src[1]) * 20 - (src[0] + src[2]) * 6 + (src[1] + src[3]) * 3 - (src[2] + src[4])); \
+ OP(dst[1], (src[1] + src[2]) * 20 - (src[0] + src[3]) * 6 + (src[0] + src[4]) * 3 - (src[1] + src[5])); \
+ OP(dst[2], (src[2] + src[3]) * 20 - (src[1] + src[4]) * 6 + (src[0] + src[5]) * 3 - (src[0] + src[6])); \
+ OP(dst[3], (src[3] + src[4]) * 20 - (src[2] + src[5]) * 6 + (src[1] + src[6]) * 3 - (src[0] + src[7])); \
+ OP(dst[4], (src[4] + src[5]) * 20 - (src[3] + src[6]) * 6 + (src[2] + src[7]) * 3 - (src[1] + src[8])); \
+ OP(dst[5], (src[5] + src[6]) * 20 - (src[4] + src[7]) * 6 + (src[3] + src[8]) * 3 - (src[2] + src[9])); \
+ OP(dst[6], (src[6] + src[7]) * 20 - (src[5] + src[8]) * 6 + (src[4] + src[9]) * 3 - (src[3] + src[10])); \
+ OP(dst[7], (src[7] + src[8]) * 20 - (src[6] + src[9]) * 6 + (src[5] + src[10]) * 3 - (src[4] + src[11])); \
+ OP(dst[8], (src[8] + src[9]) * 20 - (src[7] + src[10]) * 6 + (src[6] + src[11]) * 3 - (src[5] + src[12])); \
+ OP(dst[9], \
+ (src[9] + src[10]) * 20 - (src[8] + src[11]) * 6 + (src[7] + src[12]) * 3 - (src[6] + src[13])); \
+ OP(dst[10], \
+ (src[10] + src[11]) * 20 - (src[9] + src[12]) * 6 + (src[8] + src[13]) * 3 - (src[7] + src[14])); \
+ OP(dst[11], \
+ (src[11] + src[12]) * 20 - (src[10] + src[13]) * 6 + (src[9] + src[14]) * 3 - (src[8] + src[15])); \
+ OP(dst[12], \
+ (src[12] + src[13]) * 20 - (src[11] + src[14]) * 6 + (src[10] + src[15]) * 3 - (src[9] + src[16])); \
+ OP(dst[13], \
+ (src[13] + src[14]) * 20 - (src[12] + src[15]) * 6 + (src[11] + src[16]) * 3 - (src[10] + src[16])); \
+ OP(dst[14], \
+ (src[14] + src[15]) * 20 - (src[13] + src[16]) * 6 + (src[12] + src[16]) * 3 - (src[11] + src[15])); \
+ OP(dst[15], \
+ (src[15] + src[16]) * 20 - (src[14] + src[16]) * 6 + (src[13] + src[15]) * 3 - (src[12] + src[14])); \
+ dst += dstStride; \
+ src += srcStride; \
+ } \
+ } \
+ \
+ static void OPNAME##mpeg4_qpel16_v_lowpass(uint8 *dst, const uint8 *src, int dstStride, int srcStride) { \
+ const Crop cm; \
+ const int w = 16; \
+ int i; \
+ \
+ for (i = 0; i < w; i++) { \
+ const int src0 = src[0 * srcStride]; \
+ const int src1 = src[1 * srcStride]; \
+ const int src2 = src[2 * srcStride]; \
+ const int src3 = src[3 * srcStride]; \
+ const int src4 = src[4 * srcStride]; \
+ const int src5 = src[5 * srcStride]; \
+ const int src6 = src[6 * srcStride]; \
+ const int src7 = src[7 * srcStride]; \
+ const int src8 = src[8 * srcStride]; \
+ const int src9 = src[9 * srcStride]; \
+ const int src10 = src[10 * srcStride]; \
+ const int src11 = src[11 * srcStride]; \
+ const int src12 = src[12 * srcStride]; \
+ const int src13 = src[13 * srcStride]; \
+ const int src14 = src[14 * srcStride]; \
+ const int src15 = src[15 * srcStride]; \
+ const int src16 = src[16 * srcStride]; \
+ OP(dst[0 * dstStride], (src0 + src1) * 20 - (src0 + src2) * 6 + (src1 + src3) * 3 - (src2 + src4)); \
+ OP(dst[1 * dstStride], (src1 + src2) * 20 - (src0 + src3) * 6 + (src0 + src4) * 3 - (src1 + src5)); \
+ OP(dst[2 * dstStride], (src2 + src3) * 20 - (src1 + src4) * 6 + (src0 + src5) * 3 - (src0 + src6)); \
+ OP(dst[3 * dstStride], (src3 + src4) * 20 - (src2 + src5) * 6 + (src1 + src6) * 3 - (src0 + src7)); \
+ OP(dst[4 * dstStride], (src4 + src5) * 20 - (src3 + src6) * 6 + (src2 + src7) * 3 - (src1 + src8)); \
+ OP(dst[5 * dstStride], (src5 + src6) * 20 - (src4 + src7) * 6 + (src3 + src8) * 3 - (src2 + src9)); \
+ OP(dst[6 * dstStride], (src6 + src7) * 20 - (src5 + src8) * 6 + (src4 + src9) * 3 - (src3 + src10)); \
+ OP(dst[7 * dstStride], (src7 + src8) * 20 - (src6 + src9) * 6 + (src5 + src10) * 3 - (src4 + src11)); \
+ OP(dst[8 * dstStride], (src8 + src9) * 20 - (src7 + src10) * 6 + (src6 + src11) * 3 - (src5 + src12)); \
+ OP(dst[9 * dstStride], (src9 + src10) * 20 - (src8 + src11) * 6 + (src7 + src12) * 3 - (src6 + src13)); \
+ OP(dst[10 * dstStride], (src10 + src11) * 20 - (src9 + src12) * 6 + (src8 + src13) * 3 - (src7 + src14)); \
+ OP(dst[11 * dstStride], (src11 + src12) * 20 - (src10 + src13) * 6 + (src9 + src14) * 3 - (src8 + src15)); \
+ OP(dst[12 * dstStride], \
+ (src12 + src13) * 20 - (src11 + src14) * 6 + (src10 + src15) * 3 - (src9 + src16)); \
+ OP(dst[13 * dstStride], \
+ (src13 + src14) * 20 - (src12 + src15) * 6 + (src11 + src16) * 3 - (src10 + src16)); \
+ OP(dst[14 * dstStride], \
+ (src14 + src15) * 20 - (src13 + src16) * 6 + (src12 + src16) * 3 - (src11 + src15)); \
+ OP(dst[15 * dstStride], \
+ (src15 + src16) * 20 - (src14 + src16) * 6 + (src13 + src15) * 3 - (src12 + src14)); \
+ dst++; \
+ src++; \
+ } \
+ } \
+ \
+ static void OPNAME##qpel8_mc10_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 half[64]; \
+ \
+ put##RND##mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8); \
+ OPNAME##pixels8_l2_8(dst, src, half, stride, stride, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc20_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ OPNAME##mpeg4_qpel8_h_lowpass(dst, src, stride, stride, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc30_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 half[64]; \
+ \
+ put##RND##mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8); \
+ OPNAME##pixels8_l2_8(dst, src + 1, half, stride, stride, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc01_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 half[64]; \
+ \
+ copy_block8(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(half, full, 8, 16); \
+ OPNAME##pixels8_l2_8(dst, full, half, stride, 16, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc02_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ \
+ copy_block8(full, src, 16, stride, 9); \
+ OPNAME##mpeg4_qpel8_v_lowpass(dst, full, stride, 16); \
+ } \
+ \
+ static void OPNAME##qpel8_mc03_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 half[64]; \
+ \
+ copy_block8(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(half, full, 8, 16); \
+ OPNAME##pixels8_l2_8(dst, full + 16, half, stride, 16, 8, 8); \
+ } \
+ \
+ void ff_##OPNAME##qpel8_mc11_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfV[64]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfV, full, 8, 16); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l4_8(dst, full, halfH, halfV, halfHV, stride, 16, 8, 8, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc11_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##pixels8_l2_8(halfH, halfH, full, 8, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8); \
+ } \
+ \
+ void ff_##OPNAME##qpel8_mc31_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfV[64]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfV, full + 1, 8, 16); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l4_8(dst, full + 1, halfH, halfV, halfHV, stride, 16, 8, 8, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc31_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##pixels8_l2_8(halfH, halfH, full + 1, 8, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8); \
+ } \
+ \
+ void ff_##OPNAME##qpel8_mc13_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfV[64]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfV, full, 8, 16); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l4_8(dst, full + 16, halfH + 8, halfV, halfHV, stride, 16, 8, 8, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc13_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##pixels8_l2_8(halfH, halfH, full, 8, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l2_8(dst, halfH + 8, halfHV, stride, 8, 8, 8); \
+ } \
+ \
+ void ff_##OPNAME##qpel8_mc33_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfV[64]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfV, full + 1, 8, 16); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l4_8(dst, full + 17, halfH + 8, halfV, halfHV, stride, 16, 8, 8, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc33_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##pixels8_l2_8(halfH, halfH, full + 1, 8, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l2_8(dst, halfH + 8, halfHV, stride, 8, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc21_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 halfH[72]; \
+ uint8 halfHV[64]; \
+ \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc23_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 halfH[72]; \
+ uint8 halfHV[64]; \
+ \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l2_8(dst, halfH + 8, halfHV, stride, 8, 8, 8); \
+ } \
+ \
+ void ff_##OPNAME##qpel8_mc12_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfV[64]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfV, full, 8, 16); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc12_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##pixels8_l2_8(halfH, halfH, full, 8, 8, 16, 9); \
+ OPNAME##mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8); \
+ } \
+ \
+ void ff_##OPNAME##qpel8_mc32_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ uint8 halfV[64]; \
+ uint8 halfHV[64]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfV, full + 1, 8, 16); \
+ put##RND##mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \
+ OPNAME##pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc32_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[16 * 9]; \
+ uint8 halfH[72]; \
+ \
+ copy_block9(full, src, 16, stride, 9); \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \
+ put##RND##pixels8_l2_8(halfH, halfH, full + 1, 8, 8, 16, 9); \
+ OPNAME##mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8); \
+ } \
+ \
+ static void OPNAME##qpel8_mc22_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 halfH[72]; \
+ \
+ put##RND##mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9); \
+ OPNAME##mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8); \
+ } \
+ \
+ static void OPNAME##qpel16_mc10_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 half[256]; \
+ \
+ put##RND##mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16); \
+ OPNAME##pixels16_l2_8(dst, src, half, stride, stride, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc20_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ OPNAME##mpeg4_qpel16_h_lowpass(dst, src, stride, stride, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc30_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 half[256]; \
+ \
+ put##RND##mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16); \
+ OPNAME##pixels16_l2_8(dst, src + 1, half, stride, stride, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc01_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 half[256]; \
+ \
+ copy_block16(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(half, full, 16, 24); \
+ OPNAME##pixels16_l2_8(dst, full, half, stride, 24, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc02_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ \
+ copy_block16(full, src, 24, stride, 17); \
+ OPNAME##mpeg4_qpel16_v_lowpass(dst, full, stride, 24); \
+ } \
+ \
+ static void OPNAME##qpel16_mc03_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 half[256]; \
+ \
+ copy_block16(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(half, full, 16, 24); \
+ OPNAME##pixels16_l2_8(dst, full + 24, half, stride, 24, 16, 16); \
+ } \
+ \
+ void ff_##OPNAME##qpel16_mc11_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfV[256]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfV, full, 16, 24); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l4_8(dst, full, halfH, halfV, halfHV, stride, 24, 16, 16, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc11_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##pixels16_l2_8(halfH, halfH, full, 16, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16); \
+ } \
+ \
+ void ff_##OPNAME##qpel16_mc31_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfV[256]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfV, full + 1, 16, 24); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l4_8(dst, full + 1, halfH, halfV, halfHV, stride, 24, 16, 16, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc31_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##pixels16_l2_8(halfH, halfH, full + 1, 16, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16); \
+ } \
+ \
+ void ff_##OPNAME##qpel16_mc13_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfV[256]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfV, full, 16, 24); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l4_8(dst, full + 24, halfH + 16, halfV, halfHV, stride, 24, 16, 16, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc13_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##pixels16_l2_8(halfH, halfH, full, 16, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l2_8(dst, halfH + 16, halfHV, stride, 16, 16, 16); \
+ } \
+ \
+ void ff_##OPNAME##qpel16_mc33_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfV[256]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfV, full + 1, 16, 24); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l4_8(dst, full + 25, halfH + 16, halfV, halfHV, stride, 24, 16, 16, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc33_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##pixels16_l2_8(halfH, halfH, full + 1, 16, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l2_8(dst, halfH + 16, halfHV, stride, 16, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc21_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 halfH[272]; \
+ uint8 halfHV[256]; \
+ \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc23_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 halfH[272]; \
+ uint8 halfHV[256]; \
+ \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l2_8(dst, halfH + 16, halfHV, stride, 16, 16, 16); \
+ } \
+ \
+ void ff_##OPNAME##qpel16_mc12_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfV[256]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfV, full, 16, 24); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l2_8(dst, halfV, halfHV, stride, 16, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc12_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##pixels16_l2_8(halfH, halfH, full, 16, 16, 24, 17); \
+ OPNAME##mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16); \
+ } \
+ \
+ void ff_##OPNAME##qpel16_mc32_old_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ uint8 halfV[256]; \
+ uint8 halfHV[256]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfV, full + 1, 16, 24); \
+ put##RND##mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \
+ OPNAME##pixels16_l2_8(dst, halfV, halfHV, stride, 16, 16, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc32_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 full[24 * 17]; \
+ uint8 halfH[272]; \
+ \
+ copy_block17(full, src, 24, stride, 17); \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \
+ put##RND##pixels16_l2_8(halfH, halfH, full + 1, 16, 16, 24, 17); \
+ OPNAME##mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16); \
+ } \
+ \
+ static void OPNAME##qpel16_mc22_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) { \
+ uint8 halfH[272]; \
+ \
+ put##RND##mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17); \
+ OPNAME##mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16); \
+ }
+
+#define op_avg(a, b) a = (((a) + cm[((b) + 16) >> 5] + 1) >> 1)
+#define op_put(a, b) a = cm[((b) + 16) >> 5]
+#define op_put_no_rnd(a, b) a = cm[((b) + 15) >> 5]
+
+QPEL_MC(0, put_, _, op_put)
+QPEL_MC(1, put_no_rnd_, _no_rnd_, op_put_no_rnd)
+QPEL_MC(0, avg_, _, op_avg)
+
+#undef op_avg
+#undef op_put
+#undef op_put_no_rnd
+
+void ff_put_pixels8x8_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) {
+ put_pixels8_8_c(dst, src, stride, 8);
+}
+
+void ff_avg_pixels8x8_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) {
+ avg_pixels8_8_c(dst, src, stride, 8);
+}
+
+void ff_put_pixels16x16_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) {
+ put_pixels16_8_c(dst, src, stride, 16);
+}
+
+void ff_avg_pixels16x16_c(uint8 *dst, const uint8 *src, ptrdiff_t stride) {
+ avg_pixels16_8_c(dst, src, stride, 16);
+}
+
+#define put_qpel8_mc00_c ff_put_pixels8x8_c
+#define avg_qpel8_mc00_c ff_avg_pixels8x8_c
+#define put_qpel16_mc00_c ff_put_pixels16x16_c
+#define avg_qpel16_mc00_c ff_avg_pixels16x16_c
+#define put_no_rnd_qpel8_mc00_c ff_put_pixels8x8_c
+#define put_no_rnd_qpel16_mc00_c ff_put_pixels16x16_c
+
+void initQpel(QpelDSP *c) {
+#define dspfunc(PFX, IDX, NUM) \
+ c->PFX##_pixels_tab[IDX][0] = PFX##NUM##_mc00_c; \
+ c->PFX##_pixels_tab[IDX][1] = PFX##NUM##_mc10_c; \
+ c->PFX##_pixels_tab[IDX][2] = PFX##NUM##_mc20_c; \
+ c->PFX##_pixels_tab[IDX][3] = PFX##NUM##_mc30_c; \
+ c->PFX##_pixels_tab[IDX][4] = PFX##NUM##_mc01_c; \
+ c->PFX##_pixels_tab[IDX][5] = PFX##NUM##_mc11_c; \
+ c->PFX##_pixels_tab[IDX][6] = PFX##NUM##_mc21_c; \
+ c->PFX##_pixels_tab[IDX][7] = PFX##NUM##_mc31_c; \
+ c->PFX##_pixels_tab[IDX][8] = PFX##NUM##_mc02_c; \
+ c->PFX##_pixels_tab[IDX][9] = PFX##NUM##_mc12_c; \
+ c->PFX##_pixels_tab[IDX][10] = PFX##NUM##_mc22_c; \
+ c->PFX##_pixels_tab[IDX][11] = PFX##NUM##_mc32_c; \
+ c->PFX##_pixels_tab[IDX][12] = PFX##NUM##_mc03_c; \
+ c->PFX##_pixels_tab[IDX][13] = PFX##NUM##_mc13_c; \
+ c->PFX##_pixels_tab[IDX][14] = PFX##NUM##_mc23_c; \
+ c->PFX##_pixels_tab[IDX][15] = PFX##NUM##_mc33_c
+
+ dspfunc(put_qpel, 0, 16);
+ dspfunc(put_qpel, 1, 8);
+
+ dspfunc(put_no_rnd_qpel, 0, 16);
+ dspfunc(put_no_rnd_qpel, 1, 8);
+
+ dspfunc(avg_qpel, 0, 16);
+ dspfunc(avg_qpel, 1, 8);
+}
+
+#undef QPEL_MC
+#undef avg_qpel16_mc00_c
+#undef avg_qpel8_mc00_c
+#undef dspfunc
+#undef put_no_rnd_qpel16_mc00_c
+#undef put_no_rnd_qpel8_mc00_c
+#undef put_qpel16_mc00_c
+#undef put_qpel8_mc00_c
+
+/*
+ * area positions, #3 is 1 pixel only, other are 8 pixels
+ * |66666666|
+ * 3|44444444|55555555|
+ * - -+--------+--------+
+ * 1 2|XXXXXXXX|
+ * 1 2|XXXXXXXX|
+ * 1 2|XXXXXXXX|
+ * 1 2|XXXXXXXX|
+ * 1 2|XXXXXXXX|
+ * 1 2|XXXXXXXX|
+ * 1 2|XXXXXXXX|
+ * 1 2|XXXXXXXX|
+ * ^-start
+ */
+
+#define area1 (0)
+#define area2 (8)
+#define area3 (8 + 8)
+#define area4 (8 + 8 + 1)
+#define area5 (8 + 8 + 1 + 8)
+#define area6 (8 + 8 + 1 + 16)
+
+/**
+ Collect statistics and prepare the edge pixels required by the other spatial compensation functions.
+
+ * @param src pointer to the beginning of the processed block
+ * @param dst pointer to emu_edge, edge pixels are stored the way other compensation routines do.
+ * @param linesize byte offset between 2 vertical pixels in the source image
+ * @param range pointer to the variable where the edge pixel range is to be stored (max-min values)
+ * @param psum pointer to the variable where the edge pixel sum is to be stored
+ * @param edges Informs this routine that the block is on an image border, so it has to interpolate the missing edge
+pixels. and some of the edge pixels should be interpolated, the flag has the following meaning: 1 - mb_x==0 - first
+block in the row, interpolate area #1,#2,#3; 2 - mb_y==0 - first row, interpolate area #3,#4,#5,#6; note: 1|2 -
+mb_x==mb_y==0 - first block, use 0x80 value for all areas; 4 - mb_x>= (mb_width-1) last block in the row, interpolate
+area #5;
+-*/
+static void x8_setup_spatial_compensation(const uint8 *src, uint8 *dst, ptrdiff_t stride, int *range, int *psum,
+ int edges) {
+ const uint8 *ptr;
+ int sum;
+ int i;
+ int min_pix, max_pix;
+ uint8 c;
+
+ if ((edges & 3) == 3) {
+ *psum = 0x80 * (8 + 1 + 8 + 2);
+ *range = 0;
+ memset(dst, 0x80, 16 + 1 + 16 + 8);
+ /* this triggers flat_dc for sure. flat_dc avoids all (other)
+ * prediction modes, but requires dc_level decoding. */
+ return;
+ }
+
+ min_pix = 256;
+ max_pix = -1;
+
+ sum = 0;
+
+ if (!(edges & 1)) { // (mb_x != 0) // there is previous block on this row
+ ptr = src - 1; // left column, area 2
+ for (i = 7; i >= 0; i--) {
+ c = *(ptr - 1); // area1, same mb as area2, no need to check
+ dst[area1 + i] = c;
+ c = *ptr;
+
+ sum += c;
+ min_pix = MIN(min_pix, int(c));
+ max_pix = MAX(max_pix, int(c));
+ dst[area2 + i] = c;
+
+ ptr += stride;
+ }
+ }
+
+ if (!(edges & 2)) { // (mb_y != 0) // there is row above
+ ptr = src - stride; // top line
+ for (i = 0; i < 8; i++) {
+ c = *(ptr + i);
+ sum += c;
+ min_pix = MIN(min_pix, int(c));
+ max_pix = MAX(max_pix, int(c));
+ }
+ if (edges & 4) { // last block on the row?
+ memset(dst + area5, c, 8); // set with last pixel fr
+ memcpy(dst + area4, ptr, 8);
+ } else {
+ memcpy(dst + area4, ptr, 16); // both area4 and 5
+ }
+ // area6 always present in the above block
+ memcpy(dst + area6, ptr - stride, 8);
+ }
+ // now calculate the stuff we need
+ if (edges & 3) { // mb_x ==0 || mb_y == 0) {
+ int avg = (sum + 4) >> 3;
+
+ if (edges & 1) // (mb_x == 0) { // implies mb_y !=0
+ memset(dst + area1, avg, 8 + 8 + 1); // areas 1, 2, 3 are averaged
+ else // implies y == 0 x != 0
+ memset(dst + area3, avg, 1 + 16 + 8); // areas 3, 4, 5, 6
+
+ sum += avg * 9;
+ } else {
+ // the edge pixel, in the top line and left column
+ uint8 c = *(src - 1 - stride);
+ dst[area3] = c;
+ sum += c;
+ // edge pixel is not part of min/max
+ }
+ *range = max_pix - min_pix;
+ sum += *(dst + area5) + *(dst + area5 + 1);
+ *psum = sum;
+}
+
+static const uint16 zero_prediction_weights[64 * 2] = {
+ 640, 640, 669, 480, 708, 354, 748, 257, 792, 198, 760, 143, 808, 101, 772, 72, 480, 669, 537, 537, 598, 416,
+ 661, 316, 719, 250, 707, 185, 768, 134, 745, 97, 354, 708, 416, 598, 488, 488, 564, 388, 634, 317, 642, 241,
+ 716, 179, 706, 132, 257, 748, 316, 661, 388, 564, 469, 469, 543, 395, 571, 311, 655, 238, 660, 180, 198, 792,
+ 250, 719, 317, 634, 395, 543, 469, 469, 507, 380, 597, 299, 616, 231, 161, 855, 206, 788, 266, 710, 340, 623,
+ 411, 548, 455, 455, 548, 366, 576, 288, 122, 972, 159, 914, 211, 842, 276, 758, 341, 682, 389, 584, 483, 483,
+ 520, 390, 110, 1172, 144, 1107, 193, 1028, 254, 932, 317, 846, 366, 731, 458, 611, 499, 499,
+};
+
+static void spatial_compensation_0(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int i, j;
+ int x, y;
+ unsigned int p; // power divided by 2
+ int a;
+ uint16 left_sum[2][8] = {{0}};
+ uint16 top_sum[2][8] = {{0}};
+
+ for (i = 0; i < 8; i++) {
+ a = src[area2 + 7 - i] << 4;
+ for (j = 0; j < 8; j++) {
+ p = abs(i - j);
+ left_sum[p & 1][j] += a >> (p >> 1);
+ }
+ }
+
+ for (i = 0; i < 8; i++) {
+ a = src[area4 + i] << 4;
+ for (j = 0; j < 8; j++) {
+ p = abs(i - j);
+ top_sum[p & 1][j] += a >> (p >> 1);
+ }
+ }
+ for (; i < 10; i++) {
+ a = src[area4 + i] << 4;
+ for (j = 5; j < 8; j++) {
+ p = abs(i - j);
+ top_sum[p & 1][j] += a >> (p >> 1);
+ }
+ }
+ for (; i < 12; i++) {
+ a = src[area4 + i] << 4;
+ for (j = 7; j < 8; j++) {
+ p = abs(i - j);
+ top_sum[p & 1][j] += a >> (p >> 1);
+ }
+ }
+
+ for (i = 0; i < 8; i++) {
+ top_sum[0][i] += (top_sum[1][i] * 181 + 128) >> 8; // 181 is sqrt(2)/2
+ left_sum[0][i] += (left_sum[1][i] * 181 + 128) >> 8;
+ }
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = ((uint32)top_sum[0][x] * zero_prediction_weights[y * 16 + x * 2 + 0] +
+ (uint32)left_sum[0][y] * zero_prediction_weights[y * 16 + x * 2 + 1] + 0x8000) >>
+ 16;
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_1(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int x, y;
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = src[area4 + MIN(2 * y + x + 2, 15)];
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_2(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ for (int y = 0; y < 8; y++) {
+ memcpy(dst, src + area4 + 1 + y, 8);
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_3(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ for (int y = 0; y < 8; y++) {
+ memcpy(dst, src + area4 + ((y + 1) >> 1), 8);
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_4(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int x, y;
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = (src[area4 + x] + src[area6 + x] + 1) >> 1;
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_5(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int x, y;
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++) {
+ if (2 * x - y < 0)
+ dst[x] = src[area2 + 9 + 2 * x - y];
+ else
+ dst[x] = src[area4 + x - ((y + 1) >> 1)];
+ }
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_6(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ for (int y = 0; y < 8; y++) {
+ memcpy(dst, src + area3 - y, 8);
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_7(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int x, y;
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++) {
+ if (x - 2 * y > 0)
+ dst[x] = (src[area3 - 1 + x - 2 * y] + src[area3 + x - 2 * y] + 1) >> 1;
+ else
+ dst[x] = src[area2 + 8 - y + (x >> 1)];
+ }
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_8(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int x, y;
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = (src[area1 + 7 - y] + src[area2 + 7 - y] + 1) >> 1;
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_9(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int x, y;
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = src[area2 + 6 - MIN(x + y, 6)];
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_10(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int x, y;
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = (src[area2 + 7 - y] * (8 - x) + src[area4 + x] * x + 4) >> 3;
+ dst += stride;
+ }
+}
+
+static void spatial_compensation_11(const uint8 *src, uint8 *dst, ptrdiff_t stride) {
+ int x, y;
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = (src[area2 + 7 - y] * y + src[area4 + x] * (8 - y) + 4) >> 3;
+ dst += stride;
+ }
+}
+
+static void x8_loop_filter(uint8 *ptr, const ptrdiff_t a_stride, const ptrdiff_t b_stride, int quant) {
+ int i, t;
+ int p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
+ int ql = (quant + 10) >> 3;
+
+ for (i = 0; i < 8; i++, ptr += b_stride) {
+ p0 = ptr[-5 * a_stride];
+ p1 = ptr[-4 * a_stride];
+ p2 = ptr[-3 * a_stride];
+ p3 = ptr[-2 * a_stride];
+ p4 = ptr[-1 * a_stride];
+ p5 = ptr[0];
+ p6 = ptr[1 * a_stride];
+ p7 = ptr[2 * a_stride];
+ p8 = ptr[3 * a_stride];
+ p9 = ptr[4 * a_stride];
+
+ t = (ABS(p1 - p2) <= ql) + (ABS(p2 - p3) <= ql) + (ABS(p3 - p4) <= ql) + (ABS(p4 - p5) <= ql);
+
+ // You need at least 1 to be able to reach a total score of 6.
+ if (t > 0) {
+ t += (ABS(p5 - p6) <= ql) + (ABS(p6 - p7) <= ql) + (ABS(p7 - p8) <= ql) + (ABS(p8 - p9) <= ql) +
+ (ABS(p0 - p1) <= ql);
+ if (t >= 6) {
+ int min, max;
+
+ min = max = p1;
+ min = MIN(min, p3);
+ max = MAX(max, p3);
+ min = MIN(min, p5);
+ max = MAX(max, p5);
+ min = MIN(min, p8);
+ max = MAX(max, p8);
+ if (max - min < 2 * quant) { // early stop
+ min = MIN(min, p2);
+ max = MAX(max, p2);
+ min = MIN(min, p4);
+ max = MAX(max, p4);
+ min = MIN(min, p6);
+ max = MAX(max, p6);
+ min = MIN(min, p7);
+ max = MAX(max, p7);
+ if (max - min < 2 * quant) {
+ ptr[-2 * a_stride] = (4 * p2 + 3 * p3 + 1 * p7 + 4) >> 3;
+ ptr[-1 * a_stride] = (3 * p2 + 3 * p4 + 2 * p7 + 4) >> 3;
+ ptr[0] = (2 * p2 + 3 * p5 + 3 * p7 + 4) >> 3;
+ ptr[1 * a_stride] = (1 * p2 + 3 * p6 + 4 * p7 + 4) >> 3;
+ continue;
+ }
+ }
+ }
+ }
+ {
+ int x, x0, x1, x2;
+ int m;
+
+ x0 = (2 * p3 - 5 * p4 + 5 * p5 - 2 * p6 + 4) >> 3;
+ if (ABS(x0) < quant) {
+ x1 = (2 * p1 - 5 * p2 + 5 * p3 - 2 * p4 + 4) >> 3;
+ x2 = (2 * p5 - 5 * p6 + 5 * p7 - 2 * p8 + 4) >> 3;
+
+ x = ABS(x0) - MIN(ABS(x1), ABS(x2));
+ m = p4 - p5;
+
+ if (x > 0 && (m ^ x0) < 0) {
+ int32 sign;
+
+ sign = m >> 31;
+ m = (m ^ sign) - sign; // abs(m)
+ m >>= 1;
+
+ x = 5 * x >> 3;
+
+ if (x > m)
+ x = m;
+
+ x = (x ^ sign) - sign;
+
+ ptr[-1 * a_stride] -= x;
+ ptr[0] += x;
+ }
+ }
+ }
+ }
+}
+
+static void x8_h_loop_filter(uint8 *src, ptrdiff_t stride, int qscale) {
+ x8_loop_filter(src, stride, 1, qscale);
+}
+
+static void x8_v_loop_filter(uint8 *src, ptrdiff_t stride, int qscale) {
+ x8_loop_filter(src, 1, stride, qscale);
+}
+
+void ff_intrax8dsp_init(IntraX8DSPContext *dsp) {
+ dsp->h_loop_filter = x8_h_loop_filter;
+ dsp->v_loop_filter = x8_v_loop_filter;
+ dsp->setup_spatial_compensation = x8_setup_spatial_compensation;
+ dsp->spatial_compensation[0] = spatial_compensation_0;
+ dsp->spatial_compensation[1] = spatial_compensation_1;
+ dsp->spatial_compensation[2] = spatial_compensation_2;
+ dsp->spatial_compensation[3] = spatial_compensation_3;
+ dsp->spatial_compensation[4] = spatial_compensation_4;
+ dsp->spatial_compensation[5] = spatial_compensation_5;
+ dsp->spatial_compensation[6] = spatial_compensation_6;
+ dsp->spatial_compensation[7] = spatial_compensation_7;
+ dsp->spatial_compensation[8] = spatial_compensation_8;
+ dsp->spatial_compensation[9] = spatial_compensation_9;
+ dsp->spatial_compensation[10] = spatial_compensation_10;
+ dsp->spatial_compensation[11] = spatial_compensation_11;
+}
+
+#undef area1
+#undef area2
+#undef area3
+#undef area4
+#undef area5
+#undef area6
+
+static const uint8 x8_orient_lowquant_table[4][12][2] = {
+ {
+ /* Orient lowquant table 0 */
+ {0, 1},
+ {1, 3},
+ {2, 3},
+ {3, 4},
+ {4, 4},
+ {5, 6},
+ {7, 6},
+ {6, 5},
+ {8, 6},
+ {9, 6},
+ {10, 6},
+ {11, 6},
+ },
+ {
+ /* Orient lowquant table 1 */
+ {0, 5},
+ {1, 5},
+ {2, 5},
+ {6, 5},
+ {5, 4},
+ {8, 4},
+ {3, 2},
+ {4, 2},
+ {7, 3},
+ {9, 4},
+ {10, 5},
+ {11, 5},
+ },
+ {
+ /* Orient lowquant table 2 */
+ {0, 2},
+ {1, 2},
+ {2, 3},
+ {3, 3},
+ {4, 3},
+ {5, 6},
+ {6, 6},
+ {7, 5},
+ {8, 6},
+ {9, 6},
+ {10, 6},
+ {11, 6},
+ },
+ {
+ /* Orient lowquant table 3 */
+ {0, 3},
+ {1, 4},
+ {2, 4},
+ {3, 2},
+ {4, 2},
+ {5, 5},
+ {6, 5},
+ {7, 4},
+ {8, 5},
+ {9, 5},
+ {10, 5},
+ {11, 5},
+ },
+};
+
+static const uint8 x8_orient_highquant_table[2][12][2] = {
+ {
+ /* Orient highquant table 0 */
+ {0, 2},
+ {1, 2},
+ {2, 3},
+ {3, 3},
+ {4, 3},
+ {5, 6},
+ {7, 6},
+ {6, 5},
+ {8, 6},
+ {9, 6},
+ {10, 6},
+ {11, 6},
+ },
+ {
+ /* Orient highquant table 1 */
+ {0, 1},
+ {1, 2},
+ {2, 3},
+ {3, 5},
+ {4, 5},
+ {5, 7},
+ {7, 7},
+ {6, 6},
+ {8, 7},
+ {9, 7},
+ {10, 7},
+ {11, 7},
+ },
+};
+#define MAX_OR_VLC_BITS 7
+
+static const uint8 x8_dc_quant_table[2][8][34][2] = {
+ {
+ {
+ /* DC highquant table 0 */
+ {0, 5}, {3, 5}, {1, 4}, {2, 4}, {4, 5}, {6, 5}, {5, 4}, {7, 5}, {8, 7},
+ {9, 7}, {10, 12}, {11, 12}, {12, 12}, {13, 12}, {14, 12}, {15, 12}, {16, 12}, {25, 12},
+ {26, 12}, {27, 12}, {28, 12}, {29, 12}, {30, 12}, {31, 12}, {32, 12}, {33, 12}, {24, 8},
+ {23, 7}, {17, 3}, {18, 2}, {19, 3}, {20, 4}, {21, 5}, {22, 5},
+ },
+ {
+ /* DC highquant table 1 */
+ {0, 3}, {1, 3}, {2, 3}, {3, 4}, {4, 4}, {5, 3}, {6, 4}, {7, 4}, {8, 6},
+ {9, 7}, {10, 7}, {11, 11}, {12, 11}, {13, 11}, {14, 11}, {15, 11}, {16, 11}, {25, 11},
+ {27, 11}, {28, 11}, {29, 11}, {30, 11}, {31, 11}, {32, 10}, {33, 10}, {23, 7}, {17, 6},
+ {18, 4}, {19, 5}, {20, 5}, {21, 6}, {24, 7}, {26, 7}, {22, 5},
+ },
+ {
+ /* DC highquant table 2 */
+ {0, 7}, {1, 7}, {2, 6}, {3, 7}, {5, 7}, {4, 6}, {6, 8}, {7, 8}, {8, 13},
+ {9, 13}, {10, 13}, {11, 13}, {12, 13}, {13, 13}, {14, 13}, {15, 13}, {16, 12}, {23, 12},
+ {24, 12}, {25, 12}, {26, 12}, {27, 12}, {28, 12}, {29, 12}, {30, 12}, {31, 12}, {32, 12},
+ {33, 12}, {22, 8}, {21, 6}, {20, 5}, {19, 3}, {18, 2}, {17, 1},
+ },
+ {
+ /* DC highquant table 3 */
+ {0, 4}, {3, 4}, {1, 3}, {2, 3}, {4, 4}, {8, 5}, {9, 5}, {5, 3}, {6, 3},
+ {7, 3}, {10, 7}, {11, 11}, {12, 11}, {13, 11}, {14, 11}, {15, 11}, {16, 11}, {25, 11},
+ {26, 11}, {27, 11}, {29, 11}, {30, 11}, {31, 11}, {32, 10}, {33, 10}, {18, 7}, {21, 7},
+ {17, 5}, {19, 6}, {20, 6}, {22, 7}, {23, 7}, {24, 7}, {28, 7},
+ },
+ {
+ /* DC highquant table 4 */
+ {0, 8}, {4, 9}, {6, 9}, {1, 7}, {2, 7}, {3, 7}, {5, 8}, {7, 14}, {8, 14},
+ {9, 14}, {10, 14}, {11, 14}, {12, 14}, {13, 14}, {14, 14}, {15, 13}, {16, 13}, {24, 13},
+ {25, 13}, {26, 13}, {27, 13}, {28, 13}, {29, 13}, {30, 13}, {31, 13}, {32, 13}, {33, 13},
+ {23, 9}, {22, 7}, {21, 6}, {20, 4}, {19, 3}, {17, 2}, {18, 1},
+ },
+ {
+ /* DC highquant table 5 */
+ {0, 7}, {1, 7}, {2, 6}, {3, 6}, {4, 6}, {5, 6}, {6, 6}, {7, 6}, {8, 6}, {9, 6}, {10, 6}, {11, 6},
+ {12, 6}, {13, 6}, {14, 6}, {15, 6}, {16, 6}, {17, 6}, {18, 6}, {19, 6}, {20, 6}, {21, 6}, {22, 6}, {23, 6},
+ {24, 6}, {25, 6}, {26, 6}, {28, 6}, {29, 6}, {30, 6}, {31, 6}, {32, 6}, {33, 6}, {27, 1},
+ },
+ {
+ /* DC highquant table 6 */
+ {0, 5}, {2, 5}, {1, 4}, {3, 5}, {4, 6}, {6, 6}, {5, 5}, {7, 6}, {8, 8},
+ {9, 8}, {10, 13}, {11, 13}, {12, 13}, {13, 13}, {14, 13}, {15, 13}, {16, 13}, {25, 13},
+ {26, 13}, {27, 13}, {28, 13}, {29, 13}, {30, 13}, {31, 13}, {32, 13}, {33, 13}, {24, 9},
+ {23, 8}, {17, 2}, {18, 2}, {19, 3}, {20, 4}, {21, 5}, {22, 5},
+ },
+ {
+ /* DC highquant table 7 */
+ {0, 7}, {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7}, {7, 7}, {8, 7}, {9, 7}, {10, 7}, {11, 7},
+ {12, 7}, {13, 7}, {14, 7}, {15, 7}, {16, 7}, {19, 7}, {20, 7}, {21, 7}, {22, 7}, {23, 7}, {24, 7}, {25, 7},
+ {26, 7}, {27, 7}, {28, 7}, {29, 7}, {30, 7}, {31, 7}, {32, 7}, {33, 7}, {18, 2}, {17, 1},
+ },
+ },
+ {
+ {
+ /* DC lowquant table 0 */
+ {0, 5}, {2, 5}, {1, 4}, {3, 5}, {4, 5}, {5, 5}, {6, 6}, {7, 6}, {8, 8},
+ {9, 8}, {10, 13}, {11, 13}, {12, 13}, {13, 13}, {14, 13}, {15, 13}, {16, 13}, {25, 13},
+ {26, 13}, {27, 13}, {28, 13}, {29, 13}, {30, 13}, {31, 13}, {32, 13}, {33, 13}, {24, 9},
+ {23, 8}, {22, 6}, {21, 5}, {20, 4}, {19, 3}, {17, 2}, {18, 2},
+ },
+ {
+ /* DC lowquant table 1 */
+ {0, 4}, {3, 4}, {1, 3}, {2, 3}, {4, 4}, {6, 4}, {5, 3}, {7, 3}, {8, 4},
+ {9, 4}, {10, 5}, {11, 6}, {12, 9}, {13, 9}, {14, 13}, {15, 13}, {16, 13}, {25, 13},
+ {26, 13}, {27, 13}, {28, 12}, {29, 12}, {31, 12}, {32, 12}, {33, 12}, {21, 9}, {20, 7},
+ {17, 6}, {18, 6}, {19, 6}, {22, 7}, {23, 8}, {24, 9}, {30, 9},
+ },
+ {
+ /* DC lowquant table 2 */
+ {0, 4}, {3, 4}, {1, 3}, {2, 3}, {4, 4}, {5, 4}, {6, 4}, {7, 4}, {8, 6},
+ {9, 6}, {10, 7}, {11, 7}, {12, 12}, {13, 12}, {14, 12}, {15, 12}, {16, 12}, {25, 12},
+ {26, 12}, {27, 12}, {28, 12}, {29, 12}, {30, 12}, {31, 12}, {32, 11}, {33, 11}, {24, 8},
+ {23, 7}, {17, 4}, {18, 3}, {19, 4}, {20, 5}, {21, 6}, {22, 6},
+ },
+ {
+ /* DC lowquant table 3 */
+ {0, 4}, {6, 4}, {2, 3}, {1, 2}, {3, 3}, {4, 3}, {5, 3}, {7, 4}, {8, 6},
+ {9, 6}, {10, 7}, {11, 8}, {12, 14}, {13, 14}, {14, 14}, {15, 14}, {16, 13}, {21, 13},
+ {22, 13}, {23, 13}, {24, 13}, {25, 13}, {26, 13}, {27, 13}, {28, 13}, {29, 13}, {30, 13},
+ {31, 13}, {32, 13}, {33, 13}, {17, 9}, {18, 7}, {19, 8}, {20, 8},
+ },
+ {
+ /* DC lowquant table 4 */
+ {0, 7}, {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7}, {7, 7}, {8, 7}, {9, 7}, {10, 7}, {11, 7},
+ {12, 7}, {13, 7}, {14, 7}, {15, 7}, {16, 7}, {19, 7}, {20, 7}, {21, 7}, {22, 7}, {23, 7}, {24, 7}, {25, 7},
+ {26, 7}, {27, 7}, {28, 7}, {29, 7}, {30, 7}, {31, 7}, {32, 7}, {33, 7}, {18, 2}, {17, 1},
+ },
+ {
+ /* DC lowquant table 5 */
+ {0, 5}, {2, 5}, {1, 4}, {3, 6}, {4, 6}, {5, 6}, {6, 7}, {8, 7}, {7, 6},
+ {9, 6}, {10, 8}, {12, 8}, {11, 7}, {13, 13}, {14, 13}, {15, 13}, {16, 13}, {23, 13},
+ {24, 13}, {25, 13}, {26, 13}, {27, 13}, {28, 13}, {29, 13}, {30, 13}, {31, 13}, {32, 13},
+ {33, 12}, {22, 9}, {21, 8}, {20, 7}, {17, 3}, {19, 3}, {18, 1},
+ },
+ {
+ /* DC lowquant table 6 */
+ {0, 4}, {4, 4}, {2, 3}, {1, 2}, {3, 3}, {5, 4}, {6, 5}, {7, 6}, {8, 7},
+ {9, 7}, {10, 8}, {11, 14}, {12, 14}, {15, 14}, {16, 14}, {23, 14}, {24, 14}, {25, 14},
+ {26, 14}, {27, 14}, {28, 14}, {29, 14}, {30, 14}, {31, 14}, {32, 14}, {33, 13}, {13, 10},
+ {14, 9}, {21, 8}, {22, 8}, {20, 6}, {19, 5}, {17, 4}, {18, 3},
+ },
+ {
+ /* DC lowquant table 7 */
+ {0, 6}, {1, 6}, {2, 6}, {3, 7}, {4, 7}, {5, 6}, {6, 6}, {7, 6}, {8, 7},
+ {9, 8}, {10, 8}, {11, 9}, {12, 10}, {13, 14}, {14, 14}, {15, 14}, {16, 14}, {24, 14},
+ {25, 14}, {26, 14}, {27, 14}, {28, 14}, {29, 14}, {30, 14}, {31, 14}, {32, 13}, {33, 13},
+ {23, 8}, {22, 7}, {21, 6}, {20, 5}, {19, 4}, {18, 2}, {17, 1},
+ },
+ },
+};
+#define MAX_DC_VLC_BITS 14
+
+static const uint8 x8_ac_quant_table[2][2][8][77][2] = {
+ {
+ {
+ {
+ /* AC highquant table group 0, table 0 */
+ {0, 3}, {1, 4}, {2, 6}, {3, 6}, {4, 7}, {6, 15}, {8, 15}, {10, 15}, {12, 15}, {13, 15},
+ {14, 15}, {15, 14}, {34, 14}, {45, 14}, {46, 14}, {47, 14}, {49, 14}, {50, 14}, {51, 14}, {52, 14},
+ {53, 14}, {54, 14}, {55, 14}, {56, 14}, {57, 14}, {58, 14}, {60, 14}, {61, 14}, {62, 14}, {63, 14},
+ {64, 14}, {65, 14}, {67, 14}, {69, 14}, {70, 14}, {71, 14}, {72, 14}, {74, 14}, {75, 14}, {76, 14},
+ {9, 9}, {7, 8}, {5, 6}, {11, 9}, {18, 9}, {19, 9}, {22, 9}, {20, 7}, {17, 6}, {16, 5},
+ {21, 7}, {29, 8}, {33, 8}, {28, 6}, {27, 5}, {24, 3}, {23, 2}, {25, 4}, {26, 4}, {30, 7},
+ {32, 7}, {31, 6}, {35, 7}, {36, 7}, {37, 7}, {38, 9}, {41, 9}, {42, 8}, {39, 5}, {40, 6},
+ {43, 9}, {44, 9}, {48, 8}, {59, 9}, {66, 9}, {68, 9}, {73, 9},
+ },
+ {
+ /* AC highquant table group 0, table 1 */
+ {0, 3}, {1, 4}, {2, 4}, {3, 5}, {4, 6}, {5, 6}, {6, 6}, {7, 6}, {8, 7}, {9, 8},
+ {10, 8}, {11, 8}, {12, 8}, {13, 14}, {44, 14}, {47, 14}, {50, 14}, {51, 14}, {54, 14}, {55, 14},
+ {56, 14}, {63, 14}, {64, 14}, {67, 14}, {68, 14}, {69, 14}, {70, 14}, {72, 14}, {76, 14}, {14, 10},
+ {15, 10}, {45, 10}, {32, 8}, {16, 4}, {17, 5}, {18, 6}, {19, 7}, {31, 7}, {20, 5}, {21, 6},
+ {26, 6}, {22, 5}, {24, 5}, {23, 4}, {25, 5}, {27, 6}, {28, 6}, {29, 6}, {30, 6}, {33, 8},
+ {38, 8}, {34, 7}, {35, 7}, {36, 7}, {37, 7}, {39, 7}, {40, 7}, {41, 8}, {42, 8}, {43, 8},
+ {46, 9}, {49, 9}, {53, 8}, {58, 8}, {57, 6}, {48, 5}, {52, 5}, {59, 7}, {60, 8}, {61, 9},
+ {66, 9}, {62, 8}, {65, 8}, {71, 9}, {75, 9}, {74, 8}, {73, 5},
+ },
+ {
+ /* AC highquant table group 0, table 2 */
+ {0, 4}, {1, 5}, {2, 12}, {3, 12}, {4, 12}, {5, 12}, {6, 12}, {7, 12}, {8, 12}, {9, 12},
+ {10, 12}, {11, 12}, {12, 11}, {13, 11}, {14, 11}, {15, 11}, {16, 11}, {17, 11}, {18, 11}, {19, 11},
+ {20, 11}, {21, 11}, {22, 11}, {28, 11}, {29, 11}, {30, 11}, {31, 11}, {32, 11}, {33, 11}, {34, 11},
+ {35, 11}, {36, 11}, {37, 11}, {38, 11}, {40, 11}, {41, 11}, {42, 11}, {43, 11}, {44, 11}, {45, 11},
+ {46, 11}, {47, 11}, {48, 11}, {49, 11}, {50, 11}, {51, 11}, {52, 11}, {53, 11}, {54, 11}, {55, 11},
+ {56, 11}, {57, 11}, {58, 11}, {59, 11}, {60, 11}, {61, 11}, {62, 11}, {63, 11}, {64, 11}, {65, 11},
+ {66, 11}, {67, 11}, {68, 11}, {69, 11}, {70, 11}, {71, 11}, {72, 11}, {73, 11}, {74, 11}, {75, 11},
+ {76, 11}, {25, 5}, {26, 5}, {27, 5}, {39, 5}, {24, 2}, {23, 1},
+ },
+ {
+ /* AC highquant table group 0, table 3 */
+ {0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8},
+ {11, 8}, {12, 8}, {13, 8}, {14, 8}, {15, 8}, {16, 8}, {17, 8}, {18, 8}, {19, 8}, {20, 8}, {21, 8},
+ {22, 8}, {24, 8}, {25, 7}, {26, 7}, {27, 7}, {28, 7}, {29, 7}, {30, 7}, {31, 7}, {32, 7}, {33, 7},
+ {34, 7}, {35, 7}, {36, 7}, {37, 7}, {38, 7}, {39, 7}, {40, 7}, {41, 7}, {42, 7}, {43, 7}, {44, 7},
+ {45, 7}, {46, 7}, {47, 7}, {48, 7}, {49, 7}, {50, 7}, {51, 7}, {52, 7}, {53, 7}, {54, 7}, {55, 7},
+ {56, 7}, {57, 7}, {58, 7}, {59, 7}, {60, 7}, {61, 7}, {62, 7}, {63, 7}, {64, 7}, {65, 7}, {66, 7},
+ {67, 7}, {68, 7}, {69, 7}, {70, 7}, {71, 7}, {72, 7}, {73, 7}, {74, 7}, {75, 7}, {76, 7}, {23, 1},
+ },
+ {
+ /* AC highquant table group 0, table 4 */
+ {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9},
+ {11, 9}, {12, 9}, {13, 9}, {14, 9}, {15, 9}, {16, 9}, {17, 9}, {18, 9}, {19, 9}, {20, 9}, {21, 9},
+ {22, 8}, {25, 8}, {26, 8}, {27, 8}, {28, 8}, {29, 8}, {30, 8}, {31, 8}, {32, 8}, {33, 8}, {34, 8},
+ {35, 8}, {36, 8}, {37, 8}, {38, 8}, {39, 8}, {40, 8}, {41, 8}, {42, 8}, {43, 8}, {44, 8}, {45, 8},
+ {46, 8}, {47, 8}, {48, 8}, {49, 8}, {50, 8}, {51, 8}, {52, 8}, {53, 8}, {54, 8}, {55, 8}, {56, 8},
+ {57, 8}, {58, 8}, {59, 8}, {60, 8}, {61, 8}, {62, 8}, {63, 8}, {64, 8}, {65, 8}, {66, 8}, {67, 8},
+ {68, 8}, {69, 8}, {70, 8}, {71, 8}, {72, 8}, {73, 8}, {74, 8}, {75, 8}, {76, 8}, {23, 2}, {24, 1},
+ },
+ {
+ /* AC highquant table group 0, table 5 */
+ {0, 10}, {1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}, {6, 10}, {7, 10}, {8, 10}, {9, 10},
+ {10, 10}, {11, 10}, {12, 10}, {13, 10}, {14, 10}, {15, 10}, {16, 10}, {17, 10}, {18, 10}, {19, 10},
+ {20, 9}, {21, 9}, {22, 9}, {25, 9}, {26, 9}, {28, 9}, {29, 9}, {30, 9}, {31, 9}, {32, 9},
+ {33, 9}, {34, 9}, {35, 9}, {36, 9}, {37, 9}, {38, 9}, {39, 9}, {40, 9}, {41, 9}, {42, 9},
+ {43, 9}, {44, 9}, {45, 9}, {46, 9}, {47, 9}, {48, 9}, {49, 9}, {50, 9}, {51, 9}, {52, 9},
+ {53, 9}, {54, 9}, {55, 9}, {56, 9}, {57, 9}, {58, 9}, {59, 9}, {60, 9}, {61, 9}, {62, 9},
+ {63, 9}, {64, 9}, {65, 9}, {66, 9}, {67, 9}, {68, 9}, {69, 9}, {70, 9}, {71, 9}, {72, 9},
+ {73, 9}, {74, 9}, {75, 9}, {76, 9}, {24, 3}, {27, 2}, {23, 1},
+ },
+ {
+ /* AC highquant table group 0, table 6 */
+ {0, 2}, {1, 4}, {2, 5}, {3, 5}, {4, 6}, {5, 6}, {6, 7}, {7, 8}, {8, 8}, {9, 8},
+ {10, 9}, {11, 9}, {12, 10}, {14, 10}, {13, 9}, {15, 15}, {42, 15}, {46, 15}, {50, 15}, {51, 15},
+ {55, 15}, {56, 14}, {59, 14}, {61, 14}, {62, 14}, {63, 14}, {64, 14}, {68, 14}, {69, 14}, {70, 14},
+ {71, 14}, {72, 14}, {75, 14}, {76, 14}, {43, 10}, {37, 9}, {17, 5}, {18, 6}, {19, 6}, {16, 3},
+ {20, 4}, {21, 7}, {24, 7}, {25, 7}, {26, 7}, {22, 5}, {23, 5}, {27, 8}, {30, 8}, {28, 7},
+ {29, 7}, {31, 8}, {32, 8}, {33, 8}, {34, 8}, {35, 8}, {36, 8}, {38, 8}, {39, 8}, {40, 8},
+ {41, 9}, {44, 10}, {45, 10}, {47, 10}, {54, 10}, {49, 9}, {58, 8}, {60, 10}, {66, 10}, {67, 10},
+ {74, 10}, {65, 8}, {48, 6}, {52, 4}, {53, 6}, {57, 6}, {73, 5},
+ },
+ {
+ /* AC highquant table group 0, table 7 */
+ {0, 3}, {1, 4}, {2, 5}, {3, 5}, {4, 6}, {5, 8}, {9, 13}, {12, 13}, {13, 13}, {14, 13},
+ {42, 13}, {45, 13}, {46, 13}, {47, 13}, {50, 13}, {51, 13}, {53, 13}, {54, 13}, {55, 13}, {56, 13},
+ {58, 13}, {61, 13}, {62, 13}, {63, 13}, {64, 13}, {66, 13}, {67, 13}, {68, 13}, {69, 13}, {70, 13},
+ {72, 12}, {74, 12}, {75, 12}, {76, 12}, {6, 7}, {7, 6}, {8, 7}, {10, 8}, {11, 8}, {15, 8},
+ {31, 8}, {18, 7}, {19, 6}, {17, 5}, {16, 4}, {20, 6}, {21, 7}, {36, 8}, {37, 8}, {22, 6},
+ {27, 6}, {23, 3}, {24, 5}, {25, 5}, {26, 4}, {28, 6}, {29, 6}, {30, 5}, {32, 6}, {33, 6},
+ {34, 6}, {35, 6}, {38, 7}, {40, 7}, {41, 7}, {43, 7}, {39, 5}, {44, 8}, {52, 8}, {48, 7},
+ {49, 7}, {57, 8}, {60, 8}, {59, 7}, {65, 8}, {71, 8}, {73, 6},
+ },
+ },
+ {
+ {
+ /* AC highquant table group 1, table 0 */
+ {0, 3}, {1, 4}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 6}, {7, 7}, {9, 7}, {8, 6},
+ {10, 8}, {13, 8}, {11, 7}, {12, 7}, {14, 8}, {15, 9}, {41, 9}, {17, 6}, {18, 6}, {19, 7},
+ {21, 8}, {42, 9}, {43, 9}, {16, 4}, {20, 5}, {22, 6}, {26, 6}, {23, 4}, {24, 4}, {25, 5},
+ {27, 6}, {28, 6}, {29, 6}, {30, 7}, {31, 7}, {32, 7}, {33, 7}, {34, 7}, {35, 7}, {36, 7},
+ {37, 7}, {38, 7}, {39, 7}, {40, 7}, {44, 11}, {54, 14}, {55, 14}, {56, 14}, {64, 14}, {69, 14},
+ {70, 14}, {72, 14}, {76, 14}, {53, 10}, {45, 9}, {47, 8}, {46, 6}, {48, 5}, {49, 7}, {50, 9},
+ {51, 9}, {58, 10}, {67, 10}, {61, 9}, {52, 7}, {57, 7}, {59, 7}, {60, 8}, {62, 8}, {63, 7},
+ {65, 7}, {66, 7}, {68, 10}, {71, 10}, {74, 9}, {75, 8}, {73, 6},
+ },
+ {
+ /* AC highquant table group 1, table 1 */
+ {0, 2}, {1, 4}, {2, 5}, {3, 5}, {4, 6}, {5, 7}, {6, 7}, {7, 7}, {8, 8}, {9, 9},
+ {10, 9}, {11, 9}, {12, 9}, {13, 15}, {42, 15}, {44, 15}, {45, 15}, {46, 15}, {47, 15}, {50, 15},
+ {51, 15}, {56, 15}, {61, 15}, {62, 15}, {63, 15}, {64, 15}, {66, 15}, {67, 14}, {15, 11}, {14, 10},
+ {30, 9}, {19, 7}, {17, 5}, {18, 6}, {23, 6}, {16, 3}, {20, 4}, {21, 5}, {24, 7}, {25, 7},
+ {26, 8}, {27, 8}, {28, 7}, {22, 4}, {29, 8}, {31, 8}, {32, 9}, {33, 9}, {34, 9}, {35, 9},
+ {36, 10}, {37, 11}, {38, 11}, {39, 9}, {40, 9}, {41, 11}, {55, 11}, {43, 10}, {49, 8}, {54, 8},
+ {48, 6}, {53, 7}, {58, 8}, {59, 11}, {68, 14}, {69, 14}, {70, 14}, {71, 14}, {72, 14}, {74, 14},
+ {75, 14}, {76, 14}, {60, 10}, {65, 9}, {52, 4}, {57, 5}, {73, 5},
+ },
+ {
+ /* AC highquant table group 1, table 2 */
+ {0, 3}, {1, 4}, {2, 4}, {3, 5}, {4, 6}, {5, 7}, {7, 7}, {6, 6}, {8, 9}, {9, 9},
+ {10, 8}, {11, 15}, {13, 15}, {14, 15}, {15, 15}, {46, 15}, {47, 15}, {50, 15}, {51, 15}, {54, 14},
+ {55, 14}, {56, 14}, {62, 14}, {63, 14}, {64, 14}, {66, 14}, {67, 14}, {69, 14}, {70, 14}, {72, 14},
+ {76, 14}, {34, 10}, {12, 9}, {31, 8}, {17, 5}, {16, 3}, {18, 7}, {19, 7}, {21, 6}, {22, 5},
+ {20, 4}, {23, 4}, {24, 4}, {25, 5}, {26, 6}, {27, 6}, {28, 6}, {29, 6}, {30, 7}, {32, 7},
+ {33, 8}, {35, 8}, {36, 9}, {37, 10}, {38, 10}, {41, 9}, {42, 9}, {39, 6}, {40, 7}, {43, 8},
+ {44, 10}, {60, 10}, {45, 9}, {48, 7}, {49, 9}, {58, 9}, {53, 8}, {57, 6}, {52, 5}, {59, 9},
+ {61, 10}, {68, 10}, {65, 8}, {71, 9}, {75, 9}, {74, 8}, {73, 6},
+ },
+ {
+ /* AC highquant table group 1, table 3 */
+ {0, 3}, {1, 4}, {2, 5}, {3, 5}, {4, 6}, {5, 6}, {6, 7}, {7, 7}, {8, 6}, {9, 6},
+ {10, 7}, {11, 7}, {12, 9}, {13, 9}, {15, 8}, {14, 7}, {17, 6}, {16, 5}, {18, 9}, {42, 9},
+ {32, 8}, {19, 7}, {20, 6}, {21, 7}, {22, 7}, {27, 6}, {25, 5}, {23, 3}, {24, 3}, {26, 5},
+ {28, 6}, {29, 6}, {30, 7}, {31, 7}, {33, 8}, {34, 8}, {35, 8}, {41, 8}, {36, 7}, {38, 7},
+ {37, 6}, {39, 7}, {43, 14}, {44, 14}, {45, 14}, {50, 14}, {51, 14}, {53, 14}, {54, 13}, {55, 13},
+ {56, 13}, {58, 13}, {64, 13}, {67, 13}, {68, 13}, {69, 13}, {70, 13}, {71, 13}, {72, 13}, {74, 13},
+ {76, 13}, {47, 9}, {49, 8}, {40, 6}, {46, 7}, {48, 7}, {52, 8}, {57, 8}, {60, 7}, {59, 6},
+ {61, 9}, {75, 9}, {73, 8}, {63, 7}, {62, 6}, {65, 7}, {66, 7},
+ },
+ {
+ /* AC highquant table group 1, table 4 */
+ {0, 2}, {1, 4}, {2, 5}, {3, 5}, {4, 6}, {5, 6}, {6, 7}, {7, 7}, {8, 7}, {9, 8},
+ {10, 9}, {11, 9}, {12, 10}, {13, 10}, {14, 10}, {15, 15}, {50, 15}, {51, 15}, {54, 15}, {55, 15},
+ {56, 15}, {61, 15}, {64, 15}, {45, 12}, {47, 12}, {58, 12}, {32, 8}, {19, 7}, {18, 6}, {17, 5},
+ {16, 3}, {20, 4}, {21, 6}, {22, 6}, {24, 5}, {23, 4}, {25, 6}, {26, 6}, {27, 6}, {28, 7},
+ {29, 7}, {30, 7}, {31, 7}, {33, 8}, {34, 8}, {35, 8}, {36, 8}, {37, 8}, {38, 10}, {43, 10},
+ {41, 9}, {39, 7}, {40, 8}, {42, 9}, {44, 10}, {46, 10}, {49, 8}, {53, 9}, {59, 10}, {60, 10},
+ {48, 6}, {52, 6}, {57, 7}, {62, 12}, {67, 15}, {69, 15}, {70, 15}, {71, 15}, {72, 14}, {76, 14},
+ {63, 11}, {68, 12}, {74, 12}, {75, 11}, {66, 9}, {65, 8}, {73, 6},
+ },
+ {
+ /* AC highquant table group 1, table 5 */
+ {0, 3}, {1, 4}, {2, 4}, {3, 5}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 11}, {10, 11},
+ {11, 10}, {9, 9}, {12, 11}, {13, 15}, {14, 15}, {15, 15}, {47, 15}, {49, 15}, {50, 15}, {51, 15},
+ {54, 15}, {55, 14}, {56, 14}, {58, 14}, {63, 14}, {38, 11}, {53, 11}, {37, 9}, {32, 8}, {19, 7},
+ {18, 6}, {16, 4}, {17, 5}, {20, 5}, {21, 7}, {31, 7}, {22, 6}, {25, 5}, {24, 4}, {23, 3},
+ {26, 5}, {27, 5}, {28, 5}, {29, 6}, {30, 6}, {33, 8}, {34, 8}, {35, 7}, {36, 8}, {41, 8},
+ {40, 7}, {39, 5}, {42, 8}, {44, 10}, {60, 10}, {45, 9}, {43, 7}, {46, 9}, {59, 9}, {61, 10},
+ {64, 14}, {67, 14}, {68, 14}, {69, 14}, {70, 14}, {72, 14}, {75, 14}, {76, 14}, {66, 11}, {62, 9},
+ {48, 7}, {52, 7}, {57, 7}, {65, 8}, {71, 9}, {74, 9}, {73, 7},
+ },
+ {
+ /* AC highquant table group 1, table 6 */
+ {0, 3}, {1, 4}, {2, 4}, {3, 5}, {4, 5}, {5, 5}, {6, 5}, {7, 6}, {8, 7}, {10, 7},
+ {9, 5}, {11, 13}, {13, 13}, {15, 13}, {29, 13}, {32, 13}, {33, 13}, {34, 12}, {37, 12}, {38, 12},
+ {40, 12}, {41, 12}, {42, 12}, {43, 12}, {44, 12}, {45, 12}, {50, 12}, {53, 12}, {54, 12}, {55, 12},
+ {56, 12}, {58, 12}, {60, 12}, {61, 12}, {62, 12}, {63, 12}, {64, 12}, {66, 12}, {67, 12}, {68, 12},
+ {69, 12}, {70, 12}, {71, 12}, {72, 12}, {74, 12}, {76, 12}, {12, 7}, {14, 7}, {18, 7}, {17, 6},
+ {19, 7}, {21, 7}, {16, 4}, {20, 5}, {22, 5}, {23, 6}, {24, 6}, {25, 7}, {27, 7}, {26, 6},
+ {28, 7}, {30, 7}, {31, 7}, {35, 7}, {36, 7}, {39, 7}, {47, 6}, {46, 5}, {49, 5}, {48, 4},
+ {51, 7}, {75, 7}, {57, 6}, {52, 5}, {59, 6}, {65, 6}, {73, 5},
+ },
+ {
+ /* AC highquant table group 1, table 7 */
+ {0, 3}, {1, 4}, {2, 5}, {3, 6}, {4, 6}, {5, 8}, {6, 8}, {7, 8}, {8, 11}, {9, 15},
+ {10, 15}, {11, 15}, {12, 15}, {13, 15}, {14, 15}, {15, 15}, {38, 15}, {46, 15}, {47, 15}, {50, 15},
+ {51, 15}, {53, 15}, {54, 15}, {55, 15}, {56, 15}, {37, 11}, {58, 15}, {61, 15}, {62, 15}, {63, 15},
+ {64, 15}, {66, 15}, {67, 15}, {68, 15}, {69, 15}, {70, 15}, {72, 14}, {75, 14}, {76, 14}, {19, 9},
+ {17, 6}, {18, 7}, {21, 8}, {22, 8}, {28, 6}, {16, 4}, {20, 5}, {25, 5}, {26, 5}, {27, 5},
+ {23, 2}, {24, 3}, {29, 6}, {30, 8}, {31, 8}, {32, 9}, {36, 9}, {33, 8}, {34, 7}, {35, 8},
+ {41, 8}, {40, 7}, {42, 9}, {44, 9}, {43, 8}, {39, 5}, {45, 9}, {49, 10}, {71, 10}, {48, 8},
+ {52, 8}, {57, 9}, {60, 9}, {59, 8}, {65, 9}, {74, 9}, {73, 7},
+ },
+ },
+ },
+ {
+ {
+ {
+ /* AC lowquant table group 0, table 0 */
+ {0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}, {5, 7}, {6, 7}, {7, 7}, {8, 9}, {12, 10},
+ {13, 10}, {9, 8}, {10, 8}, {11, 8}, {14, 10}, {15, 10}, {18, 9}, {19, 10}, {41, 10}, {40, 9},
+ {17, 7}, {21, 7}, {20, 6}, {16, 4}, {22, 7}, {32, 7}, {28, 6}, {25, 5}, {23, 4}, {24, 4},
+ {26, 5}, {27, 5}, {29, 6}, {30, 6}, {31, 6}, {33, 7}, {34, 7}, {35, 7}, {36, 7}, {37, 7},
+ {38, 7}, {39, 8}, {42, 14}, {43, 14}, {44, 14}, {45, 14}, {47, 14}, {49, 14}, {50, 14}, {51, 14},
+ {53, 14}, {54, 14}, {55, 14}, {56, 14}, {58, 14}, {63, 14}, {64, 14}, {65, 14}, {46, 10}, {48, 9},
+ {52, 8}, {57, 10}, {66, 14}, {67, 14}, {68, 14}, {69, 14}, {70, 14}, {71, 14}, {72, 13}, {73, 13},
+ {74, 13}, {75, 13}, {76, 13}, {62, 9}, {59, 7}, {60, 8}, {61, 8},
+ },
+ {
+ /* AC lowquant table group 0, table 1 */
+ {0, 3}, {1, 5}, {2, 7}, {5, 8}, {6, 8}, {3, 6}, {4, 6}, {7, 8}, {8, 14}, {9, 14},
+ {11, 14}, {12, 14}, {13, 14}, {14, 14}, {15, 14}, {18, 14}, {20, 14}, {21, 14}, {22, 14}, {41, 14},
+ {45, 14}, {46, 14}, {47, 14}, {49, 14}, {50, 14}, {51, 14}, {52, 13}, {53, 13}, {54, 13}, {55, 13},
+ {56, 13}, {57, 13}, {58, 13}, {60, 13}, {61, 13}, {62, 13}, {63, 13}, {64, 13}, {66, 13}, {67, 13},
+ {68, 13}, {69, 13}, {70, 13}, {71, 13}, {72, 13}, {73, 13}, {74, 13}, {75, 13}, {76, 13}, {10, 7},
+ {16, 6}, {17, 8}, {19, 8}, {30, 7}, {23, 2}, {24, 3}, {25, 5}, {29, 6}, {31, 7}, {32, 7},
+ {26, 4}, {27, 4}, {28, 4}, {33, 7}, {34, 8}, {40, 8}, {35, 7}, {42, 8}, {43, 8}, {36, 6},
+ {37, 6}, {38, 6}, {39, 6}, {44, 8}, {48, 8}, {65, 7}, {59, 6},
+ },
+ {
+ /* AC lowquant table group 0, table 2 */
+ {0, 2}, {1, 3}, {2, 3}, {3, 4}, {4, 5}, {5, 5}, {6, 6}, {7, 6}, {8, 7}, {9, 7},
+ {10, 7}, {11, 8}, {12, 8}, {13, 8}, {14, 9}, {15, 10}, {39, 16}, {40, 16}, {41, 15}, {43, 15},
+ {44, 15}, {45, 15}, {50, 15}, {51, 15}, {53, 15}, {42, 12}, {49, 12}, {54, 15}, {55, 15}, {56, 15},
+ {58, 15}, {64, 15}, {65, 15}, {66, 15}, {67, 15}, {18, 8}, {19, 9}, {21, 9}, {17, 6}, {20, 6},
+ {22, 8}, {38, 8}, {27, 7}, {16, 4}, {23, 5}, {24, 6}, {25, 6}, {26, 6}, {28, 7}, {29, 7},
+ {30, 7}, {31, 7}, {32, 7}, {33, 7}, {34, 7}, {35, 7}, {36, 7}, {37, 7}, {46, 8}, {47, 10},
+ {62, 11}, {63, 12}, {68, 15}, {69, 15}, {70, 15}, {71, 15}, {72, 15}, {74, 15}, {75, 15}, {76, 15},
+ {48, 9}, {52, 8}, {57, 9}, {73, 9}, {59, 7}, {60, 8}, {61, 8},
+ },
+ {
+ /* AC lowquant table group 0, table 3 */
+ {0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 5}, {5, 6}, {6, 6}, {7, 7}, {8, 7}, {9, 8},
+ {10, 8}, {11, 9}, {12, 9}, {13, 9}, {14, 10}, {15, 10}, {17, 5}, {18, 7}, {19, 7}, {21, 7},
+ {24, 7}, {16, 3}, {20, 4}, {22, 5}, {23, 6}, {25, 7}, {26, 7}, {27, 8}, {28, 8}, {29, 8},
+ {30, 8}, {31, 8}, {32, 8}, {33, 9}, {37, 9}, {34, 8}, {35, 8}, {36, 8}, {38, 11}, {40, 11},
+ {39, 10}, {41, 15}, {43, 15}, {44, 15}, {45, 15}, {50, 15}, {51, 15}, {64, 15}, {66, 15}, {49, 12},
+ {47, 11}, {42, 10}, {46, 9}, {55, 10}, {56, 11}, {63, 12}, {67, 15}, {68, 15}, {69, 15}, {70, 15},
+ {71, 15}, {72, 15}, {74, 14}, {48, 7}, {53, 7}, {52, 5}, {54, 8}, {58, 10}, {61, 10}, {62, 10},
+ {65, 11}, {75, 12}, {76, 12}, {57, 7}, {59, 8}, {60, 8}, {73, 7},
+ },
+ {
+ /* AC lowquant table group 0, table 4 */
+ {0, 3}, {1, 4}, {2, 4}, {3, 5}, {4, 6}, {5, 6}, {6, 6}, {7, 7}, {9, 7}, {8, 6},
+ {10, 8}, {11, 8}, {12, 8}, {13, 9}, {14, 9}, {15, 8}, {37, 8}, {31, 7}, {18, 6}, {17, 5},
+ {16, 4}, {19, 6}, {21, 6}, {22, 5}, {20, 4}, {23, 5}, {24, 6}, {25, 6}, {26, 6}, {27, 6},
+ {28, 6}, {29, 6}, {30, 6}, {32, 7}, {33, 7}, {34, 7}, {35, 7}, {36, 7}, {38, 11}, {50, 15},
+ {51, 15}, {55, 15}, {56, 15}, {64, 15}, {69, 15}, {70, 14}, {71, 14}, {72, 14}, {75, 14}, {76, 14},
+ {45, 10}, {42, 9}, {41, 8}, {39, 7}, {40, 7}, {43, 9}, {44, 9}, {46, 9}, {47, 10}, {58, 10},
+ {49, 8}, {54, 9}, {62, 10}, {66, 10}, {48, 6}, {53, 7}, {59, 7}, {52, 4}, {57, 6}, {60, 8},
+ {61, 8}, {63, 9}, {65, 9}, {67, 10}, {68, 10}, {74, 9}, {73, 5},
+ },
+ {
+ /* AC lowquant table group 0, table 5 */
+ {0, 2}, {1, 4}, {2, 5}, {3, 5}, {4, 6}, {5, 6}, {6, 7}, {7, 8}, {8, 8}, {9, 8},
+ {10, 9}, {11, 11}, {14, 11}, {13, 10}, {12, 8}, {15, 15}, {42, 15}, {50, 15}, {51, 15}, {62, 15},
+ {64, 15}, {67, 15}, {68, 15}, {69, 14}, {70, 14}, {71, 14}, {72, 14}, {38, 11}, {40, 10}, {33, 9},
+ {17, 5}, {18, 6}, {19, 7}, {24, 7}, {16, 3}, {20, 4}, {21, 6}, {23, 6}, {22, 5}, {25, 8},
+ {27, 8}, {26, 7}, {28, 7}, {29, 8}, {31, 8}, {30, 7}, {32, 8}, {34, 9}, {35, 9}, {36, 9},
+ {37, 9}, {39, 9}, {41, 11}, {44, 11}, {43, 10}, {45, 11}, {47, 11}, {46, 10}, {56, 9}, {49, 8},
+ {48, 6}, {54, 7}, {55, 7}, {53, 5}, {52, 4}, {57, 6}, {58, 8}, {59, 8}, {60, 10}, {61, 11},
+ {75, 11}, {63, 10}, {65, 10}, {66, 10}, {74, 10}, {76, 9}, {73, 5},
+ },
+ {
+ /* AC lowquant table group 0, table 6 */
+ {0, 2}, {1, 4}, {2, 5}, {3, 6}, {4, 6}, {5, 8}, {6, 9}, {7, 10}, {8, 10}, {9, 9},
+ {10, 15}, {11, 15}, {13, 15}, {15, 15}, {37, 15}, {46, 15}, {47, 15}, {49, 15}, {50, 15}, {51, 15},
+ {53, 15}, {54, 15}, {55, 15}, {56, 15}, {58, 15}, {60, 15}, {61, 15}, {62, 15}, {63, 15}, {64, 15},
+ {67, 15}, {68, 15}, {69, 15}, {70, 15}, {71, 15}, {72, 15}, {74, 14}, {75, 14}, {76, 14}, {12, 10},
+ {14, 10}, {36, 10}, {21, 9}, {18, 8}, {19, 8}, {22, 8}, {32, 8}, {17, 5}, {16, 4}, {20, 5},
+ {26, 5}, {25, 4}, {23, 3}, {24, 3}, {27, 6}, {28, 6}, {29, 7}, {30, 7}, {31, 7}, {33, 8},
+ {34, 9}, {38, 9}, {35, 8}, {41, 9}, {42, 10}, {45, 10}, {43, 8}, {44, 8}, {39, 6}, {40, 6},
+ {48, 9}, {57, 9}, {52, 8}, {59, 9}, {65, 10}, {66, 10}, {73, 8},
+ },
+ {
+ /* AC lowquant table group 0, table 7 */
+ {0, 4}, {1, 11}, {2, 11}, {3, 11}, {4, 11}, {5, 11}, {6, 11}, {7, 11}, {8, 11}, {9, 11},
+ {10, 11}, {11, 11}, {12, 11}, {13, 11}, {14, 11}, {15, 11}, {16, 11}, {17, 10}, {18, 10}, {19, 10},
+ {20, 10}, {21, 10}, {22, 10}, {25, 10}, {28, 10}, {29, 10}, {30, 10}, {31, 10}, {32, 10}, {33, 10},
+ {34, 10}, {35, 10}, {36, 10}, {37, 10}, {38, 10}, {39, 10}, {40, 10}, {41, 10}, {42, 10}, {43, 10},
+ {44, 10}, {45, 10}, {46, 10}, {47, 10}, {48, 10}, {49, 10}, {50, 10}, {51, 10}, {52, 10}, {53, 10},
+ {54, 10}, {55, 10}, {56, 10}, {57, 10}, {58, 10}, {59, 10}, {60, 10}, {61, 10}, {62, 10}, {63, 10},
+ {64, 10}, {65, 10}, {66, 10}, {67, 10}, {68, 10}, {69, 10}, {70, 10}, {71, 10}, {72, 10}, {73, 10},
+ {74, 10}, {75, 10}, {76, 10}, {26, 4}, {27, 4}, {24, 2}, {23, 1},
+ },
+ },
+ {
+ {
+ /* AC lowquant table group 1, table 0 */
+ {0, 3}, {1, 4}, {2, 4}, {3, 5}, {4, 6}, {5, 7}, {7, 8}, {8, 8}, {6, 6}, {9, 9},
+ {10, 10}, {14, 15}, {47, 15}, {49, 14}, {50, 14}, {51, 14}, {54, 14}, {55, 14}, {56, 14}, {58, 14},
+ {15, 11}, {11, 9}, {12, 9}, {13, 9}, {37, 9}, {32, 8}, {17, 5}, {16, 4}, {18, 6}, {19, 7},
+ {21, 7}, {20, 5}, {22, 5}, {25, 5}, {24, 4}, {23, 3}, {26, 5}, {27, 5}, {28, 5}, {29, 6},
+ {30, 6}, {31, 7}, {33, 8}, {34, 8}, {35, 8}, {36, 8}, {38, 10}, {44, 11}, {46, 11}, {45, 10},
+ {53, 10}, {41, 8}, {39, 6}, {40, 7}, {42, 8}, {43, 8}, {48, 7}, {57, 7}, {52, 6}, {59, 8},
+ {60, 9}, {61, 11}, {63, 11}, {62, 10}, {64, 14}, {67, 14}, {68, 14}, {69, 14}, {70, 14}, {71, 14},
+ {72, 14}, {76, 14}, {75, 11}, {66, 10}, {74, 9}, {65, 8}, {73, 6},
+ },
+ {
+ /* AC lowquant table group 1, table 1 */
+ {0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}, {5, 6}, {6, 7}, {7, 8}, {8, 8}, {9, 8},
+ {10, 9}, {11, 9}, {12, 11}, {13, 11}, {14, 11}, {15, 11}, {24, 9}, {23, 8}, {17, 5}, {18, 6},
+ {19, 7}, {25, 10}, {27, 10}, {26, 9}, {28, 10}, {29, 12}, {35, 12}, {34, 11}, {30, 10}, {31, 10},
+ {21, 6}, {32, 10}, {33, 10}, {36, 10}, {37, 12}, {38, 12}, {39, 15}, {40, 15}, {41, 15}, {42, 15},
+ {43, 14}, {44, 14}, {45, 14}, {51, 14}, {61, 14}, {64, 14}, {46, 11}, {47, 11}, {49, 10}, {50, 12},
+ {63, 12}, {59, 11}, {56, 10}, {48, 8}, {55, 8}, {16, 3}, {20, 4}, {22, 4}, {52, 4}, {53, 6},
+ {54, 7}, {58, 8}, {60, 10}, {62, 11}, {65, 14}, {66, 14}, {67, 14}, {68, 14}, {69, 14}, {70, 14},
+ {71, 14}, {72, 14}, {74, 11}, {75, 11}, {76, 10}, {57, 6}, {73, 6},
+ },
+ {
+ /* AC lowquant table group 1, table 2 */
+ {0, 3}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {5, 8}, {6, 8}, {7, 8}, {8, 10}, {10, 10},
+ {9, 9}, {11, 10}, {12, 16}, {15, 16}, {38, 16}, {44, 16}, {46, 15}, {47, 15}, {50, 15}, {51, 15},
+ {59, 15}, {60, 15}, {61, 15}, {62, 15}, {64, 15}, {68, 15}, {69, 15}, {70, 15}, {71, 15}, {72, 15},
+ {37, 11}, {13, 10}, {14, 10}, {19, 8}, {18, 6}, {17, 5}, {21, 5}, {23, 7}, {24, 9}, {25, 9},
+ {26, 9}, {27, 9}, {28, 9}, {29, 10}, {30, 10}, {31, 10}, {32, 10}, {33, 10}, {34, 10}, {35, 9},
+ {36, 10}, {39, 10}, {40, 11}, {42, 11}, {41, 10}, {43, 10}, {45, 11}, {63, 11}, {16, 3}, {20, 3},
+ {22, 4}, {48, 7}, {49, 9}, {65, 11}, {66, 11}, {67, 11}, {74, 11}, {56, 8}, {54, 6}, {55, 6},
+ {58, 7}, {75, 8}, {76, 8}, {52, 3}, {53, 4}, {57, 5}, {73, 5},
+ },
+ {
+ /* AC lowquant table group 1, table 3 */
+ {0, 2}, {1, 3}, {2, 4}, {3, 4}, {4, 5}, {5, 5}, {6, 6}, {7, 6}, {8, 6}, {9, 6},
+ {10, 7}, {11, 7}, {12, 8}, {13, 8}, {14, 8}, {15, 9}, {19, 9}, {17, 6}, {18, 7}, {21, 8},
+ {36, 8}, {16, 4}, {20, 6}, {22, 7}, {28, 7}, {23, 6}, {24, 6}, {25, 6}, {26, 6}, {27, 6},
+ {29, 7}, {30, 7}, {31, 7}, {32, 7}, {33, 7}, {34, 7}, {35, 7}, {37, 8}, {38, 9}, {39, 11},
+ {41, 15}, {42, 15}, {43, 15}, {44, 15}, {45, 15}, {51, 15}, {54, 15}, {55, 15}, {49, 12}, {40, 10},
+ {46, 7}, {47, 8}, {48, 8}, {50, 9}, {53, 9}, {56, 15}, {67, 15}, {68, 15}, {69, 15}, {70, 14},
+ {71, 14}, {72, 14}, {74, 14}, {75, 14}, {76, 14}, {58, 11}, {65, 11}, {66, 11}, {64, 9}, {52, 7},
+ {57, 8}, {61, 8}, {60, 7}, {59, 6}, {62, 8}, {73, 8}, {63, 7},
+ },
+ {
+ /* AC lowquant table group 1, table 4 */
+ {0, 2}, {1, 4}, {2, 5}, {3, 6}, {4, 6}, {5, 7}, {6, 7}, {7, 8}, {8, 8}, {9, 8},
+ {10, 9}, {11, 9}, {12, 10}, {13, 10}, {14, 14}, {69, 14}, {70, 14}, {72, 14}, {15, 12}, {44, 11},
+ {37, 10}, {29, 8}, {19, 7}, {18, 6}, {17, 5}, {21, 6}, {24, 6}, {16, 3}, {20, 4}, {22, 5},
+ {23, 5}, {25, 6}, {26, 6}, {27, 7}, {28, 7}, {30, 7}, {31, 8}, {32, 8}, {33, 8}, {34, 8},
+ {35, 8}, {36, 9}, {38, 10}, {43, 10}, {39, 7}, {40, 8}, {41, 9}, {42, 9}, {45, 9}, {46, 9},
+ {47, 10}, {50, 12}, {51, 12}, {62, 11}, {56, 9}, {48, 7}, {49, 8}, {54, 8}, {55, 8}, {58, 8},
+ {52, 4}, {53, 6}, {57, 6}, {59, 9}, {60, 10}, {61, 10}, {63, 10}, {64, 11}, {67, 11}, {65, 9},
+ {66, 9}, {68, 11}, {71, 11}, {76, 10}, {74, 9}, {75, 9}, {73, 6},
+ },
+ {
+ /* AC lowquant table group 1, table 5 */
+ {0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 5}, {5, 6}, {6, 6}, {7, 7}, {8, 7}, {9, 7},
+ {10, 8}, {11, 8}, {12, 8}, {13, 9}, {14, 10}, {39, 11}, {40, 12}, {41, 12}, {15, 9}, {37, 9},
+ {19, 8}, {18, 7}, {21, 7}, {17, 5}, {16, 3}, {20, 5}, {22, 6}, {24, 6}, {23, 5}, {25, 7},
+ {26, 7}, {27, 7}, {28, 8}, {29, 8}, {30, 7}, {31, 8}, {32, 8}, {33, 8}, {34, 8}, {35, 8},
+ {36, 8}, {38, 9}, {42, 15}, {44, 15}, {45, 15}, {56, 15}, {43, 13}, {51, 13}, {66, 13}, {58, 11},
+ {49, 10}, {46, 8}, {47, 9}, {50, 9}, {48, 8}, {53, 7}, {54, 9}, {55, 9}, {59, 8}, {52, 5},
+ {57, 7}, {60, 8}, {61, 8}, {62, 9}, {64, 11}, {65, 12}, {67, 15}, {68, 15}, {69, 15}, {70, 15},
+ {71, 15}, {72, 15}, {74, 14}, {75, 11}, {76, 11}, {63, 8}, {73, 7},
+ },
+ {
+ /* AC lowquant table group 1, table 6 */
+ {0, 3}, {1, 4}, {2, 4}, {3, 5}, {4, 5}, {5, 6}, {6, 6}, {7, 7}, {8, 8}, {9, 8},
+ {10, 8}, {11, 9}, {12, 9}, {13, 9}, {14, 11}, {15, 12}, {45, 12}, {38, 10}, {33, 8}, {16, 3},
+ {17, 5}, {18, 6}, {19, 7}, {27, 7}, {20, 4}, {21, 6}, {25, 6}, {22, 5}, {23, 4}, {24, 5},
+ {26, 6}, {28, 7}, {29, 7}, {30, 7}, {31, 7}, {32, 7}, {34, 8}, {35, 8}, {36, 9}, {41, 9},
+ {37, 8}, {39, 7}, {40, 8}, {42, 11}, {47, 15}, {50, 15}, {51, 15}, {56, 15}, {64, 15}, {67, 15},
+ {68, 15}, {69, 15}, {70, 14}, {71, 14}, {72, 14}, {76, 14}, {44, 10}, {43, 9}, {46, 9}, {54, 9},
+ {55, 11}, {63, 11}, {61, 10}, {58, 9}, {48, 6}, {49, 7}, {53, 7}, {52, 5}, {57, 6}, {59, 8},
+ {60, 9}, {62, 10}, {74, 10}, {65, 8}, {66, 9}, {75, 9}, {73, 5},
+ },
+ {
+ /* AC lowquant table group 1, table 7 */
+ {0, 2}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {5, 7}, {6, 8}, {7, 8}, {8, 9}, {9, 9},
+ {10, 9}, {11, 10}, {12, 15}, {13, 15}, {14, 15}, {15, 15}, {32, 15}, {36, 15}, {38, 15}, {41, 15},
+ {42, 15}, {45, 15}, {47, 15}, {50, 15}, {51, 15}, {61, 15}, {62, 14}, {34, 11}, {18, 6}, {17, 5},
+ {19, 7}, {23, 8}, {24, 8}, {21, 6}, {25, 9}, {26, 10}, {28, 10}, {27, 9}, {29, 9}, {30, 10},
+ {31, 10}, {33, 10}, {35, 11}, {40, 11}, {37, 10}, {43, 11}, {44, 11}, {39, 9}, {46, 11}, {60, 11},
+ {49, 10}, {56, 9}, {59, 9}, {63, 14}, {64, 14}, {67, 14}, {68, 14}, {69, 14}, {70, 14}, {71, 14},
+ {72, 14}, {74, 11}, {76, 10}, {48, 7}, {16, 3}, {20, 4}, {22, 4}, {52, 3}, {53, 5}, {54, 7},
+ {55, 7}, {58, 7}, {65, 9}, {66, 9}, {75, 8}, {57, 5}, {73, 5},
+ },
+ },
+ },
+};
+#define MAX_AC_VLC_BITS 16
+
+#define W0 2048
+#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
+#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
+#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
+#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
+#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
+#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
+#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
+
+static void wmv2_idct_row(short *b) {
+ int s1, s2;
+ int a0, a1, a2, a3, a4, a5, a6, a7;
+
+ /* step 1 */
+ a1 = W1 * b[1] + W7 * b[7];
+ a7 = W7 * b[1] - W1 * b[7];
+ a5 = W5 * b[5] + W3 * b[3];
+ a3 = W3 * b[5] - W5 * b[3];
+ a2 = W2 * b[2] + W6 * b[6];
+ a6 = W6 * b[2] - W2 * b[6];
+ a0 = W0 * b[0] + W0 * b[4];
+ a4 = W0 * b[0] - W0 * b[4];
+
+ /* step 2 */
+ s1 = (int)(181U * (a1 - a5 + a7 - a3) + 128) >> 8; // 1, 3, 5, 7
+ s2 = (int)(181U * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+ /* step 3 */
+ b[0] = (a0 + a2 + a1 + a5 + (1 << 7)) >> 8;
+ b[1] = (a4 + a6 + s1 + (1 << 7)) >> 8;
+ b[2] = (a4 - a6 + s2 + (1 << 7)) >> 8;
+ b[3] = (a0 - a2 + a7 + a3 + (1 << 7)) >> 8;
+ b[4] = (a0 - a2 - a7 - a3 + (1 << 7)) >> 8;
+ b[5] = (a4 - a6 - s2 + (1 << 7)) >> 8;
+ b[6] = (a4 + a6 - s1 + (1 << 7)) >> 8;
+ b[7] = (a0 + a2 - a1 - a5 + (1 << 7)) >> 8;
+}
+
+static void wmv2_idct_col(short *b) {
+ int s1, s2;
+ int a0, a1, a2, a3, a4, a5, a6, a7;
+
+ /* step 1, with extended precision */
+ a1 = (W1 * b[8 * 1] + W7 * b[8 * 7] + 4) >> 3;
+ a7 = (W7 * b[8 * 1] - W1 * b[8 * 7] + 4) >> 3;
+ a5 = (W5 * b[8 * 5] + W3 * b[8 * 3] + 4) >> 3;
+ a3 = (W3 * b[8 * 5] - W5 * b[8 * 3] + 4) >> 3;
+ a2 = (W2 * b[8 * 2] + W6 * b[8 * 6] + 4) >> 3;
+ a6 = (W6 * b[8 * 2] - W2 * b[8 * 6] + 4) >> 3;
+ a0 = (W0 * b[8 * 0] + W0 * b[8 * 4]) >> 3;
+ a4 = (W0 * b[8 * 0] - W0 * b[8 * 4]) >> 3;
+
+ /* step 2 */
+ s1 = (int)(181U * (a1 - a5 + a7 - a3) + 128) >> 8;
+ s2 = (int)(181U * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+ /* step 3 */
+ b[8 * 0] = (a0 + a2 + a1 + a5 + (1 << 13)) >> 14;
+ b[8 * 1] = (a4 + a6 + s1 + (1 << 13)) >> 14;
+ b[8 * 2] = (a4 - a6 + s2 + (1 << 13)) >> 14;
+ b[8 * 3] = (a0 - a2 + a7 + a3 + (1 << 13)) >> 14;
+
+ b[8 * 4] = (a0 - a2 - a7 - a3 + (1 << 13)) >> 14;
+ b[8 * 5] = (a4 - a6 - s2 + (1 << 13)) >> 14;
+ b[8 * 6] = (a4 + a6 - s1 + (1 << 13)) >> 14;
+ b[8 * 7] = (a0 + a2 - a1 - a5 + (1 << 13)) >> 14;
+}
+
+static void wmv2_idct_add_c(uint8 *dest, ptrdiff_t line_size, int16 *block) {
+ int i;
+
+ for (i = 0; i < 64; i += 8)
+ wmv2_idct_row(block + i);
+ for (i = 0; i < 8; i++)
+ wmv2_idct_col(block + i);
+
+ for (i = 0; i < 8; i++) {
+ dest[0] = av_clip_uint8(dest[0] + block[0]);
+ dest[1] = av_clip_uint8(dest[1] + block[1]);
+ dest[2] = av_clip_uint8(dest[2] + block[2]);
+ dest[3] = av_clip_uint8(dest[3] + block[3]);
+ dest[4] = av_clip_uint8(dest[4] + block[4]);
+ dest[5] = av_clip_uint8(dest[5] + block[5]);
+ dest[6] = av_clip_uint8(dest[6] + block[6]);
+ dest[7] = av_clip_uint8(dest[7] + block[7]);
+ dest += line_size;
+ block += 8;
+ }
+}
+
+static const VLC *makeCanonicalVLC(int count, const uint8 table[][2]) {
+ uint32 codes[256], lengths[256];
+ uint64 code = 0;
+ for (int i = 0; i < count; ++i) {
+ int n = table[i][1];
+ codes[i] = code >> (32 - n);
+ lengths[i] = n;
+ code += uint64(1) << (32 - n);
+ }
+ VLC *v = const_cast<VLC *>(makeVLC(count, lengths, 4, 4, codes, 4, 4));
+ for (uint i = 0; i < v->nodes.size(); ++i)
+ if (v->nodes[i].symbol >= 0)
+ v->nodes[i].symbol = table[v->nodes[i].symbol][0];
+ return v;
+}
+#define VLC_BUFFER_SIZE 28150
+
+#define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits + table_bits - 1) / table_bits)
+
+#define DC_VLC_BITS 9
+#define OR_VLC_BITS 7
+
+#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
+#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
+#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
+
+static const VLC *j_ac_vlc[2][2][8]; // [quant < 13], [intra / inter], [select]
+static const VLC *j_dc_vlc[2][8]; // [quant], [select]
+static const VLC *j_orient_vlc[2][4]; // [quant], [select]
+
+static const VLC *x8_init_vlc(int nb_bits, int nb_codes, const uint8 table[][2]) {
+ return makeCanonicalVLC(nb_codes, table);
+}
+
+static void x8_vlc_init(void) {
+
+ int i;
+
+ // set ac tables
+ for (int i = 0; i < 2; i++)
+ for (int j = 0; j < 2; j++)
+ for (int k = 0; k < 8; k++)
+ j_ac_vlc[i][j][k] = x8_init_vlc(AC_VLC_BITS, 77, x8_ac_quant_table[i][j][k]);
+
+ // set dc tables
+ for (int i = 0; i < 2; i++)
+ for (int j = 0; j < 8; j++)
+ j_dc_vlc[i][j] = x8_init_vlc(DC_VLC_BITS, 34, x8_dc_quant_table[i][j]);
+
+ // set orient tables
+ for (i = 0; i < 2; i++)
+ j_orient_vlc[0][i] = x8_init_vlc(OR_VLC_BITS, 12, x8_orient_highquant_table[i]);
+ for (i = 0; i < 4; i++)
+ j_orient_vlc[1][i] = x8_init_vlc(OR_VLC_BITS, 12, x8_orient_lowquant_table[i]);
+}
+
+static void x8_reset_vlc_tables(IntraX8Context *w) {
+ memset(w->j_dc_vlc_table, 0, sizeof(w->j_dc_vlc_table));
+ memset(w->j_ac_vlc_table, 0, sizeof(w->j_ac_vlc_table));
+ w->j_orient_vlc_table = NULL;
+}
+
+static inline void x8_select_ac_table(IntraX8Context *const w, int mode) {
+ int table_index;
+
+ assert(mode < 4);
+
+ if (w->j_ac_vlc_table[mode])
+ return;
+
+ table_index = get_bits(w->gb, 3);
+ // 2 modes use same tables
+ w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index];
+ assert(w->j_ac_vlc_table[mode]);
+}
+
+static inline int x8_get_orient_vlc(IntraX8Context *w) {
+ if (!w->j_orient_vlc_table) {
+ int table_index = get_bits(w->gb, 1 + (w->quant < 13));
+ w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index];
+ }
+
+ return get_vlc2(w->gb, w->j_orient_vlc_table);
+}
+
+#define extra_bits(eb) (eb) // 3 bits
+#define extra_run (0xFF << 8) // 1 bit
+#define extra_level (0x00 << 8) // 1 bit
+#define run_offset(r) ((r) << 16) // 6 bits
+#define level_offset(l) ((l) << 24) // 5 bits
+static const uint32 ac_decode_table[] = {
+ /* 46 */ extra_bits(3) | extra_run | run_offset(16) | level_offset(0),
+ /* 47 */ extra_bits(3) | extra_run | run_offset(24) | level_offset(0),
+ /* 48 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1),
+ /* 49 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1),
+
+ /* 50 */ extra_bits(5) | extra_run | run_offset(32) | level_offset(0),
+ /* 51 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1),
+
+ /* 52 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4),
+ /* 53 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(8),
+ /* 54 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(12),
+ /* 55 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(16),
+ /* 56 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(24),
+
+ /* 57 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3),
+ /* 58 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7),
+
+ /* 59 */ extra_bits(2) | extra_run | run_offset(16) | level_offset(0),
+ /* 60 */ extra_bits(2) | extra_run | run_offset(20) | level_offset(0),
+ /* 61 */ extra_bits(2) | extra_run | run_offset(24) | level_offset(0),
+ /* 62 */ extra_bits(2) | extra_run | run_offset(28) | level_offset(0),
+ /* 63 */ extra_bits(4) | extra_run | run_offset(32) | level_offset(0),
+ /* 64 */ extra_bits(4) | extra_run | run_offset(48) | level_offset(0),
+
+ /* 65 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1),
+ /* 66 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1),
+ /* 67 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1),
+
+ /* 68 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4),
+ /* 69 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(8),
+ /* 70 */ extra_bits(4) | extra_level | run_offset(0) | level_offset(16),
+
+ /* 71 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3),
+ /* 72 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7),
+};
+#undef extra_bits
+#undef extra_run
+#undef extra_level
+#undef run_offset
+#undef level_offset
+
+static void x8_get_ac_rlf(IntraX8Context *const w, const int mode, int *const run, int *const level, int *const final) {
+ int i, e;
+
+ // x8_select_ac_table(w, mode);
+ i = get_vlc2(w->gb, w->j_ac_vlc_table[mode]);
+
+ if (i < 46) { // [0-45]
+ int t, l;
+ if (i < 0) {
+ *level = *final = // prevent 'may be used uninitialized'
+ *run = 64; // this would cause error exit in the ac loop
+ return;
+ }
+
+ /*
+ * i == 0-15 r = 0-15 l = 0; r = i & %01111
+ * i == 16-19 r = 0-3 l = 1; r = i & %00011
+ * i == 20-21 r = 0-1 l = 2; r = i & %00001
+ * i == 22 r = 0 l = 3; r = i & %00000
+ */
+
+ *final = t = i > 22;
+ i -= 23 * t;
+
+ /* l = lut_l[i / 2] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3 }[i >> 1];
+ * 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 */
+ l = (0xE50000 >> (i & 0x1E)) & 3; // 0x1E or ~1 or (i >> 1 << 1)
+
+ /* t = lut_mask[l] = { 0x0f, 0x03, 0x01, 0x00 }[l];
+ * as i < 256 the higher bits do not matter */
+ t = 0x01030F >> (l << 3);
+
+ *run = i & t;
+ *level = l;
+ } else if (i < 73) { // [46-72]
+ uint32 sm;
+ uint32 mask;
+
+ i -= 46;
+ sm = ac_decode_table[i];
+
+ e = get_bits(w->gb, sm & 0xF);
+ sm >>= 8; // 3 bits
+ mask = sm & 0xff;
+ sm >>= 8; // 1 bit
+
+ *run = (sm & 0xff) + (e & mask); // 6 bits
+ *level = (sm >> 8) + (e & ~mask); // 5 bits
+ *final = i > (58 - 46);
+ } else if (i < 75) { // [73-74]
+ static const uint8 crazy_mix_runlevel[32] = {
+ 0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63, 0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83,
+ 0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64, 0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84,
+ };
+
+ *final = !(i & 1);
+ e = get_bits(w->gb, 5); // get the extra bits
+ *run = crazy_mix_runlevel[e] >> 4;
+ *level = crazy_mix_runlevel[e] & 0x0F;
+ } else {
+ *level = get_bits(w->gb, 7 - 3 * (i & 1));
+ *run = get_bits(w->gb, 6);
+ *final = get_bits1(w->gb);
+ }
+ return;
+}
+
+/* static const uint8 dc_extra_sbits[] = {
+ * 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ * }; */
+static const uint8 dc_index_offset[] = {
+ 0, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+};
+
+static int x8_get_dc_rlf(IntraX8Context *const w, const int mode, int *const level, int *const final) {
+ int i, e, c;
+
+ assert(mode < 3);
+ if (!w->j_dc_vlc_table[mode]) {
+ int table_index = get_bits(w->gb, 3);
+ // 4 modes, same table
+ w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index];
+ }
+
+ i = get_vlc2(w->gb, w->j_dc_vlc_table[mode]);
+
+ /* (i >= 17) { i -= 17; final =1; } */
+ c = i > 16;
+ *final = c;
+ i -= 17 * c;
+
+ if (i <= 0) {
+ *level = 0;
+ return -i;
+ }
+ c = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[]
+ c -= c > 1;
+
+ e = get_bits(w->gb, c); // get the extra bits
+ i = dc_index_offset[i] + (e >> 1);
+
+ e = -(e & 1); // 0, 0xffffff
+ *level = (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1)
+ return 0;
+}
+
+// end of huffman
+
+static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma) {
+ int range;
+ int sum;
+ int quant;
+
+ w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad, w->frame->linesize[chroma > 0], &range, &sum,
+ w->edges);
+ if (chroma) {
+ w->orient = w->chroma_orient;
+ quant = w->quant_dc_chroma;
+ } else {
+ quant = w->quant;
+ }
+
+ w->flat_dc = 0;
+ if (range < quant || range < 3) {
+ w->orient = 0;
+
+ // yep you read right, a +-1 idct error may break decoding!
+ if (range < 3) {
+ w->flat_dc = 1;
+ sum += 9;
+ // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
+ w->predicted_dc = sum * 6899 >> 17;
+ }
+ }
+ if (chroma)
+ return 0;
+
+ assert(w->orient < 3);
+ if (range < 2 * w->quant) {
+ if ((w->edges & 3) == 0) {
+ if (w->orient == 1)
+ w->orient = 11;
+ if (w->orient == 2)
+ w->orient = 10;
+ } else {
+ w->orient = 0;
+ }
+ w->raw_orient = 0;
+ } else {
+ static const uint8 prediction_table[3][12] = {
+ {0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7},
+ {4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7},
+ {8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5},
+ };
+ w->raw_orient = x8_get_orient_vlc(w);
+ if (w->raw_orient < 0)
+ return -1;
+ assert(w->raw_orient < 12);
+ assert(w->orient < 3);
+ w->orient = prediction_table[w->orient][w->raw_orient];
+ }
+ return 0;
+}
+
+static void x8_update_predictions(IntraX8Context *const w, const int orient, const int est_run) {
+ w->prediction_table[w->mb_x * 2 + (w->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8);
+ /*
+ * y = 2n + 0 -> // 0 2 4
+ * y = 2n + 1 -> // 1 3 5
+ */
+}
+
+static void x8_get_prediction_chroma(IntraX8Context *const w) {
+ w->edges = 1 * !(w->mb_x >> 1);
+ w->edges |= 2 * !(w->mb_y >> 1);
+ w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd
+
+ w->raw_orient = 0;
+ // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC
+ if (w->edges & 3) {
+ w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
+ return;
+ }
+ // block[x - 1][y | 1 - 1)]
+ w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2;
+}
+
+static void x8_get_prediction(IntraX8Context *const w) {
+ int a, b, c, i;
+
+ w->edges = 1 * !w->mb_x;
+ w->edges |= 2 * !w->mb_y;
+ w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1));
+
+ switch (w->edges & 3) {
+ case 0:
+ break;
+ case 1:
+ // take the one from the above block[0][y - 1]
+ w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2;
+ w->orient = 1;
+ return;
+ case 2:
+ // take the one from the previous block[x - 1][0]
+ w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2;
+ w->orient = 2;
+ return;
+ case 3:
+ w->est_run = 16;
+ w->orient = 0;
+ return;
+ }
+ // no edge cases
+ b = w->prediction_table[2 * w->mb_x + !(w->mb_y & 1)]; // block[x ][y - 1]
+ a = w->prediction_table[2 * w->mb_x - 2 + (w->mb_y & 1)]; // block[x - 1][y ]
+ c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1]
+
+ w->est_run = MIN(b, a);
+ /* This condition has nothing to do with w->edges, even if it looks
+ * similar it would trigger if e.g. x = 3; y = 2;
+ * I guess somebody wrote something wrong and it became standard. */
+ if ((w->mb_x & w->mb_y) != 0)
+ w->est_run = MIN(c, w->est_run);
+ w->est_run >>= 2;
+
+ a &= 3;
+ b &= 3;
+ c &= 3;
+
+ i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
+ if (i != 3)
+ w->orient = i;
+ else
+ w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3;
+ /*
+ * lut1[b][a] = {
+ * ->{ 0, 1, 0, pad },
+ * { 0, 1, X, pad },
+ * { 2, 2, 2, pad }
+ * }
+ * pad 2 2 2;
+ * pad X 1 0;
+ * pad 0 1 0 <-
+ * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4
+ *
+ * lut2[q>12][c] = {
+ * ->{ 0, 2, 1, pad},
+ * { 2, 2, 2, pad}
+ * }
+ * pad 2 2 2;
+ * pad 1 2 0 <-
+ * -> 11 10'10 10 '11 01'10 00 => 0xEAD8
+ */
+}
+
+static void x8_ac_compensation(IntraX8Context *const w, const int direction, const int dc_level) {
+ int t;
+#define B(x, y) w->block[(x) + (y) * 8]
+#define T(x) ((x) * dc_level + 0x8000) >> 16;
+ switch (direction) {
+ case 0:
+ t = T(3811); // h
+ B(1, 0) -= t;
+ B(0, 1) -= t;
+
+ t = T(487); // e
+ B(2, 0) -= t;
+ B(0, 2) -= t;
+
+ t = T(506); // f
+ B(3, 0) -= t;
+ B(0, 3) -= t;
+
+ t = T(135); // c
+ B(4, 0) -= t;
+ B(0, 4) -= t;
+ B(2, 1) += t;
+ B(1, 2) += t;
+ B(3, 1) += t;
+ B(1, 3) += t;
+
+ t = T(173); // d
+ B(5, 0) -= t;
+ B(0, 5) -= t;
+
+ t = T(61); // b
+ B(6, 0) -= t;
+ B(0, 6) -= t;
+ B(5, 1) += t;
+ B(1, 5) += t;
+
+ t = T(42); // a
+ B(7, 0) -= t;
+ B(0, 7) -= t;
+ B(4, 1) += t;
+ B(1, 4) += t;
+ B(4, 4) += t;
+
+ t = T(1084); // g
+ B(1, 1) += t;
+ break;
+ case 1:
+ B(0, 1) -= T(6269);
+ B(0, 3) -= T(708);
+ B(0, 5) -= T(172);
+ B(0, 7) -= T(73);
+ break;
+ case 2:
+ B(1, 0) -= T(6269);
+ B(3, 0) -= T(708);
+ B(5, 0) -= T(172);
+ B(7, 0) -= T(73);
+ break;
+ }
+#undef B
+#undef T
+}
+
+static void dsp_x8_put_solidcolor(const uint8 pix, uint8 *dst, const ptrdiff_t linesize) {
+ int k;
+ for (k = 0; k < 8; k++) {
+ memset(dst, pix, 8);
+ dst += linesize;
+ }
+}
+
+static const int16 quant_table[64] = {
+ 256, 256, 256, 256, 256, 256, 259, 262, 265, 269, 272, 275, 278, 282, 285, 288, 292, 295, 299, 303, 306, 310,
+ 314, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353, 358, 362, 366, 371, 375, 379, 384, 389, 393, 398, 403,
+ 408, 413, 417, 422, 428, 433, 438, 443, 448, 454, 459, 465, 470, 476, 482, 488, 493, 499, 505, 511,
+};
+
+static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma) {
+ uint8 *scantable;
+ int final, run, level;
+ int ac_mode, dc_mode, est_run, dc_level;
+ int pos, n;
+ int zeros_only;
+ int use_quant_matrix;
+ int sign;
+
+ assert(w->orient < 12);
+ w->bdsp.clear_block(w->block);
+
+ if (chroma)
+ dc_mode = 2;
+ else
+ dc_mode = !!w->est_run; // 0, 1
+
+ if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
+ return -1;
+ n = 0;
+ zeros_only = 0;
+ if (!final) { // decode ac
+ use_quant_matrix = w->use_quant_matrix;
+ if (chroma) {
+ ac_mode = 1;
+ est_run = 64; // not used
+ } else {
+ if (w->raw_orient < 3)
+ use_quant_matrix = 0;
+
+ if (w->raw_orient > 4) {
+ ac_mode = 0;
+ est_run = 64;
+ } else {
+ if (w->est_run > 1) {
+ ac_mode = 2;
+ est_run = w->est_run;
+ } else {
+ ac_mode = 3;
+ est_run = 64;
+ }
+ }
+ }
+ x8_select_ac_table(w, ac_mode);
+ /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <-
+ * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */
+ scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3];
+ pos = 0;
+ do {
+ n++;
+ if (n >= est_run) {
+ ac_mode = 3;
+ x8_select_ac_table(w, 3);
+ }
+
+ x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
+
+ pos += run + 1;
+ if (pos > 63) {
+ // this also handles vlc error in x8_get_ac_rlf
+ return -1;
+ }
+ level = (level + 1) * w->dquant;
+ level += w->qsum;
+
+ sign = -get_bits1(w->gb);
+ level = (level ^ sign) - sign;
+
+ if (use_quant_matrix)
+ level = (level * quant_table[pos]) >> 8;
+
+ w->block[scantable[pos]] = level;
+ } while (!final);
+ } else { // DC only
+ if (w->flat_dc && ((unsigned)(dc_level + 1)) < 3) { // [-1; 1]
+ int32 divide_quant = !chroma ? w->divide_quant_dc_luma : w->divide_quant_dc_chroma;
+ int32 dc_quant = !chroma ? w->quant : w->quant_dc_chroma;
+
+ // original intent dc_level += predicted_dc/quant;
+ // but it got lost somewhere in the rounding
+ dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
+
+ dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3), w->dest[chroma],
+ w->frame->linesize[!!chroma]);
+
+ goto block_placed;
+ }
+ zeros_only = dc_level == 0;
+ }
+ if (!chroma)
+ w->block[0] = dc_level * w->quant;
+ else
+ w->block[0] = dc_level * w->quant_dc_chroma;
+
+ // there is !zero_only check in the original, but dc_level check is enough
+ if ((unsigned int)(dc_level + 1) >= 3 && (w->edges & 3) != 3) {
+ int direction;
+ /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <-
+ * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */
+ direction = (0x6A017C >> (w->orient * 2)) & 3;
+ if (direction != 3) {
+ x8_ac_compensation(w, direction, w->block[0]);
+ }
+ }
+
+ if (w->flat_dc) {
+ dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma], w->frame->linesize[!!chroma]);
+ } else {
+ w->dsp.spatial_compensation[w->orient](w->scratchpad, w->dest[chroma], w->frame->linesize[!!chroma]);
+ }
+ if (!zeros_only)
+ w->idsp.idct_add(w->dest[chroma], w->frame->linesize[!!chroma], w->block);
+
+block_placed:
+ if (!chroma)
+ x8_update_predictions(w, w->orient, n);
+
+ if (w->loopfilter) {
+ uint8 *ptr = w->dest[chroma];
+ ptrdiff_t linesize = w->frame->linesize[!!chroma];
+
+ if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))
+ w->dsp.h_loop_filter(ptr, linesize, w->quant);
+
+ if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
+ w->dsp.v_loop_filter(ptr, linesize, w->quant);
+ }
+ return 0;
+}
+
+// FIXME maybe merge with ff_*
+static void x8_init_block_index(IntraX8Context *w, Planes *frame) {
+ // not parent codec linesize as this would be wrong for field pics
+ // not that IntraX8 has interlacing support ;)
+ const ptrdiff_t linesize = frame->linesize[0];
+ const ptrdiff_t uvlinesize = frame->linesize[1];
+
+ w->dest[0] = frame->data[0];
+ w->dest[1] = frame->data[1];
+ w->dest[2] = frame->data[2];
+
+ w->dest[0] += w->mb_y * linesize << 3;
+ // chroma blocks are on add rows
+ w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2;
+ w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2;
+}
+
+int initX8(IntraX8Context *w, int16 block[64], int mb_width, int mb_height) {
+ w->mb_width = mb_width;
+ w->mb_height = mb_height;
+ w->block = block;
+ w->prediction_table = new uint8[mb_width * 4]();
+ w->idsp.idct_add = wmv2_idct_add_c;
+ memcpy(w->permutated_scantable[0], ff_wmv1_scantable[0], 64);
+ memcpy(w->permutated_scantable[1], ff_wmv1_scantable[2], 64);
+ memcpy(w->permutated_scantable[2], ff_wmv1_scantable[3], 64);
+ ff_intrax8dsp_init(&w->dsp);
+ PictureState state = {};
+ ChromaDSP chroma;
+ initSupport(&state, &chroma);
+ w->bdsp = state.bdsp;
+ static const bool initialized = (x8_vlc_init(), true);
+ (void)initialized;
+ return 0;
+}
+
+void endX8(IntraX8Context *w) {
+ delete[] w->prediction_table;
+}
+
+int ff_intrax8_decode_picture(IntraX8Context *w, Picture *pict, Bits *gb, int *mb_x, int *mb_y, int dquant,
+ int quant_offset, int loopfilter, int lowdelay) {
+ int mb_xy;
+
+ w->gb = gb;
+ w->dquant = dquant;
+ w->quant = dquant >> 1;
+ w->qsum = quant_offset;
+ w->frame = pict->f;
+ w->loopfilter = loopfilter;
+ w->use_quant_matrix = get_bits1(w->gb);
+
+ w->mb_x = *mb_x;
+ w->mb_y = *mb_y;
+
+ w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
+ if (w->quant < 5) {
+ w->quant_dc_chroma = w->quant;
+ w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
+ } else {
+ w->quant_dc_chroma = w->quant + ((w->quant + 3) >> 3);
+ w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
+ }
+ x8_reset_vlc_tables(w);
+
+ for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) {
+ x8_init_block_index(w, w->frame);
+ mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
+ if (get_bits_left(gb) < 1)
+ goto error;
+ for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
+ x8_get_prediction(w);
+ if (x8_setup_spatial_predictor(w, 0))
+ goto error;
+ if (x8_decode_intra_mb(w, 0))
+ goto error;
+
+ if (w->mb_x & w->mb_y & 1) {
+ x8_get_prediction_chroma(w);
+
+ /* when setting up chroma, no vlc is read,
+ * so no error condition can be reached */
+ x8_setup_spatial_predictor(w, 1);
+ if (x8_decode_intra_mb(w, 1))
+ goto error;
+
+ x8_setup_spatial_predictor(w, 2);
+ if (x8_decode_intra_mb(w, 2))
+ goto error;
+
+ w->dest[1] += 8;
+ w->dest[2] += 8;
+
+ pict->qscale_table[mb_xy] = w->quant;
+ mb_xy++;
+ }
+ w->dest[0] += 8;
+ }
+ }
+
+error:
+ *mb_x = w->mb_x;
+ *mb_y = w->mb_y;
+
+ return 0;
+}
+
+#undef AC_VLC_MTD
+#undef DC_VLC_BITS
+#undef DC_VLC_MTD
+#undef MAX_AC_VLC_BITS
+#undef MAX_DC_VLC_BITS
+#undef MAX_OR_VLC_BITS
+#undef MAX_TABLE_DEPTH
+#undef OR_VLC_BITS
+#undef OR_VLC_MTD
+#undef VLC_BUFFER_SIZE
+#undef W0
+#undef W1
+#undef W2
+#undef W3
+#undef W4
+#undef W5
+#undef W6
+#undef W7
+
+static int bitplane_decoding(uint8 *data, int *raw, VC1Context *v) {
+ VC1Bitplane decoder;
+ int result =
+ decoder.decode(data, raw, v->s.mb_width, v->s.mb_height >> v->field_mode, v->s.mb_stride, v->gb.stream);
+ return result;
+}
+
+static int vop_dquant_decoding(VC1Context *v) {
+ Bits *const gb = &v->gb;
+ int pqdiff;
+
+ // variable size
+ if (v->dquant != 2) {
+ v->dquantfrm = get_bits1(gb);
+ if (!v->dquantfrm)
+ return 0;
+
+ v->dqprofile = get_bits(gb, 2);
+ switch (v->dqprofile) {
+ case DQPROFILE_SINGLE_EDGE:
+ case DQPROFILE_DOUBLE_EDGES:
+ v->dqsbedge = get_bits(gb, 2);
+ break;
+ case DQPROFILE_ALL_MBS:
+ v->dqbilevel = get_bits1(gb);
+ if (!v->dqbilevel) {
+ v->halfpq = 0;
+ return 0;
+ }
+ break;
+ default:
+ break; // Forbidden ?
+ }
+ }
+
+ pqdiff = get_bits(gb, 3);
+ if (pqdiff == 7)
+ v->altpq = get_bits(gb, 5);
+ else
+ v->altpq = v->pq + pqdiff + 1;
+
+ return 0;
+}
+
+/* fill lookup tables for intensity compensation */
+#define INIT_LUT(lumscale, lumshift, luty, lutuv, chain) \
+ do { \
+ int scale, shift, i; \
+ if (!lumscale) { \
+ scale = -64; \
+ shift = (255 - lumshift * 2) * 64; \
+ if (lumshift > 31) \
+ shift += 128 << 6; \
+ } else { \
+ scale = lumscale + 32; \
+ if (lumshift > 31) \
+ shift = (lumshift - 64) * 64; \
+ else \
+ shift = lumshift << 6; \
+ } \
+ for (i = 0; i < 256; i++) { \
+ int iy = chain ? luty[i] : i; \
+ int iu = chain ? lutuv[i] : i; \
+ luty[i] = av_clip_uint8((scale * iy + shift + 32) >> 6); \
+ lutuv[i] = av_clip_uint8((scale * (iu - 128) + 128 * 64 + 32) >> 6); \
+ } \
+ } while (0)
+
+static void rotate_luts(VC1Context *v) {
+ if (v->s.pict_type == AV_PICTURE_TYPE_BI || v->s.pict_type == AV_PICTURE_TYPE_B) {
+ v->curr_use_ic = &v->aux_use_ic;
+ v->curr_luty = v->aux_luty;
+ v->curr_lutuv = v->aux_lutuv;
+ } else {
+#define ROTATE(DEF, L, N, C) \
+ do { \
+ DEF; \
+ memcpy(&tmp, L, sizeof(tmp)); \
+ memcpy(L, N, sizeof(tmp)); \
+ memcpy(N, &tmp, sizeof(tmp)); \
+ C = N; \
+ } while (0)
+
+ ROTATE(int tmp, &v->last_use_ic, &v->next_use_ic, v->curr_use_ic);
+ ROTATE(uint8 tmp[2][256], v->last_luty, v->next_luty, v->curr_luty);
+ ROTATE(uint8 tmp[2][256], v->last_lutuv, v->next_lutuv, v->curr_lutuv);
+ }
+
+ INIT_LUT(32, 0, v->curr_luty[0], v->curr_lutuv[0], 0);
+ INIT_LUT(32, 0, v->curr_luty[1], v->curr_lutuv[1], 0);
+ *v->curr_use_ic = 0;
+}
+
+static int read_bfraction(VC1Context *v, Bits *gb) {
+ int bfraction_lut_index = get_bits(gb, 3);
+
+ if (bfraction_lut_index == 7)
+ bfraction_lut_index = 7 + get_bits(gb, 4);
+
+ if (bfraction_lut_index == 21) {
+ warning("bfraction invalid\n");
+ return (-1);
+ }
+ v->bfraction_lut_index = bfraction_lut_index;
+ v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
+ return 0;
+}
+
+int ff_vc1_parse_frame_header(VC1Context *v, Bits *gb) {
+ int pqindex, lowquant, status;
+
+ v->field_mode = 0;
+ v->fcm = PROGRESSIVE;
+ if (v->finterpflag)
+ v->interpfrm = get_bits1(gb);
+ skip_bits(gb, 2); // framecnt unused
+ v->rangeredfrm = 0;
+ if (v->rangered)
+ v->rangeredfrm = get_bits1(gb);
+ if (get_bits1(gb)) {
+ v->s.pict_type = AV_PICTURE_TYPE_P;
+ } else {
+ if (v->max_b_frames && !get_bits1(gb)) {
+ v->s.pict_type = AV_PICTURE_TYPE_B;
+ } else
+ v->s.pict_type = AV_PICTURE_TYPE_I;
+ }
+
+ v->bi_type = 0;
+ if (v->s.pict_type == AV_PICTURE_TYPE_B) {
+ if (read_bfraction(v, gb) < 0)
+ return (-1);
+ if (v->bfraction == 0) {
+ v->s.pict_type = AV_PICTURE_TYPE_BI;
+ }
+ }
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
+ skip_bits(gb, 7); // skip buffer fullness
+
+ if (v->parse_only)
+ return 0;
+
+ /* calculate RND */
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
+ v->rnd = 1;
+ if (v->s.pict_type == AV_PICTURE_TYPE_P)
+ v->rnd ^= 1;
+
+ if (get_bits_left(gb) < 5)
+ return (-1);
+ /* Quantizer stuff */
+ pqindex = get_bits(gb, 5);
+ if (!pqindex)
+ return -1;
+ if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
+ v->pq = ff_vc1_pquant_table[0][pqindex];
+ else
+ v->pq = ff_vc1_pquant_table[1][pqindex];
+ v->pqindex = pqindex;
+ if (pqindex < 9)
+ v->halfpq = get_bits1(gb);
+ else
+ v->halfpq = 0;
+ switch (v->quantizer_mode) {
+ case QUANT_FRAME_IMPLICIT:
+ v->pquantizer = pqindex < 9;
+ break;
+ case QUANT_NON_UNIFORM:
+ v->pquantizer = 0;
+ break;
+ case QUANT_FRAME_EXPLICIT:
+ v->pquantizer = get_bits1(gb);
+ break;
+ default:
+ v->pquantizer = 1;
+ break;
+ }
+ v->dquantfrm = 0;
+ if (v->extended_mv == 1)
+ v->mvrange = get_unary(gb, 0, 3);
+ v->k_x = v->mvrange + 9 + (v->mvrange >> 1); // k_x can be 9 10 12 13
+ v->k_y = v->mvrange + 8; // k_y can be 8 9 10 11
+ v->range_x = 1 << (v->k_x - 1);
+ v->range_y = 1 << (v->k_y - 1);
+ if (v->multires && v->s.pict_type != AV_PICTURE_TYPE_B)
+ v->respic = get_bits(gb, 2);
+
+ if (v->res_x8 && (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)) {
+ v->x8_type = get_bits1(gb);
+ } else
+ v->x8_type = 0;
+
+ if (v->first_pic_header_flag)
+ rotate_luts(v);
+
+ switch (v->s.pict_type) {
+ case AV_PICTURE_TYPE_P:
+ v->tt_index = (v->pq > 4) + (v->pq > 12);
+
+ lowquant = (v->pq > 12) ? 0 : 1;
+ v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)];
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)];
+ v->lumscale = get_bits(gb, 6);
+ v->lumshift = get_bits(gb, 6);
+ v->last_use_ic = 1;
+ /* fill lookup tables for intensity compensation */
+ INIT_LUT(v->lumscale, v->lumshift, v->last_luty[0], v->last_lutuv[0], 1);
+ INIT_LUT(v->lumscale, v->lumshift, v->last_luty[1], v->last_lutuv[1], 1);
+ }
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ v->s.quarter_sample = (v->mv_mode2 != MV_PMODE_1MV_HPEL && v->mv_mode2 != MV_PMODE_1MV_HPEL_BILIN);
+ v->s.mspel = (v->mv_mode2 != MV_PMODE_1MV_HPEL_BILIN);
+ } else {
+ v->s.quarter_sample = (v->mv_mode != MV_PMODE_1MV_HPEL && v->mv_mode != MV_PMODE_1MV_HPEL_BILIN);
+ v->s.mspel = (v->mv_mode != MV_PMODE_1MV_HPEL_BILIN);
+ }
+
+ if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV) ||
+ v->mv_mode == MV_PMODE_MIXED_MV) {
+ status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ } else {
+ v->mv_type_is_raw = 0;
+ memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
+ }
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ if (get_bits_left(gb) < 4)
+ return (-1);
+
+ /* Hopefully this is correct for P-frames */
+ v->mv_table_index = get_bits(gb, 2); // but using ff_vc1_ tables
+ v->cbptab = get_bits(gb, 2);
+ v->cbpcy_vlc = ff_vc1_cbpcy_p_vlc[v->cbptab];
+
+ if (v->dquant) {
+
+ vop_dquant_decoding(v);
+ }
+
+ if (v->vstransform) {
+ v->ttmbf = get_bits1(gb);
+ if (v->ttmbf) {
+ v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
+ } else
+ v->ttfrm = 0; // FIXME Is that so ?
+ } else {
+ v->ttmbf = 1;
+ v->ttfrm = TT_8X8;
+ }
+ break;
+ case AV_PICTURE_TYPE_B:
+ v->tt_index = (v->pq > 4) + (v->pq > 12);
+
+ v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
+ v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
+ v->s.mspel = v->s.quarter_sample;
+
+ status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ v->mv_table_index = get_bits(gb, 2);
+ v->cbptab = get_bits(gb, 2);
+ v->cbpcy_vlc = ff_vc1_cbpcy_p_vlc[v->cbptab];
+
+ if (v->dquant) {
+
+ vop_dquant_decoding(v);
+ }
+
+ if (v->vstransform) {
+ v->ttmbf = get_bits1(gb);
+ if (v->ttmbf) {
+ v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
+ } else
+ v->ttfrm = 0;
+ } else {
+ v->ttmbf = 1;
+ v->ttfrm = TT_8X8;
+ }
+ break;
+ }
+
+ if (!v->x8_type) {
+ /* AC Syntax */
+ v->c_ac_table_index = decode012(gb);
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) {
+ v->y_ac_table_index = decode012(gb);
+ }
+ /* DC Syntax */
+ v->dc_table_index = get_bits1(gb);
+ }
+
+ if (v->s.pict_type == AV_PICTURE_TYPE_BI) {
+ v->s.pict_type = AV_PICTURE_TYPE_B;
+ v->bi_type = 1;
+ }
+ return 0;
+}
+
+int ff_vc1_parse_frame_header_adv(VC1Context *v, Bits *gb) {
+ int pqindex, lowquant;
+ int status;
+ int field_mode, fcm;
+
+ v->numref = 0;
+ v->p_frame_skipped = 0;
+ if (v->second_field) {
+ if (v->fcm != ILACE_FIELD || v->field_mode != 1)
+ return -1;
+ if (v->fptype & 4)
+ v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
+ else
+ v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
+ v->s.cur_pic.ptr->f->pict_type = v->s.pict_type;
+ if (!v->pic_header_flag)
+ goto parse_common_info;
+ }
+
+ field_mode = 0;
+ if (v->interlace) {
+ fcm = decode012(gb);
+ if (fcm) {
+ if (fcm == ILACE_FIELD)
+ field_mode = 1;
+ }
+ } else {
+ fcm = PROGRESSIVE;
+ }
+ if (!v->first_pic_header_flag && v->field_mode != field_mode)
+ return (-1);
+ v->field_mode = field_mode;
+ v->fcm = fcm;
+
+ assert(v->s.mb_height == v->s.height + 15 >> 4 || v->s.mb_height == FFALIGN(v->s.height + 15 >> 4, 2));
+ if (v->field_mode) {
+ v->s.mb_height = FFALIGN(v->s.height + 15 >> 4, 2);
+ v->fptype = get_bits(gb, 3);
+ if (v->fptype & 4) // B-picture
+ v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
+ else
+ v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
+ } else {
+ v->s.mb_height = v->s.height + 15 >> 4;
+ switch (get_unary(gb, 0, 4)) {
+ case 0:
+ v->s.pict_type = AV_PICTURE_TYPE_P;
+ break;
+ case 1:
+ v->s.pict_type = AV_PICTURE_TYPE_B;
+ break;
+ case 2:
+ v->s.pict_type = AV_PICTURE_TYPE_I;
+ break;
+ case 3:
+ v->s.pict_type = AV_PICTURE_TYPE_BI;
+ break;
+ case 4:
+ v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic
+ v->p_frame_skipped = 1;
+ break;
+ }
+ }
+ if (v->tfcntrflag)
+ skip_bits(gb, 8);
+ if (v->broadcast) {
+ if (!v->interlace || v->psf) {
+ v->rptfrm = get_bits(gb, 2);
+ } else {
+ v->tff = get_bits1(gb);
+ v->rff = get_bits1(gb);
+ }
+ } else {
+ v->tff = 1;
+ }
+ if (v->panscanflag) {
+ warning("Pan-scan");
+ //...
+ }
+ if (v->p_frame_skipped) {
+ return 0;
+ }
+ v->rnd = get_bits1(gb);
+ if (v->interlace)
+ v->uvsamp = get_bits1(gb);
+ if (v->field_mode) {
+ if (!v->refdist_flag)
+ v->refdist = 0;
+ else if ((v->s.pict_type != AV_PICTURE_TYPE_B) && (v->s.pict_type != AV_PICTURE_TYPE_BI)) {
+ v->refdist = get_bits(gb, 2);
+ if (v->refdist == 3)
+ v->refdist += get_unary(gb, 0, 14);
+ if (v->refdist > 16)
+ return (-1);
+ }
+ if ((v->s.pict_type == AV_PICTURE_TYPE_B) || (v->s.pict_type == AV_PICTURE_TYPE_BI)) {
+ if (read_bfraction(v, gb) < 0)
+ return (-1);
+ v->frfd = (v->bfraction * v->refdist) >> 8;
+ v->brfd = v->refdist - v->frfd - 1;
+ if (v->brfd < 0)
+ v->brfd = 0;
+ }
+ goto parse_common_info;
+ }
+ if (v->fcm == PROGRESSIVE) {
+ if (v->finterpflag)
+ v->interpfrm = get_bits1(gb);
+ if (v->s.pict_type == AV_PICTURE_TYPE_B) {
+ if (read_bfraction(v, gb) < 0)
+ return (-1);
+ if (v->bfraction == 0) {
+ v->s.pict_type = AV_PICTURE_TYPE_BI; /* XXX: should not happen here */
+ }
+ }
+ }
+
+parse_common_info:
+ if (v->field_mode)
+ v->cur_field_type = !(v->tff ^ v->second_field);
+ pqindex = get_bits(gb, 5);
+ if (!pqindex)
+ return -1;
+ if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
+ v->pq = ff_vc1_pquant_table[0][pqindex];
+ else
+ v->pq = ff_vc1_pquant_table[1][pqindex];
+ v->pqindex = pqindex;
+ if (pqindex < 9)
+ v->halfpq = get_bits1(gb);
+ else
+ v->halfpq = 0;
+ switch (v->quantizer_mode) {
+ case QUANT_FRAME_IMPLICIT:
+ v->pquantizer = pqindex < 9;
+ break;
+ case QUANT_NON_UNIFORM:
+ v->pquantizer = 0;
+ break;
+ case QUANT_FRAME_EXPLICIT:
+ v->pquantizer = get_bits1(gb);
+ break;
+ default:
+ v->pquantizer = 1;
+ break;
+ }
+ v->dquantfrm = 0;
+ if (v->postprocflag)
+ v->postproc = get_bits(gb, 2);
+
+ if (v->parse_only)
+ return 0;
+
+ if (v->first_pic_header_flag)
+ rotate_luts(v);
+
+ switch (v->s.pict_type) {
+ case AV_PICTURE_TYPE_I:
+ case AV_PICTURE_TYPE_BI:
+ if (v->fcm == ILACE_FRAME) { // interlace frame picture
+ status = bitplane_decoding(v->fieldtx_plane, &v->fieldtx_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ } else
+ v->fieldtx_is_raw = 0;
+ status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ v->condover = CONDOVER_NONE;
+ if (v->overlap && v->pq <= 8) {
+ v->condover = decode012(gb);
+ if (v->condover == CONDOVER_SELECT) {
+ status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v);
+ if (status < 0)
+ return -1;
+ }
+ }
+ break;
+ case AV_PICTURE_TYPE_P:
+ if (v->field_mode) {
+ v->numref = get_bits1(gb);
+ if (!v->numref) {
+ v->reffield = get_bits1(gb);
+ v->ref_field_type[0] = v->reffield ^ !v->cur_field_type;
+ }
+ }
+ if (v->extended_mv)
+ v->mvrange = get_unary(gb, 0, 3);
+ else
+ v->mvrange = 0;
+ if (v->interlace) {
+ if (v->extended_dmv)
+ v->dmvrange = get_unary(gb, 0, 3);
+ else
+ v->dmvrange = 0;
+ if (v->fcm == ILACE_FRAME) { // interlaced frame picture
+ v->fourmvswitch = get_bits1(gb);
+ v->intcomp = get_bits1(gb);
+ if (v->intcomp) {
+ v->lumscale = get_bits(gb, 6);
+ v->lumshift = get_bits(gb, 6);
+ INIT_LUT(v->lumscale, v->lumshift, v->last_luty[0], v->last_lutuv[0], 1);
+ INIT_LUT(v->lumscale, v->lumshift, v->last_luty[1], v->last_lutuv[1], 1);
+ v->last_use_ic = 1;
+ }
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ v->mbmodetab = get_bits(gb, 2);
+ if (v->fourmvswitch)
+ v->mbmode_vlc = ff_vc1_intfr_4mv_mbmode_vlc[v->mbmodetab];
+ else
+ v->mbmode_vlc = ff_vc1_intfr_non4mv_mbmode_vlc[v->mbmodetab];
+ v->imvtab = get_bits(gb, 2);
+ v->imv_vlc = ff_vc1_1ref_mvdata_vlc[v->imvtab];
+ // interlaced p-picture cbpcy range is [1, 63]
+ v->icbptab = get_bits(gb, 3);
+ v->cbpcy_vlc = ff_vc1_icbpcy_vlc[v->icbptab];
+ v->twomvbptab = get_bits(gb, 2);
+ v->twomvbp_vlc = ff_vc1_2mv_block_pattern_vlc[v->twomvbptab];
+ if (v->fourmvswitch) {
+ v->fourmvbptab = get_bits(gb, 2);
+ v->fourmvbp_vlc = ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab];
+ }
+ }
+ }
+ v->k_x = v->mvrange + 9 + (v->mvrange >> 1); // k_x can be 9 10 12 13
+ v->k_y = v->mvrange + 8; // k_y can be 8 9 10 11
+ v->range_x = 1 << (v->k_x - 1);
+ v->range_y = 1 << (v->k_y - 1);
+
+ v->tt_index = (v->pq > 4) + (v->pq > 12);
+ if (v->fcm != ILACE_FRAME) {
+ int mvmode;
+ mvmode = get_unary(gb, 1, 4);
+ lowquant = (v->pq > 12) ? 0 : 1;
+ v->mv_mode = ff_vc1_mv_pmode_table[lowquant][mvmode];
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ int mvmode2;
+ mvmode2 = get_unary(gb, 1, 3);
+ v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2];
+ if (v->field_mode) {
+ v->intcompfield = decode210(gb) ^ 3;
+ } else
+ v->intcompfield = 3;
+
+ v->lumscale2 = v->lumscale = 32;
+ v->lumshift2 = v->lumshift = 0;
+ if (v->intcompfield & 1) {
+ v->lumscale = get_bits(gb, 6);
+ v->lumshift = get_bits(gb, 6);
+ }
+ if ((v->intcompfield & 2) && v->field_mode) {
+ v->lumscale2 = get_bits(gb, 6);
+ v->lumshift2 = get_bits(gb, 6);
+ } else if (!v->field_mode) {
+ v->lumscale2 = v->lumscale;
+ v->lumshift2 = v->lumshift;
+ }
+ if (v->field_mode && v->second_field) {
+ if (v->cur_field_type) {
+ INIT_LUT(v->lumscale, v->lumshift, v->curr_luty[v->cur_field_type ^ 1],
+ v->curr_lutuv[v->cur_field_type ^ 1], 0);
+ INIT_LUT(v->lumscale2, v->lumshift2, v->last_luty[v->cur_field_type],
+ v->last_lutuv[v->cur_field_type], 1);
+ } else {
+ INIT_LUT(v->lumscale2, v->lumshift2, v->curr_luty[v->cur_field_type ^ 1],
+ v->curr_lutuv[v->cur_field_type ^ 1], 0);
+ INIT_LUT(v->lumscale, v->lumshift, v->last_luty[v->cur_field_type],
+ v->last_lutuv[v->cur_field_type], 1);
+ }
+ v->next_use_ic = *v->curr_use_ic = 1;
+ } else {
+ INIT_LUT(v->lumscale, v->lumshift, v->last_luty[0], v->last_lutuv[0], 1);
+ INIT_LUT(v->lumscale2, v->lumshift2, v->last_luty[1], v->last_lutuv[1], 1);
+ }
+ v->last_use_ic = 1;
+ }
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ v->s.quarter_sample = (v->mv_mode2 != MV_PMODE_1MV_HPEL && v->mv_mode2 != MV_PMODE_1MV_HPEL_BILIN);
+ v->s.mspel = (v->mv_mode2 != MV_PMODE_1MV_HPEL_BILIN);
+ } else {
+ v->s.quarter_sample = (v->mv_mode != MV_PMODE_1MV_HPEL && v->mv_mode != MV_PMODE_1MV_HPEL_BILIN);
+ v->s.mspel = (v->mv_mode != MV_PMODE_1MV_HPEL_BILIN);
+ }
+ }
+ if (v->fcm == PROGRESSIVE) { // progressive
+ if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV) ||
+ v->mv_mode == MV_PMODE_MIXED_MV) {
+ status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ } else {
+ v->mv_type_is_raw = 0;
+ memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
+ }
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ /* Hopefully this is correct for P-frames */
+ v->mv_table_index = get_bits(gb, 2); // but using ff_vc1_ tables
+ v->cbptab = get_bits(gb, 2);
+ v->cbpcy_vlc = ff_vc1_cbpcy_p_vlc[v->cbptab];
+ } else if (v->fcm == ILACE_FRAME) { // frame interlaced
+ v->s.quarter_sample = 1;
+ v->s.mspel = 1;
+ } else { // field interlaced
+ v->mbmodetab = get_bits(gb, 3);
+ v->imvtab = get_bits(gb, 2 + v->numref);
+ if (!v->numref)
+ v->imv_vlc = ff_vc1_1ref_mvdata_vlc[v->imvtab];
+ else
+ v->imv_vlc = ff_vc1_2ref_mvdata_vlc[v->imvtab];
+ v->icbptab = get_bits(gb, 3);
+ v->cbpcy_vlc = ff_vc1_icbpcy_vlc[v->icbptab];
+ if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_MIXED_MV) ||
+ v->mv_mode == MV_PMODE_MIXED_MV) {
+ v->fourmvbptab = get_bits(gb, 2);
+ v->fourmvbp_vlc = ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab];
+ v->mbmode_vlc = ff_vc1_if_mmv_mbmode_vlc[v->mbmodetab];
+ } else {
+ v->mbmode_vlc = ff_vc1_if_1mv_mbmode_vlc[v->mbmodetab];
+ }
+ }
+ if (v->dquant) {
+
+ vop_dquant_decoding(v);
+ }
+
+ if (v->vstransform) {
+ v->ttmbf = get_bits1(gb);
+ if (v->ttmbf) {
+ v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
+ } else
+ v->ttfrm = 0; // FIXME Is that so ?
+ } else {
+ v->ttmbf = 1;
+ v->ttfrm = TT_8X8;
+ }
+ break;
+ case AV_PICTURE_TYPE_B:
+ if (v->fcm == ILACE_FRAME) {
+ if (read_bfraction(v, gb) < 0)
+ return (-1);
+ if (v->bfraction == 0) {
+ return -1;
+ }
+ }
+ if (v->extended_mv)
+ v->mvrange = get_unary(gb, 0, 3);
+ else
+ v->mvrange = 0;
+ v->k_x = v->mvrange + 9 + (v->mvrange >> 1); // k_x can be 9 10 12 13
+ v->k_y = v->mvrange + 8; // k_y can be 8 9 10 11
+ v->range_x = 1 << (v->k_x - 1);
+ v->range_y = 1 << (v->k_y - 1);
+
+ v->tt_index = (v->pq > 4) + (v->pq > 12);
+
+ if (v->field_mode) {
+ int mvmode;
+
+ if (v->extended_dmv)
+ v->dmvrange = get_unary(gb, 0, 3);
+ mvmode = get_unary(gb, 1, 3);
+ lowquant = (v->pq > 12) ? 0 : 1;
+ v->mv_mode = ff_vc1_mv_pmode_table2[lowquant][mvmode];
+ v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV || v->mv_mode == MV_PMODE_MIXED_MV);
+ v->s.mspel = (v->mv_mode != MV_PMODE_1MV_HPEL_BILIN);
+ status = bitplane_decoding(v->forward_mb_plane, &v->fmb_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ v->mbmodetab = get_bits(gb, 3);
+ if (v->mv_mode == MV_PMODE_MIXED_MV)
+ v->mbmode_vlc = ff_vc1_if_mmv_mbmode_vlc[v->mbmodetab];
+ else
+ v->mbmode_vlc = ff_vc1_if_1mv_mbmode_vlc[v->mbmodetab];
+ v->imvtab = get_bits(gb, 3);
+ v->imv_vlc = ff_vc1_2ref_mvdata_vlc[v->imvtab];
+ v->icbptab = get_bits(gb, 3);
+ v->cbpcy_vlc = ff_vc1_icbpcy_vlc[v->icbptab];
+ if (v->mv_mode == MV_PMODE_MIXED_MV) {
+ v->fourmvbptab = get_bits(gb, 2);
+ v->fourmvbp_vlc = ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab];
+ }
+ v->numref = 1; // interlaced field B pictures are always 2-ref
+ } else if (v->fcm == ILACE_FRAME) {
+ if (v->extended_dmv)
+ v->dmvrange = get_unary(gb, 0, 3);
+ if (get_bits1(gb)) /* intcomp - present but shall always be 0 */
+ warning("Intensity compensation set for B picture\n");
+ v->intcomp = 0;
+ v->mv_mode = MV_PMODE_1MV;
+ v->fourmvswitch = 0;
+ v->s.quarter_sample = 1;
+ v->s.mspel = 1;
+ status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ v->mbmodetab = get_bits(gb, 2);
+ v->mbmode_vlc = ff_vc1_intfr_non4mv_mbmode_vlc[v->mbmodetab];
+ v->imvtab = get_bits(gb, 2);
+ v->imv_vlc = ff_vc1_1ref_mvdata_vlc[v->imvtab];
+ // interlaced p/b-picture cbpcy range is [1, 63]
+ v->icbptab = get_bits(gb, 3);
+ v->cbpcy_vlc = ff_vc1_icbpcy_vlc[v->icbptab];
+ v->twomvbptab = get_bits(gb, 2);
+ v->twomvbp_vlc = ff_vc1_2mv_block_pattern_vlc[v->twomvbptab];
+ v->fourmvbptab = get_bits(gb, 2);
+ v->fourmvbp_vlc = ff_vc1_4mv_block_pattern_vlc[v->fourmvbptab];
+ } else {
+ v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
+ v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
+ v->s.mspel = v->s.quarter_sample;
+ status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ if (status < 0)
+ return -1;
+
+ v->mv_table_index = get_bits(gb, 2);
+ v->cbptab = get_bits(gb, 2);
+ v->cbpcy_vlc = ff_vc1_cbpcy_p_vlc[v->cbptab];
+ }
+
+ if (v->dquant) {
+
+ vop_dquant_decoding(v);
+ }
+
+ if (v->vstransform) {
+ v->ttmbf = get_bits1(gb);
+ if (v->ttmbf) {
+ v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
+ } else
+ v->ttfrm = 0;
+ } else {
+ v->ttmbf = 1;
+ v->ttfrm = TT_8X8;
+ }
+ break;
+ }
+
+ /* AC Syntax */
+ v->c_ac_table_index = decode012(gb);
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) {
+ v->y_ac_table_index = decode012(gb);
+ } else if (v->fcm != PROGRESSIVE && !v->s.quarter_sample) {
+ v->range_x <<= 1;
+ v->range_y <<= 1;
+ }
+
+ /* DC Syntax */
+ v->dc_table_index = get_bits1(gb);
+ if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) && v->dquant) {
+
+ vop_dquant_decoding(v);
+ }
+
+ v->bi_type = (v->s.pict_type == AV_PICTURE_TYPE_BI);
+ if (v->bi_type)
+ v->s.pict_type = AV_PICTURE_TYPE_B;
+
+ return 0;
+}
+
+#undef INIT_LUT
+#undef ROTATE
+
+static inline int scaleforsame_x(const VC1Context *v, int n /* MV */, int dir) {
+ int scaledvalue, refdist;
+ int scalesame1, scalesame2;
+ int scalezone1_x, zone1offset_x;
+ int table_index = dir ^ v->second_field;
+
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = v->refdist;
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ if (refdist > 3)
+ refdist = 3;
+ scalesame1 = ff_vc1_field_mvpred_scales[table_index][1][refdist];
+ scalesame2 = ff_vc1_field_mvpred_scales[table_index][2][refdist];
+ scalezone1_x = ff_vc1_field_mvpred_scales[table_index][3][refdist];
+ zone1offset_x = ff_vc1_field_mvpred_scales[table_index][5][refdist];
+
+ if (ABS(n) > 255)
+ scaledvalue = n;
+ else {
+ if (ABS(n) < scalezone1_x)
+ scaledvalue = (n * scalesame1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scalesame2) >> 8) - zone1offset_x;
+ else
+ scaledvalue = ((n * scalesame2) >> 8) + zone1offset_x;
+ }
+ }
+ return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
+}
+
+static inline int scaleforsame_y(const VC1Context *v, int n /* MV */, int dir) {
+ int scaledvalue, refdist;
+ int scalesame1, scalesame2;
+ int scalezone1_y, zone1offset_y;
+ int table_index = dir ^ v->second_field;
+
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = v->refdist;
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ if (refdist > 3)
+ refdist = 3;
+ scalesame1 = ff_vc1_field_mvpred_scales[table_index][1][refdist];
+ scalesame2 = ff_vc1_field_mvpred_scales[table_index][2][refdist];
+ scalezone1_y = ff_vc1_field_mvpred_scales[table_index][4][refdist];
+ zone1offset_y = ff_vc1_field_mvpred_scales[table_index][6][refdist];
+
+ if (ABS(n) > 63)
+ scaledvalue = n;
+ else {
+ if (ABS(n) < scalezone1_y)
+ scaledvalue = (n * scalesame1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scalesame2) >> 8) - zone1offset_y;
+ else
+ scaledvalue = ((n * scalesame2) >> 8) + zone1offset_y;
+ }
+ }
+
+ if (v->cur_field_type && !v->ref_field_type[dir])
+ return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
+ else
+ return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
+}
+
+static inline int scaleforopp_x(const VC1Context *v, int n /* MV */) {
+ int scalezone1_x, zone1offset_x;
+ int scaleopp1, scaleopp2, brfd;
+ int scaledvalue;
+
+ brfd = MIN(v->brfd, 3);
+ scalezone1_x = ff_vc1_b_field_mvpred_scales[3][brfd];
+ zone1offset_x = ff_vc1_b_field_mvpred_scales[5][brfd];
+ scaleopp1 = ff_vc1_b_field_mvpred_scales[1][brfd];
+ scaleopp2 = ff_vc1_b_field_mvpred_scales[2][brfd];
+
+ if (ABS(n) > 255)
+ scaledvalue = n;
+ else {
+ if (ABS(n) < scalezone1_x)
+ scaledvalue = (n * scaleopp1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_x;
+ else
+ scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_x;
+ }
+ }
+ return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
+}
+
+static inline int scaleforopp_y(const VC1Context *v, int n /* MV */, int dir) {
+ int scalezone1_y, zone1offset_y;
+ int scaleopp1, scaleopp2, brfd;
+ int scaledvalue;
+
+ brfd = MIN(v->brfd, 3);
+ scalezone1_y = ff_vc1_b_field_mvpred_scales[4][brfd];
+ zone1offset_y = ff_vc1_b_field_mvpred_scales[6][brfd];
+ scaleopp1 = ff_vc1_b_field_mvpred_scales[1][brfd];
+ scaleopp2 = ff_vc1_b_field_mvpred_scales[2][brfd];
+
+ if (ABS(n) > 63)
+ scaledvalue = n;
+ else {
+ if (ABS(n) < scalezone1_y)
+ scaledvalue = (n * scaleopp1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_y;
+ else
+ scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_y;
+ }
+ }
+ if (v->cur_field_type && !v->ref_field_type[dir]) {
+ return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
+ } else {
+ return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
+ }
+}
+
+static inline int scaleforsame(const VC1Context *v, int n /* MV */, int dim, int dir) {
+ int brfd, scalesame;
+ int hpel = 1 - v->s.quarter_sample;
+
+ n >>= hpel;
+ if (v->s.pict_type != AV_PICTURE_TYPE_B || v->second_field || !dir) {
+ if (dim)
+ n = scaleforsame_y(v, n, dir) * (1 << hpel);
+ else
+ n = scaleforsame_x(v, n, dir) * (1 << hpel);
+ return n;
+ }
+ brfd = MIN(v->brfd, 3);
+ scalesame = ff_vc1_b_field_mvpred_scales[0][brfd];
+
+ n = (n * scalesame >> 8) * (1 << hpel);
+ return n;
+}
+
+static inline int scaleforopp(const VC1Context *v, int n /* MV */, int dim, int dir) {
+ int refdist, scaleopp;
+ int hpel = 1 - v->s.quarter_sample;
+
+ n >>= hpel;
+ if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) {
+ if (dim)
+ n = scaleforopp_y(v, n, dir) * (1 << hpel);
+ else
+ n = scaleforopp_x(v, n) * (1 << hpel);
+ return n;
+ }
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = v->refdist;
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ refdist = MIN(refdist, 3);
+ scaleopp = ff_vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist];
+
+ n = (n * scaleopp >> 8) * (1 << hpel);
+ return n;
+}
+
+/** Predict and set motion vector
+ */
+void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8 *is_intra,
+ int pred_flag, int dir) {
+ PictureState *s = &v->s;
+ int xy, wrap, off = 0;
+ int px, py;
+ int sum;
+ int mixedmv_pic, num_samefield = 0, num_oppfield = 0;
+ int opposite, a_f, b_f, c_f;
+ int16 field_predA[2];
+ int16 field_predB[2];
+ int16 field_predC[2];
+ int a_valid, b_valid, c_valid;
+ int hybridmv_thresh, y_bias = 0;
+
+ if (v->mv_mode == MV_PMODE_MIXED_MV ||
+ ((v->mv_mode == MV_PMODE_INTENSITY_COMP) && (v->mv_mode2 == MV_PMODE_MIXED_MV)))
+ mixedmv_pic = 1;
+ else
+ mixedmv_pic = 0;
+ /* scale MV difference to be quad-pel */
+ if (!s->quarter_sample) {
+ dmv_x *= 2;
+ dmv_y *= 2;
+ }
+
+ wrap = s->b8_stride;
+ xy = s->block_index[n];
+
+ if (s->mb_intra) {
+ s->mv[0][n][0] = s->cur_pic.motion_val[0][xy + v->blocks_off][0] = 0;
+ s->mv[0][n][1] = s->cur_pic.motion_val[0][xy + v->blocks_off][1] = 0;
+ s->cur_pic.motion_val[1][xy + v->blocks_off][0] = 0;
+ s->cur_pic.motion_val[1][xy + v->blocks_off][1] = 0;
+ if (mv1) { /* duplicate motion data for 1-MV block */
+ s->cur_pic.motion_val[0][xy + 1 + v->blocks_off][0] = 0;
+ s->cur_pic.motion_val[0][xy + 1 + v->blocks_off][1] = 0;
+ s->cur_pic.motion_val[0][xy + wrap + v->blocks_off][0] = 0;
+ s->cur_pic.motion_val[0][xy + wrap + v->blocks_off][1] = 0;
+ s->cur_pic.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
+ s->cur_pic.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
+ v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
+ s->cur_pic.motion_val[1][xy + 1 + v->blocks_off][0] = 0;
+ s->cur_pic.motion_val[1][xy + 1 + v->blocks_off][1] = 0;
+ s->cur_pic.motion_val[1][xy + wrap + v->blocks_off][0] = 0;
+ s->cur_pic.motion_val[1][xy + wrap + v->blocks_off][1] = 0;
+ s->cur_pic.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
+ s->cur_pic.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
+ }
+ return;
+ }
+
+ a_valid = !s->first_slice_line || (n == 2 || n == 3);
+ b_valid = a_valid;
+ c_valid = s->mb_x || (n == 1 || n == 3);
+ if (mv1) {
+ if (v->field_mode && mixedmv_pic)
+ off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
+ else
+ off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
+ b_valid = b_valid && s->mb_width > 1;
+ } else {
+ // in 4-MV mode different blocks have different B predictor position
+ switch (n) {
+ case 0:
+ if (v->res_rtm_flag)
+ off = s->mb_x ? -1 : 1;
+ else
+ off = s->mb_x ? -1 : 2 * s->mb_width - wrap - 1;
+ break;
+ case 1:
+ off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
+ break;
+ case 2:
+ off = 1;
+ break;
+ case 3:
+ off = -1;
+ }
+ if (v->field_mode && s->mb_width == 1)
+ b_valid = b_valid && c_valid;
+ }
+
+ if (v->field_mode) {
+ a_valid = a_valid && !is_intra[xy - wrap];
+ b_valid = b_valid && !is_intra[xy - wrap + off];
+ c_valid = c_valid && !is_intra[xy - 1];
+ }
+
+ if (a_valid) {
+ const int16 *A = s->cur_pic.motion_val[dir][xy - wrap + v->blocks_off];
+ a_f = v->mv_f[dir][xy - wrap + v->blocks_off];
+ num_oppfield += a_f;
+ num_samefield += 1 - a_f;
+ field_predA[0] = A[0];
+ field_predA[1] = A[1];
+ } else {
+ field_predA[0] = field_predA[1] = 0;
+ a_f = 0;
+ }
+ if (b_valid) {
+ const int16 *B = s->cur_pic.motion_val[dir][xy - wrap + off + v->blocks_off];
+ b_f = v->mv_f[dir][xy - wrap + off + v->blocks_off];
+ num_oppfield += b_f;
+ num_samefield += 1 - b_f;
+ field_predB[0] = B[0];
+ field_predB[1] = B[1];
+ } else {
+ field_predB[0] = field_predB[1] = 0;
+ b_f = 0;
+ }
+ if (c_valid) {
+ const int16 *C = s->cur_pic.motion_val[dir][xy - 1 + v->blocks_off];
+ c_f = v->mv_f[dir][xy - 1 + v->blocks_off];
+ num_oppfield += c_f;
+ num_samefield += 1 - c_f;
+ field_predC[0] = C[0];
+ field_predC[1] = C[1];
+ } else {
+ field_predC[0] = field_predC[1] = 0;
+ c_f = 0;
+ }
+
+ if (v->field_mode) {
+ if (!v->numref)
+ // REFFIELD determines if the last field or the second-last field is
+ // to be used as reference
+ opposite = 1 - v->reffield;
+ else {
+ if (num_samefield <= num_oppfield)
+ opposite = 1 - pred_flag;
+ else
+ opposite = pred_flag;
+ }
+ } else
+ opposite = 0;
+ if (opposite) {
+ v->mv_f[dir][xy + v->blocks_off] = 1;
+ v->ref_field_type[dir] = !v->cur_field_type;
+ if (a_valid && !a_f) {
+ field_predA[0] = scaleforopp(v, field_predA[0], 0, dir);
+ field_predA[1] = scaleforopp(v, field_predA[1], 1, dir);
+ }
+ if (b_valid && !b_f) {
+ field_predB[0] = scaleforopp(v, field_predB[0], 0, dir);
+ field_predB[1] = scaleforopp(v, field_predB[1], 1, dir);
+ }
+ if (c_valid && !c_f) {
+ field_predC[0] = scaleforopp(v, field_predC[0], 0, dir);
+ field_predC[1] = scaleforopp(v, field_predC[1], 1, dir);
+ }
+ } else {
+ v->mv_f[dir][xy + v->blocks_off] = 0;
+ v->ref_field_type[dir] = v->cur_field_type;
+ if (a_valid && a_f) {
+ field_predA[0] = scaleforsame(v, field_predA[0], 0, dir);
+ field_predA[1] = scaleforsame(v, field_predA[1], 1, dir);
+ }
+ if (b_valid && b_f) {
+ field_predB[0] = scaleforsame(v, field_predB[0], 0, dir);
+ field_predB[1] = scaleforsame(v, field_predB[1], 1, dir);
+ }
+ if (c_valid && c_f) {
+ field_predC[0] = scaleforsame(v, field_predC[0], 0, dir);
+ field_predC[1] = scaleforsame(v, field_predC[1], 1, dir);
+ }
+ }
+
+ if (a_valid) {
+ px = field_predA[0];
+ py = field_predA[1];
+ } else if (c_valid) {
+ px = field_predC[0];
+ py = field_predC[1];
+ } else if (b_valid) {
+ px = field_predB[0];
+ py = field_predB[1];
+ } else {
+ px = 0;
+ py = 0;
+ }
+
+ if (num_samefield + num_oppfield > 1) {
+ px = mid_pred(field_predA[0], field_predB[0], field_predC[0]);
+ py = mid_pred(field_predA[1], field_predB[1], field_predC[1]);
+ }
+
+ /* Pullback MV as specified in 8.3.5.3.4 */
+ if (!v->field_mode) {
+ int qx, qy, X, Y;
+ int MV = mv1 ? -60 : -28;
+ qx = (s->mb_x << 6) + ((n == 1 || n == 3) ? 32 : 0);
+ qy = (s->mb_y << 6) + ((n == 2 || n == 3) ? 32 : 0);
+ X = (s->mb_width << 6) - 4;
+ Y = (s->mb_height << 6) - 4;
+ if (qx + px < MV)
+ px = MV - qx;
+ if (qy + py < MV)
+ py = MV - qy;
+ if (qx + px > X)
+ px = X - qx;
+ if (qy + py > Y)
+ py = Y - qy;
+ }
+
+ if (!v->field_mode || s->pict_type != AV_PICTURE_TYPE_B) {
+ /* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */
+ hybridmv_thresh = 32;
+ if (a_valid && c_valid) {
+ if (is_intra[xy - wrap])
+ sum = ABS(px) + ABS(py);
+ else
+ sum = ABS(px - field_predA[0]) + ABS(py - field_predA[1]);
+ if (sum > hybridmv_thresh) {
+ if (get_bits1(&v->gb)) { // read HYBRIDPRED bit
+ px = field_predA[0];
+ py = field_predA[1];
+ } else {
+ px = field_predC[0];
+ py = field_predC[1];
+ }
+ } else {
+ if (is_intra[xy - 1])
+ sum = ABS(px) + ABS(py);
+ else
+ sum = ABS(px - field_predC[0]) + ABS(py - field_predC[1]);
+ if (sum > hybridmv_thresh) {
+ if (get_bits1(&v->gb)) {
+ px = field_predA[0];
+ py = field_predA[1];
+ } else {
+ px = field_predC[0];
+ py = field_predC[1];
+ }
+ }
+ }
+ }
+ }
+
+ if (v->field_mode && v->numref)
+ r_y >>= 1;
+ if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
+ y_bias = 1;
+ /* store MV using signed modulus of MV range defined in 4.11 */
+ s->mv[dir][n][0] = s->cur_pic.motion_val[dir][xy + v->blocks_off][0] =
+ ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[dir][n][1] = s->cur_pic.motion_val[dir][xy + v->blocks_off][1] =
+ ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
+ if (mv1) { /* duplicate motion data for 1-MV block */
+ s->cur_pic.motion_val[dir][xy + 1 + v->blocks_off][0] = s->cur_pic.motion_val[dir][xy + v->blocks_off][0];
+ s->cur_pic.motion_val[dir][xy + 1 + v->blocks_off][1] = s->cur_pic.motion_val[dir][xy + v->blocks_off][1];
+ s->cur_pic.motion_val[dir][xy + wrap + v->blocks_off][0] = s->cur_pic.motion_val[dir][xy + v->blocks_off][0];
+ s->cur_pic.motion_val[dir][xy + wrap + v->blocks_off][1] = s->cur_pic.motion_val[dir][xy + v->blocks_off][1];
+ s->cur_pic.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] =
+ s->cur_pic.motion_val[dir][xy + v->blocks_off][0];
+ s->cur_pic.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] =
+ s->cur_pic.motion_val[dir][xy + v->blocks_off][1];
+ v->mv_f[dir][xy + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
+ v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] =
+ v->mv_f[dir][xy + v->blocks_off];
+ }
+}
+
+/** Predict and set motion vector for interlaced frame picture MBs
+ */
+void ff_vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, int mvn, int r_x, int r_y, int dir) {
+ PictureState *s = &v->s;
+ int xy, wrap, off = 0;
+ int A[2], B[2], C[2];
+ int px = 0, py = 0;
+ int a_valid = 0, b_valid = 0, c_valid = 0;
+ int field_a, field_b, field_c; // 0: same, 1: opposite
+ int total_valid, num_samefield, num_oppfield;
+ int pos_c, pos_b, n_adj;
+
+ wrap = s->b8_stride;
+ xy = s->block_index[n];
+
+ if (s->mb_intra) {
+ s->mv[0][n][0] = s->cur_pic.motion_val[0][xy][0] = 0;
+ s->mv[0][n][1] = s->cur_pic.motion_val[0][xy][1] = 0;
+ s->cur_pic.motion_val[1][xy][0] = 0;
+ s->cur_pic.motion_val[1][xy][1] = 0;
+ if (mvn == 1) { /* duplicate motion data for 1-MV block */
+ s->cur_pic.motion_val[0][xy + 1][0] = 0;
+ s->cur_pic.motion_val[0][xy + 1][1] = 0;
+ s->cur_pic.motion_val[0][xy + wrap][0] = 0;
+ s->cur_pic.motion_val[0][xy + wrap][1] = 0;
+ s->cur_pic.motion_val[0][xy + wrap + 1][0] = 0;
+ s->cur_pic.motion_val[0][xy + wrap + 1][1] = 0;
+ v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
+ s->cur_pic.motion_val[1][xy + 1][0] = 0;
+ s->cur_pic.motion_val[1][xy + 1][1] = 0;
+ s->cur_pic.motion_val[1][xy + wrap][0] = 0;
+ s->cur_pic.motion_val[1][xy + wrap][1] = 0;
+ s->cur_pic.motion_val[1][xy + wrap + 1][0] = 0;
+ s->cur_pic.motion_val[1][xy + wrap + 1][1] = 0;
+ }
+ return;
+ }
+
+ off = ((n == 0) || (n == 1)) ? 1 : -1;
+ /* predict A */
+ if (s->mb_x || (n == 1) || (n == 3)) {
+ if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
+ || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
+ A[0] = s->cur_pic.motion_val[dir][xy - 1][0];
+ A[1] = s->cur_pic.motion_val[dir][xy - 1][1];
+ a_valid = 1;
+ } else { // current block has frame mv and cand. has field MV (so average)
+ A[0] =
+ (s->cur_pic.motion_val[dir][xy - 1][0] + s->cur_pic.motion_val[dir][xy - 1 + off * wrap][0] + 1) >> 1;
+ A[1] =
+ (s->cur_pic.motion_val[dir][xy - 1][1] + s->cur_pic.motion_val[dir][xy - 1 + off * wrap][1] + 1) >> 1;
+ a_valid = 1;
+ }
+ if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
+ a_valid = 0;
+ A[0] = A[1] = 0;
+ }
+ } else
+ A[0] = A[1] = 0;
+ /* Predict B and C */
+ B[0] = B[1] = C[0] = C[1] = 0;
+ if (n == 0 || n == 1 || v->blk_mv_type[xy]) {
+ if (!s->first_slice_line) {
+ if (!v->is_intra[s->mb_x - s->mb_stride]) {
+ b_valid = 1;
+ n_adj = n | 2;
+ pos_b = s->block_index[n_adj] - 2 * wrap;
+ if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
+ n_adj = (n & 2) | (n & 1);
+ }
+ B[0] = s->cur_pic.motion_val[dir][s->block_index[n_adj] - 2 * wrap][0];
+ B[1] = s->cur_pic.motion_val[dir][s->block_index[n_adj] - 2 * wrap][1];
+ if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
+ B[0] = (B[0] + s->cur_pic.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
+ B[1] = (B[1] + s->cur_pic.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
+ }
+ }
+ if (s->mb_width > 1) {
+ if (!v->is_intra[s->mb_x - s->mb_stride + 1]) {
+ c_valid = 1;
+ n_adj = 2;
+ pos_c = s->block_index[2] - 2 * wrap + 2;
+ if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
+ n_adj = n & 2;
+ }
+ C[0] = s->cur_pic.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][0];
+ C[1] = s->cur_pic.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][1];
+ if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
+ C[0] =
+ (1 + C[0] + (s->cur_pic.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
+ C[1] =
+ (1 + C[1] + (s->cur_pic.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
+ c_valid = 1;
+ n_adj = 3;
+ pos_c = s->block_index[3] - 2 * wrap - 2;
+ if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
+ n_adj = n | 1;
+ }
+ C[0] = s->cur_pic.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][0];
+ C[1] = s->cur_pic.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][1];
+ if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
+ C[0] =
+ (1 + C[0] + s->cur_pic.motion_val[dir][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
+ C[1] =
+ (1 + C[1] + s->cur_pic.motion_val[dir][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
+ }
+ } else
+ c_valid = 0;
+ }
+ }
+ }
+ }
+ } else {
+ pos_b = s->block_index[1];
+ b_valid = 1;
+ B[0] = s->cur_pic.motion_val[dir][pos_b][0];
+ B[1] = s->cur_pic.motion_val[dir][pos_b][1];
+ pos_c = s->block_index[0];
+ c_valid = 1;
+ C[0] = s->cur_pic.motion_val[dir][pos_c][0];
+ C[1] = s->cur_pic.motion_val[dir][pos_c][1];
+ }
+
+ total_valid = a_valid + b_valid + c_valid;
+ // check if predictor A is out of bounds
+ if (!s->mb_x && !(n == 1 || n == 3)) {
+ A[0] = A[1] = 0;
+ }
+ // check if predictor B is out of bounds
+ if ((s->first_slice_line && v->blk_mv_type[xy]) || (s->first_slice_line && !(n & 2))) {
+ B[0] = B[1] = C[0] = C[1] = 0;
+ }
+ if (!v->blk_mv_type[xy]) {
+ if (s->mb_width == 1) {
+ px = B[0];
+ py = B[1];
+ } else {
+ if (total_valid >= 2) {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ } else if (total_valid) {
+ if (a_valid) {
+ px = A[0];
+ py = A[1];
+ } else if (b_valid) {
+ px = B[0];
+ py = B[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ }
+ }
+ } else {
+ if (a_valid)
+ field_a = (A[1] & 4) ? 1 : 0;
+ else
+ field_a = 0;
+ if (b_valid)
+ field_b = (B[1] & 4) ? 1 : 0;
+ else
+ field_b = 0;
+ if (c_valid)
+ field_c = (C[1] & 4) ? 1 : 0;
+ else
+ field_c = 0;
+
+ num_oppfield = field_a + field_b + field_c;
+ num_samefield = total_valid - num_oppfield;
+ if (total_valid == 3) {
+ if ((num_samefield == 3) || (num_oppfield == 3)) {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ } else if (num_samefield >= num_oppfield) {
+ /* take one MV from same field set depending on priority
+ the check for B may not be necessary */
+ px = !field_a ? A[0] : B[0];
+ py = !field_a ? A[1] : B[1];
+ } else {
+ px = field_a ? A[0] : B[0];
+ py = field_a ? A[1] : B[1];
+ }
+ } else if (total_valid == 2) {
+ if (num_samefield >= num_oppfield) {
+ if (!field_a && a_valid) {
+ px = A[0];
+ py = A[1];
+ } else if (!field_b && b_valid) {
+ px = B[0];
+ py = B[1];
+ } else /*if (c_valid)*/ {
+ assert(c_valid);
+ px = C[0];
+ py = C[1];
+ }
+ } else {
+ if (field_a && a_valid) {
+ px = A[0];
+ py = A[1];
+ } else /*if (field_b && b_valid)*/ {
+ assert(field_b && b_valid);
+ px = B[0];
+ py = B[1];
+ }
+ }
+ } else if (total_valid == 1) {
+ px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
+ py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]);
+ }
+ }
+
+ /* store MV using signed modulus of MV range defined in 4.11 */
+ s->mv[dir][n][0] = s->cur_pic.motion_val[dir][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[dir][n][1] = s->cur_pic.motion_val[dir][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
+ if (mvn == 1) { /* duplicate motion data for 1-MV block */
+ s->cur_pic.motion_val[dir][xy + 1][0] = s->cur_pic.motion_val[dir][xy][0];
+ s->cur_pic.motion_val[dir][xy + 1][1] = s->cur_pic.motion_val[dir][xy][1];
+ s->cur_pic.motion_val[dir][xy + wrap][0] = s->cur_pic.motion_val[dir][xy][0];
+ s->cur_pic.motion_val[dir][xy + wrap][1] = s->cur_pic.motion_val[dir][xy][1];
+ s->cur_pic.motion_val[dir][xy + wrap + 1][0] = s->cur_pic.motion_val[dir][xy][0];
+ s->cur_pic.motion_val[dir][xy + wrap + 1][1] = s->cur_pic.motion_val[dir][xy][1];
+ } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
+ s->cur_pic.motion_val[dir][xy + 1][0] = s->cur_pic.motion_val[dir][xy][0];
+ s->cur_pic.motion_val[dir][xy + 1][1] = s->cur_pic.motion_val[dir][xy][1];
+ s->mv[dir][n + 1][0] = s->mv[dir][n][0];
+ s->mv[dir][n + 1][1] = s->mv[dir][n][1];
+ }
+}
+
+void ff_vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mvtype) {
+ PictureState *s = &v->s;
+ int xy, wrap;
+ int px, py;
+ int sum;
+ int r_x, r_y;
+ const uint8 *is_intra = v->mb_type;
+
+ assert(!v->field_mode);
+
+ r_x = v->range_x;
+ r_y = v->range_y;
+ /* scale MV difference to be quad-pel */
+ if (!s->quarter_sample) {
+ dmv_x[0] *= 2;
+ dmv_y[0] *= 2;
+ dmv_x[1] *= 2;
+ dmv_y[1] *= 2;
+ }
+
+ wrap = s->b8_stride;
+ xy = s->block_index[0];
+
+ if (s->mb_intra) {
+ s->cur_pic.motion_val[0][xy][0] = s->cur_pic.motion_val[0][xy][1] = s->cur_pic.motion_val[1][xy][0] =
+ s->cur_pic.motion_val[1][xy][1] = 0;
+ return;
+ }
+ if (direct && s->next_pic.ptr->field_picture)
+ warning("Mixed frame/field direct mode not supported\n");
+
+ s->mv[0][0][0] = scale_mv(s->next_pic.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = scale_mv(s->next_pic.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = scale_mv(s->next_pic.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = scale_mv(s->next_pic.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
+
+ /* Pullback predicted motion vectors as specified in 8.4.5.4 */
+ s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
+ s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
+ s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
+ s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
+ if (direct) {
+ s->cur_pic.motion_val[0][xy][0] = s->mv[0][0][0];
+ s->cur_pic.motion_val[0][xy][1] = s->mv[0][0][1];
+ s->cur_pic.motion_val[1][xy][0] = s->mv[1][0][0];
+ s->cur_pic.motion_val[1][xy][1] = s->mv[1][0][1];
+ return;
+ }
+
+ if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
+ int16 *C = s->cur_pic.motion_val[0][xy - 2];
+ const int16 *A = s->cur_pic.motion_val[0][xy - wrap * 2];
+ int off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
+ const int16 *B = s->cur_pic.motion_val[0][xy - wrap * 2 + off];
+
+ if (!s->mb_x)
+ C[0] = C[1] = 0;
+ if (!s->first_slice_line) { // predictor A is not out of bounds
+ if (s->mb_width == 1) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ }
+ } else if (s->mb_x) { // predictor C is not out of bounds
+ px = C[0];
+ py = C[1];
+ } else {
+ px = py = 0;
+ }
+ /* Pullback MV as specified in 8.3.5.3.4 */
+ {
+ int qx, qy, X, Y;
+ int sh = v->profile < PROFILE_ADVANCED ? 5 : 6;
+ int MV = 4 - (1 << sh);
+ qx = (s->mb_x << sh);
+ qy = (s->mb_y << sh);
+ X = (s->mb_width << sh) - 4;
+ Y = (s->mb_height << sh) - 4;
+ if (qx + px < MV)
+ px = MV - qx;
+ if (qy + py < MV)
+ py = MV - qy;
+ if (qx + px > X)
+ px = X - qx;
+ if (qy + py > Y)
+ py = Y - qy;
+ }
+ /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
+ if (0 && !s->first_slice_line && s->mb_x) {
+ if (is_intra[xy - wrap])
+ sum = ABS(px) + ABS(py);
+ else
+ sum = ABS(px - A[0]) + ABS(py - A[1]);
+ if (sum > 32) {
+ if (get_bits1(&v->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ } else {
+ if (is_intra[xy - 2])
+ sum = ABS(px) + ABS(py);
+ else
+ sum = ABS(px - C[0]) + ABS(py - C[1]);
+ if (sum > 32) {
+ if (get_bits1(&v->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ }
+ }
+ }
+ /* store MV using signed modulus of MV range defined in 4.11 */
+ s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
+ }
+ if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
+ int16 *C = s->cur_pic.motion_val[1][xy - 2];
+ const int16 *A = s->cur_pic.motion_val[1][xy - wrap * 2];
+ int off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
+ const int16 *B = s->cur_pic.motion_val[1][xy - wrap * 2 + off];
+
+ if (!s->mb_x)
+ C[0] = C[1] = 0;
+ if (!s->first_slice_line) { // predictor A is not out of bounds
+ if (s->mb_width == 1) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ }
+ } else if (s->mb_x) { // predictor C is not out of bounds
+ px = C[0];
+ py = C[1];
+ } else {
+ px = py = 0;
+ }
+ /* Pullback MV as specified in 8.3.5.3.4 */
+ {
+ int qx, qy, X, Y;
+ int sh = v->profile < PROFILE_ADVANCED ? 5 : 6;
+ int MV = 4 - (1 << sh);
+ qx = (s->mb_x << sh);
+ qy = (s->mb_y << sh);
+ X = (s->mb_width << sh) - 4;
+ Y = (s->mb_height << sh) - 4;
+ if (qx + px < MV)
+ px = MV - qx;
+ if (qy + py < MV)
+ py = MV - qy;
+ if (qx + px > X)
+ px = X - qx;
+ if (qy + py > Y)
+ py = Y - qy;
+ }
+ /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
+ if (0 && !s->first_slice_line && s->mb_x) {
+ if (is_intra[xy - wrap])
+ sum = ABS(px) + ABS(py);
+ else
+ sum = ABS(px - A[0]) + ABS(py - A[1]);
+ if (sum > 32) {
+ if (get_bits1(&v->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ } else {
+ if (is_intra[xy - 2])
+ sum = ABS(px) + ABS(py);
+ else
+ sum = ABS(px - C[0]) + ABS(py - C[1]);
+ if (sum > 32) {
+ if (get_bits1(&v->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ }
+ }
+ }
+ /* store MV using signed modulus of MV range defined in 4.11 */
+
+ s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
+ }
+ s->cur_pic.motion_val[0][xy][0] = s->mv[0][0][0];
+ s->cur_pic.motion_val[0][xy][1] = s->mv[0][0][1];
+ s->cur_pic.motion_val[1][xy][0] = s->mv[1][0][0];
+ s->cur_pic.motion_val[1][xy][1] = s->mv[1][0][1];
+}
+
+void ff_vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag) {
+ int dir = (v->bmvtype == BMV_TYPE_BACKWARD) ? 1 : 0;
+ PictureState *s = &v->s;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ if (v->bmvtype == BMV_TYPE_DIRECT) {
+ int total_opp, k, f;
+ if (s->next_pic.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
+ s->mv[0][0][0] = scale_mv(s->next_pic.motion_val[1][s->block_index[0] + v->blocks_off][0], v->bfraction, 0,
+ s->quarter_sample);
+ s->mv[0][0][1] = scale_mv(s->next_pic.motion_val[1][s->block_index[0] + v->blocks_off][1], v->bfraction, 0,
+ s->quarter_sample);
+ s->mv[1][0][0] = scale_mv(s->next_pic.motion_val[1][s->block_index[0] + v->blocks_off][0], v->bfraction, 1,
+ s->quarter_sample);
+ s->mv[1][0][1] = scale_mv(s->next_pic.motion_val[1][s->block_index[0] + v->blocks_off][1], v->bfraction, 1,
+ s->quarter_sample);
+
+ total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off] +
+ v->mv_f_next[0][s->block_index[1] + v->blocks_off] +
+ v->mv_f_next[0][s->block_index[2] + v->blocks_off] +
+ v->mv_f_next[0][s->block_index[3] + v->blocks_off];
+ f = (total_opp > 2) ? 1 : 0;
+ } else {
+ s->mv[0][0][0] = s->mv[0][0][1] = 0;
+ s->mv[1][0][0] = s->mv[1][0][1] = 0;
+ f = 0;
+ }
+ v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
+ for (k = 0; k < 4; k++) {
+ s->cur_pic.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
+ s->cur_pic.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
+ s->cur_pic.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
+ s->cur_pic.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
+ v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
+ v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
+ }
+ return;
+ }
+ if (v->bmvtype == BMV_TYPE_INTERPOLATED) {
+ ff_vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type, pred_flag[0], 0);
+ ff_vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type, pred_flag[1], 1);
+ return;
+ }
+ if (dir) { // backward
+ ff_vc1_pred_mv(v, n, dmv_x[1], dmv_y[1], mv1, v->range_x, v->range_y, v->mb_type, pred_flag[1], 1);
+ if (n == 3 || mv1) {
+ ff_vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type, 0, 0);
+ }
+ } else { // forward
+ ff_vc1_pred_mv(v, n, dmv_x[0], dmv_y[0], mv1, v->range_x, v->range_y, v->mb_type, pred_flag[0], 0);
+ if (n == 3 || mv1) {
+ ff_vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type, 0, 1);
+ }
+ }
+}
+
+static inline void vc1_h_overlap_filter(VC1Context *v, int16 (*left_block)[64], int16 (*right_block)[64],
+ int left_fieldtx, int right_fieldtx, int block_num) {
+ switch (block_num) {
+ case 0:
+ v->vc1dsp.vc1_h_s_overlap(
+ left_block[2], right_block[0], left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8,
+ left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8, left_fieldtx || right_fieldtx ? 0 : 1);
+ break;
+
+ case 1:
+ v->vc1dsp.vc1_h_s_overlap(right_block[0], right_block[2], 8, 8, right_fieldtx ? 0 : 1);
+ break;
+
+ case 2:
+ v->vc1dsp.vc1_h_s_overlap(!left_fieldtx && right_fieldtx ? left_block[2] + 8 : left_block[3],
+ left_fieldtx && !right_fieldtx ? right_block[0] + 8 : right_block[1],
+ left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8,
+ left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8,
+ left_fieldtx || right_fieldtx ? 2 : 1);
+ break;
+
+ case 3:
+ v->vc1dsp.vc1_h_s_overlap(right_block[1], right_block[3], 8, 8, right_fieldtx ? 2 : 1);
+ break;
+
+ case 4:
+ case 5:
+ v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num], 8, 8, 1);
+ break;
+ }
+}
+
+static inline void vc1_v_overlap_filter(VC1Context *v, int16 (*top_block)[64], int16 (*bottom_block)[64],
+ int block_num) {
+ switch (block_num) {
+ case 0:
+ v->vc1dsp.vc1_v_s_overlap(top_block[1], bottom_block[0]);
+ break;
+
+ case 1:
+ v->vc1dsp.vc1_v_s_overlap(top_block[3], bottom_block[2]);
+ break;
+
+ case 2:
+ v->vc1dsp.vc1_v_s_overlap(bottom_block[0], bottom_block[1]);
+ break;
+
+ case 3:
+ v->vc1dsp.vc1_v_s_overlap(bottom_block[2], bottom_block[3]);
+ break;
+
+ case 4:
+ case 5:
+ v->vc1dsp.vc1_v_s_overlap(top_block[block_num], bottom_block[block_num]);
+ break;
+ }
+}
+
+void ff_vc1_i_overlap_filter(VC1Context *v) {
+ PictureState *s = &v->s;
+ int16(*topleft_blk)[64], (*top_blk)[64], (*left_blk)[64], (*cur_blk)[64];
+ int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int i;
+
+ topleft_blk = v->block[v->topleft_blk_idx];
+ top_blk = v->block[v->top_blk_idx];
+ left_blk = v->block[v->left_blk_idx];
+ cur_blk = v->block[v->cur_blk_idx];
+
+ /* Within a MB, the horizontal overlap always runs before the vertical.
+ * To accomplish that, we run the H on the left and internal vertical
+ * borders of the currently decoded MB. Then, we wait for the next overlap
+ * iteration to do H overlap on the right edge of this MB, before moving
+ * over and running the V overlap on the top and internal horizontal
+ * borders. Therefore, the H overlap trails by one MB col and the
+ * V overlap trails by one MB row. This is reflected in the time at which
+ * we run the put_pixels loop, i.e. delayed by one row and one column. */
+ for (i = 0; i < block_count; i++) {
+ if (s->mb_x == 0 && (i & 5) != 1)
+ continue;
+
+ if (v->pq >= 9 || (v->profile == PROFILE_ADVANCED &&
+ (v->condover == CONDOVER_ALL ||
+ (v->over_flags_plane[mb_pos] && ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1])))))
+ vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk,
+ v->fcm == ILACE_FRAME && s->mb_x && v->fieldtx_plane[mb_pos - 1],
+ v->fcm == ILACE_FRAME && v->fieldtx_plane[mb_pos], i);
+ }
+
+ if (v->fcm != ILACE_FRAME)
+ for (i = 0; i < block_count; i++) {
+ if (s->first_slice_line && !(i & 2))
+ continue;
+
+ if (s->mb_x &&
+ (v->pq >= 9 ||
+ (v->profile == PROFILE_ADVANCED &&
+ (v->condover == CONDOVER_ALL ||
+ (v->over_flags_plane[mb_pos - 1] && ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride]))))))
+ vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i);
+ if (s->mb_x == s->mb_width - 1 &&
+ (v->pq >= 9 ||
+ (v->profile == PROFILE_ADVANCED &&
+ (v->condover == CONDOVER_ALL ||
+ (v->over_flags_plane[mb_pos] && ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride]))))))
+ vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i);
+ }
+}
+
+void ff_vc1_p_overlap_filter(VC1Context *v) {
+ PictureState *s = &v->s;
+ int16(*topleft_blk)[64], (*top_blk)[64], (*left_blk)[64], (*cur_blk)[64];
+ int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int i;
+
+ topleft_blk = v->block[v->topleft_blk_idx];
+ top_blk = v->block[v->top_blk_idx];
+ left_blk = v->block[v->left_blk_idx];
+ cur_blk = v->block[v->cur_blk_idx];
+
+ for (i = 0; i < block_count; i++) {
+ if (s->mb_x == 0 && (i & 5) != 1)
+ continue;
+
+ if (v->mb_type[s->block_index[i]] && v->mb_type[s->block_index[i] - 1])
+ vc1_h_overlap_filter(v, s->mb_x ? left_blk : cur_blk, cur_blk,
+ v->fcm == ILACE_FRAME && s->mb_x && v->fieldtx_plane[mb_pos - 1],
+ v->fcm == ILACE_FRAME && v->fieldtx_plane[mb_pos], i);
+ }
+
+ if (v->fcm != ILACE_FRAME)
+ for (i = 0; i < block_count; i++) {
+ if (s->first_slice_line && !(i & 2))
+ continue;
+
+ if (s->mb_x && v->mb_type[s->block_index[i] - 2 + (i > 3)] &&
+ v->mb_type[s->block_index[i] - s->block_wrap[i] - 2 + (i > 3)])
+ vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i);
+ if (s->mb_x == s->mb_width - 1)
+ if (v->mb_type[s->block_index[i]] && v->mb_type[s->block_index[i] - s->block_wrap[i]])
+ vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i);
+ }
+}
+
+#define LEFT_EDGE (1 << 0)
+#define RIGHT_EDGE (1 << 1)
+#define TOP_EDGE (1 << 2)
+#define BOTTOM_EDGE (1 << 3)
+
+static inline void vc1_i_h_loop_filter(VC1Context *v, uint8 *dest, uint32 flags, int block_num) {
+ PictureState *s = &v->s;
+ int pq = v->pq;
+ uint8 *dst;
+
+ if (block_num & 2)
+ return;
+
+ if (!(flags & LEFT_EDGE) || (block_num & 5) == 1) {
+ if (block_num > 3)
+ dst = dest;
+ else
+ dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
+
+ if (v->fcm == ILACE_FRAME)
+ if (block_num > 3) {
+ v->vc1dsp.vc1_h_loop_filter4(dst, 2 * s->uvlinesize, pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst + s->uvlinesize, 2 * s->uvlinesize, pq);
+ } else {
+ v->vc1dsp.vc1_h_loop_filter8(dst, 2 * s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter8(dst + s->linesize, 2 * s->linesize, pq);
+ }
+ else if (block_num > 3)
+ v->vc1dsp.vc1_h_loop_filter8(dst, s->uvlinesize, pq);
+ else
+ v->vc1dsp.vc1_h_loop_filter16(dst, s->linesize, pq);
+ }
+}
+
+static inline void vc1_i_v_loop_filter(VC1Context *v, uint8 *dest, uint32 flags, uint8 fieldtx, int block_num) {
+ PictureState *s = &v->s;
+ int pq = v->pq;
+ uint8 *dst;
+
+ if ((block_num & 5) == 1)
+ return;
+
+ if (!(flags & TOP_EDGE) || block_num & 2) {
+ if (block_num > 3)
+ dst = dest;
+ else
+ dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
+
+ if (v->fcm == ILACE_FRAME) {
+ if (block_num > 3) {
+ v->vc1dsp.vc1_v_loop_filter8(dst, 2 * s->uvlinesize, pq);
+ v->vc1dsp.vc1_v_loop_filter8(dst + s->uvlinesize, 2 * s->uvlinesize, pq);
+ } else if (block_num < 2 || !fieldtx) {
+ v->vc1dsp.vc1_v_loop_filter16(dst, 2 * s->linesize, pq);
+ v->vc1dsp.vc1_v_loop_filter16(dst + s->linesize, 2 * s->linesize, pq);
+ }
+ } else if (block_num > 3)
+ v->vc1dsp.vc1_v_loop_filter8(dst, s->uvlinesize, pq);
+ else
+ v->vc1dsp.vc1_v_loop_filter16(dst, s->linesize, pq);
+ }
+}
+
+void ff_vc1_i_loop_filter(VC1Context *v) {
+ PictureState *s = &v->s;
+ int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ uint8 *dest, fieldtx;
+ uint32 flags = 0;
+ int i;
+
+ /* Within a MB, the vertical loop filter always runs before the horizontal.
+ * To accomplish that, we run the V loop filter on top and internal
+ * horizontal borders of the last overlap filtered MB. Then, we wait for
+ * the loop filter iteration on the next row to do V loop filter on the
+ * bottom edge of this MB, before moving over and running the H loop
+ * filter on the left and internal vertical borders. Therefore, the loop
+ * filter trails by one row and one column relative to the overlap filter
+ * and two rows and two columns relative to the decoding loop. */
+ if (!s->first_slice_line) {
+ dest = s->dest[0] - 16 * s->linesize - 16;
+ flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
+ if (s->mb_x) {
+ fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
+ for (i = 0; i < block_count; i++)
+ vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, flags, fieldtx, i);
+ }
+ if (s->mb_x == v->end_mb_x - 1) {
+ dest += 16;
+ fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
+ for (i = 0; i < block_count; i++)
+ vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, flags, fieldtx, i);
+ }
+ }
+ if (s->mb_y == s->end_mb_y - 1) {
+ dest = s->dest[0] - 16;
+ flags = s->first_slice_line ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
+ if (s->mb_x) {
+ fieldtx = v->fieldtx_plane[mb_pos - 1];
+ for (i = 0; i < block_count; i++)
+ vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, flags, fieldtx, i);
+ }
+ if (s->mb_x == v->end_mb_x - 1) {
+ dest += 16;
+ fieldtx = v->fieldtx_plane[mb_pos];
+ for (i = 0; i < block_count; i++)
+ vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, flags, fieldtx, i);
+ }
+ }
+
+ if (s->mb_y >= s->start_mb_y + 2) {
+ dest = s->dest[0] - 32 * s->linesize - 16;
+ if (s->mb_x) {
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest, flags, i);
+ }
+ if (s->mb_x == v->end_mb_x - 1) {
+ dest += 16;
+ flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest, flags, i);
+ }
+ }
+ if (s->mb_y == s->end_mb_y - 1) {
+ if (s->mb_y >= s->start_mb_y + 1) {
+ dest = s->dest[0] - 16 * s->linesize - 16;
+ if (s->mb_x) {
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, flags, i);
+ }
+ if (s->mb_x == v->end_mb_x - 1) {
+ flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
+ dest += 16;
+ for (i = 0; i < block_count; i++)
+ vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, flags, i);
+ }
+ }
+ dest = s->dest[0] - 16;
+ if (s->mb_x) {
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, flags, i);
+ }
+ if (s->mb_x == v->end_mb_x - 1) {
+ dest += 16;
+ flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, flags, i);
+ }
+ }
+}
+
+static inline void vc1_p_h_loop_filter(VC1Context *v, uint8 *dest, uint32 *cbp, uint8 *is_intra, int16 (*mv)[2],
+ uint8 *mv_f, int *ttblk, uint32 flags, int block_num) {
+ PictureState *s = &v->s;
+ int pq = v->pq;
+ uint32 left_cbp = cbp[0] >> (block_num * 4), right_cbp;
+ uint8 left_is_intra, right_is_intra;
+ int tt;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize;
+ uint8 *dst;
+
+ if (block_num > 3)
+ dst = dest;
+ else
+ dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
+
+ if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
+ left_is_intra = is_intra[0] & (1 << block_num);
+
+ if (block_num > 3) {
+ right_is_intra = is_intra[1] & (1 << block_num);
+ right_cbp = cbp[1] >> (block_num * 4);
+ } else if (block_num & 1) {
+ right_is_intra = is_intra[1] & (1 << block_num - 1);
+ right_cbp = cbp[1] >> ((block_num - 1) * 4);
+ } else {
+ right_is_intra = is_intra[0] & (1 << block_num + 1);
+ right_cbp = cbp[0] >> ((block_num + 1) * 4);
+ }
+
+ if (left_is_intra || right_is_intra || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1] ||
+ (v->fcm == ILACE_FIELD && mv_f[0] != mv_f[1]))
+ v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq);
+ else {
+ idx = (left_cbp | (right_cbp >> 1)) & 5;
+ if (idx & 1)
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 8, linesize, pq);
+ if (idx & 4)
+ v->vc1dsp.vc1_h_loop_filter4(dst + 8, linesize, pq);
+ }
+ }
+
+ tt = ttblk[0] >> (block_num * 4) & 0xf;
+ if (tt == TT_4X4 || tt == TT_4X8) {
+ if (left_cbp & 3)
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
+ if (left_cbp & 12)
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4, linesize, pq);
+ }
+}
+
+static inline void vc1_p_v_loop_filter(VC1Context *v, uint8 *dest, const uint32 *cbp, const uint8 *is_intra,
+ int16 (*mv)[2], const uint8 *mv_f, const int *ttblk, uint32 flags,
+ int block_num) {
+ PictureState *s = &v->s;
+ int pq = v->pq;
+ uint32 top_cbp = cbp[0] >> (block_num * 4), bottom_cbp;
+ uint8 top_is_intra, bottom_is_intra;
+ int tt;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize;
+ uint8 *dst;
+
+ if (block_num > 3)
+ dst = dest;
+ else
+ dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
+
+ if (!(flags & BOTTOM_EDGE) || block_num < 2) {
+ top_is_intra = is_intra[0] & (1 << block_num);
+
+ if (block_num > 3) {
+ bottom_is_intra = is_intra[s->mb_stride] & (1 << block_num);
+ bottom_cbp = cbp[s->mb_stride] >> (block_num * 4);
+ } else if (block_num < 2) {
+ bottom_is_intra = is_intra[0] & (1 << block_num + 2);
+ bottom_cbp = cbp[0] >> ((block_num + 2) * 4);
+ } else {
+ bottom_is_intra = is_intra[s->mb_stride] & (1 << block_num - 2);
+ bottom_cbp = cbp[s->mb_stride] >> ((block_num - 2) * 4);
+ }
+
+ if (top_is_intra || bottom_is_intra || mv[0][0] != mv[block_num > 3 ? s->mb_stride : s->b8_stride][0] ||
+ mv[0][1] != mv[block_num > 3 ? s->mb_stride : s->b8_stride][1] ||
+ (v->fcm == ILACE_FIELD && mv_f[0] != mv_f[block_num > 3 ? s->mb_stride : s->b8_stride]))
+ v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, linesize, pq);
+ else {
+ idx = (top_cbp | (bottom_cbp >> 2)) & 3;
+ if (idx & 1)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 8 * linesize + 4, linesize, pq);
+ if (idx & 2)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 8 * linesize, linesize, pq);
+ }
+ }
+
+ tt = ttblk[0] >> (block_num * 4) & 0xf;
+ if (tt == TT_4X4 || tt == TT_8X4) {
+ if (top_cbp & 5)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
+ if (top_cbp & 10)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize, linesize, pq);
+ }
+}
+
+void ff_vc1_p_loop_filter(VC1Context *v) {
+ PictureState *s = &v->s;
+ int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
+ uint8 *dest;
+ uint32 *cbp;
+ uint8 *is_intra;
+ int16(*uvmv)[2];
+ int *ttblk;
+ uint32 flags;
+ int i;
+
+ /* Within a MB, the vertical loop filter always runs before the horizontal.
+ * To accomplish that, we run the V loop filter on all applicable
+ * horizontal borders of the MB above the last overlap filtered MB. Then,
+ * we wait for the next loop filter iteration to do H loop filter on all
+ * applicable vertical borders of this MB. Therefore, the loop filter
+ * trails by one row and one column relative to the overlap filter and two
+ * rows and two columns relative to the decoding loop. */
+ if (s->mb_y >= s->start_mb_y + 2) {
+ if (s->mb_x) {
+ dest = s->dest[0] - 32 * s->linesize - 16;
+ cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 1];
+ is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 1];
+ uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 1];
+ ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
+ flags = s->mb_y == s->start_mb_y + 2 ? TOP_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 1 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ dest = s->dest[0] - 32 * s->linesize;
+ cbp = &v->cbp[s->mb_x - 2 * s->mb_stride];
+ is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride];
+ uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride];
+ ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
+ flags = s->mb_y == s->start_mb_y + 2 ? TOP_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
+ ttblk, flags, i);
+ }
+ }
+ if (s->mb_y == s->end_mb_y - 1) {
+ if (s->mb_x) {
+ if (s->mb_y >= s->start_mb_y + 1) {
+ dest = s->dest[0] - 16 * s->linesize - 16;
+ cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
+ is_intra = &v->is_intra[s->mb_x - s->mb_stride - 1];
+ uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
+ flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, cbp, is_intra,
+ i > 3 ? uvmv
+ : &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 1 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ dest = s->dest[0] - 16;
+ cbp = &v->cbp[s->mb_x - 1];
+ is_intra = &v->is_intra[s->mb_x - 1];
+ uvmv = &v->luma_mv[s->mb_x - 1];
+ ttblk = &v->ttblk[s->mb_x - 1];
+ flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 2 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - 1 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 2 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_y >= s->start_mb_y + 1) {
+ dest = s->dest[0] - 16 * s->linesize;
+ cbp = &v->cbp[s->mb_x - s->mb_stride];
+ is_intra = &v->is_intra[s->mb_x - s->mb_stride];
+ uvmv = &v->luma_mv[s->mb_x - s->mb_stride];
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride];
+ flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
+ ttblk, flags, i);
+ }
+ dest = s->dest[0];
+ cbp = &v->cbp[s->mb_x];
+ is_intra = &v->is_intra[s->mb_x];
+ uvmv = &v->luma_mv[s->mb_x];
+ ttblk = &v->ttblk[s->mb_x];
+ flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] + v->blocks_off],
+ ttblk, flags, i);
+ }
+ }
+
+ if (s->mb_y >= s->start_mb_y + 2) {
+ if (s->mb_x >= 2) {
+ dest = s->dest[0] - 32 * s->linesize - 32;
+ cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 2];
+ is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 2];
+ uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 2];
+ ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 2];
+ flags = s->mb_x == 2 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 16 : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 4 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 2 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 4 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_x >= 1) {
+ dest = s->dest[0] - 32 * s->linesize - 16;
+ cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 1];
+ is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 1];
+ uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 1];
+ ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest, cbp, is_intra,
+ i > 3 ? uvmv
+ : &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 1 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ dest = s->dest[0] - 32 * s->linesize;
+ cbp = &v->cbp[s->mb_x - 2 * s->mb_stride];
+ is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride];
+ uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride];
+ ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
+ flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
+ ttblk, flags, i);
+ }
+ }
+ if (s->mb_y == s->end_mb_y - 1) {
+ if (s->mb_y >= s->start_mb_y + 1) {
+ if (s->mb_x >= 2) {
+ dest = s->dest[0] - 16 * s->linesize - 32;
+ cbp = &v->cbp[s->mb_x - s->mb_stride - 2];
+ is_intra = &v->is_intra[s->mb_x - s->mb_stride - 2];
+ uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 2];
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride - 2];
+ flags = s->mb_x == 2 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 16 : dest, cbp, is_intra,
+ i > 3 ? uvmv
+ : &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 4 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 2 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 4 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_x >= 1) {
+ dest = s->dest[0] - 16 * s->linesize - 16;
+ cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
+ is_intra = &v->is_intra[s->mb_x - s->mb_stride - 1];
+ uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, cbp, is_intra,
+ i > 3 ? uvmv
+ : &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 1 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ dest = s->dest[0] - 16 * s->linesize;
+ cbp = &v->cbp[s->mb_x - s->mb_stride];
+ is_intra = &v->is_intra[s->mb_x - s->mb_stride];
+ uvmv = &v->luma_mv[s->mb_x - s->mb_stride];
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride];
+ flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(
+ v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
+ ttblk, flags, i);
+ }
+ }
+ if (s->mb_x >= 2) {
+ dest = s->dest[0] - 32;
+ cbp = &v->cbp[s->mb_x - 2];
+ is_intra = &v->is_intra[s->mb_x - 2];
+ uvmv = &v->luma_mv[s->mb_x - 2];
+ ttblk = &v->ttblk[s->mb_x - 2];
+ flags = s->mb_x == 2 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 4 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - 2 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 4 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_x >= 1) {
+ dest = s->dest[0] - 16;
+ cbp = &v->cbp[s->mb_x - 1];
+ is_intra = &v->is_intra[s->mb_x - 1];
+ uvmv = &v->luma_mv[s->mb_x - 1];
+ ttblk = &v->ttblk[s->mb_x - 1];
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] - 2 + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] - 1 + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] - 2 + v->blocks_off],
+ ttblk, flags, i);
+ }
+ dest = s->dest[0];
+ cbp = &v->cbp[s->mb_x];
+ is_intra = &v->is_intra[s->mb_x];
+ uvmv = &v->luma_mv[s->mb_x];
+ ttblk = &v->ttblk[s->mb_x];
+ flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, cbp, is_intra,
+ i > 3 ? uvmv : &s->cur_pic.motion_val[0][s->block_index[i] + v->blocks_off],
+ i > 3 ? &v->mv_f[0][s->block_index[i] + v->mb_off]
+ : &v->mv_f[0][s->block_index[i] + v->blocks_off],
+ ttblk, flags, i);
+ }
+ }
+}
+
+static inline void vc1_p_h_intfr_loop_filter(VC1Context *v, uint8 *dest, const int *ttblk, uint32 flags, uint8 fieldtx,
+ int block_num) {
+ PictureState *s = &v->s;
+ int pq = v->pq;
+ int tt;
+ int linesize = block_num > 3 ? s->uvlinesize : s->linesize;
+ uint8 *dst;
+
+ if (block_num > 3)
+ dst = dest;
+ else
+ dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
+
+ tt = ttblk[0] >> (block_num * 4) & 0xf;
+ if (block_num < 4) {
+ if (fieldtx) {
+ if (block_num < 2) {
+ if (tt == TT_4X4 || tt == TT_4X8)
+ v->vc1dsp.vc1_h_loop_filter8(dst + 4, 2 * linesize, pq);
+ if (!(flags & RIGHT_EDGE) || block_num == 0)
+ v->vc1dsp.vc1_h_loop_filter8(dst + 8, 2 * linesize, pq);
+ } else {
+ if (tt == TT_4X4 || tt == TT_4X8)
+ v->vc1dsp.vc1_h_loop_filter8(dst - 7 * linesize + 4, 2 * linesize, pq);
+ if (!(flags & RIGHT_EDGE) || block_num == 2)
+ v->vc1dsp.vc1_h_loop_filter8(dst - 7 * linesize + 8, 2 * linesize, pq);
+ }
+ } else {
+ if (tt == TT_4X4 || tt == TT_4X8) {
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4, 2 * linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 4, 2 * linesize, pq);
+ }
+ if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
+ v->vc1dsp.vc1_h_loop_filter4(dst + 8, 2 * linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 8, 2 * linesize, pq);
+ }
+ }
+ } else {
+ if (tt == TT_4X4 || tt == TT_4X8) {
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4, 2 * linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 4, 2 * linesize, pq);
+ }
+ if (!(flags & RIGHT_EDGE)) {
+ v->vc1dsp.vc1_h_loop_filter4(dst + 8, 2 * linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 8, 2 * linesize, pq);
+ }
+ }
+}
+
+static inline void vc1_p_v_intfr_loop_filter(VC1Context *v, uint8 *dest, const int *ttblk, uint32 flags, uint8 fieldtx,
+ int block_num) {
+ PictureState *s = &v->s;
+ int pq = v->pq;
+ int tt;
+ int linesize = block_num > 3 ? s->uvlinesize : s->linesize;
+ uint8 *dst;
+
+ if (block_num > 3)
+ dst = dest;
+ else
+ dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
+
+ tt = ttblk[0] >> (block_num * 4) & 0xf;
+ if (block_num < 4) {
+ if (fieldtx) {
+ if (block_num < 2) {
+ if (tt == TT_4X4 || tt == TT_8X4)
+ v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
+ if (!(flags & BOTTOM_EDGE))
+ v->vc1dsp.vc1_v_loop_filter8(dst + 16 * linesize, 2 * linesize, pq);
+ } else {
+ if (tt == TT_4X4 || tt == TT_8X4)
+ v->vc1dsp.vc1_v_loop_filter8(dst + linesize, 2 * linesize, pq);
+ if (!(flags & BOTTOM_EDGE))
+ v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
+ }
+ } else {
+ if (block_num < 2) {
+ if (!(flags & TOP_EDGE) && (tt == TT_4X4 || tt == TT_8X4)) {
+ v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
+ v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
+ }
+ v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
+ v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
+ } else if (!(flags & BOTTOM_EDGE)) {
+ if (tt == TT_4X4 || tt == TT_8X4) {
+ v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
+ v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
+ }
+ v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
+ v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
+ }
+ }
+ } else {
+ if (!(flags & BOTTOM_EDGE)) {
+ if (!(flags & TOP_EDGE) && (tt == TT_4X4 || tt == TT_8X4)) {
+ v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
+ v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
+ }
+ v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
+ v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
+ }
+ }
+}
+
+void ff_vc1_p_intfr_loop_filter(VC1Context *v) {
+ PictureState *s = &v->s;
+ int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ uint8 *dest;
+ int *ttblk;
+ uint32 flags;
+ uint8 fieldtx;
+ int i;
+
+ /* Within a MB, the vertical loop filter always runs before the horizontal.
+ * To accomplish that, we run the V loop filter on all applicable
+ * horizontal borders of the MB above the last overlap filtered MB. Then,
+ * we wait for the loop filter iteration on the next row and next column to
+ * do H loop filter on all applicable vertical borders of this MB.
+ * Therefore, the loop filter trails by two rows and one column relative to
+ * the overlap filter and two rows and two columns relative to the decoding
+ * loop. */
+ if (s->mb_x) {
+ if (s->mb_y >= s->start_mb_y + 1) {
+ dest = s->dest[0] - 16 * s->linesize - 16;
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
+ flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
+ fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, ttblk, flags,
+ fieldtx, i);
+ }
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_y >= s->start_mb_y + 1) {
+ dest = s->dest[0] - 16 * s->linesize;
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride];
+ flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
+ fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, ttblk, flags, fieldtx,
+ i);
+ }
+ }
+ if (s->mb_y == s->end_mb_y - 1) {
+ if (s->mb_x) {
+ dest = s->dest[0] - 16;
+ ttblk = &v->ttblk[s->mb_x - 1];
+ flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
+ fieldtx = v->fieldtx_plane[mb_pos - 1];
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, ttblk, flags, fieldtx, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ dest = s->dest[0];
+ ttblk = &v->ttblk[s->mb_x];
+ flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
+ fieldtx = v->fieldtx_plane[mb_pos];
+ for (i = 0; i < block_count; i++)
+ vc1_p_v_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, ttblk, flags, fieldtx, i);
+ }
+ }
+
+ if (s->mb_y >= s->start_mb_y + 2) {
+ if (s->mb_x >= 2) {
+ dest = s->dest[0] - 32 * s->linesize - 32;
+ ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 2];
+ flags = s->mb_x == 2 ? LEFT_EDGE : 0;
+ fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride - 2];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 16 : dest, ttblk, flags,
+ fieldtx, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_x >= 1) {
+ dest = s->dest[0] - 32 * s->linesize - 16;
+ ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride - 1];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest, ttblk, flags,
+ fieldtx, i);
+ }
+ dest = s->dest[0] - 32 * s->linesize;
+ ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
+ flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
+ fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest, ttblk, flags, fieldtx,
+ i);
+ }
+ }
+ if (s->mb_y == s->end_mb_y - 1) {
+ if (s->mb_y >= s->start_mb_y + 1) {
+ if (s->mb_x >= 2) {
+ dest = s->dest[0] - 16 * s->linesize - 32;
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride - 2];
+ flags = s->mb_x == 2 ? LEFT_EDGE : 0;
+ fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 2];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 16 : dest, ttblk, flags,
+ fieldtx, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_x >= 1) {
+ dest = s->dest[0] - 16 * s->linesize - 16;
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, ttblk,
+ flags, fieldtx, i);
+ }
+ dest = s->dest[0] - 16 * s->linesize;
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride];
+ flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
+ fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, ttblk, flags,
+ fieldtx, i);
+ }
+ }
+ if (s->mb_x >= 2) {
+ dest = s->dest[0] - 32;
+ ttblk = &v->ttblk[s->mb_x - 2];
+ flags = s->mb_x == 2 ? LEFT_EDGE : 0;
+ fieldtx = v->fieldtx_plane[mb_pos - 2];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 : dest, ttblk, flags, fieldtx, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_x >= 1) {
+ dest = s->dest[0] - 16;
+ ttblk = &v->ttblk[s->mb_x - 1];
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ fieldtx = v->fieldtx_plane[mb_pos - 1];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, ttblk, flags, fieldtx, i);
+ }
+ dest = s->dest[0];
+ ttblk = &v->ttblk[s->mb_x];
+ flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
+ fieldtx = v->fieldtx_plane[mb_pos];
+ for (i = 0; i < block_count; i++)
+ vc1_p_h_intfr_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, ttblk, flags, fieldtx, i);
+ }
+ }
+}
+
+static inline void vc1_b_h_intfi_loop_filter(VC1Context *v, uint8 *dest, const uint32 *cbp, const int *ttblk,
+ uint32 flags, int block_num) {
+ PictureState *s = &v->s;
+ int pq = v->pq;
+ uint8 *dst;
+ uint32 block_cbp = cbp[0] >> (block_num * 4);
+ int tt;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize;
+
+ if (block_num > 3)
+ dst = dest;
+ else
+ dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
+
+ if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
+ v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq);
+ }
+
+ tt = ttblk[0] >> (block_num * 4) & 0xf;
+ if (tt == TT_4X4 || tt == TT_4X8) {
+ idx = (block_cbp | (block_cbp >> 1)) & 5;
+ if (idx & 1)
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
+ if (idx & 4)
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4, linesize, pq);
+ }
+}
+
+static inline void vc1_b_v_intfi_loop_filter(VC1Context *v, uint8 *dest, const uint32 *cbp, const int *ttblk,
+ uint32 flags, int block_num) {
+ PictureState *s = &v->s;
+ int pq = v->pq;
+ uint8 *dst;
+ uint32 block_cbp = cbp[0] >> (block_num * 4);
+ int tt;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize;
+
+ if (block_num > 3)
+ dst = dest;
+ else
+ dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
+
+ if (!(flags & BOTTOM_EDGE) || block_num < 2)
+ v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, linesize, pq);
+
+ tt = ttblk[0] >> (block_num * 4) & 0xf;
+ if (tt == TT_4X4 || tt == TT_8X4) {
+ idx = (block_cbp | (block_cbp >> 2)) & 3;
+ if (idx & 1)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
+ if (idx & 2)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize, linesize, pq);
+ }
+}
+
+void ff_vc1_b_intfi_loop_filter(VC1Context *v) {
+ PictureState *s = &v->s;
+ int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
+ uint8 *dest;
+ const uint32 *cbp;
+ int *ttblk;
+ uint32 flags = 0;
+ int i;
+
+ /* Within a MB, the vertical loop filter always runs before the horizontal.
+ * To accomplish that, we run the V loop filter on all applicable
+ * horizontal borders of the MB above the currently decoded MB. Then,
+ * we wait for the next loop filter iteration to do H loop filter on all
+ * applicable vertical borders of this MB. Therefore, the loop filter
+ * trails by one row and one column relative to the decoding loop. */
+ if (!s->first_slice_line) {
+ dest = s->dest[0] - 16 * s->linesize;
+ cbp = &v->cbp[s->mb_x - s->mb_stride];
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride];
+ flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_b_v_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, cbp, ttblk, flags, i);
+ }
+ if (s->mb_y == s->end_mb_y - 1) {
+ dest = s->dest[0];
+ cbp = &v->cbp[s->mb_x];
+ ttblk = &v->ttblk[s->mb_x];
+ flags = s->first_slice_line ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_b_v_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, cbp, ttblk, flags, i);
+ }
+
+ if (!s->first_slice_line) {
+ dest = s->dest[0] - 16 * s->linesize - 16;
+ cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
+ ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
+ if (s->mb_x) {
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, cbp, ttblk, flags,
+ i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ dest += 16;
+ cbp++;
+ ttblk++;
+ flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, cbp, ttblk, flags, i);
+ }
+ }
+ if (s->mb_y == s->end_mb_y - 1) {
+ dest = s->dest[0] - 16;
+ cbp = &v->cbp[s->mb_x - 1];
+ ttblk = &v->ttblk[s->mb_x - 1];
+ if (s->mb_x) {
+ flags = s->mb_x == 1 ? LEFT_EDGE : 0;
+ for (i = 0; i < block_count; i++)
+ vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, cbp, ttblk, flags, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ dest += 16;
+ cbp++;
+ ttblk++;
+ flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
+ for (i = 0; i < block_count; i++)
+ vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, cbp, ttblk, flags, i);
+ }
+ }
+}
+
+#undef BOTTOM_EDGE
+#undef LEFT_EDGE
+#undef RIGHT_EDGE
+#undef TOP_EDGE
+
+static inline void vc1_scale_luma(uint8 *srcY, int k, int linesize) {
+ int i, j;
+ for (j = 0; j < k; j++) {
+ for (i = 0; i < k; i++)
+ srcY[i] = ((srcY[i] - 128) >> 1) + 128;
+ srcY += linesize;
+ }
+}
+
+static inline void vc1_scale_chroma(uint8 *srcU, uint8 *srcV, int k, int uvlinesize) {
+ int i, j;
+ for (j = 0; j < k; j++) {
+ for (i = 0; i < k; i++) {
+ srcU[i] = ((srcU[i] - 128) >> 1) + 128;
+ srcV[i] = ((srcV[i] - 128) >> 1) + 128;
+ }
+ srcU += uvlinesize;
+ srcV += uvlinesize;
+ }
+}
+
+static inline void vc1_lut_scale_luma(uint8 *srcY, const uint8 *lut1, const uint8 *lut2, int k, int linesize) {
+ int i, j;
+
+ for (j = 0; j < k; j += 2) {
+ for (i = 0; i < k; i++)
+ srcY[i] = lut1[srcY[i]];
+ srcY += linesize;
+
+ if (j + 1 == k)
+ break;
+
+ for (i = 0; i < k; i++)
+ srcY[i] = lut2[srcY[i]];
+ srcY += linesize;
+ }
+}
+
+static inline void vc1_lut_scale_chroma(uint8 *srcU, uint8 *srcV, const uint8 *lut1, const uint8 *lut2, int k,
+ int uvlinesize) {
+ int i, j;
+
+ for (j = 0; j < k; j += 2) {
+ for (i = 0; i < k; i++) {
+ srcU[i] = lut1[srcU[i]];
+ srcV[i] = lut1[srcV[i]];
+ }
+ srcU += uvlinesize;
+ srcV += uvlinesize;
+
+ if (j + 1 == k)
+ break;
+
+ for (i = 0; i < k; i++) {
+ srcU[i] = lut2[srcU[i]];
+ srcV[i] = lut2[srcV[i]];
+ }
+ srcU += uvlinesize;
+ srcV += uvlinesize;
+ }
+}
+
+static const uint8 popcount4[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+static inline int get_luma_mv(VC1Context *v, int dir, int16 *tx, int16 *ty) {
+ PictureState *s = &v->s;
+ int idx = v->mv_f[dir][s->block_index[0] + v->blocks_off] | (v->mv_f[dir][s->block_index[1] + v->blocks_off] << 1) |
+ (v->mv_f[dir][s->block_index[2] + v->blocks_off] << 2) |
+ (v->mv_f[dir][s->block_index[3] + v->blocks_off] << 3);
+ static const uint8 index2[16] = {0, 0, 0, 0x23, 0, 0x13, 0x03, 0, 0, 0x12, 0x02, 0, 0x01, 0, 0, 0};
+ int opp_count = popcount4[idx];
+
+ switch (opp_count) {
+ case 0:
+ case 4:
+ *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
+ *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
+ break;
+ case 1:
+ *tx = mid_pred(s->mv[dir][idx < 2][0], s->mv[dir][1 + (idx < 4)][0], s->mv[dir][2 + (idx < 8)][0]);
+ *ty = mid_pred(s->mv[dir][idx < 2][1], s->mv[dir][1 + (idx < 4)][1], s->mv[dir][2 + (idx < 8)][1]);
+ break;
+ case 3:
+ *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
+ *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
+ break;
+ case 2:
+ *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
+ *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
+ break;
+ }
+ return opp_count;
+}
+
+static inline int get_chroma_mv(VC1Context *v, int dir, int16 *tx, int16 *ty) {
+ PictureState *s = &v->s;
+ int idx = !v->mb_type[s->block_index[0]] | (!v->mb_type[s->block_index[1]] << 1) |
+ (!v->mb_type[s->block_index[2]] << 2) | (!v->mb_type[s->block_index[3]] << 3);
+ static const uint8 index2[16] = {0, 0, 0, 0x01, 0, 0x02, 0x12, 0, 0, 0x03, 0x13, 0, 0x23, 0, 0, 0};
+ int valid_count = popcount4[idx];
+
+ switch (valid_count) {
+ case 4:
+ *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
+ *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
+ break;
+ case 3:
+ *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
+ *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
+ break;
+ case 2:
+ *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
+ *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
+ break;
+ default:
+ return 0;
+ }
+ return valid_count;
+}
+
+/** Do motion compensation over 1 macroblock
+ * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
+ */
+void ff_vc1_mc_1mv(VC1Context *v, int dir) {
+ PictureState *s = &v->s;
+ ChromaDSP *h264chroma = &v->h264chroma;
+ uint8 *srcY, *srcU, *srcV;
+ int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
+ int i;
+ const uint8(*luty)[256], (*lutuv)[256];
+ int use_ic;
+ int interlace;
+ int linesize, uvlinesize;
+
+ if ((!v->field_mode || (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && !v->s.last_pic.data[0])
+ return;
+
+ linesize = s->cur_pic.ptr->f->linesize[0];
+ uvlinesize = s->cur_pic.ptr->f->linesize[1];
+
+ mx = s->mv[dir][0][0];
+ my = s->mv[dir][0][1];
+
+ // store motion vectors for further use in B-frames
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ for (i = 0; i < 4; i++) {
+ s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
+ s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
+ }
+ }
+
+ uvmx = (mx + ((mx & 3) == 3)) >> 1;
+ uvmy = (my + ((my & 3) == 3)) >> 1;
+ v->luma_mv[s->mb_x][0] = uvmx;
+ v->luma_mv[s->mb_x][1] = uvmy;
+
+ if (v->field_mode && v->cur_field_type != v->ref_field_type[dir]) {
+ my = my - 2 + 4 * v->cur_field_type;
+ uvmy = uvmy - 2 + 4 * v->cur_field_type;
+ }
+
+ // fastuvmc shall be ignored for interlaced frame picture
+ if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
+ uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
+ uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
+ }
+ if (!dir) {
+ if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
+ srcY = s->cur_pic.data[0];
+ srcU = s->cur_pic.data[1];
+ srcV = s->cur_pic.data[2];
+ luty = v->curr_luty;
+ lutuv = v->curr_lutuv;
+ use_ic = *v->curr_use_ic;
+ interlace = 1;
+ } else {
+ srcY = s->last_pic.data[0];
+ srcU = s->last_pic.data[1];
+ srcV = s->last_pic.data[2];
+ luty = v->last_luty;
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
+ interlace = v->last_interlaced;
+ }
+ } else {
+ srcY = s->next_pic.data[0];
+ srcU = s->next_pic.data[1];
+ srcV = s->next_pic.data[2];
+ luty = v->next_luty;
+ lutuv = v->next_lutuv;
+ use_ic = v->next_use_ic;
+ interlace = v->next_interlaced;
+ }
+
+ if (!srcY || !srcU) {
+ warning("Referenced frame missing.\n");
+ return;
+ }
+
+ src_x = s->mb_x * 16 + (mx >> 2);
+ src_y = s->mb_y * 16 + (my >> 2);
+ uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
+ uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
+
+ if (v->profile != PROFILE_ADVANCED) {
+ src_x = av_clip(src_x, -16, s->mb_width * 16);
+ src_y = av_clip(src_y, -16, s->mb_height * 16);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
+ } else {
+ src_x = av_clip(src_x, -17, s->avctx->coded_width);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ if (v->fcm == ILACE_FRAME) {
+ src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
+ uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
+ } else {
+ src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ }
+ }
+
+ srcY += src_y * s->linesize + src_x;
+ srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+
+ if (v->field_mode && v->ref_field_type[dir]) {
+ srcY += linesize;
+ srcU += uvlinesize;
+ srcV += uvlinesize;
+ }
+
+ /* for grayscale we should not try to read from unknown area */
+ if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) {
+ srcU = s->sc.edge_emu_buffer + 18 * s->linesize;
+ srcV = s->sc.edge_emu_buffer + 18 * s->linesize;
+ }
+
+ if (v->rangeredfrm || use_ic || s->h_edge_pos < 22 || v_edge_pos < 22 ||
+ (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3 ||
+ (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) {
+ uint8 *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
+ uint8 *vbuf = ubuf + 9 * s->uvlinesize;
+ const int k = 17 + s->mspel * 2;
+
+ srcY -= s->mspel * (1 + s->linesize);
+ if (interlace) {
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, linesize << 1, linesize << 1, k,
+ v->field_mode ? k : k + 1 >> 1, src_x - s->mspel,
+ src_y - s->mspel >> !v->field_mode, s->h_edge_pos, s->v_edge_pos >> 1);
+ if (!v->field_mode)
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, srcY + linesize, linesize << 1,
+ linesize << 1, k, k >> 1, src_x - s->mspel, src_y - s->mspel + 1 >> 1,
+ s->h_edge_pos, s->v_edge_pos >> 1);
+ } else
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY, linesize, linesize, k,
+ v->field_mode ? (k << 1) - 1 : k, src_x - s->mspel,
+ v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : src_y - s->mspel,
+ s->h_edge_pos, s->v_edge_pos);
+ srcY = s->sc.edge_emu_buffer;
+ if (interlace) {
+ s->vdsp.emulated_edge_mc(ubuf, srcU, uvlinesize << 1, uvlinesize << 1, 9, v->field_mode ? 9 : 5, uvsrc_x,
+ uvsrc_y >> !v->field_mode, s->h_edge_pos >> 1, s->v_edge_pos >> 2);
+ s->vdsp.emulated_edge_mc(vbuf, srcV, uvlinesize << 1, uvlinesize << 1, 9, v->field_mode ? 9 : 5, uvsrc_x,
+ uvsrc_y >> !v->field_mode, s->h_edge_pos >> 1, s->v_edge_pos >> 2);
+ if (!v->field_mode) {
+ s->vdsp.emulated_edge_mc(ubuf + uvlinesize, srcU + uvlinesize, uvlinesize << 1, uvlinesize << 1, 9, 4,
+ uvsrc_x, uvsrc_y + 1 >> 1, s->h_edge_pos >> 1, s->v_edge_pos >> 2);
+ s->vdsp.emulated_edge_mc(vbuf + uvlinesize, srcV + uvlinesize, uvlinesize << 1, uvlinesize << 1, 9, 4,
+ uvsrc_x, uvsrc_y + 1 >> 1, s->h_edge_pos >> 1, s->v_edge_pos >> 2);
+ }
+ } else {
+ s->vdsp.emulated_edge_mc(ubuf, srcU, uvlinesize, uvlinesize, 9, v->field_mode ? 17 : 9, uvsrc_x,
+ v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, s->h_edge_pos >> 1,
+ s->v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(vbuf, srcV, uvlinesize, uvlinesize, 9, v->field_mode ? 17 : 9, uvsrc_x,
+ v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, s->h_edge_pos >> 1,
+ s->v_edge_pos >> 1);
+ }
+ srcU = ubuf;
+ srcV = vbuf;
+ /* if we deal with range reduction we need to scale source blocks */
+ if (v->rangeredfrm) {
+ vc1_scale_luma(srcY, k, s->linesize);
+ vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
+ }
+ /* if we deal with intensity compensation we need to scale source blocks */
+ if (use_ic) {
+ vc1_lut_scale_luma(srcY, luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)],
More information about the Scummvm-git-logs
mailing list