projectm/vendor/SOIL2/stbi_pkm_c.h
2023-03-03 14:30:24 +01:00

228 lines
5.0 KiB
C

#include "pkm_helper.h"
#include "etc1_utils.h"
static int stbi__pkm_test(stbi__context *s)
{
// check the magic number
if (stbi__get8(s) != 'P') {
stbi__rewind(s);
return 0;
}
if (stbi__get8(s) != 'K') {
stbi__rewind(s);
return 0;
}
if (stbi__get8(s) != 'M') {
stbi__rewind(s);
return 0;
}
if (stbi__get8(s) != ' ') {
stbi__rewind(s);
return 0;
}
if (stbi__get8(s) != '1') {
stbi__rewind(s);
return 0;
}
if (stbi__get8(s) != '0') {
stbi__rewind(s);
return 0;
}
stbi__rewind(s);
return 1;
}
#ifndef STBI_NO_STDIO
int stbi__pkm_test_filename (char const *filename)
{
int r;
FILE *f = fopen(filename, "rb");
if (!f) return 0;
r = stbi__pkm_test_file(f);
fclose(f);
return r;
}
int stbi__pkm_test_file (FILE *f)
{
stbi__context s;
int r,n = ftell(f);
stbi__start_file(&s,f);
r = stbi__pkm_test(&s);
fseek(f,n,SEEK_SET);
return r;
}
#endif
int stbi__pkm_test_memory (stbi_uc const *buffer, int len)
{
stbi__context s;
stbi__start_mem(&s,buffer, len);
return stbi__pkm_test(&s);
}
int stbi__pkm_test_callbacks (stbi_io_callbacks const *clbk, void *user)
{
stbi__context s;
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
return stbi__pkm_test(&s);
}
static int stbi__pkm_info(stbi__context *s, int *x, int *y, int *comp )
{
PKMHeader header;
unsigned int width, height;
stbi__getn( s, (stbi_uc*)(&header), sizeof(PKMHeader) );
if ( 0 != strcmp( header.aName, "PKM 10" ) ) {
stbi__rewind(s);
return 0;
}
width = (header.iWidthMSB << 8) | header.iWidthLSB;
height = (header.iHeightMSB << 8) | header.iHeightLSB;
*x = s->img_x = width;
*y = s->img_y = height;
*comp = s->img_n = 3;
stbi__rewind(s);
return 1;
}
int stbi__pkm_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp )
{
stbi__context s;
stbi__start_mem(&s,buffer, len);
return stbi__pkm_info( &s, x, y, comp );
}
int stbi__pkm_info_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp)
{
stbi__context s;
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
return stbi__pkm_info( &s, x, y, comp );
}
#ifndef STBI_NO_STDIO
int stbi__pkm_info_from_path(char const *filename, int *x, int *y, int *comp)
{
int res;
FILE *f = fopen(filename, "rb");
if (!f) return 0;
res = stbi__pkm_info_from_file( f, x, y, comp );
fclose(f);
return res;
}
int stbi__pkm_info_from_file(FILE *f, int *x, int *y, int *comp)
{
stbi__context s;
int res;
long n = ftell(f);
stbi__start_file(&s, f);
res = stbi__pkm_info(&s, x, y, comp);
fseek(f, n, SEEK_SET);
return res;
}
#endif
static stbi_uc * stbi__pkm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
stbi_uc *pkm_data = NULL;
stbi_uc *pkm_res_data = NULL;
PKMHeader header;
unsigned int width;
unsigned int height;
unsigned int align = 0;
unsigned int bpr;
unsigned int size;
unsigned int compressedSize;
int res;
stbi__getn( s, (stbi_uc*)(&header), sizeof(PKMHeader) );
if ( 0 != strcmp( header.aName, "PKM 10" ) ) {
return NULL;
}
width = (header.iWidthMSB << 8) | header.iWidthLSB;
height = (header.iHeightMSB << 8) | header.iHeightLSB;
*x = s->img_x = width;
*y = s->img_y = height;
*comp = s->img_n = 3;
compressedSize = etc1_get_encoded_data_size(width, height);
pkm_data = (stbi_uc *)malloc(compressedSize);
stbi__getn( s, pkm_data, compressedSize );
bpr = ((width * 3) + align) & ~align;
size = bpr * height;
pkm_res_data = (stbi_uc *)malloc(size);
res = etc1_decode_image((const etc1_byte*)pkm_data, (etc1_byte*)pkm_res_data, width, height, 3, bpr);
free( pkm_data );
if ( 0 == res ) {
if( (req_comp <= 4) && (req_comp >= 1) ) {
// user has some requirements, meet them
if( req_comp != s->img_n ) {
pkm_res_data = stbi__convert_format( pkm_res_data, s->img_n, req_comp, s->img_x, s->img_y );
*comp = req_comp;
}
}
return (stbi_uc *)pkm_res_data;
} else {
free( pkm_res_data );
}
return NULL;
}
#ifndef STBI_NO_STDIO
stbi_uc *stbi__pkm_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp)
{
stbi__context s;
stbi__start_file(&s,f);
return stbi__pkm_load(&s,x,y,comp,req_comp);
}
stbi_uc *stbi__pkm_load_from_path (char const*filename, int *x, int *y, int *comp, int req_comp)
{
stbi_uc *data;
FILE *f = fopen(filename, "rb");
if (!f) return NULL;
data = stbi__pkm_load_from_file(f,x,y,comp,req_comp);
fclose(f);
return data;
}
#endif
stbi_uc *stbi__pkm_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
{
stbi__context s;
stbi__start_mem(&s,buffer, len);
return stbi__pkm_load(&s,x,y,comp,req_comp);
}
stbi_uc *stbi__pkm_load_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
{
stbi__context s;
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
return stbi__pkm_load(&s,x,y,comp,req_comp);
}