MegaGlest/source/shared_lib/include/graphics/pixmap.h

396 lines
9.8 KiB
C++

// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_GRAPHICS_PIXMAP_H_
#define _SHARED_GRAPHICS_PIXMAP_H_
#include <string>
#include "vec.h"
#include "data_types.h"
#include <map>
#include "checksum.h"
#include "leak_dumper.h"
using std::string;
using Shared::Platform::int8;
using Shared::Platform::uint8;
using Shared::Platform::int16;
using Shared::Platform::uint16;
using Shared::Platform::int32;
using Shared::Platform::uint32;
using Shared::Platform::float32;
using Shared::Util::Checksum;
namespace Shared{ namespace Graphics{
/**
* @brief Next power of 2
* @param x The number to be rounded
* @return the rounded number
*
* Rounds an unsigned integer up to the
* next power of 2; i.e. 2, 4, 8, 16, etc.
*/
static inline unsigned int next_power_of_2(unsigned int x)
{
x--;
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return ++x;
}
/**
* @brief Count bits set
* @param w Number in which to count bits
* @return The number of bits set
*
* Counts the number of bits in an unsigned int
* that are set to 1. So, for example, in the
* number 5, hich is 101 in binary, there are
* two bits set to 1.
*/
static inline unsigned int count_bits_set(unsigned int w)
{
/*
* This is faster, and runs in parallel
*/
const int S[] = {1, 2, 4, 8, 16};
const int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};
int c = w;
c = ((c >> S[0]) & B[0]) + (c & B[0]);
c = ((c >> S[1]) & B[1]) + (c & B[1]);
c = ((c >> S[2]) & B[2]) + (c & B[2]);
c = ((c >> S[3]) & B[3]) + (c & B[3]);
c = ((c >> S[4]) & B[4]) + (c & B[4]);
return c;
}
// =====================================================
// class PixmapIo
// =====================================================
class PixmapIo {
protected:
int w;
int h;
int components;
public:
virtual ~PixmapIo(){}
int getW() const {return w;}
int getH() const {return h;}
int getComponents() const {return components;}
virtual void openRead(const string &path)= 0;
virtual void read(uint8 *pixels)= 0;
virtual void read(uint8 *pixels, int components)= 0;
virtual void openWrite(const string &path, int w, int h, int components)= 0;
virtual void write(uint8 *pixels)= 0;
};
// =====================================================
// class PixmapIoTga
// =====================================================
class PixmapIoTga: public PixmapIo {
private:
FILE *file;
public:
PixmapIoTga();
virtual ~PixmapIoTga();
virtual void openRead(const string &path);
virtual void read(uint8 *pixels);
virtual void read(uint8 *pixels, int components);
virtual void openWrite(const string &path, int w, int h, int components);
virtual void write(uint8 *pixels);
};
// =====================================================
// class PixmapIoBmp
// =====================================================
class PixmapIoBmp: public PixmapIo {
private:
FILE *file;
public:
PixmapIoBmp();
virtual ~PixmapIoBmp();
virtual void openRead(const string &path);
virtual void read(uint8 *pixels);
virtual void read(uint8 *pixels, int components);
virtual void openWrite(const string &path, int w, int h, int components);
virtual void write(uint8 *pixels);
};
// =====================================================
// class PixmapIoBmp
// =====================================================
class PixmapIoPng: public PixmapIo {
private:
FILE *file;
string path;
public:
PixmapIoPng();
virtual ~PixmapIoPng();
virtual void openRead(const string &path);
virtual void read(uint8 *pixels);
virtual void read(uint8 *pixels, int components);
virtual void openWrite(const string &path, int w, int h, int components);
virtual void write(uint8 *pixels);
};
class PixmapIoJpg: public PixmapIo {
private:
FILE *file;
string path;
public:
PixmapIoJpg();
virtual ~PixmapIoJpg();
virtual void openRead(const string &path);
virtual void read(uint8 *pixels);
virtual void read(uint8 *pixels, int components);
virtual void openWrite(const string &path, int w, int h, int components);
virtual void write(uint8 *pixels);
};
// =====================================================
// class Pixmap1D
// =====================================================
class Pixmap1D {
protected:
int w;
int components;
uint8 *pixels;
string path;
Checksum crc;
public:
//constructor & destructor
Pixmap1D();
Pixmap1D(int components);
Pixmap1D(int w, int components);
void init(int components);
void init(int w, int components);
~Pixmap1D();
//load & save
void load(const string &path);
void loadTga(const string &path);
void loadBmp(const string &path);
//get
int getW() const {return w;}
int getComponents() const {return components;}
uint8 *getPixels() const {return pixels;}
void deletePixels();
string getPath() const { return path;}
std::size_t getPixelByteCount() const;
Checksum * getCRC() { return &crc; }
};
// =====================================================
// class Pixmap2D
// =====================================================
class Pixmap2D {
protected:
int h;
int w;
int components;
uint8 *pixels;
string path;
Checksum crc;
public:
//constructor & destructor
Pixmap2D();
Pixmap2D(int components);
Pixmap2D(int w, int h, int components);
void init(int components);
void init(int w, int h, int components);
~Pixmap2D();
void Scale(int format, int newW, int newH);
//load & save
static Pixmap2D* loadPath(const string& path);
void load(const string &path);
/*void loadTga(const string &path);
void loadBmp(const string &path);*/
void save(const string &path);
void saveBmp(const string &path);
void saveTga(const string &path);
void savePng(const string &path);
void saveJpg(const string &path);
//get
int getW() const {return w;}
int getH() const {return h;}
int getComponents() const {return components;}
uint8 *getPixels() const {return pixels;}
void deletePixels();
//get data
void getPixel(int x, int y, uint8 *value) const;
void getPixel(int x, int y, float32 *value) const;
void getComponent(int x, int y, int component, uint8 &value) const;
void getComponent(int x, int y, int component, float32 &value) const;
//vector get
Vec4f getPixel4f(int x, int y) const;
Vec3f getPixel3f(int x, int y) const;
float getPixelf(int x, int y) const;
float getComponentf(int x, int y, int component) const;
//set data
void setPixel(int x, int y, const uint8 *value, int arraySize);
void setPixel(int x, int y, const float32 *value, int arraySize);
void setComponent(int x, int y, int component, uint8 value);
void setComponent(int x, int y, int component, float32 value);
//vector set
void setPixel(int x, int y, const Vec3f &p);
void setPixel(int x, int y, const Vec4f &p);
void setPixel(int x, int y, float p);
//mass set
void setPixels(const uint8 *value, int arraySize);
void setPixels(const float32 *value, int arraySize);
void setComponents(int component, uint8 value);
void setComponents(int component, float32 value);
//operations
void splat(const Pixmap2D *leftUp, const Pixmap2D *rightUp, const Pixmap2D *leftDown, const Pixmap2D *rightDown);
void lerp(float t, const Pixmap2D *pixmap1, const Pixmap2D *pixmap2);
void copy(const Pixmap2D *sourcePixmap);
void subCopy(int x, int y, const Pixmap2D *sourcePixmap);
void copyImagePart(int x, int y, const Pixmap2D *sourcePixmap);
string getPath() const { return path;}
std::size_t getPixelByteCount() const;
Checksum * getCRC() { return &crc; }
private:
bool doDimensionsAgree(const Pixmap2D *pixmap);
};
// =====================================================
// class Pixmap3D
// =====================================================
class Pixmap3D {
protected:
int h;
int w;
int d;
int components;
int slice;
uint8 *pixels;
string path;
Checksum crc;
public:
//constructor & destructor
Pixmap3D();
Pixmap3D(int w, int h, int d, int components);
Pixmap3D(int d, int components);
void init(int w, int h, int d, int components);
void init(int d, int components);
void init(int components);
~Pixmap3D();
//load & save
void loadSlice(const string &path, int slice);
void loadSliceBmp(const string &path, int slice);
void loadSliceTga(const string &path, int slice);
void loadSlicePng(const string &path, int slice);
//get
int getSlice() const { return slice; }
int getW() const {return w;}
int getH() const {return h;}
int getD() const {return d;}
int getComponents() const {return components;}
uint8 *getPixels() const {return pixels;}
void deletePixels();
string getPath() const { return path;}
std::size_t getPixelByteCount() const;
Checksum * getCRC() { return &crc; }
};
// =====================================================
// class PixmapCube
// =====================================================
class PixmapCube {
public:
enum Face{
fPositiveX,
fNegativeX,
fPositiveY,
fNegativeY,
fPositiveZ,
fNegativeZ
};
protected:
Pixmap2D faces[6];
string path[6];
Checksum crc;
public:
PixmapCube();
~PixmapCube();
//init
void init(int w, int h, int components);
void init(int components);
//load & save
void loadFace(const string &path, int face);
/*void loadFaceBmp(const string &path, int face);
void loadFaceTga(const string &path, int face);*/
//get
Pixmap2D *getFace(int face) {return &faces[face];}
const Pixmap2D *getFace(int face) const {return &faces[face];}
void deletePixels();
string getPath(int face) const { return path[face];}
std::size_t getPixelByteCount() const;
Checksum * getCRC() { return &crc; }
};
}}//end namespace
#endif