2042 lines
No EOL
47 KiB
C++
2042 lines
No EOL
47 KiB
C++
#include "windows.h"
|
|
#include "CCMap.h"
|
|
#include "stdio.h"
|
|
#include "math.h"
|
|
#include "xmmintrin.h"
|
|
#include "stdlib.h"
|
|
//#include <Windows.h> // <= 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<<i;
|
|
|
|
SRC = Map->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<<SHIFT_ECLUSE))
|
|
{
|
|
SHIFT_LINE(CurrentDST->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);
|
|
} |