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
537 lines
15 KiB
/* *************************************************************************
|
|
** 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<YSIZ; i++)
|
|
pYCnt[i] = 0;
|
|
|
|
for (i=0; i<256; i++)
|
|
{
|
|
yseg = pPalette[i].y >> 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; i<NCOL; i++, colptr++)
|
|
{
|
|
d = (3*squares[256+y - colptr->y])>>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; i<ycount; i++, pYYPtr++, dptr++, deptr++)
|
|
{
|
|
j = *pYYPtr; /* pYSlice[yseg][i]; */
|
|
colptr = pPalette+j;
|
|
yo = colptr->y;
|
|
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; yi<YSTEP-1; yi += YGAP)
|
|
{
|
|
min = 0x0FFFFFFF;
|
|
pYYPtr = (U8 *)pYSlice[yseg];
|
|
dptr = pDiff;
|
|
deptr = delta;
|
|
for (i=0; i<ycount; i++, pYYPtr++, dptr++, deptr++)
|
|
{
|
|
if (*dptr < min)
|
|
{
|
|
min = *dptr;
|
|
mini = *pYYPtr; /* pYSlice[yseg][i]; */
|
|
}
|
|
*dptr += *deptr;
|
|
*deptr += 6;
|
|
}
|
|
*pTmpPtr = (U8) mini;
|
|
pTmpPtr++;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* now do U and V dither tables and shift lookup table*/
|
|
/* NOTE: All Y, U, V values are 7 bits */
|
|
|
|
Umag = Vmag = 0;
|
|
Ubias = Vbias = 0;
|
|
|
|
/* use srand(0) and rand() to generate a repeatable series of */
|
|
/* pseudo-random numbers */
|
|
srand((unsigned)1);
|
|
|
|
for (p = 0; p < MAG_PAL_SAMPLES; ++p) // 32
|
|
{
|
|
for (i = 0; i < MAG_NUM_NEAREST; ++i) // 6
|
|
{
|
|
close_dist[i] = 0x7FFFL;
|
|
}
|
|
|
|
palindex = RANDOM(235) + 10; /* random palette index, unreserved colors */
|
|
colptr = &pPalette[palindex];
|
|
Y = colptr->y;
|
|
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);
|
|
|
|
}
|