/* ************************************************************************* ** INTEL Corporation Proprietary Information ** ** This listing is supplied under the terms of a license ** agreement with INTEL Corporation and may not be copied ** nor disclosed except in accordance with the terms of ** that agreement. ** ** Copyright (c) 1995 Intel Corporation. ** All Rights Reserved. ** ** ************************************************************************* */ //////////////////////////////////////////////////////////////////////////// // $Header: S:\h26x\src\dec\dxap.cpv 1.4 20 Oct 1996 13:22:12 AGUPTA2 $ // // $Log: S:\h26x\src\dec\dxap.cpv $ // // Rev 1.4 20 Oct 1996 13:22:12 AGUPTA2 // Changed DBOUT into DbgLog. ASSERT is not changed to DbgAssert. // // // Rev 1.3 27 Aug 1996 11:20:06 KLILLEVO // changed GlobalAlloc/GLobalLock to HeapAlloc // // Rev 1.2 27 Dec 1995 14:36:10 RMCKENZX // Added copyright notice // // Rev 1.1 10 Nov 1995 14:45:02 CZHU // // // Rev 1.0 10 Nov 1995 13:54:28 CZHU // Initial revision. #include "precomp.h" #ifdef TRACK_ALLOCATIONS char gsz1[32]; char gsz2[32]; char gsz3[32]; char gsz4[32]; char gsz5[32]; #endif U8 gUTable[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34, 40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, 136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, 138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170 }; U8 gVTable[256]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, 68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, 69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, 81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, 84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, 85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85 }; /*************************************************************************** * ComputeDymanicClut() computes the clut tables on the fly, based on the * * current palette[]; * * called from InitColorConvertor, when CLUTAP is selected * ***************************************************************************/ LRESULT ComputeDynamicClutNew(U8 *pAPTable, U8 *pActivePalette, int iPalSize) { /* * The dynamic clut consists of 4 entries which MUST be * contiguous in memory: * * ClutTable: 65536 1-byte entries * Each entry is the closest pPalette entry, as * indexed by a 14 bit value: uvuvuvuv0yyyyyyy, * dithered * * TableU: 256 4-byte entries * Each entry is u0u0u0u0:u0u0u0u0:u0u0u0u0:u0u0u0u0, * each uuuu is a 4 bit dithered u value for the * index, which is a u value in the range 8-120 * * TableV: 256 4-byte entries * Same as TableU, except the values are arranged * 0v0v0v0v:0v0v0v0v:0v0v0v0v:0v0v0v0v. */ Color *pPalette; U8 *pTmpPtr; U8 pYSlice[YSIZ][256], *pYYPtr; I32 *pYCnt; U32 *pDiff, *dptr, *delta, *deptr; I32 i,j,yseg,y,u,v,mini,yo,uo,vo,ycount,yi; U32 addr1,addr2,ind; U32 d,min; // since 3*128^2 = 49K PALETTEENTRY *lpPal, *palptr; Color *colptr; I32 Y, U, V; I32 U_0, U_1, U_2, U_3; I32 V_0, V_1, V_2, V_3; I32 Umag, Vmag; /* dist max is 128*128*3 = 49152 */ U32 dist; U32 close_dist[MAG_NUM_NEAREST]; I32 palindex; I32 R, G, B; I32 k, p, tmp, iu, iv; /* Ubias and Vbias max is (128 * 4 * BIAS_PAL_SAMPLES) = 65536 */ /* even the worst palette (all black except the reserved colors) */ /* would not achieve this. */ I32 Ubias, Vbias; U32 Udither, Vdither; U32 *TableUptr, *TableVptr; FX_ENTRY("ComputeDynamicClutNew") DEBUGMSG(ZONE_DECODE_DETAILS, ("%s: ComputeDynamic CLUT8 index tables\r\n", _fx_)); /* allocate some memory */ pPalette = (Color *)HeapAlloc(GetProcessHeap(), NULL, sizeof(Color)*256); #ifdef TRACK_ALLOCATIONS // Track memory allocation wsprintf(gsz1, "DXAP: %7ld Ln %5ld\0", sizeof(Color)*256, __LINE__); AddName((unsigned int)pPalette, gsz1); #endif pYCnt = (I32 *) HeapAlloc(GetProcessHeap(), NULL, sizeof(I32) *YSIZ); #ifdef TRACK_ALLOCATIONS // Track memory allocation wsprintf(gsz2, "DXAP: %7ld Ln %5ld\0", sizeof(I32) *YSIZ, __LINE__); AddName((unsigned int)pYCnt, gsz2); #endif pDiff = (U32 *) HeapAlloc(GetProcessHeap(), NULL, sizeof(U32) *256); #ifdef TRACK_ALLOCATIONS // Track memory allocation wsprintf(gsz3, "DXAP: %7ld Ln %5ld\0", sizeof(U32) *256, __LINE__); AddName((unsigned int)pDiff, gsz3); #endif delta = (U32 *) HeapAlloc(GetProcessHeap(), NULL, sizeof(U32) *256); #ifdef TRACK_ALLOCATIONS // Track memory allocation wsprintf(gsz4, "DXAP: %7ld Ln %5ld\0", sizeof(U32) *256, __LINE__); AddName((unsigned int)delta, gsz4); #endif lpPal = (PALETTEENTRY *)HeapAlloc(GetProcessHeap(), NULL, sizeof(PALETTEENTRY)*256); #ifdef TRACK_ALLOCATIONS // Track memory allocation wsprintf(gsz5, "DXAP: %7ld Ln %5ld\0", sizeof(PALETTEENTRY)*256, __LINE__); AddName((unsigned int)lpPal, gsz5); #endif if (!pPalette || !pYCnt || !pDiff || !delta || !lpPal) return (ICERR_MEMORY); for (i=-256; i<256; i++) squares[256+i] = i*i; memcpy((U8 *)lpPal, pActivePalette, iPalSize); palptr = lpPal; colptr = pPalette; for (i = 0; i < 256; i++) { /* In BGR (RGBQuad) order. */ B = palptr->peRed; G = palptr->peGreen; R = palptr->peBlue; colptr->y = YFROM(R, G, B); colptr->u = UFROM(R, G, B); colptr->v = VFROM(R, G, B); palptr++; colptr++; } for (i=0; i> 4; pYSlice[yseg][ pYCnt[yseg]++ ] = (U8) i; } // Do exhaustive search on all U,V points and a coarse grid in Y for (u=0; u<256; u+=UVSTEP) { for (v=0; v<256; v+=UVSTEP) { ind = TBLIDX(0,u,v); pTmpPtr = pAPTable+ind; for (y=0; y<256; y+=YSTEP) { colptr = pPalette; min = 0x0FFFFFFF; for (i=0; iy])>>1; if (d > min) continue; d += squares[256+u - colptr->u]; if (d > min) continue; d += squares[256+v - colptr->v]; if (d < min) { min = d; mini = i; } } *pTmpPtr = (U8) mini; pTmpPtr += YSTEP; } } } #ifdef STATISTICS #if defined USE_STAT_BOARD dwStopTime = ReadElapsed()>>2; #else dwStopTime = bentime(); #endif /* USE_STAT_BOARD */ dwElapsedTime = dwStopTime - dwStartTime2 - dwOverheadTime; DPF("CoarseSearch() time = %lu microseconds",dwElapsedTime); #endif // Go thru points not yet done, and search // (1) The closest point to the prev and next Y in coarse grid // (2) All the points in this Y slice // // Also, take advantage of the fact that we can do distance computation // incrementally. Keep all N errors in an array, and update each // time we change Y. for (u=0; u<256; u+=UVSTEP) { for (v=0; v<256; v+=UVSTEP) { for (y=YGAP; y<256; y+=YSTEP) { yseg = y >> 4; ycount = pYCnt[yseg] + 2; // +2 is 'cause we add 2 Y endpoints pYYPtr = (U8 *)pYSlice[yseg]; addr1 = TBLIDX(yseg*16,u,v); pYYPtr[ycount-2] = *(U8 *)(pAPTable +addr1); addr2 = TBLIDX((yseg+(yseg < (YSIZ -1)))*16,u,v); pYYPtr[ycount-1] = *(U8 *)(pAPTable +addr2); dptr = pDiff; deptr = delta; for (i=0; iy; uo = colptr->u; vo = colptr->v; *dptr = ( 3*squares[256+y-yo] + 2*(squares[256+u-uo] + squares[256+v-vo])); *deptr =( 3*(((y-yo)<<1) + 1)); } ind = TBLIDX(y,u,v); pTmpPtr = pAPTable+ind; for (yi=0; yiy; U = colptr->u; V = colptr->v; colptr = pPalette; for (i = 0; i < 255; ++i) { if (i != palindex) { dist = squares[256+(Y - colptr->y)] + squares[256+(U - colptr->u)] + squares[256+(V - colptr->v)]; /* keep a sorted list of the nearest MAG_NUM_NEAREST entries */ for (j = 0; j < MAG_NUM_NEAREST; ++j) //6 { if (dist < close_dist[j]) { /* insert new entry; shift others down */ for (k = (MAG_NUM_NEAREST-1); k > j; k--) { close_dist[k] = close_dist[k-1]; } close_dist[j] = dist; break; /* out of for j loop */ } } /* for j */ } /* if i */ ++colptr; } /* for i */ /* now calculate Umag as the average of (U - U[1-6]) */ /* calculate Vmag in the same way */ for (i = 0; i < MAG_NUM_NEAREST; ++i) { /* there are (MAG_PAL_SAMPLES * MAG_NUM_NEAREST) sqrt() */ /* calls in this method */ Umag += (I32)sqrt((double)close_dist[i]); } } /* for p */ Umag /= (MAG_NUM_NEAREST * MAG_PAL_SAMPLES); Vmag = Umag; for (p = 0; p < BIAS_PAL_SAMPLES; ++p) //132 { /* now calculate the average bias (use random RGB points) */ R = RANDOM(255); G = RANDOM(255); B = RANDOM(255); Y = YFROM(R, G, B); U = UFROM(R, G, B); V = VFROM(R, G, B); for (d = 0; d < 4; d++) { U_0 = U + (dither[d].Udither*Umag)/3; V_0 = V + (dither[d].Vdither*Vmag)/3; /* Clamp values */ if (U_0 > 255) U_0 = 255; if (V_0 > 255) V_0 = 255; /* (Y, U_0, V_0) is the dithered YUV for the RGB point */ /* colptr points to the closest palette entry to the dithered */ /* RGB */ /* colptr = &pPalette[pAPTable[TBLIDX(Y, U_0+(UVSTEP>>1), V_0+(UVSTEP>>1))]]; */ pTmpPtr= (U8 *)(pAPTable + (U32)TBLIDX(Y, U_0, V_0)) ; palindex=*pTmpPtr; colptr = &pPalette[palindex]; Ubias += (U - colptr->u); Vbias += (V - colptr->v); } } /* for p */ Ubias =(I32) (Ubias+BIAS_PAL_SAMPLES*2)/(I32)(BIAS_PAL_SAMPLES * 4); Vbias =(I32) (Vbias+BIAS_PAL_SAMPLES*2)/(I32)(BIAS_PAL_SAMPLES * 4); U_0 = (2*(I32)Umag/3); V_0 = (1*(I32)Vmag/3); U_1 = (1*(I32)Umag/3); V_1 = (2*(I32)Vmag/3); U_2 = (0*(I32)Umag/3); V_2 = (3*(I32)Vmag/3); U_3 = (3*(I32)Umag/3); V_3 = (0*(I32)Vmag/3); TableUptr = (U32 *)(pAPTable+ (U32)65536L); TableVptr = TableUptr + 256; iu = Ubias /* + (UVSTEP>>1) */; iv = Vbias /* + (UVSTEP>>1) */; for (i = 0; i < 256; i++, iu++, iv++) { /* dither: u0u0u0u0, 0v0v0v0v */ tmp = iu + U_0; Udither = gUTable[CLAMP8(tmp)]; Udither <<= 8; tmp = iu + U_1; Udither |= gUTable[CLAMP8(tmp)]; Udither <<= 8; tmp = iu ; Udither |= gUTable[CLAMP8(tmp)]; Udither <<= 8; tmp = iu + U_3; Udither |= gUTable[CLAMP8(tmp)]; *TableUptr++ = Udither ; tmp = iv + V_0; Vdither = gVTable[CLAMP8(tmp)]; Vdither <<= 8; tmp = iv + V_1; Vdither |= gVTable[CLAMP8(tmp)]; Vdither <<= 8; tmp = iv + V_2; Vdither |= gVTable[CLAMP8(tmp)]; Vdither <<= 8; tmp = iv ; Vdither |= gVTable[CLAMP8(tmp)]; /* V_3 == 0 */ *TableVptr++ = Vdither; } //adjust color for 0--8 and 120-128 for luma // 0--16, 241-255 plus dither for chroma TableUptr = (U32 *)(pAPTable+ (U32)65536L); TableVptr = TableUptr + 256; for (i=0; i<16;i++) { TableUptr[i]= TableUptr[16]; TableVptr[i]= TableVptr[16]; } for (i=241;i<256;i++) { TableUptr[i]= TableUptr[240]; TableVptr[i]= TableVptr[240]; } for (u = 0; u < 256; u += UVSTEP) { for (v = 0; v < 256; v += UVSTEP) { pTmpPtr= (U8 *)(pAPTable + (U32)TBLIDX(16, u, v)) ; mini = *pTmpPtr; for (y = Y_DITHER_MIN; y < 16; y += 2) { pTmpPtr--; *pTmpPtr = (U8)mini; } pTmpPtr= (U8 *)(pAPTable + (U32)TBLIDX(240, u, v)) ; mini = *pTmpPtr; for (y = 241; y < 256+Y_DITHER_MAX; y +=2) { pTmpPtr++; *pTmpPtr = (U8)mini; } } /* for v... */ } /* for u... */ /* free memory allocated */ HeapFree(GetProcessHeap(), NULL, pPalette); #ifdef TRACK_ALLOCATIONS // Track memory allocation RemoveName((unsigned int)pPalette); #endif HeapFree(GetProcessHeap(), NULL, pYCnt); #ifdef TRACK_ALLOCATIONS // Track memory allocation RemoveName((unsigned int)pYCnt); #endif HeapFree(GetProcessHeap(), NULL, pDiff); #ifdef TRACK_ALLOCATIONS // Track memory allocation RemoveName((unsigned int)pDiff); #endif HeapFree(GetProcessHeap(), NULL, delta); #ifdef TRACK_ALLOCATIONS // Track memory allocation RemoveName((unsigned int)delta); #endif HeapFree(GetProcessHeap(), NULL, lpPal); #ifdef TRACK_ALLOCATIONS // Track memory allocation RemoveName((unsigned int)lpPal); #endif return (ICERR_OK); }