#include "windows.h" #include "CCMap.h" #include "stdio.h" #include "math.h" #include "xmmintrin.h" #include "stdlib.h" //#include // <= for bmpheader u32 PEEKCOLOR(float Sx,float Sy , MAP *MapSRC) { u32 R,G,B,A,P1,FX,FY; float SaveX,SaveY; if ((s32)Sx >= MapSRC->SX) Sx = (s32)MapSRC->SX -1; if ((s32)Sy >= MapSRC->SY) Sy = (s32)MapSRC->SY -1; FX = (s32)(Sx * 256.0f) & 0xff; FY = (s32)(Sy * 256.0f) & 0xff; P1 = ((256 - FX) * (256 - FY))>>8; R = P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 24) & 0xff); G = P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 16) & 0xff); B = P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 8) & 0xff); A = P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 0) & 0xff); SaveX = Sx; SaveY = Sy; Sx += 1.0f; if ((s32)Sx >= MapSRC->SX) Sx = (s32)MapSRC->SX -1; if ((s32)Sy >= MapSRC->SY) Sy = (s32)MapSRC->SY -1; P1 = ((FX) * (256 - FY))>>8; R += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 24) & 0xff); G += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 16) & 0xff); B += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 8) & 0xff); A += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 0) & 0xff); Sx = SaveX; Sy = SaveY; SaveX = Sx; SaveY = Sy; Sx += 1.0f; Sy += 1.0f; if ((s32)Sx >= MapSRC->SX) Sx = MapSRC->SX -1; if ((s32)Sy >= MapSRC->SY) Sy = MapSRC->SY -1; P1 = ((FX) * (FY))>>8; R += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 24) & 0xff); G += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 16) & 0xff); B += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 8) & 0xff); A += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 0) & 0xff); Sx = SaveX; Sy = SaveY; SaveX = Sx; SaveY = Sy; Sy += 1.0f; if ((s32)Sx >= MapSRC->SX) Sx = MapSRC->SX -1; if ((s32)Sy >= MapSRC->SY) Sy = MapSRC->SY -1; P1 = ((256-FX) * (FY))>>8; R += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 24) & 0xff); G += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 16) & 0xff); B += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 8) & 0xff); A += P1 * ((((u32)*(MapSRC->GetBase() + (s32)Sx + ((s32)Sy) * MapSRC->PITCH)) >> 0) & 0xff); Sx = SaveX; Sy = SaveY; R >>= 8; G >>= 8; B >>= 8; A >>= 8; return (R<<24) | (G<<16) | (B<<8) | (A<<0); } void COPY_RESAMPLE(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC,*SRC2,PosY,LastPosY; DST = MapDST->GetBase(); for (u32 CY = 0 ; CY < MapDST->SY ; CY ++) { for (u32 CX = 0 ; CX < MapDST->SX ; CX ++ , DST ++ ) { float Sx,Sy; Sx = ((float)CX / (float)MapDST->SX) * MapSRC->SX; Sy = ((float)CY / (float)MapDST->SY) * MapSRC->SY; *DST = PEEKCOLOR(Sx,Sy , MapSRC); } DST += MapDST->PITCH - MapDST->SX; } } void DrawLine(MAP *MapDST,float X1,float Y1,float X2,float Y2,u32 Color) { s32 DX,DY,Inc,Inc2,Counter; s32 ADY,IThresh,ITCurrent,ITAdd; s32 *B0,Pitch; if (X1 < (s32)0) X1 = (s32)0; if (Y1 < (s32)0) Y1 = (s32)0; if (X1 > (s32)MapDST->SX-1) X1 = (s32)MapDST->SX-1; if (Y1 > (s32)MapDST->SY-1) Y1 = (s32)MapDST->SY-1; if (X2 < (s32)0) X2 = (s32)0; if (Y2 < (s32)0) Y2 = (s32)0; if (X2 > (s32)MapDST->SX-1) X2 = MapDST->SX-1; if (Y2 > (s32)MapDST->SY-1) Y2 = MapDST->SY-1; if (X2 < X1) { /* Swap */ DX = X1; X1 = X2; X2 = DX; DY = Y1; Y1 = Y2; Y2 = DY; } #define SRC_COLOR_OPERATION(Color) ((Color & 0x00f8f8f8) >>= 3) B0 = MapDST->GetBase(); Pitch = MapDST->PITCH; B0 += (s32)Y1 * Pitch + (s32)X1; if ((Color & 0x80000000) == 0x80000000) { Color &= 0x00f8f8f8; Color >>= 3; Color |= 0x80000000; } else Color &= 0xffffff; DX = X2 - X1; DY = Y2 - Y1; if (DX == 0) { if (Color & 0xff000000) { if (DY < 0) {DY = -DY;DY++;while (DY--) *(B0 - DY * Pitch) = Color + ((*(B0 - DY * Pitch) & 0xfcfcfcfc)>>2) + ((*(B0 - DY * Pitch) & 0xfefefefe)>>1) + ((*(B0 - DY * Pitch) & 0xf8f8f8f8)>>3); } else { DY++; while (DY--) *(B0 + DY * Pitch) = Color + ((*(B0 + DY * Pitch) & 0xfcfcfcfc)>>2) + ((*(B0 + DY * Pitch) & 0xfefefefe)>>1) + ((*(B0 + DY * Pitch) & 0xf8f8f8f8)>>3); } return; } else if (DY < 0) {DY = -DY;DY++;while (DY--) *(B0 - DY * Pitch) = Color; } else { DY++; while (DY--) *(B0 + DY * Pitch) = Color; } return; } if (DY == 0) { if (Color & 0xff000000) { DX++; while (DX--) *B0++ = Color + ((*B0 & 0xfefefefe)>>1) + ((*B0 & 0xfcfcfcfc)>>2) + ((*B0 & 0xf8f8f8f8)>>3); return; } else { DX++; while (DX--) *B0++ = Color; return; } } ADY = abs(DY); Inc2 = DY > 0 ? Pitch : -Pitch; if (ADY > DX) {Inc = Inc2;Inc2 = 1;IThresh = ADY;ITAdd = DX;} else {Inc = 1;IThresh = DX;ITAdd = ADY; }; ITCurrent = 0; if (ADY > DX) Counter = ADY; else Counter = DX; if (Color & 0xff000000) { Counter++; while (Counter--) { *B0 = Color + ((*B0 & 0xf8f8f8f8)>>3) + ((*B0 & 0xfcfcfcfc)>>2) + ((*B0 & 0xfefefefe)>>1); ITCurrent += ITAdd; if (IThresh <= ITCurrent) {B0 += Inc2;ITCurrent -= IThresh;} B0 += Inc; } } else { Counter++; while (Counter--) { *B0 = Color; ITCurrent += ITAdd; if (IThresh <= ITCurrent) {B0 += Inc2;ITCurrent -= IThresh;} B0 += Inc; } } } void DrawLine_Clip(MAP *MapDST,float X1,float Y1,float X2,float Y2,u32 Color) { if ((X1 > (s32)MapDST->SX) && (X2 > (s32)MapDST->SX)) return; if ((Y1 > (s32)MapDST->SY) && (Y2 > (s32)MapDST->SY)) return; if ((X1 < 0) && (X2 < 0)) return; if ((Y1 < 0) && (Y2 < 0)) return; if ((X1 == X2) && (Y1 == Y2)) return; for (u32 Counter = 0 ; Counter < 8 ; Counter++) { if (X1 < 0) { Y1 = ((float)Y1 + (float)(Y2 - Y1) * (float)X1 / (float)(X1 - X2)); X1 = 0; } if (X2 < 0) { Y2 = ((float)Y2 + (float)(Y1 - Y2) * (float)X2 / (float)(X2 - X1)); X2 = 0; } #define SWAP(a,b) {float SWP;SWP = a;a = b ; b = SWP; }; switch (Counter) { case 0:break; case 1:X1 = MapDST->SX - X1;X2 = MapDST->SX - X2;break; case 2:X1 = MapDST->SX - X1;X2 = MapDST->SX - X2;SWAP(X1,Y1);SWAP(X2,Y2);break; case 3:X1 = MapDST->SY - X1;X2 = MapDST->SY - X2;break; case 4:X1 = MapDST->SY - X1;X2 = MapDST->SY - X2;SWAP(X1,Y1);SWAP(X2,Y2);Counter = 80000;break; } } DrawLine(MapDST,X1,Y1,X2,Y2,Color); } void DrawQuad(MAP *MapDST,s32 X1,s32 Y1,s32 X2,s32 Y2,u32 Color,u32 Ep) { while (Ep--) { DrawLine(MapDST,X1,Y1,X2,Y1,Color); DrawLine(MapDST,X2,Y1,X2,Y2,Color); DrawLine(MapDST,X1,Y2,X2,Y2,Color); DrawLine(MapDST,X1,Y1,X1,Y2,Color); X1++;X2--;Y1++;Y2--; } } void DrawQuadFull(MAP *MapDST,s32 X1,s32 Y1,s32 X2,s32 Y2,u32 Color) { s32 *Base,XC; if (Y1 > Y2) { s32 SWP; SWP = Y1; Y1 = Y2; Y2 = SWP; } if (X1 > X2) { s32 SWP; SWP = X1; X1 = X2; X2 = SWP; } if (X1 < 0) X1 = 0; if (Y1 < 0) Y1 = 0; if (X2 < 0) X2 = 0; if (Y2 < 0) Y2 = 0; if (X1 >= (s32)MapDST->SX) X1 = (s32)MapDST->SX-1; if (Y1 >= (s32)MapDST->SY) Y1 = (s32)MapDST->SY-1; if (X2 >= (s32)MapDST->SX) X2 = (s32)MapDST->SX-1; if (Y2 >= (s32)MapDST->SY) Y2 = (s32)MapDST->SY-1; if (X1 == X2) return; if (Y1 == Y2) return; Base = MapDST->GetBase() + X1 + Y1 * MapDST->PITCH; X2 -= X1; while (Y1 < Y2) { XC = X2; while (XC --) *(Base++) = Color; Base -= X2; Base += MapDST->PITCH; Y1++; } } void DrawPointFull(MAP *MapDST,s32 X1,s32 Y1,u32 Size,u32 Color) { Size>>=1; DrawQuadFull(MapDST,X1-Size,Y1-Size,X1+Size,Y1+Size,Color); } void MIX(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*DST2,*SRC,*SRCLAST,*SRCBASE,*DSTBASE; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++) { u32 Current; LAST = DST + MapSRC->SX; SRCBASE = SRC; DSTBASE = DST; SRCLAST = SRC + MapSRC->SX; Current = 0; for (;(DST < LAST) && (*DST == 0);DST++,SRC++) {}; for (DST2 = LAST;(*(DST2) == 0)&&(DST2>DST);) {DST2--;}; for (;DST < DST2;DST++,SRC++) *DST = *SRC; DST = LAST; SRC= SRCBASE + MapSRC->PITCH; DST= DSTBASE + MapDST->PITCH; } } void COPY(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; s32 SX,SY; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); SX = MapDST->SX < MapSRC->SX ? MapDST->SX : MapSRC->SX; SY = MapDST->SY < MapSRC->SY ? MapDST->SY : MapSRC->SY; LAST = DST + SY*MapDST->PITCH; s32 copySize = sizeof(*SRC)*SX; while (DST < LAST) { memcpy(DST, SRC, copySize); DST += MapDST->PITCH; SRC += MapSRC->PITCH; } } // Original copy by philippe void _COPY(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; s32 SX,SY; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); SX = MapDST->SX < MapSRC->SX ? MapDST->SX : MapSRC->SX; SY = MapDST->SY < MapSRC->SY ? MapDST->SY : MapSRC->SY; for (u32 SizeY = 0; SizeY < SY;SizeY ++) { u32 Current; LAST = DST + (SX & ~3); Current = 0; while (DST < LAST) { *(DST++) = *(SRC++); *(DST++) = *(SRC++); *(DST++) = *(SRC++); *(DST++) = *(SRC++); _mm_prefetch((char*)(SRC + (128)),_MM_HINT_NTA); _mm_prefetch((char*)(DST + (128)),_MM_HINT_NTA);//*/ } LAST += SX & 3; while (DST < LAST) { *(DST++) = *(SRC++); } SRC+=MapSRC->PITCH-SX; DST+=MapDST->PITCH-SX; } } void SWAPMAP(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++) { u32 Current; LAST = DST + (MapSRC->SX & ~3); Current = 0; while (DST < LAST) { s32 SWAPs; SWAPs = *(DST); *(DST++) = *(SRC); *(SRC++) = SWAPs; SWAPs = *(DST); *(DST++) = *(SRC); *(SRC++) = SWAPs; SWAPs = *(DST); *(DST++) = *(SRC); *(SRC++) = SWAPs; SWAPs = *(DST); *(DST++) = *(SRC); *(SRC++) = SWAPs; _mm_prefetch((char*)(SRC + (128)),_MM_HINT_NTA); _mm_prefetch((char*)(DST + (128)),_MM_HINT_NTA);//*/ } LAST += MapSRC->SX & 3; while (DST < LAST) { s32 SWAPs; SWAPs = *(DST); *(DST++) = *(SRC); *(SRC++) = SWAPs; } SRC+=MapSRC->PITCH-MapSRC->SX; DST+=MapDST->PITCH-MapSRC->SX; } } void ORb(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 2; SizeY < MapSRC->SY - 2;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + 2; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 2; LAST = SRC + MapSRC->SX - 2 * 2; while (SRC < LAST) { *DST = *(SRC+1); *DST |= *(SRC-1); *DST |= *(SRC+MapSRC->PITCH); *DST |= *(SRC-MapSRC->PITCH); *DST &= ~0x10000; *DST |= *SRC; SRC++; DST++; } } } void SET(MAP *MapDST,s32 Value) { s32 *LAST,*DST; DST = MapDST->GetBase(); for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { u32 Current; LAST = DST + MapDST->SX; Current = 0; while (DST < LAST) { *(DST++) = Value; } DST+=MapDST->PITCH-MapDST->SX; } } void DARKER(MAP *MapDST) { s32 *LAST,*DST; DST = MapDST->GetBase(); for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { u32 Current; LAST = DST + MapDST->SX; Current = 0; while (DST < LAST) { *(DST++) = (*(DST) & 0xfefefefe)>>1; *(DST++) = (*(DST) & 0xfefefefe)>>1; *(DST++) = (*(DST) & 0xfefefefe)>>1; *(DST++) = (*(DST) & 0xfefefefe)>>1; } DST+=MapDST->PITCH-MapDST->SX; } } void COPY_O2_II(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC,*SRC2; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { LAST = DST + MapDST->SX; SRC2 = SRC + MapSRC->PITCH; while (DST < LAST) { *(DST++) = (*(SRC) + *(SRC + 1) + *(SRC2) + *(SRC2 + 1))>>(2+2); // +2 -> II SRC += 2; SRC2 += 2; } *(DST) = *(DST-1); SRC+=(MapSRC->PITCH-MapSRC->SX); SRC+= MapSRC->PITCH; DST+=MapDST->PITCH-MapDST->SX; } LAST = DST + MapDST->SX; while (DST < LAST) { *(DST) = *(DST-MapDST->PITCH); DST++; } *(DST) = *(DST-1); } /* void FLIP_H(MAP *MapDST) { s32 *LAST,*DST,*DST2; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; DST2 = DST + MapDST->SX - 1; while (DST < DST2) { s32 SWAP; SWAP = *(DST); *(DST) = *(DST2); *(DST2) = SWAP; DST++; DST2--; } } } void FLIP_V(MAP *MapDST) { s32 *LAST,*DST,*DST2; for (u32 SizeY = 0; SizeY < MapDST->SY>>1;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; DST2 = MapDST->GetBase() + (MapDST->SY - SizeY - 1) * MapDST->PITCH; while (DST < LAST) { s32 SWAP; SWAP = *(DST); *(DST) = *(DST2); *(DST2) = SWAP; DST++; DST2++; } } } */ s32 GET_AVERAGE(MAP *MapDST) { s32 *LAST,*DST,Average; Average = 0; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; for (;DST < LAST;) Average += *(DST++); } float RealA; RealA = (float)Average / ((float)MapDST->SY*(float)MapDST->SX); return (s32)RealA; } void ADD_VALUE(MAP *MapDST,s32 Value) { s32 *LAST,*DST; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; while (DST < LAST) *(DST++) += Value; } } u32 LocFAST_ABS(s32 K) { if (K > 0) return K; else return -K; } void ABS(MAP *MapDST) { s32 *LAST,*DST; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; while (DST < LAST) { /* if (*(DST) < 0) *(DST) = -(*(DST)); DST++;*/ *(DST++) = LocFAST_ABS(*(DST)); } } } void NEG(MAP *MapDST) { s32 *LAST,*DST; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; for (;DST < LAST;) *(DST++) = -(*(DST)); } } void SQR(MAP *MapDST) { s32 *LAST,*DST; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; for (;DST < LAST;) *(DST++) = (*(DST)**(DST)); } } void WAVELET_0(MAP *MapDST) { s32 *LAST,*DST,*DST2; /* XYaxis */ DST2 = DST = MapDST->GetBase(); for (u32 SizeY = 0; SizeY < MapDST->SY>>1;SizeY ++) { DST =MapDST->GetBase() + MapDST->PITCH*SizeY; DST2 =MapDST->GetBase() + MapDST->PITCH*(SizeY*2); LAST = DST2 + MapDST->SX; for (;DST2 < LAST;) { s32 Aver; #if 0 Aver = (*(DST2)+*(DST2+1+MapDST->PITCH)); Aver -= (*(DST2+1)+*(DST2+MapDST->PITCH)); *(DST) = Aver>>0; #else Aver = (*(DST2)+*(DST2+1+MapDST->PITCH)); Aver += (*(DST2+1)+*(DST2+MapDST->PITCH));//*/ *(DST) = Aver>>2; #endif DST2 += 2; //*(DST) >>= 2; DST ++; } DST2 =MapDST->GetBase() + MapDST->PITCH*SizeY; LAST = DST2 + MapDST->SX; for (;DST2 < LAST;) { *(DST) = (*(DST2)+/**(DST2)+*(DST2+1)+*/*(DST2+1))>>1; // *(DST) -= *(DST)>>2; DST2 +=2; DST ++; } } /* Yaxis */ DST2 = MapDST->GetBase(); DST = MapDST->GetBase() + (MapDST->SY>>1) * MapDST->PITCH; for (u32 SizeY = 0; SizeY < MapDST->SY>>1;SizeY ++) { LAST = DST + MapDST->SX; for (;DST < LAST;) { s32 Aver; Aver = (*(DST2)+/**(DST2)+*(DST2+MapDST->PITCH)+*/*(DST2+MapDST->PITCH))>>1; //Aver -= Aver>>2; *DST = Aver; DST2++; DST++; } DST+=MapDST->PITCH-MapDST->SX; DST2+=MapDST->PITCH-MapDST->SX; DST2+=MapDST->PITCH; } } void COMPRESS_H2(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; /* XYaxis */ for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST =MapDST->GetBase() + MapDST->PITCH*SizeY; SRC =MapSRC->GetBase() + MapSRC->PITCH*SizeY; LAST = DST + (MapDST->SX & ~1); *(DST) = (*(SRC) + *(SRC+1))>>(1); DST++; SRC+=2; for (;DST < LAST;) { *(DST) = (*(SRC) + /**(SRC) + *(SRC-1) + */*(SRC+1))>>(1); SRC += 2; DST ++; } } } void COMPRESS_V2(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST =MapDST->GetBase(); SRC =MapSRC->GetBase(); LAST = DST + MapDST->SX; for (;DST < LAST;) { *(DST) = (*(SRC) + *(SRC+MapSRC->PITCH))>>(1); SRC ++; DST ++; } for (u32 SizeY = 1; SizeY < (MapDST->SY&~1);SizeY ++) { DST =MapDST->GetBase() + MapDST->PITCH*SizeY; SRC =MapSRC->GetBase() + MapSRC->PITCH*(SizeY*2); LAST = DST + MapDST->SX; for (;DST < LAST;) { *(DST) = (*(SRC) + /**(SRC) + *(SRC-MapSRC->PITCH) + */*(SRC+MapSRC->PITCH))>>(1); SRC ++; DST ++; } } } #define K0Est 1 void DIFF_V2(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST =MapDST->GetBase(); SRC =MapSRC->GetBase(); LAST = DST + MapDST->SX; for (;DST < LAST;) { *(DST) = (*(SRC) - *(SRC+MapSRC->PITCH))>>(1-K0Est); SRC ++; DST ++; } for (u32 SizeY = 1; SizeY < (MapDST->SY&~1);SizeY ++) { DST =MapDST->GetBase() + MapDST->PITCH*SizeY; SRC =MapSRC->GetBase() + MapSRC->PITCH*(SizeY*2); LAST = DST + MapDST->SX; for (;DST < LAST;) { *(DST) = (*(SRC) + *(SRC) - *(SRC+MapSRC->PITCH) - *(SRC-MapSRC->PITCH))>>(2-K0Est); SRC ++; DST ++; } } } void DIFF_H2(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; /* XYaxis */ for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST =MapDST->GetBase() + MapDST->PITCH*SizeY; SRC =MapSRC->GetBase() + MapSRC->PITCH*SizeY; LAST = DST + (MapDST->SX & ~1); *(DST) = (*(SRC) - *(SRC+1))>>(1-K0Est); DST++; SRC+=2; for (;DST < LAST;) { *(DST) = (*(SRC) + *(SRC) - *(SRC+1) - *(SRC-1))>>(2-K0Est); SRC += 2; DST ++; } } } void WAVELET_1(MAP *MapDST,MAP *MapDIFF) { s32 *LAST,*DST,*DST2; /* XYaxis Over 2*/ DST2 = DST = MapDST->GetBase(); for (u32 SizeY = 0; SizeY < MapDST->SY>>1;SizeY ++) { DST =MapDST->GetBase() + MapDST->PITCH*SizeY; DST2 =MapDST->GetBase() + MapDST->PITCH*(SizeY*2); LAST = DST2 + MapDST->SX; for (;DST2 < LAST;) { s32 Aver; Aver = (*(DST2)+*(DST2+1+MapDST->PITCH)); Aver += (*(DST2+1)+*(DST2+MapDST->PITCH));//*/ *(DST) = Aver>>2; DST2 += 2; //*(DST) >>= 2; DST ++; } } MAP MS,MD; MAP MSD,DIFFMAP; MD = *MapDST; MD.SX>>=1; MD.SY>>=1; MD.MoveBase(MD.SY * MD.PITCH); SET(&MD,0xff00); MD.MoveBase(MD.SX); SET(&MD,0xff00); MD.MoveBase(-MD.SY * MD.PITCH); SET(&MD,0xff00); MD.MoveBase(MD.SY * MD.PITCH - MD.SX); MD = *MapDST; MD.SX>>=1; MD.SY>>=1; MS = MD; u32 GLO = 0; while (MD.SY >= 1) { MD.MoveBase(MD.SY * MD.PITCH); MD.SY>>=1; COMPRESS_V2(&MS,&MD); DIFFMAP = MD; DIFFMAP.SetBase((s32*)((u32)MapDIFF->GetBase() + (u32)MD.GetBase() - (u32)MapDST->GetBase())); DIFF_V2(&MS,&DIFFMAP); GLO++; MS = MD; } MD = *MapDST; MD.SX>>=1; MS = MD; while (MD.SX >= 1) { MD.MoveBase(MD.SX); MD.SX>>=1; COMPRESS_H2(&MS,&MD); DIFFMAP = MD; DIFFMAP.SetBase((s32*)((u32)MapDIFF->GetBase() + (u32)MD.GetBase() - (u32)MapDST->GetBase())); DIFF_H2(&MS,&DIFFMAP); MS = MD; } } void ONLY_ABS(MAP *MapDST) { s32 *LAST,*DST; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; for (;DST < LAST;) *(DST++) = *(DST) & ~(*(DST)>>31); } } void ONLY_NABS(MAP *MapDST) { s32 *LAST,*DST; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; for (;DST < LAST;) *(DST++) = -(*(DST) & (*(DST)>>31)); } } void OFFSET(MAP *MapDST,s32 DX , s32 DY) { s32 *LAST,*END,*DST,*SRC,SWAP,YSRC; /* Ofset X*/ if (DX < 0) DX = MapDST->SX - DX; DX %= MapDST->SX; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; SRC = DST+DX; LAST = DST + MapDST->SX; for (;SRC < LAST;) { SWAP = *SRC; *SRC = *DST; *DST = SWAP; DST++; SRC++; } } /* Ofset Y*/ if (DY < 0) DY = MapDST->SY - DY; DY %= MapDST->SY; YSRC = DY; for (u32 SizeY = 0; YSRC < MapDST->SY;SizeY ++,YSRC++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; SRC = MapDST->GetBase() + YSRC * MapDST->PITCH; LAST = DST + MapDST->SX; for (;DST < LAST;) { SWAP = *SRC; *SRC = *DST; *DST = SWAP; DST++; SRC++; } } } void SHIFT(MAP *MapDST,s32 SHIFT) { s32 *LAST,*DST; DST = MapDST->GetBase(); LAST = DST + MapDST->SX; if (SHIFT < 0) { SHIFT = -SHIFT; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { LAST = DST + MapDST->SX; for (;DST < LAST;) { *DST <<= SHIFT; DST++; } DST+=MapDST->PITCH-MapDST->SX; } } else { for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { LAST = DST + MapDST->SX; for (;DST < LAST;) { *DST >>= SHIFT; DST++; } DST+=MapDST->PITCH-MapDST->SX; } } } void COPY_BW(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { LAST = DST + MapDST->SX; while (DST < LAST) { /* u32 A; A = ((*(SRC) & 0xff0000) + ((*(SRC) & 0xff00)<<9) + ((*(SRC) & 0xff)<<16))>>(16); *(DST) = A; */ *(DST) = ((*(SRC) & 0xff0000) + ((*(SRC) & 0xff00)<<9) + ((*(SRC) & 0xff)<<16))>>(16); DST++; SRC++; } SRC+=MapSRC->PITCH-MapSRC->SX; DST+=MapDST->PITCH-MapDST->SX; } } void COPY_RGBA(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH; DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = SRC + MapSRC->SX; while (SRC < LAST) { s32 A; A = *(SRC); if (A > 255) A = 255; if (A < 0) A = 0; A |= (A<<8) | (A<<16); *(DST) = A; DST++; SRC++; } } } void COPY_GRADIENT(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; SRC = MapSRC->GetBase(); DST = MapDST->GetBase(); #define RADIUS_GRADIENT 1 for (u32 SizeY = RADIUS_GRADIENT; SizeY < MapSRC->SY - RADIUS_GRADIENT;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + RADIUS_GRADIENT; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + RADIUS_GRADIENT; LAST = SRC + MapSRC->SX - RADIUS_GRADIENT * 2; while (SRC < LAST) { s32 D1,D2; D1 = *(SRC - RADIUS_GRADIENT) - *(SRC + RADIUS_GRADIENT); D2 = *(SRC - MapSRC->PITCH * RADIUS_GRADIENT) - *(SRC + MapSRC->PITCH * RADIUS_GRADIENT); *DST = ((D1 * D1 + D2 * D2)); SRC++; DST++; } } } void ERODE(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + 1; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 1; LAST = SRC + MapSRC->SX - 1 * 2; while (SRC < LAST) { *DST = *SRC; if (!*(SRC+1)) *DST = 0; if (!*(SRC+1+MapSRC->PITCH))*DST = 0; if (!*(SRC+1-MapSRC->PITCH))*DST = 0; if (!*(SRC-1)) *DST = 0; if (!*(SRC-1+MapSRC->PITCH))*DST = 0; if (!*(SRC-1-MapSRC->PITCH))*DST = 0; if (!*(SRC+MapSRC->PITCH)) *DST = 0; if (!*(SRC-MapSRC->PITCH)) *DST = 0; SRC++; DST++; } } } void NON_ZERO(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + 1; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 1; LAST = SRC + MapSRC->SX - 1 * 2; while (SRC < LAST) { if ((*(SRC) & 0x30000) && (*(SRC+1) & 0x30000) && (*(SRC+MapSRC->PITCH) & 0x30000)) { *DST =*(SRC); if (((*(SRC+1) ^ *(SRC)) & 0x30000) || ((*(SRC+MapSRC->PITCH) ^ *(SRC)) & 0x30000)) { *DST = 0x40000 | *(SRC); } } else *DST =0; SRC++; DST++; } } for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 1; LAST = DST + MapDST->SX - 1 * 2; while (DST < LAST) { if (*DST & 0x40000) { if ((*(DST-1) & 0x40000) && (*(DST-1) ^ *(DST)) & 0x30000) *DST &= ~0x40000; if ((*(DST-MapDST->PITCH) & 0x40000) && (*(DST-MapDST->PITCH) ^ *(DST)) & 0x30000) *DST &= ~0x40000; } DST++; } } /* for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 1; LAST = DST + MapDST->SX - 1 * 2; while (DST < LAST) { if (!(*DST & 0x30000)) { *(DST) &= ~0x40000; *(DST+1) &= ~0x40000; *(DST+MapDST->PITCH) &= ~0x40000; *(DST-MapDST->PITCH) &= ~0x40000; *(DST-1) &= ~0x40000; *(DST-1-MapDST->PITCH) &= ~0x40000; *(DST-1+MapDST->PITCH) &= ~0x40000; *(DST+1-MapDST->PITCH) &= ~0x40000; *(DST+1+MapDST->PITCH) &= ~0x40000; } DST++; } }//*/ } /*void MIN(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + 1; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 1; LAST = SRC + MapSRC->SX - 1 * 2; while (SRC < LAST) { *DST = *SRC; if (*DST > *(SRC+1)) *DST = *(SRC+1); if (*DST > *(SRC+1+MapSRC->PITCH)) *DST = *(SRC+1+MapSRC->PITCH); if (*DST > *(SRC+1-MapSRC->PITCH)) *DST = *(SRC+1-MapSRC->PITCH); if (*DST > *(SRC-1)) *DST = *(SRC-1); if (*DST > *(SRC-1+MapSRC->PITCH)) *DST = *(SRC-1+MapSRC->PITCH); if (*DST > *(SRC-1-MapSRC->PITCH)) *DST = *(SRC-1-MapSRC->PITCH); if (*DST > *(SRC+MapSRC->PITCH)) *DST = *(SRC+MapSRC->PITCH); if (*DST > *(SRC-MapSRC->PITCH)) *DST = *(SRC-MapSRC->PITCH); SRC++; DST++; } } } void MAX(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + 1; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 1; LAST = SRC + MapSRC->SX - 1 * 2; while (SRC < LAST) { *DST = *SRC; if (*DST < *(SRC+1)) *DST = *(SRC+1); if (*DST < *(SRC+1+MapSRC->PITCH)) *DST = *(SRC+1+MapSRC->PITCH); if (*DST < *(SRC+1-MapSRC->PITCH)) *DST = *(SRC+1-MapSRC->PITCH); if (*DST < *(SRC-1)) *DST = *(SRC-1); if (*DST < *(SRC-1+MapSRC->PITCH)) *DST = *(SRC-1+MapSRC->PITCH); if (*DST < *(SRC-1-MapSRC->PITCH)) *DST = *(SRC-1-MapSRC->PITCH); if (*DST < *(SRC+MapSRC->PITCH)) *DST = *(SRC+MapSRC->PITCH); if (*DST < *(SRC-MapSRC->PITCH)) *DST = *(SRC-MapSRC->PITCH); SRC++; DST++; } } }*/ void MIN_CROSS(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + 1; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 1; LAST = SRC + MapSRC->SX - 1 * 2; while (SRC < LAST) { *DST = *SRC; if (*DST > *(SRC+1)) *DST = *(SRC+1); if (*DST > *(SRC-1)) *DST = *(SRC-1); if (*DST > *(SRC+MapSRC->PITCH)) *DST = *(SRC+MapSRC->PITCH); if (*DST > *(SRC-MapSRC->PITCH)) *DST = *(SRC-MapSRC->PITCH); SRC++; DST++; } } } void MAX_CROSS(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + 1; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 1; LAST = SRC + MapSRC->SX - 1 * 2; while (SRC < LAST) { *DST = *SRC; if (*DST < *(SRC+1)) *DST = *(SRC+1); if (*DST < *(SRC-1)) *DST = *(SRC-1); if (*DST < *(SRC+MapSRC->PITCH)) *DST = *(SRC+MapSRC->PITCH); if (*DST < *(SRC-MapSRC->PITCH)) *DST = *(SRC-MapSRC->PITCH); SRC++; DST++; } } } void COPY_O2(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC,*SRC2; SRC = MapSRC->GetBase(); for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY += 2) { DST = MapDST->GetBase() + (SizeY>>1) * MapDST->PITCH; LAST = SRC + MapSRC->SX; SRC2 = SRC + MapSRC->PITCH; while (SRC < LAST) { *(DST++) = (*(SRC) + *(SRC + 1) + *(SRC2) + *(SRC2 + 1))>>2; SRC += 2; SRC2 += 2; } *(DST) = *(DST-1); SRC+=(MapSRC->PITCH-MapSRC->SX); SRC+= MapSRC->PITCH; } LAST = DST + MapDST->SX; while (DST < LAST) { *(DST) = *(DST-MapDST->PITCH); DST++; } *(DST) = *(DST-1); } void COPY_II(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); LAST = DST + MapDST->SX; while (DST < LAST) { *(DST++) = 0; *(SRC++) &= 0xfffffffe; } SRC+=MapSRC->PITCH-MapSRC->SX; DST+=MapDST->PITCH-MapDST->SX; for (s32 SizeY = 1; SizeY < MapSRC->SY ;SizeY ++) { LAST = DST + MapDST->SX ; *(DST++) = 0; *(SRC++) &= 0xfffffffe; while (DST < LAST) { *(DST) =*(SRC); *(DST) += *(DST-MapDST->PITCH); *(DST) += *(DST-1) - *(DST-1-MapDST->PITCH); *(DST++); *(SRC++) &= 0xfffffffe; } SRC+=MapSRC->PITCH-MapSRC->SX; DST+=MapDST->PITCH-MapDST->SX; } } void COPY_O2_RGBA(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC,*SRC2; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); for (u32 SizeY = 0; 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); *(DST++) = ((A & 0xfefefefe)>>1) + ((B & 0xfefefefe)>>1);; SRC += 2; SRC2 += 2; } SRC+=(MapSRC->PITCH-MapSRC->SX); SRC+= MapSRC->PITCH; DST+=MapDST->PITCH-MapDST->SX; } } void COPY_OX_RGBA(MAP *MapSRC,MAP *MapDST) { if (MapSRC->SX < MapDST->SX) return COPY_RESAMPLE(MapSRC,MapDST); s32 LineMerg1[2048]; s32 *LAST,*DST,*SRC,*SRC2,PosY,LastPosY; SRC = MapSRC->GetBase(); LastPosY = -1; for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++) { DST = LineMerg1; LAST = SRC + MapSRC->SX; while (SRC < LAST) *(DST++) = *(SRC++); u32 SizeX; s32 *DSTO2; SizeX = MapSRC->SX; while ((SizeX>>1) >= MapDST->SX) { DST = DSTO2 = LineMerg1; LAST = DST + SizeX; while (DST < LAST) { *(DSTO2++) = (s32)((((u32)*(DST)) & 0xfefefefe)>>1) + ((((u32)*(DST+1)) & 0xfefefefe)>>1); DST += 2; } SizeX >>= 1; } if (SizeX != MapDST->SX) { u32 IncX,BasX; BasX = 0; IncX = (MapDST->SX<<16) / SizeX; DST = DSTO2 = LineMerg1; LAST = DST + SizeX; while (DST < LAST) { DSTO2[BasX>>16] = *(DST++); BasX += IncX; } SizeX = MapDST->SX; } PosY = (SizeY * MapDST->SY) / MapSRC->SY; if (PosY != LastPosY) memcpy(MapDST->GetBase() + PosY * MapDST->PITCH,LineMerg1,SizeX * 4); else { DSTO2 = LineMerg1; DST = MapDST->GetBase() + PosY * MapDST->PITCH; LAST = DST + SizeX; while (DST < LAST) { *(DST++) = (s32)((((u32)*(DST)) & 0xfefefefe)>>1) + ((((u32)*(DSTO2)) & 0xfefefefe)>>1); DSTO2++; } } LastPosY = PosY; SRC+=(MapSRC->PITCH-MapSRC->SX); } } void COPY_OX_II(MAP *MapSRC,MAP *MapDST) { s32 LineMerg1[2048]; s32 *LAST,*DST,*SRC,*SRC2,PosY,LastPosY; SRC = MapSRC->GetBase(); LastPosY = -1; for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++) { DST = LineMerg1; LAST = SRC + MapSRC->SX; while (SRC < LAST) *(DST++) = *(SRC++); u32 SizeX; s32 *DSTO2; SizeX = MapSRC->SX; while ((SizeX>>1) >= MapDST->SX) { DST = DSTO2 = LineMerg1; LAST = DST + SizeX; while (DST < LAST) { *(DSTO2++) = (*(DST) + *(DST+1))>>1; DST += 2; } SizeX >>= 1; } if (SizeX != MapDST->SX) { u32 IncX,BasX; BasX = 0; IncX = (MapDST->SX<<16) / SizeX; DST = DSTO2 = LineMerg1; LAST = DST + SizeX; while (DST < LAST) { DSTO2[BasX>>16] = *(DST++); BasX += IncX; } SizeX = MapDST->SX; } PosY = (SizeY * MapDST->SY) / MapSRC->SY; if (PosY != LastPosY) memcpy(MapDST->GetBase() + PosY * MapDST->PITCH,LineMerg1,SizeX * 4); else { DSTO2 = LineMerg1; DST = MapDST->GetBase() + PosY * MapDST->PITCH; LAST = DST + SizeX; while (DST < LAST) { *(DST++) = (*(DST) + *(DSTO2))>>1; DSTO2++; } } LastPosY = PosY; SRC+=(MapSRC->PITCH-MapSRC->SX); } } void DrawCircle(MAP *MapDST,s32 X,s32 Y,s32 Radius,u32 Color,u32 Ep) { #define DISC_DISC 40 float Alpha; s32 BX,BY; s32 BX2,BY2; Alpha = 0.0f; BX2 = Radius; BY2 = 0; Ep = DISC_DISC; while (Ep--) { Alpha += 3.1415927f * 2.0f / (float)DISC_DISC; BX = (int)(cosf(Alpha) * Radius); BY = (int)(sinf(Alpha) * Radius); DrawLine(MapDST,X + BX,Y + BY,X + BX2,Y + BY2 ,Color); BX2 = BX; BY2 = BY; } } void DrawQuad_R(MAP *MapDST,s32 X1,s32 Y1,s32 X2,s32 Y2,u32 Color,u32 Ep,float Alpha) { s32 CX,CY; CX = (X1 + X2)>>1; CY = (Y1 + Y2)>>1; X1 -= CX; X2 -= CX; Y1 -= CY; Y2 -= CY; Alpha = -Alpha; while (Ep--) { DrawLine(MapDST,(int)(CX + cosf(Alpha) * X1 + sinf(Alpha) * Y1),(int)(CY + cosf(Alpha) * Y1 - sinf(Alpha) * X1), (int)(CX + cosf(Alpha) * X2 + sinf(Alpha) * Y1),(int)(CY + cosf(Alpha) * Y1 - sinf(Alpha) * X2),Color); DrawLine(MapDST,(int)(CX + cosf(Alpha) * X2 + sinf(Alpha) * Y1),(int)(CY + cosf(Alpha) * Y1 - sinf(Alpha) * X2), (int)(CX + cosf(Alpha) * X2 + sinf(Alpha) * Y2),(int)(CY + cosf(Alpha) * Y2 - sinf(Alpha) * X2),Color); DrawLine(MapDST,(int)(CX + cosf(Alpha) * X1 + sinf(Alpha) * Y2),(int)(CY + cosf(Alpha) * Y2 - sinf(Alpha) * X1), (int)(CX + cosf(Alpha) * X2 + sinf(Alpha) * Y2),(int)(CY + cosf(Alpha) * Y2 - sinf(Alpha) * X2),Color); DrawLine(MapDST,(int)(CX + cosf(Alpha) * X1 + sinf(Alpha) * Y1),(int)(CY + cosf(Alpha) * Y1 - sinf(Alpha) * X1), (int)(CX + cosf(Alpha) * X1 + sinf(Alpha) * Y2),(int)(CY + cosf(Alpha) * Y2 - sinf(Alpha) * X1),Color); X1 --; X2 ++; Y1 --; Y2 ++; } } // based on 512 * 512 image static const UINT marker[16] = { 255, 208, 215, 102, 198, 50, 187, 156, 231, 98, 132, 201, 32, 172, 147, 15 }; u32 GET_MARKER(MAP *Map) { u32 mask = 0; int x1, y1; int x2, y2; s32 *SRC; u32 A1, A2; if (Map == NULL || Map->GetBase() == NULL) return 0; for (int i=0; i<16; i++) { x1 = marker[i] * Map->SX / 512; y1 = marker[(i+1)%16] * Map->SY / 512; x2 = (512 - marker[(i+2)%16] - 1) * Map->SX / 512; y2 = (512 - marker[(i+3)%16] - 1) * Map->SY / 512; SRC = Map->GetBase() + x1 + y1*Map->PITCH; A1 = ((*(SRC) & 0xff0000) + ((*(SRC) & 0xff00)<<9) + ((*(SRC) & 0xff)<<16))>>(16); SRC = Map->GetBase() + x2 + y2*Map->PITCH; A2 = ((*(SRC) & 0xff0000) + ((*(SRC) & 0xff00)<<9) + ((*(SRC) & 0xff)<<16))>>(16); if (A1 < A2) mask |= 1<GetBase() + x2 + y1*Map->PITCH; A1 = ((*(SRC) & 0xff0000) + ((*(SRC) & 0xff00)<<9) + ((*(SRC) & 0xff)<<16))>>(16); SRC = Map->GetBase() + x1 + y2*Map->PITCH; A2 = ((*(SRC) & 0xff0000) + ((*(SRC) & 0xff00)<<9) + ((*(SRC) & 0xff)<<16))>>(16); if (A1 < A2) mask |= 1<<(i+16); } return mask; } u32 SAVEBMP(MAP *RefMap,char *Filename) { FILE *F; F = fopen(Filename,"wb"); if (!F) return 0; BITMAPFILEHEADER st_BMPHeader; BITMAPINFOHEADER st_BMPInfoHeader; memset(&st_BMPHeader,0,sizeof(st_BMPHeader)); memset(&st_BMPInfoHeader,0,sizeof(st_BMPInfoHeader)); st_BMPHeader.bfSize = sizeof(st_BMPHeader); st_BMPHeader.bfType = 'MB'; st_BMPHeader.bfOffBits = sizeof(st_BMPHeader) + sizeof(st_BMPInfoHeader); st_BMPInfoHeader.biSize = sizeof(st_BMPInfoHeader); st_BMPInfoHeader.biPlanes = 1; st_BMPInfoHeader.biWidth = RefMap->SX; st_BMPInfoHeader.biHeight = RefMap->SY; st_BMPInfoHeader.biBitCount = 24; st_BMPInfoHeader.biCompression = BI_RGB; fwrite(&st_BMPHeader,1,sizeof(st_BMPHeader),F); fwrite(&st_BMPInfoHeader,1,sizeof(st_BMPInfoHeader),F); s32 *pBASE = RefMap->GetBase(); for (u32 CY = 0 ; CY < RefMap->SY ; CY ++) for (u32 CX = 0 ; CX < RefMap->SX ; CX ++) { u8 C[3] = { pBASE[CY*RefMap->PITCH + CX] >> 0,pBASE[CY*RefMap->PITCH + CX] >> 8 , pBASE[CY*RefMap->PITCH + CX] >> 16}; fwrite(C,1,3,F); } fclose(F); return 1; } void AND(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; for (u32 SizeY = 2; SizeY < MapSRC->SY - 2;SizeY ++) { SRC = MapSRC->GetBase() + SizeY * MapSRC->PITCH + 2; DST = MapDST->GetBase() + SizeY * MapDST->PITCH + 2; LAST = SRC + MapSRC->SX - 2 * 2; while (SRC < LAST) { *DST &= *(SRC); SRC++; DST++; } } } void AND(MAP *MapDST,s32 And) { u32 *LAST,*DST; DST = (u32*)MapDST->GetBase(); for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { LAST = DST + MapDST->SX; while (DST < LAST) { *(DST) &= And; DST++; } DST+=MapDST->PITCH-MapDST->SX; } } void ADD_NOISE(MAP *MapDST) { s32 *LAST,*DST; u32 K,KA; static u32 Init = 1; static u32 Random_T[65536]; if (Init) { Init = 65536; while (Init--) { Random_T[Init] = rand()&255; Random_T[Init] *= Random_T[Init]; Random_T[Init] >>= 8;//*/ Random_T[Init] >>= 5; } Init = 0; } DST = MapDST->GetBase(); K = rand()&65535; KA = rand()&127; for (s32 SizeY = 0; SizeY < (s32)MapDST->SY;SizeY ++) { LAST = DST + MapDST->SX; while (DST < LAST) { *(DST++) += Random_T[K&65535]; K+=KA; } DST+=MapDST->PITCH-MapDST->SX; } } #define SWAP_MAP() {Swap = CurrentSRC;CurrentSRC = CurrentDST;CurrentDST = Swap;} void BLUR_0(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST = MapDST->GetBase() + MapDST->PITCH; SRC = MapSRC->GetBase() + MapSRC->PITCH; for (u32 SizeY = 1; SizeY < MapSRC->SY - 1;SizeY ++) { SRC = MapSRC->GetBase() + MapSRC->PITCH*SizeY + 1; DST = MapDST->GetBase() + MapDST->PITCH*SizeY + 1; LAST = DST + MapDST->SX - 2; while (DST < LAST) { s32 Di,Cr,Ce; Di = *(SRC - 1 - MapSRC->PITCH) + *(SRC + 1 - MapSRC->PITCH) + *(SRC + 1 + MapSRC->PITCH) + *(SRC - 1 + MapSRC->PITCH) ; Cr = (*(SRC - 1) + *(SRC + 1) + *(SRC + MapSRC->PITCH) + *(SRC - MapSRC->PITCH)); Ce = *(SRC) << 2; *DST = (((((Di + Cr)>>1) + Cr)>>1)+Ce)>>3; SRC++; DST++; } } } void BLUR_LINE_0(s32 *SRC,s32 *DST,int Counter) { s32 *LAST; LAST = DST + Counter - 1; DST++; SRC++; while (DST < LAST) { *DST = (*SRC + *SRC + *(SRC-1) + *(SRC+1))>>2; DST++; SRC++; *DST = (*SRC + *SRC + *(SRC-1) + *(SRC+1))>>2; DST++; SRC++; _mm_prefetch((char*)(SRC + (128)),_MM_HINT_NTA); _mm_prefetch((char*)(DST + (128)),_MM_HINT_NTA);//*/ } } void BLUR_COLUMN_0(s32 *SRC,s32 *DST,int Counter,int PitchS,int PitchD) { s32 *LAST,*SRC_PR,*SRC_MR; LAST = DST + PitchD * (Counter - 1); SRC_MR = SRC; SRC += PitchS; DST += PitchD; SRC_PR = SRC + PitchS; while (DST < LAST) { *(DST+0) = (*(SRC+0) + *(SRC+0) + *(SRC_MR+0) + *(SRC_PR+0))>>2; *(DST+1) = (*(SRC+1) + *(SRC+1) + *(SRC_MR+1) + *(SRC_PR+1))>>2; *(DST+2) = (*(SRC+2) + *(SRC+2) + *(SRC_MR+2) + *(SRC_PR+2))>>2; *(DST+3) = (*(SRC+3) + *(SRC+3) + *(SRC_MR+3) + *(SRC_PR+3))>>2; *(DST+4) = (*(SRC+4) + *(SRC+4) + *(SRC_MR+4) + *(SRC_PR+4))>>2; *(DST+5) = (*(SRC+5) + *(SRC+5) + *(SRC_MR+5) + *(SRC_PR+5))>>2; *(DST+6) = (*(SRC+6) + *(SRC+6) + *(SRC_MR+6) + *(SRC_PR+6))>>2; *(DST+7) = (*(SRC+7) + *(SRC+7) + *(SRC_MR+7) + *(SRC_PR+7))>>2; DST+= PitchD; SRC_PR+= PitchS; SRC_MR+= PitchS; SRC+= PitchS; _mm_prefetch((char*)(SRC_PR + (PitchS<<2)),_MM_HINT_NTA); _mm_prefetch((char*)(DST + (PitchD<<2)),_MM_HINT_NTA); } } void BLUR_LINE(s32 *SRC,s32 *DST,int Counter,int Radius) { s32 *LAST,*SRC_PR,*SRC_MR; s32 Accum; LAST = DST + Counter - Radius; SRC_PR = SRC + Radius * 2 + 1; SRC_MR = SRC; Accum = 0; while (SRC_MR < SRC_PR) Accum+= *(SRC_MR++); SRC_MR = DST; DST += Radius; while (SRC_MR < DST) *(SRC_MR++) = Accum; SRC_MR = SRC; while (DST < LAST) { *DST = Accum; Accum += *SRC_PR; Accum -= *SRC_MR; DST++; SRC_PR++; SRC_MR++; _mm_prefetch((char*)(SRC_PR + (128)),_MM_HINT_NTA); _mm_prefetch((char*)(DST + (128)),_MM_HINT_NTA);//*/ } SRC_MR = DST; DST += Radius; while (SRC_MR < DST) *(SRC_MR++) = Accum; } void BLUR_COLUMN(s32 *SRC,s32 *DST,int Counter,int Radius,int PitchS,int PitchD) { s32 *LAST,*SRC_PR,*SRC_MR; float Accum1,Accum2,Accum3,Accum4,Accum5,Accum6,Accum7,Accum8; LAST = DST + PitchD * (Counter - Radius); SRC_PR = SRC + PitchS * (Radius * 2 + 1); SRC_MR = SRC; Accum1 = Accum2 = Accum3 = Accum4 = 0; Accum5 = Accum6 = Accum7 = Accum8 = 0; while (SRC_MR < SRC_PR) { Accum1+= *(SRC_MR+0); Accum2+= *(SRC_MR+1); Accum3+= *(SRC_MR+2); Accum4+= *(SRC_MR+3); Accum5+= *(SRC_MR+4); Accum6+= *(SRC_MR+5); Accum7+= *(SRC_MR+6); Accum8+= *(SRC_MR+7); SRC_MR += PitchS; _mm_prefetch((char*)(SRC_MR + (PitchS<<2)),_MM_HINT_NTA); } SRC_MR = DST; DST += Radius * PitchD; while (SRC_MR < DST) { *(SRC_MR+0) = Accum1; *(SRC_MR+1) = Accum2; *(SRC_MR+2) = Accum3; *(SRC_MR+3) = Accum4; *(SRC_MR+4) = Accum5; *(SRC_MR+5) = Accum6; *(SRC_MR+6) = Accum7; *(SRC_MR+7) = Accum8; SRC_MR += PitchD; _mm_prefetch((char*)(SRC_MR + (PitchD<<2)),_MM_HINT_NTA); } SRC_MR = SRC; while (DST < LAST) { *(DST+0) = Accum1; *(DST+1) = Accum2; *(DST+2) = Accum3; *(DST+3) = Accum4; *(DST+4) = Accum5; *(DST+5) = Accum6; *(DST+6) = Accum7; *(DST+7) = Accum8; Accum1 += *(SRC_PR+0); Accum1 -= *(SRC_MR+0); Accum2 += *(SRC_PR+1); Accum2 -= *(SRC_MR+1); Accum3 += *(SRC_PR+2); Accum3 -= *(SRC_MR+2); Accum4 += *(SRC_PR+3); Accum4 -= *(SRC_MR+3); Accum5 += *(SRC_PR+4); Accum5 -= *(SRC_MR+4); Accum6 += *(SRC_PR+5); Accum6 -= *(SRC_MR+5); Accum7 += *(SRC_PR+6); Accum7 -= *(SRC_MR+6); Accum8 += *(SRC_PR+7); Accum8 -= *(SRC_MR+7); DST+= PitchD; SRC_PR+= PitchS; SRC_MR+= PitchS; _mm_prefetch((char*)(SRC_PR + (PitchS<<2)),_MM_HINT_NTA); _mm_prefetch((char*)(DST + (PitchD<<2)),_MM_HINT_NTA); } SRC_MR = DST; DST += Radius * PitchD; while (SRC_MR < DST) { *(SRC_MR+0) = Accum1; *(SRC_MR+1) = Accum2; *(SRC_MR+2) = Accum3; *(SRC_MR+3) = Accum4; *(SRC_MR+4) = Accum5; *(SRC_MR+5) = Accum6; *(SRC_MR+6) = Accum7; *(SRC_MR+7) = Accum8; SRC_MR+= PitchD; } } #define SHIFT_ECLUSE 8 void SHIFT_LINE(s32 *DST,int Counter) { Counter >>= 3; while (Counter--) { *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; _mm_prefetch((char*)(DST + (128)),_MM_HINT_NTA); } } void SHIFT_COLUMN(s32 *DST,int Counter,int Pitch) { while (Counter--) { *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; *(DST++) >>= SHIFT_ECLUSE; DST+=Pitch - 8; _mm_prefetch((char*)(DST + (Pitch<<1)),_MM_HINT_NTA); } } void Renormalize(MAP *MapDST,int Factor) { if (Factor) { s32 *LAST,*DST; Factor = 65536 / Factor; for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++) { DST = MapDST->GetBase() + SizeY * MapDST->PITCH; LAST = DST + MapDST->SX; while (DST < LAST) { *DST *= Factor; *DST >>= 16; DST++; } } } } void LF_GaussianFilter(MAP *MapSRCConst,MAP *MapDST,MAP *MapSRC,int Radius,int Derviv) { if ((Radius == 1) || (Radius == 2) || (Radius == 4)) { MAP16 BlurredMazp; BlurredMazp.SetBase((s16*)MapDST->GetBase()); BlurredMazp.PITCH = BlurredMazp.SX = MapDST->SX; BlurredMazp.SY = MapDST->SY; /* Copy */ u32 CounterY = BlurredMazp.SY; s16 *Mdst = BlurredMazp.GetBase();s32 *MSrc = MapSRCConst->GetBase(); while(CounterY--) { u32 Counter = BlurredMazp.SX; while(Counter--) *(Mdst++) = (s16)*(MSrc++); MSrc += MapSRCConst->PITCH - MapSRCConst->SX; } switch (Radius) { case 1:MAP16_BLUR_Inplace(&BlurredMazp, 1 , Derviv+1);break; case 2:MAP16_BLUR_Inplace(&BlurredMazp, 2 , Derviv+1);break; case 4:MAP16_BLUR_Inplace(&BlurredMazp, 3 , Derviv+1);break; } Mdst = BlurredMazp.GetBase() + BlurredMazp.SX * BlurredMazp.SY; MSrc = MapDST->GetBase() + MapDST->PITCH * MapDST->SY; CounterY = BlurredMazp.SY; while (CounterY--) { u32 Counter = BlurredMazp.SX; MSrc -= MapSRCConst->PITCH - MapSRCConst->SX; while(Counter--) *(--MSrc) = (s32)*(--Mdst); } return; } s32 Factor,Withness; MAP *CurrentSRC,*CurrentDST,*Swap; COPY(MapSRCConst,MapSRC); CurrentSRC = MapSRC; CurrentDST = MapDST; if ( (!Derviv) ) { COPY(MapSRC,MapDST); return; } if (!Radius) { COPY(MapSRCConst,MapSRC); while (Derviv--) { BLUR_0(MapSRC,MapDST); COPY(MapDST,MapSRC); } return; } /* X-Axis */ for (u32 SizeY = 0; SizeY < CurrentDST->SY;SizeY ++) { MAP *SaveCurrentSRC,*SaveCurrentDST; SaveCurrentSRC = CurrentSRC; SaveCurrentDST = CurrentDST; Withness = 1; if (Radius) { for (u32 Counter = 0 ; Counter < Derviv ; Counter++) { Withness = Withness * (Radius * 2 + 1); BLUR_LINE(CurrentSRC->GetBase() + SizeY * CurrentSRC->PITCH,CurrentDST->GetBase() + SizeY * CurrentDST->PITCH,CurrentDST->SX,Radius); if (Withness & (0xffffffff<GetBase() + SizeY * CurrentDST->PITCH,CurrentDST->SX); Withness >>= SHIFT_ECLUSE; } SWAP_MAP(); } } else { for (u32 Counter = 0 ; Counter < Derviv ; Counter++) { BLUR_LINE_0(CurrentSRC->GetBase() + SizeY * CurrentSRC->PITCH,CurrentDST->GetBase() + SizeY * CurrentDST->PITCH,CurrentDST->SX); SWAP_MAP(); } } CurrentSRC = SaveCurrentSRC; CurrentDST = SaveCurrentDST; }//*/ if (Derviv & 1) SWAP_MAP(); Factor = Withness; /* Y-Axis */ for (u32 SizeX = 0; SizeX < CurrentDST->SX;SizeX += 8) { MAP *SaveCurrentSRC,*SaveCurrentDST; SaveCurrentSRC = CurrentSRC; SaveCurrentDST = CurrentDST; Withness = Factor; if (Radius) { for (u32 Counter = 0 ; Counter < Derviv ; Counter++) { Withness = Withness * (Radius * 2 + 1); BLUR_COLUMN(CurrentSRC->GetBase() + SizeX,CurrentDST->GetBase() + SizeX,CurrentDST->SY,Radius,CurrentSRC->PITCH,CurrentDST->PITCH); if (Withness & 0xffff0000) { SHIFT_COLUMN(CurrentDST->GetBase() + SizeX,CurrentDST->SY,CurrentDST->PITCH); Withness >>= SHIFT_ECLUSE; } SWAP_MAP(); } } else { for (u32 Counter = 0 ; Counter < Derviv ; Counter++) { BLUR_COLUMN_0(CurrentSRC->GetBase() + SizeX,CurrentDST->GetBase() + SizeX,CurrentDST->SY,CurrentSRC->PITCH,CurrentDST->PITCH); SWAP_MAP(); } } CurrentSRC = SaveCurrentSRC; CurrentDST = SaveCurrentDST; }//*/ if (Derviv & 1) SWAP_MAP(); if (CurrentDST == MapDST) { COPY(MapSRC,MapDST); } Factor = Withness; if (Factor != 1) Renormalize(MapDST,Factor);//*/ } inline u32 FAST_ABS(s32 K) { return abs(K); } void II(MAP *MapDST) { s32 *LAST,*DST; DST = MapDST->GetBase(); LAST = DST + MapDST->SX; for (;DST < LAST;) {*(DST++) = 0;}; DST+=MapDST->PITCH-MapDST->SX; for (u32 SizeY = 1; SizeY < MapDST->SY;SizeY ++) { LAST = DST + MapDST->SX; *(DST++) = 0; for (;DST < LAST;) { *DST += *(DST-1); *DST += *(DST-MapDST->PITCH); *DST -= *(DST-1-MapDST->PITCH); DST++; } DST+=MapDST->PITCH-MapDST->SX; } } void ABS_SUB(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++) { LAST = DST + MapDST->SX; while (DST < LAST) { *DST = (*SRC - *DST); *SRC = FAST_ABS(*DST); SRC++; DST++; } SRC+=MapSRC->PITCH-MapSRC->SX; DST+=MapDST->PITCH-MapDST->SX; } } void SUB(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++) { LAST = DST + MapDST->SX; while (DST < LAST) { *DST = *SRC - *DST; SRC++; DST++; } SRC+=MapSRC->PITCH-MapSRC->SX; DST+=MapDST->PITCH-MapDST->SX; } } void ADD(MAP *MapSRC,MAP *MapDST) { s32 *LAST,*DST,*SRC; DST = MapDST->GetBase(); SRC = MapSRC->GetBase(); for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++) { LAST = DST + MapDST->SX; while (DST < LAST) { *DST += *SRC; SRC++; DST++; } SRC+=MapSRC->PITCH-MapSRC->SX; DST+=MapDST->PITCH-MapDST->SX; } } void SET_BORDER(MAP *MapSRC,s32 Size,s32 Value) { DrawQuadFull(MapSRC,0,0,MapSRC->SX,Size,(u32)Value); DrawQuadFull(MapSRC,0,0,Size,MapSRC->SY,(u32)Value); DrawQuadFull(MapSRC,MapSRC->SX-Size,0,MapSRC->SX,MapSRC->SY,(u32)Value); DrawQuadFull(MapSRC,0,MapSRC->SY-Size,MapSRC->SX,MapSRC->SY,(u32)Value); }