1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Xvid MPEG-4 IDCT 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (C) 2006-2011 Xvid Solutions GmbH 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci/** 24cabdff1aSopenharmony_ci * @file 25cabdff1aSopenharmony_ci * Walken IDCT 26cabdff1aSopenharmony_ci * Alternative IDCT implementation for decoding compatibility. 27cabdff1aSopenharmony_ci * 28cabdff1aSopenharmony_ci * @author Skal 29cabdff1aSopenharmony_ci * @note This C version is not the original IDCT, but a modified one that 30cabdff1aSopenharmony_ci * yields the same error profile as the MMX/MMXEXT/SSE2 versions. 31cabdff1aSopenharmony_ci */ 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "config.h" 34cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 35cabdff1aSopenharmony_ci#include "avcodec.h" 36cabdff1aSopenharmony_ci#include "idctdsp.h" 37cabdff1aSopenharmony_ci#include "xvididct.h" 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_ci#define ROW_SHIFT 11 40cabdff1aSopenharmony_ci#define COL_SHIFT 6 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ci// #define FIX(x) (int)((x) * (1 << ROW_SHIFT)) 43cabdff1aSopenharmony_ci#define RND0 65536 // 1 << (COL_SHIFT + ROW_SHIFT - 1); 44cabdff1aSopenharmony_ci#define RND1 3597 // FIX (1.75683487303); 45cabdff1aSopenharmony_ci#define RND2 2260 // FIX (1.10355339059); 46cabdff1aSopenharmony_ci#define RND3 1203 // FIX (0.587788325588); 47cabdff1aSopenharmony_ci#define RND4 0 48cabdff1aSopenharmony_ci#define RND5 120 // FIX (0.058658283817); 49cabdff1aSopenharmony_ci#define RND6 512 // FIX (0.25); 50cabdff1aSopenharmony_ci#define RND7 512 // FIX (0.25); 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_cistatic const int TAB04[] = { 22725, 21407, 19266, 16384, 12873, 8867, 4520 }; 53cabdff1aSopenharmony_cistatic const int TAB17[] = { 31521, 29692, 26722, 22725, 17855, 12299, 6270 }; 54cabdff1aSopenharmony_cistatic const int TAB26[] = { 29692, 27969, 25172, 21407, 16819, 11585, 5906 }; 55cabdff1aSopenharmony_cistatic const int TAB35[] = { 26722, 25172, 22654, 19266, 15137, 10426, 5315 }; 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_cistatic int idct_row(short *in, const int *const tab, int rnd) 58cabdff1aSopenharmony_ci{ 59cabdff1aSopenharmony_ci const unsigned c1 = tab[0]; 60cabdff1aSopenharmony_ci const unsigned c2 = tab[1]; 61cabdff1aSopenharmony_ci const unsigned c3 = tab[2]; 62cabdff1aSopenharmony_ci const unsigned c4 = tab[3]; 63cabdff1aSopenharmony_ci const unsigned c5 = tab[4]; 64cabdff1aSopenharmony_ci const unsigned c6 = tab[5]; 65cabdff1aSopenharmony_ci const unsigned c7 = tab[6]; 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci const int right = in[5] | in[6] | in[7]; 68cabdff1aSopenharmony_ci const int left = in[1] | in[2] | in[3]; 69cabdff1aSopenharmony_ci if (!(right | in[4])) { 70cabdff1aSopenharmony_ci const int k = c4 * in[0] + rnd; 71cabdff1aSopenharmony_ci if (left) { 72cabdff1aSopenharmony_ci const unsigned a0 = k + c2 * in[2]; 73cabdff1aSopenharmony_ci const unsigned a1 = k + c6 * in[2]; 74cabdff1aSopenharmony_ci const unsigned a2 = k - c6 * in[2]; 75cabdff1aSopenharmony_ci const unsigned a3 = k - c2 * in[2]; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci const int b0 = c1 * in[1] + c3 * in[3]; 78cabdff1aSopenharmony_ci const int b1 = c3 * in[1] - c7 * in[3]; 79cabdff1aSopenharmony_ci const int b2 = c5 * in[1] - c1 * in[3]; 80cabdff1aSopenharmony_ci const int b3 = c7 * in[1] - c5 * in[3]; 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_ci in[0] = (int)(a0 + b0) >> ROW_SHIFT; 83cabdff1aSopenharmony_ci in[1] = (int)(a1 + b1) >> ROW_SHIFT; 84cabdff1aSopenharmony_ci in[2] = (int)(a2 + b2) >> ROW_SHIFT; 85cabdff1aSopenharmony_ci in[3] = (int)(a3 + b3) >> ROW_SHIFT; 86cabdff1aSopenharmony_ci in[4] = (int)(a3 - b3) >> ROW_SHIFT; 87cabdff1aSopenharmony_ci in[5] = (int)(a2 - b2) >> ROW_SHIFT; 88cabdff1aSopenharmony_ci in[6] = (int)(a1 - b1) >> ROW_SHIFT; 89cabdff1aSopenharmony_ci in[7] = (int)(a0 - b0) >> ROW_SHIFT; 90cabdff1aSopenharmony_ci } else { 91cabdff1aSopenharmony_ci const int a0 = k >> ROW_SHIFT; 92cabdff1aSopenharmony_ci if (a0) { 93cabdff1aSopenharmony_ci in[0] = 94cabdff1aSopenharmony_ci in[1] = 95cabdff1aSopenharmony_ci in[2] = 96cabdff1aSopenharmony_ci in[3] = 97cabdff1aSopenharmony_ci in[4] = 98cabdff1aSopenharmony_ci in[5] = 99cabdff1aSopenharmony_ci in[6] = 100cabdff1aSopenharmony_ci in[7] = a0; 101cabdff1aSopenharmony_ci } else 102cabdff1aSopenharmony_ci return 0; 103cabdff1aSopenharmony_ci } 104cabdff1aSopenharmony_ci } else if (!(left | right)) { 105cabdff1aSopenharmony_ci const int a0 = (int)(rnd + c4 * (in[0] + in[4])) >> ROW_SHIFT; 106cabdff1aSopenharmony_ci const int a1 = (int)(rnd + c4 * (in[0] - in[4])) >> ROW_SHIFT; 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_ci in[0] = a0; 109cabdff1aSopenharmony_ci in[3] = a0; 110cabdff1aSopenharmony_ci in[4] = a0; 111cabdff1aSopenharmony_ci in[7] = a0; 112cabdff1aSopenharmony_ci in[1] = a1; 113cabdff1aSopenharmony_ci in[2] = a1; 114cabdff1aSopenharmony_ci in[5] = a1; 115cabdff1aSopenharmony_ci in[6] = a1; 116cabdff1aSopenharmony_ci } else { 117cabdff1aSopenharmony_ci const unsigned int k = c4 * in[0] + rnd; 118cabdff1aSopenharmony_ci const unsigned int a0 = k + c2 * in[2] + c4 * in[4] + c6 * in[6]; 119cabdff1aSopenharmony_ci const unsigned int a1 = k + c6 * in[2] - c4 * in[4] - c2 * in[6]; 120cabdff1aSopenharmony_ci const unsigned int a2 = k - c6 * in[2] - c4 * in[4] + c2 * in[6]; 121cabdff1aSopenharmony_ci const unsigned int a3 = k - c2 * in[2] + c4 * in[4] - c6 * in[6]; 122cabdff1aSopenharmony_ci 123cabdff1aSopenharmony_ci const unsigned int b0 = c1 * in[1] + c3 * in[3] + c5 * in[5] + c7 * in[7]; 124cabdff1aSopenharmony_ci const unsigned int b1 = c3 * in[1] - c7 * in[3] - c1 * in[5] - c5 * in[7]; 125cabdff1aSopenharmony_ci const unsigned int b2 = c5 * in[1] - c1 * in[3] + c7 * in[5] + c3 * in[7]; 126cabdff1aSopenharmony_ci const unsigned int b3 = c7 * in[1] - c5 * in[3] + c3 * in[5] - c1 * in[7]; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci in[0] = (int)(a0 + b0) >> ROW_SHIFT; 129cabdff1aSopenharmony_ci in[1] = (int)(a1 + b1) >> ROW_SHIFT; 130cabdff1aSopenharmony_ci in[2] = (int)(a2 + b2) >> ROW_SHIFT; 131cabdff1aSopenharmony_ci in[3] = (int)(a3 + b3) >> ROW_SHIFT; 132cabdff1aSopenharmony_ci in[4] = (int)(a3 - b3) >> ROW_SHIFT; 133cabdff1aSopenharmony_ci in[5] = (int)(a2 - b2) >> ROW_SHIFT; 134cabdff1aSopenharmony_ci in[6] = (int)(a1 - b1) >> ROW_SHIFT; 135cabdff1aSopenharmony_ci in[7] = (int)(a0 - b0) >> ROW_SHIFT; 136cabdff1aSopenharmony_ci } 137cabdff1aSopenharmony_ci return 1; 138cabdff1aSopenharmony_ci} 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_ci#define TAN1 0x32EC 141cabdff1aSopenharmony_ci#define TAN2 0x6A0A 142cabdff1aSopenharmony_ci#define TAN3 0xAB0E 143cabdff1aSopenharmony_ci#define SQRT2 0x5A82 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci#define MULT(c, x, n) ((unsigned)((int)((c) * (unsigned)(x)) >> (n))) 146cabdff1aSopenharmony_ci// 12b version => #define MULT(c,x, n) ((((c) >> 3) * (x)) >> ((n) - 3)) 147cabdff1aSopenharmony_ci// 12b zero-testing version: 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci#define BUTTERFLY(a, b, tmp) \ 150cabdff1aSopenharmony_ci (tmp) = (a) + (b); \ 151cabdff1aSopenharmony_ci (b) = (a) - (b); \ 152cabdff1aSopenharmony_ci (a) = (tmp) 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_ci#define LOAD_BUTTERFLY(m1, m2, a, b, tmp, s) \ 155cabdff1aSopenharmony_ci (m1) = (s)[(a)] + (s)[(b)]; \ 156cabdff1aSopenharmony_ci (m2) = (s)[(a)] - (s)[(b)] 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_cistatic void idct_col_8(short *const in) 159cabdff1aSopenharmony_ci{ 160cabdff1aSopenharmony_ci int mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, spill; 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci // odd 163cabdff1aSopenharmony_ci 164cabdff1aSopenharmony_ci mm4 = (int) in[7 * 8]; 165cabdff1aSopenharmony_ci mm5 = (int) in[5 * 8]; 166cabdff1aSopenharmony_ci mm6 = (int) in[3 * 8]; 167cabdff1aSopenharmony_ci mm7 = (int) in[1 * 8]; 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci mm0 = MULT(TAN1, mm4, 16) + mm7; 170cabdff1aSopenharmony_ci mm1 = MULT(TAN1, mm7, 16) - mm4; 171cabdff1aSopenharmony_ci mm2 = MULT(TAN3, mm5, 16) + mm6; 172cabdff1aSopenharmony_ci mm3 = MULT(TAN3, mm6, 16) - mm5; 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci mm7 = mm0 + mm2; 175cabdff1aSopenharmony_ci mm4 = mm1 - mm3; 176cabdff1aSopenharmony_ci mm0 = mm0 - mm2; 177cabdff1aSopenharmony_ci mm1 = mm1 + mm3; 178cabdff1aSopenharmony_ci mm6 = mm0 + mm1; 179cabdff1aSopenharmony_ci mm5 = mm0 - mm1; 180cabdff1aSopenharmony_ci mm5 = 2 * MULT(SQRT2, mm5, 16); // 2*sqrt2 181cabdff1aSopenharmony_ci mm6 = 2 * MULT(SQRT2, mm6, 16); // Watch out: precision loss but done to match 182cabdff1aSopenharmony_ci // the pmulhw used in MMX/MMXEXT/SSE2 versions 183cabdff1aSopenharmony_ci 184cabdff1aSopenharmony_ci // even 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ci mm1 = (int) in[2 * 8]; 187cabdff1aSopenharmony_ci mm2 = (int) in[6 * 8]; 188cabdff1aSopenharmony_ci mm3 = MULT(TAN2, mm2, 16) + mm1; 189cabdff1aSopenharmony_ci mm2 = MULT(TAN2, mm1, 16) - mm2; 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci LOAD_BUTTERFLY(mm0, mm1, 0 * 8, 4 * 8, spill, in); 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_ci BUTTERFLY(mm0, mm3, spill); 194cabdff1aSopenharmony_ci BUTTERFLY(mm0, mm7, spill); 195cabdff1aSopenharmony_ci in[8 * 0] = (int16_t) (mm0 >> COL_SHIFT); 196cabdff1aSopenharmony_ci in[8 * 7] = (int16_t) (mm7 >> COL_SHIFT); 197cabdff1aSopenharmony_ci BUTTERFLY(mm3, mm4, mm0); 198cabdff1aSopenharmony_ci in[8 * 3] = (int16_t) (mm3 >> COL_SHIFT); 199cabdff1aSopenharmony_ci in[8 * 4] = (int16_t) (mm4 >> COL_SHIFT); 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci BUTTERFLY(mm1, mm2, mm0); 202cabdff1aSopenharmony_ci BUTTERFLY(mm1, mm6, mm0); 203cabdff1aSopenharmony_ci in[8 * 1] = (int16_t) (mm1 >> COL_SHIFT); 204cabdff1aSopenharmony_ci in[8 * 6] = (int16_t) (mm6 >> COL_SHIFT); 205cabdff1aSopenharmony_ci BUTTERFLY(mm2, mm5, mm0); 206cabdff1aSopenharmony_ci in[8 * 2] = (int16_t) (mm2 >> COL_SHIFT); 207cabdff1aSopenharmony_ci in[8 * 5] = (int16_t) (mm5 >> COL_SHIFT); 208cabdff1aSopenharmony_ci} 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_cistatic void idct_col_4(short *const in) 211cabdff1aSopenharmony_ci{ 212cabdff1aSopenharmony_ci int mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, spill; 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_ci // odd 215cabdff1aSopenharmony_ci 216cabdff1aSopenharmony_ci mm0 = (int) in[1 * 8]; 217cabdff1aSopenharmony_ci mm2 = (int) in[3 * 8]; 218cabdff1aSopenharmony_ci 219cabdff1aSopenharmony_ci mm1 = MULT(TAN1, mm0, 16); 220cabdff1aSopenharmony_ci mm3 = MULT(TAN3, mm2, 16); 221cabdff1aSopenharmony_ci 222cabdff1aSopenharmony_ci mm7 = mm0 + mm2; 223cabdff1aSopenharmony_ci mm4 = mm1 - mm3; 224cabdff1aSopenharmony_ci mm0 = mm0 - mm2; 225cabdff1aSopenharmony_ci mm1 = mm1 + mm3; 226cabdff1aSopenharmony_ci mm6 = mm0 + mm1; 227cabdff1aSopenharmony_ci mm5 = mm0 - mm1; 228cabdff1aSopenharmony_ci mm6 = 2 * MULT(SQRT2, mm6, 16); // 2*sqrt2 229cabdff1aSopenharmony_ci mm5 = 2 * MULT(SQRT2, mm5, 16); 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_ci // even 232cabdff1aSopenharmony_ci 233cabdff1aSopenharmony_ci mm0 = mm1 = (int) in[0 * 8]; 234cabdff1aSopenharmony_ci mm3 = (int) in[2 * 8]; 235cabdff1aSopenharmony_ci mm2 = MULT(TAN2, mm3, 16); 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_ci BUTTERFLY(mm0, mm3, spill); 238cabdff1aSopenharmony_ci BUTTERFLY(mm0, mm7, spill); 239cabdff1aSopenharmony_ci in[8 * 0] = (int16_t) (mm0 >> COL_SHIFT); 240cabdff1aSopenharmony_ci in[8 * 7] = (int16_t) (mm7 >> COL_SHIFT); 241cabdff1aSopenharmony_ci BUTTERFLY(mm3, mm4, mm0); 242cabdff1aSopenharmony_ci in[8 * 3] = (int16_t) (mm3 >> COL_SHIFT); 243cabdff1aSopenharmony_ci in[8 * 4] = (int16_t) (mm4 >> COL_SHIFT); 244cabdff1aSopenharmony_ci 245cabdff1aSopenharmony_ci BUTTERFLY(mm1, mm2, mm0); 246cabdff1aSopenharmony_ci BUTTERFLY(mm1, mm6, mm0); 247cabdff1aSopenharmony_ci in[8 * 1] = (int16_t) (mm1 >> COL_SHIFT); 248cabdff1aSopenharmony_ci in[8 * 6] = (int16_t) (mm6 >> COL_SHIFT); 249cabdff1aSopenharmony_ci BUTTERFLY(mm2, mm5, mm0); 250cabdff1aSopenharmony_ci in[8 * 2] = (int16_t) (mm2 >> COL_SHIFT); 251cabdff1aSopenharmony_ci in[8 * 5] = (int16_t) (mm5 >> COL_SHIFT); 252cabdff1aSopenharmony_ci} 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_cistatic void idct_col_3(short *const in) 255cabdff1aSopenharmony_ci{ 256cabdff1aSopenharmony_ci int mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, spill; 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_ci // odd 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci mm7 = (int) in[1 * 8]; 261cabdff1aSopenharmony_ci mm4 = MULT(TAN1, mm7, 16); 262cabdff1aSopenharmony_ci 263cabdff1aSopenharmony_ci mm6 = mm7 + mm4; 264cabdff1aSopenharmony_ci mm5 = mm7 - mm4; 265cabdff1aSopenharmony_ci mm6 = 2 * MULT(SQRT2, mm6, 16); // 2*sqrt2 266cabdff1aSopenharmony_ci mm5 = 2 * MULT(SQRT2, mm5, 16); 267cabdff1aSopenharmony_ci 268cabdff1aSopenharmony_ci // even 269cabdff1aSopenharmony_ci 270cabdff1aSopenharmony_ci mm0 = mm1 = (int) in[0 * 8]; 271cabdff1aSopenharmony_ci mm3 = (int) in[2 * 8]; 272cabdff1aSopenharmony_ci mm2 = MULT(TAN2, mm3, 16); 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci BUTTERFLY(mm0, mm3, spill); 275cabdff1aSopenharmony_ci BUTTERFLY(mm0, mm7, spill); 276cabdff1aSopenharmony_ci in[8 * 0] = (int16_t) (mm0 >> COL_SHIFT); 277cabdff1aSopenharmony_ci in[8 * 7] = (int16_t) (mm7 >> COL_SHIFT); 278cabdff1aSopenharmony_ci BUTTERFLY(mm3, mm4, mm0); 279cabdff1aSopenharmony_ci in[8 * 3] = (int16_t) (mm3 >> COL_SHIFT); 280cabdff1aSopenharmony_ci in[8 * 4] = (int16_t) (mm4 >> COL_SHIFT); 281cabdff1aSopenharmony_ci 282cabdff1aSopenharmony_ci BUTTERFLY(mm1, mm2, mm0); 283cabdff1aSopenharmony_ci BUTTERFLY(mm1, mm6, mm0); 284cabdff1aSopenharmony_ci in[8 * 1] = (int16_t) (mm1 >> COL_SHIFT); 285cabdff1aSopenharmony_ci in[8 * 6] = (int16_t) (mm6 >> COL_SHIFT); 286cabdff1aSopenharmony_ci BUTTERFLY(mm2, mm5, mm0); 287cabdff1aSopenharmony_ci in[8 * 2] = (int16_t) (mm2 >> COL_SHIFT); 288cabdff1aSopenharmony_ci in[8 * 5] = (int16_t) (mm5 >> COL_SHIFT); 289cabdff1aSopenharmony_ci} 290cabdff1aSopenharmony_ci 291cabdff1aSopenharmony_civoid ff_xvid_idct(int16_t *const in) 292cabdff1aSopenharmony_ci{ 293cabdff1aSopenharmony_ci int i, rows = 0x07; 294cabdff1aSopenharmony_ci 295cabdff1aSopenharmony_ci idct_row(in + 0 * 8, TAB04, RND0); 296cabdff1aSopenharmony_ci idct_row(in + 1 * 8, TAB17, RND1); 297cabdff1aSopenharmony_ci idct_row(in + 2 * 8, TAB26, RND2); 298cabdff1aSopenharmony_ci if (idct_row(in + 3 * 8, TAB35, RND3)) 299cabdff1aSopenharmony_ci rows |= 0x08; 300cabdff1aSopenharmony_ci if (idct_row(in + 4 * 8, TAB04, RND4)) 301cabdff1aSopenharmony_ci rows |= 0x10; 302cabdff1aSopenharmony_ci if (idct_row(in + 5 * 8, TAB35, RND5)) 303cabdff1aSopenharmony_ci rows |= 0x20; 304cabdff1aSopenharmony_ci if (idct_row(in + 6 * 8, TAB26, RND6)) 305cabdff1aSopenharmony_ci rows |= 0x40; 306cabdff1aSopenharmony_ci if (idct_row(in + 7 * 8, TAB17, RND7)) 307cabdff1aSopenharmony_ci rows |= 0x80; 308cabdff1aSopenharmony_ci 309cabdff1aSopenharmony_ci if (rows & 0xF0) { 310cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) 311cabdff1aSopenharmony_ci idct_col_8(in + i); 312cabdff1aSopenharmony_ci } else if (rows & 0x08) { 313cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) 314cabdff1aSopenharmony_ci idct_col_4(in + i); 315cabdff1aSopenharmony_ci } else { 316cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) 317cabdff1aSopenharmony_ci idct_col_3(in + i); 318cabdff1aSopenharmony_ci } 319cabdff1aSopenharmony_ci} 320cabdff1aSopenharmony_ci 321cabdff1aSopenharmony_cistatic void xvid_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 322cabdff1aSopenharmony_ci{ 323cabdff1aSopenharmony_ci ff_xvid_idct(block); 324cabdff1aSopenharmony_ci ff_put_pixels_clamped_c(block, dest, line_size); 325cabdff1aSopenharmony_ci} 326cabdff1aSopenharmony_ci 327cabdff1aSopenharmony_cistatic void xvid_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block) 328cabdff1aSopenharmony_ci{ 329cabdff1aSopenharmony_ci ff_xvid_idct(block); 330cabdff1aSopenharmony_ci ff_add_pixels_clamped_c(block, dest, line_size); 331cabdff1aSopenharmony_ci} 332cabdff1aSopenharmony_ci 333cabdff1aSopenharmony_ciav_cold void ff_xvid_idct_init(IDCTDSPContext *c, AVCodecContext *avctx) 334cabdff1aSopenharmony_ci{ 335cabdff1aSopenharmony_ci const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8; 336cabdff1aSopenharmony_ci 337cabdff1aSopenharmony_ci if (high_bit_depth || avctx->lowres || 338cabdff1aSopenharmony_ci !(avctx->idct_algo == FF_IDCT_AUTO || 339cabdff1aSopenharmony_ci avctx->idct_algo == FF_IDCT_XVID)) 340cabdff1aSopenharmony_ci return; 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_ci if (avctx->idct_algo == FF_IDCT_XVID) { 343cabdff1aSopenharmony_ci c->idct_put = xvid_idct_put; 344cabdff1aSopenharmony_ci c->idct_add = xvid_idct_add; 345cabdff1aSopenharmony_ci c->idct = ff_xvid_idct; 346cabdff1aSopenharmony_ci c->perm_type = FF_IDCT_PERM_NONE; 347cabdff1aSopenharmony_ci } 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ci#if ARCH_X86 350cabdff1aSopenharmony_ci ff_xvid_idct_init_x86(c, avctx, high_bit_depth); 351cabdff1aSopenharmony_ci#elif ARCH_MIPS 352cabdff1aSopenharmony_ci ff_xvid_idct_init_mips(c, avctx, high_bit_depth); 353cabdff1aSopenharmony_ci#endif 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_ci ff_init_scantable_permutation(c->idct_permutation, c->perm_type); 356cabdff1aSopenharmony_ci} 357