-
Notifications
You must be signed in to change notification settings - Fork 0
/
image.h
111 lines (92 loc) · 2.91 KB
/
image.h
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
103
104
105
106
107
108
109
110
111
//
// Created by Ole on 10.09.2017.
//
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#define VIVID_OPENGL
#ifdef VIVID_OPENGL
#define VIVID_IMAGE_FORMAT_RGB 0x1907
#define VIVID_IMAGE_FORMAT_RGBA 0x1908
#else
#define VIVID_IMAGE_FORMAT_RGB 3
#define VIVID_IMAGE_FORMAT_RGBA 4
#endif
namespace vivid { namespace util {
struct Chunk {
unsigned int length;
std::string type;
std::vector<unsigned char> data;
unsigned int crc;
Chunk(unsigned int length, std::string type, std::vector<unsigned char>& data, unsigned int crc)
: length(length), type(std::move(type)), data(data), crc(crc) {}
};
struct PixelRGB {
union {
struct {
unsigned char red, green, blue;
};
struct {
unsigned char r{}, g{}, b{};
};
};
PixelRGB(unsigned char red, unsigned char green, unsigned char blue)
: red(red), green(green), blue(blue) {}
PixelRGB()
: red(0), green(0), blue(0) {}
unsigned int color() const { return ((unsigned int) 0xFF) << 24 | r << 16 | g << 8 | b; }
};
struct PixelRGBA {
union {
struct {
unsigned char red, green, blue, alpha;
};
struct {
unsigned char r{}, g{}, b{}, a{};
};
};
PixelRGBA(unsigned char alpha, unsigned char red, unsigned char green, unsigned char blue)
: alpha(alpha), red(red), green(green), blue(blue) {}
PixelRGBA()
: alpha(0), red(0), green(0), blue(0) {}
PixelRGBA(const PixelRGB& pixelRGB)
: alpha(255), red(pixelRGB.red), green(pixelRGB.green), blue(pixelRGB.blue) {}
unsigned int color() const { return a << 24 | r << 16 | g << 8 | b; }
};
struct ImageFormat {
unsigned int width;
unsigned int height;
unsigned int bitDepth;
unsigned int colorFormat;
unsigned int compressionMethod;
unsigned int filterMethod;
unsigned int interlaceMethod;
ImageFormat()
: width(0), height(0), bitDepth(0), colorFormat(0) {}
};
class Image {
private:
ImageFormat format;
unsigned char* data;
public:
explicit Image(const std::string& path);
~Image();
inline const PixelRGBA getPixel(unsigned int& x, unsigned int& y) {
if (getColorFormat() == VIVID_IMAGE_FORMAT_RGBA)
return ((PixelRGBA*) data)[x + y * format.width];
if (getColorFormat() == VIVID_IMAGE_FORMAT_RGB)
return PixelRGBA(((PixelRGB*) data)[x + y * format.width]);
}
inline const unsigned char* const getPixels() const { return data; }
inline const unsigned int& getWidth() const { return format.width; }
inline const unsigned int& getHeight() const { return format.height; }
inline const unsigned int& getBitDepth() const { return format.bitDepth; }
inline const unsigned int& getColorFormat() const { return format.colorFormat; }
inline const ImageFormat& getFormat() const { return format; }
private:
void loadChunks(std::vector<Chunk>& chunks, const unsigned char* data, unsigned int size);
Chunk loadChunk(const unsigned char* data, unsigned int& offset);
};
}}