Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
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.
2026-06-24 21:28:16 -05:00

513 lines
16 KiB
C++

#ifndef _IMAGE_H
#define _IMAGE_H
#include<stdio.h>
#include<math.h>
#include<Stuff\Stuff.hpp>
#include<windows.h>
//>>>>>>>>>>>>>>>>>>>>>>>>> Error Handleing Cluge
//!!!!!!!!!!!!!!!!!!!!!!!!! This must be addressed
#define GENFERR(x) PAUSE((x))
#define GENNFERR(x) PAUSE((x))
//>>>>>>>>>>>>>>>>>>>>>>>>>>> Errors
#define IERR_OK (1<<0)
#define IERR_FILE (1<<1)
#define IERR_NOIMAGE (1<<2)
//>>>>>>>>>>>>>>>>>>>>>>>>>>>> Flags
#define IMG_LOCKED (1<<0)
#define IMG_ISDATA (1<<1)
//>>>>>>>>>>>>>>>>>>>>>>>>>>>> Macros
#define RGB16(r,g,b) ((((WORD)r&0xf8)<<8)|(((WORD)g&0xfc)<<3)|(((WORD)b&0xf8)>>3))
#define RGB24(r,g,b,a,mr,mg,mb,ma) (PMASK24(r,mr)|PMASK24(g,mg)|PMASK24(b,mb)|PMASK24(a,ma))
#define PMASK24(p,mp) ((((DWORD)(p))|((DWORD)(p)<<8)|((DWORD)(p)<<16)|((DWORD)(p)<<24))&(mp))
#define Mask(x,y) ((x)&(~(y)))
//>>>>>>>>>>>>>>>>>>>>>>>>>>> Structs/unions
enum ITYPE {ITYPE_RGB,ITYPE_INDEXED} ;
enum RMETHOD {RMD_REDC,RMD_BLUEC,RMD_GREENC,RMD_ALPHAC,RMD_MAX,RMD_BHT} ;
//>>>>>>>>>>>>>>>>>>>>>>>>>>> custom types
typedef unsigned long int DWORD;
typedef unsigned short int WORD;
typedef unsigned char BYTE;
typedef int BOOL;
#define TRUE 1
#define FALSE 0
//>>>>>>>>>>>>>>>>>>>>>>>>>>> Classes
class Image;
class RGBMask;
class ImgRGBColor;
class RGBPixel;
class FRect
{
public:
float top,left,right,bottom;
FRect(float x1=0,float y1=0,float x2=0,float y2=0)
{top=y1; bottom=y2; left=x1; right=x2; }
FRect(double x1,double y1=0,double x2=0,double y2=0)
{top=(float)y1; bottom=(float)y2; left=(float)x1; right=(float)x2; }
FRect(int x1,int y1,int x2,int y2)
{top=(float)y1; bottom=(float)y2; left=(float)x1; right=(float)x2; }
};
class TRect:public RECT
{
public:
TRect(int x1=0,int y1=0,int x2=0,int y2=0) {top=y1; bottom=y2; left=x1; right=x2; }
TRect(FRect &rct)
{top=(int)rct.top; bottom=(int)rct.bottom;
left=(int)rct.left; right=(int)rct.right; }
};
class RGBPixel
{
public:
union {
unsigned long int dword;
unsigned short int wrd[2];
unsigned char com[4];
};
RGBPixel(const ImgRGBColor &col,const RGBMask &mask) { Set(col,mask); }
void Set(const ImgRGBColor &col,const RGBMask &mask);
void Set(const ImgRGBColor &col);
friend ImgRGBColor;
};
class RGBMask
{
protected:
DWORD R,G,B,A;
DWORD irs,igs,ibs,ias;
DWORD rbs,gbs,bbs,albs;
DWORD ras,gas,bas,aas;
DWORD bits;
// DWORD rmax,gmax,bmax,amax;
public:
RGBMask(DWORD r=0xff0000,DWORD g=0x00ff00,DWORD b=0x0000ff,DWORD a=0) { Set(r,g,b,a); }
int Set(DWORD r=0xff0000,DWORD g=0x00ff00,DWORD b=0x0000ff,DWORD a=0);
int IsValid() { return R && B && G; }
int operator==(RGBMask &mask) { return (R==mask.R)&&(G==mask.G)&&(B==mask.B)&&(A==mask.A); }
DWORD GetRMask() {return R;}
DWORD GetGMask() {return G;}
DWORD GetBMask() {return B;}
DWORD GetAMask() {return A;}
DWORD GetRBits() {return rbs;}
DWORD GetGBits() {return gbs;}
DWORD GetBBits() {return bbs;}
DWORD GetABits() {return albs;}
DWORD GetBpp() {return bits;}
friend class ImgRGBColor;
friend class RGBPixel;
};
class ImgRGBColor
{
private:
public:
int r,g,b,a;
void Bound(); //makes sure color is in valid range
//construction
ImgRGBColor() {}
ImgRGBColor(int ir,int ig,int ib,int ia=255) { Set(ir,ig,ib,ia);}
ImgRGBColor(float ir,float ig,float ib,float ia=1.0) { Set(ir,ig,ib,ia);}
ImgRGBColor(DWORD ir,DWORD ig,DWORD ib,DWORD ia=255) { Set(ir,ig,ib,ia);}
ImgRGBColor(RGBPixel &pix,RGBMask &mask) { Set(pix,mask); }
ImgRGBColor(COLORREF col) { Set(col&0xff,(col>>8)&0xff,(col>>16)&0xff); }
//initalization
void Set(DWORD ir,DWORD ig,DWORD ib,DWORD ia=255) { r=ir; g=ig; b=ib; a=ia; }
void Set(int ir,int ig,int ib,int ia=255) { r=ir; g=ig; b=ib; a=ia; }
void Set(float ir,float ig,float ib,float ia=1.0) { Set((int)(ir*255),(int)(ig*255),(int)(ib*255),(int)(ia*255));}
void SetBounded(int ir,int ig,int ib,int ia=255) { Set(ir,ig,ib,ia); Bound(); } //keeps values in legal range
void Set(const RGBPixel &pix,const RGBMask &mask);
//conditionals
int operator==(const ImgRGBColor &ac) { return (r==ac.r) && (g==ac.g) && (b==ac.b); }
int operator!=(const ImgRGBColor &ac) { return (r!=ac.r) || (g!=ac.g) || (b!=ac.b); }
int LSDiff(const ImgRGBColor &ac) { return abs(ac.r-r)+abs(ac.g-g)+abs(ac.b-b)+abs(ac.a-a); } //least squares difference
void Merge(const ImgRGBColor &ac,int dw=1,int sw=1); //weighted merge
void Blend(const ImgRGBColor &ac,float trans=.5); //weighted merge
void ContrastBy(float cont) { SetBounded((int)((r-128*cont)+128),(int)((g-128*cont)+128),(int)((b-128*cont)+128)); }
void BrightenBy(float bgt) { SetBounded((int)(r*bgt),(int)(g*bgt),(int)(b*bgt)); }
//operators
ImgRGBColor &operator-(int col) { Set(r-col,g-col,b-col,a); return *this; }
ImgRGBColor &operator-(float col) { Set(r-col*255,g-col*255,b-col*255,(float)(a/255.0)); return *this; }
ImgRGBColor &operator+(int col) { Set(r+col,g+col,b+col,a); return *this; }
ImgRGBColor &operator+(float col) { Set(r+col*255,g+col*255,b+col*255,(float)(a/255.0)); return *this; }
ImgRGBColor &operator=(int col) { Set(col,col,col); return *this;}
ImgRGBColor &operator=(float col) { Set(col,col,col); return *this;}
ImgRGBColor &operator++() { Set(r+1,g+1,b+1,a); return *this; }
ImgRGBColor &operator--() { Set(r-1,g-1,b-1,a); return *this; }
ImgRGBColor &operator+=(const ImgRGBColor &ac) { Set(r+ac.r,g+ac.g,b+ac.b); return *this; }
ImgRGBColor operator+(const ImgRGBColor &ac) { return ImgRGBColor(r+ac.r,g+ac.g,b+ac.b); }
ImgRGBColor operator/(int dv) { return ImgRGBColor(r/dv,g/dv,b/dv); }
ImgRGBColor &operator=(const ImgRGBColor &ac) { r=ac.r; g=ac.g; b=ac.b; a=ac.a; return *this; }
//operations
void Invert() { r=255-r; g=255-g; b=255-b; a=255-a; }
void MakeBW() { r=g=b=(BYTE)(g*0.59f+b*0.11f+r*0.3f); }
float GetBrightness() { return (g*0.59f+b*0.11f+r*0.3f)*(1/255.0f);}
friend class RGBPixel;
friend class Image;
friend class DXImage;
friend class OctTree;
};
class Point
{
public:
int x,y,z;
Point(int ix=0,int iy=0,int iz=0);
int XDist(int);
int YDist(int);
double Dist(int,int);
int XDist(Point p);
int YDist(Point p);
double Dist(Point p);
};
class ImageOperator
{
protected:
int Rows,Cols;
float **dat;
float Sum;
void CalculateSum();
void Create(int sr,int sc);
void Destroy();
public:
ImageOperator() {Rows=Cols=0; dat=new float *[0];}
ImageOperator(int sr,int sc) { ImageOperator(); Create(sr,sc); }
~ImageOperator() {Destroy(); }
float GetWeight(int r,int c) {return dat[r][c];}
float GetTotal() {return Sum;}
int GetRows() {return Rows;}
int GetCols() {return Cols;}
void CreateGaussian(float pix);
void CreateGaussian(int xl,int yl);
void CreateMean(int sx,int sy);
friend class Image;
};
class Histogram
{
friend class Image;
protected:
int Data[256];
int Peak;
public:
Histogram();
Histogram(Image &img,RMETHOD rmet=RMD_REDC);
~Histogram();
void Clear();
int GetBottom(float per=0.5);
int GetTop(float per=0.5);
};
class RGBHistogram
{
friend class Image;
protected:
Histogram RHist,GHist,BHist;
public:
RGBHistogram();
RGBHistogram(Image &img);
void Clear();
ImgRGBColor GetBottom(float per=0.5);
ImgRGBColor GetTop(float per=0.5);
};
class Image
{
protected:
int Flag;
BYTE *Data;
char fname[MAX_PATH];
ImgRGBColor *pal;
RGBMask Mask;
int Bpp,Pitch;
int xlen,ylen;
int xpos,ypos,vxlen,vylen;
ITYPE itype;
// Internal memory Management
int LockStack;
virtual void IAlloc();
virtual void IFree();
virtual void SetData(BYTE *); //assume to be corrrctly for formated with Pitch=xlen
virtual void RealizePalette(); //makes the new pallette take effect
void AllocPal() {if(pal) return; else pal=new ImgRGBColor[256];}
// Internal data Management
void Init();
void CorrectPitch(); //corrects the pitch of loaded image
//Multiple or incorrect calls will corrupt data
void DeInterlace(); //deinterlaces a 4 interlaced image
void DePitch(BYTE *); //fills buffer with copy of depitched data
void MaskFrom(RGBMask &imask); //Remask the data from this mask to correct mask
//Internal Manipulation
void Difference();
void UnDifference();
void InternalLoadPng();
void InternalSavePng();
public:
void FillHistogram(Histogram *hist,RMETHOD rmet=RMD_REDC);
void FillHistogram(RGBHistogram *hist);
void MaskTo(RGBMask &omask); //Remask the data from this mask to correct mask
int GetXPos() {return xpos;}
int GetYPos() {return ypos;}
void ResetPos() {xpos=ypos=0;}
void IgnoreVDims() {xpos=ypos=0; vxlen=xlen; vylen=ylen;}
int GetHeight() {return ylen;}
int GetWidth() {return xlen;}
int GetVHeight() {return vylen;}
int GetVWidth() {return vxlen;}
int GetPitch() {return Pitch;}
int GetIType() {return itype;}
int GetBpp() {return Bpp;}
char *GetFileName() {return fname;}
Image();
Image(Image &img);
Image(char *);
Image(int xl,int yl);
Image(int xl,int yl,ImgRGBColor col);
void Delete();
int IsData();
bool HasAlpha() {return Mask.GetABits()!=0;}
//>>>>>>>>>>>>>>>>>>>> creation
void CreateGrid(int xlen=320,int ylen=200,int gx=10,int gy=10,ImgRGBColor bgk=ImgRGBColor(0,0,0),ImgRGBColor frg=ImgRGBColor(255,255,255),ITYPE itp=ITYPE_RGB,int bpp=24);
void CreateFade(int xl=320,int yl=200,ImgRGBColor rgb1=ImgRGBColor(255,255,255),ImgRGBColor rgb2=ImgRGBColor(0,0,0),int ort=0,ITYPE itp=ITYPE_RGB,int bpp=24);
void CreateSolid(int xl=320,int yl=200,ImgRGBColor col=ImgRGBColor(0,0,0),ITYPE itp=ITYPE_RGB,int bpp=24);
void CreateBlank(int xl=320,int yl=200,ITYPE itp=ITYPE_RGB,int bpp=24);
void CreateBlank(int xl,int yl,ITYPE itp,int bpp,RGBMask &msk);
void FillColor(ImgRGBColor fcol=ImgRGBColor(0,0,0));
//>>>>>>>>>>>>>>>>>>>> enhancment
void Swap(const ImgRGBColor &,const ImgRGBColor &);
void ReplaceAlpha(int acutoff=0,const ImgRGBColor &bcol=ImgRGBColor(0,0,0)); //Replaces alpha <= this value with color
void GaussianBlur(float pix);
void MeanBlur(int xs,int ys);
void ApplyOperator(ImageOperator &Opt);
void Pad(int pixs=1);
void MakeSlopeMap(float xscale=1.0f,float yscale=1.0f,float zscale=1.0f,ImgRGBColor lowcol=ImgRGBColor(255,0,0),ImgRGBColor highcol=ImgRGBColor(255,0,0));
void MakeContourMap(float xscale=1.0f,float yscale=1.0f,float zscale=1.0f,int step=10,ImgRGBColor bgcol=ImgRGBColor(0,0,0),ImgRGBColor lolinecol=ImgRGBColor(255,255,255),ImgRGBColor highlinecol=ImgRGBColor(255,255,255));
void ShowSlopeLimit(float xscale=1.0f,float yscale=1.0f,float zscale=1.0f,float limit=45.0f,ImgRGBColor lowcol=ImgRGBColor(255,0,0),ImgRGBColor highcol=ImgRGBColor(255,0,0));
float GetBrightness();
void BrightenBy(float bght);
void ContrastBy(float bght);
void AdjustToRange(ImgRGBColor &maxcol,ImgRGBColor &mincol);
void AutoAdjust();
//>>>>>>>>>>>>>>>>>>>> Memory Management
virtual BYTE *Lock();
virtual void UnLock();
//>>>>>>>>>>>>>>>>>>>> External Pallete Management
virtual void SetPaletteEntry(int idx,int r,int g ,int b);
void SetPaletteEntry(int idx,float r,float g,float b);
void SetPaletteEntry(int,const ImgRGBColor &rgb);
ImgRGBColor GetPaletteEntry(int);
void MakeGrayscalePalette();
void MakePalette(ImgRGBColor low,ImgRGBColor high);
//>>>>>>>>>>>>>>>>>>>> manipulation
void MakeRGB(RGBMask msk=RGBMask(0xff0000,0x00ff00,0x0000ff,0));
void MakeRGB24();
void MakeRGB16(RGBMask msk=RGBMask(0xf800,0x07E0,0x001f,0));
void MakeBW();
void Invert();
void Quantize();
void Crop(int x1,int y1,int x2, int y2);
Point Crop(ImgRGBColor ccl=ImgRGBColor(0,0,0));
void ReduceTo8Bit(RMETHOD rm);
void Blt(Image &img,RECT &dst);
void Blt(Image &img,RECT dst,RECT &src);
void Blt(Image &img,FRect dst);
void Blt(Image &img,FRect dst,FRect src);
void Blt(Image &img,int x=0,int y=0);
void Blt(Image &img,int x,int y,RECT &src);
void Blt(Image &img,int x,int y,FRect src);
void BltDominantColor(Image &img,RECT dst,RECT &src);
void BltBlend(Image &img,float efact,RECT &src,float tfact,float rfact,float bfact,float lfact);
// Blends edges of image into other images that are sampled differently
// efact = % of edge to blend 0-1
// tfact = reduction coefficent of above image <0 if same as this image
void Rotate180();
//>>>>>>>>>>>>>>>>>>>> Super Cool Manipulations
void CreateDifferentialMap();
void CreateDifferentialMap(float *, int);
//>>>>>>>>>>>>>>>>>>>> File management
void Load(FILE *);
void Load(char *);
void Load();
int IsTiff(FILE *);
void LoadTiff(FILE *);
void LoadTiff(char *);
void SaveTiff(FILE *);
void SaveTiff(char *);
int IsGif(FILE *fl);
void LoadGif(FILE *);
void LoadGif(char *);
void SaveGif(FILE *);
void SaveGif(char *);
int IsTga();
void LoadTga(FILE *);
void SaveTga(FILE *);
void GetTgaInfo(FILE *);
void SaveTga(char *);
void LoadTga(char *);
void GetTgaInfo(char *);
void LoadTga(Stuff::FileStream *stream);
void GetTgaInfo(Stuff::FileStream *stream);
void SaveTga(Stuff::FileStream *stream);
int IsPng();
int IsPng(FILE *fl);
void LoadPng(FILE *);
void SavePng(FILE *);
void GetPngInfo(FILE *);
void LoadPng(char *);
void SavePng(char *);
void GetPngInfo(char *);
int IsPng(Stuff::FileStream *stream);
void LoadPng(Stuff::FileStream *stream);
void SavePng(Stuff::FileStream *stream);
void GetPngInfo(Stuff::FileStream *stream);
void SaveRaw(FILE *);
void SaveRaw(char *);
//>>>>>>>>>>>>>>>>>>>> matinaance
ImgRGBColor GetColor(Point &p);
Image &operator=(Image &img);
bool operator==(Image &img);
bool operator!=(Image &img) {return !(*this==img);}
~Image();
friend class OctQuant; // Octree color quantization
};
//Inline functions
__inline void RGBPixel::Set(const ImgRGBColor &col,const RGBMask &mask)
{
switch(mask.bits)
{
case 16:
wrd[0]=(WORD)(((col.r>>mask.ras)<<mask.irs)|((col.g>>mask.gas)<<mask.igs)|
((col.b>>mask.bas)<<mask.ibs)|((col.a>>mask.aas)<<mask.ias));
break;
case 24:
{
unsigned long int tdw;
tdw=((col.r>>mask.ras)<<mask.irs)|((col.g>>mask.gas)<<mask.igs)|
((col.b>>mask.bas)<<mask.ibs)|((col.a>>mask.aas)<<mask.ias);
wrd[0]=(unsigned short)(tdw&0xffff);
com[2]=(unsigned char)((tdw>>16)&0xff);
}
break;
case 32:
dword=((col.r>>mask.ras)<<mask.irs)|((col.g>>mask.gas)<<mask.igs)|
((col.b>>mask.bas)<<mask.ibs)|((col.a>>mask.aas)<<mask.ias);
break;
default:
GENFERR("SetPixel Unsupported number of bits.");
break;
}
}
__inline void RGBPixel::Set(const ImgRGBColor &col)
{
RGBMask m(0xff0000,0x00ff00,0x0000ff);
Set(col,m);
}
// ImgRGBColor Functions
__inline void ImgRGBColor::Set(const RGBPixel &pix,const RGBMask &mask)
{
Set(
((pix.dword&mask.R)>>mask.irs)<<mask.ras,
((pix.dword&mask.G)>>mask.igs)<<mask.gas,
((pix.dword&mask.B)>>mask.ibs)<<mask.bas,
((pix.dword&mask.A)>>mask.ias)<<mask.aas
);
}
__inline void ImgRGBColor::Bound()
{
if(r>255) r=255; else if(r<0) r=0;
if(g>255) g=255; else if(g<0) g=0;
if(b>255) b=255; else if(b<0) b=0;
}
__inline void ImgRGBColor::Merge(const ImgRGBColor &ac,int dw,int sw) //weighted merge
{
r=(r*dw+ac.r*sw)/(dw+sw);
g=(g*dw+ac.g*sw)/(dw+sw);
b=(b*dw+ac.b*sw)/(dw+sw);
}
__inline void ImgRGBColor::Blend(const ImgRGBColor &ac,float trans) //weighted merge
{
r=(unsigned long)(r*(1-trans)+ac.r*trans);
g=(unsigned long)(g*(1-trans)+ac.g*trans);
b=(unsigned long)(b*(1-trans)+ac.b*trans);
}
#endif