mirror of
https://github.com/glest/glest-source.git
synced 2025-09-25 23:19:07 +02:00
569 lines
15 KiB
C++
569 lines
15 KiB
C++
// ==============================================================
|
|
// This file is part of MegaGlest (www.glest.org)
|
|
//
|
|
// Image.h -- Copyright (c) 2006 David Henry
|
|
// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda
|
|
//
|
|
// This code is licensed under the MIT license:
|
|
// http://www.opensource.org/licenses/mit-license.php
|
|
//
|
|
// Open Source Initiative OSI - The MIT License (MIT):Licensing
|
|
//
|
|
// The MIT License (MIT)
|
|
// Copyright (c) <year> <copyright holders>
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
// to deal in the Software without restriction, including without limitation
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.//
|
|
//
|
|
// Declaration of DDS, TGA, PCX, JPEG and PNG image loader classes.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
#ifndef __IMAGE_H__
|
|
#define __IMAGE_H__
|
|
|
|
#ifdef _WIN32
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <memory>
|
|
#endif // _WIN32
|
|
|
|
#include <GL/glew.h>
|
|
|
|
#if !defined(_WIN32) || defined(__MINGW32__)
|
|
#include <tr1/memory>
|
|
#endif
|
|
|
|
#include <stdexcept>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <png.h>
|
|
|
|
extern "C" {
|
|
#include <jpeglib.h>
|
|
}
|
|
|
|
using std::cout;
|
|
using std::endl;
|
|
using std::string;
|
|
|
|
#if defined(_WIN32)
|
|
using std::tr1::shared_ptr;
|
|
#endif
|
|
|
|
namespace Shared { namespace Graphics { namespace md5 {
|
|
|
|
#ifndef _WIN32
|
|
//using boost::shared_ptr;
|
|
using std::tr1::shared_ptr;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Image class diagram:
|
|
//
|
|
// +------- (abs) +---------------+
|
|
// | Image | | runtime_error |
|
|
// +---------+ +---------------+
|
|
// ^ ^
|
|
// | +------------+ |
|
|
// +---| ImageDDS | +----------------+
|
|
// | +------------+ | ImageException |
|
|
// | +----------------+
|
|
// | +------------+
|
|
// +---| ImageTGA |
|
|
// | +------------+
|
|
// | +---------------+
|
|
// | +------------+ | ImageBuffer |
|
|
// +---| ImagePCX | +---------------+
|
|
// | +------------+
|
|
// |
|
|
// | +------------+
|
|
// +---| ImageJPEG | +----------------+
|
|
// | +------------+ | ImageFactory |
|
|
// | +----------------+
|
|
// | +------------+
|
|
// +---| ImagePNG |
|
|
// +------------+
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class ImageException - Exception class for ImageBuffer and Image
|
|
// loaders. This acts like a standard runtime_error exception but
|
|
// know which file has failed to be loaded.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class ImageException : public std::runtime_error {
|
|
public:
|
|
// Constructors
|
|
ImageException (const string &error)
|
|
: std::runtime_error (error) { }
|
|
ImageException (const string &error, const string &filename)
|
|
: std::runtime_error (error), _which (filename) { }
|
|
virtual ~ImageException () throw () { }
|
|
|
|
public:
|
|
// Public interface
|
|
virtual const char *which () const throw () {
|
|
return _which.c_str ();
|
|
}
|
|
|
|
private:
|
|
// Member variables
|
|
string _which;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class ImageBuffer - An image file loader class. Load a whole file
|
|
// into a memory buffer.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class ImageBuffer {
|
|
public:
|
|
// Constructors/destructor
|
|
ImageBuffer (const string &filename);
|
|
|
|
ImageBuffer (const ImageBuffer &that)
|
|
: _filename (that._filename), _data (NULL), _length (that._length)
|
|
{
|
|
_data = new GLubyte[_length];
|
|
memcpy (_data, that._data, _length);
|
|
}
|
|
|
|
~ImageBuffer ();
|
|
|
|
private:
|
|
// Disable default constructor
|
|
ImageBuffer ();
|
|
|
|
public:
|
|
// Accessors
|
|
const string &filename () const { return _filename; }
|
|
const GLubyte *data () const { return _data; }
|
|
size_t length () const { return _length; }
|
|
|
|
ImageBuffer &operator= (const ImageBuffer &rhs)
|
|
{
|
|
this->~ImageBuffer ();
|
|
new (this) ImageBuffer (rhs);
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
// Member variables
|
|
string _filename;
|
|
|
|
GLubyte *_data;
|
|
size_t _length;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class Image - A generic image loader class for creating OpenGL
|
|
// textures from. All other specific image loader are derived from it.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class Image {
|
|
protected:
|
|
// Default constructor
|
|
Image ()
|
|
: _width (0), _height (0), _numMipmaps (0),
|
|
_format (0), _components (0), _pixels (NULL),
|
|
_standardCoordSystem (true) { }
|
|
|
|
private:
|
|
// Disable copy constructor.
|
|
Image (const Image &img);
|
|
|
|
public:
|
|
// Constructors/destructor
|
|
Image (const string &name, GLsizei w, GLsizei h, GLint numMipMaps,
|
|
GLenum format, GLint components, const GLubyte *pixels,
|
|
bool stdCoordSystem);
|
|
|
|
virtual ~Image();
|
|
|
|
public:
|
|
// Return true if we're working with S3
|
|
// compressed textures (DDS files)
|
|
bool isCompressed () const;
|
|
bool isPowerOfTwo () const;
|
|
|
|
// Accessors
|
|
GLsizei width () const { return _width; }
|
|
GLsizei height () const { return _height; }
|
|
GLint numMipmaps () const { return _numMipmaps; }
|
|
GLenum format () const { return _format; }
|
|
GLint components () const { return _components; }
|
|
const GLubyte *pixels () const { return _pixels; }
|
|
const string &name () const { return _name; }
|
|
bool stdCoordSystem () const { return _standardCoordSystem; }
|
|
|
|
protected:
|
|
// Member variables
|
|
GLsizei _width;
|
|
GLsizei _height;
|
|
GLint _numMipmaps;
|
|
|
|
// OpenGL texture format and internal
|
|
// format (components)
|
|
GLenum _format;
|
|
GLint _components;
|
|
|
|
// Image data
|
|
GLubyte *_pixels;
|
|
|
|
string _name;
|
|
|
|
// Is the picture in standard OpenGL 2D coordinate
|
|
// system? (starts lower-left corner)
|
|
bool _standardCoordSystem;
|
|
};
|
|
|
|
|
|
// Definition of type aliases
|
|
typedef shared_ptr<Image> ImagePtr;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class ImageDDS - A DirectDraw Surface (DDS) image loader class.
|
|
// Support only DXT1, DXT3 and DXT5 formats, since OpenGL doesn't
|
|
// support others. GL_EXT_texture_compression_s3tc must be supported.
|
|
//
|
|
// NOTE: Because DirectX uses the upper left corner as origin of the
|
|
// picture when OpenGL uses the lower left corner, the texture generated
|
|
// from it will be rendered upside-down.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class ImageDDS : public Image {
|
|
public:
|
|
// Constructor
|
|
ImageDDS (const ImageBuffer &ibuff);
|
|
|
|
private:
|
|
// Internal data structures and
|
|
// member variables
|
|
struct DDPixelFormat
|
|
{
|
|
GLuint size;
|
|
GLuint flags;
|
|
GLuint fourCC;
|
|
GLuint bpp;
|
|
GLuint redMask;
|
|
GLuint greenMask;
|
|
GLuint blueMask;
|
|
GLuint alphaMask;
|
|
};
|
|
|
|
struct DDSCaps
|
|
{
|
|
GLuint caps;
|
|
GLuint caps2;
|
|
GLuint caps3;
|
|
GLuint caps4;
|
|
};
|
|
|
|
struct DDColorKey
|
|
{
|
|
GLuint lowVal;
|
|
GLuint highVal;
|
|
};
|
|
|
|
struct DDSurfaceDesc
|
|
{
|
|
GLuint size;
|
|
GLuint flags;
|
|
GLuint height;
|
|
GLuint width;
|
|
GLuint pitch;
|
|
GLuint depth;
|
|
GLuint mipMapLevels;
|
|
GLuint alphaBitDepth;
|
|
GLuint reserved;
|
|
GLuint surface;
|
|
|
|
DDColorKey ckDestOverlay;
|
|
DDColorKey ckDestBlt;
|
|
DDColorKey ckSrcOverlay;
|
|
DDColorKey ckSrcBlt;
|
|
|
|
DDPixelFormat format;
|
|
DDSCaps caps;
|
|
|
|
GLuint textureStage;
|
|
};
|
|
|
|
const DDSurfaceDesc *_ddsd;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class glImageTGA - A TrueVision TARGA (TGA) image loader class.
|
|
// Support 24-32 bits BGR files; 16 bits RGB; 8 bits indexed (BGR
|
|
// palette); 8 and 16 bits grayscale; all compressed and uncompressed.
|
|
// Compressed TGA images use RLE algorithm.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class ImageTGA : public Image {
|
|
public:
|
|
// Constructor
|
|
ImageTGA (const ImageBuffer &ibuff);
|
|
|
|
private:
|
|
// Internal functions
|
|
void getTextureInfo ();
|
|
|
|
void readTGA8bits (const GLubyte *data, const GLubyte *colormap);
|
|
void readTGA16bits (const GLubyte *data);
|
|
void readTGA24bits (const GLubyte *data);
|
|
void readTGA32bits (const GLubyte *data);
|
|
void readTGAgray8bits (const GLubyte *data);
|
|
void readTGAgray16bits (const GLubyte *data);
|
|
|
|
void readTGA8bitsRLE (const GLubyte *data, const GLubyte *colormap);
|
|
void readTGA16bitsRLE (const GLubyte *data);
|
|
void readTGA24bitsRLE (const GLubyte *data);
|
|
void readTGA32bitsRLE (const GLubyte *data);
|
|
void readTGAgray8bitsRLE (const GLubyte *data);
|
|
void readTGAgray16bitsRLE (const GLubyte *data);
|
|
|
|
private:
|
|
// Member variables
|
|
#pragma pack(push, 1)
|
|
// tga header
|
|
struct TGA_Header
|
|
{
|
|
GLubyte id_lenght; // size of image id
|
|
GLubyte colormap_type; // 1 is has a colormap
|
|
GLubyte image_type; // compression type
|
|
|
|
short cm_first_entry; // colormap origin
|
|
short cm_length; // colormap length
|
|
GLubyte cm_size; // colormap size
|
|
|
|
short x_origin; // bottom left x coord origin
|
|
short y_origin; // bottom left y coord origin
|
|
|
|
short width; // picture width (in pixels)
|
|
short height; // picture height (in pixels)
|
|
|
|
GLubyte pixel_depth; // bits per pixel: 8, 16, 24 or 32
|
|
GLubyte image_descriptor; // 24 bits = 0x00; 32 bits = 0x80
|
|
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
const TGA_Header *_header;
|
|
|
|
// NOTE:
|
|
// 16 bits images are stored in RGB
|
|
// 8-24-32 images are stored in BGR(A)
|
|
|
|
// RGBA/BGRA component table access -- usefull for
|
|
// switching from bgra to rgba at load time.
|
|
static int rgbaTable[4]; // bgra to rgba: 2, 1, 0, 3
|
|
static int bgraTable[4]; // bgra to bgra: 0, 1, 2, 3
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class ImagePCX - A Zsoft PCX image loader class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class ImagePCX : public Image {
|
|
public:
|
|
// Constructor
|
|
ImagePCX (const ImageBuffer &ibuff);
|
|
|
|
private:
|
|
// Internal functions
|
|
void readPCX1bit (const GLubyte *data);
|
|
void readPCX4bits (const GLubyte *data);
|
|
void readPCX8bits (const GLubyte *data,
|
|
const GLubyte *palette);
|
|
void readPCX24bits (const GLubyte *data);
|
|
|
|
private:
|
|
#pragma pack(push, 1)
|
|
// pcx header
|
|
struct PCX_Header
|
|
{
|
|
GLubyte manufacturer;
|
|
GLubyte version;
|
|
GLubyte encoding;
|
|
GLubyte bitsPerPixel;
|
|
|
|
GLushort xmin, ymin;
|
|
GLushort xmax, ymax;
|
|
GLushort horzRes, vertRes;
|
|
|
|
GLubyte palette[48];
|
|
GLubyte reserved;
|
|
GLubyte numColorPlanes;
|
|
|
|
GLushort bytesPerScanLine;
|
|
GLushort paletteType;
|
|
GLushort horzSize, vertSize;
|
|
|
|
GLubyte padding[54];
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
const PCX_Header *_header;
|
|
|
|
// RGBA/BGRA component table access -- usefull for
|
|
// switching from bgra to rgba at load time.
|
|
static int rgbTable[3]; // bgra to rgba: 0, 1, 2
|
|
static int bgrTable[3]; // bgra to bgra: 2, 1, 0
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class ImageJPEG - A JPEG image loader class using libjpeg.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class ImageJPEG : public Image {
|
|
public:
|
|
// Constructor
|
|
ImageJPEG (const ImageBuffer &ibuff);
|
|
|
|
private:
|
|
// Error manager, using C's setjmp/longjmp
|
|
struct my_error_mgr
|
|
{
|
|
jpeg_error_mgr pub; // "public" fields
|
|
jmp_buf setjmp_buffer; // for return to caller
|
|
|
|
string errorMsg; // last error message
|
|
};
|
|
|
|
typedef my_error_mgr *my_error_ptr;
|
|
|
|
private:
|
|
// libjpeg's callback functions for reading data
|
|
static void initSource_callback (j_decompress_ptr cinfo);
|
|
static boolean fillInputBuffer_callback (j_decompress_ptr cinfo);
|
|
static void skipInputData_callback (j_decompress_ptr cinfo,
|
|
long num_bytes);
|
|
static void termSource_callback (j_decompress_ptr cinfo);
|
|
|
|
// libjpeg's callback functions for error handling
|
|
static void errorExit_callback (j_common_ptr cinfo);
|
|
static void outputMessage_callback (j_common_ptr cinfo);
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class ImagePNG - A Portable Network Graphic (PNG) image loader
|
|
// class using libpng and zlib.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class ImagePNG : public Image {
|
|
public:
|
|
// Constructor
|
|
ImagePNG (const ImageBuffer &ibuff);
|
|
|
|
private:
|
|
// Internal functions
|
|
void getTextureInfo (int color_type);
|
|
|
|
// libpng's callback functions for reading data
|
|
// and error handling
|
|
static void read_callback (png_structp png_ptr,
|
|
png_bytep data, png_size_t length);
|
|
static void error_callback (png_structp png_ptr,
|
|
png_const_charp error_msg);
|
|
static void warning_callback (png_structp png_ptr,
|
|
png_const_charp warning_msg);
|
|
|
|
public:
|
|
// Data source manager. Contains an image buffer and
|
|
// an offset position into file's data
|
|
struct my_source_mgr
|
|
{
|
|
// Constructors
|
|
my_source_mgr ()
|
|
: pibuff (NULL), offset (0) { }
|
|
my_source_mgr (const ImageBuffer &ibuff)
|
|
: pibuff (&ibuff), offset (0) { }
|
|
|
|
// Public member variables
|
|
const ImageBuffer *pibuff;
|
|
size_t offset;
|
|
};
|
|
|
|
typedef my_source_mgr *my_source_ptr;
|
|
|
|
private:
|
|
// Member variables
|
|
string errorMsg;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class ImageFactory - An Image Factory Class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
class ImageFactory {
|
|
public:
|
|
// Public interface
|
|
static Image *createImage (const ImageBuffer &ibuff)
|
|
{
|
|
string ext;
|
|
Image *result;
|
|
|
|
// Extract file extension
|
|
const string &filename = ibuff.filename ();
|
|
ext.assign (filename, filename.find_last_of ('.') + 1, string::npos);
|
|
|
|
if (ext.compare ("dds") == 0)
|
|
{
|
|
result = new ImageDDS (ibuff);
|
|
}
|
|
else if (ext.compare ("tga") == 0)
|
|
{
|
|
result = new ImageTGA (ibuff);
|
|
}
|
|
else if (ext.compare ("pcx") == 0)
|
|
{
|
|
result = new ImagePCX (ibuff);
|
|
}
|
|
else if (ext.compare ("jpg") == 0)
|
|
{
|
|
result = new ImageJPEG (ibuff);
|
|
}
|
|
else if (ext.compare ("png") == 0)
|
|
{
|
|
result = new ImagePNG (ibuff);
|
|
}
|
|
else
|
|
{
|
|
throw ImageException ("Unhandled image file format", filename);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
};
|
|
|
|
}}} //end namespace
|
|
|
|
#endif // __IMAGE_H__
|