VERSIÓ 1.3.11
- [NEW] surf.loadex()
This commit is contained in:
228
gifenc_old.h
228
gifenc_old.h
@@ -1,228 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace gif
|
||||
{
|
||||
struct gif_t {
|
||||
uint16_t w, h;
|
||||
int depth;
|
||||
int bgindex;
|
||||
FILE *fd;
|
||||
int offset;
|
||||
int nframes;
|
||||
uint8_t *frame, *back;
|
||||
uint32_t partial;
|
||||
uint8_t buffer[0xFF];
|
||||
};
|
||||
|
||||
struct node_t {
|
||||
uint16_t key;
|
||||
node_t *children[];
|
||||
};
|
||||
|
||||
static node_t *new_node(uint16_t key, int degree)
|
||||
{
|
||||
node_t *node = (node_t*)calloc(1, sizeof(*node) + degree * sizeof(node_t *));
|
||||
if (node) node->key = key;
|
||||
return node;
|
||||
}
|
||||
|
||||
static node_t *new_trie(int degree, int *nkeys)
|
||||
{
|
||||
node_t *root = new_node(0, degree);
|
||||
/* Create nodes for single pixels. */
|
||||
for (*nkeys = 0; *nkeys < degree; (*nkeys)++) root->children[*nkeys] = new_node(*nkeys, degree);
|
||||
*nkeys += 2; /* skip clear code and stop code */
|
||||
return root;
|
||||
}
|
||||
|
||||
static void del_trie(node_t *root, int degree)
|
||||
{
|
||||
if (!root) return;
|
||||
for (int i = 0; i < degree; i++) del_trie(root->children[i], degree);
|
||||
free(root);
|
||||
}
|
||||
|
||||
static void put_loop(gif_t *gif, uint16_t loop);
|
||||
|
||||
gif_t *create(const char *fname, uint16_t width, uint16_t height, uint8_t *palette, uint8_t depth, int16_t bgindex, int loop)
|
||||
{
|
||||
gif_t *gif = (gif_t*)calloc(1, sizeof(*gif) + (bgindex < 0 ? 2 : 1)*width*height);
|
||||
gif->w = width; gif->h = height;
|
||||
gif->bgindex = bgindex;
|
||||
gif->frame = (uint8_t *) &gif[1];
|
||||
gif->back = &gif->frame[width*height];
|
||||
gif->fd = fopen(fname, "wb");
|
||||
if (!gif->fd) { free(gif); return NULL; }
|
||||
fwrite("GIF89a", 6, 1, gif->fd);
|
||||
fwrite(&width, 2, 1, gif->fd);
|
||||
fwrite(&height, 2, 1, gif->fd);
|
||||
gif->depth = depth;
|
||||
fputc((!palette?0x70:0xF0|(depth-1)), gif->fd);
|
||||
fputc(bgindex, gif->fd); fputc(0, gif->fd);
|
||||
if (palette) fwrite(palette, 3 << depth, 1, gif->fd);
|
||||
if (loop >= 0 && loop <= 0xFFFF) put_loop(gif, (uint16_t)loop);
|
||||
return gif;
|
||||
}
|
||||
|
||||
static void put_loop(gif_t *gif, uint16_t loop)
|
||||
{
|
||||
fputc('!', gif->fd); fputc(0xFF, gif->fd); fputc(0x0B, gif->fd);
|
||||
fwrite("NETSCAPE2.0", 11, 1, gif->fd);
|
||||
fputc(0x03, gif->fd); fputc(0x01, gif->fd);
|
||||
fwrite(&loop, 2, 1, gif->fd);
|
||||
fputc(0, gif->fd);
|
||||
}
|
||||
|
||||
/* Add packed key to buffer, updating offset and partial.
|
||||
* gif->offset holds position to put next *bit*
|
||||
* gif->partial holds bits to include in next byte */
|
||||
static void put_key(gif_t *gif, uint16_t key, int key_size)
|
||||
{
|
||||
int byte_offset, bit_offset, bits_to_write;
|
||||
byte_offset = gif->offset / 8;
|
||||
bit_offset = gif->offset % 8;
|
||||
gif->partial |= ((uint32_t) key) << bit_offset;
|
||||
bits_to_write = bit_offset + key_size;
|
||||
while (bits_to_write >= 8) {
|
||||
gif->buffer[byte_offset++] = gif->partial & 0xFF;
|
||||
if (byte_offset == 0xFF) {
|
||||
fputc(0xFF, gif->fd);
|
||||
fwrite(gif->buffer, 0xFF, 1, gif->fd);
|
||||
byte_offset = 0;
|
||||
}
|
||||
gif->partial >>= 8;
|
||||
bits_to_write -= 8;
|
||||
}
|
||||
gif->offset = (gif->offset + key_size) % (0xFF * 8);
|
||||
}
|
||||
|
||||
static void end_key(gif_t *gif)
|
||||
{
|
||||
uint8_t byte_offset;
|
||||
byte_offset = gif->offset >> 3;
|
||||
if (gif->offset & 0x07) gif->buffer[byte_offset++] = gif->partial & 0xFF;
|
||||
if (byte_offset)
|
||||
{
|
||||
fputc(byte_offset, gif->fd);
|
||||
fwrite(gif->buffer, byte_offset, 1, gif->fd);
|
||||
}
|
||||
fputc(0, gif->fd);
|
||||
gif->offset = gif->partial = 0;
|
||||
}
|
||||
|
||||
static void put_image(gif_t *gif, uint16_t w, uint16_t h, uint16_t x, uint16_t y)
|
||||
{
|
||||
int nkeys, key_size, i, j;
|
||||
node_t *node, *child, *root;
|
||||
int degree = 1 << gif->depth;
|
||||
|
||||
fputc(',', gif->fd);
|
||||
fwrite(&x, 2, 1, gif->fd);
|
||||
fwrite(&y, 2, 1, gif->fd);
|
||||
fwrite(&w, 2, 1, gif->fd);
|
||||
fwrite(&h, 2, 1, gif->fd);
|
||||
fputc(0, gif->fd); fputc(gif->depth, gif->fd);
|
||||
root = node = new_trie(degree, &nkeys);
|
||||
key_size = gif->depth + 1;
|
||||
put_key(gif, degree, key_size); /* clear code */
|
||||
for (i = y; i < y+h; i++) {
|
||||
for (j = x; j < x+w; j++) {
|
||||
uint8_t pixel = gif->frame[i*gif->w+j] & (degree - 1);
|
||||
child = node->children[pixel];
|
||||
if (child) {
|
||||
node = child;
|
||||
} else {
|
||||
put_key(gif, node->key, key_size);
|
||||
if (nkeys < 0x1000) {
|
||||
if (nkeys == (1 << key_size))
|
||||
key_size++;
|
||||
node->children[pixel] = new_node(nkeys++, degree);
|
||||
} else {
|
||||
put_key(gif, degree, key_size); /* clear code */
|
||||
del_trie(root, degree);
|
||||
root = node = new_trie(degree, &nkeys);
|
||||
key_size = gif->depth + 1;
|
||||
}
|
||||
node = root->children[pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
put_key(gif, node->key, key_size);
|
||||
put_key(gif, degree + 1, key_size); /* stop code */
|
||||
end_key(gif);
|
||||
del_trie(root, degree);
|
||||
}
|
||||
|
||||
static int get_bbox(gif_t *gif, uint16_t *w, uint16_t *h, uint16_t *x, uint16_t *y)
|
||||
{
|
||||
int i, j, k;
|
||||
int left, right, top, bottom;
|
||||
uint8_t back;
|
||||
left = gif->w; right = 0;
|
||||
top = gif->h; bottom = 0;
|
||||
k = 0;
|
||||
for (i = 0; i < gif->h; i++) {
|
||||
for (j = 0; j < gif->w; j++, k++) {
|
||||
back = gif->bgindex >= 0 ? gif->bgindex : gif->back[k];
|
||||
if (gif->frame[k] != back) {
|
||||
if (j < left) left = j;
|
||||
if (j > right) right = j;
|
||||
if (i < top) top = i;
|
||||
if (i > bottom) bottom = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (left != gif->w && top != gif->h) {
|
||||
*x = left; *y = top;
|
||||
*w = right - left + 1;
|
||||
*h = bottom - top + 1;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void add_graphics_control_extension(gif_t *gif, uint16_t d)
|
||||
{
|
||||
uint8_t flags = ((gif->bgindex >= 0 ? 2 : 1) << 2) + 1;
|
||||
fputc('!', gif->fd); fputc(0xF9, gif->fd); fputc(0x04, gif->fd); fputc(flags, gif->fd);
|
||||
fwrite(&d, 2, 1, gif->fd);
|
||||
fputc(gif->bgindex, gif->fd); fputc(0, gif->fd);
|
||||
}
|
||||
|
||||
void addFrame(gif_t *gif, uint16_t delay)
|
||||
{
|
||||
uint16_t w, h, x, y;
|
||||
uint8_t *tmp;
|
||||
|
||||
if (delay || (gif->bgindex >= 0))
|
||||
add_graphics_control_extension(gif, delay);
|
||||
if (gif->nframes == 0) {
|
||||
w = gif->w;
|
||||
h = gif->h;
|
||||
x = y = 0;
|
||||
} else if (!get_bbox(gif, &w, &h, &x, &y)) {
|
||||
/* image's not changed; save one pixel just to add delay */
|
||||
w = h = 1;
|
||||
x = y = 0;
|
||||
}
|
||||
put_image(gif, w, h, x, y);
|
||||
gif->nframes++;
|
||||
if (gif->bgindex < 0) {
|
||||
tmp = gif->back;
|
||||
gif->back = gif->frame;
|
||||
gif->frame = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void close(gif_t* gif)
|
||||
{
|
||||
fputc(';', gif->fd);
|
||||
fclose(gif->fd);
|
||||
free(gif);
|
||||
}
|
||||
|
||||
}
|
||||
19
jfile.cpp
19
jfile.cpp
@@ -139,6 +139,25 @@ char *file_getfilebuffer(const char *resourcename, int& filesize, const bool zer
|
||||
return buffer;
|
||||
}
|
||||
|
||||
FILE *file_getfilepointerex(const char *filename, int& filesize, const bool binary) {
|
||||
|
||||
FILE *f;
|
||||
f = fopen(filename, binary?"rb":"r");
|
||||
fseek(f, 0, SEEK_END);
|
||||
filesize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
return f;
|
||||
}
|
||||
|
||||
char *file_getfilebufferex(const char *filename, int& filesize, const bool zero_terminate) {
|
||||
FILE *f = file_getfilepointerex(filename, filesize, true);
|
||||
char* buffer = (char*)malloc(zero_terminate?filesize:filesize+1);
|
||||
fread(buffer, filesize, 1, f);
|
||||
if (zero_terminate) buffer[filesize]=0;
|
||||
fclose(f);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Crea la carpeta del sistema donde guardar datos
|
||||
void file_setconfigfolder(const char *foldername)
|
||||
{
|
||||
|
||||
3
jfile.h
3
jfile.h
@@ -14,5 +14,8 @@ void file_setsource(const int src);
|
||||
FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary=false);
|
||||
char *file_getfilebuffer(const char *resourcename, int& filesize, const bool zero_terminate=false);
|
||||
|
||||
FILE *file_getfilepointerex(const char *filename, int& filesize, const bool binary=false);
|
||||
char *file_getfilebufferex(const char *filename, int& filesize, const bool zero_terminate=false);
|
||||
|
||||
const char* file_getconfigvalue(const char *key);
|
||||
void file_setconfigvalue(const char* key, const char* value);
|
||||
|
||||
7
lua.cpp
7
lua.cpp
@@ -26,6 +26,12 @@ extern "C" {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cpp_surf_loadex(lua_State *L) {
|
||||
const char* str = luaL_checkstring(L, 1);
|
||||
lua_pushinteger(L, loadsurf(str, true));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cpp_surf_save(lua_State *L) {
|
||||
uint8_t surface = luaL_checkinteger(L, 1);
|
||||
const char* str = luaL_checkstring(L, 2);
|
||||
@@ -877,6 +883,7 @@ void push_lua_funcs() {
|
||||
lua_newtable(L);
|
||||
lua_pushcfunction(L,cpp_surf_new); lua_setfield(L, -2, "new");
|
||||
lua_pushcfunction(L,cpp_surf_load); lua_setfield(L, -2, "load");
|
||||
lua_pushcfunction(L,cpp_surf_loadex); lua_setfield(L, -2, "loadex");
|
||||
lua_pushcfunction(L,cpp_surf_save); lua_setfield(L, -2, "save");
|
||||
lua_pushcfunction(L,cpp_surf_free); lua_setfield(L, -2, "free");
|
||||
lua_pushcfunction(L,cpp_surf_size); lua_setfield(L, -2, "size");
|
||||
|
||||
34
mini.cpp
34
mini.cpp
@@ -216,7 +216,7 @@ uint8_t newsurf(int w, int h) {
|
||||
return i;
|
||||
}
|
||||
|
||||
uint8_t loadsurf(const char* filename) {
|
||||
uint8_t loadsurf(const char* filename, const bool external) {
|
||||
// Si el gif ja s'ha carregat en una textura, tornem eixa textura
|
||||
for (int i=0; i<MAX_TEXTURES; ++i)
|
||||
if (surfaces[i].name && strcmp(surfaces[i].name, filename)==0) {
|
||||
@@ -224,12 +224,31 @@ uint8_t loadsurf(const char* filename) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// Carregar l'arxiu de disc
|
||||
int size;
|
||||
uint8_t *buffer;
|
||||
if (external) {
|
||||
buffer = (uint8_t*)file_getfilebufferex(filename, size);
|
||||
} else {
|
||||
buffer = (uint8_t*)file_getfilebuffer(filename, size);
|
||||
}
|
||||
|
||||
// Si no s'ha pogut, petar
|
||||
if (!buffer) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error al intentar obrir l'arxiu '%s'\n", filename);
|
||||
return 255;
|
||||
}
|
||||
|
||||
// Agafar la pròxima textura lliure
|
||||
int i = 0;
|
||||
while (i<MAX_TEXTURES && surfaces[i].p != NULL) ++i;
|
||||
//[TODO] Gestionar el cas en que no queden surfaces lliures
|
||||
|
||||
int size;
|
||||
uint8_t *buffer = (uint8_t*)file_getfilebuffer(filename, size);
|
||||
// Si no en queden lliures, petar
|
||||
if (i==MAX_TEXTURES) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: no queden textures lliures\n");
|
||||
return 255;
|
||||
}
|
||||
|
||||
surfaces[i].p = LoadGif(buffer, &surfaces[i].w, &surfaces[i].h);
|
||||
surfaces[i].size = surfaces[i].w*surfaces[i].h;
|
||||
surfaces[i].name = (char*)malloc(strlen(filename)+1);
|
||||
@@ -243,13 +262,6 @@ uint8_t loadsurf(const char* filename) {
|
||||
void savesurf(uint8_t surface, const char* filename, uint8_t *pal, uint8_t colors)
|
||||
{
|
||||
gif::write_gif(filename, surfaces[surface].p, surfaces[surface].w, surfaces[surface].h, pal, colors);
|
||||
/*uint8_t depth=0;
|
||||
do { colors = colors >> 1; depth++; } while (colors!=0);
|
||||
printf("pal depth: %i\n", depth);
|
||||
gif::gif_t *file = gif::create(filename, surfaces[surface].w, surfaces[surface].h, pal, (pal?depth:8), -1, -1);
|
||||
memcpy(file->frame, surfaces[surface].p, surfaces[surface].w*surfaces[surface].h);
|
||||
gif::addFrame(file, 0);
|
||||
gif::close(file);*/
|
||||
}
|
||||
|
||||
void freesurf(uint8_t surface) {
|
||||
|
||||
2
mini.h
2
mini.h
@@ -118,7 +118,7 @@ int scrw();
|
||||
int scrh();
|
||||
|
||||
uint8_t newsurf(int w, int h);
|
||||
uint8_t loadsurf(const char* filename);
|
||||
uint8_t loadsurf(const char* filename, const bool external = false);
|
||||
void savesurf(uint8_t surface, const char* filename, uint8_t *pal, uint8_t colors=0);
|
||||
void freesurf(uint8_t surface);
|
||||
int surfw(uint8_t surface);
|
||||
|
||||
Reference in New Issue
Block a user