aboutsummaryrefslogtreecommitdiff
path: root/src/WEBPImage.cpp
blob: 4c4652e0bf3ba8c5940acc674299f875e6a6b8f6 (plain) (blame)
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
93
94
95
96
97
98
99
100
101
102
#include "WEBPImage.h"
#include "reader.h"

#define ENABLE_DEBUG
#include "debug.h"

#include <iostream>

using std::cout, std::endl;

namespace TehImage
{
	int WEBPImage::writeToFile(std::string filename)
	{
		cout << "Not implemented" << endl;
		return 1;
	}
	
	int WEBPImage::readFromFile(std::string filename)
	{
		static_assert(std::endian::native == std::endian::little, "Must use little endian");
		reader = std::make_unique<Reader>(filename, FileEndianness::LITTLE);
		
		refreshBitBuffer();

		char RIFF[4], WEBP[4];
		char RIFFExpected[] = {'R','I','F','F'};
		readFourCC(RIFF);
		uint32_t imgSize = readBits(32);
		readFourCC(WEBP);
		char WEBPExpected[] = {'W','E','B','P'};
		if(strncmp(RIFF, RIFFExpected, 4) != 0 || strncmp(WEBP, WEBPExpected, 4) != 0)
		{
			cout << "Not a webp" << endl;
			// cout << '#' << std::hex << RIFF.raw << " #" << RIFFExpected.raw << std::dec << endl;
			// cout << '#' << std::hex << WEBP.raw << " #" << WEBPExpected.raw << std::dec << endl;
			return 1;
		}

		// refreshBitBuffer();

		char VP8L[4];
		readFourCC(VP8L);
		char VP8LExpected[] = {'V', 'P', '8', 'L'};
		uint32_t VP8LSize = readBits(32);
		uint8_t signature = readBits(8);
		if(strncmp(VP8L, VP8LExpected, 4) != 0)
		{
			cout << "VP8L error" << endl;
			return 1;
		}

		uint16_t width = readBits(14) + 1;
		uint16_t height = readBits(14) + 1;

		cout << width << " " << height << endl;

		bool alpha = readBits(1);
		uint8_t versionNumber = readBits(3);

		cout << "Alpha: " << (alpha?"Y":"N") << ", version: " << 0+versionNumber << endl;

		if (readBits(1)) {
			cout << (int) readBits(2) << endl;
		}
		
		cout << "Not finished" << endl;
		return 1;
	}

	bool WEBPImage::readBit()
	{
		bool res = bitBuffer & (1 << (bitBufferPos++));
		if(bitBufferPos >= 8)
			refreshBitBuffer();
		return res?1:0;
	}

	uint32_t WEBPImage::readBits(size_t count)
	{
		uint32_t out = 0;
		for(int i = 0; i < count; i++)
		{
			out |= readBit() << i;
		}
		return out;
	}

	void WEBPImage::readFourCC(char* dest)
	{
		for(int i = 0; i < 4; i++)
		{
			dest[i] = readBits(8);
		}
	}

	void WEBPImage::refreshBitBuffer()
	{
		bitBuffer = reader->readByte();
		bitBufferPos = 0;
	}
}