From 5f260010b0af26e9c453931f42edcb02ce894a16 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sat, 12 Oct 2024 09:04:12 +0100 Subject: [PATCH] Reduce CLX frame header size to 6 --- src/internal/cel2clx.cpp | 7 +++---- src/internal/cl22clx.cpp | 11 ++++------- src/internal/pcx2clx.cpp | 9 ++++----- src/internal/pixels2clx.cpp | 7 +++---- src/public/include/dvl_gfx_common.hpp | 12 ++++++++++++ 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/internal/cel2clx.cpp b/src/internal/cel2clx.cpp index 58d51ba..6685989 100644 --- a/src/internal/cel2clx.cpp +++ b/src/internal/cel2clx.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include "clx_encode.hpp" @@ -83,9 +84,8 @@ std::optional CelToClx(const uint8_t *data, size_t size, // CLX frame header. const size_t frameHeaderPos = clxData.size(); - constexpr size_t FrameHeaderSize = 10; - clxData.resize(clxData.size() + FrameHeaderSize); - WriteLE16(&clxData[frameHeaderPos], FrameHeaderSize); + clxData.resize(clxData.size() + ClxFrameHeaderSize); + WriteLE16(&clxData[frameHeaderPos], ClxFrameHeaderSize); WriteLE16(&clxData[frameHeaderPos + 2], frameWidth); unsigned transparentRunWidth = 0; @@ -109,7 +109,6 @@ std::optional CelToClx(const uint8_t *data, size_t size, } AppendClxTransparentRun(transparentRunWidth, clxData); WriteLE16(&clxData[frameHeaderPos + 4], frameHeight); - memset(&clxData[frameHeaderPos + 6], 0, 4); } WriteLE32(&clxData[clxDataOffset + 4 * (1 + static_cast(numFrames))], static_cast(clxData.size() - clxDataOffset)); diff --git a/src/internal/cl22clx.cpp b/src/internal/cl22clx.cpp index 2395070..7508dd2 100644 --- a/src/internal/cl22clx.cpp +++ b/src/internal/cl22clx.cpp @@ -16,8 +16,6 @@ namespace dvl_gfx { namespace { -constexpr size_t FrameHeaderSize = 10; - constexpr bool IsCl2Opaque(uint8_t control) { constexpr uint8_t Cl2OpaqueMin = 0x80; @@ -122,14 +120,14 @@ std::optional Cl2ToClx(const uint8_t *data, size_t size, const uint16_t frameWidth = numWidths == 1 ? *widths : widths[frame - 1]; const size_t frameHeaderPos = clxData.size(); - clxData.resize(clxData.size() + FrameHeaderSize); - WriteLE16(&clxData[frameHeaderPos], FrameHeaderSize); + clxData.resize(clxData.size() + ClxFrameHeaderSize); + WriteLE16(&clxData[frameHeaderPos], ClxFrameHeaderSize); WriteLE16(&clxData[frameHeaderPos + 2], frameWidth); unsigned transparentRunWidth = 0; int_fast16_t xOffset = 0; size_t frameHeight = 0; - const uint8_t *src = frameBegin + FrameHeaderSize; + const uint8_t *src = frameBegin + LoadLE16(frameBegin); while (src != frameEnd) { auto remainingWidth = static_cast(frameWidth) - xOffset; while (remainingWidth > 0) { @@ -175,7 +173,6 @@ std::optional Cl2ToClx(const uint8_t *data, size_t size, AppendClxTransparentRun(transparentRunWidth, clxData); WriteLE16(&clxData[frameHeaderPos + 4], frameHeight); - memset(&clxData[frameHeaderPos + 6], 0, 4); } WriteLE32(&clxData[clxDataOffset + 4 * (1 + static_cast(numFrames))], static_cast(clxData.size() - clxDataOffset)); @@ -211,7 +208,7 @@ std::optional Cl2ToClxNoReencode(uint8_t *data, size_t size, uint8_t *frameBegin = frameEnd; frameEnd = &groupBegin[LoadLE32(&groupBegin[4 * (frame + 1)])]; - const size_t numPixels = CountCl2FramePixels(frameBegin + FrameHeaderSize, frameEnd); + const size_t numPixels = CountCl2FramePixels(frameBegin + LoadLE16(frameBegin), frameEnd); const uint16_t frameWidth = numWidths == 1 ? *widths : widths[frame - 1]; const uint16_t frameHeight = numPixels / frameWidth; diff --git a/src/internal/pcx2clx.cpp b/src/internal/pcx2clx.cpp index 19a3380..8267724 100644 --- a/src/internal/pcx2clx.cpp +++ b/src/internal/pcx2clx.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -65,18 +66,16 @@ std::optional PcxToClx(const uint8_t *data, size_t size, // 3. Height // 4..5. Unused (0) const size_t frameHeaderPos = clxData.size(); - constexpr size_t FrameHeaderSize = 10; - clxData.resize(clxData.size() + FrameHeaderSize); + clxData.resize(clxData.size() + ClxFrameHeaderSize); // Frame header: const uint16_t frameWidth = cropWidths.empty() - ? width + ? static_cast(width) : cropWidths[std::min(cropWidths.size(), frame) - 1]; - WriteLE16(&clxData[frameHeaderPos], FrameHeaderSize); + WriteLE16(&clxData[frameHeaderPos], ClxFrameHeaderSize); WriteLE16(&clxData[frameHeaderPos + 2], static_cast(frameWidth)); WriteLE16(&clxData[frameHeaderPos + 4], static_cast(frameHeight)); - memset(&clxData[frameHeaderPos + 6], 0, 4); for (unsigned j = 0; j < frameHeight; ++j) { uint8_t *buffer = &frameBuffer[static_cast(j) * width]; diff --git a/src/internal/pixels2clx.cpp b/src/internal/pixels2clx.cpp index 72fa84c..3e8629a 100644 --- a/src/internal/pixels2clx.cpp +++ b/src/internal/pixels2clx.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include "clx_encode.hpp" @@ -33,14 +34,12 @@ void Pixels2Clx( // 3. Height // 4..5. Unused (0) const size_t frameHeaderPos = clxData.size(); - constexpr size_t FrameHeaderSize = 10; - clxData.resize(clxData.size() + FrameHeaderSize); + clxData.resize(clxData.size() + ClxFrameHeaderSize); // Frame header: - WriteLE16(&clxData[frameHeaderPos], FrameHeaderSize); + WriteLE16(&clxData[frameHeaderPos], ClxFrameHeaderSize); WriteLE16(&clxData[frameHeaderPos + 2], static_cast(width)); WriteLE16(&clxData[frameHeaderPos + 4], static_cast(frameHeight)); - memset(&clxData[frameHeaderPos + 6], 0, 4); const uint8_t *frameBuffer = &pixels[static_cast((frame - 1) * pitch * frameHeight)]; unsigned transparentRunWidth = 0; diff --git a/src/public/include/dvl_gfx_common.hpp b/src/public/include/dvl_gfx_common.hpp index f72683d..cc8b577 100644 --- a/src/public/include/dvl_gfx_common.hpp +++ b/src/public/include/dvl_gfx_common.hpp @@ -1,6 +1,7 @@ #ifndef DVL_GFX_COMMON_H_ #define DVL_GFX_COMMON_H_ +#include #include #include @@ -16,5 +17,16 @@ struct Size { uint32_t height; }; +/** + * CLX frame header is 6 bytes: + * + * Bytes | Type | Value + * :-----:|:--------:|------------- + * 0..2 | uint16_t | header size + * 2..4 | uint16_t | width + * 4..6 | uint16_t | height + */ +constexpr size_t ClxFrameHeaderSize = 6; + } // namespace dvl_gfx #endif // DVL_GFX_COMMON_H_