@ -4,24 +4,24 @@
*
* CONFIGURATION :
*
* # define SUPPORT_STB_IMAGE / INCLUDE_STB_IMAGE
*
* # define SUPPORT_FILEFORMAT_BMP / SUPPORT_LOAD_BMP
* # define SUPPORT_FILEFORMAT_PNG / SUPPORT_LOAD_PNG
* # define SUPPORT_FILEFORMAT_BMP
* # define SUPPORT_FILEFORMAT_PNG
* # define SUPPORT_FILEFORMAT_TGA
* # define SUPPORT_FILEFORMAT_JPG / ENABLE_LOAD_JPG
* # define SUPPORT_FILEFORMAT_JPG
* # define SUPPORT_FILEFORMAT_GIF
* # define SUPPORT_FILEFORMAT_PSD
* # define SUPPORT_FILEFORMAT_HDR
* # define SUPPORT_FILEFORMAT_DDS / ENABLE_LOAD_DDS
* # define SUPPORT_FILEFORMAT_DDS
* # define SUPPORT_FILEFORMAT_PKM
* # define SUPPORT_FILEFORMAT_KTX
* # define SUPPORT_FILEFORMAT_PVR
* # define SUPPORT_FILEFORMAT_ASTC
* Selected desired fileformats to be supported for loading . Some of those formats are
* Selecte desired fileformats to be supported for image data loading . Some of those formats are
* supported by default , to remove support , just comment unrequired # define in this module
*
* # define SUPPORT_IMAGE_RESIZE / INCLUDE_STB_IMAGE_RESIZE
* # define SUPPORT_IMAGE_MANIPULATION
* Support multiple image editing functions to scale , adjust colors , flip , draw on images , crop . . .
* If not defined only three image editing functions supported : ImageFormat ( ) , ImageAlphaMask ( ) , ImageToPOT ( )
*
* DEPENDENCIES :
* stb_image - Multiple image formats loading ( JPEG , PNG , BMP , TGA , PSD , GIF , PIC )
@ -50,6 +50,12 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/ / Default configuration flags ( supported features )
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# define SUPPORT_FILEFORMAT_PNG
# define SUPPORT_IMAGE_MANIPULATION
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# include "raylib.h"
# include <stdlib.h> // Required for: malloc(), free()
@ -61,23 +67,46 @@
# include "utils.h" // Required for: fopen() Android mapping, TraceLog()
/ / Support only desired texture formats , by default : JPEG , PNG , BMP , TGA
/ / # define STBI_NO_JPEG / / Image format . jpg and . jpeg
/ / # define STBI_NO_PNG
/ / # define STBI_NO_BMP
/ / # define STBI_NO_TGA
# define STBI_NO_PSD
# define STBI_NO_GIF
# define STBI_NO_HDR
/ / Support only desired texture formats on stb_image
# if !defined(SUPPORT_FILEFORMAT_BMP)
# define STBI_NO_BMP
# endif
# if !defined(SUPPORT_FILEFORMAT_PNG)
# define STBI_NO_PNG
# endif
# if !defined(SUPPORT_FILEFORMAT_TGA)
# define STBI_NO_TGA
# endif
# if !defined(SUPPORT_FILEFORMAT_JPG)
# define STBI_NO_JPEG / / Image format .jpg and .jpeg
# endif
# if !defined(SUPPORT_FILEFORMAT_PSD)
# define STBI_NO_PSD
# endif
# if !defined(SUPPORT_FILEFORMAT_GIF)
# define STBI_NO_GIF
# endif
# if !defined(SUPPORT_FILEFORMAT_HDR)
# define STBI_NO_HDR
# endif
/ / Image fileformats not supported by default
# define STBI_NO_PIC
# define STBI_NO_PNM / / Image format .ppm and .pgm
# define STB_IMAGE_IMPLEMENTATION
# include "external/stb_image.h" // Required for: stbi_load()
/ / NOTE : Used to read image data ( multiple formats support )
# define STB_IMAGE_RESIZE_IMPLEMENTATION
# include "external/stb_image_resize.h" // Required for: stbir_resize_uint8()
/ / NOTE : Used for image scaling on ImageResize ( )
# if (defined(SUPPORT_FILEFORMAT_BMP) || defined(SUPPORT_FILEFORMAT_PNG) || defined(SUPPORT_FILEFORMAT_TGA) || \
defined ( SUPPORT_FILEFORMAT_JPG ) | | defined ( SUPPORT_FILEFORMAT_PSD ) | | defined ( SUPPORT_FILEFORMAT_GIF ) | | \
defined ( SUPPORT_FILEFORMAT_HDR ) )
# define STB_IMAGE_IMPLEMENTATION
# include "external/stb_image.h" // Required for: stbi_load()
/ / NOTE : Used to read image data ( multiple formats support )
# endif
# if defined(SUPPORT_IMAGE_MANIPULATION)
# define STB_IMAGE_RESIZE_IMPLEMENTATION
# include "external/stb_image_resize.h" // Required for: stbir_resize_uint8()
/ / NOTE : Used for image scaling on ImageResize ( )
# endif
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Defines and Macros
@ -102,11 +131,21 @@
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Module specific Functions Declaration
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# if defined(SUPPORT_FILEFORMAT_DDS)
static Image LoadDDS ( const char * fileName ) ; / / Load DDS file
# endif
# if defined(SUPPORT_FILEFORMAT_PKM)
static Image LoadPKM ( const char * fileName ) ; / / Load PKM file
# endif
# if defined(SUPPORT_FILEFORMAT_KTX)
static Image LoadKTX ( const char * fileName ) ; / / Load KTX file
# endif
# if defined(SUPPORT_FILEFORMAT_PVR)
static Image LoadPVR ( const char * fileName ) ; / / Load PVR file
# endif
# if defined(SUPPORT_FILEFORMAT_ASTC)
static Image LoadASTC ( const char * fileName ) ; / / Load ASTC file
# endif
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Module Functions Definition
@ -124,18 +163,32 @@ Image LoadImage(const char *fileName)
image . mipmaps = 0 ;
image . format = 0 ;
if ( ( strcmp ( GetExtension ( fileName ) , " png " ) = = 0 ) | |
( strcmp ( GetExtension ( fileName ) , " bmp " ) = = 0 ) | |
( strcmp ( GetExtension ( fileName ) , " tga " ) = = 0 ) | |
( strcmp ( GetExtension ( fileName ) , " jpg " ) = = 0 )
# ifndef STBI_NO_GIF
| | ( strcmp ( GetExtension ( fileName ) , " gif " ) = = 0 )
if ( IsFileExtension ( fileName , " .rres " ) )
{
RRES rres = LoadResource ( fileName , 0 ) ;
/ / NOTE : Parameters for RRES_TYPE_IMAGE are : width , height , format , mipmaps
if ( rres [ 0 ] . type = = RRES_TYPE_IMAGE ) image = LoadImagePro ( rres [ 0 ] . data , rres [ 0 ] . param1 , rres [ 0 ] . param2 , rres [ 0 ] . param3 ) ;
else TraceLog ( WARNING , " [%s] Resource file does not contain image data " , fileName ) ;
UnloadResource ( rres ) ;
}
else if ( ( IsFileExtension ( fileName , " .png " ) )
# if defined(SUPPORT_FILEFORMAT_BMP)
| | ( IsFileExtension ( fileName , " .bmp " ) )
# endif
# if defined(SUPPORT_FILEFORMAT_TGA)
| | ( IsFileExtension ( fileName , " .tga " ) )
# endif
# ifndef STBI_NO_PSD
| | ( strcmp ( GetExtension ( fileName ) , " psd " ) = = 0 )
# if defined(SUPPORT_FILEFORMAT_JPG)
| | ( IsFileExtension ( fileName , " .jpg " ) )
# endif
# ifndef STBI_NO_PIC
| | ( strcmp ( GetExtension ( fileName ) , " pic " ) = = 0 )
# if defined(SUPPORT_FILEFORMAT_DDS)
| | ( IsFileExtension ( fileName , " .gif " ) )
# endif
# if defined(SUPPORT_FILEFORMAT_PSD)
| | ( IsFileExtension ( fileName , " .psd " ) )
# endif
)
{
@ -155,22 +208,22 @@ Image LoadImage(const char *fileName)
else if ( imgBpp = = 3 ) image . format = UNCOMPRESSED_R8G8B8 ;
else if ( imgBpp = = 4 ) image . format = UNCOMPRESSED_R8G8B8A8 ;
}
else if ( strcmp ( GetExtension ( fileName ) , " dds " ) = = 0 ) image = LoadDDS ( fileName ) ;
else if ( strcmp ( Get Extension( fileName ) ," pkm " ) = = 0 ) image = LoadPKM ( fileName ) ;
else if ( strcmp ( GetExtension ( fileName ) , " ktx " ) = = 0 ) image = LoadKTX ( fileName ) ;
else if ( strcmp ( GetExtension ( fileName ) , " pvr " ) = = 0 ) image = LoadPVR ( fileName ) ;
else if ( strcmp ( GetExtension ( fileName ) , " astc " ) = = 0 ) image = LoadASTC ( fileName ) ;
else if ( strcmp ( GetExtension ( fileName ) , " rres " ) = = 0 )
{
RRES rres = LoadResource ( fileName , 0 ) ;
/ / NOTE : Parameters for RRES_TYPE_IMAGE are : width , height , format , mipmaps
if ( rres [ 0 ] . type = = RRES_TYPE_IMAGE ) image = LoadImagePro ( rres [ 0 ] . data , rres [ 0 ] . param1 , rres [ 0 ] . param2 , rres [ 0 ] . param3 ) ;
else TraceLog ( WARNING , " [%s] Resource file does not contain image data " , fileName ) ;
UnloadResource ( rres ) ;
p">}
# if defined(SUPPORT_FILEFORMAT_DDS)
else if ( IsFile Extension( fileName , " .dds " ) ) image = LoadDDS ( fileName ) ;
# endif
# if defined(SUPPORT_FILEFORMAT_PKM)
else if ( IsFileExtension ( fileName , " .pkm " ) ) image = LoadPKM ( fileName ) ;
# endif
# if defined(SUPPORT_FILEFORMAT_KTX)
else if ( IsFileExtension ( fileName , " .ktx " ) ) image = LoadKTX ( fileName ) ;
# endif
# if defined(SUPPORT_FILEFORMAT_PVR)
else if ( IsFileExtension ( fileName , " .pvr " ) ) image = LoadPVR ( fileName ) ;
# endif
# if defined(SUPPORT_FILEFORMAT_ASTC)
else if ( IsFileExtension ( fileName , " .astc " ) ) image = LoadASTC ( fileName ) ;
# endif
k">else TraceLog ( WARNING , " [%s] Image fileformat not supported " , fileName ) ;
if ( image . data ! = NULL ) TraceLog ( INFO , " [%s] Image loaded successfully (%ix%i) " , fileName , image . width , image . height ) ;
else TraceLog ( WARNING , " [%s] Image could not be loaded " , fileName ) ;
@ -664,115 +717,6 @@ void ImageAlphaMask(Image *image, Image alphaMask)
}
}
/ / Dither image data to 16 bpp or lower ( Floyd - Steinberg dithering )
/ / NOTE : In case selected bpp do not represent an known 16 bit format ,
/ / dithered data is stored in the LSB part of the unsigned short
void ImageDither ( Image * image , int rBpp , int gBpp , int bBpp , int aBpp )
{
if ( image - > format > = COMPRESSED_DXT1_RGB )
{
TraceLog ( WARNING , " Compressed data formats can not be dithered " ) ;
return ;
}
if ( ( rBpp + gBpp + bBpp + aBpp ) > 16 )
{
TraceLog ( WARNING , " Unsupported dithering bpps (%ibpp), only 16bpp or lower modes supported " , ( rBpp + gBpp + bBpp + aBpp ) ) ;
}
else
{
Color * pixels = GetImageData ( * image ) ;
free ( image - > data ) ; / / free old image data
if ( ( image - > format ! = UNCOMPRESSED_R8G8B8 ) & & ( image - > format ! = UNCOMPRESSED_R8G8B8A8 ) )
{
TraceLog ( WARNING , " Image format is already 16bpp or lower, dithering could have no effect " ) ;
}
/ / Define new image format , check if desired bpp match internal known format
if ( ( rBpp = = 5 ) & & ( gBpp = = 6 ) & & ( bBpp = = 5 ) & & ( aBpp = = 0 ) ) image - > format = UNCOMPRESSED_R5G6B5 ;
else if ( ( rBpp = = 5 ) & & ( gBpp = = 5 ) & & ( bBpp = = 5 ) & & ( aBpp = = 1 ) ) image - > format = UNCOMPRESSED_R5G5B5A1 ;
else if ( ( rBpp = = 4 ) & & ( gBpp = = 4 ) & & ( bBpp = = 4 ) & & ( aBpp = = 4 ) ) image - > format = UNCOMPRESSED_R4G4B4A4 ;
else
{
image - > format = 0 ;
TraceLog ( WARNING , " Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i) " , ( rBpp + gBpp + bBpp + aBpp ) , rBpp , gBpp , bBpp , aBpp ) ;
}
/ / NOTE : We will store the dithered data as unsigned short ( 16 bpp )
image - > data = ( unsigned short * ) malloc ( image - > width * image - > height * sizeof ( unsigned short ) ) ;
Color oldPixel = WHITE ;
Color newPixel = WHITE ;
int rError , gError , bError ;
unsigned short rPixel , gPixel , bPixel , aPixel ; / / Used for 16 bit pixel composition
# define MIN(a,b) (((a)<(b))?(a):(b))
for ( int y = 0 ; y < image - > height ; y + + )
{
for ( int x = 0 ; x < image - > width ; x + + )
{
oldPixel = pixels [ y * image - > width + x ] ;
/ / NOTE : New pixel obtained by bits truncate , it would be better to round values ( check ImageFormat ( ) )
newPixel . r = oldPixel . r > > ( 8 - rBpp ) ; / / R bits
newPixel . g = oldPixel . g > > ( 8 - gBpp ) ; / / G bits
newPixel . b = oldPixel . b > > ( 8 - bBpp ) ; / / B bits
newPixel . a = oldPixel . a > > ( 8 - aBpp ) ; / / A bits ( not used on dithering )
/ / NOTE : Error must be computed between new and old pixel but using same number of bits !
/ / We want to know how much color precision we have lost . . .
rError = ( int ) oldPixel . r - ( int ) ( newPixel . r < < ( 8 - rBpp ) ) ;
gError = ( int ) oldPixel . g - ( int ) ( newPixel . g < < ( 8 - gBpp ) ) ;
bError = ( int ) oldPixel . b - ( int ) ( newPixel . b < < ( 8 - bBpp ) ) ;
pixels [ y * image - > width + x ] = newPixel ;
/ / NOTE : Some cases are out of the array and should be ignored
if ( x < ( image - > width - 1 ) )
{
pixels [ y * image - > width + x + 1 ] . r = MIN ( ( int ) pixels [ y * image - > width + x + 1 ] . r + ( int ) ( ( float ) rError * 7.0f / 16 ) , 0xff ) ;
pixels [ y * image - > width + x + 1 ] . g = MIN ( ( int ) pixels [ y * image - > width + x + 1 ] . g + ( int ) ( ( float ) gError * 7.0f / 16 ) , 0xff ) ;
pixels [ y * image - > width + x + 1 ] . b = MIN ( ( int ) pixels [ y * image - > width + x + 1 ] . b + ( int ) ( ( float ) bError * 7.0f / 16 ) , 0xff ) ;
}
if ( ( x > 0 ) & & ( y < ( image - > height - 1 ) ) )
{
pixels [ ( y + 1 ) * image - > width + x - 1 ] . r = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x - 1 ] . r + ( int ) ( ( float ) rError * 3.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x - 1 ] . g = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x - 1 ] . g + ( int ) ( ( float ) gError * 3.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x - 1 ] . b = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x - 1 ] . b + ( int ) ( ( float ) bError * 3.0f / 16 ) , 0xff ) ;
}
if ( y < ( image - > height - 1 ) )
{
pixels [ ( y + 1 ) * image - > width + x ] . r = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x ] . r + ( int ) ( ( float ) rError * 5.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x ] . g = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x ] . g + ( int ) ( ( float ) gError * 5.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x ] . b = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x ] . b + ( int ) ( ( float ) bError * 5.0f / 16 ) , 0xff ) ;
}
if ( ( x < ( image - > width - 1 ) ) & & ( y < ( image - > height - 1 ) ) )
{
pixels [ ( y + 1 ) * image - > width + x + 1 ] . r = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x + 1 ] . r + ( int ) ( ( float ) rError * 1.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x + 1 ] . g = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x + 1 ] . g + ( int ) ( ( float ) gError * 1.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x + 1 ] . b = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x + 1 ] . b + ( int ) ( ( float ) bError * 1.0f / 16 ) , 0xff ) ;
}
rPixel = ( unsigned short ) newPixel . r ;
gPixel = ( unsigned short ) newPixel . g ;
bPixel = ( unsigned short ) newPixel . b ;
aPixel = ( unsigned short ) newPixel . a ;
( ( unsigned short * ) image - > data ) [ y * image - > width + x ] = ( rPixel < < ( gBpp + bBpp + aBpp ) ) | ( gPixel < < ( bBpp + aBpp ) ) | ( bPixel < < aBpp ) | aPixel ;
}
}
free ( pixels ) ;
}
}
/ / Convert image to POT ( power - of - two )
/ / NOTE : It could be useful on OpenGL ES 2.0 ( RPI , HTML5 )
void ImageToPOT ( Image * image , Color fillColor )
@ -818,6 +762,7 @@ void ImageToPOT(Image *image, Color fillColor)
}
}
# if defined(SUPPORT_IMAGE_MANIPULATION)
/ / Copy an image to a new image
Image ImageCopy ( Image image )
{
@ -1203,6 +1148,115 @@ void ImageFlipHorizontal(Image *image)
image - > data = processed . data ;
}
/ / Dither image data to 16 bpp or lower ( Floyd - Steinberg dithering )
/ / NOTE : In case selected bpp do not represent an known 16 bit format ,
/ / dithered data is stored in the LSB part of the unsigned short
void ImageDither ( Image * image , int rBpp , int gBpp , int bBpp , int aBpp )
{
if ( image - > format > = COMPRESSED_DXT1_RGB )
{
TraceLog ( WARNING , " Compressed data formats can not be dithered " ) ;
return ;
}
if ( ( rBpp + gBpp + bBpp + aBpp ) > 16 )
{
TraceLog ( WARNING , " Unsupported dithering bpps (%ibpp), only 16bpp or lower modes supported " , ( rBpp + gBpp + bBpp + aBpp ) ) ;
}
else
{
Color * pixels = GetImageData ( * image ) ;
free ( image - > data ) ; / / free old image data
if ( ( image - > format ! = UNCOMPRESSED_R8G8B8 ) & & ( image - > format ! = UNCOMPRESSED_R8G8B8A8 ) )
{
TraceLog ( WARNING , " Image format is already 16bpp or lower, dithering could have no effect " ) ;
}
/ / Define new image format , check if desired bpp match internal known format
if ( ( rBpp = = 5 ) & & ( gBpp = = 6 ) & & ( bBpp = = 5 ) & & ( aBpp = = 0 ) ) image - > format = UNCOMPRESSED_R5G6B5 ;
else if ( ( rBpp = = 5 ) & & ( gBpp = = 5 ) & & ( bBpp = = 5 ) & & ( aBpp = = 1 ) ) image - > format = UNCOMPRESSED_R5G5B5A1 ;
else if ( ( rBpp = = 4 ) & & ( gBpp = = 4 ) & & ( bBpp = = 4 ) & & ( aBpp = = 4 ) ) image - > format = UNCOMPRESSED_R4G4B4A4 ;
else
{
image - > format = 0 ;
TraceLog ( WARNING , " Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i) " , ( rBpp + gBpp + bBpp + aBpp ) , rBpp , gBpp , bBpp , aBpp ) ;
}
/ / NOTE : We will store the dithered data as unsigned short ( 16 bpp )
image - > data = ( unsigned short * ) malloc ( image - > width * image - > height * sizeof ( unsigned short ) ) ;
Color oldPixel = WHITE ;
Color newPixel = WHITE ;
int rError , gError , bError ;
unsigned short rPixel , gPixel , bPixel , aPixel ; / / Used for 16 bit pixel composition
# define MIN(a,b) (((a)<(b))?(a):(b))
for ( int y = 0 ; y < image - > height ; y + + )
{
for ( int x = 0 ; x < image - > width ; x + + )
{
oldPixel = pixels [ y * image - > width + x ] ;
/ / NOTE : New pixel obtained by bits truncate , it would be better to round values ( check ImageFormat ( ) )
newPixel . r = oldPixel . r > > ( 8 - rBpp ) ; / / R bits
newPixel . g = oldPixel . g > > ( 8 - gBpp ) ; / / G bits
newPixel . b = oldPixel . b > > ( 8 - bBpp ) ; / / B bits
newPixel . a = oldPixel . a > > ( 8 - aBpp ) ; / / A bits ( not used on dithering )
/ / NOTE : Error must be computed between new and old pixel but using same number of bits !
/ / We want to know how much color precision we have lost . . .
rError = ( int ) oldPixel . r - ( int ) ( newPixel . r < < ( 8 - rBpp ) ) ;
gError = ( int ) oldPixel . g - ( int ) ( newPixel . g < < ( 8 - gBpp ) ) ;
bError = ( int ) oldPixel . b - ( int ) ( newPixel . b < < ( 8 - bBpp ) ) ;
pixels [ y * image - > width + x ] = newPixel ;
/ / NOTE : Some cases are out of the array and should be ignored
if ( x < ( image - > width - 1 ) )
{
pixels [ y * image - > width + x + 1 ] . r = MIN ( ( int ) pixels [ y * image - > width + x + 1 ] . r + ( int ) ( ( float ) rError * 7.0f / 16 ) , 0xff ) ;
pixels [ y * image - > width + x + 1 ] . g = MIN ( ( int ) pixels [ y * image - > width + x + 1 ] . g + ( int ) ( ( float ) gError * 7.0f / 16 ) , 0xff ) ;
pixels [ y * image - > width + x + 1 ] . b = MIN ( ( int ) pixels [ y * image - > width + x + 1 ] . b + ( int ) ( ( float ) bError * 7.0f / 16 ) , 0xff ) ;
}
if ( ( x > 0 ) & & ( y < ( image - > height - 1 ) ) )
{
pixels [ ( y + 1 ) * image - > width + x - 1 ] . r = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x - 1 ] . r + ( int ) ( ( float ) rError * 3.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x - 1 ] . g = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x - 1 ] . g + ( int ) ( ( float ) gError * 3.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x - 1 ] . b = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x - 1 ] . b + ( int ) ( ( float ) bError * 3.0f / 16 ) , 0xff ) ;
}
if ( y < ( image - > height - 1 ) )
{
pixels [ ( y + 1 ) * image - > width + x ] . r = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x ] . r + ( int ) ( ( float ) rError * 5.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x ] . g = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x ] . g + ( int ) ( ( float ) gError * 5.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x ] . b = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x ] . b + ( int ) ( ( float ) bError * 5.0f / 16 ) , 0xff ) ;
}
if ( ( x < ( image - > width - 1 ) ) & & ( y < ( image - > height - 1 ) ) )
{
pixels [ ( y + 1 ) * image - > width + x + 1 ] . r = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x + 1 ] . r + ( int ) ( ( float ) rError * 1.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x + 1 ] . g = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x + 1 ] . g + ( int ) ( ( float ) gError * 1.0f / 16 ) , 0xff ) ;
pixels [ ( y + 1 ) * image - > width + x + 1 ] . b = MIN ( ( int ) pixels [ ( y + 1 ) * image - > width + x + 1 ] . b + ( int ) ( ( float ) bError * 1.0f / 16 ) , 0xff ) ;
}
rPixel = ( unsigned short ) newPixel . r ;
gPixel = ( unsigned short ) newPixel . g ;
bPixel = ( unsigned short ) newPixel . b ;
aPixel = ( unsigned short ) newPixel . a ;
( ( unsigned short * ) image - > data ) [ y * image - > width + x ] = ( rPixel < < ( gBpp + bBpp + aBpp ) ) | ( gPixel < < ( bBpp + aBpp ) ) | ( bPixel < < aBpp ) | aPixel ;
}
}
free ( pixels ) ;
}
}
/ / Modify image color : tint
void ImageColorTint ( Image * image , Color color )
{
@ -1359,6 +1413,7 @@ void ImageColorBrightness(Image *image, int brightness)
image - > data = processed . data ;
}
# endif / / SUPPORT_IMAGE_MANIPULATION
/ / Generate GPU mipmaps for a texture
void GenTextureMipmaps ( Texture2D * texture )
@ -1547,6 +1602,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
/ / Module specific Functions Definition
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# if defined(SUPPORT_FILEFORMAT_DDS)
/ / Loading DDS image data ( compressed or uncompressed )
static Image LoadDDS ( const char * fileName )
{
@ -1744,7 +1800,9 @@ static Image LoadDDS(const char *fileName)
return image ;
}
# endif
# if defined(SUPPORT_FILEFORMAT_PKM)
/ / Loading PKM image data ( ETC1 / ETC2 compression )
/ / NOTE : KTX is the standard Khronos Group compression format ( ETC1 / ETC2 , mipmaps )
/ / PKM is a much simpler file format used mainly to contain a single ETC1 / ETC2 compressed image ( no mipmaps )
@ -1836,7 +1894,9 @@ static Image LoadPKM(const char *fileName)
return image ;
}
# endif
# if defined(SUPPORT_FILEFORMAT_KTX)
/ / Load KTX compressed image data ( ETC1 / ETC2 compression )
static Image LoadKTX ( const char * fileName )
{
@ -1929,7 +1989,9 @@ static Image LoadKTX(const char *fileName)
return image ;
}
# endif
# if defined(SUPPORT_FILEFORMAT_PVR)
/ / Loading PVR image data ( uncompressed or PVRT compression )
/ / NOTE : PVR v2 not supported , use PVR v3 instead
static Image LoadPVR ( const char * fileName )
@ -2087,7 +2149,9 @@ static Image LoadPVR(const char *fileName)
return image ;
}
# endif
# if defined(SUPPORT_FILEFORMAT_ASTC)
/ / Load ASTC compressed image data ( ASTC compression )
static Image LoadASTC ( const char * fileName )
{
@ -2170,3 +2234,4 @@ static Image LoadASTC(const char *fileName)
return image ;
}
# endif