diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c8e5d5..ab6dd43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,12 +57,14 @@ set(mapper_HDRS PixelAttributes.h PlayerAttributes.h TileGenerator.h + ZlibDecompressor.h ) set(mapper_SRCS PixelAttributes.cpp PlayerAttributes.cpp TileGenerator.cpp + ZlibDecompressor.cpp mapper.cpp ) diff --git a/TileGenerator.cpp b/TileGenerator.cpp index d22d9d7..bd0c89d 100644 --- a/TileGenerator.cpp +++ b/TileGenerator.cpp @@ -13,10 +13,10 @@ #include #include #include -#include #include "config.h" #include "PlayerAttributes.h" #include "TileGenerator.h" +#include "ZlibDecompressor.h" #include "colors.h" using namespace std; @@ -70,40 +70,6 @@ static inline int readBlockContent(const unsigned char *mapData, int version, in } } -static inline std::string zlibDecompress(const unsigned char *data, std::size_t size, std::size_t *processed) -{ - string buffer; - const size_t BUFSIZE = 128 * 1024; - uint8_t temp_buffer[BUFSIZE]; - - z_stream strm; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.next_in = Z_NULL; - strm.avail_in = size; - - if (inflateInit(&strm) != Z_OK) { - throw DecompressError(); - } - - strm.next_in = const_cast(data); - int ret = 0; - do { - strm.avail_out = BUFSIZE; - strm.next_out = temp_buffer; - ret = inflate(&strm, Z_NO_FLUSH); - buffer += string(reinterpret_cast(temp_buffer), BUFSIZE - strm.avail_out); - } while (ret == Z_OK); - if (ret != Z_STREAM_END) { - throw DecompressError(); - } - *processed = strm.next_in - data; - (void)inflateEnd(&strm); - - return buffer; -} - static inline int colorSafeBounds(int color) { if (color > 255) { @@ -371,11 +337,12 @@ void TileGenerator::renderMap() else { dataOffset = 2; } - size_t processed; - string mapData = zlibDecompress(data + dataOffset, length - dataOffset, &processed); - dataOffset += processed; - string mapMetadata = zlibDecompress(data + dataOffset, length - dataOffset, &processed); - dataOffset += processed; + + ZlibDecompressor decompressor(data, length); + decompressor.setSeekPos(dataOffset); + ZlibDecompressor::string mapData = decompressor.decompress(); + ZlibDecompressor::string mapMetadata = decompressor.decompress(); + dataOffset = decompressor.seekPos(); // Skip unused data if (version <= 21) { @@ -455,11 +422,11 @@ void TileGenerator::renderMap() } } -inline void TileGenerator::renderMapBlock(const std::string &mapBlock, const BlockPos &pos, int version) +inline void TileGenerator::renderMapBlock(const unsigned_string &mapBlock, const BlockPos &pos, int version) { int xBegin = (pos.x - m_xMin) * 16; int zBegin = (m_zMax - pos.z) * 16; - const unsigned char *mapData = reinterpret_cast(mapBlock.c_str()); + const unsigned char *mapData = mapBlock.c_str(); for (int z = 0; z < 16; ++z) { int imageY = getImageY(zBegin + 15 - z); for (int x = 0; x < 16; ++x) { @@ -608,7 +575,7 @@ std::map TileGenerator::getBlocksOnZ(int zPos, sq const unsigned char *data = reinterpret_cast(sqlite3_column_blob(statement, 1)); int size = sqlite3_column_bytes(statement, 1); BlockPos pos = decodeBlockPos(blocknum); - blocks[pos.x].push_back(Block(pos, std::basic_string(data, size))); + blocks[pos.x].push_back(Block(pos, unsigned_string(data, size))); } else { break; diff --git a/TileGenerator.h b/TileGenerator.h index da5a7f2..75b9253 100644 --- a/TileGenerator.h +++ b/TileGenerator.h @@ -62,9 +62,6 @@ class DbError { class ColorError { }; -class DecompressError { -}; - class VersionError { }; @@ -72,8 +69,9 @@ class VersionError { class TileGenerator { private: + typedef std::basic_string unsigned_string; typedef std::map ColorMap; - typedef std::pair > Block; + typedef std::pair Block; typedef std::list BlockList; public: @@ -98,7 +96,7 @@ private: void renderMap(); std::list getZValueList() const; std::map getBlocksOnZ(int zPos, sqlite3_stmt *statement) const; - void renderMapBlock(const std::string &mapBlock, const BlockPos &pos, int version); + void renderMapBlock(const unsigned_string &mapBlock, const BlockPos &pos, int version); void renderShading(int zPos); void renderScale(); void renderOrigin(); diff --git a/ZlibDecompressor.cpp b/ZlibDecompressor.cpp new file mode 100644 index 0000000..ba73aba --- /dev/null +++ b/ZlibDecompressor.cpp @@ -0,0 +1,70 @@ +/* + * ===================================================================== + * Version: 1.0 + * Created: 18.09.2012 10:20:47 + * Author: Miroslav Bendík + * Company: LinuxOS.sk + * ===================================================================== + */ + +#include +#include "ZlibDecompressor.h" + +ZlibDecompressor::ZlibDecompressor(const unsigned char *data, std::size_t size): + m_data(data), + m_seekPos(0), + m_size(size) +{ +} + +ZlibDecompressor::~ZlibDecompressor() +{ +} + +void ZlibDecompressor::setSeekPos(std::size_t seekPos) +{ + m_seekPos = seekPos; +} + +std::size_t ZlibDecompressor::seekPos() const +{ + return m_seekPos; +} + +ZlibDecompressor::string ZlibDecompressor::decompress() +{ + const unsigned char *data = m_data + m_seekPos; + const std::size_t size = m_size - m_seekPos; + + string buffer; + const size_t BUFSIZE = 128 * 1024; + uint8_t temp_buffer[BUFSIZE]; + + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.next_in = Z_NULL; + strm.avail_in = size; + + if (inflateInit(&strm) != Z_OK) { + throw DecompressError(); + } + + strm.next_in = const_cast(data); + int ret = 0; + do { + strm.avail_out = BUFSIZE; + strm.next_out = temp_buffer; + ret = inflate(&strm, Z_NO_FLUSH); + buffer += string(reinterpret_cast(temp_buffer), BUFSIZE - strm.avail_out); + } while (ret == Z_OK); + if (ret != Z_STREAM_END) { + throw DecompressError(); + } + m_seekPos += strm.next_in - data; + (void)inflateEnd(&strm); + + return buffer; +} + diff --git a/ZlibDecompressor.h b/ZlibDecompressor.h new file mode 100644 index 0000000..5b842bd --- /dev/null +++ b/ZlibDecompressor.h @@ -0,0 +1,37 @@ +/* + * ===================================================================== + * Version: 1.0 + * Created: 18.09.2012 10:20:51 + * Author: Miroslav Bendík + * Company: LinuxOS.sk + * ===================================================================== + */ + +#ifndef ZLIBDECOMPRESSOR_H_ZQL1PN8Q +#define ZLIBDECOMPRESSOR_H_ZQL1PN8Q + +#include +#include + + +class ZlibDecompressor +{ +public: + typedef std::basic_string string; + class DecompressError { + }; + + ZlibDecompressor(const unsigned char *data, std::size_t size); + ~ZlibDecompressor(); + void setSeekPos(std::size_t seekPos); + std::size_t seekPos() const; + string decompress(); + +private: + const unsigned char *m_data; + std::size_t m_seekPos; + std::size_t m_size; +}; /* ----- end of class ZlibDecompressor ----- */ + +#endif /* end of include guard: ZLIBDECOMPRESSOR_H_ZQL1PN8Q */ +