Skip to content

Commit

Permalink
Reduce CLX frame header size to 6
Browse files Browse the repository at this point in the history
  • Loading branch information
glebm committed Oct 12, 2024
1 parent 64c0629 commit 5f26001
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 20 deletions.
7 changes: 3 additions & 4 deletions src/internal/cel2clx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <memory>
#include <vector>

#include <dvl_gfx_common.hpp>
#include <dvl_gfx_endian.hpp>

#include "clx_encode.hpp"
Expand Down Expand Up @@ -83,9 +84,8 @@ std::optional<IoError> 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;
Expand All @@ -109,7 +109,6 @@ std::optional<IoError> 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<size_t>(numFrames))], static_cast<uint32_t>(clxData.size() - clxDataOffset));
Expand Down
11 changes: 4 additions & 7 deletions src/internal/cl22clx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ namespace dvl_gfx {

namespace {

constexpr size_t FrameHeaderSize = 10;

constexpr bool IsCl2Opaque(uint8_t control)
{
constexpr uint8_t Cl2OpaqueMin = 0x80;
Expand Down Expand Up @@ -122,14 +120,14 @@ std::optional<IoError> 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<int_fast16_t>(frameWidth) - xOffset;
while (remainingWidth > 0) {
Expand Down Expand Up @@ -175,7 +173,6 @@ std::optional<IoError> 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<size_t>(numFrames))], static_cast<uint32_t>(clxData.size() - clxDataOffset));
Expand Down Expand Up @@ -211,7 +208,7 @@ std::optional<IoError> 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;
Expand Down
9 changes: 4 additions & 5 deletions src/internal/pcx2clx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <cassert>
#include <cerrno>
#include <cstdint>
#include <cstring>
#include <filesystem>
#include <fstream>
Expand Down Expand Up @@ -65,18 +66,16 @@ std::optional<IoError> 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<uint16_t>(width)
: cropWidths[std::min<size_t>(cropWidths.size(), frame) - 1];

WriteLE16(&clxData[frameHeaderPos], FrameHeaderSize);
WriteLE16(&clxData[frameHeaderPos], ClxFrameHeaderSize);
WriteLE16(&clxData[frameHeaderPos + 2], static_cast<uint16_t>(frameWidth));
WriteLE16(&clxData[frameHeaderPos + 4], static_cast<uint16_t>(frameHeight));
memset(&clxData[frameHeaderPos + 6], 0, 4);

for (unsigned j = 0; j < frameHeight; ++j) {
uint8_t *buffer = &frameBuffer[static_cast<size_t>(j) * width];
Expand Down
7 changes: 3 additions & 4 deletions src/internal/pixels2clx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <string>
#include <vector>

#include <dvl_gfx_common.hpp>
#include <dvl_gfx_endian.hpp>

#include "clx_encode.hpp"
Expand Down Expand Up @@ -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<uint16_t>(width));
WriteLE16(&clxData[frameHeaderPos + 4], static_cast<uint16_t>(frameHeight));
memset(&clxData[frameHeaderPos + 6], 0, 4);

const uint8_t *frameBuffer = &pixels[static_cast<size_t>((frame - 1) * pitch * frameHeight)];
unsigned transparentRunWidth = 0;
Expand Down
12 changes: 12 additions & 0 deletions src/public/include/dvl_gfx_common.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef DVL_GFX_COMMON_H_
#define DVL_GFX_COMMON_H_

#include <cstddef>
#include <cstdint>

#include <string>
Expand All @@ -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_

0 comments on commit 5f26001

Please sign in to comment.