gosu 0.14.4 → 0.15.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/COPYING +1 -1
- data/Gosu/Buttons.hpp +1 -0
- data/Gosu/Channel.h +25 -0
- data/Gosu/Color.h +38 -0
- data/Gosu/Font.h +36 -0
- data/Gosu/Gosu.h +79 -0
- data/Gosu/Image.h +54 -0
- data/Gosu/Sample.h +19 -0
- data/Gosu/Song.h +24 -0
- data/Gosu/TextInput.h +30 -0
- data/Gosu/Version.hpp +2 -2
- data/Gosu/Window.h +61 -0
- data/Gosu/Window.hpp +3 -2
- data/README.md +1 -1
- data/ext/gosu/extconf.rb +3 -0
- data/lib/gosu/compat.rb +12 -7
- data/lib/gosu/patches.rb +8 -2
- data/lib/gosu/swig_patches.rb +20 -9
- data/rdoc/gosu.rb +28 -7
- data/src/ChannelWrapper.cpp +50 -0
- data/src/ColorWrapper.cpp +126 -0
- data/src/Constants.cpp +287 -0
- data/src/Font.cpp +1 -0
- data/src/FontWrapper.cpp +74 -0
- data/src/GosuWrapper.cpp +232 -0
- data/src/Graphics.cpp +4 -1
- data/src/GraphicsImpl.hpp +0 -1
- data/src/ImageWrapper.cpp +168 -0
- data/src/LargeImageData.cpp +1 -0
- data/src/MarkupParser.cpp +11 -3
- data/src/RubyGosu.cxx +186 -121
- data/src/RubyGosu.h +2 -2
- data/src/SampleWrapper.cpp +30 -0
- data/src/SongWrapper.cpp +52 -0
- data/src/TexChunk.cpp +29 -19
- data/src/Text.cpp +2 -0
- data/src/TextBuilder.cpp +3 -3
- data/src/TextInputWrapper.cpp +101 -0
- data/src/TrueTypeFont.cpp +1 -0
- data/src/Window.cpp +62 -28
- data/src/WindowUIKit.cpp +8 -4
- data/src/WindowWrapper.cpp +289 -0
- data/src/stb_image.h +153 -56
- data/src/stb_image_write.h +111 -60
- data/src/stb_truetype.h +74 -39
- data/src/stb_vorbis.c +55 -15
- data/src/utf8proc.c +47 -29
- data/src/utf8proc.h +46 -24
- data/src/utf8proc_data.h +10043 -9609
- metadata +23 -4
data/src/WindowUIKit.cpp
CHANGED
@@ -13,12 +13,12 @@ struct Gosu::Window::Impl
|
|
13
13
|
unique_ptr<Graphics> graphics;
|
14
14
|
unique_ptr<Input> input;
|
15
15
|
|
16
|
-
bool fullscreen;
|
17
16
|
double update_interval;
|
18
17
|
string caption;
|
19
18
|
};
|
20
19
|
|
21
|
-
Gosu::Window::Window(unsigned width, unsigned height, bool fullscreen, double update_interval
|
20
|
+
Gosu::Window::Window(unsigned width, unsigned height, bool fullscreen, double update_interval,
|
21
|
+
bool resizable)
|
22
22
|
: pimpl(new Impl)
|
23
23
|
{
|
24
24
|
pimpl->window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
@@ -43,7 +43,6 @@ Gosu::Window::Window(unsigned width, unsigned height, bool fullscreen, double up
|
|
43
43
|
// Now let the controller know about our Input instance.
|
44
44
|
[pimpl->controller trackTextInput:*pimpl->input];
|
45
45
|
|
46
|
-
pimpl->fullscreen = fullscreen;
|
47
46
|
pimpl->update_interval = update_interval;
|
48
47
|
}
|
49
48
|
|
@@ -63,7 +62,12 @@ unsigned Gosu::Window::height() const
|
|
63
62
|
|
64
63
|
bool Gosu::Window::fullscreen() const
|
65
64
|
{
|
66
|
-
return
|
65
|
+
return true;
|
66
|
+
}
|
67
|
+
|
68
|
+
bool Gosu::Window::resizable() const
|
69
|
+
{
|
70
|
+
return false;
|
67
71
|
}
|
68
72
|
|
69
73
|
void Gosu::Window::resize(unsigned width, unsigned height, bool fullscreen)
|
@@ -0,0 +1,289 @@
|
|
1
|
+
#include <Gosu/Gosu.hpp>
|
2
|
+
|
3
|
+
namespace Gosu
|
4
|
+
{
|
5
|
+
class WindowForWrapper : public Gosu::Window
|
6
|
+
{
|
7
|
+
public:
|
8
|
+
WindowForWrapper(int width, int height, bool fullscreen, double update_interval, bool resizable);
|
9
|
+
void update() override;
|
10
|
+
void draw() override;
|
11
|
+
void default_button_down(unsigned btn); // Enables fullscreen toggle
|
12
|
+
void button_down(Gosu::Button btn) override;
|
13
|
+
void button_up(Gosu::Button btn) override;
|
14
|
+
void drop(const std::string &filename) override;
|
15
|
+
bool needs_redraw() const override;
|
16
|
+
bool needs_cursor() const override;
|
17
|
+
void close() override;
|
18
|
+
|
19
|
+
void close_immediately();
|
20
|
+
|
21
|
+
std::function<void ()> update_callback;
|
22
|
+
std::function<void ()> draw_callback;
|
23
|
+
std::function<void (unsigned btn)> button_down_callback;
|
24
|
+
std::function<void (unsigned btn)> button_up_callback;
|
25
|
+
std::function<void (const char *filename)> drop_callback;
|
26
|
+
std::function<bool ()> needs_redraw_callback;
|
27
|
+
std::function<bool ()> needs_cursor_callback;
|
28
|
+
std::function<void ()> close_callback;
|
29
|
+
};
|
30
|
+
} // namespace Gosu
|
31
|
+
|
32
|
+
Gosu::WindowForWrapper::WindowForWrapper(int width, int height, bool fullscreen,
|
33
|
+
double update_interval, bool resizable)
|
34
|
+
: Gosu::Window(width, height, fullscreen, update_interval, resizable)
|
35
|
+
{
|
36
|
+
}
|
37
|
+
|
38
|
+
void Gosu::WindowForWrapper::update()
|
39
|
+
{
|
40
|
+
if (update_callback != nullptr) {
|
41
|
+
update_callback();
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
void Gosu::WindowForWrapper::draw()
|
46
|
+
{
|
47
|
+
if (draw_callback != nullptr) {
|
48
|
+
draw_callback();
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
void Gosu::WindowForWrapper::default_button_down(unsigned btn)
|
53
|
+
{
|
54
|
+
Gosu::Window::button_down(Gosu::ButtonName(btn));
|
55
|
+
}
|
56
|
+
|
57
|
+
void Gosu::WindowForWrapper::button_down(Gosu::Button btn)
|
58
|
+
{
|
59
|
+
if (button_down_callback != nullptr) {
|
60
|
+
button_down_callback(btn.id());
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
void Gosu::WindowForWrapper::button_up(Gosu::Button btn)
|
65
|
+
{
|
66
|
+
if (button_up_callback != nullptr) {
|
67
|
+
button_up_callback(btn.id());
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
void Gosu::WindowForWrapper::drop(const std::string &filename)
|
72
|
+
{
|
73
|
+
if (drop_callback != nullptr) {
|
74
|
+
drop_callback(filename.c_str());
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
bool Gosu::WindowForWrapper::needs_redraw() const
|
79
|
+
{
|
80
|
+
if (needs_redraw_callback != nullptr) {
|
81
|
+
return needs_redraw_callback();
|
82
|
+
}
|
83
|
+
else {
|
84
|
+
return true;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
bool Gosu::WindowForWrapper::needs_cursor() const
|
89
|
+
{
|
90
|
+
if (needs_cursor_callback != nullptr) {
|
91
|
+
return needs_cursor_callback();
|
92
|
+
}
|
93
|
+
else {
|
94
|
+
return false;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
void Gosu::WindowForWrapper::close()
|
99
|
+
{
|
100
|
+
if (close_callback != nullptr) {
|
101
|
+
close_callback();
|
102
|
+
}
|
103
|
+
else {
|
104
|
+
Gosu::Window::close();
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
void Gosu::WindowForWrapper::close_immediately()
|
109
|
+
{
|
110
|
+
Gosu::Window::close();
|
111
|
+
}
|
112
|
+
|
113
|
+
extern "C" {
|
114
|
+
#include <Gosu/Window.h>
|
115
|
+
#include <Gosu/TextInput.h>
|
116
|
+
|
117
|
+
// Constructor
|
118
|
+
Gosu_Window *Gosu_Window_create(int width, int height, bool fullscreen, double update_interval, bool resizable)
|
119
|
+
{
|
120
|
+
return reinterpret_cast<Gosu_Window *>(new Gosu::WindowForWrapper(width, height, fullscreen, update_interval, resizable));
|
121
|
+
};
|
122
|
+
|
123
|
+
// Callbacks
|
124
|
+
void Gosu_Window_set_draw(Gosu_Window *window, void function(void *data), void *data)
|
125
|
+
{
|
126
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->draw_callback = [=]() { function(data); };
|
127
|
+
}
|
128
|
+
|
129
|
+
void Gosu_Window_set_update(Gosu_Window *window, void function(void *data), void *data)
|
130
|
+
{
|
131
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->update_callback = [=]() { function(data); };
|
132
|
+
}
|
133
|
+
|
134
|
+
void Gosu_Window_set_button_down(Gosu_Window *window, void function(void *data, unsigned btn), void *data)
|
135
|
+
{
|
136
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->button_down_callback = [=](unsigned btn) { function(data, btn); };
|
137
|
+
}
|
138
|
+
|
139
|
+
void Gosu_Window_default_button_down(Gosu_Window *window, unsigned btn)
|
140
|
+
{
|
141
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->default_button_down(btn);
|
142
|
+
}
|
143
|
+
|
144
|
+
void Gosu_Window_set_button_up(Gosu_Window *window, void function(void *data, unsigned btn), void *data)
|
145
|
+
{
|
146
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->button_up_callback = [=](unsigned btn) { function(data, btn); };
|
147
|
+
}
|
148
|
+
|
149
|
+
void Gosu_Window_set_drop(Gosu_Window *window, void function(void *data, const char *filename), void *data)
|
150
|
+
{
|
151
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->drop_callback = [=](const char *filename) { function(data, filename); };
|
152
|
+
}
|
153
|
+
|
154
|
+
void Gosu_Window_set_needs_redraw(Gosu_Window *window, bool function(void *data), void *data)
|
155
|
+
{
|
156
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->needs_redraw_callback = [=]() -> bool { return function(data); };
|
157
|
+
}
|
158
|
+
|
159
|
+
void Gosu_Window_set_needs_cursor(Gosu_Window *window, bool function(void *data), void *data)
|
160
|
+
{
|
161
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->needs_cursor_callback = [=]() -> bool { return function(data); };
|
162
|
+
}
|
163
|
+
|
164
|
+
void Gosu_Window_set_close(Gosu_Window *window, void function(void *data), void *data)
|
165
|
+
{
|
166
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->close_callback = [=]() { function(data); };
|
167
|
+
}
|
168
|
+
|
169
|
+
Gosu_TextInput *Gosu_Window_text_input(Gosu_Window *window)
|
170
|
+
{
|
171
|
+
Gosu::Window *gosu_window = reinterpret_cast<Gosu::WindowForWrapper *>(window);
|
172
|
+
return reinterpret_cast<Gosu_TextInput *>(gosu_window->input().text_input());
|
173
|
+
}
|
174
|
+
|
175
|
+
void Gosu_Window_set_text_input(Gosu_Window *window, Gosu_TextInput *text_input)
|
176
|
+
{
|
177
|
+
Gosu::Window *gosu_window = reinterpret_cast<Gosu::WindowForWrapper *>(window);
|
178
|
+
gosu_window->input().set_text_input(reinterpret_cast<Gosu::TextInput *>(text_input));
|
179
|
+
}
|
180
|
+
|
181
|
+
void Gosu_Window_show(Gosu_Window *window)
|
182
|
+
{
|
183
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->show();
|
184
|
+
}
|
185
|
+
|
186
|
+
bool Gosu_Window_tick(Gosu_Window *window)
|
187
|
+
{
|
188
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->tick();
|
189
|
+
}
|
190
|
+
|
191
|
+
void Gosu_Window_close_immediately(Gosu_Window *window)
|
192
|
+
{
|
193
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->close_immediately();
|
194
|
+
}
|
195
|
+
|
196
|
+
bool Gosu_Window_is_fullscreen(Gosu_Window *window)
|
197
|
+
{
|
198
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->fullscreen();
|
199
|
+
}
|
200
|
+
|
201
|
+
bool Gosu_Window_is_resizable(Gosu_Window *window)
|
202
|
+
{
|
203
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->resizable();
|
204
|
+
}
|
205
|
+
|
206
|
+
const char *Gosu_Window_caption(Gosu_Window *window)
|
207
|
+
{
|
208
|
+
static thread_local std::string caption;
|
209
|
+
caption = reinterpret_cast<Gosu::WindowForWrapper *>(window)->caption();
|
210
|
+
|
211
|
+
return caption.c_str();
|
212
|
+
}
|
213
|
+
|
214
|
+
void Gosu_Window_set_caption(Gosu_Window *window, const char *caption)
|
215
|
+
{
|
216
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->set_caption(caption);
|
217
|
+
}
|
218
|
+
|
219
|
+
double Gosu_Window_update_interval(Gosu_Window *window)
|
220
|
+
{
|
221
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->update_interval();
|
222
|
+
}
|
223
|
+
|
224
|
+
void Gosu_Window_set_update_interval(Gosu_Window *window, double update_interval)
|
225
|
+
{
|
226
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->set_update_interval(update_interval);
|
227
|
+
}
|
228
|
+
|
229
|
+
void Gosu_Window_set_mouse_x(Gosu_Window *window, double x)
|
230
|
+
{
|
231
|
+
Gosu::Window *gosu_window = reinterpret_cast<Gosu::WindowForWrapper *>(window);
|
232
|
+
gosu_window->input().set_mouse_position(x, gosu_window->input().mouse_x());
|
233
|
+
}
|
234
|
+
|
235
|
+
void Gosu_Window_set_mouse_y(Gosu_Window *window, double y)
|
236
|
+
{
|
237
|
+
Gosu::Window *gosu_window = reinterpret_cast<Gosu::WindowForWrapper *>(window);
|
238
|
+
gosu_window->input().set_mouse_position(gosu_window->input().mouse_x(), y);
|
239
|
+
}
|
240
|
+
|
241
|
+
double Gosu_Window_mouse_x(Gosu_Window *window)
|
242
|
+
{
|
243
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->input().mouse_x();
|
244
|
+
}
|
245
|
+
|
246
|
+
double Gosu_Window_mouse_y(Gosu_Window *window)
|
247
|
+
{
|
248
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->input().mouse_y();
|
249
|
+
}
|
250
|
+
|
251
|
+
int Gosu_Window_width(Gosu_Window *window)
|
252
|
+
{
|
253
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->width();
|
254
|
+
}
|
255
|
+
|
256
|
+
void Gosu_Window_set_width(Gosu_Window *window, int width)
|
257
|
+
{
|
258
|
+
Gosu::Window *gosu_window = reinterpret_cast<Gosu::WindowForWrapper *>(window);
|
259
|
+
gosu_window->resize(width, gosu_window->height(), gosu_window->fullscreen());
|
260
|
+
}
|
261
|
+
|
262
|
+
int Gosu_Window_height(Gosu_Window *window)
|
263
|
+
{
|
264
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->height();
|
265
|
+
}
|
266
|
+
|
267
|
+
void Gosu_Window_set_height(Gosu_Window *window, int height)
|
268
|
+
{
|
269
|
+
Gosu::Window *gosu_window = reinterpret_cast<Gosu::WindowForWrapper *>(window);
|
270
|
+
gosu_window->resize(gosu_window->width(), height, gosu_window->fullscreen());
|
271
|
+
}
|
272
|
+
|
273
|
+
void Gosu_Window_resize(Gosu_Window *window, int width, int height, bool fullscreen)
|
274
|
+
{
|
275
|
+
reinterpret_cast<Gosu::WindowForWrapper *>(window)->resize(width, height, fullscreen);
|
276
|
+
}
|
277
|
+
|
278
|
+
int Gosu_Window_is_button_down(Gosu_Window *window, unsigned btn)
|
279
|
+
{
|
280
|
+
return reinterpret_cast<Gosu::WindowForWrapper *>(window)->input().down(Gosu::Button(btn));
|
281
|
+
}
|
282
|
+
|
283
|
+
// Destructor
|
284
|
+
void Gosu_Window_destroy(Gosu_Window *window)
|
285
|
+
{
|
286
|
+
delete (reinterpret_cast<Gosu::WindowForWrapper *>(window));
|
287
|
+
}
|
288
|
+
|
289
|
+
}
|
data/src/stb_image.h
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* stb_image - v2.
|
1
|
+
/* stb_image - v2.23 - public domain image loader - http://nothings.org/stb
|
2
2
|
no warranty implied; use at your own risk
|
3
3
|
|
4
4
|
Do this:
|
@@ -48,6 +48,10 @@ LICENSE
|
|
48
48
|
|
49
49
|
RECENT REVISION HISTORY:
|
50
50
|
|
51
|
+
2.23 (2019-08-11) fix clang static analysis warning
|
52
|
+
2.22 (2019-03-04) gif fixes, fix warnings
|
53
|
+
2.21 (2019-02-25) fix typo in comment
|
54
|
+
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
|
51
55
|
2.19 (2018-02-11) fix warning
|
52
56
|
2.18 (2018-01-30) fix warnings
|
53
57
|
2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
|
@@ -84,6 +88,7 @@ RECENT REVISION HISTORY:
|
|
84
88
|
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
|
85
89
|
Arseny Kapoulkine
|
86
90
|
John-Mark Allen
|
91
|
+
Carmelo J Fdez-Aguera
|
87
92
|
|
88
93
|
Bug & warning fixes
|
89
94
|
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
@@ -99,7 +104,7 @@ RECENT REVISION HISTORY:
|
|
99
104
|
Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
|
100
105
|
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
|
101
106
|
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
|
102
|
-
Christian Floisand Kevin Schmidt
|
107
|
+
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
|
103
108
|
Blazej Dariusz Roszkowski github:Michaelangel007
|
104
109
|
*/
|
105
110
|
|
@@ -161,6 +166,16 @@ RECENT REVISION HISTORY:
|
|
161
166
|
//
|
162
167
|
// ===========================================================================
|
163
168
|
//
|
169
|
+
// UNICODE:
|
170
|
+
//
|
171
|
+
// If compiling for Windows and you wish to use Unicode filenames, compile
|
172
|
+
// with
|
173
|
+
// #define STBI_WINDOWS_UTF8
|
174
|
+
// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert
|
175
|
+
// Windows wchar_t filenames to utf8.
|
176
|
+
//
|
177
|
+
// ===========================================================================
|
178
|
+
//
|
164
179
|
// Philosophy
|
165
180
|
//
|
166
181
|
// stb libraries are designed with the following priorities:
|
@@ -171,12 +186,12 @@ RECENT REVISION HISTORY:
|
|
171
186
|
//
|
172
187
|
// Sometimes I let "good performance" creep up in priority over "easy to maintain",
|
173
188
|
// and for best performance I may provide less-easy-to-use APIs that give higher
|
174
|
-
// performance, in addition to the easy
|
189
|
+
// performance, in addition to the easy-to-use ones. Nevertheless, it's important
|
175
190
|
// to keep in mind that from the standpoint of you, a client of this library,
|
176
191
|
// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
|
177
192
|
//
|
178
193
|
// Some secondary priorities arise directly from the first two, some of which
|
179
|
-
//
|
194
|
+
// provide more explicit reasons why performance can't be emphasized.
|
180
195
|
//
|
181
196
|
// - Portable ("ease of use")
|
182
197
|
// - Small source code footprint ("easy to maintain")
|
@@ -219,11 +234,10 @@ RECENT REVISION HISTORY:
|
|
219
234
|
//
|
220
235
|
// HDR image support (disable by defining STBI_NO_HDR)
|
221
236
|
//
|
222
|
-
// stb_image
|
223
|
-
//
|
224
|
-
//
|
225
|
-
//
|
226
|
-
// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
237
|
+
// stb_image supports loading HDR images in general, and currently the Radiance
|
238
|
+
// .HDR file format specifically. You can still load any file through the existing
|
239
|
+
// interface; if you attempt to load an HDR file, it will be automatically remapped
|
240
|
+
// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
227
241
|
// both of these constants can be reconfigured through this interface:
|
228
242
|
//
|
229
243
|
// stbi_hdr_to_ldr_gamma(2.2f);
|
@@ -257,7 +271,7 @@ RECENT REVISION HISTORY:
|
|
257
271
|
//
|
258
272
|
// By default we convert iphone-formatted PNGs back to RGB, even though
|
259
273
|
// they are internally encoded differently. You can disable this conversion
|
260
|
-
// by
|
274
|
+
// by calling stbi_convert_iphone_png_to_rgb(0), in which case
|
261
275
|
// you will always just get the native iphone "format" through (which
|
262
276
|
// is BGR stored in RGB).
|
263
277
|
//
|
@@ -319,6 +333,7 @@ enum
|
|
319
333
|
STBI_rgb_alpha = 4
|
320
334
|
};
|
321
335
|
|
336
|
+
#include <stdlib.h>
|
322
337
|
typedef unsigned char stbi_uc;
|
323
338
|
typedef unsigned short stbi_us;
|
324
339
|
|
@@ -326,11 +341,13 @@ typedef unsigned short stbi_us;
|
|
326
341
|
extern "C" {
|
327
342
|
#endif
|
328
343
|
|
344
|
+
#ifndef STBIDEF
|
329
345
|
#ifdef STB_IMAGE_STATIC
|
330
346
|
#define STBIDEF static
|
331
347
|
#else
|
332
348
|
#define STBIDEF extern
|
333
349
|
#endif
|
350
|
+
#endif
|
334
351
|
|
335
352
|
//////////////////////////////////////////////////////////////////////////////
|
336
353
|
//
|
@@ -355,10 +372,6 @@ typedef struct
|
|
355
372
|
|
356
373
|
STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels);
|
357
374
|
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
|
358
|
-
#ifndef STBI_NO_GIF
|
359
|
-
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
|
360
|
-
#endif
|
361
|
-
|
362
375
|
|
363
376
|
#ifndef STBI_NO_STDIO
|
364
377
|
STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
@@ -366,6 +379,14 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in
|
|
366
379
|
// for stbi_load_from_file, file pointer is left pointing immediately after image
|
367
380
|
#endif
|
368
381
|
|
382
|
+
#ifndef STBI_NO_GIF
|
383
|
+
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
|
384
|
+
#endif
|
385
|
+
|
386
|
+
#ifdef STBI_WINDOWS_UTF8
|
387
|
+
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
|
388
|
+
#endif
|
389
|
+
|
369
390
|
////////////////////////////////////
|
370
391
|
//
|
371
392
|
// 16-bits-per-channel interface
|
@@ -525,6 +546,12 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
|
|
525
546
|
#define STBI_ASSERT(x) assert(x)
|
526
547
|
#endif
|
527
548
|
|
549
|
+
#ifdef __cplusplus
|
550
|
+
#define STBI_EXTERN extern "C"
|
551
|
+
#else
|
552
|
+
#define STBI_EXTERN extern
|
553
|
+
#endif
|
554
|
+
|
528
555
|
|
529
556
|
#ifndef _MSC_VER
|
530
557
|
#ifdef __cplusplus
|
@@ -649,14 +676,18 @@ static int stbi__cpuid3(void)
|
|
649
676
|
|
650
677
|
#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
|
651
678
|
|
679
|
+
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
|
652
680
|
static int stbi__sse2_available(void)
|
653
681
|
{
|
654
682
|
int info3 = stbi__cpuid3();
|
655
683
|
return ((info3 >> 26) & 1) != 0;
|
656
684
|
}
|
685
|
+
#endif
|
686
|
+
|
657
687
|
#else // assume GCC-style if not VC++
|
658
688
|
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
659
689
|
|
690
|
+
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
|
660
691
|
static int stbi__sse2_available(void)
|
661
692
|
{
|
662
693
|
// If we're even attempting to compile this on GCC/Clang, that means
|
@@ -664,6 +695,8 @@ static int stbi__sse2_available(void)
|
|
664
695
|
// instructions at will, and so are we.
|
665
696
|
return 1;
|
666
697
|
}
|
698
|
+
#endif
|
699
|
+
|
667
700
|
#endif
|
668
701
|
#endif
|
669
702
|
|
@@ -1070,6 +1103,7 @@ static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
|
|
1070
1103
|
}
|
1071
1104
|
}
|
1072
1105
|
|
1106
|
+
#ifndef STBI_NO_GIF
|
1073
1107
|
static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
|
1074
1108
|
{
|
1075
1109
|
int slice;
|
@@ -1081,6 +1115,7 @@ static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int byt
|
|
1081
1115
|
bytes += slice_size;
|
1082
1116
|
}
|
1083
1117
|
}
|
1118
|
+
#endif
|
1084
1119
|
|
1085
1120
|
static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
1086
1121
|
{
|
@@ -1131,7 +1166,7 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
|
|
1131
1166
|
return (stbi__uint16 *) result;
|
1132
1167
|
}
|
1133
1168
|
|
1134
|
-
#if !defined(STBI_NO_HDR)
|
1169
|
+
#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR)
|
1135
1170
|
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
|
1136
1171
|
{
|
1137
1172
|
if (stbi__vertically_flip_on_load && result != NULL) {
|
@@ -1143,10 +1178,38 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
|
|
1143
1178
|
|
1144
1179
|
#ifndef STBI_NO_STDIO
|
1145
1180
|
|
1181
|
+
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
1182
|
+
STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
|
1183
|
+
STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
|
1184
|
+
#endif
|
1185
|
+
|
1186
|
+
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
1187
|
+
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
|
1188
|
+
{
|
1189
|
+
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
|
1190
|
+
}
|
1191
|
+
#endif
|
1192
|
+
|
1146
1193
|
static FILE *stbi__fopen(char const *filename, char const *mode)
|
1147
1194
|
{
|
1148
1195
|
FILE *f;
|
1149
|
-
#if defined(_MSC_VER) &&
|
1196
|
+
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
1197
|
+
wchar_t wMode[64];
|
1198
|
+
wchar_t wFilename[1024];
|
1199
|
+
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
|
1200
|
+
return 0;
|
1201
|
+
|
1202
|
+
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
|
1203
|
+
return 0;
|
1204
|
+
|
1205
|
+
#if _MSC_VER >= 1400
|
1206
|
+
if (0 != _wfopen_s(&f, wFilename, wMode))
|
1207
|
+
f = 0;
|
1208
|
+
#else
|
1209
|
+
f = _wfopen(wFilename, wMode);
|
1210
|
+
#endif
|
1211
|
+
|
1212
|
+
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
1150
1213
|
if (0 != fopen_s(&f, filename, mode))
|
1151
1214
|
f=0;
|
1152
1215
|
#else
|
@@ -1539,18 +1602,18 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|
1539
1602
|
// convert source image with img_n components to one with req_comp components;
|
1540
1603
|
// avoid switch per pixel, so use switch per scanline and massive macros
|
1541
1604
|
switch (STBI__COMBO(img_n, req_comp)) {
|
1542
|
-
STBI__CASE(1,2) { dest[0]=src[0]
|
1605
|
+
STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break;
|
1543
1606
|
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1544
|
-
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]
|
1607
|
+
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break;
|
1545
1608
|
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
1546
1609
|
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1547
|
-
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]
|
1548
|
-
STBI__CASE(3,4) { dest[0]=src[0]
|
1610
|
+
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
|
1611
|
+
STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break;
|
1549
1612
|
STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
1550
|
-
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2])
|
1613
|
+
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break;
|
1551
1614
|
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
1552
|
-
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2])
|
1553
|
-
STBI__CASE(4,3) { dest[0]=src[0]
|
1615
|
+
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
1616
|
+
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
1554
1617
|
default: STBI_ASSERT(0);
|
1555
1618
|
}
|
1556
1619
|
#undef STBI__CASE
|
@@ -1588,18 +1651,18 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
|
|
1588
1651
|
// convert source image with img_n components to one with req_comp components;
|
1589
1652
|
// avoid switch per pixel, so use switch per scanline and massive macros
|
1590
1653
|
switch (STBI__COMBO(img_n, req_comp)) {
|
1591
|
-
STBI__CASE(1,2) { dest[0]=src[0]
|
1654
|
+
STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break;
|
1592
1655
|
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1593
|
-
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]
|
1656
|
+
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break;
|
1594
1657
|
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
1595
1658
|
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1596
|
-
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]
|
1597
|
-
STBI__CASE(3,4) { dest[0]=src[0]
|
1659
|
+
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
|
1660
|
+
STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break;
|
1598
1661
|
STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
1599
|
-
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2])
|
1662
|
+
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break;
|
1600
1663
|
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
1601
|
-
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2])
|
1602
|
-
STBI__CASE(4,3) { dest[0]=src[0]
|
1664
|
+
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
1665
|
+
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
1603
1666
|
default: STBI_ASSERT(0);
|
1604
1667
|
}
|
1605
1668
|
#undef STBI__CASE
|
@@ -1623,7 +1686,11 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
|
1623
1686
|
for (k=0; k < n; ++k) {
|
1624
1687
|
output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
|
1625
1688
|
}
|
1626
|
-
|
1689
|
+
}
|
1690
|
+
if (n < comp) {
|
1691
|
+
for (i=0; i < x*y; ++i) {
|
1692
|
+
output[i*comp + n] = data[i*comp + n]/255.0f;
|
1693
|
+
}
|
1627
1694
|
}
|
1628
1695
|
STBI_FREE(data);
|
1629
1696
|
return output;
|
@@ -3596,7 +3663,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3596
3663
|
int k;
|
3597
3664
|
unsigned int i,j;
|
3598
3665
|
stbi_uc *output;
|
3599
|
-
stbi_uc *coutput[4];
|
3666
|
+
stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL };
|
3600
3667
|
|
3601
3668
|
stbi__resample res_comp[4];
|
3602
3669
|
|
@@ -3717,7 +3784,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3717
3784
|
if (n == 1)
|
3718
3785
|
for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
|
3719
3786
|
else
|
3720
|
-
for (i=0; i < z->s->img_x; ++i) *out++ = y[i]
|
3787
|
+
for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; }
|
3721
3788
|
}
|
3722
3789
|
}
|
3723
3790
|
}
|
@@ -4731,7 +4798,7 @@ static void stbi__de_iphone(stbi__png *z)
|
|
4731
4798
|
static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
4732
4799
|
{
|
4733
4800
|
stbi_uc palette[1024], pal_img_n=0;
|
4734
|
-
stbi_uc has_trans=0, tc[3];
|
4801
|
+
stbi_uc has_trans=0, tc[3]={0};
|
4735
4802
|
stbi__uint16 tc16[3];
|
4736
4803
|
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
|
4737
4804
|
int first=1,k,interlace=0, color=0, is_iphone=0;
|
@@ -5009,11 +5076,11 @@ static int stbi__high_bit(unsigned int z)
|
|
5009
5076
|
{
|
5010
5077
|
int n=0;
|
5011
5078
|
if (z == 0) return -1;
|
5012
|
-
if (z >= 0x10000) n += 16
|
5013
|
-
if (z >= 0x00100) n += 8
|
5014
|
-
if (z >= 0x00010) n += 4
|
5015
|
-
if (z >= 0x00004) n += 2
|
5016
|
-
if (z >= 0x00002) n += 1
|
5079
|
+
if (z >= 0x10000) { n += 16; z >>= 16; }
|
5080
|
+
if (z >= 0x00100) { n += 8; z >>= 8; }
|
5081
|
+
if (z >= 0x00010) { n += 4; z >>= 4; }
|
5082
|
+
if (z >= 0x00004) { n += 2; z >>= 2; }
|
5083
|
+
if (z >= 0x00002) { n += 1;/* >>= 1;*/ }
|
5017
5084
|
return n;
|
5018
5085
|
}
|
5019
5086
|
|
@@ -5030,7 +5097,7 @@ static int stbi__bitcount(unsigned int a)
|
|
5030
5097
|
// extract an arbitrarily-aligned N-bit value (N=bits)
|
5031
5098
|
// from v, and then make it 8-bits long and fractionally
|
5032
5099
|
// extend it to full full range.
|
5033
|
-
static int stbi__shiftsigned(int v, int shift, int bits)
|
5100
|
+
static int stbi__shiftsigned(unsigned int v, int shift, int bits)
|
5034
5101
|
{
|
5035
5102
|
static unsigned int mul_table[9] = {
|
5036
5103
|
0,
|
@@ -5171,7 +5238,10 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|
5171
5238
|
psize = (info.offset - 14 - info.hsz) >> 2;
|
5172
5239
|
}
|
5173
5240
|
|
5174
|
-
|
5241
|
+
if (info.bpp == 24 && ma == 0xff000000)
|
5242
|
+
s->img_n = 3;
|
5243
|
+
else
|
5244
|
+
s->img_n = ma ? 4 : 3;
|
5175
5245
|
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
|
5176
5246
|
target = req_comp;
|
5177
5247
|
else
|
@@ -5207,6 +5277,8 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|
5207
5277
|
out[z++] = pal[color][0];
|
5208
5278
|
out[z++] = pal[color][1];
|
5209
5279
|
out[z++] = pal[color][2];
|
5280
|
+
if (target == 4) out[z++] = 255;
|
5281
|
+
if (i+1 == (int) s->img_x) break;
|
5210
5282
|
if((--bit_offset) < 0) {
|
5211
5283
|
bit_offset = 7;
|
5212
5284
|
v = stbi__get8(s);
|
@@ -5299,7 +5371,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|
5299
5371
|
stbi_uc *p1 = out + j *s->img_x*target;
|
5300
5372
|
stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
|
5301
5373
|
for (i=0; i < (int) s->img_x*target; ++i) {
|
5302
|
-
t = p1[i]
|
5374
|
+
t = p1[i]; p1[i] = p2[i]; p2[i] = t;
|
5303
5375
|
}
|
5304
5376
|
}
|
5305
5377
|
}
|
@@ -5479,6 +5551,8 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|
5479
5551
|
int RLE_repeating = 0;
|
5480
5552
|
int read_next_pixel = 1;
|
5481
5553
|
STBI_NOTUSED(ri);
|
5554
|
+
STBI_NOTUSED(tga_x_origin); // @TODO
|
5555
|
+
STBI_NOTUSED(tga_y_origin); // @TODO
|
5482
5556
|
|
5483
5557
|
// do a tiny bit of precessing
|
5484
5558
|
if ( tga_image_type >= 8 )
|
@@ -5642,6 +5716,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|
5642
5716
|
// Microsoft's C compilers happy... [8^(
|
5643
5717
|
tga_palette_start = tga_palette_len = tga_palette_bits =
|
5644
5718
|
tga_x_origin = tga_y_origin = 0;
|
5719
|
+
STBI_NOTUSED(tga_palette_start);
|
5645
5720
|
// OK, done
|
5646
5721
|
return tga_data;
|
5647
5722
|
}
|
@@ -5789,7 +5864,7 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|
5789
5864
|
// Else if n is 128, noop.
|
5790
5865
|
// Endloop
|
5791
5866
|
|
5792
|
-
// The RLE-compressed data is
|
5867
|
+
// The RLE-compressed data is preceded by a 2-byte data count for each row in the data,
|
5793
5868
|
// which we're going to just skip.
|
5794
5869
|
stbi__skip(s, h * channelCount * 2 );
|
5795
5870
|
|
@@ -6342,22 +6417,27 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|
6342
6417
|
int first_frame;
|
6343
6418
|
int pi;
|
6344
6419
|
int pcount;
|
6420
|
+
STBI_NOTUSED(req_comp);
|
6345
6421
|
|
6346
6422
|
// on first frame, any non-written pixels get the background colour (non-transparent)
|
6347
6423
|
first_frame = 0;
|
6348
6424
|
if (g->out == 0) {
|
6349
|
-
if (!stbi__gif_header(s, g, comp,0))
|
6350
|
-
|
6351
|
-
|
6352
|
-
|
6353
|
-
|
6354
|
-
|
6355
|
-
|
6425
|
+
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
|
6426
|
+
if (!stbi__mad3sizes_valid(4, g->w, g->h, 0))
|
6427
|
+
return stbi__errpuc("too large", "GIF image is too large");
|
6428
|
+
pcount = g->w * g->h;
|
6429
|
+
g->out = (stbi_uc *) stbi__malloc(4 * pcount);
|
6430
|
+
g->background = (stbi_uc *) stbi__malloc(4 * pcount);
|
6431
|
+
g->history = (stbi_uc *) stbi__malloc(pcount);
|
6432
|
+
if (!g->out || !g->background || !g->history)
|
6433
|
+
return stbi__errpuc("outofmem", "Out of memory");
|
6434
|
+
|
6435
|
+
// image is treated as "transparent" at the start - ie, nothing overwrites the current background;
|
6356
6436
|
// background colour is only used for pixels that are not rendered first frame, after that "background"
|
6357
|
-
// color refers to
|
6358
|
-
memset(
|
6359
|
-
memset(
|
6360
|
-
memset(
|
6437
|
+
// color refers to the color that was there the previous frame.
|
6438
|
+
memset(g->out, 0x00, 4 * pcount);
|
6439
|
+
memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent)
|
6440
|
+
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
|
6361
6441
|
first_frame = 1;
|
6362
6442
|
} else {
|
6363
6443
|
// second frame - how do we dispoase of the previous one?
|
@@ -6418,6 +6498,13 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|
6418
6498
|
g->cur_x = g->start_x;
|
6419
6499
|
g->cur_y = g->start_y;
|
6420
6500
|
|
6501
|
+
// if the width of the specified rectangle is 0, that means
|
6502
|
+
// we may not see *any* pixels or the image is malformed;
|
6503
|
+
// to make sure this is caught, move the current y down to
|
6504
|
+
// max_y (which is what out_gif_code checks).
|
6505
|
+
if (w == 0)
|
6506
|
+
g->cur_y = g->max_y;
|
6507
|
+
|
6421
6508
|
g->lflags = stbi__get8(s);
|
6422
6509
|
|
6423
6510
|
if (g->lflags & 0x40) {
|
@@ -6437,7 +6524,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|
6437
6524
|
return stbi__errpuc("missing color table", "Corrupt GIF");
|
6438
6525
|
|
6439
6526
|
o = stbi__process_gif_raster(s, g);
|
6440
|
-
if (o
|
6527
|
+
if (!o) return NULL;
|
6441
6528
|
|
6442
6529
|
// if this was the first frame,
|
6443
6530
|
pcount = g->w * g->h;
|
@@ -6565,6 +6652,7 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|
6565
6652
|
stbi_uc *u = 0;
|
6566
6653
|
stbi__gif g;
|
6567
6654
|
memset(&g, 0, sizeof(g));
|
6655
|
+
STBI_NOTUSED(ri);
|
6568
6656
|
|
6569
6657
|
u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
|
6570
6658
|
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
|
@@ -6576,6 +6664,9 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|
6576
6664
|
// can be done for multiple frames.
|
6577
6665
|
if (req_comp && req_comp != 4)
|
6578
6666
|
u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
|
6667
|
+
} else if (g.out) {
|
6668
|
+
// if there was an error and we allocated an image buffer, free it!
|
6669
|
+
STBI_FREE(g.out);
|
6579
6670
|
}
|
6580
6671
|
|
6581
6672
|
// free buffers needed for multiple frame loading;
|
@@ -6852,7 +6943,12 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6852
6943
|
return 0;
|
6853
6944
|
if (x) *x = s->img_x;
|
6854
6945
|
if (y) *y = s->img_y;
|
6855
|
-
if (comp)
|
6946
|
+
if (comp) {
|
6947
|
+
if (info.bpp == 24 && info.ma == 0xff000000)
|
6948
|
+
*comp = 3;
|
6949
|
+
else
|
6950
|
+
*comp = info.ma ? 4 : 3;
|
6951
|
+
}
|
6856
6952
|
return 1;
|
6857
6953
|
}
|
6858
6954
|
#endif
|
@@ -7238,6 +7334,7 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user
|
|
7238
7334
|
|
7239
7335
|
/*
|
7240
7336
|
revision history:
|
7337
|
+
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
|
7241
7338
|
2.19 (2018-02-11) fix warning
|
7242
7339
|
2.18 (2018-01-30) fix warnings
|
7243
7340
|
2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
|