mirror of https://github.com/sz3/libcimbar
A bunch of WIP stuff
This commit is contained in:
parent
4ba1f0d6a7
commit
5eb9773855
|
@ -16,9 +16,12 @@ endif()
|
|||
set (PROJECTS
|
||||
#src/exe/cimbar
|
||||
|
||||
#src/lib/encoder
|
||||
src/lib/bit_file
|
||||
src/lib/cimb_translator
|
||||
src/lib/encoder
|
||||
src/lib/extractor
|
||||
#src/lib/util
|
||||
src/lib/serialize
|
||||
src/lib/util
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(SOURCES
|
||||
bitreader.h
|
||||
bitwriter.h
|
||||
)
|
||||
|
||||
add_custom_target(bit_file SOURCES ${SOURCES})
|
||||
|
||||
add_subdirectory(test)
|
|
@ -0,0 +1,60 @@
|
|||
#include <iostream>
|
||||
#include <tuple>
|
||||
|
||||
class bitreader
|
||||
{
|
||||
public:
|
||||
bitreader(const char* buffer, unsigned size)
|
||||
: _buffer(buffer)
|
||||
, _size(size)
|
||||
, _position(0)
|
||||
, _bitoffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return _position >= _size;
|
||||
}
|
||||
|
||||
unsigned readBit()
|
||||
{
|
||||
if (empty())
|
||||
return 0;
|
||||
|
||||
unsigned bit = (_buffer[_position] & (1 << (7 - _bitoffset)));
|
||||
++_bitoffset;
|
||||
if (_bitoffset == 8)
|
||||
{
|
||||
_position += 1;
|
||||
_bitoffset -= 8;
|
||||
}
|
||||
return bit? 1 : 0;
|
||||
}
|
||||
|
||||
unsigned read(unsigned how_many_bits)
|
||||
{
|
||||
//auto [bytes, bits] = bytes_and_bits(how_many_bits, _bitoffset);
|
||||
|
||||
unsigned res = 0;
|
||||
for (unsigned i = 0; i < how_many_bits; ++i)
|
||||
{
|
||||
unsigned bit = readBit();
|
||||
res |= bit << (how_many_bits - i - 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::tuple<unsigned, unsigned> bytes_and_bits(unsigned how_many_bits, unsigned bitoffset) const
|
||||
{
|
||||
unsigned remainder_bits = how_many_bits % 8;
|
||||
unsigned bytes = how_many_bits / 8;
|
||||
return {bytes, remainder_bits};
|
||||
}
|
||||
|
||||
protected:
|
||||
const char* _buffer;
|
||||
unsigned _size;
|
||||
unsigned _position;
|
||||
unsigned _bitoffset;
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
class bitwriter
|
||||
{
|
||||
public:
|
||||
bitwriter(char* buffer, unsigned size)
|
||||
: _buffer(buffer)
|
||||
, _size(size)
|
||||
{
|
||||
}
|
||||
|
||||
bool writeBit(bool bit)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
char* _buffer;
|
||||
unsigned _size;
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
project(bit_file_test)
|
||||
|
||||
set (SOURCES
|
||||
test.cpp
|
||||
bitreaderTest.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${libcimbar_SOURCE_DIR}/test
|
||||
${libcimbar_SOURCE_DIR}/test/lib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
)
|
||||
|
||||
add_executable (
|
||||
bit_file_test
|
||||
${SOURCES}
|
||||
)
|
||||
|
||||
add_test(bit_file_test bit_file_test)
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#include "unittest.h"
|
||||
|
||||
#include "bitreader.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
TEST_CASE( "bitreaderTest/testSimple", "[unit]" )
|
||||
{
|
||||
std::string input = "Hello world";
|
||||
bitreader br(input.data(), input.size());
|
||||
assertEquals( 0x48, br.read(8) );
|
||||
assertEquals( 0x65, br.read(8) );
|
||||
assertEquals( 0x6c, br.read(8) );
|
||||
assertEquals( 0x6c, br.read(8) );
|
||||
assertEquals( 0x6f, br.read(8) );
|
||||
assertEquals( 0x20, br.read(8) );
|
||||
}
|
||||
|
||||
TEST_CASE( "bitreaderTest/testDefault", "[unit]" )
|
||||
{
|
||||
std::string input = "Hello world";
|
||||
bitreader br(input.data(), input.size());
|
||||
|
||||
std::vector<unsigned> res;
|
||||
while (!br.empty())
|
||||
res.push_back(br.read(8));
|
||||
|
||||
std::vector<unsigned> expected({0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64});
|
||||
assertEquals(expected, res);
|
||||
}
|
||||
|
||||
TEST_CASE( "bitreaderTest/testPartial", "[unit]" )
|
||||
{
|
||||
std::string input = "Hello world";
|
||||
bitreader br(input.data(), input.size());
|
||||
|
||||
std::vector<unsigned> res;
|
||||
while (!br.empty())
|
||||
res.push_back(br.read(5));
|
||||
|
||||
std::vector<unsigned> expected({9, 1, 18, 22, 24, 27, 3, 15, 4, 1, 27, 22, 30, 28, 19, 12, 12, 16});
|
||||
assertEquals(expected, res);
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(SOURCES
|
||||
CimbWriter.cpp
|
||||
CimbWriter.h
|
||||
)
|
||||
|
||||
add_library(cimb_translator STATIC ${SOURCES})
|
||||
|
||||
add_subdirectory(test)
|
|
@ -0,0 +1,43 @@
|
|||
#include "CimbWriter.h"
|
||||
|
||||
#include "serialize/format.h"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
using std::string;
|
||||
|
||||
namespace {
|
||||
string getTileDir(unsigned tile_bits)
|
||||
{
|
||||
return fmt::format("{}/bitmap/{}", LIBCIMBAR_PROJECT_ROOT, tile_bits);
|
||||
}
|
||||
}
|
||||
|
||||
CimbWriter::CimbWriter(unsigned tile_bits)
|
||||
{
|
||||
_numSymbols = (1 << tile_bits);
|
||||
load_tiles(getTileDir(tile_bits));
|
||||
}
|
||||
|
||||
cv::Mat CimbWriter::load_tile(string tile_dir, unsigned index)
|
||||
{
|
||||
string imgPath = fmt::format("{}/{:02x}.png", tile_dir, index);
|
||||
std::cout << imgPath << std::endl;
|
||||
cv::Mat temp = cv::imread(imgPath);
|
||||
return temp;
|
||||
}
|
||||
|
||||
// dir will need to be passed via env? Doesn't make sense to compile it in, and doesn't *really* make sense to use cwd
|
||||
bool CimbWriter::load_tiles(std::string tile_dir)
|
||||
{
|
||||
for (unsigned i = 0; i < _numSymbols; ++i)
|
||||
_tiles.push_back(load_tile(tile_dir, i));
|
||||
return true;
|
||||
}
|
||||
|
||||
const cv::Mat& CimbWriter::encode(unsigned bits) const
|
||||
{
|
||||
unsigned symbol = bits % _numSymbols;
|
||||
unsigned color = bits / _numSymbols;
|
||||
std::cout << fmt::format("symbol {}, color {}", symbol, color) << std::endl;
|
||||
return _tiles[symbol];
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class CimbWriter
|
||||
{
|
||||
public:
|
||||
CimbWriter(unsigned tile_bits=4);
|
||||
|
||||
cv::Mat load_tile(std::string tile_dir, unsigned index);
|
||||
bool load_tiles(std::string tile_dir);
|
||||
|
||||
const cv::Mat& encode(unsigned bits) const;
|
||||
|
||||
protected:
|
||||
std::vector<cv::Mat> _tiles;
|
||||
unsigned _numSymbols;
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(cimb_translator_test)
|
||||
|
||||
set (SOURCES
|
||||
test.cpp
|
||||
CimbWriterTest.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${libcimbar_SOURCE_DIR}/test
|
||||
${libcimbar_SOURCE_DIR}/test/lib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
)
|
||||
|
||||
add_executable (
|
||||
cimb_translator_test
|
||||
${SOURCES}
|
||||
)
|
||||
|
||||
add_test(cimb_translator_test cimb_translator_test)
|
||||
|
||||
target_link_libraries(cimb_translator_test
|
||||
cimb_translator
|
||||
|
||||
opencv_core
|
||||
opencv_imgcodecs
|
||||
opencv_imgproc
|
||||
opencv_photo
|
||||
)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#include "unittest.h"
|
||||
|
||||
#include "CimbWriter.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
TEST_CASE( "CimbWriterTest/testSimple", "[unit]" )
|
||||
{
|
||||
CimbWriter cw(4);
|
||||
cv::Mat res = cw.encode(15);
|
||||
|
||||
std::cout << res << std::endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(SOURCES
|
||||
Decoder.cpp
|
||||
Decoder.h
|
||||
Encoder.cpp
|
||||
Encoder.h
|
||||
)
|
||||
|
||||
add_library(encoder STATIC ${SOURCES})
|
||||
|
||||
add_subdirectory(test)
|
|
@ -0,0 +1,39 @@
|
|||
#include "Decoder.h"
|
||||
|
||||
#include "bit_file/bitreader.h"
|
||||
#include "util/File.h"
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
Decoder::Decoder()
|
||||
{
|
||||
}
|
||||
|
||||
/* while bits == f.read_tile()
|
||||
* decode(bits)
|
||||
*
|
||||
* bitwriter bw("output.txt");
|
||||
* img = open("foo.png")
|
||||
* for tileX, tileY in img
|
||||
* bits = decoder.decode(img, tileX, tileY)
|
||||
* bw.write(bits)
|
||||
* if bw.shouldFlush()
|
||||
* bw.flush()
|
||||
*
|
||||
* */
|
||||
|
||||
|
||||
unsigned Decoder::decode(string filename)
|
||||
{
|
||||
unsigned bits_per_op = 6;
|
||||
|
||||
File f(filename);
|
||||
|
||||
char buffer[8192];
|
||||
while (f.good())
|
||||
{
|
||||
bitreader br(buffer, 8192);
|
||||
unsigned bits = br.read(bits_per_op);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class Decoder
|
||||
{
|
||||
public:
|
||||
Decoder(); // pass in handler interface
|
||||
|
||||
unsigned decode(std::string filename);
|
||||
|
||||
protected:
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
#include "Encoder.h"
|
||||
|
||||
#include "bit_file/bitreader.h"
|
||||
#include "util/File.h"
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
Encoder::Encoder(unsigned bits_per_symbol, unsigned bits_per_color)
|
||||
: _bitsPerSymbol(bits_per_symbol)
|
||||
, _bitsPerColor(bits_per_color)
|
||||
{
|
||||
}
|
||||
|
||||
/* while bits == f.read(buffer, 8192)
|
||||
* encode(bits)
|
||||
*
|
||||
* char buffer[2000];
|
||||
* while f.read(buffer)
|
||||
* bit_buffer bb(buffer)
|
||||
* while bb
|
||||
* bits1 = bb.get(_bitsPerSymbol)
|
||||
* bits2 = bb.get(_bitsPerColor)
|
||||
*
|
||||
* */
|
||||
|
||||
|
||||
unsigned Encoder::encode(string filename, string output)
|
||||
{
|
||||
unsigned bits_per_op = _bitsPerColor + _bitsPerSymbol;
|
||||
unsigned readSize = 8192; // should be a multiple of bits_per_op and 8
|
||||
|
||||
char buffer[readSize];
|
||||
File f(filename);
|
||||
while (f.good())
|
||||
{
|
||||
unsigned bytes = f.read(buffer, readSize);
|
||||
bitreader br(buffer, bytes);
|
||||
while (!br.empty())
|
||||
{
|
||||
unsigned bits = br.read(bits_per_op);
|
||||
std::cout << "read " << bits << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class Encoder
|
||||
{
|
||||
public:
|
||||
Encoder(unsigned bits_per_symbol, unsigned bits_per_color); // pass in handler interface
|
||||
|
||||
unsigned encode(std::string filename, std::string output);
|
||||
|
||||
protected:
|
||||
unsigned _bitsPerSymbol;
|
||||
unsigned _bitsPerColor;
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(encoder_test)
|
||||
|
||||
set (SOURCES
|
||||
test.cpp
|
||||
EncoderTest.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${libcimbar_SOURCE_DIR}/test
|
||||
${libcimbar_SOURCE_DIR}/test/lib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
)
|
||||
|
||||
add_executable (
|
||||
encoder_test
|
||||
${SOURCES}
|
||||
)
|
||||
|
||||
add_test(encoder_test encoder_test)
|
||||
|
||||
target_link_libraries(encoder_test
|
||||
encoder
|
||||
)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include "unittest.h"
|
||||
|
||||
#include "encoder/Encoder.h"
|
||||
#include "util/File.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
TEST_CASE( "EncoderTest/testDefault", "[unit]" )
|
||||
{
|
||||
std::string input = "Hello world";
|
||||
File f("/tmp/test.txt");
|
||||
f.write(input.data(), input.size());
|
||||
|
||||
Encoder enc(4, 2);
|
||||
enc.encode("/tmp/test.txt", "/tmp/doesntmatteryet.txt");
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(SOURCES
|
||||
format.h
|
||||
)
|
||||
|
||||
add_custom_target(serialize SOURCES ${SOURCES})
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#define FMT_HEADER_ONLY
|
||||
#include "cppformat/format.h"
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
set(SOURCES
|
||||
File.h
|
||||
)
|
||||
|
||||
add_custom_target(util SOURCES ${SOURCES})
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
class File
|
||||
{
|
||||
public:
|
||||
File(std::string filename, bool write=false)
|
||||
{
|
||||
_fp = fopen(filename.c_str(), write? "wb" : "rb");
|
||||
_good = true;
|
||||
}
|
||||
|
||||
unsigned read(char* buffer, unsigned bytes)
|
||||
{
|
||||
unsigned res = fread(buffer, sizeof(char), bytes, _fp);
|
||||
if (res != bytes)
|
||||
_good = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
unsigned write(char* buffer, unsigned bytes)
|
||||
{
|
||||
unsigned res = fwrite(buffer, sizeof(char), bytes, _fp);
|
||||
if (res != bytes)
|
||||
_good = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
~File()
|
||||
{
|
||||
if (_fp != NULL)
|
||||
fclose(_fp);
|
||||
}
|
||||
|
||||
bool good() const
|
||||
{
|
||||
return _good;
|
||||
}
|
||||
|
||||
protected:
|
||||
FILE* _fp;
|
||||
bool _good;
|
||||
};
|
Loading…
Reference in New Issue