-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSDLImage.h
80 lines (67 loc) · 2.74 KB
/
SDLImage.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
#pragma once
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
#include "constants.h"
#include "Image.h"
namespace dawn
{
class SDLImage : public Image
{
public:
SDLImage(const std::string &path) : Image(path) {
LoadImage();
}
virtual void path(const std::string &path) {
if (m_path != path) {
setChanged();
m_path = path;
LoadImage();
}
}
virtual BufferPtr buffer() { return m_buffer; }
virtual unsigned int width() { return m_width; }
virtual unsigned int height() { return m_height; }
virtual CONSTANTS::PixelFormat format() { return m_format; }
private:
void LoadImage() {
std::cout << "Loading " << m_path << std::endl;
SDL_Surface *surface = IMG_Load(m_path.c_str());
if (surface) {
const uint8_t *originalRaw = static_cast<uint8_t *>(surface->pixels);
uint8_t *flippedRaw = new uint8_t[surface->pitch * surface->h];
for (unsigned i = 0; i < surface->h; ++i) {
const uint8_t *srcBeg = originalRaw + (surface->pitch *(surface->h - i - 1));
const uint8_t *srcEnd = srcBeg + surface->pitch;
std::copy(srcBeg, srcEnd, flippedRaw + surface->pitch * i);
}
int bpp = surface->format->BytesPerPixel;
if (bpp == 4) {
m_format = (surface->format->Rmask == 0x000000ff) ? CONSTANTS::RGBAFormat : CONSTANTS::BGRAFormat;
} else if (bpp == 3) {
m_format = (surface->format->Rmask == 0x000000ff) ? CONSTANTS::RGBFormat : CONSTANTS::BGRFormat;
}
if (bpp == 4) {
for(unsigned int pos = 0; pos < (surface->h * surface->pitch); pos += 4) {
unsigned char c0 = flippedRaw[pos+0];
unsigned char c1 = flippedRaw[pos+1];
unsigned char c2 = flippedRaw[pos+2];
float a = flippedRaw[pos+3] / 256.0;
flippedRaw[pos+0] = round(c0 * a);
flippedRaw[pos+1] = round(c1 * a);
flippedRaw[pos+2] = round(c2 * a);
}
}
m_width = surface->w;
m_height = surface->h;
m_buffer = BufferPtr(new Buffer(flippedRaw, surface->pitch * surface->h));
SDL_FreeSurface(surface);
delete [] flippedRaw;
}
}
BufferPtr m_buffer;
unsigned int m_width;
unsigned int m_height;
CONSTANTS::PixelFormat m_format;
};
}