Paranoia2/utils/common/imagelib.h

200 lines
6.7 KiB
C

/*
imagelib.h - simple loader\serializer for TGA & BMP
Copyright (C) 2015 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef IMAGELIB_H
#define IMAGELIB_H
#define GAMMA ( 2.2f ) // Valve Software gamma
#define INVGAMMA ( 1.0f / 2.2f ) // back to 1.0
/*
========================================================================
.BMP image format
========================================================================
*/
#pragma pack( 1 )
typedef struct
{
char id[2]; // bmfh.bfType
dword fileSize; // bmfh.bfSize
dword reserved0; // bmfh.bfReserved1 + bmfh.bfReserved2
dword bitmapDataOffset; // bmfh.bfOffBits
dword bitmapHeaderSize; // bmih.biSize
int width; // bmih.biWidth
int height; // bmih.biHeight
word planes; // bmih.biPlanes
word bitsPerPixel; // bmih.biBitCount
dword compression; // bmih.biCompression
dword bitmapDataSize; // bmih.biSizeImage
dword hRes; // bmih.biXPelsPerMeter
dword vRes; // bmih.biYPelsPerMeter
dword colors; // bmih.biClrUsed
dword importantColors; // bmih.biClrImportant
} bmp_t;
#pragma pack( )
/*
========================================================================
.TGA image format (Truevision Targa)
========================================================================
*/
#pragma pack( 1 )
typedef struct tga_s
{
byte id_length;
byte colormap_type;
byte image_type;
word colormap_index;
word colormap_length;
byte colormap_size;
word x_origin;
word y_origin;
word width;
word height;
byte pixel_size;
byte attributes;
} tga_t;
#pragma pack( )
#define IMAGE_MINWIDTH 1 // last mip-level is 1x1
#define IMAGE_MINHEIGHT 1
#define IMAGE_MAXWIDTH 4096
#define IMAGE_MAXHEIGHT 4096
#define MIP_MAXWIDTH 1024 // large sizes it's too complicated for quantizer
#define MIP_MAXHEIGHT 1024 // and provoked color degradation
#define IMAGE_HAS_ALPHA (IMAGE_HAS_1BIT_ALPHA|IMAGE_HAS_8BIT_ALPHA|IMAGE_HAS_SDF_ALPHA)
#define IMG_DIFFUSE 0 // same as default pad1 always equal 0
#define IMG_ALPHAMASK 1 // alpha-channel that stored separate as luminance texture
#define IMG_NORMALMAP 2 // indexed normalmap
#define IMG_GLOSSMAP 3 // luminance or color specularity map
#define IMG_GLOSSPOWER 4 // gloss power map (each value is a specular pow)
#define IMG_HEIGHTMAP 5 // heightmap (for parallax occlusion mapping or source of normalmap)
#define IMG_LUMA 6 // luma or glow texture with self-illuminated parts
#define IMG_STALKER_BUMP 7 // stalker two-component bump
#define IMG_STALKER_GLOSS 8 // stalker two-component bump
// NOTE: ordering is important!
#define IMG_SKYBOX_FT 9
#define IMG_SKYBOX_BK 10
#define IMG_SKYBOX_UP 11
#define IMG_SKYBOX_DN 12
#define IMG_SKYBOX_RT 13
#define IMG_SKYBOX_LF 14
#define IMG_CUBEMAP_PX 15
#define IMG_CUBEMAP_NX 16
#define IMG_CUBEMAP_PY 17
#define IMG_CUBEMAP_NY 18
#define IMG_CUBEMAP_PZ 19
#define IMG_CUBEMAP_NZ 20
// rgbdata->flags
typedef enum
{
IMAGE_QUANTIZED = BIT( 0 ), // this image already quantized
IMAGE_HAS_COLOR = BIT( 1 ), // image contain RGB-channel
IMAGE_HAS_1BIT_ALPHA = BIT( 2 ), // textures with '{'
IMAGE_HAS_8BIT_ALPHA = BIT( 3 ), // image contain full-range alpha-channel
IMAGE_HAS_SDF_ALPHA = BIT( 4 ), // SIgned distance field alpha
IMAGE_CUBEMAP = BIT( 5 ), // it's 6-sides cubemap buffer
IMAGE_SKYBOX = BIT( 6 ), // it's 6-sides skybox buffer
IMAGE_DXT_FORMAT = BIT( 7 ), // this image have a DXT compression
IMAGE_QUAKE1_PAL = BIT( 8 ), // image has Quake1 palette
IMAGE_NOMIPS = BIT( 9 ), // don't build mips before DXT compression
// Image_Process manipulation flags
IMAGE_FLIP_X = BIT( 10 ), // flip the image by width
IMAGE_FLIP_Y = BIT( 11 ), // flip the image by height
IMAGE_ROT_90 = BIT( 12 ), // flip from upper left corner to down right corner
IMAGE_ROT180 = IMAGE_FLIP_X|IMAGE_FLIP_Y,
IMAGE_ROT270 = IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90,
} imgFlags_t;
// loaded image
typedef struct rgbdata_s
{
word width; // image width
word height; // image height
word flags; // misc image flags
byte *palette; // palette if present
byte *buffer; // image buffer
size_t size; // for bounds checking
float reflectivity[3]; // sum color of all pixels
} rgbdata_t;
typedef struct imgtype_s
{
char *ext;
char type;
} imgtype_t;
typedef struct loadimage_s
{
const char *formatstring;
const char *ext;
rgbdata_t *(*loadfunc)( const char *name, const byte *buffer, size_t filesize );
} loadimage_t;
typedef struct saveimage_s
{
const char *formatstring;
const char *ext;
bool (*savefunc)( const char *name, rgbdata_t *pix );
} saveimage_t;
// image loading
rgbdata_t *Image_LoadTGA( const char *name, const byte *buffer, size_t filesize );
rgbdata_t *Image_LoadBMP( const char *name, const byte *buffer, size_t filesize );
rgbdata_t *Image_LoadDDS( const char *name, const byte *buffer, size_t filesize );
// image storing
bool Image_SaveTGA( const char *name, rgbdata_t *pix );
bool Image_SaveBMP( const char *name, rgbdata_t *pix );
bool Image_SaveDDS( const char *name, rgbdata_t *pix );
// common functions
rgbdata_t *Image_Alloc( int width, int height, bool paletted = false );
rgbdata_t *Image_AllocCubemap( int width, int height );
rgbdata_t *Image_AllocSkybox( int width, int height );
rgbdata_t *Image_Copy( rgbdata_t *src );
void Image_PackRGB( float flColor[3], dword &icolor );
void Image_UnpackRGB( dword icolor, float flColor[3] );
char Image_HintFromSuf( const char *lumpname );
rgbdata_t *COM_LoadImage( const char *filename, bool quiet = false );
rgbdata_t *COM_LoadImageMemory( const char *filename, const byte *buf, size_t fileSize );
const imgtype_t *Image_ImageTypeFromHint( char value );
bool COM_SaveImage( const char *filename, rgbdata_t *pix );
bool Image_ValidSize( const char *name, int width, int height );
void Image_BuildMipMap( byte *in, int width, int height, bool isNormalMap );
rgbdata_t *Image_Resample( rgbdata_t *pic, int new_width, int new_height );
rgbdata_t *Image_MergeColorAlpha( rgbdata_t *color, rgbdata_t *alpha );
rgbdata_t *Image_CreateCubemap( rgbdata_t *images[6], bool skybox = false, bool nomips = false );
void Image_ConvertBumpStalker( rgbdata_t *bump, rgbdata_t *gloss );
void Image_MakeSignedDistanceField( rgbdata_t *pic );
rgbdata_t *Image_ExtractAlphaMask( rgbdata_t *pic );
void Image_MakeOneBitAlpha( rgbdata_t *pic );
rgbdata_t *Image_Quantize( rgbdata_t *pic );
void Image_ApplyGamma( rgbdata_t *pic );
rgbdata_t *Image_Flip( rgbdata_t *src );
extern float g_gamma;
#endif//IMAGELIB_H