Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
1383 lines
32 KiB
C++
1383 lines
32 KiB
C++
#include "image.h"
|
|
#include<stdio.h>
|
|
#include<math.h>
|
|
#include<string.h>
|
|
|
|
|
|
#define Round(x) floor((x)+.5f);
|
|
|
|
// >>>>>>>>>>>>>>>>>>>> Histogram Members
|
|
|
|
Histogram::Histogram()
|
|
{
|
|
}
|
|
|
|
void Histogram::Clear()
|
|
{
|
|
for(int i=0;i<256;i++) Data[i]=0;
|
|
Peak=0;
|
|
}
|
|
|
|
Histogram::Histogram(Image &img,RMETHOD rmet)
|
|
{
|
|
Histogram();
|
|
img.FillHistogram(this,rmet);
|
|
}
|
|
|
|
int Histogram::GetBottom(float per)
|
|
{
|
|
int lowcut=(int)(per*.01*Peak);
|
|
int i;
|
|
for(i=0;i<256;i++) if (Data[i]>lowcut) return i;
|
|
STOP(("Invalid Histogram"));
|
|
return 0;
|
|
}
|
|
|
|
int Histogram::GetTop(float per)
|
|
{
|
|
int lowcut=(int)(per*.01*Peak);
|
|
for(int i=255;i>=0;i--) if (Data[i]>lowcut) return i;
|
|
STOP(("Invalid Histogram"));
|
|
return 255;
|
|
}
|
|
|
|
Histogram::~Histogram()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
RGBHistogram::RGBHistogram(Image &img)
|
|
{
|
|
img.FillHistogram(this);
|
|
}
|
|
|
|
void RGBHistogram::Clear()
|
|
{
|
|
RHist.Clear();
|
|
GHist.Clear();
|
|
BHist.Clear();
|
|
}
|
|
|
|
ImgRGBColor RGBHistogram::GetBottom(float per)
|
|
{
|
|
ImgRGBColor col;
|
|
col.r=RHist.GetBottom(per);
|
|
col.g=GHist.GetBottom(per);
|
|
col.b=BHist.GetBottom(per);
|
|
col.a=0;
|
|
return col;
|
|
}
|
|
|
|
ImgRGBColor RGBHistogram::GetTop(float per)
|
|
{
|
|
ImgRGBColor col;
|
|
col.r=RHist.GetTop(per);
|
|
col.g=GHist.GetTop(per);
|
|
col.b=BHist.GetTop(per);
|
|
col.a=255;
|
|
return col;
|
|
}
|
|
|
|
// >>>>>>>>>>>>>>>>>>>> Image Members
|
|
|
|
|
|
Image::Image(char *Str)
|
|
{
|
|
Init();
|
|
Load(Str);
|
|
}
|
|
|
|
Image::Image(Image &img)
|
|
{
|
|
Init();
|
|
*this=img;
|
|
}
|
|
|
|
void Image::Init()
|
|
{
|
|
strcpy(fname,"");
|
|
Data=NULL;
|
|
xpos=ypos=vxlen=vylen=LockStack=Pitch=Bpp=xlen=ylen=0;
|
|
itype=ITYPE_RGB;
|
|
pal=NULL;
|
|
Mask.Set(0x00ff0000,0x0000ff00,0x000000ff,0) ;
|
|
}
|
|
|
|
Image::Image() { Init(); }
|
|
|
|
Image::Image(int xl,int yl)
|
|
{
|
|
Init();
|
|
CreateBlank(xl,yl);
|
|
}
|
|
|
|
Image::Image(int xl,int yl,ImgRGBColor col)
|
|
{
|
|
Init();
|
|
CreateSolid(xl,yl,col);
|
|
}
|
|
|
|
Image::~Image() { Delete(); }
|
|
|
|
ImgRGBColor Image::GetColor(Point &p)
|
|
{
|
|
if(p.x>=xlen || p.y>=ylen) return ImgRGBColor(0,0,0);
|
|
ImgRGBColor trgb;
|
|
RGBPixel *tptr;
|
|
BYTE *bp=Lock();
|
|
tptr=(RGBPixel *)(bp+ ((p.x+p.y*xlen)*(Bpp>>3)));
|
|
trgb.Set(*tptr,Mask);
|
|
UnLock();
|
|
return trgb;
|
|
}
|
|
|
|
// >>>>>>>>>>>>>>>>>>>>>>>> Internals
|
|
void Image::IAlloc()
|
|
{
|
|
if(IsData()) IFree();
|
|
Pitch=xlen*(Bpp>>3);
|
|
BYTE *dt=new BYTE[ylen*Pitch+4];
|
|
if(dt==NULL)
|
|
GENFERR("Not Enough Memory to Create Image");
|
|
|
|
Data=dt;
|
|
Flag|=IMG_ISDATA;
|
|
}
|
|
|
|
void Image::SetData(BYTE *dt)
|
|
{
|
|
int y,axl=xlen*(Bpp>>3);
|
|
int yval1,yval2;
|
|
if(!IsData()) IAlloc();
|
|
BYTE *dat=Lock();
|
|
|
|
for(yval1=yval2=y=0;y<ylen;y++,yval1+=Pitch,yval2+=axl)
|
|
memcpy(dat+yval1,dt+yval2,axl);
|
|
// for(x=0;x<axl;x++) dat[x+yval1]=dt[x+yval2]; //Revised for Performance
|
|
|
|
UnLock();
|
|
}
|
|
|
|
void Image::IFree()
|
|
{
|
|
if(IsData()) delete Data;
|
|
Mask(Flag,IMG_ISDATA);
|
|
Data=0;
|
|
}
|
|
|
|
|
|
void Image::Delete()
|
|
{
|
|
IFree();
|
|
fname[0]=0;
|
|
xpos=ypos=vxlen=vylen=Bpp=xlen=ylen=0;
|
|
itype=ITYPE_RGB;
|
|
if(pal) delete pal;
|
|
// for(int i=0;i<256;i++) pal[i].r=pal[i].g=pal[i].b=0;
|
|
}
|
|
|
|
int Image::IsData() {return Flag&IMG_ISDATA;}
|
|
|
|
BYTE *Image::Lock()
|
|
{
|
|
if(Flag&IMG_LOCKED) UnLock();
|
|
Flag|=IMG_LOCKED;
|
|
return Data;
|
|
}
|
|
|
|
void Image::UnLock() { if(Flag&IMG_LOCKED) Mask(Flag,IMG_LOCKED); }
|
|
|
|
//>>>>>>>>>>>>>>>>>> Palletteing
|
|
void Image::RealizePalette() //here for overloading
|
|
{ }
|
|
|
|
void Image::SetPaletteEntry(int idx,int r,int g ,int b)
|
|
{
|
|
AllocPal();
|
|
SetPaletteEntry(idx,ImgRGBColor(r,g,b));
|
|
}
|
|
|
|
void Image::SetPaletteEntry(int idx,float r,float g,float b)
|
|
{
|
|
AllocPal();
|
|
SetPaletteEntry(idx,ImgRGBColor(r,g,b));
|
|
}
|
|
|
|
void Image::SetPaletteEntry(int idx,const ImgRGBColor &rgb)
|
|
{
|
|
AllocPal();
|
|
if (idx>255 ||idx <0) return;
|
|
pal[idx]=rgb;
|
|
RealizePalette();
|
|
}
|
|
|
|
void Image::MakeGrayscalePalette()
|
|
{
|
|
AllocPal();
|
|
int i;
|
|
|
|
for(i=0;i<256;i++)
|
|
{
|
|
pal[i]=i;
|
|
}
|
|
|
|
RealizePalette();
|
|
}
|
|
|
|
ImgRGBColor Image::GetPaletteEntry(int idx)
|
|
{ return pal[idx]; }
|
|
|
|
//>>>>>>>>>>>>>>>>>> Loading Helpers
|
|
|
|
void Image::Load(char *str)
|
|
{
|
|
FILE *fl=fopen(str,"rb");
|
|
|
|
if(!fl)
|
|
{
|
|
char tfn[MAX_PATH*2];
|
|
strcpy(tfn,"Cannot open file for reading:");
|
|
strcat(tfn,str);
|
|
GENNFERR(tfn);
|
|
}
|
|
|
|
strcpy(fname,str);
|
|
Load(fl);
|
|
fclose(fl);
|
|
}
|
|
|
|
void Image::Load(FILE *fl)
|
|
{
|
|
if(IsTiff(fl))
|
|
LoadTiff(fl);
|
|
else
|
|
if(IsGif(fl))
|
|
LoadGif(fl);
|
|
else
|
|
if(IsPng(fl))
|
|
LoadPng(fl);
|
|
else
|
|
if(IsTga())
|
|
LoadTga(fl);
|
|
else
|
|
STOP(("Unknown format for General Load"));
|
|
// if(IsTga()) LoadTga(fl);
|
|
// if(IsPng()) LoadPng(fl);
|
|
}
|
|
|
|
void Image::Load()
|
|
{
|
|
Load(fname);
|
|
}
|
|
|
|
void Image::Blt(Image &img,FRect dst)
|
|
{
|
|
dst.left*=vxlen; dst.right*=vxlen;
|
|
dst.top*=vylen; dst.bottom*=vylen;
|
|
Blt(img,(RECT)TRect(dst));
|
|
}
|
|
|
|
void Image::Blt(Image &img,FRect dst,FRect src)
|
|
{
|
|
dst.left*=vxlen; dst.right*=vxlen;
|
|
dst.top*=vylen; dst.bottom*=vylen;
|
|
src.left*=img.vxlen; src.right*=img.vxlen;
|
|
src.top*=img.vylen; src.bottom*=img.vylen;
|
|
Blt(img,TRect(dst),TRect(src));
|
|
}
|
|
|
|
void Image::Blt(Image &img,int x,int y,FRect src)
|
|
{
|
|
src.left*=img.vxlen; src.right*=img.vxlen;
|
|
src.top*=img.vylen; src.bottom*=img.vylen;
|
|
Blt(img,x,y,TRect(src));
|
|
}
|
|
|
|
void Image::Blt(Image &img,RECT &dst)
|
|
{
|
|
Blt(img,dst,TRect(0,0,img.vxlen,img.vylen));
|
|
}
|
|
|
|
void Image::Blt(Image &img,int x,int y)
|
|
{
|
|
Blt(img,x,y,TRect(0,0,img.vxlen,img.vylen));
|
|
}
|
|
|
|
/*
|
|
void Image::Blt(Image &img,RECT dst,RECT &src)
|
|
{
|
|
int dr,db;
|
|
int xd,yd;
|
|
int ddx,ddy;
|
|
|
|
float MyFact;
|
|
MyFact=((float)(src.right-src.left))/(dst.right-dst.left);
|
|
|
|
src.top+=(int)(MyFact/2);
|
|
src.bottom+=(int)(MyFact/2);
|
|
src.left+=(int)(MyFact/2);
|
|
src.right+=(int)(MyFact/2);
|
|
|
|
ddx=dst.right-dst.left;
|
|
ddy=dst.bottom-dst.top;
|
|
xd=src.right-src.left;
|
|
yd=src.bottom-src.top;
|
|
|
|
dst.right-=xpos;
|
|
dst.left-=xpos;
|
|
dst.bottom-=ypos;
|
|
dst.top-=ypos;
|
|
|
|
|
|
if(src.left>=(img.xpos+img.xlen) || src.top>=(img.ypos+img.ylen) ||
|
|
src.right<=img.xpos || src.bottom<img.ypos ) return;
|
|
|
|
|
|
//left clip
|
|
if(src.left<=img.xpos) //fix source move dest.
|
|
{ dst.left+=(img.xpos-src.left)*ddx/xd; src.left=0;}
|
|
else //fix destination move source
|
|
src.left-=img.xpos;
|
|
|
|
if(src.top<=img.ypos) //fix source move dest.
|
|
{ dst.top+=(img.ypos-src.top)*ddy/yd; src.top=0; }
|
|
else //fix destination move source
|
|
src.top-=img.ypos;
|
|
|
|
//right clip
|
|
|
|
if(src.right>(img.xpos+img.xlen))
|
|
{
|
|
dst.right-=(src.right-(img.xpos+img.xlen))*ddx/xd;
|
|
src.right=img.xlen;
|
|
}
|
|
else
|
|
src.right=img.xlen-((img.xlen+img.xpos)-src.right);
|
|
|
|
if(src.bottom>(img.ypos+img.ylen))
|
|
{
|
|
dst.bottom-=(src.bottom-(img.ypos+img.ylen))*ddy/yd;
|
|
src.bottom=img.ylen;
|
|
}
|
|
else
|
|
src.bottom=img.ylen-((img.ylen+img.ypos)-src.bottom);
|
|
|
|
|
|
if(dst.left<0) { src.left-=dst.left*img.xlen/ddx; dst.left=0; }
|
|
if(dst.top<0) { src.top-=dst.top*img.ylen/ddy; dst.top=0; }
|
|
|
|
|
|
if(dst.right>xlen) { src.right=src.left+(xlen-dst.left)*xd/ddx; dr=xlen;}
|
|
else {dr=dst.right; }
|
|
|
|
if(dst.bottom>ylen){ src.bottom=src.top+(ylen-dst.top)*yd/ddy; db=ylen; }
|
|
else {db=dst.bottom; }
|
|
|
|
dst.right=dr;
|
|
dst.bottom=db;
|
|
|
|
|
|
if(src.right<=0 || src.bottom<=0 ||
|
|
src.left>=img.xlen || src.top>=img.ylen) return;
|
|
|
|
//ret=Surface->Blt(&dst,img.Surface,&src,flag,&bfx);
|
|
|
|
BYTE *dptS=img.Lock(),*dptD=Lock();
|
|
|
|
if((dst.right-dst.left)<=(src.right-src.left)) //Downsample X
|
|
{
|
|
if((dst.bottom-dst.top)<=(src.bottom-src.top)) //Downsample Y
|
|
{
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int x,y;
|
|
float prx=(float)(src.right-src.left)/(2*(dst.right-dst.left));
|
|
float pry=(float)(src.bottom-src.top)/(2*(dst.bottom-dst.top));
|
|
float csx,csy;
|
|
ImgRGBColor col,colsum;
|
|
RGBPixel *tptr;
|
|
|
|
ImageOperator Opt;
|
|
|
|
Opt.CreateGaussian((int)(pry*2),(int)(prx*2));
|
|
int r,c,cpx,cpy,idx;
|
|
float fr,fg,fb,fa,sum,w;
|
|
BYTE *tdp;
|
|
int rs,re,cs,ce;
|
|
re=Opt.GetRows()>>1;
|
|
rs=-re;
|
|
ce=Opt.GetCols()>>1;
|
|
cs=-ce;
|
|
|
|
|
|
|
|
for(csy=(float)src.top,y=dst.top;y<dst.bottom;y++,csy+=pry*2)
|
|
for(csx=(float)src.left,x=dst.left;x<dst.right;x++,csx+=prx*2)
|
|
{
|
|
|
|
cpx=(int)Round(csx+cs);
|
|
cpy=(int)Round(csy+rs);
|
|
tdp=dptS+(cpx+cpy*img.xlen)*psizeS;
|
|
fr=fg=fb=fa=sum=0.0f;
|
|
for(r=rs;r<=re;r++,tdp+=img.Pitch)
|
|
for(idx=0,c=cs;c<=ce;c++,idx+=psizeS)
|
|
{
|
|
|
|
cpx=(int)(csx+c); cpy=(int)(csy+r);
|
|
if(cpx>=0 && cpy>=0 && cpx<img.xlen && cpy<img.ylen)
|
|
{
|
|
tptr=(RGBPixel *)(tdp+idx);
|
|
col.Set(*tptr,img.Mask);
|
|
w=Opt.GetWeight(r+re,c+ce);
|
|
fr+=col.r*w;
|
|
fg+=col.g*w;
|
|
fb+=col.b*w;
|
|
fa+=col.a*w;
|
|
sum+=w;
|
|
}
|
|
}
|
|
fr/=sum; fg/=sum; fb/=sum; fa/=sum;
|
|
colsum.r=(int)floor(fr+0.05f);
|
|
colsum.g=(int)floor(fg+0.05f);
|
|
colsum.b=(int)floor(fb+0.05f);
|
|
colsum.a=(int)floor(fa+0.05f);
|
|
|
|
tptr=(RGBPixel *)(dptD+((int)x+((int)y)*xlen)*psizeD);
|
|
tptr->Set(colsum,Mask);
|
|
}
|
|
|
|
}
|
|
else //UpSample Y
|
|
{
|
|
GENFERR("Upsampling not supported(yet)");
|
|
}
|
|
|
|
}
|
|
else //UpSample X
|
|
{
|
|
if((dst.bottom-dst.top)<=(src.bottom-src.top)) //Downsample Y
|
|
{
|
|
GENFERR("Upsampling not supported(yet)");
|
|
}
|
|
else //UpSample Y
|
|
{
|
|
GENFERR("Upsampling not supported(yet)");
|
|
}
|
|
}
|
|
|
|
UnLock();
|
|
img.UnLock();
|
|
|
|
|
|
}
|
|
*/
|
|
|
|
|
|
void Image::Blt(Image &img,RECT dst,RECT &src)
|
|
{
|
|
int dr,db;
|
|
int xd,yd;
|
|
int ddx,ddy;
|
|
ddx=dst.right-dst.left;
|
|
ddy=dst.bottom-dst.top;
|
|
xd=src.right-src.left;
|
|
yd=src.bottom-src.top;
|
|
|
|
dst.right-=xpos;
|
|
dst.left-=xpos;
|
|
dst.bottom-=ypos;
|
|
dst.top-=ypos;
|
|
|
|
|
|
if(src.left>=(img.xpos+img.xlen) || src.top>=(img.ypos+img.ylen) ||
|
|
src.right<=img.xpos || src.bottom<img.ypos ) return;
|
|
|
|
|
|
//left clip
|
|
if(src.left<=img.xpos) //fix source move dest.
|
|
{ dst.left+=(img.xpos-src.left)*ddx/xd; src.left=0;}
|
|
else //fix destination move source
|
|
src.left-=img.xpos;
|
|
|
|
if(src.top<=img.ypos) //fix source move dest.
|
|
{ dst.top+=(img.ypos-src.top)*ddy/yd; src.top=0; }
|
|
else //fix destination move source
|
|
src.top-=img.ypos;
|
|
|
|
//right clip
|
|
|
|
if(src.right>(img.xpos+img.xlen))
|
|
{
|
|
dst.right-=(src.right-(img.xpos+img.xlen))*ddx/xd;
|
|
src.right=img.xlen;
|
|
}
|
|
else
|
|
src.right=img.xlen-((img.xlen+img.xpos)-src.right);
|
|
|
|
if(src.bottom>(img.ypos+img.ylen))
|
|
{
|
|
dst.bottom-=(src.bottom-(img.ypos+img.ylen))*ddy/yd;
|
|
src.bottom=img.ylen;
|
|
}
|
|
else
|
|
src.bottom=img.ylen-((img.ylen+img.ypos)-src.bottom);
|
|
|
|
|
|
if(dst.left<0) { src.left-=dst.left*img.xlen/ddx; dst.left=0; }
|
|
if(dst.top<0) { src.top-=dst.top*img.ylen/ddy; dst.top=0; }
|
|
|
|
|
|
if(dst.right>xlen) { src.right=src.left+(xlen-dst.left)*xd/ddx; dr=xlen;}
|
|
else {dr=dst.right; }
|
|
|
|
if(dst.bottom>ylen){ src.bottom=src.top+(ylen-dst.top)*yd/ddy; db=ylen; }
|
|
else {db=dst.bottom; }
|
|
|
|
dst.right=dr;
|
|
dst.bottom=db;
|
|
|
|
|
|
if(src.right<=0 || src.bottom<=0 ||
|
|
src.left>=img.xlen || src.top>=img.ylen) return;
|
|
|
|
//ret=Surface->Blt(&dst,img.Surface,&src,flag,&bfx);
|
|
|
|
|
|
enum STYPE {ST_DOWN,ST_UP,ST_COPY};
|
|
STYPE xdec,ydec;
|
|
|
|
if((dst.right-dst.left)==(src.right-src.left))
|
|
xdec=ST_COPY;
|
|
else
|
|
if((dst.right-dst.left)<(src.right-src.left))
|
|
xdec=ST_DOWN;
|
|
else
|
|
xdec=ST_UP;
|
|
|
|
if((dst.bottom-dst.top)==(src.bottom-src.top))
|
|
ydec=ST_COPY;
|
|
else
|
|
if((dst.bottom-dst.top)<(src.bottom-src.top))
|
|
ydec=ST_DOWN;
|
|
else
|
|
ydec=ST_UP;
|
|
|
|
BYTE *dptS=img.Lock(),*dptD=Lock();
|
|
bool fastcopy;
|
|
|
|
if(Bpp==img.Bpp && Mask==img.Mask) fastcopy=true; else fastcopy=false;
|
|
|
|
if(xdec==ST_COPY && ydec==ST_COPY)
|
|
{//Pure Copy
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int sp=img.GetPitch()-(src.right-src.left)*psizeS,dp=GetPitch()-(dst.right-dst.left)*psizeD;
|
|
int x,y;
|
|
ImgRGBColor col;
|
|
RGBPixel *tptr;
|
|
BYTE *tdptS=dptS+(src.left+src.top*img.GetWidth())*psizeS,*tdptD=dptD+(dst.left+dst.top*GetWidth())*psizeD;
|
|
|
|
|
|
if(fastcopy)
|
|
{
|
|
int scanllen=(dst.right-dst.left)*psizeD;
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=img.GetPitch(), tdptD+=GetPitch())
|
|
CopyMemory(tdptD,tdptS,scanllen);
|
|
}
|
|
else
|
|
|
|
|
|
{
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=sp,tdptD+=dp)
|
|
for(x=dst.left;x<dst.right;x++,tdptS+=psizeS,tdptD+=psizeD)
|
|
{
|
|
tptr=(RGBPixel *)(tdptS);
|
|
col.Set(*tptr,img.Mask);
|
|
tptr=(RGBPixel *)(tdptD);
|
|
tptr->Set(col,Mask);
|
|
}
|
|
}
|
|
}
|
|
|
|
if((xdec==ST_DOWN && ydec==ST_DOWN) ||
|
|
(xdec==ST_DOWN && ydec==ST_COPY) ||
|
|
(xdec==ST_COPY && ydec==ST_DOWN))
|
|
{
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int x,y;
|
|
float prx=(float)(src.right-src.left)/(2*(dst.right-dst.left));
|
|
float pry=(float)(src.bottom-src.top)/(2*(dst.bottom-dst.top));
|
|
float csx,csy,xslp,yslp;
|
|
int coldiv;
|
|
ImgRGBColor col,colsum;
|
|
RGBPixel *tptr;
|
|
int ixslp,iyslp;
|
|
|
|
for(csy=(float)src.top+pry,y=dst.top;y<dst.bottom;y++,csy+=pry*2)
|
|
for(csx=(float)src.left+prx,x=dst.left;x<dst.right;x++,csx+=prx*2)
|
|
{
|
|
colsum.r=colsum.g=colsum.b=colsum.a=0;
|
|
coldiv=0;
|
|
for(yslp=csy-pry;yslp<csy+pry;yslp+=1.0f)
|
|
for(xslp=csx-prx;xslp<csx+prx;xslp+=1.0f)
|
|
{
|
|
ixslp=(int)xslp;
|
|
iyslp=(int)yslp;
|
|
if(ixslp>=0 && iyslp>=0 && ixslp<img.xlen && iyslp<img.ylen)
|
|
{
|
|
tptr=(RGBPixel *)(dptS+(ixslp+iyslp*img.xlen)*psizeS);
|
|
col.Set(*tptr,img.Mask);
|
|
colsum.r+=col.r;
|
|
colsum.g+=col.g;
|
|
colsum.b+=col.b;
|
|
colsum.a+=col.a;
|
|
coldiv++;
|
|
}
|
|
}
|
|
|
|
if(coldiv==0) coldiv=1;
|
|
colsum.r/=coldiv;
|
|
colsum.g/=coldiv;
|
|
colsum.b/=coldiv;
|
|
colsum.a/=coldiv;
|
|
tptr=(RGBPixel *)(dptD+((int)x+((int)y)*xlen)*psizeD);
|
|
tptr->Set(colsum,Mask);
|
|
}
|
|
}
|
|
|
|
if((xdec==ST_UP && ydec==ST_UP) ||
|
|
(xdec==ST_UP && ydec==ST_COPY) ||
|
|
(xdec==ST_COPY && ydec==ST_UP))
|
|
{
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int x,y;
|
|
float prx=(float)(src.right-src.left)/(dst.right-dst.left);
|
|
float pry=(float)(src.bottom-src.top)/(dst.bottom-dst.top);
|
|
float yacc,xacc;
|
|
ImgRGBColor lhcol,nhcol,lvcol,nvcol,col;
|
|
RGBPixel *tptr;
|
|
int ixacc,iyacc;
|
|
yacc=0.0f;
|
|
for(y=dst.top;y<dst.bottom;y++)
|
|
{
|
|
xacc=0.0f;
|
|
iyacc=(int)yacc;
|
|
for(x=dst.left;x<dst.right;x++)
|
|
{
|
|
ixacc=(int)xacc;
|
|
tptr=(RGBPixel *)(dptS+(ixacc+iyacc*img.xlen)*psizeS);
|
|
col.Set(*tptr,img.Mask);
|
|
|
|
tptr=(RGBPixel *)(dptD+(x+y*xlen)*psizeD);
|
|
tptr->Set(col,Mask);
|
|
|
|
xacc+=prx;
|
|
}
|
|
yacc+=pry;
|
|
}
|
|
|
|
}
|
|
|
|
if((xdec==ST_DOWN && ydec==ST_UP) ||
|
|
(xdec==ST_UP && ydec==ST_DOWN) )
|
|
{
|
|
Image tmpim;
|
|
RECT tmpdrct;
|
|
tmpdrct.left=tmpdrct.top=0;
|
|
tmpdrct.right=dst.right-dst.left;
|
|
tmpdrct.bottom=src.bottom-src.top;
|
|
tmpim.CreateBlank(tmpdrct.right,tmpdrct.bottom,itype,Bpp);
|
|
tmpim.Blt(img,tmpdrct,src);
|
|
Blt(tmpim,dst,tmpdrct);
|
|
}
|
|
|
|
UnLock();
|
|
img.UnLock();
|
|
|
|
|
|
}
|
|
|
|
|
|
void Image::Blt(Image &img,int x,int y,RECT &src)
|
|
{
|
|
|
|
int xd,yd;
|
|
xd=src.right-src.left;
|
|
yd=src.bottom-src.top;
|
|
|
|
x+=img.xpos-xpos;
|
|
y+=img.ypos-ypos;
|
|
|
|
if((x+xd)>xlen) src.right-=(x+xd)-xlen;
|
|
if((y+yd)>ylen) src.bottom-=(y+yd)-ylen;
|
|
|
|
if(x<0) {src.left-=x; x=0;}
|
|
if(y<0) {src.top-=y; y=0;}
|
|
|
|
if(src.right<=0 || src.bottom<=0 ||
|
|
src.left>=img.xlen || src.top>=img.ylen) return;
|
|
|
|
|
|
RECT dst={x,y,x+img.xlen,y+img.ylen};
|
|
|
|
if(dst.bottom>ylen) dst.bottom=ylen;
|
|
if(dst.right>xlen) dst.right=xlen;
|
|
|
|
//ret=Surface->Blt(&dst,img.Surface,NULL,flag,&bfx);
|
|
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int xc,yc,axlS=img.Pitch,axlD=Pitch;
|
|
RGBPixel *tptr;
|
|
ImgRGBColor col;
|
|
|
|
BYTE *dptS=img.Lock(),*dptD=Lock();
|
|
int SVoff,DVoff;
|
|
int SHoff,DHoff;
|
|
|
|
for(SVoff=src.top*axlS,DVoff=dst.top*axlD,yc=dst.top;
|
|
yc<dst.bottom;
|
|
yc++,SVoff+=axlS,DVoff+=axlD)
|
|
for(SHoff=src.left*psizeS,DHoff=dst.left*psizeD,xc=dst.left;
|
|
xc<dst.right;
|
|
xc++,SHoff+=psizeS,DHoff+=psizeD)
|
|
{
|
|
tptr=(RGBPixel *)(dptS+SHoff+SVoff);
|
|
col.Set(*tptr,Mask);
|
|
tptr=(RGBPixel *)(dptD+DHoff+DVoff);
|
|
tptr->Set(col,img.Mask);
|
|
}
|
|
|
|
UnLock();
|
|
img.UnLock();
|
|
|
|
}
|
|
|
|
void Image::MeanBlur(int xs,int ys)
|
|
{
|
|
ImageOperator Fil;
|
|
Fil.CreateMean(xs,ys);
|
|
ApplyOperator(Fil);
|
|
}
|
|
|
|
void Image::GaussianBlur(float pix)
|
|
{
|
|
ImageOperator Fil;
|
|
Fil.CreateGaussian(pix);
|
|
ApplyOperator(Fil);
|
|
}
|
|
|
|
void Image::ApplyOperator(ImageOperator &Opt)
|
|
{
|
|
if(itype!=ITYPE_RGB)
|
|
GENNFERR("(ApplyOperator)Image is not RGB");
|
|
|
|
Image tmpimg;
|
|
tmpimg.CreateBlank(xlen,ylen,itype,Bpp);
|
|
tmpimg.Mask=Mask;
|
|
|
|
int x,y,r,c,cpx,cpy;
|
|
float fr,fg,fb,fa,sum,w;
|
|
int rs,re,cs,ce,psize=Bpp>>3;
|
|
re=Opt.GetRows()>>1;
|
|
rs=-re;
|
|
ce=Opt.GetCols()>>1;
|
|
cs=-ce;
|
|
|
|
BYTE *dpt=Lock();
|
|
BYTE *dd=tmpimg.Lock();
|
|
|
|
|
|
RGBPixel *tptr;
|
|
ImgRGBColor col;
|
|
|
|
int idx;
|
|
|
|
BYTE *tdp;
|
|
|
|
for(y=0;y<ylen;y++)
|
|
for(x=0;x<xlen;x++)
|
|
{
|
|
tdp=(BYTE *)(dpt+((x+cs)+(y+rs)*xlen)*psize);
|
|
sum=fr=fg=fb=fa=0.0f; //Zero out Accumulators
|
|
BYTE *tdp=(BYTE *)(dpt+((x+cs)+(y+rs)*xlen)*psize);
|
|
|
|
if( (x+cs)<0 || (x+ce)>=xlen ||
|
|
(y+rs)<0 || (y+re)>=ylen ) //This is an edge
|
|
{
|
|
|
|
for(r=rs;r<=re;r++,tdp+=Pitch)
|
|
for(idx=0,c=cs;c<=ce;c++,idx+=psize)
|
|
{
|
|
cpx=x+c; cpy=y+r;
|
|
if(cpx>=0 && cpy>=0 && cpx<xlen && cpy<ylen)
|
|
{
|
|
tptr=(RGBPixel *)(tdp+idx);
|
|
col.Set(*tptr,Mask);
|
|
w=Opt.GetWeight(r+re,c+ce);
|
|
fr+=col.r*w;
|
|
fg+=col.g*w;
|
|
fb+=col.b*w;
|
|
fa+=col.a*w;
|
|
sum+=w;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
for(r=rs;r<=re;r++,tdp+=Pitch)
|
|
for(idx=0,c=cs;c<=ce;c++,idx+=psize)
|
|
{
|
|
tptr=(RGBPixel *)(tdp+idx);
|
|
col.Set(*tptr,Mask);
|
|
w=Opt.GetWeight(r+re,c+ce);
|
|
fr+=col.r*w;
|
|
fg+=col.g*w;
|
|
fb+=col.b*w;
|
|
fa+=col.a*w;
|
|
}
|
|
sum=Opt.GetTotal();
|
|
}
|
|
|
|
fr/=sum; fg/=sum; fb/=sum; fa/=sum;
|
|
col.r=(int)floor(fr+0.5f);
|
|
col.g=(int)floor(fg+0.5f);
|
|
col.b=(int)floor(fb+0.5f);
|
|
col.a=(int)floor(fa+0.5f);
|
|
tptr=(RGBPixel *)(dd);
|
|
tptr->Set(col,tmpimg.Mask);
|
|
dd+=psize;
|
|
}
|
|
|
|
tmpimg.UnLock();
|
|
UnLock();
|
|
*this=tmpimg;
|
|
}
|
|
|
|
void Image::BltBlend(Image &img,float efact,RECT &src,float tfact,float rfact,float bfact,float lfact)
|
|
{
|
|
RECT dst;
|
|
dst.top=dst.left=0;
|
|
dst.right=GetWidth();
|
|
dst.bottom=GetHeight();
|
|
|
|
|
|
float MyFact;
|
|
MyFact=((float)(src.right-src.left))/(dst.right-dst.left);
|
|
if(tfact<MyFact) tfact=MyFact;
|
|
if(bfact<MyFact) bfact=MyFact;
|
|
if(rfact<MyFact) rfact=MyFact;
|
|
if(lfact<MyFact) lfact=MyFact;
|
|
|
|
src.top+=(int)(MyFact/2);
|
|
src.bottom+=(int)(MyFact/2);
|
|
src.left+=(int)(MyFact/2);
|
|
src.right+=(int)(MyFact/2);
|
|
|
|
/*
|
|
int dr,db;
|
|
int xd,yd;
|
|
int ddx,ddy;
|
|
ddx=dst.right-dst.left;
|
|
ddy=dst.bottom-dst.top;
|
|
xd=src.right-src.left;
|
|
yd=src.bottom-src.top;
|
|
|
|
dst.right-=xpos;
|
|
dst.left-=xpos;
|
|
dst.bottom-=ypos;
|
|
dst.top-=ypos;
|
|
|
|
|
|
|
|
if(src.left>=(img.xpos+img.xlen) || src.top>=(img.ypos+img.ylen) ||
|
|
src.right<=img.xpos || src.bottom<img.ypos ) return;
|
|
|
|
|
|
//left clip
|
|
if(src.left<=img.xpos) //fix source move dest.
|
|
{ dst.left+=(img.xpos-src.left)*ddx/xd; src.left=0;}
|
|
else //fix destination move source
|
|
src.left-=img.xpos;
|
|
|
|
if(src.top<=img.ypos) //fix source move dest.
|
|
{ dst.top+=(img.ypos-src.top)*ddy/yd; src.top=0; }
|
|
else //fix destination move source
|
|
src.top-=img.ypos;
|
|
|
|
//right clip
|
|
|
|
if(src.right>(img.xpos+img.xlen+1))
|
|
{
|
|
dst.right-=(src.right-(img.xpos+img.xlen))*ddx/xd;
|
|
src.right=img.xlen;
|
|
}
|
|
else
|
|
src.right=img.xlen-((img.xlen+img.xpos)-src.right);
|
|
|
|
if(src.bottom>(img.ypos+img.ylen+1))
|
|
{
|
|
dst.bottom-=(src.bottom-(img.ypos+img.ylen))*ddy/yd;
|
|
src.bottom=img.ylen;
|
|
}
|
|
else
|
|
src.bottom=img.ylen-((img.ylen+img.ypos)-src.bottom);
|
|
|
|
|
|
if(dst.left<0) { src.left-=dst.left*img.xlen/ddx; dst.left=0; }
|
|
if(dst.top<0) { src.top-=dst.top*img.ylen/ddy; dst.top=0; }
|
|
|
|
|
|
if(dst.right>xlen) { src.right=src.left+(xlen-dst.left)*xd/ddx; dr=xlen;}
|
|
else {dr=dst.right; }
|
|
|
|
if(dst.bottom>ylen){ src.bottom=src.top+(ylen-dst.top)*yd/ddy; db=ylen; }
|
|
else {db=dst.bottom; }
|
|
|
|
dst.right=dr;
|
|
dst.bottom=db;
|
|
|
|
|
|
if(src.right<=0 || src.bottom<=0 ||
|
|
src.left>=img.xlen || src.top>=img.ylen) return;
|
|
|
|
//ret=Surface->Blt(&dst,img.Surface,&src,flag,&bfx);
|
|
*/
|
|
|
|
BYTE *dptS=img.Lock(),*dptD=Lock();
|
|
|
|
if((dst.right-dst.left)<=(src.right-src.left)) //Downsample X
|
|
{
|
|
if((dst.bottom-dst.top)<=(src.bottom-src.top)) //Downsample Y
|
|
{
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int x,y;
|
|
float prx=(float)(src.right-src.left)/(2*(dst.right-dst.left));
|
|
float pry=(float)(src.bottom-src.top)/(2*(dst.bottom-dst.top));
|
|
float csx,csy;
|
|
ImgRGBColor col,colsum;
|
|
RGBPixel *tptr;
|
|
|
|
ImageOperator Opt;
|
|
|
|
int r,c,cpx,cpy,idx;
|
|
float fr,fg,fb,fa,sum,w;
|
|
float CurFact;
|
|
BYTE *tdp;
|
|
|
|
int rs,re,cs,ce;
|
|
|
|
Opt.CreateGaussian((int)MyFact,(int)MyFact);
|
|
re=Opt.GetRows()>>1;
|
|
rs=-re;
|
|
ce=Opt.GetCols()>>1;
|
|
cs=-ce;
|
|
|
|
float tr,br,lr,rr,mr;
|
|
float invefact=1/efact;
|
|
|
|
for(csy=(float)src.top,y=dst.top;y<dst.bottom;y++,csy+=pry*2)
|
|
for(csx=(float)src.left,x=dst.left;x<dst.right;x++,csx+=prx*2)
|
|
{
|
|
|
|
tr=1.0f-((float)(y*invefact)/(ylen));
|
|
if(tr<0) tr=0.0f;
|
|
br=((float)(( (y+1) - (ylen-(ylen*efact)) )*invefact)/(ylen));
|
|
if(br<0) br=0.0f;
|
|
lr=1.0f-((float)(x*invefact)/(xlen));
|
|
if(lr<0) lr=0.0f;
|
|
rr=((float)(( (x+1) - (xlen-(xlen*efact)) )*invefact)/(xlen));
|
|
if(rr<0) rr=0.0f;
|
|
mr=1.0f-(tr+br+lr+rr);
|
|
if(mr<0) mr=0.0f;
|
|
|
|
CurFact=MyFact;
|
|
CurFact=(tfact*tr)>CurFact?tfact*tr:CurFact;
|
|
CurFact=(bfact*br)>CurFact?bfact*br:CurFact;
|
|
CurFact=(lfact*lr)>CurFact?lfact*lr:CurFact;
|
|
CurFact=(rfact*rr)>CurFact?rfact*rr:CurFact;
|
|
|
|
/*
|
|
CurFact=
|
|
(MyFact*mr+
|
|
tfact*tr+
|
|
bfact*br+
|
|
lfact*lr+
|
|
rfact*rr)/( tr+br+lr+rr+mr );
|
|
*/
|
|
CurFact=(float)floor(CurFact+0.5f);
|
|
|
|
Opt.CreateGaussian((int)CurFact,(int)CurFact);
|
|
re=Opt.GetRows()>>1;
|
|
rs=-re;
|
|
ce=Opt.GetCols()>>1;
|
|
cs=-ce;
|
|
|
|
cpx=(int)Round(csx+cs);
|
|
cpy=(int)Round(csy+rs);
|
|
tdp=dptS+(cpx+cpy*img.xlen)*psizeS;
|
|
fr=fg=fb=fa=sum=0.0f;
|
|
for(r=rs;r<=re;r++,tdp+=img.Pitch)
|
|
for(idx=0,c=cs;c<=ce;c++,idx+=psizeS)
|
|
{
|
|
cpx=(int)(csx+c); cpy=(int)(csy+r);
|
|
// cpx=(int)Round(csx+c); cpy=(int)Round(csy+r);
|
|
if(cpx>=0 && cpy>=0 && cpx<img.xlen && cpy<img.ylen)
|
|
{
|
|
tptr=(RGBPixel *)(tdp+idx);
|
|
col.Set(*tptr,img.Mask);
|
|
w=Opt.GetWeight(r+re,c+ce);
|
|
fr+=col.r*w;
|
|
fg+=col.g*w;
|
|
fb+=col.b*w;
|
|
fa+=col.a*w;
|
|
sum+=w;
|
|
}
|
|
}
|
|
fr/=sum; fg/=sum; fb/=sum; fa/=sum;
|
|
colsum.r=(int)Round(fr);
|
|
colsum.g=(int)Round(fg);
|
|
colsum.b=(int)Round(fb);
|
|
colsum.a=(int)Round(fa);
|
|
|
|
tptr=(RGBPixel *)(dptD+(x+y*xlen)*psizeD);
|
|
tptr->Set(colsum,Mask);
|
|
}
|
|
|
|
}
|
|
else //UpSample Y
|
|
{
|
|
GENFERR("Upsampling not supported(yet)");
|
|
}
|
|
}
|
|
else //UpSample X
|
|
{
|
|
if((dst.bottom-dst.top)<=(src.bottom-src.top)) //Downsample Y
|
|
{
|
|
GENFERR("Upsampling not supported(yet)");
|
|
}
|
|
else //UpSample Y
|
|
{
|
|
GENFERR("Upsampling not supported(yet)");
|
|
}
|
|
}
|
|
|
|
UnLock();
|
|
img.UnLock();
|
|
|
|
|
|
|
|
}
|
|
|
|
//
|
|
// Added by SMJ on 6/4/99
|
|
//
|
|
void Image::Rotate180()
|
|
{
|
|
int pixelSize = Bpp / 8;
|
|
int dataSize = Pitch * ylen;
|
|
BYTE* back = Data + dataSize - pixelSize;
|
|
BYTE* newData = new BYTE [dataSize];
|
|
BYTE* front = newData;
|
|
|
|
while (back > Data)
|
|
{
|
|
memcpy(front,back,pixelSize);
|
|
|
|
front += pixelSize;
|
|
back -= pixelSize;
|
|
}
|
|
|
|
delete Data;
|
|
Data = newData;
|
|
}
|
|
|
|
void Image::BltDominantColor(Image &img,RECT dst,RECT &src)
|
|
{
|
|
int dr,db;
|
|
int xd,yd;
|
|
int ddx,ddy;
|
|
ddx=dst.right-dst.left;
|
|
ddy=dst.bottom-dst.top;
|
|
xd=src.right-src.left;
|
|
yd=src.bottom-src.top;
|
|
|
|
dst.right-=xpos;
|
|
dst.left-=xpos;
|
|
dst.bottom-=ypos;
|
|
dst.top-=ypos;
|
|
|
|
|
|
if(src.left>=(img.xpos+img.xlen) || src.top>=(img.ypos+img.ylen) ||
|
|
src.right<=img.xpos || src.bottom<img.ypos ) return;
|
|
|
|
|
|
//left clip
|
|
if(src.left<=img.xpos) //fix source move dest.
|
|
{ dst.left+=(img.xpos-src.left)*ddx/xd; src.left=0;}
|
|
else //fix destination move source
|
|
src.left-=img.xpos;
|
|
|
|
if(src.top<=img.ypos) //fix source move dest.
|
|
{ dst.top+=(img.ypos-src.top)*ddy/yd; src.top=0; }
|
|
else //fix destination move source
|
|
src.top-=img.ypos;
|
|
|
|
//right clip
|
|
|
|
if(src.right>(img.xpos+img.xlen))
|
|
{
|
|
dst.right-=(src.right-(img.xpos+img.xlen))*ddx/xd;
|
|
src.right=img.xlen;
|
|
}
|
|
else
|
|
src.right=img.xlen-((img.xlen+img.xpos)-src.right);
|
|
|
|
if(src.bottom>(img.ypos+img.ylen))
|
|
{
|
|
dst.bottom-=(src.bottom-(img.ypos+img.ylen))*ddy/yd;
|
|
src.bottom=img.ylen;
|
|
}
|
|
else
|
|
src.bottom=img.ylen-((img.ylen+img.ypos)-src.bottom);
|
|
|
|
|
|
if(dst.left<0) { src.left-=dst.left*img.xlen/ddx; dst.left=0; }
|
|
if(dst.top<0) { src.top-=dst.top*img.ylen/ddy; dst.top=0; }
|
|
|
|
|
|
if(dst.right>xlen) { src.right=src.left+(xlen-dst.left)*xd/ddx; dr=xlen;}
|
|
else {dr=dst.right; }
|
|
|
|
if(dst.bottom>ylen){ src.bottom=src.top+(ylen-dst.top)*yd/ddy; db=ylen; }
|
|
else {db=dst.bottom; }
|
|
|
|
dst.right=dr;
|
|
dst.bottom=db;
|
|
|
|
|
|
if(src.right<=0 || src.bottom<=0 ||
|
|
src.left>=img.xlen || src.top>=img.ylen) return;
|
|
|
|
//ret=Surface->Blt(&dst,img.Surface,&src,flag,&bfx);
|
|
|
|
|
|
enum STYPE {ST_DOWN,ST_UP,ST_COPY};
|
|
STYPE xdec,ydec;
|
|
|
|
if((dst.right-dst.left)==(src.right-src.left))
|
|
xdec=ST_COPY;
|
|
else
|
|
if((dst.right-dst.left)<(src.right-src.left))
|
|
xdec=ST_DOWN;
|
|
else
|
|
xdec=ST_UP;
|
|
|
|
if((dst.bottom-dst.top)==(src.bottom-src.top))
|
|
ydec=ST_COPY;
|
|
else
|
|
if((dst.bottom-dst.top)<(src.bottom-src.top))
|
|
ydec=ST_DOWN;
|
|
else
|
|
ydec=ST_UP;
|
|
|
|
if(ydec==ST_UP || xdec==ST_UP )
|
|
STOP(("Upsampling Not Supported"));
|
|
|
|
BYTE *dptS=img.Lock(),*dptD=Lock();
|
|
bool fastcopy;
|
|
|
|
if(Bpp==img.Bpp && Mask==img.Mask) fastcopy=true; else fastcopy=false;
|
|
|
|
if(xdec==ST_COPY && ydec==ST_COPY)
|
|
{//Pure Copy
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int sp=img.GetPitch()-(src.right-src.left)*psizeS,dp=GetPitch()-(dst.right-dst.left)*psizeD;
|
|
int x,y;
|
|
ImgRGBColor col;
|
|
RGBPixel *tptr;
|
|
BYTE *tdptS=dptS+(src.left+src.top*img.GetWidth())*psizeS,*tdptD=dptD+(dst.left+dst.top*GetWidth())*psizeD;
|
|
|
|
|
|
if(fastcopy)
|
|
{
|
|
int scanllen=(dst.right-dst.left)*psizeD;
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=img.GetPitch(), tdptD+=GetPitch())
|
|
CopyMemory(tdptD,tdptS,scanllen);
|
|
}
|
|
else
|
|
|
|
|
|
{
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=sp,tdptD+=dp)
|
|
for(x=dst.left;x<dst.right;x++,tdptS+=psizeS,tdptD+=psizeD)
|
|
{
|
|
tptr=(RGBPixel *)(tdptS);
|
|
col.Set(*tptr,img.Mask);
|
|
tptr=(RGBPixel *)(tdptD);
|
|
tptr->Set(col,Mask);
|
|
}
|
|
}
|
|
}
|
|
|
|
if((xdec==ST_DOWN && ydec==ST_DOWN) ||
|
|
(xdec==ST_DOWN && ydec==ST_COPY) ||
|
|
(xdec==ST_COPY && ydec==ST_DOWN))
|
|
{
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int x,y;
|
|
float prx=(float)(src.right-src.left)/(2*(dst.right-dst.left));
|
|
float pry=(float)(src.bottom-src.top)/(2*(dst.bottom-dst.top));
|
|
float csx,csy,xslp,yslp;
|
|
int colmax,idx;
|
|
ImgRGBColor col;
|
|
RGBPixel *tptr;
|
|
colmax=(int)ceil(prx*2)*(int)ceil(pry*2);
|
|
int *ColorCount=new int[colmax];
|
|
ImgRGBColor *ColorList=new ImgRGBColor[colmax];
|
|
int colortotal;
|
|
|
|
for(csy=(float)src.top+pry,y=dst.top;y<dst.bottom;y++,csy+=pry*2)
|
|
for(csx=(float)src.left+prx,x=dst.left;x<dst.right;x++,csx+=prx*2)
|
|
{
|
|
colortotal=0;
|
|
|
|
for(yslp=csy-pry;yslp<csy+pry;yslp+=1.0f)
|
|
for(xslp=csx-prx;xslp<csx+prx;xslp+=1.0f)
|
|
if(((int)xslp)>=0 && ((int)yslp)>=0 && ((int)xslp)<img.xlen && ((int)yslp)<img.ylen)
|
|
{
|
|
tptr=(RGBPixel *)(dptS+((int)xslp+((int)yslp)*img.xlen)*psizeS);
|
|
col.Set(*tptr,img.Mask);
|
|
for(idx=0;idx<colortotal && ColorList[idx]!=col;idx++);
|
|
|
|
if(idx<colortotal)
|
|
{
|
|
ColorCount[idx]++;
|
|
}
|
|
else
|
|
{
|
|
ColorCount[colortotal]=1;
|
|
ColorList[colortotal]=col;
|
|
colortotal++;
|
|
}
|
|
|
|
}
|
|
|
|
int maxnum,maxval;
|
|
|
|
maxval=0;
|
|
|
|
for(idx=0;idx<colortotal;idx++)
|
|
{
|
|
if(ColorCount[idx]>maxval)
|
|
{
|
|
maxnum=idx;
|
|
maxval=ColorCount[idx];
|
|
}
|
|
}
|
|
|
|
|
|
tptr=(RGBPixel *)(dptD+((int)x+((int)y)*xlen)*psizeD);
|
|
tptr->Set(ColorList[maxnum],Mask);
|
|
}
|
|
|
|
delete ColorCount;
|
|
delete ColorList;
|
|
|
|
}
|
|
|
|
|
|
UnLock();
|
|
img.UnLock();
|
|
}
|
|
|
|
// Image Operator
|
|
|
|
void ImageOperator::Create(int sr,int sc)
|
|
{
|
|
Destroy();
|
|
|
|
|
|
Rows=sr;
|
|
Cols=sc;
|
|
|
|
Rows|=1; Cols|=1; //Always make odd No even filters have unpredicatable results
|
|
|
|
dat=new float *[Rows];
|
|
int i,j;
|
|
for(i=0;i<Rows;i++)
|
|
{
|
|
dat[i]=new float[Cols];
|
|
for(j=0;j<Cols;j++)
|
|
dat[i][j]=0.0f;
|
|
}
|
|
|
|
Sum=0.0f;
|
|
}
|
|
|
|
void ImageOperator::Destroy()
|
|
{
|
|
int i;
|
|
for(i=0;i<Rows;i++)
|
|
delete dat[i];
|
|
|
|
delete dat;
|
|
|
|
}
|
|
|
|
void ImageOperator::CreateGaussian(float pix)
|
|
{
|
|
//Implement This
|
|
//Create a Square Gaussian Matrix Based on a pixel radius
|
|
CreateMean((int)pix,(int)pix);
|
|
|
|
}
|
|
|
|
void ImageOperator::CreateGaussian(int sx,int sy)
|
|
{
|
|
Create(sx,sy);
|
|
|
|
|
|
Sum=0.0f;
|
|
|
|
int i,j;
|
|
for(i=0;i<Rows;i++)
|
|
for(j=0;j<Cols;j++)
|
|
{
|
|
dat[i][j]=(float)(exp((float)-(j*j/sx*sx))*exp((float)-(i*i/sy*sy)));
|
|
Sum+=dat[i][j];
|
|
}
|
|
|
|
}
|
|
|
|
void ImageOperator::CreateMean(int sx,int sy)
|
|
{
|
|
Create(sx,sy);
|
|
|
|
int i,j;
|
|
for(i=0;i<Rows;i++)
|
|
for(j=0;j<Cols;j++)
|
|
{
|
|
dat[i][j]=1.0f;
|
|
}
|
|
|
|
Sum=(float)Rows*Cols;
|
|
}
|
|
|
|
void ImageOperator::CalculateSum()
|
|
{
|
|
|
|
Sum=0.0f;
|
|
|
|
int i,j;
|
|
for(i=0;i<Rows;i++)
|
|
for(j=0;j<Cols;j++)
|
|
{
|
|
Sum+=dat[i][j];
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|