diff --git a/TSE_Base/src/Types.hpp b/TSE_Base/src/Types.hpp index e5f2fc2..ff00438 100644 --- a/TSE_Base/src/Types.hpp +++ b/TSE_Base/src/Types.hpp @@ -6,7 +6,7 @@ namespace TSE { typedef std::string string; - typedef char byte; + typedef unsigned char byte; typedef signed char sbyte; typedef unsigned short ushort; diff --git a/TSE_Core/include/FI/FreeImage.h b/TSE_Core/include/FI/FreeImage.h new file mode 100644 index 0000000..188face --- /dev/null +++ b/TSE_Core/include/FI/FreeImage.h @@ -0,0 +1,1163 @@ +// ========================================================== +// FreeImage 3 +// +// Design and implementation by +// - Floris van den Berg (flvdberg@wxs.nl) +// - Hervé Drolon (drolon@infonie.fr) +// +// Contributors: +// - see changes log named 'Whatsnew.txt', see header of each .h and .cpp file +// +// This file is part of FreeImage 3 +// +// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE +// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT +// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY +// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL +// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER +// THIS DISCLAIMER. +// +// Use at your own risk! +// ========================================================== + +#ifndef FREEIMAGE_H +#define FREEIMAGE_H + +// Version information ------------------------------------------------------ + +#define FREEIMAGE_MAJOR_VERSION 3 +#define FREEIMAGE_MINOR_VERSION 18 +#define FREEIMAGE_RELEASE_SERIAL 0 + +// Compiler options --------------------------------------------------------- + +#include // needed for UNICODE functions + +#if defined(FREEIMAGE_LIB) + #define DLL_API + #define DLL_CALLCONV +#else + #if defined(_WIN32) || defined(__WIN32__) + #define DLL_CALLCONV __stdcall + // The following ifdef block is the standard way of creating macros which make exporting + // from a DLL simpler. All files within this DLL are compiled with the FREEIMAGE_EXPORTS + // symbol defined on the command line. this symbol should not be defined on any project + // that uses this DLL. This way any other project whose source files include this file see + // DLL_API functions as being imported from a DLL, wheras this DLL sees symbols + // defined with this macro as being exported. + #ifdef FREEIMAGE_EXPORTS + #define DLL_API __declspec(dllexport) + #else + #define DLL_API __declspec(dllimport) + #endif // FREEIMAGE_EXPORTS + #else + // try the gcc visibility support (see http://gcc.gnu.org/wiki/Visibility) + #if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) + #ifndef GCC_HASCLASSVISIBILITY + #define GCC_HASCLASSVISIBILITY + #endif + #endif // __GNUC__ + #define DLL_CALLCONV + #if defined(GCC_HASCLASSVISIBILITY) + #define DLL_API __attribute__ ((visibility("default"))) + #else + #define DLL_API + #endif + #endif // WIN32 / !WIN32 +#endif // FREEIMAGE_LIB + +// Endianness: +// Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined. +// If your big endian system isn't being detected, add an OS specific check +// or define any of FREEIMAGE_BIGENDIAN and FREEIMAGE_LITTLEENDIAN directly +// to specify the desired endianness. +#if (!defined(FREEIMAGE_BIGENDIAN) && !defined(FREEIMAGE_LITTLEENDIAN)) +#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__) + #define FREEIMAGE_BIGENDIAN + #endif // BYTE_ORDER +#endif // !FREEIMAGE_[BIG|LITTLE]ENDIAN + +// Color-Order: +// The specified order of color components red, green and blue affects 24- +// and 32-bit images of type FIT_BITMAP as well as the colors that are part +// of a color palette. All other images always use RGB order. By default, +// color order is coupled to endianness: +// little-endian -> BGR +// big-endian -> RGB +// However, you can always define FREEIMAGE_COLORORDER to any of the known +// orders FREEIMAGE_COLORORDER_BGR (0) and FREEIMAGE_COLORORDER_RGB (1) to +// specify your preferred color order. +#define FREEIMAGE_COLORORDER_BGR 0 +#define FREEIMAGE_COLORORDER_RGB 1 +#if (!defined(FREEIMAGE_COLORORDER)) || ((FREEIMAGE_COLORORDER != FREEIMAGE_COLORORDER_BGR) && (FREEIMAGE_COLORORDER != FREEIMAGE_COLORORDER_RGB)) + #if defined(FREEIMAGE_BIGENDIAN) + #define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB + #else + #define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR + #endif // FREEIMAGE_BIGENDIAN +#endif // FREEIMAGE_COLORORDER + +// Ensure 4-byte enums if we're using Borland C++ compilers +#if defined(__BORLANDC__) +#pragma option push -b +#endif + +// For C compatibility -------------------------------------------------------- + +#ifdef __cplusplus +#define FI_DEFAULT(x) = x +#define FI_ENUM(x) enum x +#define FI_STRUCT(x) struct x +#else +#define FI_DEFAULT(x) +#define FI_ENUM(x) typedef int x; enum x +#define FI_STRUCT(x) typedef struct x x; struct x +#endif + +// Bitmap types ------------------------------------------------------------- + +FI_STRUCT (FIBITMAP) { void *data; }; +FI_STRUCT (FIMULTIBITMAP) { void *data; }; + +// Types used in the library (directly copied from Windows) ----------------- + +#if defined(__MINGW32__) && defined(_WINDOWS_H) +#define _WINDOWS_ // prevent a bug in MinGW32 +#endif // __MINGW32__ + +#ifndef _WINDOWS_ +#define _WINDOWS_ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef NULL +#define NULL 0 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _MSC_VER +// define portable types for 32-bit / 64-bit OS +#include +typedef int32_t BOOL; +typedef uint8_t BYTE; +typedef uint16_t WORD; +typedef uint32_t DWORD; +typedef int32_t LONG; +typedef int64_t INT64; +typedef uint64_t UINT64; +#else +// MS is not C99 ISO compliant +typedef long BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef long LONG; +typedef signed __int64 INT64; +typedef unsigned __int64 UINT64; +#endif // _MSC_VER + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif // WIN32 + +typedef struct tagRGBQUAD { +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; +#else + BYTE rgbRed; + BYTE rgbGreen; + BYTE rgbBlue; +#endif // FREEIMAGE_COLORORDER + BYTE rgbReserved; +} RGBQUAD; + +typedef struct tagRGBTRIPLE { +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR + BYTE rgbtBlue; + BYTE rgbtGreen; + BYTE rgbtRed; +#else + BYTE rgbtRed; + BYTE rgbtGreen; + BYTE rgbtBlue; +#endif // FREEIMAGE_COLORORDER +} RGBTRIPLE; + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(pop) +#else +#pragma pack() +#endif // WIN32 + +typedef struct tagBITMAPINFOHEADER{ + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +} BITMAPINFOHEADER, *PBITMAPINFOHEADER; + +typedef struct tagBITMAPINFO { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[1]; +} BITMAPINFO, *PBITMAPINFO; + +#endif // _WINDOWS_ + +// Types used in the library (specific to FreeImage) ------------------------ + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif // WIN32 + +/** 48-bit RGB +*/ +typedef struct tagFIRGB16 { + WORD red; + WORD green; + WORD blue; +} FIRGB16; + +/** 64-bit RGBA +*/ +typedef struct tagFIRGBA16 { + WORD red; + WORD green; + WORD blue; + WORD alpha; +} FIRGBA16; + +/** 96-bit RGB Float +*/ +typedef struct tagFIRGBF { + float red; + float green; + float blue; +} FIRGBF; + +/** 128-bit RGBA Float +*/ +typedef struct tagFIRGBAF { + float red; + float green; + float blue; + float alpha; +} FIRGBAF; + +/** Data structure for COMPLEX type (complex number) +*/ +typedef struct tagFICOMPLEX { + /// real part + double r; + /// imaginary part + double i; +} FICOMPLEX; + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(pop) +#else +#pragma pack() +#endif // WIN32 + +// Indexes for byte arrays, masks and shifts for treating pixels as words --- +// These coincide with the order of RGBQUAD and RGBTRIPLE ------------------- + +#ifndef FREEIMAGE_BIGENDIAN +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR +// Little Endian (x86 / MS Windows, Linux) : BGR(A) order +#define FI_RGBA_RED 2 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 0 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x00FF0000 +#define FI_RGBA_GREEN_MASK 0x0000FF00 +#define FI_RGBA_BLUE_MASK 0x000000FF +#define FI_RGBA_ALPHA_MASK 0xFF000000 +#define FI_RGBA_RED_SHIFT 16 +#define FI_RGBA_GREEN_SHIFT 8 +#define FI_RGBA_BLUE_SHIFT 0 +#define FI_RGBA_ALPHA_SHIFT 24 +#else +// Little Endian (x86 / MaxOSX) : RGB(A) order +#define FI_RGBA_RED 0 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 2 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x000000FF +#define FI_RGBA_GREEN_MASK 0x0000FF00 +#define FI_RGBA_BLUE_MASK 0x00FF0000 +#define FI_RGBA_ALPHA_MASK 0xFF000000 +#define FI_RGBA_RED_SHIFT 0 +#define FI_RGBA_GREEN_SHIFT 8 +#define FI_RGBA_BLUE_SHIFT 16 +#define FI_RGBA_ALPHA_SHIFT 24 +#endif // FREEIMAGE_COLORORDER +#else +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR +// Big Endian (PPC / none) : BGR(A) order +#define FI_RGBA_RED 2 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 0 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x0000FF00 +#define FI_RGBA_GREEN_MASK 0x00FF0000 +#define FI_RGBA_BLUE_MASK 0xFF000000 +#define FI_RGBA_ALPHA_MASK 0x000000FF +#define FI_RGBA_RED_SHIFT 8 +#define FI_RGBA_GREEN_SHIFT 16 +#define FI_RGBA_BLUE_SHIFT 24 +#define FI_RGBA_ALPHA_SHIFT 0 +#else +// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order +#define FI_RGBA_RED 0 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 2 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0xFF000000 +#define FI_RGBA_GREEN_MASK 0x00FF0000 +#define FI_RGBA_BLUE_MASK 0x0000FF00 +#define FI_RGBA_ALPHA_MASK 0x000000FF +#define FI_RGBA_RED_SHIFT 24 +#define FI_RGBA_GREEN_SHIFT 16 +#define FI_RGBA_BLUE_SHIFT 8 +#define FI_RGBA_ALPHA_SHIFT 0 +#endif // FREEIMAGE_COLORORDER +#endif // FREEIMAGE_BIGENDIAN + +#define FI_RGBA_RGB_MASK (FI_RGBA_RED_MASK|FI_RGBA_GREEN_MASK|FI_RGBA_BLUE_MASK) + +// The 16bit macros only include masks and shifts, since each color element is not byte aligned + +#define FI16_555_RED_MASK 0x7C00 +#define FI16_555_GREEN_MASK 0x03E0 +#define FI16_555_BLUE_MASK 0x001F +#define FI16_555_RED_SHIFT 10 +#define FI16_555_GREEN_SHIFT 5 +#define FI16_555_BLUE_SHIFT 0 +#define FI16_565_RED_MASK 0xF800 +#define FI16_565_GREEN_MASK 0x07E0 +#define FI16_565_BLUE_MASK 0x001F +#define FI16_565_RED_SHIFT 11 +#define FI16_565_GREEN_SHIFT 5 +#define FI16_565_BLUE_SHIFT 0 + +// ICC profile support ------------------------------------------------------ + +#define FIICC_DEFAULT 0x00 +#define FIICC_COLOR_IS_CMYK 0x01 + +FI_STRUCT (FIICCPROFILE) { + WORD flags; //! info flag + DWORD size; //! profile's size measured in bytes + void *data; //! points to a block of contiguous memory containing the profile +}; + +// Important enums ---------------------------------------------------------- + +/** I/O image format identifiers. +*/ +FI_ENUM(FREE_IMAGE_FORMAT) { + FIF_UNKNOWN = -1, + FIF_BMP = 0, + FIF_ICO = 1, + FIF_JPEG = 2, + FIF_JNG = 3, + FIF_KOALA = 4, + FIF_LBM = 5, + FIF_IFF = FIF_LBM, + FIF_MNG = 6, + FIF_PBM = 7, + FIF_PBMRAW = 8, + FIF_PCD = 9, + FIF_PCX = 10, + FIF_PGM = 11, + FIF_PGMRAW = 12, + FIF_PNG = 13, + FIF_PPM = 14, + FIF_PPMRAW = 15, + FIF_RAS = 16, + FIF_TARGA = 17, + FIF_TIFF = 18, + FIF_WBMP = 19, + FIF_PSD = 20, + FIF_CUT = 21, + FIF_XBM = 22, + FIF_XPM = 23, + FIF_DDS = 24, + FIF_GIF = 25, + FIF_HDR = 26, + FIF_FAXG3 = 27, + FIF_SGI = 28, + FIF_EXR = 29, + FIF_J2K = 30, + FIF_JP2 = 31, + FIF_PFM = 32, + FIF_PICT = 33, + FIF_RAW = 34, + FIF_WEBP = 35, + FIF_JXR = 36 +}; + +/** Image type used in FreeImage. +*/ +FI_ENUM(FREE_IMAGE_TYPE) { + FIT_UNKNOWN = 0, //! unknown type + FIT_BITMAP = 1, //! standard image : 1-, 4-, 8-, 16-, 24-, 32-bit + FIT_UINT16 = 2, //! array of unsigned short : unsigned 16-bit + FIT_INT16 = 3, //! array of short : signed 16-bit + FIT_UINT32 = 4, //! array of unsigned long : unsigned 32-bit + FIT_INT32 = 5, //! array of long : signed 32-bit + FIT_FLOAT = 6, //! array of float : 32-bit IEEE floating point + FIT_DOUBLE = 7, //! array of double : 64-bit IEEE floating point + FIT_COMPLEX = 8, //! array of FICOMPLEX : 2 x 64-bit IEEE floating point + FIT_RGB16 = 9, //! 48-bit RGB image : 3 x 16-bit + FIT_RGBA16 = 10, //! 64-bit RGBA image : 4 x 16-bit + FIT_RGBF = 11, //! 96-bit RGB float image : 3 x 32-bit IEEE floating point + FIT_RGBAF = 12 //! 128-bit RGBA float image : 4 x 32-bit IEEE floating point +}; + +/** Image color type used in FreeImage. +*/ +FI_ENUM(FREE_IMAGE_COLOR_TYPE) { + FIC_MINISWHITE = 0, //! min value is white + FIC_MINISBLACK = 1, //! min value is black + FIC_RGB = 2, //! RGB color model + FIC_PALETTE = 3, //! color map indexed + FIC_RGBALPHA = 4, //! RGB color model with alpha channel + FIC_CMYK = 5 //! CMYK color model +}; + +/** Color quantization algorithms. +Constants used in FreeImage_ColorQuantize. +*/ +FI_ENUM(FREE_IMAGE_QUANTIZE) { + FIQ_WUQUANT = 0, //! Xiaolin Wu color quantization algorithm + FIQ_NNQUANT = 1, //! NeuQuant neural-net quantization algorithm by Anthony Dekker + FIQ_LFPQUANT = 2 //! Lossless Fast Pseudo-Quantization Algorithm by Carsten Klein +}; + +/** Dithering algorithms. +Constants used in FreeImage_Dither. +*/ +FI_ENUM(FREE_IMAGE_DITHER) { + FID_FS = 0, //! Floyd & Steinberg error diffusion + FID_BAYER4x4 = 1, //! Bayer ordered dispersed dot dithering (order 2 dithering matrix) + FID_BAYER8x8 = 2, //! Bayer ordered dispersed dot dithering (order 3 dithering matrix) + FID_CLUSTER6x6 = 3, //! Ordered clustered dot dithering (order 3 - 6x6 matrix) + FID_CLUSTER8x8 = 4, //! Ordered clustered dot dithering (order 4 - 8x8 matrix) + FID_CLUSTER16x16= 5, //! Ordered clustered dot dithering (order 8 - 16x16 matrix) + FID_BAYER16x16 = 6 //! Bayer ordered dispersed dot dithering (order 4 dithering matrix) +}; + +/** Lossless JPEG transformations +Constants used in FreeImage_JPEGTransform +*/ +FI_ENUM(FREE_IMAGE_JPEG_OPERATION) { + FIJPEG_OP_NONE = 0, //! no transformation + FIJPEG_OP_FLIP_H = 1, //! horizontal flip + FIJPEG_OP_FLIP_V = 2, //! vertical flip + FIJPEG_OP_TRANSPOSE = 3, //! transpose across UL-to-LR axis + FIJPEG_OP_TRANSVERSE = 4, //! transpose across UR-to-LL axis + FIJPEG_OP_ROTATE_90 = 5, //! 90-degree clockwise rotation + FIJPEG_OP_ROTATE_180 = 6, //! 180-degree rotation + FIJPEG_OP_ROTATE_270 = 7 //! 270-degree clockwise (or 90 ccw) +}; + +/** Tone mapping operators. +Constants used in FreeImage_ToneMapping. +*/ +FI_ENUM(FREE_IMAGE_TMO) { + FITMO_DRAGO03 = 0, //! Adaptive logarithmic mapping (F. Drago, 2003) + FITMO_REINHARD05 = 1, //! Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005) + FITMO_FATTAL02 = 2 //! Gradient domain high dynamic range compression (R. Fattal, 2002) +}; + +/** Upsampling / downsampling filters. +Constants used in FreeImage_Rescale. +*/ +FI_ENUM(FREE_IMAGE_FILTER) { + FILTER_BOX = 0, //! Box, pulse, Fourier window, 1st order (constant) b-spline + FILTER_BICUBIC = 1, //! Mitchell & Netravali's two-param cubic filter + FILTER_BILINEAR = 2, //! Bilinear filter + FILTER_BSPLINE = 3, //! 4th order (cubic) b-spline + FILTER_CATMULLROM = 4, //! Catmull-Rom spline, Overhauser spline + FILTER_LANCZOS3 = 5 //! Lanczos3 filter +}; + +/** Color channels. +Constants used in color manipulation routines. +*/ +FI_ENUM(FREE_IMAGE_COLOR_CHANNEL) { + FICC_RGB = 0, //! Use red, green and blue channels + FICC_RED = 1, //! Use red channel + FICC_GREEN = 2, //! Use green channel + FICC_BLUE = 3, //! Use blue channel + FICC_ALPHA = 4, //! Use alpha channel + FICC_BLACK = 5, //! Use black channel + FICC_REAL = 6, //! Complex images: use real part + FICC_IMAG = 7, //! Complex images: use imaginary part + FICC_MAG = 8, //! Complex images: use magnitude + FICC_PHASE = 9 //! Complex images: use phase +}; + +// Metadata support --------------------------------------------------------- + +/** + Tag data type information (based on TIFF specifications) + + Note: RATIONALs are the ratio of two 32-bit integer values. +*/ +FI_ENUM(FREE_IMAGE_MDTYPE) { + FIDT_NOTYPE = 0, //! placeholder + FIDT_BYTE = 1, //! 8-bit unsigned integer + FIDT_ASCII = 2, //! 8-bit bytes w/ last byte null + FIDT_SHORT = 3, //! 16-bit unsigned integer + FIDT_LONG = 4, //! 32-bit unsigned integer + FIDT_RATIONAL = 5, //! 64-bit unsigned fraction + FIDT_SBYTE = 6, //! 8-bit signed integer + FIDT_UNDEFINED = 7, //! 8-bit untyped data + FIDT_SSHORT = 8, //! 16-bit signed integer + FIDT_SLONG = 9, //! 32-bit signed integer + FIDT_SRATIONAL = 10, //! 64-bit signed fraction + FIDT_FLOAT = 11, //! 32-bit IEEE floating point + FIDT_DOUBLE = 12, //! 64-bit IEEE floating point + FIDT_IFD = 13, //! 32-bit unsigned integer (offset) + FIDT_PALETTE = 14, //! 32-bit RGBQUAD + FIDT_LONG8 = 16, //! 64-bit unsigned integer + FIDT_SLONG8 = 17, //! 64-bit signed integer + FIDT_IFD8 = 18 //! 64-bit unsigned integer (offset) +}; + +/** + Metadata models supported by FreeImage +*/ +FI_ENUM(FREE_IMAGE_MDMODEL) { + FIMD_NODATA = -1, + FIMD_COMMENTS = 0, //! single comment or keywords + FIMD_EXIF_MAIN = 1, //! Exif-TIFF metadata + FIMD_EXIF_EXIF = 2, //! Exif-specific metadata + FIMD_EXIF_GPS = 3, //! Exif GPS metadata + FIMD_EXIF_MAKERNOTE = 4, //! Exif maker note metadata + FIMD_EXIF_INTEROP = 5, //! Exif interoperability metadata + FIMD_IPTC = 6, //! IPTC/NAA metadata + FIMD_XMP = 7, //! Abobe XMP metadata + FIMD_GEOTIFF = 8, //! GeoTIFF metadata + FIMD_ANIMATION = 9, //! Animation metadata + FIMD_CUSTOM = 10, //! Used to attach other metadata types to a dib + FIMD_EXIF_RAW = 11 //! Exif metadata as a raw buffer +}; + +/** + Handle to a metadata model +*/ +FI_STRUCT (FIMETADATA) { void *data; }; + +/** + Handle to a FreeImage tag +*/ +FI_STRUCT (FITAG) { void *data; }; + +// File IO routines --------------------------------------------------------- + +#ifndef FREEIMAGE_IO +#define FREEIMAGE_IO + +typedef void* fi_handle; +typedef unsigned (DLL_CALLCONV *FI_ReadProc) (void *buffer, unsigned size, unsigned count, fi_handle handle); +typedef unsigned (DLL_CALLCONV *FI_WriteProc) (void *buffer, unsigned size, unsigned count, fi_handle handle); +typedef int (DLL_CALLCONV *FI_SeekProc) (fi_handle handle, long offset, int origin); +typedef long (DLL_CALLCONV *FI_TellProc) (fi_handle handle); + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif // WIN32 + +FI_STRUCT(FreeImageIO) { + FI_ReadProc read_proc; //! pointer to the function used to read data + FI_WriteProc write_proc; //! pointer to the function used to write data + FI_SeekProc seek_proc; //! pointer to the function used to seek + FI_TellProc tell_proc; //! pointer to the function used to aquire the current position +}; + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(pop) +#else +#pragma pack() +#endif // WIN32 + +/** +Handle to a memory I/O stream +*/ +FI_STRUCT (FIMEMORY) { void *data; }; + +#endif // FREEIMAGE_IO + +// Plugin routines ---------------------------------------------------------- + +#ifndef PLUGINS +#define PLUGINS + +typedef const char *(DLL_CALLCONV *FI_FormatProc)(void); +typedef const char *(DLL_CALLCONV *FI_DescriptionProc)(void); +typedef const char *(DLL_CALLCONV *FI_ExtensionListProc)(void); +typedef const char *(DLL_CALLCONV *FI_RegExprProc)(void); +typedef void *(DLL_CALLCONV *FI_OpenProc)(FreeImageIO *io, fi_handle handle, BOOL read); +typedef void (DLL_CALLCONV *FI_CloseProc)(FreeImageIO *io, fi_handle handle, void *data); +typedef int (DLL_CALLCONV *FI_PageCountProc)(FreeImageIO *io, fi_handle handle, void *data); +typedef int (DLL_CALLCONV *FI_PageCapabilityProc)(FreeImageIO *io, fi_handle handle, void *data); +typedef FIBITMAP *(DLL_CALLCONV *FI_LoadProc)(FreeImageIO *io, fi_handle handle, int page, int flags, void *data); +typedef BOOL (DLL_CALLCONV *FI_SaveProc)(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data); +typedef BOOL (DLL_CALLCONV *FI_ValidateProc)(FreeImageIO *io, fi_handle handle); +typedef const char *(DLL_CALLCONV *FI_MimeProc)(void); +typedef BOOL (DLL_CALLCONV *FI_SupportsExportBPPProc)(int bpp); +typedef BOOL (DLL_CALLCONV *FI_SupportsExportTypeProc)(FREE_IMAGE_TYPE type); +typedef BOOL (DLL_CALLCONV *FI_SupportsICCProfilesProc)(void); +typedef BOOL (DLL_CALLCONV *FI_SupportsNoPixelsProc)(void); + +FI_STRUCT (Plugin) { + FI_FormatProc format_proc; + FI_DescriptionProc description_proc; + FI_ExtensionListProc extension_proc; + FI_RegExprProc regexpr_proc; + FI_OpenProc open_proc; + FI_CloseProc close_proc; + FI_PageCountProc pagecount_proc; + FI_PageCapabilityProc pagecapability_proc; + FI_LoadProc load_proc; + FI_SaveProc save_proc; + FI_ValidateProc validate_proc; + FI_MimeProc mime_proc; + FI_SupportsExportBPPProc supports_export_bpp_proc; + FI_SupportsExportTypeProc supports_export_type_proc; + FI_SupportsICCProfilesProc supports_icc_profiles_proc; + FI_SupportsNoPixelsProc supports_no_pixels_proc; +}; + +typedef void (DLL_CALLCONV *FI_InitProc)(Plugin *plugin, int format_id); + +#endif // PLUGINS + + +// Load / Save flag constants ----------------------------------------------- + +#define FIF_LOAD_NOPIXELS 0x8000 //! loading: load the image header only (not supported by all plugins, default to full loading) + +#define BMP_DEFAULT 0 +#define BMP_SAVE_RLE 1 +#define CUT_DEFAULT 0 +#define DDS_DEFAULT 0 +#define EXR_DEFAULT 0 //! save data as half with piz-based wavelet compression +#define EXR_FLOAT 0x0001 //! save data as float instead of as half (not recommended) +#define EXR_NONE 0x0002 //! save with no compression +#define EXR_ZIP 0x0004 //! save with zlib compression, in blocks of 16 scan lines +#define EXR_PIZ 0x0008 //! save with piz-based wavelet compression +#define EXR_PXR24 0x0010 //! save with lossy 24-bit float compression +#define EXR_B44 0x0020 //! save with lossy 44% float compression - goes to 22% when combined with EXR_LC +#define EXR_LC 0x0040 //! save images with one luminance and two chroma channels, rather than as RGB (lossy compression) +#define FAXG3_DEFAULT 0 +#define GIF_DEFAULT 0 +#define GIF_LOAD256 1 //! load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color +#define GIF_PLAYBACK 2 //! 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading +#define HDR_DEFAULT 0 +#define ICO_DEFAULT 0 +#define ICO_MAKEALPHA 1 //! convert to 32bpp and create an alpha channel from the AND-mask when loading +#define IFF_DEFAULT 0 +#define J2K_DEFAULT 0 //! save with a 16:1 rate +#define JP2_DEFAULT 0 //! save with a 16:1 rate +#define JPEG_DEFAULT 0 //! loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420) +#define JPEG_FAST 0x0001 //! load the file as fast as possible, sacrificing some quality +#define JPEG_ACCURATE 0x0002 //! load the file with the best quality, sacrificing some speed +#define JPEG_CMYK 0x0004 //! load separated CMYK "as is" (use | to combine with other load flags) +#define JPEG_EXIFROTATE 0x0008 //! load and rotate according to Exif 'Orientation' tag if available +#define JPEG_GREYSCALE 0x0010 //! load and convert to a 8-bit greyscale image +#define JPEG_QUALITYSUPERB 0x80 //! save with superb quality (100:1) +#define JPEG_QUALITYGOOD 0x0100 //! save with good quality (75:1) +#define JPEG_QUALITYNORMAL 0x0200 //! save with normal quality (50:1) +#define JPEG_QUALITYAVERAGE 0x0400 //! save with average quality (25:1) +#define JPEG_QUALITYBAD 0x0800 //! save with bad quality (10:1) +#define JPEG_PROGRESSIVE 0x2000 //! save as a progressive-JPEG (use | to combine with other save flags) +#define JPEG_SUBSAMPLING_411 0x1000 //! save with high 4x1 chroma subsampling (4:1:1) +#define JPEG_SUBSAMPLING_420 0x4000 //! save with medium 2x2 medium chroma subsampling (4:2:0) - default value +#define JPEG_SUBSAMPLING_422 0x8000 //! save with low 2x1 chroma subsampling (4:2:2) +#define JPEG_SUBSAMPLING_444 0x10000 //! save with no chroma subsampling (4:4:4) +#define JPEG_OPTIMIZE 0x20000 //! on saving, compute optimal Huffman coding tables (can reduce a few percent of file size) +#define JPEG_BASELINE 0x40000 //! save basic JPEG, without metadata or any markers +#define KOALA_DEFAULT 0 +#define LBM_DEFAULT 0 +#define MNG_DEFAULT 0 +#define PCD_DEFAULT 0 +#define PCD_BASE 1 //! load the bitmap sized 768 x 512 +#define PCD_BASEDIV4 2 //! load the bitmap sized 384 x 256 +#define PCD_BASEDIV16 3 //! load the bitmap sized 192 x 128 +#define PCX_DEFAULT 0 +#define PFM_DEFAULT 0 +#define PICT_DEFAULT 0 +#define PNG_DEFAULT 0 +#define PNG_IGNOREGAMMA 1 //! loading: avoid gamma correction +#define PNG_Z_BEST_SPEED 0x0001 //! save using ZLib level 1 compression flag (default value is 6) +#define PNG_Z_DEFAULT_COMPRESSION 0x0006 //! save using ZLib level 6 compression flag (default recommended value) +#define PNG_Z_BEST_COMPRESSION 0x0009 //! save using ZLib level 9 compression flag (default value is 6) +#define PNG_Z_NO_COMPRESSION 0x0100 //! save without ZLib compression +#define PNG_INTERLACED 0x0200 //! save using Adam7 interlacing (use | to combine with other save flags) +#define PNM_DEFAULT 0 +#define PNM_SAVE_RAW 0 //! if set the writer saves in RAW format (i.e. P4, P5 or P6) +#define PNM_SAVE_ASCII 1 //! if set the writer saves in ASCII format (i.e. P1, P2 or P3) +#define PSD_DEFAULT 0 +#define PSD_CMYK 1 //! reads tags for separated CMYK (default is conversion to RGB) +#define PSD_LAB 2 //! reads tags for CIELab (default is conversion to RGB) +#define PSD_NONE 0x0100 //! save without any compression +#define PSD_RLE 0x0200 //! save using RLE compression +#define PSD_PSB 0x2000 //! save using Adobe Large Document Format (use | to combine with other save flags) +#define RAS_DEFAULT 0 +#define RAW_DEFAULT 0 //! load the file as linear RGB 48-bit +#define RAW_PREVIEW 1 //! try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit +#define RAW_DISPLAY 2 //! load the file as RGB 24-bit +#define RAW_HALFSIZE 4 //! output a half-size color image +#define RAW_UNPROCESSED 8 //! output a FIT_UINT16 raw Bayer image +#define SGI_DEFAULT 0 +#define TARGA_DEFAULT 0 +#define TARGA_LOAD_RGB888 1 //! if set the loader converts RGB555 and ARGB8888 -> RGB888. +#define TARGA_SAVE_RLE 2 //! if set, the writer saves with RLE compression +#define TIFF_DEFAULT 0 +#define TIFF_CMYK 0x0001 //! reads/stores tags for separated CMYK (use | to combine with compression flags) +#define TIFF_PACKBITS 0x0100 //! save using PACKBITS compression +#define TIFF_DEFLATE 0x0200 //! save using DEFLATE compression (a.k.a. ZLIB compression) +#define TIFF_ADOBE_DEFLATE 0x0400 //! save using ADOBE DEFLATE compression +#define TIFF_NONE 0x0800 //! save without any compression +#define TIFF_CCITTFAX3 0x1000 //! save using CCITT Group 3 fax encoding +#define TIFF_CCITTFAX4 0x2000 //! save using CCITT Group 4 fax encoding +#define TIFF_LZW 0x4000 //! save using LZW compression +#define TIFF_JPEG 0x8000 //! save using JPEG compression +#define TIFF_LOGLUV 0x10000 //! save using LogLuv compression +#define WBMP_DEFAULT 0 +#define XBM_DEFAULT 0 +#define XPM_DEFAULT 0 +#define WEBP_DEFAULT 0 //! save with good quality (75:1) +#define WEBP_LOSSLESS 0x100 //! save in lossless mode +#define JXR_DEFAULT 0 //! save with quality 80 and no chroma subsampling (4:4:4) +#define JXR_LOSSLESS 0x0064 //! save lossless +#define JXR_PROGRESSIVE 0x2000 //! save as a progressive-JXR (use | to combine with other save flags) + +// Background filling options --------------------------------------------------------- +// Constants used in FreeImage_FillBackground and FreeImage_EnlargeCanvas + +#define FI_COLOR_IS_RGB_COLOR 0x00 //! RGBQUAD color is a RGB color (contains no valid alpha channel) +#define FI_COLOR_IS_RGBA_COLOR 0x01 //! RGBQUAD color is a RGBA color (contains a valid alpha channel) +#define FI_COLOR_FIND_EQUAL_COLOR 0x02 //! For palettized images: lookup equal RGB color from palette +#define FI_COLOR_ALPHA_IS_INDEX 0x04 //! The color's rgbReserved member (alpha) contains the palette index to be used +#define FI_COLOR_PALETTE_SEARCH_MASK (FI_COLOR_FIND_EQUAL_COLOR | FI_COLOR_ALPHA_IS_INDEX) // No color lookup is performed + +// RescaleEx options --------------------------------------------------------- +// Constants used in FreeImage_RescaleEx + +#define FI_RESCALE_DEFAULT 0x00 //! default options; none of the following other options apply +#define FI_RESCALE_TRUE_COLOR 0x01 //! for non-transparent greyscale images, convert to 24-bit if src bitdepth <= 8 (default is a 8-bit greyscale image). +#define FI_RESCALE_OMIT_METADATA 0x02 //! do not copy metadata to the rescaled image + + +#ifdef __cplusplus +extern "C" { +#endif + +// Init / Error routines ---------------------------------------------------- + +DLL_API void DLL_CALLCONV FreeImage_Initialise(BOOL load_local_plugins_only FI_DEFAULT(FALSE)); +DLL_API void DLL_CALLCONV FreeImage_DeInitialise(void); + +// Version routines --------------------------------------------------------- + +DLL_API const char *DLL_CALLCONV FreeImage_GetVersion(void); +DLL_API const char *DLL_CALLCONV FreeImage_GetCopyrightMessage(void); + +// Message output functions ------------------------------------------------- + +typedef void (*FreeImage_OutputMessageFunction)(FREE_IMAGE_FORMAT fif, const char *msg); +typedef void (DLL_CALLCONV *FreeImage_OutputMessageFunctionStdCall)(FREE_IMAGE_FORMAT fif, const char *msg); + +DLL_API void DLL_CALLCONV FreeImage_SetOutputMessageStdCall(FreeImage_OutputMessageFunctionStdCall omf); +DLL_API void DLL_CALLCONV FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf); +DLL_API void DLL_CALLCONV FreeImage_OutputMessageProc(int fif, const char *fmt, ...); + +// Allocate / Clone / Unload routines --------------------------------------- + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); +DLL_API FIBITMAP * DLL_CALLCONV FreeImage_Clone(FIBITMAP *dib); +DLL_API void DLL_CALLCONV FreeImage_Unload(FIBITMAP *dib); + +// Header loading routines +DLL_API BOOL DLL_CALLCONV FreeImage_HasPixels(FIBITMAP *dib); + +// Load / Save routines ----------------------------------------------------- + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Load(FREE_IMAGE_FORMAT fif, const char *filename, int flags FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, int flags FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveU(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const wchar_t *filename, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveToHandle(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); + +// Memory I/O stream routines ----------------------------------------------- + +DLL_API FIMEMORY *DLL_CALLCONV FreeImage_OpenMemory(BYTE *data FI_DEFAULT(0), DWORD size_in_bytes FI_DEFAULT(0)); +DLL_API void DLL_CALLCONV FreeImage_CloseMemory(FIMEMORY *stream); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveToMemory(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FIMEMORY *stream, int flags FI_DEFAULT(0)); +DLL_API long DLL_CALLCONV FreeImage_TellMemory(FIMEMORY *stream); +DLL_API BOOL DLL_CALLCONV FreeImage_SeekMemory(FIMEMORY *stream, long offset, int origin); +DLL_API BOOL DLL_CALLCONV FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes); +DLL_API unsigned DLL_CALLCONV FreeImage_ReadMemory(void *buffer, unsigned size, unsigned count, FIMEMORY *stream); +DLL_API unsigned DLL_CALLCONV FreeImage_WriteMemory(const void *buffer, unsigned size, unsigned count, FIMEMORY *stream); + +DLL_API FIMULTIBITMAP *DLL_CALLCONV FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags); + +// Plugin Interface --------------------------------------------------------- + +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterLocalPlugin(FI_InitProc proc_address, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0)); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterExternalPlugin(const char *path, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0)); +DLL_API int DLL_CALLCONV FreeImage_GetFIFCount(void); +DLL_API int DLL_CALLCONV FreeImage_SetPluginEnabled(FREE_IMAGE_FORMAT fif, BOOL enable); +DLL_API int DLL_CALLCONV FreeImage_IsPluginEnabled(FREE_IMAGE_FORMAT fif); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFormat(const char *format); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromMime(const char *mime); +DLL_API const char *DLL_CALLCONV FreeImage_GetFormatFromFIF(FREE_IMAGE_FORMAT fif); +DLL_API const char *DLL_CALLCONV FreeImage_GetFIFExtensionList(FREE_IMAGE_FORMAT fif); +DLL_API const char *DLL_CALLCONV FreeImage_GetFIFDescription(FREE_IMAGE_FORMAT fif); +DLL_API const char *DLL_CALLCONV FreeImage_GetFIFRegExpr(FREE_IMAGE_FORMAT fif); +DLL_API const char *DLL_CALLCONV FreeImage_GetFIFMimeType(FREE_IMAGE_FORMAT fif); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilename(const char *filename); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilenameU(const wchar_t *filename); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsReading(FREE_IMAGE_FORMAT fif); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsWriting(FREE_IMAGE_FORMAT fif); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportBPP(FREE_IMAGE_FORMAT fif, int bpp); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportType(FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsNoPixels(FREE_IMAGE_FORMAT fif); + +// Multipaging interface ---------------------------------------------------- + +DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory FI_DEFAULT(FALSE), int flags FI_DEFAULT(0)); +DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags FI_DEFAULT(0)); +DLL_API int DLL_CALLCONV FreeImage_GetPageCount(FIMULTIBITMAP *bitmap); +DLL_API void DLL_CALLCONV FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data); +DLL_API void DLL_CALLCONV FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data); +DLL_API void DLL_CALLCONV FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page); +DLL_API FIBITMAP * DLL_CALLCONV FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page); +DLL_API void DLL_CALLCONV FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *data, BOOL changed); +DLL_API BOOL DLL_CALLCONV FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source); +DLL_API BOOL DLL_CALLCONV FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count); + +// File type request routines ------------------------------------------------ + +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileType(const char *filename, int size FI_DEFAULT(0)); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeU(const wchar_t *filename, int size FI_DEFAULT(0)); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size FI_DEFAULT(0)); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size FI_DEFAULT(0)); + +DLL_API BOOL DLL_CALLCONV FreeImage_Validate(FREE_IMAGE_FORMAT fif, const char *filename); +DLL_API BOOL DLL_CALLCONV FreeImage_ValidateU(FREE_IMAGE_FORMAT fif, const wchar_t *filename); +DLL_API BOOL DLL_CALLCONV FreeImage_ValidateFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle); +DLL_API BOOL DLL_CALLCONV FreeImage_ValidateFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream); + + +// Image type request routine ----------------------------------------------- + +DLL_API FREE_IMAGE_TYPE DLL_CALLCONV FreeImage_GetImageType(FIBITMAP *dib); + +// FreeImage helper routines ------------------------------------------------ + +DLL_API BOOL DLL_CALLCONV FreeImage_IsLittleEndian(void); +DLL_API BOOL DLL_CALLCONV FreeImage_LookupX11Color(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue); +DLL_API BOOL DLL_CALLCONV FreeImage_LookupSVGColor(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue); + +// Pixel access routines ---------------------------------------------------- + +DLL_API BYTE *DLL_CALLCONV FreeImage_GetBits(FIBITMAP *dib); +DLL_API BYTE *DLL_CALLCONV FreeImage_GetScanLine(FIBITMAP *dib, int scanline); + +DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value); +DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value); +DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value); +DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value); + +// DIB info routines -------------------------------------------------------- + +DLL_API unsigned DLL_CALLCONV FreeImage_GetColorsUsed(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetBPP(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetWidth(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetHeight(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetLine(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetPitch(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetDIBSize(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetMemorySize(FIBITMAP *dib); +DLL_API RGBQUAD *DLL_CALLCONV FreeImage_GetPalette(FIBITMAP *dib); + +DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterX(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterY(FIBITMAP *dib); +DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res); +DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res); + +DLL_API BITMAPINFOHEADER *DLL_CALLCONV FreeImage_GetInfoHeader(FIBITMAP *dib); +DLL_API BITMAPINFO *DLL_CALLCONV FreeImage_GetInfo(FIBITMAP *dib); +DLL_API FREE_IMAGE_COLOR_TYPE DLL_CALLCONV FreeImage_GetColorType(FIBITMAP *dib); + +DLL_API unsigned DLL_CALLCONV FreeImage_GetRedMask(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetGreenMask(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetBlueMask(FIBITMAP *dib); + +DLL_API unsigned DLL_CALLCONV FreeImage_GetTransparencyCount(FIBITMAP *dib); +DLL_API BYTE * DLL_CALLCONV FreeImage_GetTransparencyTable(FIBITMAP *dib); +DLL_API void DLL_CALLCONV FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled); +DLL_API void DLL_CALLCONV FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count); +DLL_API BOOL DLL_CALLCONV FreeImage_IsTransparent(FIBITMAP *dib); +DLL_API void DLL_CALLCONV FreeImage_SetTransparentIndex(FIBITMAP *dib, int index); +DLL_API int DLL_CALLCONV FreeImage_GetTransparentIndex(FIBITMAP *dib); + +DLL_API BOOL DLL_CALLCONV FreeImage_HasBackgroundColor(FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor); +DLL_API BOOL DLL_CALLCONV FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetThumbnail(FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_SetThumbnail(FIBITMAP *dib, FIBITMAP *thumbnail); + +// ICC profile routines ----------------------------------------------------- + +DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_GetICCProfile(FIBITMAP *dib); +DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size); +DLL_API void DLL_CALLCONV FreeImage_DestroyICCProfile(FIBITMAP *dib); + +// Line conversion routines ------------------------------------------------- + +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To4(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To4(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To4(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To4(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To8(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To8(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To8(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To8(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_565_To16_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_555_To16_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels); + +// Smart conversion routines ------------------------------------------------ + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo4Bits(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo8Bits(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToGreyscale(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits555(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits565(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo24Bits(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo32Bits(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantize(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize FI_DEFAULT(FIQ_WUQUANT), int PaletteSize FI_DEFAULT(256), int ReserveSize FI_DEFAULT(0), RGBQUAD *ReservePalette FI_DEFAULT(NULL)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Threshold(FIBITMAP *dib, BYTE T); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Dither(FIBITMAP *dib, FREE_IMAGE_DITHER algorithm); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBitsEx(BOOL copySource, BYTE *bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE)); +DLL_API void DLL_CALLCONV FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE)); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToFloat(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBF(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBAF(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToUINT16(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGB16(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBA16(FIBITMAP *dib); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear FI_DEFAULT(TRUE)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear FI_DEFAULT(TRUE)); + +// Tone mapping operators --------------------------------------------------- + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ToneMapping(FIBITMAP *dib, FREE_IMAGE_TMO tmo, double first_param FI_DEFAULT(0), double second_param FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoDrago03(FIBITMAP *src, double gamma FI_DEFAULT(2.2), double exposure FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05Ex(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0), double adaptation FI_DEFAULT(1), double color_correction FI_DEFAULT(0)); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoFattal02(FIBITMAP *src, double color_saturation FI_DEFAULT(0.5), double attenuation FI_DEFAULT(0.85)); + +// ZLib interface ----------------------------------------------------------- + +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibUncompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGZip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGUnzip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCRC32(DWORD crc, BYTE *source, DWORD source_size); + +// -------------------------------------------------------------------------- +// Metadata routines +// -------------------------------------------------------------------------- + +// tag creation / destruction +DLL_API FITAG *DLL_CALLCONV FreeImage_CreateTag(void); +DLL_API void DLL_CALLCONV FreeImage_DeleteTag(FITAG *tag); +DLL_API FITAG *DLL_CALLCONV FreeImage_CloneTag(FITAG *tag); + +// tag getters and setters +DLL_API const char *DLL_CALLCONV FreeImage_GetTagKey(FITAG *tag); +DLL_API const char *DLL_CALLCONV FreeImage_GetTagDescription(FITAG *tag); +DLL_API WORD DLL_CALLCONV FreeImage_GetTagID(FITAG *tag); +DLL_API FREE_IMAGE_MDTYPE DLL_CALLCONV FreeImage_GetTagType(FITAG *tag); +DLL_API DWORD DLL_CALLCONV FreeImage_GetTagCount(FITAG *tag); +DLL_API DWORD DLL_CALLCONV FreeImage_GetTagLength(FITAG *tag); +DLL_API const void *DLL_CALLCONV FreeImage_GetTagValue(FITAG *tag); + +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagKey(FITAG *tag, const char *key); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagDescription(FITAG *tag, const char *description); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagID(FITAG *tag, WORD id); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagCount(FITAG *tag, DWORD count); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagLength(FITAG *tag, DWORD length); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagValue(FITAG *tag, const void *value); + +// iterator +DLL_API FIMETADATA *DLL_CALLCONV FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag); +DLL_API BOOL DLL_CALLCONV FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag); +DLL_API void DLL_CALLCONV FreeImage_FindCloseMetadata(FIMETADATA *mdhandle); + +// metadata setter and getter +DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag); +DLL_API BOOL DLL_CALLCONV FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag); +DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadataKeyValue(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, const char *value); + +// helpers +DLL_API unsigned DLL_CALLCONV FreeImage_GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src); + +// tag to C string conversion +DLL_API const char* DLL_CALLCONV FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make FI_DEFAULT(NULL)); + +// -------------------------------------------------------------------------- +// JPEG lossless transformation routines +// -------------------------------------------------------------------------- + +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombined(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* src_stream, FIMEMORY* dst_stream, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); + + +// -------------------------------------------------------------------------- +// Image manipulation toolkit +// -------------------------------------------------------------------------- + +// rotation and flipping +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rotate(FIBITMAP *dib, double angle, const void *bkcolor FI_DEFAULT(NULL)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateEx(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask); +DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal(FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_FlipVertical(FIBITMAP *dib); + +// upsampling / downsampling +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rescale(FIBITMAP *dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter FI_DEFAULT(FILTER_CATMULLROM)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert FI_DEFAULT(TRUE)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RescaleRect(FIBITMAP *dib, int dst_width, int dst_height, int left, int top, int right, int bottom, FREE_IMAGE_FILTER filter FI_DEFAULT(FILTER_CATMULLROM), unsigned flags FI_DEFAULT(0)); + +// color manipulation routines (point operations) +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustCurve(FIBITMAP *dib, BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel); +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustGamma(FIBITMAP *dib, double gamma); +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustBrightness(FIBITMAP *dib, double percentage); +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustContrast(FIBITMAP *dib, double percentage); +DLL_API BOOL DLL_CALLCONV FreeImage_Invert(FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_GetHistogram(FIBITMAP *dib, DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel FI_DEFAULT(FICC_BLACK)); +DLL_API int DLL_CALLCONV FreeImage_GetAdjustColorsLookupTable(BYTE *LUT, double brightness, double contrast, double gamma, BOOL invert); +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustColors(FIBITMAP *dib, double brightness, double contrast, double gamma, BOOL invert FI_DEFAULT(FALSE)); +DLL_API unsigned DLL_CALLCONV FreeImage_ApplyColorMapping(FIBITMAP *dib, RGBQUAD *srccolors, RGBQUAD *dstcolors, unsigned count, BOOL ignore_alpha, BOOL swap); +DLL_API unsigned DLL_CALLCONV FreeImage_SwapColors(FIBITMAP *dib, RGBQUAD *color_a, RGBQUAD *color_b, BOOL ignore_alpha); +DLL_API unsigned DLL_CALLCONV FreeImage_ApplyPaletteIndexMapping(FIBITMAP *dib, BYTE *srcindices, BYTE *dstindices, unsigned count, BOOL swap); +DLL_API unsigned DLL_CALLCONV FreeImage_SwapPaletteIndices(FIBITMAP *dib, BYTE *index_a, BYTE *index_b); + +// channel processing routines +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetChannel(FIBITMAP *dib, FREE_IMAGE_COLOR_CHANNEL channel); +DLL_API BOOL DLL_CALLCONV FreeImage_SetChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetComplexChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); +DLL_API BOOL DLL_CALLCONV FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); + +// copy / paste / composite routines +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Copy(FIBITMAP *dib, int left, int top, int right, int bottom); +DLL_API BOOL DLL_CALLCONV FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_CreateView(FIBITMAP *dib, unsigned left, unsigned top, unsigned right, unsigned bottom); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Composite(FIBITMAP *fg, BOOL useFileBkg FI_DEFAULT(FALSE), RGBQUAD *appBkColor FI_DEFAULT(NULL), FIBITMAP *bg FI_DEFAULT(NULL)); +DLL_API BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib); + +// background filling routines +DLL_API BOOL DLL_CALLCONV FreeImage_FillBackground(FIBITMAP *dib, const void *color, int options FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_EnlargeCanvas(FIBITMAP *src, int left, int top, int right, int bottom, const void *color, int options FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateEx(int width, int height, int bpp, const RGBQUAD *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, const void *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); + +// miscellaneous algorithms +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MultigridPoissonSolver(FIBITMAP *Laplacian, int ncycle FI_DEFAULT(3)); + +// restore the borland-specific enum size option +#if defined(__BORLANDC__) +#pragma option pop +#endif + +#ifdef __cplusplus +} +#endif + +#endif // FREEIMAGE_H diff --git a/TSE_Core/src/BehaviourScripts/Camera.cpp b/TSE_Core/src/BehaviourScripts/Camera.cpp new file mode 100644 index 0000000..b3db71c --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/Camera.cpp @@ -0,0 +1,203 @@ +#include "Camera.hpp" +#include "elements/Transformable.hpp" +#include "interfaces/IRenderer.hpp" + +TSE::Camera* TSE::Camera::mainCamera = nullptr; + +float TSE::Camera::GetRenderScale() const +{ + return RenderScale; +} + +TSE::ProjectionType TSE::Camera::GetProjection() const +{ + return projection; +} + +float TSE::Camera::GetNearClippingPlane() const +{ + return nearClippingPlane; +} + +float TSE::Camera::GetFarClippingPlane() const +{ + return farClippingPlane; +} + +float TSE::Camera::GetFov() const +{ + return fov; +} + +TSE::Vector3 TSE::Camera::SceenPositionToGamePosition(Vector2 screenPos) +{ + float x = 2.0f * screenPos.x / lastRtSize.x -1.0f; + float y = 1.0f - 2.0f * screenPos.y / lastRtSize.y; + float z = -1.0f; + Vector4 ndc(x,y,x,1); + + Matrix4x4 InversProj = Matrix4x4(*projectionMatrix); + InversProj.Invert(); + Vector4 camSpace = InversProj * ndc; + camSpace = camSpace / camSpace.w; + Vector3 relativPos(camSpace); + relativPos.z = 0; + return baseObject->LocalToGlobalPosition(relativPos); +} + +void TSE::Camera::SetRenderScale(float v) +{ + RenderScale = v; RecalculateProjMatrix(); +} + +void TSE::Camera::SetProjection(ProjectionType v) +{ + projection = v; RecalculateProjMatrix(); +} + +void TSE::Camera::SetNearClippingPlane(float v) +{ + nearClippingPlane = v; RecalculateProjMatrix(); +} + +void TSE::Camera::SetFarClippingPlane(float v) +{ + farClippingPlane = v; RecalculateProjMatrix(); +} + +void TSE::Camera::SetFov(float v) +{ + fov = v; RecalculateProjMatrix(); +} + +TSE::Camera::Camera() +{ +} + +TSE::Camera::~Camera() +{ + delete(projectionMatrix); + if(mainCamera == this) + mainCamera = nullptr; +} + +void TSE::Camera::OnResize(float width, float height, IResizable *wnd) +{ + lastRtSize = {width, height}; + RecalculateProjMatrix(); +} + +void TSE::Camera::SetRenderTarget(IRenderTarget *target) +{ + if(rt != nullptr) + rt->RemoveResizeNotifiable(this); + if(target != nullptr) + target->AddResizeNotifiable(this); + rt = target; + RecalculateProjMatrix(); +} + +TSE::IRenderTarget *TSE::Camera::GetRenderTarget() +{ + return rt; +} + +void TSE::Camera::RecalculateProjMatrix() +{ + if(projectionMatrix) + delete(projectionMatrix); + + if(projection == ProjectionType::Orthographic) + { + float x = lastRtSize.x / RenderScale; + float y = lastRtSize.y / RenderScale; + float mx = -x; + float my = -y; + projectionMatrix = new Matrix4x4(Matrix4x4::Orthographic(mx, x, my, y, nearClippingPlane, farClippingPlane)); + } + else if(projection == ProjectionType::Perspective) + { + float x = lastRtSize.x / RenderScale; + float y = lastRtSize.y / RenderScale; + + float aspectRatio = x / y; + + projectionMatrix = new Matrix4x4(Matrix4x4::Perspective(fov, aspectRatio, nearClippingPlane, farClippingPlane)); + } +} + +void TSE::Camera::OnUpdate() +{ + if(mainCamera == nullptr && baseObject->name != ".EditorCamera") + { + mainCamera = this; + } + IRenderer::camerasToRenderWith.push_back(this); +} + +void TSE::Camera::Start() +{ + if(mainCamera == nullptr && baseObject->name != ".EditorCamera") + { + mainCamera = this; + } +} + + +TSE::Matrix4x4 BuildView_Zplus_RH(const TSE::Matrix4x4& world) +{ + using namespace TSE; + // Welt-Position (w=1) + Vector3 pos = Vector3(world * Vector4(0,0,0,1)); + + // Richtungsachsen in Welt (w=0, KEINE Translation!) + Vector3 fwdWS = Vector3(world * Vector4(0,0,1,0)); // +Z vorwärts in Welt + Vector3 upWS = Vector3(world * Vector4(0,1,0,0)); // +Y oben in Welt + + // Orthonormale Basis aufbauen (X+ soll "right" sein) + Vector3 f = Vector3::Normalize(fwdWS); + Vector3 r = Vector3::Normalize(Vector3::Cross(upWS, f)); // right = up × forward => (+1,0,0) im Identity-Fall + Vector3 u = Vector3::Cross(f, r); // re-orthonormalisiertes up + + Matrix4x4 view(1.0f); // Identität als Basis + + // Row-major befüllen (Zeilen = r,u,-f), letzte Spalte = -dot(row, pos) bzw. +dot(f,pos) + view.m[0][0] = r.x; view.m[0][1] = r.y; view.m[0][2] = r.z; view.m[0][3] = -Vector3::Dot(r, pos); + view.m[1][0] = u.x; view.m[1][1] = u.y; view.m[1][2] = u.z; view.m[1][3] = -Vector3::Dot(u, pos); + view.m[2][0] = -f.x; view.m[2][1] = -f.y; view.m[2][2] = -f.z; view.m[2][3] = Vector3::Dot(f, pos); + view.m[3][0] = 0.0f; view.m[3][1] = 0.0f; view.m[3][2] = 0.0f; view.m[3][3] = 1.0f; + + return view; +} + +void TSE::Camera::PreDraw(IShader *shader) +{ + rt->Bind(); + shader->SetUniform("prMatrix", projectionMatrix); + + auto worlmatrix = baseObject->GetGlobalMatrix(); + + viewMatrix = BuildView_Zplus_RH(worlmatrix); + + shader->SetUniform("camMatrix", &viewMatrix); +} + +void TSE::Camera::PostDraw() +{ + rt->Unbind(); +} + +void TSE::Camera::Bind() +{ + rt->Bind(); +} + +void TSE::Camera::Unbind() +{ + rt->Unbind(); +} + +void TSE::Camera::UpdateRenderTarget() +{ + rt->Update(); +} diff --git a/TSE_Core/src/BehaviourScripts/Camera.hpp b/TSE_Core/src/BehaviourScripts/Camera.hpp new file mode 100644 index 0000000..477ae0f --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/Camera.hpp @@ -0,0 +1,79 @@ +#pragma once + +#define CAMERA typeid(Camera).name() + +#include "interfaces/IShader.hpp" +#include "Matrix4x4.hpp" +#include "Vector2.hpp" +#include "Vector3.hpp" +#include "interfaces/IRenderTarget.hpp" +#include "elements/BehaviourScript.hpp" + +namespace TSE +{ + enum ProjectionType + { + Orthographic = 1, + Perspective = 2, + }; + + class Camera : public IResizeNotifiable, public BehaviourScript + { + private: + float RenderScale = 32; + IRenderTarget* rt = nullptr; + ProjectionType projection = ProjectionType::Orthographic; + Matrix4x4* projectionMatrix = nullptr; + Matrix4x4 viewMatrix; + + float nearClippingPlane = 0; + float farClippingPlane = 100; + + //perspective + float fov = 60; + + Vector2 lastRtSize = {0, 0}; + + public: + static Camera* mainCamera; + + // Getter + float GetRenderScale() const; + ProjectionType GetProjection() const; + float GetNearClippingPlane() const; + float GetFarClippingPlane() const; + float GetFov() const; + + // Setter + Vector3 SceenPositionToGamePosition(Vector2 screenPos); + void SetRenderScale(float v); + void SetProjection(ProjectionType v); + void SetNearClippingPlane(float v); + void SetFarClippingPlane(float v); + void SetFov(float v); + + Camera(); + ~Camera(); + void OnResize(float width, float height, IResizable* wnd) override; + void SetRenderTarget(IRenderTarget* target); + IRenderTarget* GetRenderTarget(); + + void RecalculateProjMatrix(); + + void OnUpdate() override; + void Start() override; + + void PreDraw(IShader* shader); + + void PostDraw(); + + void Bind(); + void Unbind(); + void UpdateRenderTarget(); + + inline const char* GetName() override + { + return "Camera"; + } + }; +} // namespace TSE diff --git a/TSE_Core/src/BehaviourScripts/Image.cpp b/TSE_Core/src/BehaviourScripts/Image.cpp new file mode 100644 index 0000000..0f4a50e --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/Image.cpp @@ -0,0 +1,47 @@ +#include "Image.hpp" + +#include "Renderable.hpp" +#include "MeshContainer.hpp" +#include "Debug.hpp" +#include "elements/Transformable.hpp" + +TSE::Image::Image() +{ +} + +void TSE::Image::SetSprite(Sprite &s) +{ + if(!baseObject->HasBehaviourScript(RENDERABLE) || !baseObject->HasBehaviourScript(MESH_CONTAINER)) + { + TSE_WARNING("Dependencies not found for Image BehaviourScript."); + return; + } + if(&s == nullptr) return; + spr = s; + sprPtr = &spr; + Renderable* r = (Renderable*)baseObject->GetBehaviourScript(RENDERABLE); + r->GetMaterial()->SetValue("mainTex", s.GetTexture()); + MeshContainer* mc = (MeshContainer*)baseObject->GetBehaviourScript(MESH_CONTAINER); + s.GetUVs(mc->GetMesh()->uvs); + lastrect = s.GetUVRect(); +} + +TSE::Sprite &TSE::Image::GetSprite() +{ + return spr; +} + +TSE::Sprite *TSE::Image::GetSpritePtr() +{ + return sprPtr; +} + +void TSE::Image::OnUpdate() +{ + if(lastrect.p1 != spr.GetUVRect().p1 || lastrect.p2 != spr.GetUVRect().p2) + { + lastrect = spr.GetUVRect(); + MeshContainer* mc = (MeshContainer*)baseObject->GetBehaviourScript(MESH_CONTAINER); + spr.GetUVs(mc->GetMesh()->uvs); + } +} diff --git a/TSE_Core/src/BehaviourScripts/Image.hpp b/TSE_Core/src/BehaviourScripts/Image.hpp new file mode 100644 index 0000000..a0f06ec --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/Image.hpp @@ -0,0 +1,29 @@ +#pragma once + +#define IMAGE typeid(Image).name() + +#include "elements/Texture.hpp" +#include "elements/BehaviourScript.hpp" + +namespace TSE +{ + class Image : public BehaviourScript + { + private: + Sprite spr; + Sprite* sprPtr = nullptr; + Rect lastrect; + + public: + Image(); + void SetSprite(Sprite& s); + Sprite& GetSprite(); + Sprite* GetSpritePtr(); + void OnUpdate() override; + inline const char* GetName() override + { + return "Image"; + }; + }; +} // namespace TSE + diff --git a/TSE_Core/src/BehaviourScripts/ImageAnimation.cpp b/TSE_Core/src/BehaviourScripts/ImageAnimation.cpp new file mode 100644 index 0000000..7d6cd6d --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/ImageAnimation.cpp @@ -0,0 +1,88 @@ +#include "ImageAnimation.hpp" +#include "Debug.hpp" +#include "elements/Transformable.hpp" +#include "utils/Time.hpp" + +TSE::ImageAnimation::ImageAnimation() +{ +} + +void TSE::ImageAnimation::SetAnimationSet(ImageAnimationSet *set) +{ + animations[set->Name] = set; +} + +void TSE::ImageAnimation::SetAnimationSet(string name, ImageAnimationSet *set) +{ + animations[name] = set; +} + +void TSE::ImageAnimation::StartAnimation(const string name) +{ + currentAnimation = name; + frame = 0; + deltatime = 0; +} + +int TSE::ImageAnimation::GetImageAnimationSetCount() +{ + return animations.size(); +} + +TSE::ImageAnimationSet *TSE::ImageAnimation::GetImageAnimationAt(int &i) +{ + auto it = animations.begin(); + for (int j = 0; j < i; j++) + { + it++; + } + return it->second; +} + +TSE::string &TSE::ImageAnimation::GetCurrentAnimation() +{ + return currentAnimation; +} + +int &TSE::ImageAnimation::GetCurrentFrame() +{ + return frame; +} + +float &TSE::ImageAnimation::GetDeltaTime() +{ + return deltatime; +} + +void TSE::ImageAnimation::RemoveAnimationSet(std::string &name) +{ + if(currentAnimation == name) + { + currentAnimation = ""; + frame = 0; + deltatime = 0; + } + animations.erase(name); +} + +void TSE::ImageAnimation::OnUpdate() +{ + if(currentAnimation == "") return; + if(animations.find(currentAnimation) == animations.end()) + { + TSE_ERROR("AnimationSet " + currentAnimation + " not found."); + return; + } + deltatime += Time::deltaTime(); + if(deltatime >= animations[currentAnimation]->frameTime) + { + deltatime = 0; + frame++; + if(frame >= animations[currentAnimation]->Sprites.size()) + { + frame = 0; + } + Image* img = (Image*)baseObject->GetBehaviourScript(IMAGE); + img->SetSprite(*animations[currentAnimation]->Sprites[frame]); + } +} diff --git a/TSE_Core/src/BehaviourScripts/ImageAnimation.hpp b/TSE_Core/src/BehaviourScripts/ImageAnimation.hpp new file mode 100644 index 0000000..6c52ee6 --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/ImageAnimation.hpp @@ -0,0 +1,38 @@ +#pragma once + +#define IMAGE_ANIMATION typeid(ImageAnimation).name() + +#include "Image.hpp" +#include "elements/BehaviourScript.hpp" +#include "elements/ImageAnimationSet.hpp" +#include + + +namespace TSE +{ + class ImageAnimation : public BehaviourScript + { + private: + std::unordered_map animations; + string currentAnimation = ""; + int frame = 0; + float deltatime = 0; + + public: + ImageAnimation(); + void SetAnimationSet(ImageAnimationSet* set); + void SetAnimationSet(string name, ImageAnimationSet* set); + void StartAnimation(const string name); + int GetImageAnimationSetCount(); + ImageAnimationSet* GetImageAnimationAt(int& i); + string& GetCurrentAnimation(); + int& GetCurrentFrame(); + float& GetDeltaTime(); + void RemoveAnimationSet(std::string& name); + void OnUpdate() override; + inline const char* GetName() override + { + return "Image Animation"; + } + }; +} // namespace TSE diff --git a/TSE_Core/src/BehaviourScripts/ParticleSystem.cpp b/TSE_Core/src/BehaviourScripts/ParticleSystem.cpp new file mode 100644 index 0000000..a18eacc --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/ParticleSystem.cpp @@ -0,0 +1,233 @@ +#include "ParticleSystem.hpp" +#include +#include +#include +#include "utils/Time.hpp" +#include "elements/Transformable.hpp" + +void TSE::ParticleSystem::OnUpdate() +{ + if(firstFrame) + { + firstFrame = false; + return; + } + particles.erase( + std::remove_if(particles.begin(), particles.end(), + [](auto* particle) + { + particle->lifetime -= Time::deltaTime(); + if (particle->lifetime <= 0.0f) { + delete particle; + return true; // aus vector löschen + } + return false; // behalten + }), + particles.end() + ); + for(auto particle : particles) + { + MoveParticle(particle); + RotateParticle(particle); + ColorParticle(particle); + } + time += Time::deltaTime(); + if(particles.size() < particleCount) + { + const float spawnInterwal = maxLifetime / particleCount; + if(spawnInterwal < Time::deltaTime()) + { + time = 0; + int count = Time::deltaTime() / spawnInterwal; + for (size_t i = 0; i < count; i++) + { + CreateParticle(); + } + } + else + { + if(time >= spawnInterwal) + { + time = 0; + CreateParticle(); + } + } + + } +} + +void TSE::ParticleSystem::Start() +{ + rng = std::mt19937(std::time(nullptr)); +} + +const std::vector &TSE::ParticleSystem::GetParticles() +{ + return particles; +} + +float naive_lerp(float a, float b, float t) +{ + return a + t * (b - a); +} + +void TSE::ParticleSystem::MoveParticle(Particle *&particle) +{ + float age = particle->lifetime / maxLifetime; + float speed = startSpeed; + if(changeSpeedOverLifetime) + { + speed = naive_lerp(startSpeed, endSpeed, age); + } + if(speed == 0) return; + particle->position = Vector3::Lerp(particle->position, particle->position + particle->direction, speed * Time::deltaTime()); +} + +void TSE::ParticleSystem::RotateParticle(Particle *&particle) +{ + float age = particle->lifetime / maxLifetime; + float speed = startRotationSpeed; + if(changeRotationspeedOverLifetime) + { + speed = naive_lerp(startRotationSpeed, endRotationSpeed, age); + } + if(speed == 0) return; + particle->rotationRad = naive_lerp(particle->rotationRad, particle->rotationRad - particle->rotDirection, speed * Time::deltaTime()); +} + +void TSE::ParticleSystem::ColorParticle(Particle *&particle) +{ + float age = particle->lifetime / maxLifetime; + Color c = startColor; + if(changeColorOverLifetime) + { + c = Color::Lerp(endColor, startColor, age); + } + particle->color = c; +} + +void TSE::ParticleSystem::CreateParticle() +{ + std::uniform_real_distribution dist(0.0f, 1.0f); + std::uniform_int_distribution distI(0,1); + + Particle* part = new Particle(); + part->color = startColor; + part->lifetime = maxLifetime; + if(startWithRandomLifetime) + { + part->lifetime = naive_lerp(minLifetime, maxLifetime, dist(rng)); + } + part->size = maxSize; + if(startWithRandomSize) + { + part->size = naive_lerp(minSize, maxSize, dist(rng)); + } + part->rotationRad = maxrotationRad; + if(startWithRandomRotation) + { + part->rotationRad = naive_lerp(minRotationRad, maxrotationRad, dist(rng)); + } + part->rotDirection = rotationDirection; + if(startWithRandomRotationDirection) + { + int rnd = distI(rng); + if(rnd == 0) rnd--; + part->rotDirection = rnd; + } + Vector3 localPos = SamplePointInVolume(rng); + part->position = baseObject->LocalToGlobalPosition(localPos); + Vector3 direction = localPos - offset; + direction.Normalize(); + Vector3 globalOBJPos = baseObject->GetGlobalPosition(); + Vector3 globalOffsetPos = baseObject->LocalToGlobalPosition(direction); + + Vector3 globalDirection = globalOffsetPos - globalOBJPos; + globalDirection.Normalize(); + part->direction = globalDirection; + + particles.push_back(part); +} + +float TSE::ParticleSystem::PlaneAsCosAlpha() +{ + return std::clamp(conePlane * 2.0f - 1.0f, -1.0f, 1.0f); +} + +bool TSE::ParticleSystem::InVolume(const Vector3 &x) +{ + // no cone set + if(conePlane == 0) return false; + + // out of radius + const Vector3 v = x - offset; + const float r2 = v.LengthSqr(); + if(r2 > radius * radius ) return false; + + //full circle + if(conePlane == 1 || r2 <= TSE_EPSILON) return true; + + const float invr = 1.0f / std::sqrt(r2); + const float cosTheta = Vector3::Dot(Vector3(v.x * invr, v.y * invr, v.z * invr), forward); + const float cosA = PlaneAsCosAlpha(); + + if (conePlane <= 0.5f) return cosTheta >= cosA; + else return cosTheta <= cosA; // Inverse +} + +void TSE::ParticleSystem::BuildTangent(Vector3 &t, Vector3 &b) +{ + if (std::abs(forward.z) < 0.999f) + { + t = Vector3::Cross(forward, Vector3::forward); + } + else + { + t = Vector3::Cross(forward, Vector3::up); + } + t.NormalizeSafe(Vector3::right); + + b = Vector3::Cross(forward, t); +} + +TSE::Vector3 TSE::ParticleSystem::SampleDirection(float u1, float u2) +{ + const float cosA = PlaneAsCosAlpha(); + + float z; + if(conePlane == 1) + { + z = -1.0f + 2.0f * u1; + } + // else if(conePlane <= 0.5f) + // { + // z = 1.0f - u1 * (1.0f - cosA); + // } + else + { + z = -1.0f + u1 * (1.0f + cosA); + } + + const float phi = 2.0f * TSE_PI * u2; + const float s = std::sqrt(((0.0f) > (1.0f - z * z)) ? (0.0f) : (1.0f - z * z)); + + Vector3 t, b; + BuildTangent(t,b); + return Vector3(t.x * (s * std::cos(phi)) + b.x * (s * std::sin(phi)) + forward.x * z, + t.y * (s * std::cos(phi)) + b.y * (s * std::sin(phi)) + forward.y * z, + t.z * (s * std::cos(phi)) + b.z * (s * std::sin(phi)) + forward.z * z); +} + +TSE::Vector3 TSE::ParticleSystem::samplePointInVolume(float u1, float u2, float u3) +{ + const Vector3 dir = SampleDirection(u1,u2); + const float r = radius * std::cbrt(u3); + return offset + dir * r; +} + +TSE::Vector3 TSE::ParticleSystem::SamplePointInVolume(std::mt19937 &rng) +{ + if(conePlane == 0) return Vector3::zero; + std::uniform_real_distribution U(0.0f, 1.0f); + return samplePointInVolume(U(rng), U(rng), U(rng)); +} diff --git a/TSE_Core/src/BehaviourScripts/ParticleSystem.hpp b/TSE_Core/src/BehaviourScripts/ParticleSystem.hpp new file mode 100644 index 0000000..d710e0a --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/ParticleSystem.hpp @@ -0,0 +1,95 @@ +#pragma once + +#define PARTICLESYSTEM typeid(ParticleSystem).name() + +#include +#include +#include "Vector3.hpp" +#include "Color.hpp" +#include "MathF.hpp" +#include "elements/BehaviourScript.hpp" + +namespace TSE +{ + struct Particle + { + public: + Vector3 position; + float size; + float rotationRad; + Color color; + + float lifetime; + Vector3 direction; + float rotDirection; + }; + + class ParticleSystem : public BehaviourScript + { + public: + //Random Rotation + bool startWithRandomRotationDirection = false; + float rotationDirection = 1; //1 or -1 //-> used if not random + bool startWithRandomRotation = false; + float minRotationRad = 0; + float maxrotationRad = 2 * TSE_PI; //-> used if not random + //Random Size + bool startWithRandomSize = false; + float minSize = 1; + float maxSize = 2; //-> used if not random + //Random Lifetime + bool startWithRandomLifetime = false; + float minLifetime = 1; // -> smallest possible lifetime + float maxLifetime = 2; // -> biggest possible lifetime -> also the lifetime if not random + //Color over Lifetime + bool changeColorOverLifetime = false; + Color startColor = Color::white; + Color endColor = Color::white; + //Speed over Lifetime + bool changeSpeedOverLifetime = false; + float startSpeed = 1; + float endSpeed = 0.5f; + //Ratationspeed over Lifetime + bool changeRotationspeedOverLifetime = false; + float startRotationSpeed = 1; + float endRotationSpeed = 0.5f; + //Rest + uint particleCount = 10; + bool startWithSimulatedParicles = false; + + //Spawn Area + Vector3 offset; + float conePlane = 1; + float radius = 1; + Vector3 forward = Vector3::forward; + + private: + std::vector particles; + float time; + std::mt19937 rng; + bool firstFrame = true; + + public: + void OnUpdate() override; + void Start() override; + inline const char* GetName() override + { + return "Particle System"; + } + const std::vector& GetParticles(); + + private: + void MoveParticle(Particle*& particle); + void RotateParticle(Particle*& particle); + void ColorParticle(Particle*& particle); + void CreateParticle(); + float PlaneAsCosAlpha(); + bool InVolume(const Vector3& x); + void BuildTangent(Vector3& t, Vector3& b); + Vector3 SampleDirection(float u1, float u2); + Vector3 samplePointInVolume(float u1, float u2, float u3); + + Vector3 SamplePointInVolume(std::mt19937& rng); + }; + +} // namespace TSE diff --git a/TSE_Core/src/elements/ErrorTextureData.hpp b/TSE_Core/src/elements/ErrorTextureData.hpp new file mode 100644 index 0000000..5c70809 --- /dev/null +++ b/TSE_Core/src/elements/ErrorTextureData.hpp @@ -0,0 +1,112 @@ +#pragma once + +constexpr int errorTexWidth = 20; + +constexpr int errorTexHeight = 20; + +constexpr int errorTexBpp = 32; + +constexpr int errorTexChannels = 4; + +const unsigned char errorTextureData[errorTexWidth * errorTexHeight * errorTexChannels] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 +}; \ No newline at end of file diff --git a/TSE_Core/src/elements/ImageAnimationSet.cpp b/TSE_Core/src/elements/ImageAnimationSet.cpp new file mode 100644 index 0000000..7c93dea --- /dev/null +++ b/TSE_Core/src/elements/ImageAnimationSet.cpp @@ -0,0 +1,7 @@ +#include "ImageAnimationSet.hpp" + +TSE::ImageAnimationSet::ImageAnimationSet(std::vector *s, std::string &name) +{ + Sprites = *s; + Name = std::string(name); +} \ No newline at end of file diff --git a/TSE_Core/src/elements/ImageAnimationSet.hpp b/TSE_Core/src/elements/ImageAnimationSet.hpp new file mode 100644 index 0000000..0b5e01b --- /dev/null +++ b/TSE_Core/src/elements/ImageAnimationSet.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "Sprite.hpp" +#include "Types.hpp" + +namespace TSE +{ + struct ImageAnimationSet + { + public: + std::string Name = ""; + std::vector Sprites; + float frameTime = 0; + ImageAnimationSet() = default; + ImageAnimationSet(std::vector* s, std::string& name); + }; +} // namespace TSE diff --git a/TSE_Core/src/elements/Scene.cpp b/TSE_Core/src/elements/Scene.cpp new file mode 100644 index 0000000..6c9e1fd --- /dev/null +++ b/TSE_Core/src/elements/Scene.cpp @@ -0,0 +1,124 @@ +#include "Scene.hpp" + +void TSE::Scene::Render(IRenderer &rnd, const IWindow &wnd) +{ + int counter = 1; + for(auto l : layers) + { + l.second->Render(rnd); + if(counter++ != layers.size()) + { + rnd.End(); //OPTIMIZE: + //takes up 13,97% of function, but only needed, if there is more then one layer + //possible optimizations: + // -remove layers + // -make layer calculations, in shader + // -make an offset, that is calculated on cpu, and then commit everything at once + + // now it is better because it is only done once per frame if only one shader is used, or textures are full, or more then one layers are used + rnd.Flush(); + rnd.Begin(); + wnd.ClearDepthBuffer(); + } + } +} + +void TSE::Scene::DoneRender() +{ + IRenderer::camerasToRenderWith.clear(); +} + +void TSE::Scene::AddLayer(Layer *l) +{ + layers.push_back(std::pair(l->GetName(), l)); +} + +void TSE::Scene::RemoveLayer(const string &name) +{ + auto it = layers.begin(); + for (int j = 0; j < layers.size(); j++) + { + if(it->first == name) + { + layers.erase(it); + break; + } + it++; + } +} + +int TSE::Scene::GetLayerCount() const +{ + return layers.size(); +} + +TSE::Layer *TSE::Scene::GetLayerAt(const int &i) const +{ + auto it = layers.begin(); + for (int j = 0; j < i; j++) + { + it++; + + } + + return (*it).second; +} + +void TSE::Scene::SetName(const string &nname) +{ + name = nname; +} + +TSE::string TSE::Scene::GetName() +{ + return name; +} + +void TSE::Scene::Update() +{ + for(auto l : layers) + { + l.second->Update(); + } +} + +void TSE::Scene::RenameLayer(const string &oldName, const string &newName) +{ + for (int j = 0; j < layers.size(); j++) + { + if(layers[j].first == oldName) + { + layers[j].first = newName; + layers[j].second->SetName(newName); + break; + } + } +} + +void TSE::Scene::MoveLayerUp(Layer *l) +{ + auto it = layers.begin(); + for (int j = 0; j < layers.size(); j++) + { + if(it->first == l->GetName()) + { + std::swap(layers[j-1], layers[j]); + break; + } + it++; + } +} + +void TSE::Scene::MoveLayerDown(Layer *l) +{ + auto it = layers.begin(); + for (int j = 0; j < layers.size(); j++) + { + if(it->first == l->GetName()) + { + std::swap(layers[j+1], layers[j]); + break; + } + it++; + } +} diff --git a/TSE_Core/src/elements/Scene.hpp b/TSE_Core/src/elements/Scene.hpp new file mode 100644 index 0000000..b98c0fa --- /dev/null +++ b/TSE_Core/src/elements/Scene.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include "Layer.hpp" +#include "interfaces/IWindow.hpp" +#include "Types.hpp" + +namespace TSE +{ + class Scene + { + private: + string name = "Unnamed"; + std::vector> layers; + + public: + void Render(IRenderer& rnd, const IWindow& wnd); + void DoneRender(); + void AddLayer(Layer* l); + void RemoveLayer(const string& name); + int GetLayerCount() const; + Layer* GetLayerAt(const int& i) const; + void SetName(const string& name); + string GetName(); + void Update(); + void RenameLayer(const string& oldName, const string& newName); + void MoveLayerUp(Layer* l); + void MoveLayerDown(Layer* l); + }; +} // namespace TSE diff --git a/TSE_Core/src/elements/Sprite.cpp b/TSE_Core/src/elements/Sprite.cpp new file mode 100644 index 0000000..bd0962d --- /dev/null +++ b/TSE_Core/src/elements/Sprite.cpp @@ -0,0 +1,26 @@ +#include "Sprite.hpp" + +TSE::Sprite::Sprite(Texture *tex, Rect bounds) +{ + this->tex = tex; + uvBounds = bounds; +} + +TSE::Texture *TSE::Sprite::GetTexture() +{ + return tex; +} + +TSE::Rect &TSE::Sprite::GetUVRect() +{ + return uvBounds; +} + +void TSE::Sprite::GetUVs(std::vector &uvs) +{ + uvs.clear(); + uvs.push_back(Vector2(uvBounds.p1)); + uvs.push_back(Vector2(uvBounds.p2.x, uvBounds.p1.y)); + uvs.push_back(Vector2(uvBounds.p2)); + uvs.push_back(Vector2(uvBounds.p1.x, uvBounds.p2.y)); +} diff --git a/TSE_Core/src/elements/Sprite.hpp b/TSE_Core/src/elements/Sprite.hpp new file mode 100644 index 0000000..474a683 --- /dev/null +++ b/TSE_Core/src/elements/Sprite.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "Rect.hpp" + +namespace TSE +{ + class Texture; + + struct Sprite + { + private: + Texture* tex = nullptr; + Rect uvBounds = Rect(0,0,0,0); + + public: + inline Sprite() {}; + Sprite(Texture* tex, Rect bounds); + ~Sprite() = default; + Texture* GetTexture(); + Rect& GetUVRect(); + void GetUVs(std::vector& uvs); + }; +} // namespace TSE diff --git a/TSE_Core/src/elements/Texture.cpp b/TSE_Core/src/elements/Texture.cpp new file mode 100644 index 0000000..c1b0961 --- /dev/null +++ b/TSE_Core/src/elements/Texture.cpp @@ -0,0 +1,359 @@ +#include "Texture.hpp" +#include "Debug.hpp" +#include "Color.hpp" +#include "ErrorTextureData.hpp" + +TSE::Texture::Texture(const string &path) +{ + FREE_IMAGE_FORMAT fif = FREE_IMAGE_FORMAT::FIF_UNKNOWN; + bmp = nullptr; + imagePtr = nullptr; + Size = Vector2(0,0); + + fif = FreeImage_GetFileType(path.c_str(), 0); + if(fif == FREE_IMAGE_FORMAT::FIF_UNKNOWN) + fif = FreeImage_GetFIFFromFilename(path.c_str()); + if(fif == FREE_IMAGE_FORMAT::FIF_UNKNOWN) + { + TSE_ERROR("Failed to load image. Unsupported Format."); + Bpp = 24; + makeError(*this); + return; + } + if(FreeImage_FIFSupportsReading(fif)) + { + bmp = FreeImage_Load(fif, path.c_str()); + if(FreeImage_GetBPP(bmp) != 32) + { + auto tmpBmp = FreeImage_ConvertTo32Bits(bmp); + FreeImage_Unload(bmp); + bmp = tmpBmp; + } + } + if(bmp == nullptr) + { + TSE_ERROR("Failed to load image. Bitmap was nullptr."); + Bpp = 24; + makeError(*this); + return; + } + Bpp = FreeImage_GetBPP(bmp); + imagePtr = FreeImage_GetBits(bmp); + + switch (Bpp) + { + case 32: + chanels = 4; + break; + case 24: + chanels = 3; + case 8: + chanels = 4; + } + + Size = Vector2(FreeImage_GetWidth(bmp), FreeImage_GetHeight(bmp)); + regist(); +} + +TSE::Texture::Texture(const int &width, const int &height, int bpp) +{ + switch (bpp) + { + case 32: + chanels = 4; + break; + case 24: + chanels = 3; + case 8: + chanels = 4; + } + Bpp = bpp; + Size = Vector2(width, height); + bmp = FreeImage_Allocate(width, height, bpp); + imagePtr = FreeImage_GetBits(bmp); + regist(); +} + +TSE::Texture::Texture(const Vector2 &size, int bpp) +{ + switch (bpp) + { + case 32: + chanels = 4; + break; + case 24: + chanels = 3; + case 8: + chanels = 4; + } + Bpp = bpp; + Size = size; + bmp = FreeImage_Allocate(size.x, size.y, bpp); + imagePtr = FreeImage_GetBits(bmp); + regist(); +} + +TSE::Texture::~Texture() +{ + if(bmp != nullptr) + { + FreeImage_Unload(bmp); + bmp = nullptr; + } + if(TextureID != 0) + { + //glDeleteTextures(1, &TextureID); --> need to do in platform openGL + PlatformDestroy(); + TextureID = 0; + } +} + +TSE::uint TSE::Texture::bpp() const +{ + return Bpp; +} + +TSE::Vector2 TSE::Texture::size() const +{ + return Size; +} + +float TSE::Texture::width() const +{ + return Size.x; +} + +float TSE::Texture::height() const +{ + return Size.y; +} + +TSE::byte TSE::Texture::Chanels() const +{ + return chanels; +} + +TSE::byte *TSE::Texture::GetImagePtr() const +{ + return imagePtr; +} + +void TSE::Texture::SetPixel(const Vector2 &pos, const Color &c) +{ + SetPixel(pos.x, pos.y, c); +} + +void TSE::Texture::GetPixel(const Vector2 &pos, Color &c) const +{ + GetPixel(pos.x, pos.y, c); +} + +void TSE::Texture::SetPixelNoApply(const Vector2 &pos, const Color &c) +{ + SetPixelNoApply(pos.x, pos.y, c); +} + +void TSE::Texture::ToSprite(Sprite &s) +{ + s = Sprite(this, Rect(0,0,1,1)); +} + +void TSE::Texture::SetChanels(const byte &ch) +{ + chanels = ch; +} + +uint TSE::Texture::GetTextureId() const +{ + return TextureID; +} + +void TSE::Texture::SetTextureId(uint id) +{ + TextureID = id; +} + +void TSE::Texture::SetPixel(const int &x, const int &y, const Color &c) +{ + SetPixelNoApply(x,y,c); + Apply(); +} + +void TSE::Texture::GetPixel(const int &x, const int &y, Color &c) const +{ + if(x >= width() || x < 0 ||y >= height() || y < 0) + { + TSE_WARNING("trying to access pixel outside of texture.\n pixel: (" + std::to_string(x) + ";" + std::to_string(y) + ")\nTexture size: (" + std::to_string(width()) + ";" + std::to_string(height()) ); + return; + } + byte* pixel = getPixelPointer(x,y); + byte b = *pixel++; + byte g = *pixel++; + byte r = *pixel++; + byte a = *pixel++; + if(bpp() == 8) + c = Color(r,r,r); + else if(bpp() == 24) + c = Color(r,g,b,a); + else if(bpp() == 32) + c = Color(r,g,b); +} + +void TSE::Texture::Fill(const Color &c) +{ + for (int x = 0; x < width(); x++) + { + for (int y = 0; y < height(); y++) + { + SetPixelNoApply(x,y,c); + } + + } + Apply(); +} + +void TSE::Texture::SetPixelNoApply(const int &x, const int &y, const Color &c) +{ + if(x >= width() || x < 0 ||y >= height() || y < 0) + { + TSE_WARNING("trying to access pixel outside of texture.\n pixel: (" + std::to_string(x) + ";" + std::to_string(y) + ")\nTexture size: (" + std::to_string(width()) + ";" + std::to_string(height()) ); + return; + } + + byte* pixel = getPixelPointer(x,y); + if(chanels == 4 && bpp() == 8) + { + byte r2bit = static_cast(c.r * 3.0f); + byte g2bit = static_cast(c.g * 3.0f); + byte b2bit = static_cast(c.b * 3.0f); + byte a2bit = static_cast(c.a * 3.0f); + + byte result = (r2bit << 6) | (g2bit << 4) | (b2bit << 2) | a2bit; + *pixel++ = result; + return; + } + *pixel++ = c.B(); + if(bpp() > 8) + { + *pixel++ = c.G(); + *pixel++ = c.R(); + if(bpp() > 24) + *pixel++ = c.A(); + } +} + +void TSE::Texture::AddPixelNoApply(const int &x, const int &y, const Color &c) +{ + if(x >= width() || x < 0 ||y >= height() || y < 0) + { + TSE_WARNING("trying to access pixel outside of texture.\n pixel: (" + std::to_string(x) + ";" + std::to_string(y) + ")\nTexture size: (" + std::to_string(width()) + ";" + std::to_string(height()) ); + return; + } + + byte* pixel = getPixelPointer(x,y); + if(chanels == 4 && bpp() == 8) //TODO add propper adding, becouse currently is only setting + { + byte r2bit = static_cast(c.r * 3.0f); + byte g2bit = static_cast(c.g * 3.0f); + byte b2bit = static_cast(c.b * 3.0f); + byte a2bit = static_cast(c.a * 3.0f); + + byte result = (r2bit << 6) | (g2bit << 4) | (b2bit << 2) | a2bit; + *pixel++ = result; + return; + } + Color bc(pixel[2], pixel[1], pixel[0], pixel[3]); + + bc = c + bc; + + *pixel++ = bc.B(); + if(bpp() > 8) + { + *pixel++ = bc.G(); + *pixel++ = bc.R(); + if(bpp() > 24) + *pixel++ = bc.A(); + } +} + +void TSE::Texture::Recreate(const int &x, const int &y, const int &bpp, const int &chanels) +{ + if(bmp != nullptr) + { + FreeImage_Unload(bmp); + bmp = nullptr; + } + if(TextureID != 0) + { + PlatformDestroy(); + TextureID = 0; + } + this->chanels = chanels; + Bpp = bpp; + Size = Vector2(x, y); + bmp = FreeImage_Allocate(x, y, bpp); + imagePtr = FreeImage_GetBits(bmp); + regist(); +} + +void TSE::Texture::SavePNG(const std::string &path) const +{ + if(!FreeImage_Save(FREE_IMAGE_FORMAT::FIF_PNG, bmp, path.c_str(), PNG_Z_NO_COMPRESSION)) + TSE_ERROR("Failed to save Image to \"" + path + "\""); +} + +TSE::byte *TSE::Texture::getPixelPointer(const int &x, const int &y) const +{ + int alphaoffset = y * 2; + if(bpp() > 24) + alphaoffset = 0; + int offset = ((y * width() + x) * (bpp() / 8) + alphaoffset); + return imagePtr + offset; +} + +void TSE::Texture::makeError(Texture &tex) +{ + tex.Bpp = errorTexBpp; + tex.chanels = errorTexChannels; + tex.Size = Vector2(errorTexWidth, errorTexHeight); + + tex.bmp = FreeImage_ConvertFromRawBits( + const_cast(errorTextureData), // wichtig: cast! + errorTexWidth, + errorTexHeight, + errorTexWidth * errorTexChannels, + errorTexBpp, + FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, + FI_RGBA_BLUE_MASK, + true // top-down + ); + + tex.imagePtr = FreeImage_GetBits(tex.bmp); + tex.regist(); +} + +void TSE::Texture::bind() const +{ + helper->Bind(this); +} + +void TSE::Texture::unbind() const +{ + helper->UnBind(this); +} + +void TSE::Texture::Apply() +{ + helper->Apply(this); +} + +void TSE::Texture::regist() +{ + helper->Regist(this); +} + +void TSE::Texture::PlatformDestroy() +{ + helper->PlatromDestroy(this); +} diff --git a/TSE_Core/src/elements/Texture.hpp b/TSE_Core/src/elements/Texture.hpp new file mode 100644 index 0000000..ee7aa89 --- /dev/null +++ b/TSE_Core/src/elements/Texture.hpp @@ -0,0 +1,62 @@ +#pragma once + +#include "Sprite.hpp" +#include "interfaces/ITexture.hpp" +#include "Types.hpp" +#include "Vector2.hpp" +#include "interfaces/ITextureHelper.hpp" + +#define FREEIMAGE_LIB +#include "FI/FreeImage.h" + +namespace TSE +{ + class Texture : public ITexture + { + protected: + uint TextureID = 0; + Vector2 Size; + uint Bpp; + byte chanels = 0; + FIBITMAP* bmp = nullptr; + byte* imagePtr = nullptr; + + public: + string name = "Unnamed"; + static ITextureHelper* helper; + + Texture(const string& path); + Texture(const int& width, const int& height, int bpp = 32); + Texture(const Vector2& size, int bpp = 32); + ~Texture(); + + uint bpp() const; + Vector2 size() const override; + float width() const override; + float height() const override; + byte Chanels() const; + byte* GetImagePtr() const; + void SetPixel(const Vector2& pos, const Color& c); + void GetPixel(const Vector2& pos, Color& c) const; + void SetPixelNoApply(const Vector2& pos, const Color& c); + void ToSprite(Sprite& s); + void SetChanels(const byte& ch); + uint GetTextureId() const override; + void SetTextureId(uint id); + void SetPixel(const int& x, const int& y, const Color& c); + void GetPixel(const int& x, const int& y, Color& c) const; + void Fill(const Color& c); + void SetPixelNoApply(const int& x, const int& y, const Color& c); + void AddPixelNoApply(const int& x, const int& y, const Color& c); + void Recreate(const int& x, const int& y, const int& bpp, const int& chanels); + void SavePNG(const std::string& path) const; + byte* getPixelPointer(const int& x, const int& y) const; + static void makeError(Texture& tex); + + void bind() const; + void unbind() const; + void Apply(); + void regist(); + void PlatformDestroy(); + }; +} // namespace TSE diff --git a/TSE_Core/src/elements/TileSet.cpp b/TSE_Core/src/elements/TileSet.cpp new file mode 100644 index 0000000..e37c7b6 --- /dev/null +++ b/TSE_Core/src/elements/TileSet.cpp @@ -0,0 +1,35 @@ +#include "TileSet.hpp" +#include "Debug.hpp" + +#define PADDING 0.0f + +TSE::TileSet::TileSet(Texture *tex, int x, int y) +{ + SetTexture(tex); + SetCount(x,y); +} + +void TSE::TileSet::SetCount(int x, int y) +{ + resx = x; + resy = y; +} + +void TSE::TileSet::SetTexture(Texture *tex) +{ + this->tex = tex; +} + +void TSE::TileSet::GetSpriteAt(int x, int y, Sprite &s) +{ + if(x < 0 || x >= resx || y < 0 || y >= resy) + { + TSE_ERROR("The sprite you are trying to access is out of range"); + return; + } + + Vector2 startpos = Vector2(((tex->size().x / resx) * (x + PADDING)) / tex->size().x, ((tex->size().y / resy) * (y + PADDING)) / tex->size().y); + Vector2 endpos = Vector2(((tex->size().x / resx) * ((x + 1) - PADDING)) / tex->size().x, ((tex->size().y / resy) * ((y + 1) - PADDING)) / tex->size().y); + + s = Sprite(tex, Rect(startpos, endpos)); +} diff --git a/TSE_Core/src/elements/TileSet.hpp b/TSE_Core/src/elements/TileSet.hpp new file mode 100644 index 0000000..d5fa3dd --- /dev/null +++ b/TSE_Core/src/elements/TileSet.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "Texture.hpp" +#include "Sprite.hpp" + +namespace TSE +{ + class TileSet + { + private: + Texture* tex = nullptr; + int resx = 0, resy = 0; + + public: + TileSet(Texture* tex, int x, int y); + + void SetCount(int x, int y); + void SetTexture(Texture* tex); + + void GetSpriteAt(int x, int y, Sprite& s); + + inline void SetCount(Vector2& v) + { + SetCount(v.x, v.y); + }; + inline void GetSpriteAt(Vector2& v, Sprite& s) + { + GetSpriteAt(v.x, v.y, s); + }; + }; +} // namespace TSE diff --git a/TSE_Core/src/interfaces/ITextureHelper.hpp b/TSE_Core/src/interfaces/ITextureHelper.hpp new file mode 100644 index 0000000..eac9141 --- /dev/null +++ b/TSE_Core/src/interfaces/ITextureHelper.hpp @@ -0,0 +1,16 @@ +#pragma once + +namespace TSE +{ + class Texture; + + class ITextureHelper + { + public: + virtual void Bind(const Texture* tex) = 0; + virtual void UnBind(const Texture* tex) = 0; + virtual void Apply(Texture* tex) = 0; + virtual void Regist(Texture* tex) = 0; + virtual void PlatromDestroy(Texture* tex) = 0; + }; +} // namespace TSE diff --git a/TSE_GlfwImpl/src/InputGlfw.cpp b/TSE_GlfwImpl/src/InputGlfw.cpp index 7fa9df8..06a7f62 100644 --- a/TSE_GlfwImpl/src/InputGlfw.cpp +++ b/TSE_GlfwImpl/src/InputGlfw.cpp @@ -1,16 +1,16 @@ #include "InputGlfw.hpp" -void TSE::InputGlfw::Init() +void TSE::GLFW::InputGlfw::Init() { Instance = new InputGlfw(); } -void TSE::InputGlfw::Delete() +void TSE::GLFW::InputGlfw::Delete() { delete(Instance); } -void TSE::InputGlfw::KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) +void TSE::GLFW::InputGlfw::KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { switch (action) { @@ -35,7 +35,7 @@ void TSE::InputGlfw::KeyCallback(GLFWwindow *window, int key, int scancode, int } } -void TSE::InputGlfw::MouseButtonCallback(GLFWwindow *window, int button, int action, int mods) +void TSE::GLFW::InputGlfw::MouseButtonCallback(GLFWwindow *window, int button, int action, int mods) { switch (action) { @@ -60,7 +60,7 @@ void TSE::InputGlfw::MouseButtonCallback(GLFWwindow *window, int button, int act } } -void TSE::InputGlfw::CursorPosCallback(GLFWwindow *window, double xpos, double ypos) +void TSE::GLFW::InputGlfw::CursorPosCallback(GLFWwindow *window, double xpos, double ypos) { for(auto handler : ((InputGlfw*)instance())->cursorHandler) { @@ -68,7 +68,7 @@ void TSE::InputGlfw::CursorPosCallback(GLFWwindow *window, double xpos, double y } } -void TSE::InputGlfw::ScrollCallback(GLFWwindow *window, double xoffset, double yoffset) +void TSE::GLFW::InputGlfw::ScrollCallback(GLFWwindow *window, double xoffset, double yoffset) { for(auto handler : ((InputGlfw*)instance())->cursorHandler) { @@ -99,7 +99,7 @@ std::string UTF32ToUTF8(char32_t ch) return result; } -void TSE::InputGlfw::CharCallback(GLFWwindow *window, unsigned int codepoint) +void TSE::GLFW::InputGlfw::CharCallback(GLFWwindow *window, unsigned int codepoint) { char32_t c = static_cast(codepoint); std::string msg = UTF32ToUTF8(c); diff --git a/TSE_GlfwImpl/src/InputGlfw.hpp b/TSE_GlfwImpl/src/InputGlfw.hpp index ec50375..38a3c2c 100644 --- a/TSE_GlfwImpl/src/InputGlfw.hpp +++ b/TSE_GlfwImpl/src/InputGlfw.hpp @@ -3,7 +3,7 @@ #include "interfaces/IInputManager.hpp" #include "GLFW/glfw3.h" -namespace TSE +namespace TSE::GLFW { class InputGlfw : public IInputManager { diff --git a/TSE_GlfwOpenGlImpl/src/OpenGLRenderingBackend.cpp b/TSE_GlfwOpenGlImpl/src/OpenGLRenderingBackend.cpp index 41bcbe7..0f8d9a3 100644 --- a/TSE_GlfwOpenGlImpl/src/OpenGLRenderingBackend.cpp +++ b/TSE_GlfwOpenGlImpl/src/OpenGLRenderingBackend.cpp @@ -8,6 +8,8 @@ #include "extern/imgui_impl_glfw.h" #include "extern/imgui_impl_opengl3.h" #include "PathHelper.hpp" +#include "elements/Texture.hpp" +#include "TextureHelperOpenGL.hpp" TSE::GLFW::OpenGLRenderingBackend::OpenGLRenderingBackend(Color _backgroundColor, bool _vsync) : OpenGLRenderingBackend(_backgroundColor, _vsync, 0, false){ } @@ -32,6 +34,8 @@ TSE::GLFW::OpenGLRenderingBackend::~OpenGLRenderingBackend() void TSE::GLFW::OpenGLRenderingBackend::InitPreWindow() { + Texture::helper = new TextureHelperOpenGL(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, TSE_OPENGL_VERSION_MAJOR); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, TSE_OPENGL_VERSION_MINOR); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, 1); diff --git a/TSE_GlfwOpenGlImpl/src/TextureHelperOpenGL.cpp b/TSE_GlfwOpenGlImpl/src/TextureHelperOpenGL.cpp new file mode 100644 index 0000000..1a285ea --- /dev/null +++ b/TSE_GlfwOpenGlImpl/src/TextureHelperOpenGL.cpp @@ -0,0 +1,60 @@ +#include "TextureHelperOpenGL.hpp" +#include + +void TSE::GLFW::TextureHelperOpenGL::Bind(const Texture *tex) +{ + glBindTexture(GL_TEXTURE_2D, tex->GetTextureId()); +} + +void TSE::GLFW::TextureHelperOpenGL::UnBind(const Texture *tex) +{ + glBindTexture(GL_TEXTURE_2D, 0); +} + +void TSE::GLFW::TextureHelperOpenGL::Apply(Texture *tex) +{ + glBindTexture(GL_TEXTURE_2D, tex->GetTextureId()); + if(tex->Chanels() == 1) + { + if (tex->bpp() == 8) + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->width(), tex->height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr()); + } + if(tex->Chanels() == 3) + { + if(tex->bpp() == 24) + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->width(), tex->height(), 0, GL_BGR, GL_UNSIGNED_BYTE, tex->GetImagePtr()); + } + else if(tex->Chanels() == 4) + { + if(tex->bpp() == 32) + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->width(), tex->height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, tex->GetImagePtr()); + if (tex->bpp() == 8) //need to decode it with bitwise operations in shader + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->width(), tex->height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr()); + } + + glGenerateMipmap(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, 0); +} + +void TSE::GLFW::TextureHelperOpenGL::Regist(Texture *tex) +{ + uint TextureID; + + glGenTextures(1, &TextureID); + glBindTexture(GL_TEXTURE_2D, TextureID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + tex->SetTextureId(TextureID); + + tex->Apply(); +} + +void TSE::GLFW::TextureHelperOpenGL::PlatromDestroy(Texture *tex) +{ + uint id = tex->GetTextureId(); + glDeleteTextures(1, &id); +} diff --git a/TSE_GlfwOpenGlImpl/src/TextureHelperOpenGL.hpp b/TSE_GlfwOpenGlImpl/src/TextureHelperOpenGL.hpp new file mode 100644 index 0000000..adf77cb --- /dev/null +++ b/TSE_GlfwOpenGlImpl/src/TextureHelperOpenGL.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "interfaces/ITextureHelper.hpp" +#include "elements/Texture.hpp" + +namespace TSE::GLFW +{ + class TextureHelperOpenGL : public ITextureHelper + { + public: + void Bind(const Texture* tex) override; + void UnBind(const Texture* tex) override; + void Apply(Texture* tex) override; + void Regist(Texture* tex) override; + void PlatromDestroy(Texture* tex) override; + }; +} // namespace TSE::GLFW