vputil.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285
  1. /****************************************************************************
  2. *
  3. * Module Title : vputil.c
  4. *
  5. * Description : Codec utility functions.
  6. *
  7. ***************************************************************************/
  8. #define STRICT /* Strict type checking */
  9. /****************************************************************************
  10. * Header Files
  11. ***************************************************************************/
  12. #include <math.h>
  13. #include "codec_common.h"
  14. /****************************************************************************
  15. * Macros
  16. ****************************************************************************/
  17. #define FILTER_WEIGHT 128
  18. #define FILTER_SHIFT 7
  19. #define MIN(a, b) ( ( a < b ) ? a : b )
  20. /****************************************************************************
  21. * Imports
  22. ***************************************************************************/
  23. extern void UtilMachineSpecificConfig ( void );
  24. extern void fillidctconstants ( void );
  25. /****************************************************************************
  26. * Module Statics
  27. ****************************************************************************/
  28. INT32 BilinearFilters[8][2] =
  29. {
  30. { 128, 0 },
  31. { 112, 16 },
  32. { 96, 32 },
  33. { 80, 48 },
  34. { 64, 64 },
  35. { 48, 80 },
  36. { 32, 96 },
  37. { 16, 112 }
  38. };
  39. // VP6.2 Bicubic filter taps calculated for 32 values of 'A' from -0.25 to -1.00 in steps of -0.05
  40. // For each 'A' there are 8 sets of data corresponding to 1/8 pel offsets 0 to 7/8.
  41. // These are only used in VP6.2 and upwards
  42. // The last entry is a dummy entry used for backwards compatibility with VP61
  43. static INT32 BicubicFilterSet[17][8][4] =
  44. {
  45. { { 0, 128, 0, 0 },
  46. { -3, 122, 9, 0 },
  47. { -4, 109, 24, -1 },
  48. { -5, 91, 45, -3 },
  49. { -4, 68, 68, -4 },
  50. { -3, 45, 91, -5 },
  51. { -1, 24, 109, -4 },
  52. { 0, 9, 122, -3 },
  53. },
  54. { { 0, 128, 0, 0 },
  55. { -4, 124, 9, -1 },
  56. { -5, 110, 25, -2 },
  57. { -6, 91, 46, -3 },
  58. { -5, 69, 69, -5 },
  59. { -3, 46, 91, -6 },
  60. { -2, 25, 110, -5 },
  61. { -1, 9, 124, -4 },
  62. },
  63. { { 0, 128, 0, 0 },
  64. { -4, 123, 10, -1 },
  65. { -6, 110, 26, -2 },
  66. { -7, 92, 47, -4 },
  67. { -6, 70, 70, -6 },
  68. { -4, 47, 92, -7 },
  69. { -2, 26, 110, -6 },
  70. { -1, 10, 123, -4 },
  71. },
  72. { { 0, 128, 0, 0 }, // Approx A=-0.4
  73. { -5, 124, 10, -1 },
  74. { -7, 110, 27, -2 },
  75. { -7, 91, 48, -4 },
  76. { -6, 70, 70, -6 },
  77. { -4, 48, 92, -8 },
  78. { -2, 27, 110, -7 },
  79. { -1, 10, 124, -5 },
  80. },
  81. { { 0, 128, 0, 0 },
  82. { -6, 124, 11, -1 },
  83. { -8, 111, 28, -3 },
  84. { -8, 92, 49, -5 },
  85. { -7, 71, 71, -7 },
  86. { -5, 49, 92, -8 },
  87. { -3, 28, 111, -8 },
  88. { -1, 11, 124, -6 },
  89. },
  90. { { 0, 128, 0, 0 }, // Corresponds approximately to VDub bicubic A=-0.50
  91. { -6, 123, 12, -1 },
  92. { -9, 111, 29, -3 },
  93. { -9, 93, 50, -6 },
  94. { -8, 72, 72, -8 },
  95. { -6, 50, 93, -9 },
  96. { -3, 29, 111, -9 },
  97. { -1, 12, 123, -6 },
  98. },
  99. { { 0, 128, 0, 0 },
  100. { -7, 124, 12, -1 },
  101. { -10, 111, 30, -3 },
  102. { -10, 93, 51, -6 },
  103. { -9, 73, 73, -9 },
  104. { -6, 51, 93, -10 },
  105. { -3, 30, 111, -10 },
  106. { -1, 12, 124, -7 },
  107. },
  108. { { 0, 128, 0, 0 },
  109. { -7, 123, 13, -1 },
  110. { -11, 112, 31, -4 },
  111. { -11, 94, 52, -7 },
  112. { -10, 74, 74, -10 },
  113. { -7, 52, 94, -11 },
  114. { -4, 31, 112, -11 },
  115. { -1, 13, 123, -7 },
  116. },
  117. { { 0, 128, 0, 0 },
  118. { -8, 124, 13, -1 },
  119. { -12, 112, 32, -4 },
  120. { -12, 94, 53, -7 },
  121. { -10, 74, 74, -10 },
  122. { -7, 53, 94, -12 },
  123. { -4, 32, 112, -12 },
  124. { -1, 13, 124, -8 },
  125. },
  126. { { 0, 128, 0, 0 },
  127. { -9, 124, 14, -1 },
  128. { -13, 112, 33, -4 },
  129. { -13, 95, 54, -8 },
  130. { -11, 75, 75, -11 },
  131. { -8, 54, 95, -13 },
  132. { -4, 33, 112, -13 },
  133. { -1, 14, 124, -9 },
  134. },
  135. { { 0, 128, 0, 0 }, // Corresponds approximately to VDub bicubic A=-0.75
  136. { -9, 123, 15, -1 },
  137. { -14, 113, 34, -5 },
  138. { -14, 95, 55, -8 },
  139. { -12, 76, 76, -12 },
  140. { -8, 55, 95, -14 },
  141. { -5, 34, 112, -13 },
  142. { -1, 15, 123, -9 },
  143. },
  144. { { 0, 128, 0, 0 },
  145. { -10, 124, 15, -1 },
  146. { -14, 113, 34, -5 },
  147. { -15, 96, 56, -9 },
  148. { -13, 77, 77, -13 },
  149. { -9, 56, 96, -15 },
  150. { -5, 34, 113, -14 },
  151. { -1, 15, 124, -10 },
  152. },
  153. { { 0, 128, 0, 0 },
  154. { -10, 123, 16, -1 },
  155. { -15, 113, 35, -5 },
  156. { -16, 98, 56, -10 },
  157. { -14, 78, 78, -14 },
  158. { -10, 56, 98, -16 },
  159. { -5, 35, 113, -15 },
  160. { -1, 16, 123, -10 },
  161. },
  162. { { 0, 128, 0, 0 },
  163. { -11, 124, 17, -2 },
  164. { -16, 113, 36, -5 },
  165. { -17, 98, 57, -10 },
  166. { -14, 78, 78, -14 },
  167. { -10, 57, 98, -17 },
  168. { -5, 36, 113, -16 },
  169. { -2, 17, 124, -11 },
  170. },
  171. { { 0, 128, 0, 0 },
  172. { -12, 125, 17, -2 },
  173. { -17, 114, 37, -6 },
  174. { -18, 99, 58, -11 },
  175. { -15, 79, 79, -15 },
  176. { -11, 58, 99, -18 },
  177. { -6, 37, 114, -17 },
  178. { -2, 17, 125, -12 },
  179. },
  180. { { 0, 128, 0, 0 },
  181. { -12, 124, 18, -2 },
  182. { -18, 114, 38, -6 },
  183. { -19, 99, 59, -11 },
  184. { -16, 80, 80, -16 },
  185. { -11, 59, 99, -19 },
  186. { -6, 38, 114, -18 },
  187. { -2, 18, 124, -12 },
  188. },
  189. // Dummy entry for backwards VP61 compatibility
  190. {
  191. { 0, 128, 0, 0 },
  192. { -4, 118, 16, -2 },
  193. { -7, 106, 34, -5 },
  194. { -8, 90, 53, -7 },
  195. { -8, 72, 72, -8 },
  196. { -7, 53, 90, -8 },
  197. { -5, 34, 106, -7 },
  198. { -2, 16, 118, -4 }
  199. }
  200. };
  201. //static INT32 FData[BLOCK_HEIGHT_WIDTH*11]; // Temp data bufffer used in filtering
  202. /****************************************************************************
  203. * Exports
  204. ****************************************************************************/
  205. // Function pointers to platform specif routines
  206. void (*ReconIntra)( INT16 *tmpBuffer, UINT8 *ReconPtr, UINT16 *ChangePtr, UINT32 LineStep );
  207. void (*ReconInter)( INT16 *tmpBuffer, UINT8 *ReconPtr, UINT8 *RefPtr, INT16 *ChangePtr, UINT32 LineStep );
  208. void (*ReconInterHalfPixel2)( INT16 * tmpBuffer, UINT8 * ReconPtr, UINT8 *RefPtr1, UINT8 *RefPtr2, INT16 *ChangePtr, UINT32 LineStep );
  209. void (*fdct_short)( INT16 *InputData, INT16 *OutputData );
  210. void (*idct[65])( INT16 *InputData, INT16 *QuantMatrix, INT16 *OutputData );
  211. void (*ClearSysState)( void );
  212. void (*ReconBlock)( INT16 *SrcBlock, INT16 *ReconRefPtr, UINT8 *DestBlock, UINT32 LineStep );
  213. void (*SubtractBlock)( UINT8 *SrcBlock, INT16 *DestPtr, UINT32 LineStep );
  214. void (*UnpackBlock)( UINT8 *ReconPtr, INT16 *ReconRefPtr, UINT32 ReconPixelsPerLine);
  215. void (*AverageBlock)( UINT8 *ReconPtr1, UINT8 *ReconPtr2, UINT16 *ReconRefPtr, UINT32 ReconPixelsPerLine );
  216. void (*CopyBlock)( unsigned char *src, unsigned char *dest, unsigned int srcstride );
  217. void (*Copy12x12)( const unsigned char *src, unsigned char *dest, unsigned int srcstride, unsigned int deststride );
  218. void (*idctc[65])( INT16 *InputData, INT16 *QuantMatrix, INT16 *OutputData );
  219. void (*FilterBlockBil_8)( UINT8 *ReconPtr1, UINT8 *ReconPtr2, UINT8 *ReconRefPtr, UINT32 ReconPixelsPerLine, INT32 ModX, INT32 ModY );
  220. void (*FilterBlock)( UINT8 *ReconPtr1, UINT8 *ReconPtr2, UINT16 *ReconRefPtr, UINT32 PixelsPerLine, INT32 ModX, INT32 ModY, BOOL UseBicubic, UINT8 BicubicAlpha );
  221. /****************************************************************************
  222. *
  223. * ROUTINE : ClearSysState_C
  224. *
  225. * INPUTS : None.
  226. *
  227. * OUTPUTS : None.
  228. *
  229. * RETURNS : void
  230. *
  231. * FUNCTION : Null placeholder function.
  232. *
  233. * SPECIAL NOTES : Stub in the C-code for a function required when using
  234. * MMX, XMM, etc. to clear system state.
  235. *
  236. ****************************************************************************/
  237. void ClearSysState_C ( void )
  238. {
  239. }
  240. /****************************************************************************
  241. *
  242. * ROUTINE : AverageBlock_C
  243. *
  244. * INPUTS : UINT8 *ReconPtr1 : Pointer to first reference block.
  245. * UINT8 *ReconPtr2 : Pointer to second reference block.
  246. * UINT32 ReconPixelsPerLine : Stride of reference blocks.
  247. *
  248. * OUTPUTS : UINT16 *ReconRefPtr : Pointer to output block.
  249. *
  250. * RETURNS : void
  251. *
  252. * FUNCTION : Takes two input blocks and creates an output block
  253. * by pixel averaging.
  254. *
  255. * SPECIAL NOTES : None.
  256. *
  257. ****************************************************************************/
  258. void AverageBlock_C ( UINT8 *ReconPtr1, UINT8 *ReconPtr2, UINT16 *ReconRefPtr, UINT32 ReconPixelsPerLine )
  259. {
  260. UINT32 i;
  261. // For each block row
  262. for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ )
  263. {
  264. ReconRefPtr[0] = (INT16)(((INT32)(ReconPtr1[0]) + ((INT32)ReconPtr2[0]))>>1);
  265. ReconRefPtr[1] = (INT16)(((INT32)(ReconPtr1[1]) + ((INT32)ReconPtr2[1]))>>1);
  266. ReconRefPtr[2] = (INT16)(((INT32)(ReconPtr1[2]) + ((INT32)ReconPtr2[2]))>>1);
  267. ReconRefPtr[3] = (INT16)(((INT32)(ReconPtr1[3]) + ((INT32)ReconPtr2[3]))>>1);
  268. ReconRefPtr[4] = (INT16)(((INT32)(ReconPtr1[4]) + ((INT32)ReconPtr2[4]))>>1);
  269. ReconRefPtr[5] = (INT16)(((INT32)(ReconPtr1[5]) + ((INT32)ReconPtr2[5]))>>1);
  270. ReconRefPtr[6] = (INT16)(((INT32)(ReconPtr1[6]) + ((INT32)ReconPtr2[6]))>>1);
  271. ReconRefPtr[7] = (INT16)(((INT32)(ReconPtr1[7]) + ((INT32)ReconPtr2[7]))>>1);
  272. // Start next row
  273. ReconPtr1 += ReconPixelsPerLine;
  274. ReconPtr2 += ReconPixelsPerLine;
  275. ReconRefPtr += BLOCK_HEIGHT_WIDTH;
  276. }
  277. }
  278. /****************************************************************************
  279. *
  280. * ROUTINE : UnpackBlock_C
  281. *
  282. * INPUTS : UINT8 *ReconPtr : Pointer to reference block.
  283. * UINT32 ReconPixelsPerLine : Stride of reference block.
  284. *
  285. * OUTPUTS : UINT16 *ReconRefPtr : Pointer to output block.
  286. *
  287. * RETURNS : void
  288. *
  289. * FUNCTION : Converts block of 8x8 unsigned 8-bit to block of
  290. * signed 16-bit.
  291. *
  292. * SPECIAL NOTES : None.
  293. *
  294. ****************************************************************************/
  295. void UnpackBlock_C ( UINT8 *ReconPtr, INT16 *ReconRefPtr, UINT32 ReconPixelsPerLine )
  296. {
  297. UINT32 i;
  298. // For each block row
  299. for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ )
  300. {
  301. ReconRefPtr[0] = (INT16)ReconPtr[0];
  302. ReconRefPtr[1] = (INT16)ReconPtr[1];
  303. ReconRefPtr[2] = (INT16)ReconPtr[2];
  304. ReconRefPtr[3] = (INT16)ReconPtr[3];
  305. ReconRefPtr[4] = (INT16)ReconPtr[4];
  306. ReconRefPtr[5] = (INT16)ReconPtr[5];
  307. ReconRefPtr[6] = (INT16)ReconPtr[6];
  308. ReconRefPtr[7] = (INT16)ReconPtr[7];
  309. // Start next row
  310. ReconPtr += ReconPixelsPerLine;
  311. ReconRefPtr += BLOCK_HEIGHT_WIDTH;
  312. }
  313. }
  314. /****************************************************************************
  315. *
  316. * ROUTINE : SubtractBlock_C
  317. *
  318. * INPUTS : UINT8 *SrcBlock : Pointer to 8x8 source block.
  319. * UINT32 LineStep : Stride of source block.
  320. *
  321. * OUTPUTS : INT16 *DestPtr : Pointer to 8x8 output block.
  322. *
  323. * RETURNS : void
  324. *
  325. * FUNCTION : Subtracts block pointed to by DestPtr from that pointed
  326. * to by SrcBlock. Result stored in DstPtr.
  327. *
  328. * SPECIAL NOTES : None.
  329. *
  330. ****************************************************************************/
  331. void SubtractBlock_C ( UINT8 *SrcBlock, INT16 *DestPtr, UINT32 LineStep )
  332. {
  333. UINT32 i;
  334. // For each block row
  335. for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ )
  336. {
  337. DestPtr[0] = (INT16)((INT32)SrcBlock[0] - (INT32)DestPtr[0]);
  338. DestPtr[1] = (INT16)((INT32)SrcBlock[1] - (INT32)DestPtr[1]);
  339. DestPtr[2] = (INT16)((INT32)SrcBlock[2] - (INT32)DestPtr[2]);
  340. DestPtr[3] = (INT16)((INT32)SrcBlock[3] - (INT32)DestPtr[3]);
  341. DestPtr[4] = (INT16)((INT32)SrcBlock[4] - (INT32)DestPtr[4]);
  342. DestPtr[5] = (INT16)((INT32)SrcBlock[5] - (INT32)DestPtr[5]);
  343. DestPtr[6] = (INT16)((INT32)SrcBlock[6] - (INT32)DestPtr[6]);
  344. DestPtr[7] = (INT16)((INT32)SrcBlock[7] - (INT32)DestPtr[7]);
  345. // Start next row
  346. SrcBlock += LineStep;
  347. DestPtr += BLOCK_HEIGHT_WIDTH;
  348. }
  349. }
  350. /****************************************************************************
  351. *
  352. * ROUTINE : CopyBlock_C
  353. *
  354. * INPUTS : unsigned char *src : Pointer to 8x8 source block.
  355. * unsigned int srcstride : Pointer to 8x8 destination block.
  356. *
  357. * OUTPUTS : unsigned char *dest : Stride of blocks.
  358. *
  359. * RETURNS : void
  360. *
  361. * FUNCTION : Copies a block from source to destination.
  362. *
  363. * SPECIAL NOTES : Copies block in chunks of 32-bits at a time.
  364. *
  365. ****************************************************************************/
  366. void CopyBlock_C ( unsigned char *src, unsigned char *dest, unsigned int srcstride )
  367. {
  368. int j;
  369. unsigned char *s = src;
  370. unsigned char *d = dest;
  371. unsigned int stride = srcstride;
  372. for ( j=0; j<8; j++ )
  373. {
  374. ((UINT32*)d)[0] = ((UINT32*)s)[0];
  375. ((UINT32*)d)[1] = ((UINT32*)s)[1];
  376. s += stride;
  377. d += stride;
  378. }
  379. }
  380. /****************************************************************************
  381. *
  382. * ROUTINE : Copy12x12_C
  383. *
  384. * INPUTS : const unsigned char *src : Pointer to source block.
  385. * unsigned int srcstride : Stride of the source block.
  386. * unsigned int deststride : Stride of the destination block.
  387. *
  388. * OUTPUTS : unsigned char *dest : Pointer to destination block.
  389. *
  390. * RETURNS : void
  391. *
  392. * FUNCTION : Copies a 12x12 block from source to destination.
  393. *
  394. * SPECIAL NOTES : None.
  395. *
  396. ****************************************************************************/
  397. void Copy12x12_C
  398. (
  399. const unsigned char *src,
  400. unsigned char *dest,
  401. unsigned int srcstride,
  402. unsigned int deststride
  403. )
  404. {
  405. int j;
  406. const unsigned char *s = src;
  407. unsigned char *d = dest;
  408. for ( j=0; j<12; j++ )
  409. {
  410. d[0] = s[0];
  411. d[1] = s[1];
  412. d[2] = s[2];
  413. d[3] = s[3];
  414. d[4] = s[4];
  415. d[5] = s[5];
  416. d[6] = s[6];
  417. d[7] = s[7];
  418. d[8] = s[8];
  419. d[9] = s[9];
  420. d[10] = s[10];
  421. d[11] = s[11];
  422. s += srcstride;
  423. d += deststride;
  424. }
  425. }
  426. /****************************************************************************
  427. *
  428. * ROUTINE : InitVPUtil
  429. *
  430. * INPUTS : None.
  431. *
  432. * OUTPUTS : None.
  433. *
  434. * RETURNS : void
  435. *
  436. * FUNCTION : Setup static initialized variables for Util.
  437. *
  438. * SPECIAL NOTES : None
  439. *
  440. ****************************************************************************/
  441. void InitVPUtil ( void )
  442. {
  443. fillidctconstants ();
  444. UtilMachineSpecificConfig ();
  445. }
  446. /****************************************************************************
  447. /* Fractional pixel prediction filtering...
  448. ****************************************************************************/
  449. /****************************************************************************
  450. *
  451. * ROUTINE : FilterBlock1d
  452. *
  453. * INPUTS : UINT8 *SrcPtr : Pointer to source block.
  454. * UINT32 SrcPixelsPerLine : Stride of source block.
  455. * UINT32 PixelStep : 1 for horizontal filtering,
  456. * SrcPixelsPerLine for vertical filtering.
  457. * UINT32 OutputHeight : Height of the output block.
  458. * UINT32 OutputWidth : Width of the output block.
  459. * INT32 *Filter : Array of 4 filter taps.
  460. *
  461. * OUTPUTS : UINT16 *OutputPtr : Pointer to output block.
  462. *
  463. * RETURNS : void.
  464. *
  465. * FUNCTION : Applies a 1-D 4-tap filter to the source block in
  466. * either horizontal or vertical direction to produce the
  467. * filtered output block.
  468. *
  469. * SPECIAL NOTES : Four filter taps should sum to FILTER_WEIGHT.
  470. * PixelStep defines whether the filter is applied
  471. * horizontally (PixelStep=1) or vertically (PixelStep=stride).
  472. * It defines the offset required to move from one input
  473. * to the next.
  474. *
  475. ****************************************************************************/
  476. void FilterBlock1d
  477. (
  478. UINT8 *SrcPtr,
  479. UINT16 *OutputPtr,
  480. UINT32 SrcPixelsPerLine,
  481. UINT32 PixelStep,
  482. UINT32 OutputHeight,
  483. UINT32 OutputWidth,
  484. INT32 *Filter
  485. )
  486. {
  487. UINT32 i, j;
  488. INT32 Temp;
  489. for ( i=0; i<OutputHeight; i++ )
  490. {
  491. for ( j=0; j<OutputWidth; j++ )
  492. {
  493. // Apply filter...
  494. Temp = ((INT32)SrcPtr[-(INT32)PixelStep] * Filter[0]) +
  495. ((INT32)SrcPtr[0] * Filter[1]) +
  496. ((INT32)SrcPtr[PixelStep] * Filter[2]) +
  497. ((INT32)SrcPtr[2*PixelStep] * Filter[3]) +
  498. (FILTER_WEIGHT >> 1); // Rounding
  499. // Normalize back to 0-255
  500. Temp = Temp >> FILTER_SHIFT;
  501. if ( Temp < 0 )
  502. Temp = 0;
  503. else if ( Temp > 255 )
  504. Temp = 255;
  505. OutputPtr[j] = (INT16)Temp;
  506. SrcPtr++;
  507. }
  508. // Next row...
  509. SrcPtr += SrcPixelsPerLine - OutputWidth;
  510. OutputPtr += OutputWidth;
  511. }
  512. }
  513. /****************************************************************************
  514. *
  515. * ROUTINE : FilterBlock2dFirstPass
  516. *
  517. * INPUTS : UINT8 *SrcPtr : Pointer to source block.
  518. * UINT32 SrcPixelsPerLine : Stride of source block.
  519. * UINT32 PixelStep : 1 for horizontal filtering,
  520. * SrcPixelsPerLine for vertical filtering.
  521. * UINT32 OutputHeight : Height of the output block.
  522. * UINT32 OutputWidth : Width of the output block.
  523. * INT32 *Filter : Array of 4 filter taps.
  524. *
  525. * OUTPUTS : INT32 *OutputPtr : Pointer to output block.
  526. *
  527. * RETURNS : void.
  528. *
  529. * FUNCTION : Applies a 1-D 4-tap filter to the source block in
  530. * either horizontal or vertical direction to produce the
  531. * filtered output block. Used to implement first-pass
  532. * of 2-D separable filter.
  533. *
  534. * SPECIAL NOTES : Produces INT32 output to retain precision for next pass.
  535. * Four filter taps should sum to FILTER_WEIGHT.
  536. * PixelStep defines whether the filter is applied
  537. * horizontally (PixelStep=1) or vertically (PixelStep=stride).
  538. * It defines the offset required to move from one input
  539. * to the next.
  540. *
  541. ****************************************************************************/
  542. void FilterBlock2dFirstPass
  543. (
  544. UINT8 *SrcPtr,
  545. INT32 *OutputPtr,
  546. UINT32 SrcPixelsPerLine,
  547. UINT32 PixelStep,
  548. UINT32 OutputHeight,
  549. UINT32 OutputWidth,
  550. INT32 *Filter
  551. )
  552. {
  553. UINT32 i, j;
  554. INT32 Temp;
  555. for ( i=0; i<OutputHeight; i++ )
  556. {
  557. for ( j=0; j<OutputWidth; j++ )
  558. {
  559. // Apply filter
  560. Temp = ((INT32)SrcPtr[-(INT32)PixelStep] * Filter[0]) +
  561. ((INT32)SrcPtr[0] * Filter[1]) +
  562. ((INT32)SrcPtr[PixelStep] * Filter[2]) +
  563. ((INT32)SrcPtr[2*PixelStep] * Filter[3]) +
  564. (FILTER_WEIGHT >> 1); // Rounding
  565. // Normalize back to 0-255
  566. Temp = Temp >> FILTER_SHIFT;
  567. if ( Temp < 0 )
  568. Temp = 0;
  569. else if ( Temp > 255 )
  570. Temp = 255;
  571. OutputPtr[j] = Temp;
  572. SrcPtr++;
  573. }
  574. // Next row...
  575. SrcPtr += SrcPixelsPerLine - OutputWidth;
  576. OutputPtr += OutputWidth;
  577. }
  578. }
  579. /****************************************************************************
  580. *
  581. * ROUTINE : FilterBlock2dSecondPass
  582. *
  583. * INPUTS : INT32 *SrcPtr : Pointer to source block.
  584. * UINT32 SrcPixelsPerLine : Stride of source block.
  585. * UINT32 PixelStep : 1 for horizontal filtering,
  586. * SrcPixelsPerLine for vertical filtering.
  587. * UINT32 OutputHeight : Height of the output block.
  588. * UINT32 OutputWidth : Width of the output block.
  589. * INT32 *Filter : Array of 4 filter taps.
  590. *
  591. * OUTPUTS : UINT16 *OutputPtr : Pointer to output block.
  592. *
  593. * RETURNS : void.
  594. *
  595. * FUNCTION : Applies a 1-D 4-tap filter to the source block in
  596. * either horizontal or vertical direction to produce the
  597. * filtered output block. Used to implement second-pass
  598. * of 2-D separable filter.
  599. *
  600. * SPECIAL NOTES : Requires 32-bit input as produced by FilterBlock2dFirstPass.
  601. * Four filter taps should sum to FILTER_WEIGHT.
  602. * PixelStep defines whether the filter is applied
  603. * horizontally (PixelStep=1) or vertically (PixelStep=stride).
  604. * It defines the offset required to move from one input
  605. * to the next.
  606. *
  607. ****************************************************************************/
  608. void FilterBlock2dSecondPass
  609. (
  610. INT32 *SrcPtr,
  611. UINT16 *OutputPtr,
  612. UINT32 SrcPixelsPerLine,
  613. UINT32 PixelStep,
  614. UINT32 OutputHeight,
  615. UINT32 OutputWidth,
  616. INT32 *Filter
  617. )
  618. {
  619. UINT32 i,j;
  620. INT32 Temp;
  621. for ( i=0; i < OutputHeight; i++ )
  622. {
  623. for ( j = 0; j < OutputWidth; j++ )
  624. {
  625. // Apply filter
  626. Temp = ((INT32)SrcPtr[-(INT32)PixelStep] * Filter[0]) +
  627. ((INT32)SrcPtr[0] * Filter[1]) +
  628. ((INT32)SrcPtr[PixelStep] * Filter[2]) +
  629. ((INT32)SrcPtr[2*PixelStep] * Filter[3]) +
  630. (FILTER_WEIGHT >> 1); // Rounding
  631. // Normalize back to 0-255
  632. Temp = Temp >> FILTER_SHIFT;
  633. if ( Temp < 0 )
  634. Temp = 0;
  635. else if ( Temp > 255 )
  636. Temp = 255;
  637. OutputPtr[j] = (UINT16)Temp;
  638. SrcPtr++;
  639. }
  640. // Start next row
  641. SrcPtr += SrcPixelsPerLine - OutputWidth;
  642. OutputPtr += OutputWidth;
  643. }
  644. }
  645. /****************************************************************************
  646. *
  647. * ROUTINE : FilterBlock2d
  648. *
  649. * INPUTS : UINT8 *SrcPtr : Pointer to source block.
  650. * UINT32 SrcPixelsPerLine : Stride of input block.
  651. * INT32 *HFilter : Array of 4 horizontal filter taps.
  652. * INT32 *VFilter : Array of 4 vertical filter taps.
  653. *
  654. * OUTPUTS : UINT16 *OutputPtr : Pointer to filtered block.
  655. *
  656. * RETURNS : void
  657. *
  658. * FUNCTION : 2-D filters an 8x8 input block by applying a 4-tap
  659. * filter horizontally followed by a 4-tap filter vertically
  660. * on the result.
  661. *
  662. * SPECIAL NOTES : The intermediate horizontally filtered block must produce
  663. * 3 more points than the input block in each column. This
  664. * is to ensure that the 4-tap filter has one extra data-point
  665. * at the top & 2 extra data-points at the bottom of each
  666. * column so filter taps do not extend beyond data. Thus the
  667. * output of the first stage filter is an 8x11 (HxV) block.
  668. *
  669. ****************************************************************************/
  670. void FilterBlock2d
  671. (
  672. UINT8 *SrcPtr,
  673. UINT16 *OutputPtr,
  674. UINT32 SrcPixelsPerLine,
  675. INT32 *HFilter,
  676. INT32 *VFilter
  677. )
  678. {
  679. INT32 FData[BLOCK_HEIGHT_WIDTH*11]; // Temp data bufffer used in filtering
  680. // First filter 1-D horizontally...
  681. FilterBlock2dFirstPass ( SrcPtr-SrcPixelsPerLine, FData, SrcPixelsPerLine, 1, 11, 8, HFilter );
  682. // then filter verticaly...
  683. FilterBlock2dSecondPass ( FData+BLOCK_HEIGHT_WIDTH, OutputPtr, BLOCK_HEIGHT_WIDTH, BLOCK_HEIGHT_WIDTH, 8, 8, VFilter );
  684. }
  685. /****************************************************************************
  686. *
  687. * ROUTINE : FilterBlock1dBil
  688. *
  689. * INPUTS : UINT8 *SrcPtr : Pointer to source block.
  690. * UINT32 SrcPixelsPerLine : Stride of input block.
  691. * UINT32 PixelStep : Offset between filter input samples (see notes).
  692. * UINT32 OutputHeight : Input block height.
  693. * UINT32 OutputWidth : Input block width.
  694. * INT32 *Filter : Array of 2 bi-linear filter taps.
  695. *
  696. * OUTPUTS : UINT16 *OutputPtr : Pointer to filtered block.
  697. *
  698. * RETURNS : void
  699. *
  700. * FUNCTION : Applies a 2-tap 1-D bi-linear filter to input block in
  701. * either horizontal or vertical direction.
  702. *
  703. * SPECIAL NOTES : PixelStep defines whether the filter is applied
  704. * horizontally (PixelStep=1) or vertically (PixelStep=stride).
  705. * It defines the offset required to move from one input
  706. * to the next.
  707. *
  708. ****************************************************************************/
  709. void FilterBlock1dBil
  710. (
  711. UINT8 *SrcPtr,
  712. UINT16 *OutputPtr,
  713. UINT32 SrcPixelsPerLine,
  714. UINT32 PixelStep,
  715. UINT32 OutputHeight,
  716. UINT32 OutputWidth,
  717. INT32 *Filter
  718. )
  719. {
  720. UINT32 i, j;
  721. for ( i=0; i<OutputHeight; i++ )
  722. {
  723. for ( j=0; j<OutputWidth; j++ )
  724. {
  725. // Apply filter
  726. // NOTE: Rounding doesn't improve accuracy but is
  727. // easier to implement on certain platforms.
  728. OutputPtr[j] = (INT16)( ( ((INT32)SrcPtr[0] * Filter[0]) +
  729. ((INT32)SrcPtr[PixelStep] * Filter[1]) +
  730. (FILTER_WEIGHT/2) ) >> FILTER_SHIFT );
  731. SrcPtr++;
  732. }
  733. // Next row...
  734. SrcPtr += SrcPixelsPerLine - OutputWidth;
  735. OutputPtr += OutputWidth;
  736. }
  737. }
  738. /****************************************************************************
  739. *
  740. * ROUTINE : FilterBlock2dBil_FirstPass
  741. *
  742. * INPUTS : UINT8 *SrcPtr : Pointer to source block.
  743. * UINT32 SrcPixelsPerLine : Stride of input block.
  744. * UINT32 PixelStep : Offset between filter input samples (see notes).
  745. * UINT32 OutputHeight : Input block height.
  746. * UINT32 OutputWidth : Input block width.
  747. * INT32 *Filter : Array of 2 bi-linear filter taps.
  748. *
  749. * OUTPUTS : INT32 *OutputPtr : Pointer to filtered block.
  750. *
  751. * RETURNS : void
  752. *
  753. * FUNCTION : Applies a 1-D 2-tap bi-linear filter to the source block in
  754. * either horizontal or vertical direction to produce the
  755. * filtered output block. Used to implement first-pass
  756. * of 2-D separable filter.
  757. *
  758. * SPECIAL NOTES : Produces INT32 output to retain precision for next pass.
  759. * Two filter taps should sum to FILTER_WEIGHT.
  760. * PixelStep defines whether the filter is applied
  761. * horizontally (PixelStep=1) or vertically (PixelStep=stride).
  762. * It defines the offset required to move from one input
  763. * to the next.
  764. *
  765. ****************************************************************************/
  766. void FilterBlock2dBil_FirstPass
  767. (
  768. UINT8 *SrcPtr,
  769. INT32 *OutputPtr,
  770. UINT32 SrcPixelsPerLine,
  771. UINT32 PixelStep,
  772. UINT32 OutputHeight,
  773. UINT32 OutputWidth,
  774. INT32 *Filter
  775. )
  776. {
  777. UINT32 i, j;
  778. for ( i=0; i<OutputHeight; i++ )
  779. {
  780. for ( j=0; j<OutputWidth; j++ )
  781. {
  782. // Apply bilinear filter
  783. OutputPtr[j] = ( ( (INT32)SrcPtr[0] * Filter[0]) +
  784. ((INT32)SrcPtr[PixelStep] * Filter[1]) +
  785. (FILTER_WEIGHT/2) ) >> FILTER_SHIFT;
  786. SrcPtr++;
  787. }
  788. // Next row...
  789. SrcPtr += SrcPixelsPerLine - OutputWidth;
  790. OutputPtr += OutputWidth;
  791. }
  792. }
  793. /****************************************************************************
  794. *
  795. * ROUTINE : FilterBlock2dBil_SecondPass
  796. *
  797. * INPUTS : INT32 *SrcPtr : Pointer to source block.
  798. * UINT32 SrcPixelsPerLine : Stride of input block.
  799. * UINT32 PixelStep : Offset between filter input samples (see notes).
  800. * UINT32 OutputHeight : Input block height.
  801. * UINT32 OutputWidth : Input block width.
  802. * INT32 *Filter : Array of 2 bi-linear filter taps.
  803. *
  804. * OUTPUTS : UINT16 *OutputPtr : Pointer to filtered block.
  805. *
  806. * RETURNS : void
  807. *
  808. * FUNCTION : Applies a 1-D 2-tap bi-linear filter to the source block in
  809. * either horizontal or vertical direction to produce the
  810. * filtered output block. Used to implement second-pass
  811. * of 2-D separable filter.
  812. *
  813. * SPECIAL NOTES : Requires 32-bit input as produced by FilterBlock2dBil_FirstPass.
  814. * Two filter taps should sum to FILTER_WEIGHT.
  815. * PixelStep defines whether the filter is applied
  816. * horizontally (PixelStep=1) or vertically (PixelStep=stride).
  817. * It defines the offset required to move from one input
  818. * to the next.
  819. *
  820. ****************************************************************************/
  821. void FilterBlock2dBil_SecondPass
  822. (
  823. INT32 *SrcPtr,
  824. UINT16 *OutputPtr,
  825. UINT32 SrcPixelsPerLine,
  826. UINT32 PixelStep,
  827. UINT32 OutputHeight,
  828. UINT32 OutputWidth,
  829. INT32 *Filter
  830. )
  831. {
  832. UINT32 i,j;
  833. INT32 Temp;
  834. for ( i=0; i<OutputHeight; i++ )
  835. {
  836. for ( j=0; j<OutputWidth; j++ )
  837. {
  838. // Apply filter
  839. Temp = ((INT32)SrcPtr[0] * Filter[0]) +
  840. ((INT32)SrcPtr[PixelStep] * Filter[1]) +
  841. (FILTER_WEIGHT/2);
  842. OutputPtr[j] = (UINT16)(Temp >> FILTER_SHIFT);
  843. SrcPtr++;
  844. }
  845. // Next row...
  846. SrcPtr += SrcPixelsPerLine - OutputWidth;
  847. OutputPtr += OutputWidth;
  848. }
  849. }
  850. /****************************************************************************
  851. *
  852. * ROUTINE : FilterBlock2dBil
  853. *
  854. * INPUTS : UINT8 *SrcPtr : Pointer to source block.
  855. * UINT32 SrcPixelsPerLine : Stride of input block.
  856. * INT32 *HFilter : Array of 2 horizontal filter taps.
  857. * INT32 *VFilter : Array of 2 vertical filter taps.
  858. *
  859. * OUTPUTS : UINT16 *OutputPtr : Pointer to filtered block.
  860. *
  861. * RETURNS : void
  862. *
  863. * FUNCTION : 2-D filters an 8x8 input block by applying a 2-tap
  864. * bi-linear filter horizontally followed by a 2-tap
  865. * bi-linear filter vertically on the result.
  866. *
  867. * SPECIAL NOTES : The intermediate horizontally filtered block must produce
  868. * 1 more point than the input block in each column. This
  869. * is to ensure that the 2-tap filter has one extra data-point
  870. * at the top of each column so filter taps do not extend
  871. * beyond data. Thus the output of the first stage filter
  872. * is an 8x9 (HxV) block.
  873. *
  874. ****************************************************************************/
  875. void FilterBlock2dBil
  876. (
  877. UINT8 *SrcPtr,
  878. UINT16 *OutputPtr,
  879. UINT32 SrcPixelsPerLine,
  880. INT32 *HFilter,
  881. INT32 *VFilter
  882. )
  883. {
  884. INT32 FData[BLOCK_HEIGHT_WIDTH*11]; // Temp data bufffer used in filtering
  885. // First filter 1-D horizontally...
  886. FilterBlock2dBil_FirstPass ( SrcPtr, FData, SrcPixelsPerLine, 1, 9, 8, HFilter );
  887. // then 1-D vertically...
  888. FilterBlock2dBil_SecondPass ( FData, OutputPtr, BLOCK_HEIGHT_WIDTH, BLOCK_HEIGHT_WIDTH, 8, 8, VFilter );
  889. }
  890. /****************************************************************************
  891. *
  892. * ROUTINE : FilterBlock_C
  893. *
  894. * INPUTS : UINT8 *ReconPtr1 : Pointer to first 8x8 input block.
  895. * UINT8 *ReconPtr2 : Pointer to second 8x8 input block.
  896. * UINT32 PixelsPerLine : Stride for ReconPtr1 & ReconPtr2.
  897. * INT32 ModX : Fractional part of x-component of motion vector.
  898. * INT32 ModY : Fractional part of y-component of motion vector.
  899. * BOOL UseBicubic : TRUE=Bicubic, FALSE=Bi-Linear filter.
  900. * UINT8 BicubicAlpha : Defines which set of bicubic taps to use.
  901. *
  902. * OUTPUTS : UINT16 *ReconRefPtr : Pointer to 8x8 filtered block.
  903. *
  904. * RETURNS : void
  905. *
  906. * FUNCTION : Produces a filtered fractional pel prediction block
  907. * using bilinear or bicubic filters.
  908. * This is used by baseline VP6.2 and upwards.
  909. *
  910. * SPECIAL NOTES : ReconPtr1 & ReconPtr2 point to blocks that bracket the
  911. * position of the fractional pixel motion vector. These
  912. * two blocks are combined using either a bi-linear or
  913. * bi-cubic filter to produce the output prediction block
  914. * for this motion vector.
  915. * ModX, ModY are used for filter selection--see code
  916. * comment for definition.
  917. *
  918. ****************************************************************************/
  919. void FilterBlock_C
  920. (
  921. UINT8 *ReconPtr1,
  922. UINT8 *ReconPtr2,
  923. UINT16 *ReconRefPtr,
  924. UINT32 PixelsPerLine,
  925. INT32 ModX,
  926. INT32 ModY,
  927. BOOL UseBicubic,
  928. UINT8 BicubicAlpha
  929. )
  930. {
  931. int diff;
  932. // ModX and ModY are the bottom three bits of the signed motion vector
  933. // components (in 1/8th pel units). This works out to be what we want
  934. // --despite the pointer swapping that goes on below.
  935. // For example...
  936. // if MV x-component is +ve then ModX = x%8.
  937. // if MV x-component is -ve then ModX = 8+(x%8), where X%8 is in the range -7 to -1.
  938. // Swap pointers to ensure that ReconPtr1 is "smaller than",
  939. // i.e. above, left, above-right or above-left, ReconPtr1
  940. diff = ReconPtr2 - ReconPtr1;
  941. if ( diff<0 )
  942. {
  943. // ReconPtr1>ReconPtr2, so swap...
  944. UINT8 *temp = ReconPtr1;
  945. ReconPtr1 = ReconPtr2;
  946. ReconPtr2 = temp;
  947. diff = (int)(ReconPtr2-ReconPtr1);
  948. }
  949. if ( diff==1 )
  950. {
  951. // Fractional pixel in horizontal only...
  952. if ( UseBicubic )
  953. FilterBlock1d ( ReconPtr1, ReconRefPtr, PixelsPerLine, 1, 8, 8, BicubicFilterSet[BicubicAlpha][ModX] );
  954. else
  955. FilterBlock1dBil ( ReconPtr1, ReconRefPtr, PixelsPerLine, 1, 8, 8, BilinearFilters[ModX] );
  956. }
  957. else if ( diff == (int)(PixelsPerLine) )
  958. {
  959. // Fractional pixel in vertical only...
  960. if ( UseBicubic )
  961. FilterBlock1d ( ReconPtr1, ReconRefPtr, PixelsPerLine, PixelsPerLine, 8, 8, BicubicFilterSet[BicubicAlpha][ModY] );
  962. else
  963. FilterBlock1dBil ( ReconPtr1, ReconRefPtr, PixelsPerLine, PixelsPerLine, 8, 8, BilinearFilters[ModY] );
  964. }
  965. else if(diff == (int)(PixelsPerLine - 1))
  966. {
  967. // ReconPtr1 is Top right...
  968. if ( UseBicubic )
  969. FilterBlock2d ( ReconPtr1-1, ReconRefPtr, PixelsPerLine, BicubicFilterSet[BicubicAlpha][ModX], BicubicFilterSet[BicubicAlpha][ModY] );
  970. else
  971. FilterBlock2dBil ( ReconPtr1-1, ReconRefPtr, PixelsPerLine, BilinearFilters[ModX], BilinearFilters[ModY] );
  972. }
  973. else if(diff == (int)(PixelsPerLine + 1) )
  974. {
  975. // ReconPtr1 is Top left...
  976. if ( UseBicubic )
  977. FilterBlock2d ( ReconPtr1, ReconRefPtr, PixelsPerLine, BicubicFilterSet[BicubicAlpha][ModX], BicubicFilterSet[BicubicAlpha][ModY] );
  978. else
  979. FilterBlock2dBil ( ReconPtr1, ReconRefPtr, PixelsPerLine, BilinearFilters[ModX], BilinearFilters[ModY] );
  980. }
  981. }
  982. /****************************************************************************
  983. *
  984. * ROUTINE : FilterBlock1dBil_8
  985. *
  986. * INPUTS : UINT8 *SrcPtr : Pointer to source block.
  987. * UINT32 SrcPixelsPerLine : Stride of input block.
  988. * UINT32 PixelStep : Offset between filter input samples (see notes).
  989. * UINT32 OutputHeight : Input block height.
  990. * UINT32 OutputWidth : Input block width.
  991. * INT32 *Filter : Array of 2 bi-linear filter taps.
  992. *
  993. * OUTPUTS : UINT8 *OutputPtr : Pointer to filtered block.
  994. *
  995. * RETURNS : void
  996. *
  997. * FUNCTION : Applies a 2-tap 1-D bi-linear filter to input block in
  998. * either horizontal or vertical direction.
  999. *
  1000. * SPECIAL NOTES : PixelStep defines whether the filter is applied
  1001. * horizontally (PixelStep=1) or vertically (PixelStep=stride).
  1002. * It defines the offset required to move from one input
  1003. * to the next.
  1004. *
  1005. ****************************************************************************/
  1006. void FilterBlock1dBil_8
  1007. (
  1008. UINT8 *SrcPtr,
  1009. UINT8 *OutputPtr,
  1010. UINT32 SrcPixelsPerLine,
  1011. UINT32 PixelStep,
  1012. UINT32 OutputHeight,
  1013. UINT32 OutputWidth,
  1014. INT32 *Filter )
  1015. {
  1016. UINT32 i, j;
  1017. for ( i=0; i<OutputHeight; i++ )
  1018. {
  1019. for ( j=0; j<OutputWidth; j++ )
  1020. {
  1021. // Apply filter
  1022. // NOTE: Rounding doesn't improve accuracy but is
  1023. // easier to implement on certain platforms.
  1024. OutputPtr[j] = (UINT8)( ( ((INT32)SrcPtr[0] * Filter[0]) +
  1025. ((INT32)SrcPtr[PixelStep] * Filter[1]) +
  1026. (FILTER_WEIGHT/2) ) >> FILTER_SHIFT );
  1027. SrcPtr++;
  1028. }
  1029. // Next row...
  1030. SrcPtr += SrcPixelsPerLine - OutputWidth;
  1031. OutputPtr += OutputWidth;
  1032. }
  1033. }
  1034. /****************************************************************************
  1035. *
  1036. * ROUTINE : FilterBlock2dBil_SecondPass_8
  1037. *
  1038. * INPUTS : INT32 *SrcPtr : Pointer to source block.
  1039. * UINT32 SrcPixelsPerLine : Stride of input block.
  1040. * UINT32 PixelStep : Offset between filter input samples (see notes).
  1041. * UINT32 OutputHeight : Input block height.
  1042. * UINT32 OutputWidth : Input block width.
  1043. * INT32 *Filter : Array of 2 bi-linear filter taps.
  1044. *
  1045. * OUTPUTS : UINT8 *OutputPtr : Pointer to filtered block.
  1046. *
  1047. * RETURNS : void
  1048. *
  1049. * FUNCTION : Applies a 1-D 2-tap bi-linear filter to the source block in
  1050. * either horizontal or vertical direction to produce the
  1051. * filtered output block. Used to implement second-pass
  1052. * of 2-D separable bi-linear filter.
  1053. *
  1054. * SPECIAL NOTES : Requires 32-bit input as produced by FilterBlock2dBil_FirstPass.
  1055. * Two filter taps should sum to FILTER_WEIGHT.
  1056. * PixelStep defines whether the filter is applied
  1057. * horizontally (PixelStep=1) or vertically (PixelStep=stride).
  1058. * It defines the offset required to move from one input
  1059. * to the next.
  1060. *
  1061. ****************************************************************************/
  1062. void FilterBlock2dBil_SecondPass_8
  1063. (
  1064. INT32 *SrcPtr,
  1065. UINT8 *OutputPtr,
  1066. UINT32 SrcPixelsPerLine,
  1067. UINT32 PixelStep,
  1068. UINT32 OutputHeight,
  1069. UINT32 OutputWidth,
  1070. INT32 *Filter
  1071. )
  1072. {
  1073. UINT32 i, j;
  1074. INT32 Temp;
  1075. INT32 RoundValue = ((FILTER_WEIGHT*FILTER_WEIGHT) >> 1);
  1076. for ( i=0; i<OutputHeight; i++ )
  1077. {
  1078. for ( j=0; j<OutputWidth; j++ )
  1079. {
  1080. // Apply bi-linear filter...
  1081. Temp = ((INT32)SrcPtr[0] * Filter[0]) +
  1082. ((INT32)SrcPtr[PixelStep] * Filter[1]) +
  1083. (FILTER_WEIGHT / 2);
  1084. OutputPtr[j] = (UINT8)(Temp >> FILTER_SHIFT);
  1085. SrcPtr++;
  1086. }
  1087. // Next row...
  1088. SrcPtr += SrcPixelsPerLine - OutputWidth;
  1089. OutputPtr += OutputWidth;
  1090. }
  1091. }
  1092. /****************************************************************************
  1093. *
  1094. * ROUTINE : FilterBlock2dBil_8
  1095. *
  1096. * INPUTS : UINT8 *SrcPtr : Pointer to source block.
  1097. * UINT32 SrcPixelsPerLine : Stride of input block.
  1098. * INT32 *HFilter : Array of 2 horizontal filter taps.
  1099. * INT32 *VFilter : Array of 2 vertical filter taps.
  1100. *
  1101. * OUTPUTS : UINT8 *OutputPtr : Pointer to filtered block.
  1102. *
  1103. * RETURNS : void
  1104. *
  1105. * FUNCTION : 2-D filters an 8x8 input block by applying a 2-tap
  1106. * bi-linear filter horizontally followed by a 2-tap
  1107. * bi-linear filter vertically on the result. Output
  1108. * is 8-bit unsigned.
  1109. *
  1110. * SPECIAL NOTES : The intermediate horizontally filtered block must produce
  1111. * 1 more point than the input block in each column. This
  1112. * is to ensure that the 2-tap filter has one extra data-point
  1113. * at the top of each column so filter taps do not extend
  1114. * beyond data. Thus the output of the first stage filter
  1115. * is an 8x9 (HxV) block.
  1116. *
  1117. ****************************************************************************/
  1118. void FilterBlock2dBil_8
  1119. (
  1120. UINT8 *SrcPtr,
  1121. UINT8 *OutputPtr,
  1122. UINT32 SrcPixelsPerLine,
  1123. INT32 *HFilter,
  1124. INT32 *VFilter
  1125. )
  1126. {
  1127. INT32 FData[BLOCK_HEIGHT_WIDTH*11]; // Temp data bufffer used in filtering
  1128. // First filter 1-D horizontally...
  1129. FilterBlock2dBil_FirstPass ( SrcPtr, FData, SrcPixelsPerLine, 1, 9, 8, HFilter );
  1130. // then filter 1-D vertically..
  1131. FilterBlock2dBil_SecondPass_8 ( FData, OutputPtr, BLOCK_HEIGHT_WIDTH, BLOCK_HEIGHT_WIDTH, 8, 8, VFilter );
  1132. }
  1133. /****************************************************************************
  1134. *
  1135. * ROUTINE : FilterBlockBil_8_C
  1136. *
  1137. * INPUTS : UINT8 *ReconPtr1 : Pointer to first 8x8 input block.
  1138. * UINT8 *ReconPtr2 : Pointer to second 8x8 input block.
  1139. * UINT32 PixelsPerLine : Stride for ReconPtr1 & ReconPtr2.
  1140. * INT32 ModX : Fractional part of x-component of motion vector.
  1141. * INT32 ModY : Fractional part of y-component of motion vector.
  1142. *
  1143. * OUTPUTS : UINT8 *ReconRefPtr : Pointer to 8x8 filtered block.
  1144. *
  1145. * RETURNS : void
  1146. *
  1147. * FUNCTION : Produces a filtered fractional pel prediction block
  1148. * using bilinear filter.
  1149. *
  1150. * SPECIAL NOTES : ReconPtr1 & ReconPtr2 point to blocks that bracket the
  1151. * position of the fractional pixel motion vector. These
  1152. * two blocks are combined using a bi-linear filter to
  1153. * produce the output prediction block for this motion vector.
  1154. * ModX, ModY are used for filter selection--see code
  1155. * comment for definition.
  1156. *
  1157. ****************************************************************************/
  1158. void FilterBlockBil_8_C
  1159. (
  1160. UINT8 *ReconPtr1,
  1161. UINT8 *ReconPtr2,
  1162. UINT8 *ReconRefPtr,
  1163. UINT32 PixelsPerLine,
  1164. INT32 ModX,
  1165. INT32 ModY
  1166. )
  1167. {
  1168. int diff;
  1169. // ModX and ModY are the bottom three bits of the signed motion vector
  1170. // components (in 1/8th pel units). This works out to be what we want
  1171. // --despite the pointer swapping that goes on below.
  1172. // For example...
  1173. // if MV x-component is +ve then ModX = x%8.
  1174. // if MV x-component is -ve then ModX = 8+(x%8), where X%8 is in the range -7 to -1.
  1175. // Swap pointers to ensure that ReconPtr1 is "smaller than",
  1176. // i.e. above, left, above-right or above-left, ReconPtr1
  1177. diff = ReconPtr2 - ReconPtr1;
  1178. if ( diff<0 )
  1179. {
  1180. // ReconPtr1>ReconPtr2, so swap...
  1181. UINT8 *temp = ReconPtr1;
  1182. ReconPtr1 = ReconPtr2;
  1183. ReconPtr2 = temp;
  1184. diff = (int)(ReconPtr2-ReconPtr1);
  1185. }
  1186. if ( diff==1 )
  1187. {
  1188. // Fractional pixel in horizontal only...
  1189. FilterBlock1dBil_8 ( ReconPtr1, ReconRefPtr, PixelsPerLine, 1, 8, 8, BilinearFilters[ModX] );
  1190. }
  1191. else if ( diff == (int)(PixelsPerLine) )
  1192. {
  1193. // Fractional pixel in vertical only...
  1194. FilterBlock1dBil_8 ( ReconPtr1, ReconRefPtr, PixelsPerLine, PixelsPerLine, 8, 8, BilinearFilters[ModY] );
  1195. }
  1196. else if ( diff == (int)(PixelsPerLine - 1))
  1197. {
  1198. // ReconPtr1 is Top right...
  1199. FilterBlock2dBil_8 ( ReconPtr1-1, ReconRefPtr, PixelsPerLine, BilinearFilters[ModX], BilinearFilters[ModY] );
  1200. }
  1201. else if ( diff == (int)(PixelsPerLine + 1) )
  1202. {
  1203. // ReconPtr1 is Top left
  1204. FilterBlock2dBil_8 ( ReconPtr1, ReconRefPtr, PixelsPerLine, BilinearFilters[ModX], BilinearFilters[ModY] );
  1205. }
  1206. }