Readable image types:
.bmp, .cut, .dds, .doom, .gif, .ico, .jpg, .lbm, .mdl, .mng, .pal, .pbm, .pcd, .pcx, .pgm, .pic, .png, .ppm, .psd, .psp, .raw, .sgi, .tga and .tif files.
Writable image types:
.bmp, .dds, .h, .jpg, .pal, .pbm, .pcx, .pgm,.png, .ppm, .raw, .sgi, .tga and .tif.
Code: Select all
// Bitmap.h: interface for the CBitmap class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_BITMAP_H__BBA7EEE5_879F_4ABE_A878_51FE098C3A0D__INCLUDED_)
#define AFX_BITMAP_H__BBA7EEE5_879F_4ABE_A878_51FE098C3A0D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <string>
using std::string;
class CBitmap
{
public:
CBitmap(unsigned char* data,int xsize,int ysize);
CBitmap(string filename);
CBitmap();
CBitmap(const CBitmap& old);
void operator=(const CBitmap& bm);
virtual ~CBitmap();
void Load(string filename);
void Save(string filename);
unsigned int CreateTexture(bool mipmaps);
void CreateAlpha(unsigned char red,unsigned char green,unsigned char blue);
void Renormalize(float3 newCol);
CBitmap GetRegion(int startx, int starty, int width, int height);
CBitmap CreateMipmapLevel(void);
unsigned char* mem;
int xsize;
int ysize;
CBitmap CreateRescaled(int newx, int newy);
void ReverseYAxis(void);
};
#endif // !defined(AFX_BITMAP_H__BBA7EEE5_879F_4ABE_A878_51FE098C3A0D__INCLUDED_)
Code: Select all
#include "stdafx.h"
// Bitmap.cpp: implementation of the CBitmap class.
//
//////////////////////////////////////////////////////////////////////
#include "Bitmap.h"
#include "mygl.h"
#include <ostream>
#include <fstream>
#include "filehandler.h"
//#include "mmgr.h"
#include <il/il.h>
#pragma comment(lib, "devil.lib")
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBitmap::CBitmap()
: xsize(1),
ysize(1)
{
mem=new unsigned char[4];
}
CBitmap::~CBitmap()
{
if(mem!=0)
delete[] mem;
}
CBitmap::CBitmap(const CBitmap& old)
{
xsize=old.xsize;
ysize=old.ysize;
mem=new unsigned char[xsize*ysize*4];
memcpy(mem,old.mem,xsize*ysize*4);
}
CBitmap::CBitmap(unsigned char *data, int xsize, int ysize)
: xsize(xsize),
ysize(ysize)
{
mem=new unsigned char[xsize*ysize*4];
memcpy(mem,data,xsize*ysize*4);
}
CBitmap::CBitmap(string filename)
: mem(0),
xsize(0),
ysize(0)
{
Load(filename);
}
void CBitmap::operator=(const CBitmap& bm)
{
delete[] mem;
xsize=bm.xsize;
ysize=bm.ysize;
mem=new unsigned char[xsize*ysize*4];
memcpy(mem,bm.mem,xsize*ysize*4);
}
void CBitmap::Load(string filename)
{
ilInit();
ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
ilEnable(IL_ORIGIN_SET);
if(mem != NULL) delete [] mem;
CFileHandler file(filename);
if(file.FileExists() == false)
{
xsize = 1;
ysize = 1;
mem=new unsigned char[4];
memset(mem, 0, 4);
return;
}
unsigned char *buffer = new unsigned char[file.FileSize()];
file.Read(buffer, file.FileSize());
ILuint ImageName = 0;
ilGenImages(1, &ImageName);
ilBindImage(ImageName);
const bool success = ilLoadL(IL_TYPE_UNKNOWN, buffer, file.FileSize());
delete [] buffer;
if(success == false)
{
xsize = 1;
ysize = 1;
mem=new unsigned char[4];
memset(mem, 0, 4);
return;
}
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
xsize = ilGetInteger(IL_IMAGE_WIDTH);
ysize = ilGetInteger(IL_IMAGE_HEIGHT);
mem = new unsigned char[xsize * ysize * 4];
memcpy(mem, (unsigned char *) ilGetData() , xsize * ysize * 4);
ilDeleteImages(1, &ImageName);
}
void CBitmap::Save(string filename)
{
ILuint ImageName = 0;
ilGenImages(1, &ImageName);
ilBindImage(ImageName);
ilTexImage(xsize, ysize, 0, 32, IL_RGBA, IL_UNSIGNED_BYTE, mem);
ilSaveImage((char *)filename.c_str());
ilDeleteImages(1, &ImageName);
}
unsigned int CBitmap::CreateTexture(bool mipmaps)
{
if(mem==NULL)
return 0;
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
if(mipmaps)
{
// create mipmapped texture
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,xsize, ysize, GL_RGBA, GL_UNSIGNED_BYTE, mem);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
//glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8 ,xsize, ysize, 0,GL_RGBA, GL_UNSIGNED_BYTE, mem);
gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,xsize, ysize, GL_RGBA, GL_UNSIGNED_BYTE, mem);
}
return texture;
}
void CBitmap::CreateAlpha(unsigned char red,unsigned char green,unsigned char blue)
{
float3 aCol;
for(int a=0;a<3;++a){
int cCol=0;
int numCounted=0;
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
if(mem[(y*xsize+x)*4+3]!=0 && !(mem[(y*xsize+x)*4+0]==red && mem[(y*xsize+x)*4+1]==green && mem[(y*xsize+x)*4+2]==blue)){
cCol+=mem[(y*xsize+x)*4+a];
++numCounted;
}
}
}
aCol.xyz[a]=cCol/255.0f/numCounted;
}
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
if(mem[(y*xsize+x)*4+0]==red && mem[(y*xsize+x)*4+1]==green && mem[(y*xsize+x)*4+2]==blue){
mem[(y*xsize+x)*4+0]=unsigned char (aCol.x*255);
mem[(y*xsize+x)*4+1]=unsigned char (aCol.y*255);
mem[(y*xsize+x)*4+2]=unsigned char (aCol.z*255);
mem[(y*xsize+x)*4+3]=0;
}
}
}
}
void CBitmap::Renormalize(float3 newCol)
{
float3 aCol;
// float3 aSpread;
float3 colorDif;
// float3 spreadMul;
for(int a=0;a<3;++a){
int cCol=0;
int numCounted=0;
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
if(mem[(y*xsize+x)*4+3]!=0){
cCol+=mem[(y*xsize+x)*4+a];
++numCounted;
}
}
}
aCol.xyz[a]=cCol/255.0f/numCounted;
cCol/=xsize*ysize;
colorDif.xyz[a]=newCol[a]-aCol[a];
/* int spread=0;
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
if(mem[(y*xsize+x)*4+3]!=0){
int dif=mem[(y*xsize+x)*4+a]-cCol;
spread+=abs(dif);
}
}
}
aSpread.xyz[a]=spread/255.0f/numCounted;
spreadMul.xyz[a]=(float)(newSpread[a]/aSpread[a]);*/
}
for(int a=0;a<3;++a){
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
float nc=float(mem[(y*xsize+x)*4+a])/255.0f+colorDif.xyz[a];
/* float r=newCol.xyz[a]+(nc-newCol.xyz[a])*spreadMul.xyz[a];*/
mem[(y*xsize+x)*4+a]=unsigned char(min(255,max(0,nc*255)));
}
}
}
}
CBitmap CBitmap::GetRegion(int startx, int starty, int width, int height)
{
CBitmap bm;
delete[] bm.mem;
bm.mem=new unsigned char[width*height*4];
bm.xsize=width;
bm.ysize=height;
for(int y=0;y<height;++y){
for(int x=0;x<width;++x){
bm.mem[(y*width+x)*4]=mem[((starty+y)*xsize+startx+x)*4];
bm.mem[(y*width+x)*4+1]=mem[((starty+y)*xsize+startx+x)*4+1];
bm.mem[(y*width+x)*4+2]=mem[((starty+y)*xsize+startx+x)*4+2];
bm.mem[(y*width+x)*4+3]=mem[((starty+y)*xsize+startx+x)*4+3];
}
}
return bm;
}
CBitmap CBitmap::CreateMipmapLevel(void)
{
CBitmap bm;
delete[] bm.mem;
bm.xsize=xsize/2;
bm.ysize=ysize/2;
bm.mem=new unsigned char[bm.xsize*bm.ysize*4];
for(int y=0;y<ysize/2;++y){
for(int x=0;x<xsize/2;++x){
float r=0,g=0,b=0,a=0;
for(int y2=0;y2<2;++y2){
for(int x2=0;x2<2;++x2){
r+=mem[((y*2+y2)*xsize+x*2+x2)*4+0];
g+=mem[((y*2+y2)*xsize+x*2+x2)*4+1];
b+=mem[((y*2+y2)*xsize+x*2+x2)*4+2];
a+=mem[((y*2+y2)*xsize+x*2+x2)*4+3];
}
}
bm.mem[(y*bm.xsize+x)*4]=unsigned char(r/4);
bm.mem[(y*bm.xsize+x)*4+1]=unsigned char(g/4);
bm.mem[(y*bm.xsize+x)*4+2]=unsigned char(b/4);
bm.mem[(y*bm.xsize+x)*4+3]=unsigned char(a/4);
}
}
return bm;
}
CBitmap CBitmap::CreateRescaled(int newx, int newy)
{
CBitmap bm;
delete[] bm.mem;
bm.xsize=newx;
bm.ysize=newy;
bm.mem=new unsigned char[bm.xsize*bm.ysize*4];
float dx=float(xsize)/newx;
float dy=float(ysize)/newy;
float cy=0;
for(int y=0;y<newy;++y){
int sy=(int)cy;
cy+=dy;
int ey=(int)cy;
if(ey==sy)
ey=sy+1;
float cx=0;
for(int x=0;x<newx;++x){
int sx=(int)cx;
cx+=dx;
int ex=(int)cx;
if(ex==sx)
ex=sx+1;
int r=0,g=0,b=0,a=0;
for(int y2=sy;y2<ey;++y2){
for(int x2=sx;x2<ex;++x2){
r+=mem[(y2*xsize+x2)*4+0];
g+=mem[(y2*xsize+x2)*4+1];
b+=mem[(y2*xsize+x2)*4+2];
a+=mem[(y2*xsize+x2)*4+3];
}
}
bm.mem[(y*bm.xsize+x)*4+0]=r/((ex-sx)*(ey-sy));
bm.mem[(y*bm.xsize+x)*4+1]=g/((ex-sx)*(ey-sy));
bm.mem[(y*bm.xsize+x)*4+2]=b/((ex-sx)*(ey-sy));
bm.mem[(y*bm.xsize+x)*4+3]=a/((ex-sx)*(ey-sy));
}
}
return bm;
}
void CBitmap::ReverseYAxis(void)
{
unsigned char* buf=new unsigned char[xsize*ysize*4];
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
buf[((ysize-1-y)*xsize+x)*4+0]=mem[((y)*xsize+x)*4+0];
buf[((ysize-1-y)*xsize+x)*4+1]=mem[((y)*xsize+x)*4+1];
buf[((ysize-1-y)*xsize+x)*4+2]=mem[((y)*xsize+x)*4+2];
buf[((ysize-1-y)*xsize+x)*4+3]=mem[((y)*xsize+x)*4+3];
}
}
delete[] mem;
mem=buf;
}