From d74a505d406faf276a265beaf8925d6e8ff9cec0 Mon Sep 17 00:00:00 2001 From: jussi Date: Fri, 3 Nov 2023 23:12:55 +0200 Subject: Compress/decompress and Encode/Decode DataBase64. --- src/core.c | 435 ++++++++++++++++++++++++++++++++++++++++++++++----------- src/lua_core.c | 27 +++- src/models.c | 8 +- 3 files changed, 378 insertions(+), 92 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index ea29083..c4fbf50 100644 --- a/src/core.c +++ b/src/core.c @@ -4,6 +4,12 @@ #include "textures.h" #include "lua_core.h" +void unloadBuffer( Buffer *buffer ) { + free( buffer->data ); + + TraceLog( LOG_INFO, "BUFFER: Unloaded buffer with %u bytes of data", buffer->size ); +} + /* ## Core - Window */ @@ -591,89 +597,6 @@ int lcoreOpenURL( lua_State *L ) { return 0; } -/* -> buffer = RL.LoadBuffer( data{} buffer, int type ) - -Load Buffer. Type should be one of the Buffer types - -- Success return Buffer -*/ -int lcoreLoadBuffer( lua_State *L ) { - luaL_checktype( L, 1, LUA_TTABLE ); - int type = luaL_checkinteger( L, 2 ); - - Buffer buffer = { 0 }; - int len = uluaGetTableLen( L, 1 ); - - switch ( type ) { - case BUFFER_UNSIGNED_CHAR: - buffer.size = len * sizeof( unsigned char ); - break; - case BUFFER_UNSIGNED_SHORT: - buffer.size = len * sizeof( unsigned short ); - break; - case BUFFER_UNSIGNED_INT: - buffer.size = len * sizeof( unsigned int ); - break; - case BUFFER_FLOAT: - buffer.size = len * sizeof( float ); - break; - default: - break; - } - buffer.data = malloc( buffer.size ); - - int t = 1; - int i = 0; - unsigned char *up = buffer.data; - unsigned short *sp = buffer.data; - unsigned int *ip = buffer.data; - float *fp = buffer.data; - - lua_pushnil( L ); - - while ( lua_next( L, t ) != 0 ) { - switch ( type ) { - case BUFFER_UNSIGNED_CHAR: - *up = (unsigned char)lua_tointeger( L, -1 ); - up++; - break; - case BUFFER_UNSIGNED_SHORT: - *sp = (unsigned short)lua_tointeger( L, -1 ); - up++; - break; - case BUFFER_UNSIGNED_INT: - *ip = (unsigned int)lua_tointeger( L, -1 ); - up++; - break; - case BUFFER_FLOAT: - *fp = (float)lua_tonumber( L, -1 ); - fp++; - break; - default: - break; - } - lua_pop( L, 1 ); - i++; - } - uluaPushBuffer( L, buffer ); - - return 1; -} - -/* -> RL.UnloadBuffer( Buffer buffer ) - -Unload buffer data -*/ -int lcoreUnloadBuffer( lua_State *L ) { - Buffer *buffer = uluaGetBuffer( L, 1 ); - - free( buffer->data ); - - return 0; -} - /* > enabled = RL.IsGCUnloadEnabled() @@ -2007,6 +1930,99 @@ int lcoreGetFileModTime( lua_State *L ) { return 1; } +/* +## Core - Compression/Encoding functionality +*/ + +/* +> compData = RL.CompressData( string data ) + +Compress data (DEFLATE algorithm) + +- Success return Buffer +*/ +int lcoreCompressData( lua_State *L ) { + Buffer *inBuffer = uluaGetBuffer( L, 1 ); + Buffer outBuffer = { + .size = 0, + .type = inBuffer->type + }; + unsigned char *compData = CompressData( inBuffer->data, inBuffer->size, (int*)&outBuffer.size ); + + outBuffer.data = malloc( outBuffer.size ); + memcpy( outBuffer.data, compData, outBuffer.size ); + uluaPushBuffer( L, outBuffer ); + + free( compData ); + + return 1; +} + +/* +> data, dataSize = RL.DecompressData( Buffer compData ) + +Decompress data (DEFLATE algorithm). + +- Success return string, int +*/ +int lcoreDecompressData( lua_State *L ) { + Buffer *inBuffer = uluaGetBuffer( L, 1 ); + Buffer outBuffer = { + .size = 0, + .type = inBuffer->type + }; + unsigned char *data = DecompressData( inBuffer->data, inBuffer->size, (int*)&outBuffer.size ); + + outBuffer.data = malloc( outBuffer.size ); + memcpy( outBuffer.data, data, outBuffer.size ); + uluaPushBuffer( L, outBuffer ); + + free( data ); + + return 1; +} + +/* +> encodedData, outputSize = RL.EncodeDataBase64( string data ) + +Encode data to Base64 string + +- Success return string, int +*/ +int lcoreEncodeDataBase64( lua_State *L ) { + int dataSize = 0; + const char *string = luaL_checklstring( L, 1, (size_t*)&dataSize ); + + int outputSize = 0; + char *compData = EncodeDataBase64( string, dataSize, &outputSize ); + + lua_pushstring( L, compData ); + lua_pushinteger( L, outputSize ); + + free( compData ); + + return 2; +} + +/* +> decodedData, outputSize = RL.DecodeDataBase64( string data ) + +Decode Base64 string data + +- Success return string, int +*/ +int lcoreDecodeDataBase64( lua_State *L ) { + int outputSize = 0; + unsigned char *decodedData = DecodeDataBase64( luaL_checkstring( L, 1 ), &outputSize ); + + lua_pushstring( L, decodedData ); + lua_pushinteger( L, outputSize ); + + free( decodedData ); + + return 2; +} + /* ## Core - Camera2D */ @@ -2696,3 +2712,256 @@ int lcoreGetScreenToWorld2D( lua_State *L ) { return 1; } + +/* +## Core - Buffer +*/ + +/* +> buffer = RL.LoadBuffer( data{} buffer, int type ) + +Load Buffer. Type should be one of the Buffer types + +- Success return Buffer +*/ +int lcoreLoadBuffer( lua_State *L ) { + luaL_checktype( L, 1, LUA_TTABLE ); + int type = luaL_checkinteger( L, 2 ); + + Buffer buffer = { + .type = type + }; + int len = uluaGetTableLen( L, 1 ); + + switch ( type ) { + case BUFFER_UNSIGNED_CHAR: + buffer.size = len * sizeof( unsigned char ); + break; + case BUFFER_UNSIGNED_SHORT: + buffer.size = len * sizeof( unsigned short ); + break; + case BUFFER_UNSIGNED_INT: + buffer.size = len * sizeof( unsigned int ); + break; + case BUFFER_CHAR: + buffer.size = len * sizeof( char ); + break; + case BUFFER_SHORT: + buffer.size = len * sizeof( short ); + break; + case BUFFER_INT: + buffer.size = len * sizeof( int ); + break; + case BUFFER_FLOAT: + buffer.size = len * sizeof( float ); + break; + case BUFFER_DOUBLE: + buffer.size = len * sizeof( double ); + break; + default: + break; + } + buffer.data = malloc( buffer.size ); + + int t = 1; + int i = 0; + unsigned char *ucp = buffer.data; + unsigned short *usp = buffer.data; + unsigned int *uip = buffer.data; + char *cp = buffer.data; + short *sp = buffer.data; + int *ip = buffer.data; + float *fp = buffer.data; + double *dp = buffer.data; + + lua_pushnil( L ); + + while ( lua_next( L, t ) != 0 ) { + switch ( type ) { + case BUFFER_UNSIGNED_CHAR: + *ucp = (unsigned char)lua_tointeger( L, -1 ); + ucp++; + break; + case BUFFER_UNSIGNED_SHORT: + *usp = (unsigned short)lua_tointeger( L, -1 ); + usp++; + break; + case BUFFER_UNSIGNED_INT: + *uip = (unsigned int)lua_tointeger( L, -1 ); + uip++; + break; + case BUFFER_CHAR: + *cp = (char)lua_tointeger( L, -1 ); + cp++; + break; + case BUFFER_SHORT: + *sp = (short)lua_tointeger( L, -1 ); + sp++; + break; + case BUFFER_INT: + *ip = (int)lua_tointeger( L, -1 ); + ip++; + break; + case BUFFER_FLOAT: + *fp = (float)lua_tonumber( L, -1 ); + fp++; + break; + case BUFFER_DOUBLE: + *dp = (double)lua_tonumber( L, -1 ); + dp++; + break; + default: + break; + } + lua_pop( L, 1 ); + i++; + } + uluaPushBuffer( L, buffer ); + + return 1; +} + +/* +> RL.UnloadBuffer( Buffer buffer ) + +Unload buffer data +*/ +int lcoreUnloadBuffer( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + unloadBuffer( buffer ); + + return 0; +} + +/* +> data = RL.GetBufferData( Buffer buffer ) + +Get buffer data as table in the format is was stored + +- Success return data{} +*/ +int lcoreGetBufferData( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + if ( buffer->type == BUFFER_UNSIGNED_CHAR ) { + unsigned char *p = buffer->data; + size_t count = buffer->size / sizeof( unsigned char ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (unsigned char)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_UNSIGNED_SHORT ) { + unsigned short *p = buffer->data; + size_t count = buffer->size / sizeof( unsigned short ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (unsigned short)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_UNSIGNED_INT ) { + unsigned int *p = buffer->data; + size_t count = buffer->size / sizeof( unsigned int ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (unsigned int)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_CHAR ) { + char *p = buffer->data; + size_t count = buffer->size / sizeof( char ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (char)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_SHORT ) { + short *p = buffer->data; + size_t count = buffer->size / sizeof( short ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (short)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_INT ) { + int *p = buffer->data; + size_t count = buffer->size / sizeof( int ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushinteger( L, (int)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_FLOAT ) { + float *p = buffer->data; + size_t count = buffer->size / sizeof( float ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushnumber( L, (float)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + else if ( buffer->type == BUFFER_DOUBLE ) { + double *p = buffer->data; + size_t count = buffer->size / sizeof( double ); + lua_createtable( L, count, 0 ); + + for ( int i = 0; i < count; i++ ) { + lua_pushnumber( L, (double)*p ); + lua_rawseti( L, -2, i+1 ); + p++; + } + } + + return 1; +} + +/* +> type = RL.GetBufferType( Buffer buffer ) + +Get buffer type + +- Success return int +*/ +int lcoreGetBufferType( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + lua_pushinteger( L, buffer->type ); + + return 1; +} + +/* +> size = RL.GetBufferSize( Buffer buffer ) + +Get buffer size + +- Success return int +*/ +int lcoreGetBufferSize( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + lua_pushinteger( L, buffer->size ); + + return 1; +} diff --git a/src/lua_core.c b/src/lua_core.c index 499f2a2..37d34fc 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -20,7 +20,7 @@ static int gcBuffer( lua_State *L ) { Buffer *buffer = luaL_checkudata( L, 1, "Buffer" ); - free( buffer->data ); + unloadBuffer( buffer ); } static void defineBuffer() { @@ -219,7 +219,7 @@ static int gcMaterial( lua_State *L ) { Material *material = luaL_checkudata( L, 1, "Material" ); /* Custom UnloadMaterial since we don't want to free Shaders or Textures. */ - RL_FREE( material->maps ); + unloadMaterial( material ); // UnloadMaterial( *material ); } @@ -900,10 +900,14 @@ static void defineGlobals() { assignGlobalInt( GLFW_PRESS, "GLFW_PRESS" ); // The key or mouse button was pressed assignGlobalInt( GLFW_REPEAT, "GLFW_REPEAT" ); // The key was held down until it repeated /* CBuffer Data Types */ - assignGlobalInt( BUFFER_UNSIGNED_CHAR, "BUFFER_UNSIGNED_CHAR" ); // C type char - assignGlobalInt( BUFFER_UNSIGNED_SHORT, "BUFFER_UNSIGNED_SHORT" ); // C type short - assignGlobalInt( BUFFER_UNSIGNED_INT, "BUFFER_UNSIGNED_INT" ); // C type int + assignGlobalInt( BUFFER_UNSIGNED_CHAR, "BUFFER_UNSIGNED_CHAR" ); // C type unsigned char + assignGlobalInt( BUFFER_UNSIGNED_SHORT, "BUFFER_UNSIGNED_SHORT" ); // C type unsigned short + assignGlobalInt( BUFFER_UNSIGNED_INT, "BUFFER_UNSIGNED_INT" ); // C type unsigned int + assignGlobalInt( BUFFER_CHAR, "BUFFER_CHAR" ); // C type char + assignGlobalInt( BUFFER_SHORT, "BUFFER_SHORT" ); // C type short + assignGlobalInt( BUFFER_INT, "BUFFER_INT" ); // C type int assignGlobalInt( BUFFER_FLOAT, "BUFFER_FLOAT" ); // C type float + assignGlobalInt( BUFFER_DOUBLE, "BUFFER_DOUBLE" ); // C type double /* Window Events. */ assignGlobalInt( EVENT_WINDOW_SIZE, "EVENT_WINDOW_SIZE" ); // GLFW event window size changed assignGlobalInt( EVENT_WINDOW_MAXIMIZE, "EVENT_WINDOW_MAXIMIZE" ); // GLFW event window maximize @@ -1542,8 +1546,6 @@ void luaRegister() { assingGlobalFunction( "SetLogLevelInvalid", lcoreSetLogLevelInvalid ); assingGlobalFunction( "GetLogLevelInvalid", lcoreGetLogLevelInvalid ); assingGlobalFunction( "OpenURL", lcoreOpenURL ); - assingGlobalFunction( "LoadBuffer", lcoreLoadBuffer ); - assingGlobalFunction( "UnloadBuffer", lcoreUnloadBuffer ); assingGlobalFunction( "IsGCUnloadEnabled", lcoreIsGCUnloadEnabled ); /* Cursor. */ assingGlobalFunction( "ShowCursor", lcoreShowCursor ); @@ -1594,6 +1596,11 @@ void luaRegister() { assingGlobalFunction( "IsFileDropped", lcoreIsFileDropped ); assingGlobalFunction( "LoadDroppedFiles", lcoreLoadDroppedFiles ); assingGlobalFunction( "GetFileModTime", lcoreGetFileModTime ); + /* Compression/Encoding functionality. */ + assingGlobalFunction( "CompressData", lcoreCompressData ); + assingGlobalFunction( "DecompressData", lcoreDecompressData ); + assingGlobalFunction( "EncodeDataBase64", lcoreEncodeDataBase64 ); + assingGlobalFunction( "DecodeDataBase64", lcoreDecodeDataBase64 ); /* Camera2D. */ assingGlobalFunction( "CreateCamera2D", lcoreCreateCamera2D ); assingGlobalFunction( "BeginMode2D", lcoreBeginMode2D ); @@ -1685,6 +1692,12 @@ void luaRegister() { assingGlobalFunction( "GetWorldToScreenEx", lcoreGetWorldToScreenEx ); assingGlobalFunction( "GetWorldToScreen2D", lcoreGetWorldToScreen2D ); assingGlobalFunction( "GetScreenToWorld2D", lcoreGetScreenToWorld2D ); + /* Buffer. */ + assingGlobalFunction( "LoadBuffer", lcoreLoadBuffer ); + assingGlobalFunction( "UnloadBuffer", lcoreUnloadBuffer ); + assingGlobalFunction( "GetBufferData", lcoreGetBufferData ); + assingGlobalFunction( "GetBufferType", lcoreGetBufferType ); + assingGlobalFunction( "GetBufferSize", lcoreGetBufferSize ); /* Shapes. */ /* Drawing. */ diff --git a/src/models.c b/src/models.c index 64a8d3b..2db4b5b 100644 --- a/src/models.c +++ b/src/models.c @@ -6,6 +6,10 @@ #include "textures.h" #include "core.h" +void unloadMaterial( Material *material ) { + free( material->maps ); +} + // Unload model (but not meshes) from memory (RAM and/or VRAM) void UnloadModelKeepMeshes( Model model ) { // Unload materials maps @@ -23,7 +27,7 @@ void UnloadModelKeepMeshes( Model model ) { RL_FREE(model.bones); RL_FREE(model.bindPose); - TRACELOG(LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM"); + TraceLog( LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM" ); } void DrawBillboardProNoRatio( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ) { @@ -1194,7 +1198,7 @@ int lmodelsUnloadMaterial( lua_State *L ) { Material *material = uluaGetMaterial( L, 1 ); /* Custom UnloadMaterial since we don't want to free Shaders or Textures. */ - RL_FREE( material->maps ); + unloadMaterial( material ); // UnloadMaterial( *material ); -- cgit v1.2.3