mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2025-10-30 03:44:26 +00:00
228 lines
5.0 KiB
C
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);
|
|
}
|