1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#pragma once
#include <cstdint>
#include <string>
#define READER_BUFFER_SIZE 4096
#define WRITER_BUFFER_SIZE 4096
#define DEFINE_INT_READER(TYPE) \
template<> TYPE Reader::readData<TYPE>() \
{ \
TYPE in, out; \
readBytes((char*)&in, sizeof(TYPE)); \
convertEndian((uint8_t*)&in, (uint8_t*)&out, sizeof(TYPE), fileEndianness); \
return out; \
} \
#define DEFINE_INT_WRITER(TYPE) \
template <> void Writer::writeData(TYPE toWrite) \
{ \
TYPE converted; \
convertEndian((uint8_t*)&toWrite, (uint8_t*)&converted, sizeof(TYPE), fileEndianness); \
writeBytes((char*)&converted, sizeof(TYPE)); \
} \
namespace TehImage
{
enum FileEndianness
{
NO_CONVERT,
LITTLE,
BIG
};
void convertEndian(uint8_t* in, uint8_t* out, std::size_t bytes, FileEndianness target);
class Reader
{
public:
//Bytes are big endian
Reader(std::string file, FileEndianness fileEndianness);
~Reader();
template <typename T>
T readData();
char readByte();
void readBytes(char* out, std::size_t len);
void skipBytes(std::size_t len);
void close();
private:
char buffer[READER_BUFFER_SIZE];
std::size_t pos;
FILE* file;
bool ready = false;
FileEndianness fileEndianness;
void refreshBuffer();
};
class Writer
{
public:
//Bytes are big endian
Writer(std::string filename, FileEndianness fileEndianness);
~Writer();
template <typename T>
void writeData(T toWrite);
void writeByte(char toWrite);
void writeBytes(char toWrite[], std::size_t len);
void zeroBytes(std::size_t len);
void close();
void flushBuffer();
char buffer[WRITER_BUFFER_SIZE];
std::size_t pos;
private:
FILE* file;
bool ready = false;
FileEndianness fileEndianness;
};
}
|