#include "SCENE.h" //#define BACK_DEBUG_INFO_TEXT void SET_BORDER(MAP *MapSRC,s32 Size,s32 Value); void OR(MAP *MapSRC,MAP *MapDST); void MAP16_Neg(MAP16 *MapSRC); u32 MAP_2_MAP16_RGBA(MAP *MapSRC,MAP16 *MapDST,u32 RGBA ); //#pragma optimize("",off) typedef struct SolverS_ { union { struct { s16 InitValue; s16 SolvedValue; }; u32 RGBA; }; } SolverS; #define VIBE_THRESH 3500 static s32 BLUADDDENOISE = 1; static s32 BLUADDDENOISE_SUMM = -32; u32 SOLVE_Thresj = 8; static Vector BigGain = Vector(1,1,1); static float AlphaGain = 1; static float NoiseMesure = 1; void TRK_AE_ComputeBackgroundParrams(s32 FactorBlur, s32 FactorBlurSumm) { BLUADDDENOISE = FactorBlur; BLUADDDENOISE_SUMM = FactorBlurSumm; } /* This function will back-compute the camera gain. */ void BACK_ComputeGain(MAP *pFIX,MAP *pCUR,MAP16 *pALpha) { s32 *pFIXBASE = pFIX->GetBase(); s32 *pCURBASE = pCUR->GetBase(); s16 *pALphaBASE = pALpha->GetBase(); Vector BigCoefB = Vector(0,0,0); Vector BigCoefF = Vector(0,0,0); u32 Number; Number = 0; for (int X = 4 ; X < pFIX->SX - 4; X++) for (int Y = 4 ; Y < pFIX->SY - 4; Y++) { { if (pALphaBASE[X + Y * pALpha->PITCH] < 16) { BigCoefB.x += (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0]; BigCoefB.y += (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1]; BigCoefB.z += (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2]; BigCoefF.x += (float)((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[0]; BigCoefF.y += (float)((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[1]; BigCoefF.z += (float)((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[2]; Number++; } } } AlphaGain = 1; if (Number > 4000) { BigGain = Vector(BigCoefF.x / BigCoefB.x ,BigCoefF.y / BigCoefB.y ,BigCoefF.z / BigCoefB.z ); AlphaGain = (BigGain.y * 2 + BigGain.x + BigGain.z)/4.0f; } else BigGain = Vector(1,1,1); } /* This test function will*/ #define SILHOUETE_THRESHOLD 240 //#define SILHOUETE_THRESHOLD_BORDER 220 void BACK_ComputeBack(MAP *pFIX,MAP *pCUR,MAP16 *pALphaFronteer,MAP16 *pALpha) { s32 *pFIXBASE = pFIX->GetBase(); s32 *pCURBASE = pCUR->GetBase(); s16 *pALphaBASE = pALpha->GetBase(); s16 *pALphaFronteerBASE = pALphaFronteer->GetBase(); for (int X = 4 ; X < pFIX->SX - 4; X++) for (int Y = 4 ; Y < pFIX->SY - 4; Y++) { if ((pALphaFronteerBASE[X + Y * pALpha->PITCH] & (8)) ) { float R = ((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[0] / BigGain.x; float G = ((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[1] / BigGain.y; float B = ((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[2] / BigGain.z; float A = (((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[3]) / (AlphaGain * AlphaGain); if (R > 255 ) R = 255; if (G > 255 ) G = 255; if (B > 255 ) B = 255; if (A > 255 ) A = 255; ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0] = R; ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1] = G; ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2] = B; ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[3] = A; } else { /* float R = ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0] * BigGain.x; float G = ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1] * BigGain.y; float B = ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2] * BigGain.z; float A = ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[3] * AlphaGain; if (R > 255 ) R = 255; if (G > 255 ) G = 255; if (B > 255 ) B = 255; if (A > 255 ) A = 255; ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0] = 0.25f * R + 0.75f * (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0]; ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1] = 0.25f * G + 0.75f * (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1]; ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2] = 0.25f * B + 0.75f * (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2]; ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[3] = 0.25f * A + 0.75f * (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[3];*/ } } } /* */ void COPY_O2_RGBA_ENERGY(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC,*SRC2; SET(MapDST,0); DST = MapDST->GetBase() + MapDST->PITCH; SRC = MapSRC->GetBase() + MapSRC->PITCH; for (u32 SizeY = 1; SizeY < MapDST->SY ;SizeY ++) { LAST = DST + MapDST->SX; SRC2 = SRC + MapSRC->PITCH; while (DST < LAST) { u32 A,B; A = ((*(SRC) & 0xfefefefe)>>1) + ((*(SRC + 1) & 0xfefefefe)>>1); B = ((*(SRC2) & 0xfefefefe)>>1) + ((*(SRC2 + 1) & 0xfefefefe)>>1); A &= 0xffffff; B &= 0xffffff; float R1,R2,R3,R4,AvSqr,SqrAv,EQ; R1 = (*(SRC) & 0xff00)>>8; R2 = (*(SRC2) & 0xff00)>>8; R3 = (*(SRC+1) & 0xff00)>>8; R4 = (*(SRC2+1) & 0xff00)>>8; AvSqr = (R1*R1 + R2*R2 + R3*R3 + R4*R4) / 4.0f; SqrAv = (R1 + R2 + R3 + R4)/4.0f; SqrAv *= SqrAv; EQ = sqrtf(AvSqr - SqrAv) * 2; R1 = (*(SRC) & 0xff0000)>>16; R2 = (*(SRC2) & 0xff0000)>>16; R3 = (*(SRC+1) & 0xff0000)>>16; R4 = (*(SRC2+1) & 0xff0000)>>16; AvSqr = (R1*R1 + R2*R2 + R3*R3 + R4*R4) / 4.0f; SqrAv = (R1 + R2 + R3 + R4)/4.0f; SqrAv *= SqrAv; EQ += sqrtf(AvSqr - SqrAv); R1 = (*(SRC) & 0xff)>>0; R2 = (*(SRC2) & 0xff)>>0; R3 = (*(SRC+1) & 0xff)>>0; R4 = (*(SRC2+1) & 0xff)>>0; AvSqr = (R1*R1 + R2*R2 + R3*R3 + R4*R4) / 4.0f; SqrAv = (R1 + R2 + R3 + R4)/4.0f; SqrAv *= SqrAv; EQ += sqrtf(AvSqr - SqrAv); EQ /= 4; if (EQ > 255) EQ = 255; *(DST) = ((A & 0xfefefe)>>1) + ((B & 0xfefefe)>>1);; //EQ = 0; *DST |= (s32)(((u32)EQ)<<24); DST++; SRC += 2; SRC2 += 2; } SRC+=(MapSRC->PITCH-MapSRC->SX); SRC+= MapSRC->PITCH; DST+=MapDST->PITCH-MapDST->SX; } } s32 SolverRGBDistance(s32 *A,s32 *B) { //return 0; float Re = (float)(((u8*)A)[0]) - (float)(((u8*)B)[0]); float Gr = (float)(((u8*)A)[1]) - (float)(((u8*)B)[1]); float Bl = (float)(((u8*)A)[2]) - (float)(((u8*)B)[2]); float Del = (Re*Re+ Gr*Gr + Bl*Bl) - 16; if (Del < 0) Del = 0; Del *= 4; float Res = (1<SolvedValue)>>SOLVE_Thresj) ; \ if (SolverMode & 2) {\ T2 = ((SolverRGBDistance((int*)&BaseRGB,&PixelRGB[a + b * Pitch]) * Pixel->SolvedValue)>>SOLVE_Thresj) * DistanceFactor;\ if (T2 > T1) T1 = T2;\ }\ if (T1 > 1 << SOLVE_Thresj) T1 = 1 << SOLVE_Thresj;\ if (T1 < 0) T1 = 0;\ if (T1 > Pixel[a + b * Pitch].SolvedValue)\ {\ Pixel[a + b * Pitch].SolvedValue = T1;\ StackPos++;\ RecurseBackgroundSolver(&Pixel[a + b * Pitch],&PixelRGB[a + b * Pitch],*PixelRGB,Pitch);\ StackPos--;\ }\ }\ SolverDX -= a ; SolverDY -= b;\ } static u32 SolverMode = 1; static u32 StackPos = 0; static int SolverDX = 0; static int SolverDY = 0; void RecurseBackgroundSolver(SolverS *Pixel,s32 *PixelRGB,u32 BaseRGB,s32 Pitch) { //if (StackPos > 20) return; float DistanceLL = (SolverDX * SolverDX + SolverDY * SolverDY); float DistanceFactor = (5.0f - sqrtf(DistanceLL)) / 2.0f; if (DistanceFactor > 1.0f) DistanceFactor = 1.0f; if (DistanceFactor < 0.0f) return; if (*PixelRGB) { PARSE_SOLVE(0,-1); PARSE_SOLVE(1,0); PARSE_SOLVE(-1,0); PARSE_SOLVE(0,1); /* PARSE_SOLVE(1,+Pitch); PARSE_SOLVE(1,-Pitch); PARSE_SOLVE(-1,+Pitch); PARSE_SOLVE(-1,-Pitch);*/ } } s32 L_Limit; s32 AverageV = 0; s32 AverageN = 0; u32 gRED = 0; #define DEPMAX 20 void RecurseEdgesSolver(s32 *Pixel,s32 Pitch) { if (gRED > DEPMAX) return; AverageV += *Pixel>>2; AverageN ++; if (*Pixel & 3) return; gRED++; *Pixel |= 1; #define EDGE_PARSE_SOLVE(a,b) \ if (Pixel[a + b * Pitch] > L_Limit)\ {\ RecurseEdgesSolver(&Pixel[a + b * Pitch],Pitch);\ } EDGE_PARSE_SOLVE(0,-1); EDGE_PARSE_SOLVE(1,0); EDGE_PARSE_SOLVE(-1,0); EDGE_PARSE_SOLVE(0,1); gRED--; } void RecurseEdgesSolverClose(s32 *Pixel,s32 Pitch) { if (gRED > DEPMAX) return; *Pixel &= ~1; if (*Pixel & 2) return; gRED++; *Pixel |= 2; #define EDGE_PARSE_CLOSE(a,b) \ if (Pixel[a + b * Pitch] & 1)\ {\ RecurseEdgesSolverClose(&Pixel[a + b * Pitch],Pitch);\ } EDGE_PARSE_CLOSE(0,-1); EDGE_PARSE_CLOSE(1,0); EDGE_PARSE_CLOSE(-1,0); EDGE_PARSE_CLOSE(0,1); gRED--; } s32 PitchUsed; s32 StackSize = 0; u32 ReturnValueHoleSolver = 0; SolverS *CurrentPixel; void RecurseBackgroundHoleSolver() { //if (StackSize > 4000) return; StackSize++; { #define PARSE_SOLVE_HOLE(a,b) \ CurrentPixel += a + b * PitchUsed;\ if (SolverMode == 1) {\ if (CurrentPixel->SolvedValue == 1) \ {\ CurrentPixel->SolvedValue = 2; \ RecurseBackgroundHoleSolver(); \ }\ }\ if (SolverMode == 2) {\ if (CurrentPixel->SolvedValue == 2) \ {\ CurrentPixel->SolvedValue = 3; \ RecurseBackgroundHoleSolver(); \ }\ }\ CurrentPixel -= a + b * PitchUsed; PARSE_SOLVE_HOLE(0,-1); PARSE_SOLVE_HOLE(1,0); PARSE_SOLVE_HOLE(-1,0); PARSE_SOLVE_HOLE(0,1); } StackSize--; ReturnValueHoleSolver ++; } u32 RecurseConstantSilhouettteSolver(s16 *Pixel,s32 Pitch,u32 ANDValue,u32 OrValue,u32 TEST) { u32 Ret = 0; if (*Pixel & TEST) { *Pixel &= ~TEST; #define PARSE_SOLVE_SILHOUETTE(a,b) \ if (Pixel[a + b * Pitch] & 2) Ret ++; \ if ((Pixel[a + b * Pitch] & TEST)) \ {\ Ret += RecurseConstantSilhouettteSolver(&Pixel[a + b * Pitch],Pitch,ANDValue,OrValue,TEST); \ } PARSE_SOLVE_SILHOUETTE(0,-1); PARSE_SOLVE_SILHOUETTE(1,0); PARSE_SOLVE_SILHOUETTE(-1,0); PARSE_SOLVE_SILHOUETTE(0,1); *Pixel &= ANDValue; *Pixel |= OrValue; } return Ret; } u32 CompuSetBackGroundErnergy(MAP *CurrentMap,MAP *ZMap,s32 Mode) { static MAP16 WorkingMap; static u32 WorkingBufSize = 0; static u32 LearningTime = 0; //return 0; u32 REs = 0; u8 TransTable[256]; u8 TransTable2[256]; //return; MAP16 M1,M2,LEARNINGFRONTEER,M7,M8,NoiseMap; MAP RGBCUR,RGBFIX,RGBLOCAL; if (CurrentMap->SX * CurrentMap->SY == 0) return 0; /**************** Init working maps **************/ if (WorkingBufSize < CurrentMap->SX * CurrentMap->SY) { WorkingMap.SetSize(CurrentMap->SX*2, CurrentMap->SY*3, 1); } if (Mode == 0) memset(WorkingMap.GetBase(),0,WorkingBufSize * 6 * 2); M1.SX = CurrentMap->SX; M1.SY = CurrentMap->SY; M1.PITCH = CurrentMap->SX; NoiseMap = M7= M8 = M2 = LEARNINGFRONTEER = M1; M1.SetBase(WorkingMap.GetBase()); M2.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY); LEARNINGFRONTEER.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 2); M7.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 3); M8.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 4); NoiseMap.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 5); RGBFIX = *CurrentMap; RGBFIX.staticBase = 1; RGBFIX.SX >>= 1; RGBFIX.PITCH >>= 1; RGBFIX.SY >>= 1; RGBCUR = RGBFIX; RGBFIX.SetBase((s32*)M7.GetBase()); RGBCUR.SetBase((s32*)M8.GetBase()); MAP O2; O2 = *CurrentMap; O2.staticBase = 1; O2.SX >>= 1; O2.SY >>= 1; O2.PITCH = RGBCUR.PITCH; O2.SetBase(RGBCUR.GetBase()); COPY_O2_RGBA(CurrentMap,&O2); BACK_ComputeGain(&RGBFIX,&O2,&M2); COPY(&O2,&RGBCUR); RGBLOCAL = RGBCUR; RGBLOCAL.SetBase((s32*)M1.GetBase()); LEARNINGFRONTEER.SX >>= 1; LEARNINGFRONTEER.SY >>= 1; //MAP16_BLUR_Inplace(&M1,1,1); // MAP16_Denoise_FAST(&M2,&M1); //MAP16_Copy(&M2,&M1); s32 *RGBLOCALBASE = RGBLOCAL.GetBase(); s32 *RGBFIXBASE = RGBFIX.GetBase(); s32 *RGBCURBASE = RGBCUR.GetBase(); s16 *M1BASE = M1.GetBase(); s16 *M2BASE = M2.GetBase(); s32 *O2BASE = O2.GetBase(); s16 *LFBASE = LEARNINGFRONTEER.GetBase(); s16 *NoiseBASE = NoiseMap.GetBase(); s32 *ZMapBASE = NULL; if (ZMap) ZMapBASE = ZMap->GetBase(); if (Mode < 15) { MAP16_Set(&NoiseMap,0); MAP16_Set(&LEARNINGFRONTEER,0); /* Learning mode */ SOLVE_Thresj = 9; LearningTime = 0; COPY(&RGBCUR,&RGBFIX); BigGain = Vector(1,1,1); } else { SET_BORDER(&RGBFIX,4,0); M2.SX = RGBCUR.SX; M2.SY = RGBCUR.SY; Vector BigGainF = BigGain; Vector BigGainB = Vector(1.0f / BigGain.x,1.0f / BigGain.y,1.0f / BigGain.z); Vector MAXVec = Vector(1,1,1); float AlphaGainF = AlphaGain; float AlphaGainB = 1.0f / AlphaGain; BigGainB.Max(MAXVec); BigGainF.Max(MAXVec); if (AlphaGainF < 1.0f) AlphaGainF = 1.0f; if (AlphaGainB < 1.0f) AlphaGainB = 1.0f; for (int Y = 1 ; Y < RGBCUR.SY -1; Y++) for (int X = 1 ; X < RGBCUR.SX -1; X++) { /* RGBDISTANCE */ float RF = (float)((u8 *)&RGBFIXBASE[(X) + (Y) * RGBFIX.PITCH])[0] * BigGainF.x; float GF = (float)((u8 *)&RGBFIXBASE[(X) + (Y) * RGBFIX.PITCH])[1] * BigGainF.y; float BF = (float)((u8 *)&RGBFIXBASE[(X) + (Y) * RGBFIX.PITCH])[2] * BigGainF.z; float AF = (float)((u8 *)&RGBFIXBASE[(X) + (Y) * RGBFIX.PITCH])[3] * AlphaGainF; float RC = (float)((u8 *)&RGBCURBASE[(X) + (Y) * RGBCUR.PITCH])[0] * BigGainB.x; float GC = (float)((u8 *)&RGBCURBASE[(X) + (Y) * RGBCUR.PITCH])[1] * BigGainB.y; float BC = (float)((u8 *)&RGBCURBASE[(X) + (Y) * RGBCUR.PITCH])[2] * BigGainB.z; float AC = (float)((u8 *)&RGBCURBASE[(X) + (Y) * RGBCUR.PITCH])[3] * AlphaGainB; if (RF > 255.0f) {RF = 255.f;AF /= 2.f;AC /= 2.0f;}; if (GF > 255.0f) {GF = 255.f;AF /= 2.f;AC /= 2.0f;}; if (BF > 255.0f) {BF = 255.f;AF /= 2.f;AC /= 2.0f;}; if (AF > 255.0f) AF = 255.f; if (RC > 255.0f) {RC = 255.f;AF /= 2.f;AC /= 2.0f;}; if (GC > 255.0f) {GC = 255.f;AF /= 2.f;AC /= 2.0f;}; if (BC > 255.0f) {BC = 255.f;AF /= 2.f;AC /= 2.0f;}; if (AC > 255.0f) AC = 255.f; float Distance = 3.0/4.0f*0.925f * ((RF - RC) * (RF - RC) + (GF - GC) * (GF - GC) + (GF - GC) * (GF - GC) + (BF - BC) * (BF - BC) ) + (AF - AC) * (AF - AC) * 1; float GL = (RF + GF + GF + BF) * 0.25f; //Distance = ((Distance * GL / 255.0f)*3 + Distance)/4.f; //float Distance = (AF - AC) * (AF - AC) * 8 ; if (ZMap) { if (((u32 *)ZMapBASE)[X*2 + Y*2 * ZMap->PITCH] == 1) Distance = 1; else if (ZMapBASE[X*2 + Y*2 * ZMap->PITCH]) Distance = 1000000000.0f; } /* if ((X == 80) && (Y==60)) Distance = 1000000000.0f; else Distance = 0.0f;*/ ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue = M2BASE[X + Y * M2.PITCH] = 0; if (Distance > 0) { Distance = ((Distance - 1) /1.5f); if (Distance > 1<InitValue = M2BASE[X + Y * M2.PITCH] = Distance; } } if (BLUADDDENOISE) { SET_BORDER16(&M2 ,4,0); MAP16_Add(&M2,BLUADDDENOISE_SUMM); MAP16_OnlyAbs(&M2); MAP16_BLUR_Inplace(&M2 , 1, BLUADDDENOISE); } /*M1.SX >>= 1; M1.SY >>= 1; M1.PITCH >>= 1; MAP16_Denoise_FAST(&M2,&M1); MAP16_Copy(&M1,&M2); M1.SX <<= 1; M1.SY <<= 1; M1.PITCH <<= 1; /*MAP16_Add(&M2,-128); MAP16_Shift(&M2,1);//*/ //MAP16_BLUR_Inplace(&M2 , 1 , 1); SET_BORDER16(&M2 ,4,0); for (int Y = 1 ; Y < RGBLOCAL.SY -1; Y++) for (int X = 1 ; X < RGBLOCAL.SX -1; X++) { if (M2BASE[X + Y * M2.PITCH] > ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue) ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue = M2BASE[X + Y * M2.PITCH]; ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = 0; } /* Then Recurse Parse */ //COPY(&RGBLOCAL,&RGBCUR); SET_BORDER(&RGBLOCAL,4,0); SET_BORDER(&RGBCUR,4,0); //for (int zK = 0 ; zK < 80 ; zK++) for (int Y = 2 ; Y < RGBCUR.SY -2; Y++) for (int X = 2 ; X < RGBCUR.SX -2; X++) { if (((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue >= (1<<(SOLVE_Thresj)) - (1<<(SOLVE_Thresj>>2))) { ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue; } } for (int Y = 2 ; Y < RGBCUR.SY -2; Y++) for (int X = 2 ; X < RGBCUR.SX -2; X++) { if (((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue) { u32 BaseRGB = RGBCURBASE[X + Y * RGBLOCAL.PITCH]; SolverMode = 1; RecurseBackgroundSolver( (SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH], (s32*)&RGBCURBASE[X + Y * RGBCUR.PITCH], BaseRGB,RGBLOCAL.PITCH); } } for (int Y = 2 ; Y < RGBCUR.SY -2; Y++) for (int X = 2 ; X < RGBCUR.SX -2; X++) { ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue; ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = 0; M2BASE[X + Y * M2.PITCH] = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue; } /*************************************************************************************/ /* Color continuity SOLVER */ /*************************************************************************************/ if (1) { // color similarity detection MAP16_BLUR_Inplace(&M2 , 1 , 3); for (int Y = 2 ; Y < RGBCUR.SY -2; Y++) for (int X = 2 ; X < RGBCUR.SX -2; X++) { if (M2BASE[X + Y * M2.PITCH] >= (1<<(SOLVE_Thresj))/* - (1<<(SOLVE_Thresj-4))*/) { // Recurse Call Solver ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue; } } for (int Y = 2 ; Y < RGBCUR.SY -2; Y++) for (int X = 2 ; X < RGBCUR.SX -2; X++) { if (M2BASE[X + Y * M2.PITCH] >= (1<<(SOLVE_Thresj)) - (1<<(SOLVE_Thresj-4))) { // Recurse Call Solver ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue; u32 BaseRGB = RGBCURBASE[X + Y * RGBLOCAL.PITCH]; SolverMode = 2; RecurseBackgroundSolver( (SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH], (s32*)&RGBCURBASE[X + Y * RGBCUR.PITCH], BaseRGB,RGBLOCAL.PITCH); } } } COPY(&RGBLOCAL,&RGBCUR); /*************************************************************************************/ /* HOLES SOLVER */ /*************************************************************************************/ if (1) { /* recurse Destroy small Holes (front and back)*/ for(u32 HoleMode = 0 ; HoleMode < 2 ; HoleMode++ ) { // HoleMode == 0 -> Erase Front, // HoleMode == 1 -> Erase Back, SET_BORDER(&RGBCUR,4,0); for (int Y = 0 ; Y < RGBCUR.SY ; Y++) for (int X = 0 ; X < RGBCUR.SX ; X++) ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 0; for (int Y = 2 ; Y < RGBCUR.SY - 2 ; Y++) for (int X = 2 ; X < RGBCUR.SX - 2 ; X++) if (HoleMode == 1) { if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue > 32) (( SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 1; } else { if ((((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue >= 0) && ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue < (1<<(SOLVE_Thresj-1))) (( SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 1; } SET_BORDER(&RGBCUR,4,0); PitchUsed = RGBCUR.PITCH; for (int Y = 2 ; Y < RGBCUR.SY -2; Y++) for (int X = 2 ; X < RGBCUR.SX -2; X++) { /* Recurse compute pixel size */ SolverMode = 1; if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue == 1) { ReturnValueHoleSolver = 0; CurrentPixel = (SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH]; RecurseBackgroundHoleSolver(); if (ReturnValueHoleSolver < 128) { SolverMode = 2; CurrentPixel = (SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH]; RecurseBackgroundHoleSolver(); } } } for (int Y = 0 ; Y < RGBCUR.SY ; Y++) for (int X = 0 ; X < RGBCUR.SX ; X++) { if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue == 3) { if (HoleMode == 0) ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue = 255; else ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue = 0; } ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue; if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue > 256) ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 256; if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue < 0) ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 0; M2BASE[X + Y * M2.PITCH] = RGBCURBASE[X + Y * RGBCUR.PITCH] = ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue; } } } /* Testing Mode */ /*************************************************************************************/ /* BORDER SOLVER */ /*************************************************************************************/ if (1) { /* Detect fronteers */ for (int Y = 0 ; Y < RGBCUR.SY ; Y++) for (int X = 0 ; X < RGBCUR.SX ; X++) { if ((RGBCURBASE[X + Y * RGBCUR.PITCH] < 128)) { M2BASE[X + Y * M2.PITCH] = 256; } else M2BASE[X + Y * M2.PITCH] = 0; } MAP16_BLUR_Inplace(&M2,1,1); for (int Y = 0 ; Y < RGBCUR.SY ; Y++) for (int X = 0 ; X < RGBCUR.SX ; X++) { LFBASE[X + Y * LEARNINGFRONTEER.PITCH] >>= 5; LFBASE[X + Y * LEARNINGFRONTEER.PITCH]-=LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>6; if ((M2BASE[X + Y * M2.PITCH] < 256 - 0) && (M2BASE[X + Y * M2.PITCH] > 0)) LFBASE[X + Y * LEARNINGFRONTEER.PITCH]+=256>>6; else LFBASE[X + Y * LEARNINGFRONTEER.PITCH]-=LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>0; LFBASE[X + Y * LEARNINGFRONTEER.PITCH] <<= 5; if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>5 >= SILHOUETE_THRESHOLD) LFBASE[X + Y * LEARNINGFRONTEER.PITCH] |= 16; else { if (M2BASE[X + Y * M2.PITCH] < 128) LFBASE[X + Y * LEARNINGFRONTEER.PITCH] |= 1; else LFBASE[X + Y * LEARNINGFRONTEER.PITCH] |= 2; } if (M2BASE[X + Y * M2.PITCH] & 0xff) { RGBCURBASE[X + Y * RGBCUR.PITCH]-=M2BASE[X + Y * M2.PITCH]; } M2BASE[X + Y * M2.PITCH] = RGBCURBASE[X + Y * RGBCUR.PITCH] ; } /* Recursive "filling" of shapes wiht constant contour */ SET_BORDER16(&LEARNINGFRONTEER , 2 , 0); for (int Y = 1 ; Y < LEARNINGFRONTEER.SY-1 ; Y++) for (int X = 1 ; X < LEARNINGFRONTEER.SX-1 ; X++) { if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH] & 1) { if (RecurseConstantSilhouettteSolver(&LFBASE[X + Y * LEARNINGFRONTEER.PITCH],LEARNINGFRONTEER.PITCH,0xffffffff,4,1) == 0) RecurseConstantSilhouettteSolver(&LFBASE[X + Y * LEARNINGFRONTEER.PITCH],LEARNINGFRONTEER.PITCH,0xffffffff,8,4+16); } } /* for (int Y = 0 ; Y < LEARNINGFRONTEER.SY ; Y++) for (int X = 0 ; X < LEARNINGFRONTEER.SX ; X++) { if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH] & 8) { LFBASE[X + Y * LEARNINGFRONTEER.PITCH] = SILHOUETE_THRESHOLD<<4; } }*/ } /* Kill Noise; */ static u32 RRR = 1; if (RRR) for (int Y = 2 ; Y < NoiseMap.SY-2 ; Y++) for (int X = 2 ; X < NoiseMap.SX-2 ; X++) { u32 LastWas1 = NoiseBASE[X + Y * NoiseMap.PITCH]&1; NoiseBASE[X + Y * NoiseMap.PITCH] -= NoiseBASE[X + Y * NoiseMap.PITCH]>>3; NoiseBASE[X + Y * NoiseMap.PITCH] &= ~1; if (M2BASE[X + Y * M2.PITCH] > 128) { if (!LastWas1) NoiseBASE[X + Y * NoiseMap.PITCH] += 1024; { NoiseBASE[X + Y * NoiseMap.PITCH] += 1; } } else { if (LastWas1) { NoiseBASE[X + Y * NoiseMap.PITCH] += 1024; } } if (NoiseBASE[X + Y * NoiseMap.PITCH] > VIBE_THRESH) { REs++; M2BASE[X + Y * M2.PITCH] = 0; } } /* finishing */ #define _PITCH M1.PITCH for (int Y = 0 ; Y < M1.SY ; Y++) for (int X = 0 ; X < M1.SX ; X++) { /* RGBDISTANCE */ if (X & 1) { M1BASE[X + Y * M1.PITCH] = ( M2BASE[(X>>1) + (Y>>1) * M2.PITCH] + M2BASE[(X>>1) + 1 + (Y>>1) * M2.PITCH])>>1; } else M1BASE[X + Y * M1.PITCH] = M2BASE[(X>>1) + (Y>>1) * M2.PITCH]; if (Y & 1) { if (X & 1) { M1BASE[X + Y * M1.PITCH] += ( M2BASE[(X>>1) + ((Y>>1)+1) * M2.PITCH] + M2BASE[(X>>1) + 1 + ((Y>>1)+1) * M2.PITCH])>>1; } else M1BASE[X + Y * M1.PITCH] += M2BASE[(X>>1) + ((Y>>1)+1) * M2.PITCH]; M1BASE[X + Y * M1.PITCH]>>=1; } /*if (M1BASE[X + Y * M1.PITCH] < 128) M1BASE[X + Y * M1.PITCH] = 0; else M1BASE[X + Y * M1.PITCH] = 255;*/ if (M1BASE[X + Y * M1.PITCH] < 0) M1BASE[X + Y * M1.PITCH] = 0; if (M1BASE[X + Y * M1.PITCH] > 255) { M1BASE[X + Y * M1.PITCH] = 255; } } } /* Compute Noise Mesure NoiseMesure*/ MAP16_2_MAP(&M1,CurrentMap,24); /* *********************************************************************************************** */ /* LEARNING BACKGROUND */ /* *********************************************************************************************** */ if (0) { COPY_O2_RGBA_ENERGY(CurrentMap,&O2); BACK_ComputeBack(&RGBFIX,&O2,&LEARNINGFRONTEER,&M2); /* DEBUG RESULT SHOW*/ #ifdef BACK_DEBUG_INFO COPY(&RGBFIX,&O2); for (int X = 4 ; X < O2.SX - 4; X++) for (int Y = 4 ; Y < O2.SY - 4; Y++) { if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH] & 8) { O2BASE[X + Y * O2.PITCH] = 0xff0000; } /* if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH] & 2) { O2BASE[X + Y * O2.PITCH] = 0xff00; }*/ if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>5 > SILHOUETE_THRESHOLD>>1) O2BASE[X + Y * O2.PITCH] = 0xff00; else if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>5) { O2BASE[X + Y * O2.PITCH] = 0xff; //LFBASE[X + Y * LEARNINGFRONTEER.PITCH] = 0; }//*/ O2BASE[X + Y * O2.PITCH] |= 0xff000000; } COPY(&O2,CurrentMap); #endif } /* COPY(&RGBFIX,&O2); for (int X = 4 ; X < O2.SX - 4; X++) for (int Y = 4 ; Y < O2.SY - 4; Y++) { s16 Value = M2BASE[X + Y * M2.PITCH]; if (Value > 255) Value = 255; O2BASE[X + Y * O2.PITCH] = 0; if (Value > 128) { Value -= 128; Value <<= 1; O2BASE[X + Y * O2.PITCH] += Value<<8; O2BASE[X + Y * O2.PITCH] += Value<<16; O2BASE[X + Y * O2.PITCH] ^= 0xff00; } else { Value <<= 1; O2BASE[X + Y * O2.PITCH] += Value<<8; O2BASE[X + Y * O2.PITCH] += Value<<0; O2BASE[X + Y * O2.PITCH] ^= 0xff; } O2BASE[X + Y * O2.PITCH] |= 0xff000000; } COPY(&O2,CurrentMap); //*/ #ifdef BACK_DEBUG_INFO_TEXT char DEDEDE[1024]; sprintf(DEDEDE,"%d",REs); DRawTEXT_Soft_B((u8*)DEDEDE,(u32*)CurrentMap->GetBase(),16, 32, CurrentMap->PITCH, CurrentMap->SY, 0xff00f0f0); #endif LearningTime++; if (LearningTime < 30) { if ((LearningTime > 15) && ((LearningTime & 3) == 0)&& (REs > 80) && (SOLVE_Thresj < 12)) { SOLVE_Thresj++; } return 512; } else return 0; }