Initial fixed huffman coding for png.
This commit is contained in:
parent
e4f9393ee7
commit
7f5009fb5e
39 changed files with 1294 additions and 440 deletions
|
@ -18,6 +18,7 @@ list(APPEND TestFiles
|
|||
compiler/TestLexer.cpp
|
||||
compiler/TestTemplatingEngine.cpp
|
||||
compression/TestStreamCompressor.cpp
|
||||
compression/TestHuffmanStream.cpp
|
||||
database/TestDatabase.cpp
|
||||
fonts/TestFontReader.cpp
|
||||
graphics/TestRasterizer.cpp
|
||||
|
|
60
test/compression/TestHuffmanStream.cpp
Normal file
60
test/compression/TestHuffmanStream.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "HuffmanStream.h"
|
||||
|
||||
|
||||
void testHuffmanCodeLengthTable()
|
||||
{
|
||||
HuffmanCodeLengthTable table;
|
||||
|
||||
std::vector<std::pair<unsigned, unsigned char> > mappings {{144, 8}, {112, 9}, {24, 7}, {8 ,8}};
|
||||
std::vector<unsigned char> code_length_sequence;
|
||||
for(const auto& entry : mappings)
|
||||
{
|
||||
for(unsigned idx=0;idx<entry.first;idx++)
|
||||
{
|
||||
code_length_sequence.push_back(entry.second);
|
||||
}
|
||||
}
|
||||
table.setInputLengthSequence(code_length_sequence, false);
|
||||
|
||||
table.buildCompressedLengthSequence();
|
||||
|
||||
auto compressed_sequence = table.getCompressedLengthSequence();
|
||||
for (auto entry : compressed_sequence)
|
||||
{
|
||||
std::cout << "Count " << entry.first << " extra bits " << entry.second << std::endl;
|
||||
}
|
||||
|
||||
auto compressed_lengths = table.getCompressedLengthCounts();
|
||||
for(unsigned idx = 0; idx<compressed_lengths.size(); idx++)
|
||||
{
|
||||
std::cout << "Slot " << idx << " length " << compressed_lengths[idx] << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
testHuffmanCodeLengthTable();
|
||||
//HuffmanStream stream(nullptr, nullptr);
|
||||
|
||||
//stream.setCodeLengthAlphabetLengths({3, 3, 3, 3, 3, 2, 4, 4});
|
||||
|
||||
//stream.setCodeLengthAlphabetLengths({2, 2, 3, 3, 3, 3});
|
||||
|
||||
//stream.buildCodeLengthMapping();
|
||||
|
||||
std::cout << "*******" << std::endl;
|
||||
//stream.setCodeLengthAlphabetLengths({4, 0, 6, 7, 3, 2, 4, 2, 7, 4, 6, 3, 0, 6});
|
||||
|
||||
//stream.buildCodeLengthMapping();
|
||||
|
||||
//const auto mapping = stream.getCodeLengthMapping();
|
||||
|
||||
//stream.generateFixedCodeMapping();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -3,9 +3,13 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
void testReading()
|
||||
{
|
||||
std::vector<std::string> bytes{"11100101", "00110101", "00010001"};
|
||||
std::vector<std::string> bytes{
|
||||
"11101101",
|
||||
"01011101",
|
||||
"00001001",
|
||||
"01111111"};
|
||||
|
||||
BufferBitStream stream;
|
||||
for(const auto& byte : bytes)
|
||||
|
@ -14,17 +18,67 @@ int main()
|
|||
}
|
||||
|
||||
unsigned char buffer{0} ;
|
||||
auto valid = stream.readNextNBits(3, buffer);
|
||||
auto valid = stream.readNextNBits(1, buffer);
|
||||
std::cout << "Slice0 is " << ByteUtils::toString(buffer) << std::endl;
|
||||
|
||||
valid = stream.readNextNBits(3, buffer);
|
||||
valid = stream.readNextNBits(2, buffer);
|
||||
std::cout << "Slice1 is " << ByteUtils::toString(buffer) << std::endl;
|
||||
|
||||
valid = stream.readNextNBits(5, buffer);
|
||||
std::cout << "Slice2 is " << ByteUtils::toString(buffer) << std::endl;
|
||||
|
||||
valid = stream.readNextNBits(7, buffer);
|
||||
valid = stream.readNextNBits(5, buffer);
|
||||
std::cout << "Slice3 is " << ByteUtils::toString(buffer) << std::endl;
|
||||
|
||||
valid = stream.readNextNBits(4, buffer);
|
||||
std::cout << "Slice3 is " << ByteUtils::toString(buffer) << " and int " << static_cast<int>(buffer) << std::endl;
|
||||
|
||||
valid = stream.readNextNBits(3, buffer);
|
||||
std::cout << "Slice3 is " << ByteUtils::toString(buffer) << std::endl;
|
||||
}
|
||||
|
||||
void testWriting()
|
||||
{
|
||||
BufferBitStream stream;
|
||||
|
||||
stream.writeByte(ByteUtils::getFromString("01100000"));
|
||||
|
||||
auto bits0 = ByteUtils::getFromString("00000111");
|
||||
stream.writeNBits(bits0, 3);
|
||||
|
||||
stream.writeByte(ByteUtils::getFromString("11110000"));
|
||||
|
||||
auto bits1 = ByteUtils::getFromString("01001101");
|
||||
stream.writeNBits(bits1, 7);
|
||||
|
||||
stream.writeByte(ByteUtils::getFromString("11110000"));
|
||||
|
||||
auto bits2 = ByteUtils::getFromString("00000001");
|
||||
stream.writeNBits(bits2, 1);
|
||||
|
||||
stream.flushRemainingBits();
|
||||
|
||||
stream.resetOffsets();
|
||||
|
||||
auto byte0 = ByteUtils::toString(*stream.readNextByte());
|
||||
auto byte1 = ByteUtils::toString(*stream.readNextByte());
|
||||
auto byte2 = ByteUtils::toString(*stream.readNextByte());
|
||||
auto byte3 = ByteUtils::toString(*stream.readNextByte());
|
||||
auto byte4 = ByteUtils::toString(*stream.readNextByte());
|
||||
|
||||
std::cout << "Got bytes 0 " << byte0 << std::endl;
|
||||
std::cout << "Got bytes 1 " << byte1 << std::endl;
|
||||
std::cout << "Got bytes 2 " << byte2 << std::endl;
|
||||
std::cout << "Got bytes 3 " << byte3 << std::endl;
|
||||
std::cout << "Got bytes 4 " << byte4 << std::endl;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
//testReading()
|
||||
|
||||
testWriting();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,5 +24,10 @@ int main()
|
|||
std::cout << "Byte2 is " << ByteUtils::toString(byte2) << std::endl;
|
||||
std::cout << "Byte3 is " << ByteUtils::toString(byte3) << std::endl;
|
||||
|
||||
std::cout << "Mirroring" << std::endl;
|
||||
|
||||
auto out = ByteUtils::mirror(byte);
|
||||
std::cout << "Mirror is " << ByteUtils::toString(out) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,25 +5,43 @@
|
|||
#include "Image.h"
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
void testThirdParty()
|
||||
{
|
||||
//const auto path = "/home/jmsgrogan/Downloads/test.png";
|
||||
|
||||
//const auto path = "/home/jmsgrogan/Downloads/index.png";
|
||||
const auto path = "/home/jmsgrogan/Downloads/index.png";
|
||||
|
||||
const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test.png";
|
||||
//const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test.png";
|
||||
|
||||
File file(path);
|
||||
std::cout << file.dumpBinary();
|
||||
//File file(path);
|
||||
//std::cout << file.dumpBinary();
|
||||
|
||||
PngReader reader;
|
||||
reader.setPath(path);
|
||||
auto image = reader.read();
|
||||
|
||||
for(unsigned idx=0; idx<image->getWidth()*image->getBytesPerRow(); idx++)
|
||||
{
|
||||
std::cout << "Image val: " << idx << " | " << static_cast<int>(image->getDataRef()[idx]) << std::endl;
|
||||
}
|
||||
//for(unsigned idx=0; idx<image->getWidth()*image->getBytesPerRow(); idx++)
|
||||
//{
|
||||
// std::cout << "Image val: " << idx << " | " << static_cast<int>(image->getDataRef()[idx]) << std::endl;
|
||||
//}
|
||||
}
|
||||
|
||||
void testFixedCode()
|
||||
{
|
||||
const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test_fixed.png";
|
||||
|
||||
//File file(path);
|
||||
//std::cout << file.dumpBinary();
|
||||
|
||||
PngReader reader;
|
||||
reader.setPath(path);
|
||||
auto image = reader.read();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
testThirdParty();
|
||||
//testFixedCode();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
#include "File.h"
|
||||
#include "BitStream.h"
|
||||
#include "ByteUtils.h"
|
||||
#include "ImagePrimitives.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
void testCompressedPng()
|
||||
{
|
||||
unsigned width = 20;
|
||||
unsigned height = 20;
|
||||
|
@ -26,11 +27,11 @@ int main()
|
|||
image->setData(data);
|
||||
|
||||
PngWriter writer;
|
||||
writer.setPath("test.png");
|
||||
writer.setPath("test_compressed.png");
|
||||
writer.write(image);
|
||||
|
||||
return 0;
|
||||
File test_file("test.png");
|
||||
return;
|
||||
File test_file("test_compressed.png");
|
||||
test_file.SetAccessMode(File::AccessMode::Read);
|
||||
test_file.Open(true);
|
||||
|
||||
|
@ -39,6 +40,41 @@ int main()
|
|||
std::cout << static_cast<unsigned>(*byte) << std::endl;
|
||||
}
|
||||
test_file.Close();
|
||||
}
|
||||
|
||||
void testFixedPng()
|
||||
{
|
||||
unsigned width = 10;
|
||||
unsigned height = 10;
|
||||
unsigned numChannels = 1;
|
||||
auto image = Image<unsigned char>::Create(width, height);
|
||||
image->setNumChannels(numChannels);
|
||||
image->setBitDepth(8);
|
||||
|
||||
std::vector<unsigned char> data(width*height, 0);
|
||||
for (unsigned idx=0; idx<width*height; idx++)
|
||||
{
|
||||
//unsigned char val = 100 * idx /(width*height);
|
||||
unsigned char val = 10;
|
||||
data[idx] = val;
|
||||
}
|
||||
|
||||
image->setData(data);
|
||||
|
||||
PngWriter writer;
|
||||
writer.setPath("test_fixed.png");
|
||||
writer.setCompressionMethod(Deflate::CompressionMethod::FIXED_HUFFMAN);
|
||||
writer.write(image);
|
||||
|
||||
//return;
|
||||
File test_file("test_fixed.png");
|
||||
std::cout << test_file.dumpBinary();
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
//testCompressedPng();
|
||||
testFixedPng();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue