diff --git a/docs/ase-file-specs.md b/docs/ase-file-specs.md index 6107089e7..e2285598e 100644 --- a/docs/ase-file-specs.md +++ b/docs/ase-file-specs.md @@ -17,6 +17,8 @@ ASE files use Intel (little-endian) byte order. * `DWORD`: A 32-bit unsigned integer value * `LONG`: A 32-bit signed integer value * `FIXED`: A 32-bit fixed point (16.16) value +* `FLOAT`: A 32-bit single-precision value +* `DOUBLE`: A 64-bit double-precision value * `QWORD`: A 64-bit unsigned integer value * `LONG64`: A 64-bit signed integer value * `BYTE[n]`: "n" bytes. @@ -399,19 +401,23 @@ there is an User Data Chunk at the first frame after the Palette Chunk. + If type==0x000A FIXED + If type==0x000B - STRING + FLOAT + If type==0x000C - POINT + DOUBLE + If type==0x000D - SIZE + STRING + If type==0x000E + POINT + + If type==0x000F + SIZE + + If type==0x0010 RECT - + If type==0x000F (vector) + + If type==0x0011 (vector) DWORD Number of elements WORD Element's type BYTE[] As many values as the number of elements indicates Structure depends on the element's type - + If type==0x0010 (nested properties map) + + If type==0x0012 (nested properties map) DWORD Number of properties BYTE[] Nested properties data Structure is the same as indicated in this loop diff --git a/src/app/file/ase_format.cpp b/src/app/file/ase_format.cpp index a186f07d4..e12bdd424 100644 --- a/src/app/file/ase_format.cpp +++ b/src/app/file/ase_format.cpp @@ -1459,6 +1459,12 @@ static void ase_file_write_property_value(FILE* f, else if (const UserData::Fixed* v = std::get_if(&value)) { fputl(v->value, f); } + else if (const float_t* v = std::get_if(&value)) { + fputf(*v, f); + } + else if (const double_t* v = std::get_if(&value)) { + fputd(*v, f); + } else if (const std::string* v = std::get_if(&value)) { ase_file_write_string(f, *v); } diff --git a/src/app/script/values.cpp b/src/app/script/values.cpp index 82900b3c2..a99438c88 100644 --- a/src/app/script/values.cpp +++ b/src/app/script/values.cpp @@ -61,6 +61,19 @@ int get_value_from_lua(lua_State* L, int index) { return lua_tointeger(L, index); } +// ---------------------------------------------------------------------- +// float + +template<> +void push_value_to_lua(lua_State* L, const float& value) { + lua_pushnumber(L, value); +} + +template<> +float get_value_from_lua(lua_State* L, int index) { + return lua_tonumber(L, index); +} + // ---------------------------------------------------------------------- // double @@ -321,6 +334,11 @@ void push_value_to_lua(lua_State* L, const doc::UserData::Variant& value) break; case USER_DATA_PROPERTY_TYPE_FIXED: push_value_to_lua(L, *std::get_if(&value)); + case USER_DATA_PROPERTY_TYPE_FLOAT: + push_value_to_lua(L, *std::get_if(&value)); + break; + case USER_DATA_PROPERTY_TYPE_DOUBLE: + push_value_to_lua(L, *std::get_if(&value)); break; case USER_DATA_PROPERTY_TYPE_STRING: push_value_to_lua(L, *std::get_if(&value)); @@ -366,9 +384,7 @@ doc::UserData::Variant get_value_from_lua(lua_State* L, int index) if (lua_isinteger(L, index)) v = lua_tointeger(L, index); else { - v = doc::UserData::Fixed{ - fixmath::ftofix(lua_tonumber(L, index)) - }; + v = lua_tonumber(L, index); } break; diff --git a/src/dio/aseprite_decoder.cpp b/src/dio/aseprite_decoder.cpp index 72aac76d3..3e210a825 100644 --- a/src/dio/aseprite_decoder.cpp +++ b/src/dio/aseprite_decoder.cpp @@ -391,6 +391,67 @@ std::string AsepriteDecoder::readString() return string; } +float AsepriteDecoder::readFloat() +{ + int b1, b2, b3, b4; + + if ((b1 = read8()) == EOF) + return EOF; + + if ((b2 = read8()) == EOF) + return EOF; + + if ((b3 = read8()) == EOF) + return EOF; + + if ((b4 = read8()) == EOF) + return EOF; + + // Little endian. + int v = ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1); + return *reinterpret_cast(&v); +} + +double AsepriteDecoder::readDouble() +{ + int b1, b2, b3, b4, b5, b6, b7, b8; + + if ((b1 = read8()) == EOF) + return EOF; + + if ((b2 = read8()) == EOF) + return EOF; + + if ((b3 = read8()) == EOF) + return EOF; + + if ((b4 = read8()) == EOF) + return EOF; + + if ((b5 = read8()) == EOF) + return EOF; + + if ((b6 = read8()) == EOF) + return EOF; + + if ((b7 = read8()) == EOF) + return EOF; + + if ((b8 = read8()) == EOF) + return EOF; + + // Little endian. + long long v = (((long long)b8 << 56) | + ((long long)b7 << 48) | + ((long long)b6 << 40) | + ((long long)b5 << 32) | + ((long long)b4 << 24) | + ((long long)b3 << 16) | + ((long long)b2 << 8) | + (long long)b1); + return *reinterpret_cast(&v); +} + doc::Palette* AsepriteDecoder::readColorChunk(doc::Palette* prevPal, doc::frame_t frame) { @@ -1249,6 +1310,14 @@ const doc::UserData::Variant AsepriteDecoder::readPropertyValue(uint16_t type) int32_t value = read32(); return doc::UserData::Fixed{value}; } + case USER_DATA_PROPERTY_TYPE_FLOAT: { + float value = readFloat(); + return value; + } + case USER_DATA_PROPERTY_TYPE_DOUBLE: { + double value = readDouble(); + return value; + } case USER_DATA_PROPERTY_TYPE_STRING: { std::string value = readString(); return value; diff --git a/src/dio/aseprite_decoder.h b/src/dio/aseprite_decoder.h index d5b2281b3..46984f2f7 100644 --- a/src/dio/aseprite_decoder.h +++ b/src/dio/aseprite_decoder.h @@ -46,6 +46,8 @@ private: void readFrameHeader(AsepriteFrameHeader* frame_header); void readPadding(const int bytes); std::string readString(); + float readFloat(); + double readDouble(); doc::Palette* readColorChunk(doc::Palette* prevPal, doc::frame_t frame); doc::Palette* readColor2Chunk(doc::Palette* prevPal, doc::frame_t frame); doc::Palette* readPaletteChunk(doc::Palette* prevPal, doc::frame_t frame); diff --git a/src/doc/user_data.h b/src/doc/user_data.h index 2c938a6ba..379a5e94d 100644 --- a/src/doc/user_data.h +++ b/src/doc/user_data.h @@ -31,12 +31,14 @@ #define USER_DATA_PROPERTY_TYPE_INT64 0x0008 #define USER_DATA_PROPERTY_TYPE_UINT64 0x0009 #define USER_DATA_PROPERTY_TYPE_FIXED 0x000A -#define USER_DATA_PROPERTY_TYPE_STRING 0x000B -#define USER_DATA_PROPERTY_TYPE_POINT 0x000C -#define USER_DATA_PROPERTY_TYPE_SIZE 0x000D -#define USER_DATA_PROPERTY_TYPE_RECT 0x000E -#define USER_DATA_PROPERTY_TYPE_VECTOR 0x000F -#define USER_DATA_PROPERTY_TYPE_PROPERTIES 0x0010 +#define USER_DATA_PROPERTY_TYPE_FLOAT 0x000B +#define USER_DATA_PROPERTY_TYPE_DOUBLE 0x000C +#define USER_DATA_PROPERTY_TYPE_STRING 0x000D +#define USER_DATA_PROPERTY_TYPE_POINT 0x000E +#define USER_DATA_PROPERTY_TYPE_SIZE 0x000F +#define USER_DATA_PROPERTY_TYPE_RECT 0x0010 +#define USER_DATA_PROPERTY_TYPE_VECTOR 0x0011 +#define USER_DATA_PROPERTY_TYPE_PROPERTIES 0x0012 namespace doc { @@ -59,6 +61,7 @@ namespace doc { int32_t, uint32_t, int64_t, uint64_t, Fixed, + float, double, std::string, gfx::Point, gfx::Size,