actually using lzw this time I think.
This commit is contained in:
@@ -81,7 +81,7 @@ void expandPixel(Grid2& grid, AnimationConfig config, std::vector<std::tuple<siz
|
|||||||
Vec2 seedPOS = std::get<1>(seed);
|
Vec2 seedPOS = std::get<1>(seed);
|
||||||
Vec4 seedColor = std::get<2>(seed);
|
Vec4 seedColor = std::get<2>(seed);
|
||||||
std::vector<size_t> neighbors = grid.getNeighbors(id);
|
std::vector<size_t> neighbors = grid.getNeighbors(id);
|
||||||
grid.setSize(id, grid.getSize(id)+4);
|
//grid.setSize(id, grid.getSize(id)+4);
|
||||||
for (size_t neighbor : neighbors) {
|
for (size_t neighbor : neighbors) {
|
||||||
if (visitedThisFrame.count(neighbor)) {
|
if (visitedThisFrame.count(neighbor)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -107,12 +107,12 @@ void expandPixel(Grid2& grid, AnimationConfig config, std::vector<std::tuple<siz
|
|||||||
newcolor = newcolor.clamp(0.0f, 1.0f);
|
newcolor = newcolor.clamp(0.0f, 1.0f);
|
||||||
|
|
||||||
grid.setColor(neighbor, newcolor);
|
grid.setColor(neighbor, newcolor);
|
||||||
//newseeds.emplace_back(neighbor, neipos, newcolor);
|
newseeds.emplace_back(neighbor, neipos, newcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//seeds.clear();
|
seeds.clear();
|
||||||
//seeds.shrink_to_fit();
|
seeds.shrink_to_fit();
|
||||||
//seeds = std::move(newseeds);
|
seeds = std::move(newseeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool exportavi(std::vector<std::vector<uint8_t>> frames, AnimationConfig config) {
|
//bool exportavi(std::vector<std::vector<uint8_t>> frames, AnimationConfig config) {
|
||||||
|
|||||||
@@ -124,69 +124,40 @@ public:
|
|||||||
throw std::runtime_error("LZ78 compression can only be applied to raw data");
|
throw std::runtime_error("LZ78 compression can only be applied to raw data");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::vector<uint8_t>> repeats = getRepeats();
|
std::unordered_map<uint16_t, uint16_t> dict;
|
||||||
repeats = sortvecs(repeats);
|
for (uint16_t i = 0; i < 256; i++) {
|
||||||
uint16_t nextDict = 1;
|
dict[i] = i;
|
||||||
|
}
|
||||||
|
//std::vector<std::vector<uint8_t>> repeats = getRepeats();
|
||||||
|
//repeats = sortvecs(repeats);
|
||||||
|
|
||||||
std::vector<uint16_t> compressed;
|
std::vector<uint16_t> compressed;
|
||||||
size_t cpos = 0;
|
uint16_t nextDict = 256;
|
||||||
|
uint16_t cpos = 0;
|
||||||
|
|
||||||
for (const auto& rseq : repeats) {
|
for (uint8_t byte : _data) {
|
||||||
if (!rseq.empty() && rseq.size() > 1 && overheadmap.size() < 65535) {
|
uint16_t newval = cpos << 8 | byte;
|
||||||
overheadmap[nextDict] = rseq;
|
if (dict.find(newval) != dict.end()) {
|
||||||
nextDict++;
|
cpos = dict[newval];
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (cpos < _data.size()) {
|
|
||||||
bool found_match = false;
|
|
||||||
uint16_t best_dict_index = 0;
|
|
||||||
size_t best_match_length = 0;
|
|
||||||
|
|
||||||
// Iterate through dictionary in priority order (longest patterns first)
|
|
||||||
for (uint16_t dict_idx = 1; dict_idx <= overheadmap.size(); dict_idx++) {
|
|
||||||
const auto& dict_seq = overheadmap[dict_idx];
|
|
||||||
|
|
||||||
// Quick length check - if remaining data is shorter than pattern, skip
|
|
||||||
if (dict_seq.size() > (_data.size() - cpos)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this pattern matches at current position
|
|
||||||
bool match = true;
|
|
||||||
for (size_t i = 0; i < dict_seq.size(); ++i) {
|
|
||||||
if (_data[cpos + i] != dict_seq[i]) {
|
|
||||||
match = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
// Found a match - use it immediately (first match is best due to sorting)
|
|
||||||
best_dict_index = dict_idx;
|
|
||||||
best_match_length = dict_seq.size();
|
|
||||||
found_match = true;
|
|
||||||
break; // Stop searching - we found our match
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_match && best_match_length > 1) {
|
|
||||||
// Write dictionary reference
|
|
||||||
compressed.push_back(best_dict_index);
|
|
||||||
cpos += best_match_length;
|
|
||||||
} else {
|
} else {
|
||||||
// Write literal: 0 followed by the literal byte
|
_compressedData.push_back(cpos);
|
||||||
compressed.push_back(0);
|
_compressedData.push_back(byte);
|
||||||
compressed.push_back(_data[cpos]);
|
if (nextDict < 65535) {
|
||||||
cpos++;
|
dict[newval] = nextDict++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
cpos = 0;
|
||||||
|
}
|
||||||
|
if (cpos != 0) {
|
||||||
|
_compressedData.push_back(cpos);
|
||||||
|
_compressedData.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ratio = compressed.size() / _data.size();
|
ratio = compressed.size() / _data.size();
|
||||||
sourceSize = _data.size();
|
sourceSize = _data.size();
|
||||||
|
|
||||||
_compressedData = std::move(compressed);
|
// _compressedData = std::move(compressed);
|
||||||
_compressedData.shrink_to_fit();
|
// _compressedData.shrink_to_fit();
|
||||||
|
|
||||||
// Clear uncompressed data
|
// Clear uncompressed data
|
||||||
_data.clear();
|
_data.clear();
|
||||||
@@ -367,42 +338,29 @@ private:
|
|||||||
if (cformat != compresstype::LZ78) {
|
if (cformat != compresstype::LZ78) {
|
||||||
throw std::runtime_error("Data is not LZ78 compressed");
|
throw std::runtime_error("Data is not LZ78 compressed");
|
||||||
}
|
}
|
||||||
//std::cout << "why is this breaking? breakpoint f366" << std::endl;
|
|
||||||
std::vector<uint8_t> decompressedData;
|
|
||||||
decompressedData.reserve(sourceSize);
|
|
||||||
|
|
||||||
size_t cpos = 0;
|
std::unordered_map<uint16_t, std::vector<uint8_t>> dict;
|
||||||
|
for (uint16_t i = 0; i < 256; i++) {
|
||||||
while (cpos < _compressedData.size()) {
|
dict[i] = {static_cast<uint8_t>(i)};
|
||||||
uint16_t token = _compressedData[cpos++];
|
|
||||||
//std::cout << "why is this breaking? breakpoint f374." << cpos << std::endl;
|
|
||||||
if (token != 0) {
|
|
||||||
// Dictionary reference
|
|
||||||
auto it = overheadmap.find(token);
|
|
||||||
if (it != overheadmap.end()) {
|
|
||||||
const std::vector<uint8_t>& dict_entry = it->second;
|
|
||||||
decompressedData.insert(decompressedData.end(), dict_entry.begin(), dict_entry.end());
|
|
||||||
} else {
|
|
||||||
throw std::runtime_error("Invalid dictionary reference in compressed data");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Literal byte
|
|
||||||
if (cpos < _compressedData.size()) {
|
|
||||||
decompressedData.push_back(static_cast<uint8_t>(_compressedData[cpos++]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_data = std::move(decompressedData);
|
uint16_t nextdict = 256;
|
||||||
_compressedData.clear();
|
|
||||||
_compressedData.shrink_to_fit();
|
for (size_t i = 0; i < _compressedData.size(); i+=2) {
|
||||||
overheadmap.clear();
|
uint16_t cpos = _compressedData[i];
|
||||||
cformat = compresstype::RAW;
|
uint8_t byte = _compressedData[i+1];
|
||||||
|
std::vector<uint8_t> seq = dict[cpos];
|
||||||
|
seq.push_back(byte);
|
||||||
|
_data.insert(_data.end(), seq.begin(), seq.end());
|
||||||
|
if (nextdict < 65535 && cpos != 0) {
|
||||||
|
dict[nextdict++] = seq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cformat == compresstype::RAW;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
frame& decompressFrameRLE() {
|
frame& decompressFrameRLE() {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
std::vector<uint8_t> decompressed;
|
std::vector<uint8_t> decompressed;
|
||||||
|
|||||||
Reference in New Issue
Block a user