gosu 0.14.4 → 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/COPYING +1 -1
  4. data/Gosu/Buttons.hpp +1 -0
  5. data/Gosu/Channel.h +25 -0
  6. data/Gosu/Color.h +38 -0
  7. data/Gosu/Font.h +36 -0
  8. data/Gosu/Gosu.h +79 -0
  9. data/Gosu/Image.h +54 -0
  10. data/Gosu/Sample.h +19 -0
  11. data/Gosu/Song.h +24 -0
  12. data/Gosu/TextInput.h +30 -0
  13. data/Gosu/Version.hpp +2 -2
  14. data/Gosu/Window.h +61 -0
  15. data/Gosu/Window.hpp +3 -2
  16. data/README.md +1 -1
  17. data/ext/gosu/extconf.rb +3 -0
  18. data/lib/gosu/compat.rb +12 -7
  19. data/lib/gosu/patches.rb +8 -2
  20. data/lib/gosu/swig_patches.rb +20 -9
  21. data/rdoc/gosu.rb +28 -7
  22. data/src/ChannelWrapper.cpp +50 -0
  23. data/src/ColorWrapper.cpp +126 -0
  24. data/src/Constants.cpp +287 -0
  25. data/src/Font.cpp +1 -0
  26. data/src/FontWrapper.cpp +74 -0
  27. data/src/GosuWrapper.cpp +232 -0
  28. data/src/Graphics.cpp +4 -1
  29. data/src/GraphicsImpl.hpp +0 -1
  30. data/src/ImageWrapper.cpp +168 -0
  31. data/src/LargeImageData.cpp +1 -0
  32. data/src/MarkupParser.cpp +11 -3
  33. data/src/RubyGosu.cxx +186 -121
  34. data/src/RubyGosu.h +2 -2
  35. data/src/SampleWrapper.cpp +30 -0
  36. data/src/SongWrapper.cpp +52 -0
  37. data/src/TexChunk.cpp +29 -19
  38. data/src/Text.cpp +2 -0
  39. data/src/TextBuilder.cpp +3 -3
  40. data/src/TextInputWrapper.cpp +101 -0
  41. data/src/TrueTypeFont.cpp +1 -0
  42. data/src/Window.cpp +62 -28
  43. data/src/WindowUIKit.cpp +8 -4
  44. data/src/WindowWrapper.cpp +289 -0
  45. data/src/stb_image.h +153 -56
  46. data/src/stb_image_write.h +111 -60
  47. data/src/stb_truetype.h +74 -39
  48. data/src/stb_vorbis.c +55 -15
  49. data/src/utf8proc.c +47 -29
  50. data/src/utf8proc.h +46 -24
  51. data/src/utf8proc_data.h +10043 -9609
  52. metadata +23 -4
@@ -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 pimpl->fullscreen;
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
+ }
@@ -1,4 +1,4 @@
1
- /* stb_image - v2.19 - public domain image loader - http://nothings.org/stb
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 github:darealshinji
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 to use ones. Nevertheless, it's important
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
- // make more explicit reasons why performance can't be emphasized.
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 now supports loading HDR images in general, and currently
223
- // the Radiance .HDR file format, although the support is provided
224
- // generically. You can still load any file through the existing interface;
225
- // if you attempt to load an HDR file, it will be automatically remapped to
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 by calling stbi_convert_iphone_png_to_rgb(0), in which case
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) || !defined(STBI_NO_LINEAR)
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) && _MSC_VER >= 1400
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], dest[1]=255; } break;
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], dest[3]=255; } break;
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], dest[3]=src[1]; } break;
1548
- STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break;
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]), dest[1] = 255; } break;
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]), dest[1] = src[3]; } break;
1553
- STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
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], dest[1]=0xffff; } break;
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], dest[3]=0xffff; } break;
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], dest[3]=src[1]; } break;
1597
- STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break;
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]), dest[1] = 0xffff; } break;
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]), dest[1] = src[3]; } break;
1602
- STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
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
- if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f;
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], *out++ = 255;
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, z >>= 16;
5013
- if (z >= 0x00100) n += 8, z >>= 8;
5014
- if (z >= 0x00010) n += 4, z >>= 4;
5015
- if (z >= 0x00004) n += 2, z >>= 2;
5016
- if (z >= 0x00002) n += 1, z >>= 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
- s->img_n = ma ? 4 : 3;
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], p1[i] = p2[i], p2[i] = t;
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 preceeded by a 2-byte data count for each row in the data,
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)) return 0; // stbi__g_failure_reason set by stbi__gif_header
6350
- g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
6351
- g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
6352
- g->history = (stbi_uc *) stbi__malloc(g->w * g->h);
6353
- if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
6354
-
6355
- // image is treated as "tranparent" at the start - ie, nothing overwrites the current background;
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 teh color that was there the previous frame.
6358
- memset( g->out, 0x00, 4 * g->w * g->h );
6359
- memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent)
6360
- memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame
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 == NULL) return NULL;
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) *comp = info.ma ? 4 : 3;
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