Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

537 lines
15 KiB

  1. /* *************************************************************************
  2. ** INTEL Corporation Proprietary Information
  3. **
  4. ** This listing is supplied under the terms of a license
  5. ** agreement with INTEL Corporation and may not be copied
  6. ** nor disclosed except in accordance with the terms of
  7. ** that agreement.
  8. **
  9. ** Copyright (c) 1995 Intel Corporation.
  10. ** All Rights Reserved.
  11. **
  12. ** *************************************************************************
  13. */
  14. ////////////////////////////////////////////////////////////////////////////
  15. // $Header: S:\h26x\src\dec\dxap.cpv 1.4 20 Oct 1996 13:22:12 AGUPTA2 $
  16. //
  17. // $Log: S:\h26x\src\dec\dxap.cpv $
  18. //
  19. // Rev 1.4 20 Oct 1996 13:22:12 AGUPTA2
  20. // Changed DBOUT into DbgLog. ASSERT is not changed to DbgAssert.
  21. //
  22. //
  23. // Rev 1.3 27 Aug 1996 11:20:06 KLILLEVO
  24. // changed GlobalAlloc/GLobalLock to HeapAlloc
  25. //
  26. // Rev 1.2 27 Dec 1995 14:36:10 RMCKENZX
  27. // Added copyright notice
  28. //
  29. // Rev 1.1 10 Nov 1995 14:45:02 CZHU
  30. //
  31. //
  32. // Rev 1.0 10 Nov 1995 13:54:28 CZHU
  33. // Initial revision.
  34. #include "precomp.h"
  35. #ifdef TRACK_ALLOCATIONS
  36. char gsz1[32];
  37. char gsz2[32];
  38. char gsz3[32];
  39. char gsz4[32];
  40. char gsz5[32];
  41. #endif
  42. U8 gUTable[256] =
  43. {
  44. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  45. 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  46. 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  47. 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  48. 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
  49. 34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,
  50. 40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
  51. 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
  52. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  53. 130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
  54. 136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
  55. 138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
  56. 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
  57. 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
  58. 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
  59. 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170
  60. };
  61. U8 gVTable[256]=
  62. {
  63. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  64. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  65. 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  66. 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  67. 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
  68. 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
  69. 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
  70. 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
  71. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  72. 65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
  73. 68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
  74. 69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
  75. 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
  76. 81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
  77. 84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
  78. 85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85
  79. };
  80. /***************************************************************************
  81. * ComputeDymanicClut() computes the clut tables on the fly, based on the *
  82. * current palette[]; *
  83. * called from InitColorConvertor, when CLUTAP is selected *
  84. ***************************************************************************/
  85. LRESULT ComputeDynamicClutNew(U8 *pAPTable,
  86. U8 *pActivePalette,
  87. int iPalSize)
  88. {
  89. /*
  90. * The dynamic clut consists of 4 entries which MUST be
  91. * contiguous in memory:
  92. *
  93. * ClutTable: 65536 1-byte entries
  94. * Each entry is the closest pPalette entry, as
  95. * indexed by a 14 bit value: uvuvuvuv0yyyyyyy,
  96. * dithered
  97. *
  98. * TableU: 256 4-byte entries
  99. * Each entry is u0u0u0u0:u0u0u0u0:u0u0u0u0:u0u0u0u0,
  100. * each uuuu is a 4 bit dithered u value for the
  101. * index, which is a u value in the range 8-120
  102. *
  103. * TableV: 256 4-byte entries
  104. * Same as TableU, except the values are arranged
  105. * 0v0v0v0v:0v0v0v0v:0v0v0v0v:0v0v0v0v.
  106. */
  107. Color *pPalette;
  108. U8 *pTmpPtr;
  109. U8 pYSlice[YSIZ][256], *pYYPtr;
  110. I32 *pYCnt;
  111. U32 *pDiff, *dptr, *delta, *deptr;
  112. I32 i,j,yseg,y,u,v,mini,yo,uo,vo,ycount,yi;
  113. U32 addr1,addr2,ind;
  114. U32 d,min; // since 3*128^2 = 49K
  115. PALETTEENTRY *lpPal, *palptr;
  116. Color *colptr;
  117. I32 Y, U, V;
  118. I32 U_0, U_1, U_2, U_3;
  119. I32 V_0, V_1, V_2, V_3;
  120. I32 Umag, Vmag;
  121. /* dist max is 128*128*3 = 49152 */
  122. U32 dist;
  123. U32 close_dist[MAG_NUM_NEAREST];
  124. I32 palindex;
  125. I32 R, G, B;
  126. I32 k, p, tmp, iu, iv;
  127. /* Ubias and Vbias max is (128 * 4 * BIAS_PAL_SAMPLES) = 65536 */
  128. /* even the worst palette (all black except the reserved colors) */
  129. /* would not achieve this. */
  130. I32 Ubias, Vbias;
  131. U32 Udither, Vdither;
  132. U32 *TableUptr, *TableVptr;
  133. FX_ENTRY("ComputeDynamicClutNew")
  134. DEBUGMSG(ZONE_DECODE_DETAILS, ("%s: ComputeDynamic CLUT8 index tables\r\n", _fx_));
  135. /* allocate some memory */
  136. pPalette = (Color *)HeapAlloc(GetProcessHeap(), NULL, sizeof(Color)*256);
  137. #ifdef TRACK_ALLOCATIONS
  138. // Track memory allocation
  139. wsprintf(gsz1, "DXAP: %7ld Ln %5ld\0", sizeof(Color)*256, __LINE__);
  140. AddName((unsigned int)pPalette, gsz1);
  141. #endif
  142. pYCnt = (I32 *) HeapAlloc(GetProcessHeap(), NULL, sizeof(I32) *YSIZ);
  143. #ifdef TRACK_ALLOCATIONS
  144. // Track memory allocation
  145. wsprintf(gsz2, "DXAP: %7ld Ln %5ld\0", sizeof(I32) *YSIZ, __LINE__);
  146. AddName((unsigned int)pYCnt, gsz2);
  147. #endif
  148. pDiff = (U32 *) HeapAlloc(GetProcessHeap(), NULL, sizeof(U32) *256);
  149. #ifdef TRACK_ALLOCATIONS
  150. // Track memory allocation
  151. wsprintf(gsz3, "DXAP: %7ld Ln %5ld\0", sizeof(U32) *256, __LINE__);
  152. AddName((unsigned int)pDiff, gsz3);
  153. #endif
  154. delta = (U32 *) HeapAlloc(GetProcessHeap(), NULL, sizeof(U32) *256);
  155. #ifdef TRACK_ALLOCATIONS
  156. // Track memory allocation
  157. wsprintf(gsz4, "DXAP: %7ld Ln %5ld\0", sizeof(U32) *256, __LINE__);
  158. AddName((unsigned int)delta, gsz4);
  159. #endif
  160. lpPal = (PALETTEENTRY *)HeapAlloc(GetProcessHeap(), NULL, sizeof(PALETTEENTRY)*256);
  161. #ifdef TRACK_ALLOCATIONS
  162. // Track memory allocation
  163. wsprintf(gsz5, "DXAP: %7ld Ln %5ld\0", sizeof(PALETTEENTRY)*256, __LINE__);
  164. AddName((unsigned int)lpPal, gsz5);
  165. #endif
  166. if (!pPalette || !pYCnt || !pDiff || !delta || !lpPal)
  167. return (ICERR_MEMORY);
  168. for (i=-256; i<256; i++)
  169. squares[256+i] = i*i;
  170. memcpy((U8 *)lpPal, pActivePalette, iPalSize);
  171. palptr = lpPal;
  172. colptr = pPalette;
  173. for (i = 0; i < 256; i++) {
  174. /* In BGR (RGBQuad) order. */
  175. B = palptr->peRed;
  176. G = palptr->peGreen;
  177. R = palptr->peBlue;
  178. colptr->y = YFROM(R, G, B);
  179. colptr->u = UFROM(R, G, B);
  180. colptr->v = VFROM(R, G, B);
  181. palptr++;
  182. colptr++;
  183. }
  184. for (i=0; i<YSIZ; i++)
  185. pYCnt[i] = 0;
  186. for (i=0; i<256; i++)
  187. {
  188. yseg = pPalette[i].y >> 4;
  189. pYSlice[yseg][ pYCnt[yseg]++ ] = (U8) i;
  190. }
  191. // Do exhaustive search on all U,V points and a coarse grid in Y
  192. for (u=0; u<256; u+=UVSTEP)
  193. {
  194. for (v=0; v<256; v+=UVSTEP)
  195. {
  196. ind = TBLIDX(0,u,v);
  197. pTmpPtr = pAPTable+ind;
  198. for (y=0; y<256; y+=YSTEP)
  199. {
  200. colptr = pPalette;
  201. min = 0x0FFFFFFF;
  202. for (i=0; i<NCOL; i++, colptr++)
  203. {
  204. d = (3*squares[256+y - colptr->y])>>1;
  205. if (d > min)
  206. continue;
  207. d += squares[256+u - colptr->u];
  208. if (d > min)
  209. continue;
  210. d += squares[256+v - colptr->v];
  211. if (d < min)
  212. {
  213. min = d;
  214. mini = i;
  215. }
  216. }
  217. *pTmpPtr = (U8) mini;
  218. pTmpPtr += YSTEP;
  219. }
  220. }
  221. }
  222. #ifdef STATISTICS
  223. #if defined USE_STAT_BOARD
  224. dwStopTime = ReadElapsed()>>2;
  225. #else
  226. dwStopTime = bentime();
  227. #endif /* USE_STAT_BOARD */
  228. dwElapsedTime = dwStopTime - dwStartTime2 - dwOverheadTime;
  229. DPF("CoarseSearch() time = %lu microseconds",dwElapsedTime);
  230. #endif
  231. // Go thru points not yet done, and search
  232. // (1) The closest point to the prev and next Y in coarse grid
  233. // (2) All the points in this Y slice
  234. //
  235. // Also, take advantage of the fact that we can do distance computation
  236. // incrementally. Keep all N errors in an array, and update each
  237. // time we change Y.
  238. for (u=0; u<256; u+=UVSTEP)
  239. {
  240. for (v=0; v<256; v+=UVSTEP)
  241. {
  242. for (y=YGAP; y<256; y+=YSTEP)
  243. {
  244. yseg = y >> 4;
  245. ycount = pYCnt[yseg] + 2; // +2 is 'cause we add 2 Y endpoints
  246. pYYPtr = (U8 *)pYSlice[yseg];
  247. addr1 = TBLIDX(yseg*16,u,v);
  248. pYYPtr[ycount-2] = *(U8 *)(pAPTable +addr1);
  249. addr2 = TBLIDX((yseg+(yseg < (YSIZ -1)))*16,u,v);
  250. pYYPtr[ycount-1] = *(U8 *)(pAPTable +addr2);
  251. dptr = pDiff;
  252. deptr = delta;
  253. for (i=0; i<ycount; i++, pYYPtr++, dptr++, deptr++)
  254. {
  255. j = *pYYPtr; /* pYSlice[yseg][i]; */
  256. colptr = pPalette+j;
  257. yo = colptr->y;
  258. uo = colptr->u;
  259. vo = colptr->v;
  260. *dptr = ( 3*squares[256+y-yo] + 2*(squares[256+u-uo] + squares[256+v-vo]));
  261. *deptr =( 3*(((y-yo)<<1) + 1));
  262. }
  263. ind = TBLIDX(y,u,v);
  264. pTmpPtr = pAPTable+ind;
  265. for (yi=0; yi<YSTEP-1; yi += YGAP)
  266. {
  267. min = 0x0FFFFFFF;
  268. pYYPtr = (U8 *)pYSlice[yseg];
  269. dptr = pDiff;
  270. deptr = delta;
  271. for (i=0; i<ycount; i++, pYYPtr++, dptr++, deptr++)
  272. {
  273. if (*dptr < min)
  274. {
  275. min = *dptr;
  276. mini = *pYYPtr; /* pYSlice[yseg][i]; */
  277. }
  278. *dptr += *deptr;
  279. *deptr += 6;
  280. }
  281. *pTmpPtr = (U8) mini;
  282. pTmpPtr++;
  283. }
  284. }
  285. }
  286. }
  287. /* now do U and V dither tables and shift lookup table*/
  288. /* NOTE: All Y, U, V values are 7 bits */
  289. Umag = Vmag = 0;
  290. Ubias = Vbias = 0;
  291. /* use srand(0) and rand() to generate a repeatable series of */
  292. /* pseudo-random numbers */
  293. srand((unsigned)1);
  294. for (p = 0; p < MAG_PAL_SAMPLES; ++p) // 32
  295. {
  296. for (i = 0; i < MAG_NUM_NEAREST; ++i) // 6
  297. {
  298. close_dist[i] = 0x7FFFL;
  299. }
  300. palindex = RANDOM(235) + 10; /* random palette index, unreserved colors */
  301. colptr = &pPalette[palindex];
  302. Y = colptr->y;
  303. U = colptr->u;
  304. V = colptr->v;
  305. colptr = pPalette;
  306. for (i = 0; i < 255; ++i)
  307. {
  308. if (i != palindex)
  309. {
  310. dist = squares[256+(Y - colptr->y)] +
  311. squares[256+(U - colptr->u)] +
  312. squares[256+(V - colptr->v)];
  313. /* keep a sorted list of the nearest MAG_NUM_NEAREST entries */
  314. for (j = 0; j < MAG_NUM_NEAREST; ++j) //6
  315. {
  316. if (dist < close_dist[j])
  317. {
  318. /* insert new entry; shift others down */
  319. for (k = (MAG_NUM_NEAREST-1); k > j; k--)
  320. {
  321. close_dist[k] = close_dist[k-1];
  322. }
  323. close_dist[j] = dist;
  324. break; /* out of for j loop */
  325. }
  326. } /* for j */
  327. } /* if i */
  328. ++colptr;
  329. } /* for i */
  330. /* now calculate Umag as the average of (U - U[1-6]) */
  331. /* calculate Vmag in the same way */
  332. for (i = 0; i < MAG_NUM_NEAREST; ++i)
  333. {
  334. /* there are (MAG_PAL_SAMPLES * MAG_NUM_NEAREST) sqrt() */
  335. /* calls in this method */
  336. Umag += (I32)sqrt((double)close_dist[i]);
  337. }
  338. } /* for p */
  339. Umag /= (MAG_NUM_NEAREST * MAG_PAL_SAMPLES);
  340. Vmag = Umag;
  341. for (p = 0; p < BIAS_PAL_SAMPLES; ++p) //132
  342. {
  343. /* now calculate the average bias (use random RGB points) */
  344. R = RANDOM(255);
  345. G = RANDOM(255);
  346. B = RANDOM(255);
  347. Y = YFROM(R, G, B);
  348. U = UFROM(R, G, B);
  349. V = VFROM(R, G, B);
  350. for (d = 0; d < 4; d++)
  351. {
  352. U_0 = U + (dither[d].Udither*Umag)/3;
  353. V_0 = V + (dither[d].Vdither*Vmag)/3;
  354. /* Clamp values */
  355. if (U_0 > 255) U_0 = 255;
  356. if (V_0 > 255) V_0 = 255;
  357. /* (Y, U_0, V_0) is the dithered YUV for the RGB point */
  358. /* colptr points to the closest palette entry to the dithered */
  359. /* RGB */
  360. /* colptr = &pPalette[pAPTable[TBLIDX(Y, U_0+(UVSTEP>>1), V_0+(UVSTEP>>1))]]; */
  361. pTmpPtr= (U8 *)(pAPTable + (U32)TBLIDX(Y, U_0, V_0)) ;
  362. palindex=*pTmpPtr;
  363. colptr = &pPalette[palindex];
  364. Ubias += (U - colptr->u);
  365. Vbias += (V - colptr->v);
  366. }
  367. } /* for p */
  368. Ubias =(I32) (Ubias+BIAS_PAL_SAMPLES*2)/(I32)(BIAS_PAL_SAMPLES * 4);
  369. Vbias =(I32) (Vbias+BIAS_PAL_SAMPLES*2)/(I32)(BIAS_PAL_SAMPLES * 4);
  370. U_0 = (2*(I32)Umag/3); V_0 = (1*(I32)Vmag/3);
  371. U_1 = (1*(I32)Umag/3); V_1 = (2*(I32)Vmag/3);
  372. U_2 = (0*(I32)Umag/3); V_2 = (3*(I32)Vmag/3);
  373. U_3 = (3*(I32)Umag/3); V_3 = (0*(I32)Vmag/3);
  374. TableUptr = (U32 *)(pAPTable+ (U32)65536L);
  375. TableVptr = TableUptr + 256;
  376. iu = Ubias /* + (UVSTEP>>1) */;
  377. iv = Vbias /* + (UVSTEP>>1) */;
  378. for (i = 0; i < 256; i++, iu++, iv++)
  379. {
  380. /* dither: u0u0u0u0, 0v0v0v0v */
  381. tmp = iu + U_0;
  382. Udither = gUTable[CLAMP8(tmp)];
  383. Udither <<= 8;
  384. tmp = iu + U_1;
  385. Udither |= gUTable[CLAMP8(tmp)]; Udither <<= 8; tmp = iu ;
  386. Udither |= gUTable[CLAMP8(tmp)]; Udither <<= 8; tmp = iu + U_3;
  387. Udither |= gUTable[CLAMP8(tmp)];
  388. *TableUptr++ = Udither ;
  389. tmp = iv + V_0;
  390. Vdither = gVTable[CLAMP8(tmp)];
  391. Vdither <<= 8;
  392. tmp = iv + V_1; Vdither |= gVTable[CLAMP8(tmp)]; Vdither <<= 8;
  393. tmp = iv + V_2; Vdither |= gVTable[CLAMP8(tmp)]; Vdither <<= 8;
  394. tmp = iv ; Vdither |= gVTable[CLAMP8(tmp)]; /* V_3 == 0 */
  395. *TableVptr++ = Vdither;
  396. }
  397. //adjust color for 0--8 and 120-128 for luma
  398. // 0--16, 241-255 plus dither for chroma
  399. TableUptr = (U32 *)(pAPTable+ (U32)65536L);
  400. TableVptr = TableUptr + 256;
  401. for (i=0; i<16;i++)
  402. {
  403. TableUptr[i]= TableUptr[16];
  404. TableVptr[i]= TableVptr[16];
  405. }
  406. for (i=241;i<256;i++)
  407. {
  408. TableUptr[i]= TableUptr[240];
  409. TableVptr[i]= TableVptr[240];
  410. }
  411. for (u = 0; u < 256; u += UVSTEP) {
  412. for (v = 0; v < 256; v += UVSTEP) {
  413. pTmpPtr= (U8 *)(pAPTable + (U32)TBLIDX(16, u, v)) ;
  414. mini = *pTmpPtr;
  415. for (y = Y_DITHER_MIN; y < 16; y += 2)
  416. {
  417. pTmpPtr--;
  418. *pTmpPtr = (U8)mini;
  419. }
  420. pTmpPtr= (U8 *)(pAPTable + (U32)TBLIDX(240, u, v)) ;
  421. mini = *pTmpPtr;
  422. for (y = 241; y < 256+Y_DITHER_MAX; y +=2)
  423. {
  424. pTmpPtr++;
  425. *pTmpPtr = (U8)mini;
  426. }
  427. } /* for v... */
  428. } /* for u... */
  429. /* free memory allocated */
  430. HeapFree(GetProcessHeap(), NULL, pPalette);
  431. #ifdef TRACK_ALLOCATIONS
  432. // Track memory allocation
  433. RemoveName((unsigned int)pPalette);
  434. #endif
  435. HeapFree(GetProcessHeap(), NULL, pYCnt);
  436. #ifdef TRACK_ALLOCATIONS
  437. // Track memory allocation
  438. RemoveName((unsigned int)pYCnt);
  439. #endif
  440. HeapFree(GetProcessHeap(), NULL, pDiff);
  441. #ifdef TRACK_ALLOCATIONS
  442. // Track memory allocation
  443. RemoveName((unsigned int)pDiff);
  444. #endif
  445. HeapFree(GetProcessHeap(), NULL, delta);
  446. #ifdef TRACK_ALLOCATIONS
  447. // Track memory allocation
  448. RemoveName((unsigned int)delta);
  449. #endif
  450. HeapFree(GetProcessHeap(), NULL, lpPal);
  451. #ifdef TRACK_ALLOCATIONS
  452. // Track memory allocation
  453. RemoveName((unsigned int)lpPal);
  454. #endif
  455. return (ICERR_OK);
  456. }