diff --git a/include/ctrff/3dsx.hpp b/include/ctrff/3dsx.hpp index 8dc23bb..e99a16e 100644 --- a/include/ctrff/3dsx.hpp +++ b/include/ctrff/3dsx.hpp @@ -22,7 +22,7 @@ class CTRFF_API _3dsx : public BinFile { void Write(std::fstream& f) const override; void Read(std::fstream& f) override; - ctrff::u32 Magic; + ctrff::u32 Magic; // 0x58534433 "3DSX" ctrff::u16 HeaderSize; ctrff::u16 RelocHeaderSize; ctrff::u32 FormatVersion; diff --git a/include/ctrff/bclim.hpp b/include/ctrff/bclim.hpp index 4b5c8b9..b7db170 100644 --- a/include/ctrff/bclim.hpp +++ b/include/ctrff/bclim.hpp @@ -81,6 +81,11 @@ class CTRFF_API BCLIM : public BinFile { void CreateByImage(const std::vector& data, int w, int h, Format fmt); + Format GetFmt() const { return (Format)pImag.Format; } + std::vector GetImage() { return pBuffer; } + int GetWidth() const { return pImag.Width; } + int GetHeight() const { return pImag.Height; } + /** Write not supported btw */ void Write(std::fstream& f) const override; void Read(std::fstream& f) override; diff --git a/include/ctrff/lz11.hpp b/include/ctrff/lz11.hpp index cce6b48..66f3e8b 100644 --- a/include/ctrff/lz11.hpp +++ b/include/ctrff/lz11.hpp @@ -5,5 +5,6 @@ namespace ctrff { namespace LZ11 { CTRFF_API std::vector Compress(const std::vector& in); -} +CTRFF_API std::vector Decompress(const std::vector& in); +} // namespace LZ11 } // namespace ctrff \ No newline at end of file diff --git a/source/bclim.cpp b/source/bclim.cpp index d3b6b1b..50109fb 100644 --- a/source/bclim.cpp +++ b/source/bclim.cpp @@ -18,22 +18,23 @@ CTRFF_API void BCLIM::Write(std::fstream& f) const { } CTRFF_API void BCLIM::Read(std::fstream& f) { - f.seekg(std::ios::end); + f.seekg(0, std::ios::end); size_t size = f.tellg(); if (size < (sizeof(Header) + sizeof(ImagHeader))) { throw std::runtime_error("Invalid File!"); } f.seekg(size - sizeof(Header) - sizeof(ImagHeader)); - Header h; - ImagHeader imag; - f.read(reinterpret_cast(&h), sizeof(h)); - f.read(reinterpret_cast(&imag), sizeof(imag)); - if (h.Magic != 0x4d494c43) { + f.read(reinterpret_cast(&pCurrent), sizeof(pCurrent)); + f.read(reinterpret_cast(&pImag), sizeof(pImag)); + if (pCurrent.Magic != 0x4d494c43) { throw std::runtime_error("[ctrff] BCLIM: Not a bclim file!"); } - if (imag.Magic != 0x67616d69) { + if (pImag.Magic != 0x67616d69) { throw std::runtime_error("[ctrff] BCLIM: Invalid Data"); } + f.seekg(0, std::ios::beg); + pBuffer.resize(pImag.ImageSize); + f.read(reinterpret_cast(pBuffer.data()), pBuffer.size()); } CTRFF_API void BCLIM::CreateByImage(const std::vector& data, int w, int h, diff --git a/source/helper.cpp b/source/helper.cpp index 01ba247..d6fc264 100644 --- a/source/helper.cpp +++ b/source/helper.cpp @@ -30,9 +30,9 @@ CTRFF_API ctrff::u32 ctrff::TileIndex(const int &x, const int &y, CTRFF_API void ctrff::RGB565toRGBA(std::vector &img, ctrff::u16 *icon, const int &w, const int &h) { - if (img.size() != (48 * 48 * 4)) { - img.resize(48 * 48 * 4); + if (img.size() != (w * h * 4)) { img.clear(); + img.resize(w * h * 4); } for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { diff --git a/source/lz11.cpp b/source/lz11.cpp index 27851b2..9e3c167 100644 --- a/source/lz11.cpp +++ b/source/lz11.cpp @@ -37,7 +37,7 @@ ctrff::u32 GetOccurenceLength(const ctrff::u8* new_ptr, u32 new_len, CTRFF_API std::vector Compress(const std::vector& in) { if (in.size() > 0xFFFFFF) { - std::cout << "ERROR: LZ11 input is too large!" << std::endl; + throw std::runtime_error("[ctrff] LZ11: Input is tool large to compress"); return std::vector(); } std::stringstream s; @@ -121,5 +121,55 @@ CTRFF_API std::vector Compress(const std::vector& in) { std::string tmp = s.str(); return std::vector(tmp.begin(), tmp.end()); } + +// Baed on +// https://github.com/Gericom/EveryFileExplorer/blob/master/CommonCompressors/LZ11.cs +// Needs some fixes cause this code looks very unsafe to me tbh +CTRFF_API std::vector Decompress(const std::vector& in) { + if (!in.size()) { + throw std::runtime_error("[ctrff] LZ11: Cannot decompress empty buffer!"); + } + if (in[0] != 0x11) { + throw std::runtime_error("[ctrff] LZ11: Not a lz11 file!"); + } + u32 len = in[1] | (in[2] << 8) | (in[3] << 16); + std::vector ret(len, 0x0); + int off = 4; + int dst_off = 0; + while (true) { + u8 header = in[off++]; + for (int i = 0; i < 8; i++) { + if ((header & 0x80) == 0) { + ret[dst_off++] = in[off++]; + } else { + u8 a = in[off++]; + int off2; + int length; + if ((a >> 4) == 0) { + u8 b = in[off++]; + u8 c = in[off++]; + length = (((a & 0xF) << 4) | (b >> 4)) + 0x11; + off2 = (((b & 0xF) << 8) | c) + 1; + } else if ((a >> 4) == 1) { + u8 b = in[off++]; + u8 c = in[off++]; + u8 d = in[off++]; + length = (((a & 0xF) << 12) | (b << 4) | (c >> 4)) + 0x111; + off2 = (((c & 0xF) << 8) | d) + 1; + } else { + u8 b = in[off++]; + off2 = (((a & 0xF) << 8) | b) + 1; + length = (a >> 4) + 1; + } + for (int j = 0; j < length; j++) { + ret[dst_off] = ret[dst_off - off2]; + dst_off++; + } + } + if (dst_off >= len) return ret; + header <<= 1; + } + } +} } // namespace LZ11 } // namespace ctrff \ No newline at end of file