aboutsummaryrefslogtreecommitdiff
path: root/src/zlib.cpp
diff options
context:
space:
mode:
authorDylan <boss@tehbox.org>2026-05-06 15:55:59 +1200
committerDylan <boss@tehbox.org>2026-05-06 15:55:59 +1200
commit85cd1ecf29c3a295536ccc3782c2415d7518aef0 (patch)
tree2725c2b022a081e57e9dca90ef1fb309ff379337 /src/zlib.cpp
parent4d5d07beeef8ae4b7daf602bf66216ed8ff81442 (diff)
downloadtehimage-PNG-writing.tar.gz
tehimage-PNG-writing.zip
feat: Implemented PNG image writingPNG-writing
It finally works now Definitely some clean up to be done
Diffstat (limited to 'src/zlib.cpp')
-rw-r--r--src/zlib.cpp40
1 files changed, 31 insertions, 9 deletions
diff --git a/src/zlib.cpp b/src/zlib.cpp
index 022b2fc..221137c 100644
--- a/src/zlib.cpp
+++ b/src/zlib.cpp
@@ -5,6 +5,7 @@
#include <bitset>
#include <cstdint>
#include <cstring>
+#include <exception>
#include <iomanip>
#include <iostream>
#include <stdexcept>
@@ -274,7 +275,6 @@ namespace TehImage
long byte = stream->pos / 8;
if(byte >= stream->length)
{
- cout << byte << " " << stream->length << endl;
throw std::out_of_range("Ran out of compressed data");
}
stream->pos++;
@@ -334,7 +334,6 @@ namespace TehImage
bool final;
do
{
-
final = nextBit(&stream);
CompressionType method = (CompressionType)nextBits(&stream, 2);
@@ -368,6 +367,8 @@ namespace TehImage
do
{
code = getNextCode(&stream);
+
+ // cout << 'a' << endl;
if(outPos > outLength && code != 256)
{
throw std::out_of_range("No more space left in image (normal)");
@@ -376,10 +377,14 @@ namespace TehImage
out[outPos++] = (uint8_t)code;
else if(code > 256)
{
+ // cout << 'b' << endl;
unsigned int len = lenStart[code-257] + (int)nextBits(&stream, lenExtra[code-257]);
+ // cout << 'c' << endl;
unsigned int distCode = getNextCode(&stream, &distTree);
+ // cout << 'd' << endl;
unsigned int dist = distStart[distCode] + (int)nextBits(&stream, distExtra[distCode]);
+ // cout << 'e' << endl;
if(outPos + len > outLength)
{
throw std::out_of_range("No more space left in image (RLE error)");
@@ -389,7 +394,9 @@ namespace TehImage
out[outPos] = out[outPos - dist];
outPos++;
}
+ // cout << 'f' << endl;
}
+ // cout << 'z' << endl;
}
while(code != 256);
}
@@ -440,7 +447,7 @@ namespace TehImage
getStaticHuffmanCodes(codes, codeLens, distCodes, distCodeLens);
// cout << inPos << " " << length << endl;
- HashTable hashTable(255);
+ HashTable hashTable(256);
while(inPos < length)
{
if(inPos + 2 >= length)
@@ -451,22 +458,26 @@ namespace TehImage
}
char curr[3];
- memcpy(curr, &data[inPos], 3);
- if(hashTable.contains(curr))
+ memcpy(curr, &(data[inPos]), 3);
+ if(hashTable.contains(curr) && inPos - hashTable.get(curr) < 32768)
{
unsigned long pos = hashTable.get(curr);
int length = 3;
- while(data[pos + length] == data[inPos + length])
+ while(data[pos + length] == data[inPos + length]
+ && pos + length < inPos && length < 258)
length++;
+ // length--;
-
+ bool lFound = false, dFound = false;
uint16_t lenCode, lenExtraBits;
- for(uint16_t i = 0; i < 30; i++)
+ for(uint16_t i = 0; i < 29; i++)
{
if(lenStart[i] <= length && lenStart[i] + (0b1 << lenExtra[i]) - 1 >= length)
{
lenCode = i;
lenExtraBits = length - lenStart[i];
+ lFound = true;
+ break;
}
}
unsigned long dist = inPos - pos;
@@ -476,10 +487,19 @@ namespace TehImage
if(distStart[i] <= dist && distStart[i] + (0b1 << distExtra[i]) - 1 >= dist)
{
distCode = i;
- distExtraBits = dist - distCodes[i];
+ distExtraBits = dist - distStart[i];
+ dFound = true;
+ break;
}
}
+ if(!(lFound && dFound))
+ {
+ cout << ((lFound)?'y':'n') << " " << ((dFound)?'y':'n') << endl;
+ cout << length << " " << dist << endl;
+ throw std::runtime_error("UH OH");
+ }
+
writeCode(&outStream, codes[lenCode + 257], codeLens[lenCode + 257]);
writeBits(&outStream, lenExtra[lenCode], lenExtraBits);
writeCode(&outStream, distCodes[distCode], distCodeLens[distCode]);
@@ -494,6 +514,8 @@ namespace TehImage
inPos++;
}
}
+
+ writeCode(&outStream, codes[256], codeLens[256]);
return (outStream.pos / 8) + ((outStream.pos % 8 == 0)?0:1);
}