gosu 0.15.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/COPYING +1 -1
  4. data/dependencies/SDL/include/SDL.h +138 -0
  5. data/dependencies/SDL/include/SDL_assert.h +293 -0
  6. data/dependencies/SDL/include/SDL_atomic.h +295 -0
  7. data/dependencies/SDL/include/SDL_audio.h +859 -0
  8. data/dependencies/SDL/include/SDL_bits.h +121 -0
  9. data/dependencies/SDL/include/SDL_blendmode.h +123 -0
  10. data/dependencies/SDL/include/SDL_clipboard.h +71 -0
  11. data/dependencies/SDL/include/SDL_config.h +55 -0
  12. data/dependencies/SDL/include/SDL_config_android.h +182 -0
  13. data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
  14. data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
  15. data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
  16. data/dependencies/SDL/include/SDL_config_os2.h +188 -0
  17. data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
  18. data/dependencies/SDL/include/SDL_config_psp.h +165 -0
  19. data/dependencies/SDL/include/SDL_config_windows.h +288 -0
  20. data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
  21. data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
  22. data/dependencies/SDL/include/SDL_copying.h +20 -0
  23. data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
  24. data/dependencies/SDL/include/SDL_egl.h +1676 -0
  25. data/dependencies/SDL/include/SDL_endian.h +263 -0
  26. data/dependencies/SDL/include/SDL_error.h +112 -0
  27. data/dependencies/SDL/include/SDL_events.h +827 -0
  28. data/dependencies/SDL/include/SDL_filesystem.h +136 -0
  29. data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
  30. data/dependencies/SDL/include/SDL_gesture.h +87 -0
  31. data/dependencies/SDL/include/SDL_haptic.h +1247 -0
  32. data/dependencies/SDL/include/SDL_hints.h +1578 -0
  33. data/dependencies/SDL/include/SDL_joystick.h +499 -0
  34. data/dependencies/SDL/include/SDL_keyboard.h +217 -0
  35. data/dependencies/SDL/include/SDL_keycode.h +351 -0
  36. data/dependencies/SDL/include/SDL_loadso.h +81 -0
  37. data/dependencies/SDL/include/SDL_locale.h +101 -0
  38. data/dependencies/SDL/include/SDL_log.h +211 -0
  39. data/dependencies/SDL/include/SDL_main.h +180 -0
  40. data/dependencies/SDL/include/SDL_messagebox.h +146 -0
  41. data/dependencies/SDL/include/SDL_metal.h +117 -0
  42. data/dependencies/SDL/include/SDL_misc.h +75 -0
  43. data/dependencies/SDL/include/SDL_mouse.h +302 -0
  44. data/dependencies/SDL/include/SDL_mutex.h +251 -0
  45. data/dependencies/SDL/include/SDL_name.h +33 -0
  46. data/dependencies/SDL/include/SDL_opengl.h +2183 -0
  47. data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
  48. data/dependencies/SDL/include/SDL_opengles.h +39 -0
  49. data/dependencies/SDL/include/SDL_opengles2.h +52 -0
  50. data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
  51. data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
  52. data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
  53. data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
  54. data/dependencies/SDL/include/SDL_pixels.h +479 -0
  55. data/dependencies/SDL/include/SDL_platform.h +198 -0
  56. data/dependencies/SDL/include/SDL_power.h +75 -0
  57. data/dependencies/SDL/include/SDL_quit.h +58 -0
  58. data/dependencies/SDL/include/SDL_rect.h +174 -0
  59. data/dependencies/SDL/include/SDL_render.h +1158 -0
  60. data/dependencies/SDL/include/SDL_revision.h +2 -0
  61. data/dependencies/SDL/include/SDL_rwops.h +283 -0
  62. data/dependencies/SDL/include/SDL_scancode.h +413 -0
  63. data/dependencies/SDL/include/SDL_sensor.h +267 -0
  64. data/dependencies/SDL/include/SDL_shape.h +144 -0
  65. data/dependencies/SDL/include/SDL_stdinc.h +647 -0
  66. data/dependencies/SDL/include/SDL_surface.h +563 -0
  67. data/dependencies/SDL/include/SDL_system.h +325 -0
  68. data/dependencies/SDL/include/SDL_syswm.h +354 -0
  69. data/dependencies/SDL/include/SDL_test.h +69 -0
  70. data/dependencies/SDL/include/SDL_test_assert.h +105 -0
  71. data/dependencies/SDL/include/SDL_test_common.h +218 -0
  72. data/dependencies/SDL/include/SDL_test_compare.h +69 -0
  73. data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
  74. data/dependencies/SDL/include/SDL_test_font.h +81 -0
  75. data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
  76. data/dependencies/SDL/include/SDL_test_harness.h +134 -0
  77. data/dependencies/SDL/include/SDL_test_images.h +78 -0
  78. data/dependencies/SDL/include/SDL_test_log.h +67 -0
  79. data/dependencies/SDL/include/SDL_test_md5.h +129 -0
  80. data/dependencies/SDL/include/SDL_test_memory.h +63 -0
  81. data/dependencies/SDL/include/SDL_test_random.h +115 -0
  82. data/dependencies/SDL/include/SDL_thread.h +366 -0
  83. data/dependencies/SDL/include/SDL_timer.h +115 -0
  84. data/dependencies/SDL/include/SDL_touch.h +102 -0
  85. data/dependencies/SDL/include/SDL_types.h +29 -0
  86. data/dependencies/SDL/include/SDL_version.h +162 -0
  87. data/dependencies/SDL/include/SDL_video.h +1282 -0
  88. data/dependencies/SDL/include/SDL_vulkan.h +276 -0
  89. data/dependencies/SDL/include/begin_code.h +166 -0
  90. data/dependencies/SDL/include/close_code.h +40 -0
  91. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  92. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  93. data/dependencies/SDL_sound/SDL_sound.c +795 -0
  94. data/dependencies/SDL_sound/SDL_sound.h +725 -0
  95. data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
  96. data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
  97. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
  98. data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
  99. data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
  100. data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
  101. data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
  102. data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
  103. data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
  104. data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
  105. data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
  106. data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
  107. data/dependencies/SDL_sound/dr_flac.h +5906 -0
  108. data/dependencies/SDL_sound/dr_mp3.h +2832 -0
  109. data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
  110. data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
  111. data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
  112. data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
  113. data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
  114. data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
  115. data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
  116. data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
  117. data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
  118. data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
  119. data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
  120. data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
  121. data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
  122. data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
  123. data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
  124. data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
  125. data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
  126. data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
  127. data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
  128. data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
  129. data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
  130. data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
  131. data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
  132. data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
  133. data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
  134. data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
  135. data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
  136. data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
  137. data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
  138. data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
  139. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
  140. data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
  141. data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
  142. data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
  143. data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
  144. data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
  145. data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +128 -23
  146. data/dependencies/al_soft/AL/al.h +655 -0
  147. data/dependencies/al_soft/AL/alc.h +270 -0
  148. data/dependencies/al_soft/AL/alext.h +585 -0
  149. data/dependencies/al_soft/AL/efx-creative.h +3 -0
  150. data/dependencies/al_soft/AL/efx-presets.h +402 -0
  151. data/dependencies/al_soft/AL/efx.h +762 -0
  152. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  153. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  154. data/{src → dependencies/stb}/stb_image.h +476 -176
  155. data/{src → dependencies/stb}/stb_image_write.h +253 -131
  156. data/{src → dependencies/stb}/stb_truetype.h +262 -104
  157. data/{src → dependencies/utf8proc}/utf8proc.c +47 -29
  158. data/{src → dependencies/utf8proc}/utf8proc.h +46 -24
  159. data/{src → dependencies/utf8proc}/utf8proc_data.h +10043 -9609
  160. data/ext/gosu/extconf.rb +53 -39
  161. data/{Gosu → include/Gosu}/Audio.hpp +6 -8
  162. data/include/Gosu/Bitmap.hpp +100 -0
  163. data/{Gosu → include/Gosu}/Buttons.hpp +104 -44
  164. data/include/Gosu/Channel.h +25 -0
  165. data/include/Gosu/Color.h +38 -0
  166. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  167. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  168. data/include/Gosu/Font.h +36 -0
  169. data/{Gosu → include/Gosu}/Font.hpp +1 -1
  170. data/{Gosu → include/Gosu}/Fwd.hpp +0 -5
  171. data/include/Gosu/Gosu.h +82 -0
  172. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  173. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  174. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  175. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  176. data/include/Gosu/Image.h +54 -0
  177. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  178. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  179. data/{Gosu → include/Gosu}/Input.hpp +39 -51
  180. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  181. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  182. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  183. data/include/Gosu/Sample.h +19 -0
  184. data/include/Gosu/Song.h +24 -0
  185. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  186. data/include/Gosu/TextInput.h +30 -0
  187. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  188. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  189. data/{Gosu → include/Gosu}/Utility.hpp +15 -4
  190. data/{Gosu → include/Gosu}/Version.hpp +2 -2
  191. data/include/Gosu/Window.h +63 -0
  192. data/{Gosu → include/Gosu}/Window.hpp +23 -25
  193. data/lib/OpenAL32.dll +0 -0
  194. data/lib/SDL2.dll +0 -0
  195. data/lib/gosu.rb +0 -3
  196. data/lib/gosu/patches.rb +0 -23
  197. data/lib/gosu/preview.rb +1 -3
  198. data/lib/gosu/swig_patches.rb +3 -2
  199. data/lib64/OpenAL32.dll +0 -0
  200. data/lib64/SDL2.dll +0 -0
  201. data/rdoc/gosu.rb +98 -22
  202. data/src/Audio.cpp +50 -224
  203. data/src/AudioFile.hpp +20 -37
  204. data/src/AudioFileAudioToolbox.cpp +237 -0
  205. data/src/AudioFileSDLSound.cpp +147 -0
  206. data/src/AudioImpl.cpp +3 -12
  207. data/src/AudioImpl.hpp +3 -1
  208. data/src/Bitmap.cpp +85 -83
  209. data/src/BitmapIO.cpp +52 -58
  210. data/src/ChannelWrapper.cpp +50 -0
  211. data/src/ColorWrapper.cpp +126 -0
  212. data/src/Constants.cpp +338 -0
  213. data/src/Font.cpp +4 -1
  214. data/src/FontWrapper.cpp +74 -0
  215. data/src/GosuWrapper.cpp +251 -0
  216. data/src/Graphics.cpp +7 -4
  217. data/src/Image.cpp +13 -16
  218. data/src/ImageWrapper.cpp +168 -0
  219. data/src/Input.cpp +412 -164
  220. data/src/LargeImageData.cpp +2 -1
  221. data/src/MarkupParser.cpp +2 -1
  222. data/src/RubyGosu.cxx +912 -172
  223. data/src/RubyGosu.h +4 -2
  224. data/src/SampleWrapper.cpp +30 -0
  225. data/src/SongWrapper.cpp +52 -0
  226. data/src/TexChunk.cpp +1 -1
  227. data/src/Text.cpp +1 -0
  228. data/src/TextBuilder.cpp +3 -1
  229. data/src/TextInputWrapper.cpp +101 -0
  230. data/src/Texture.cpp +1 -1
  231. data/src/TrueTypeFont.cpp +2 -1
  232. data/src/Utility.cpp +11 -7
  233. data/src/Window.cpp +30 -39
  234. data/src/WindowWrapper.cpp +317 -0
  235. metadata +212 -43
  236. data/Gosu/AutoLink.hpp +0 -14
  237. data/Gosu/Bitmap.hpp +0 -113
  238. data/lib/gosu/zen.rb +0 -89
  239. data/src/AudioToolboxFile.hpp +0 -210
  240. data/src/OggFile.hpp +0 -92
  241. data/src/SndFile.hpp +0 -174
  242. data/src/WinMain.cpp +0 -64
@@ -1,4 +1,4 @@
1
- /* stb_image_write - v1.09 - public domain - http://nothings.org/stb/stb_image_write.h
1
+ /* stb_image_write - v1.15 - public domain - http://nothings.org/stb
2
2
  writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
3
3
  no warranty implied; use at your own risk
4
4
 
@@ -10,15 +10,9 @@
10
10
 
11
11
  Will probably not work correctly with strict-aliasing optimizations.
12
12
 
13
- If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause
14
- compilation warnings or even errors. To avoid this, also before #including,
15
-
16
- #define STBI_MSC_SECURE_CRT
17
-
18
13
  ABOUT:
19
14
 
20
- This header file is a library for writing images to C stdio. It could be
21
- adapted to write to memory or a general streaming interface; let me know.
15
+ This header file is a library for writing images to C stdio or a callback.
22
16
 
23
17
  The PNG output is not optimal; it is 20-50% larger than the file
24
18
  written by a decent optimizing implementation; though providing a custom
@@ -38,6 +32,14 @@ BUILDING:
38
32
  The returned data will be freed with STBIW_FREE() (free() by default),
39
33
  so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
40
34
 
35
+ UNICODE:
36
+
37
+ If compiling for Windows and you wish to use Unicode filenames, compile
38
+ with
39
+ #define STBIW_WINDOWS_UTF8
40
+ and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert
41
+ Windows wchar_t filenames to utf8.
42
+
41
43
  USAGE:
42
44
 
43
45
  There are five functions, one for each image file format:
@@ -103,7 +105,7 @@ USAGE:
103
105
 
104
106
  TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
105
107
  data, set the global variable 'stbi_write_tga_with_rle' to 0.
106
-
108
+
107
109
  JPEG does ignore alpha channels in input data; quality is between 1 and 100.
108
110
  Higher quality looks better but results in a bigger image.
109
111
  JPEG baseline (no JPEG progressive).
@@ -111,7 +113,7 @@ USAGE:
111
113
  CREDITS:
112
114
 
113
115
 
114
- Sean Barrett - PNG/BMP/TGA
116
+ Sean Barrett - PNG/BMP/TGA
115
117
  Baldur Karlsson - HDR
116
118
  Jean-Sebastien Guay - TGA monochrome
117
119
  Tim Kelsey - misc enhancements
@@ -148,6 +150,8 @@ LICENSE
148
150
  #ifndef INCLUDE_STB_IMAGE_WRITE_H
149
151
  #define INCLUDE_STB_IMAGE_WRITE_H
150
152
 
153
+ #include <stdlib.h>
154
+
151
155
  // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
152
156
  #ifndef STBIWDEF
153
157
  #ifdef STB_IMAGE_WRITE_STATIC
@@ -173,6 +177,10 @@ STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const
173
177
  STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
174
178
  STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
175
179
  STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
180
+
181
+ #ifdef STBI_WINDOWS_UTF8
182
+ STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
183
+ #endif
176
184
  #endif
177
185
 
178
186
  typedef void stbi_write_func(void *context, void *data, int size);
@@ -239,17 +247,17 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
239
247
  #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
240
248
 
241
249
  #ifdef STB_IMAGE_WRITE_STATIC
242
- static int stbi__flip_vertically_on_write=0;
243
250
  static int stbi_write_png_compression_level = 8;
244
251
  static int stbi_write_tga_with_rle = 1;
245
252
  static int stbi_write_force_png_filter = -1;
246
253
  #else
247
254
  int stbi_write_png_compression_level = 8;
248
- int stbi__flip_vertically_on_write=0;
249
255
  int stbi_write_tga_with_rle = 1;
250
256
  int stbi_write_force_png_filter = -1;
251
257
  #endif
252
258
 
259
+ static int stbi__flip_vertically_on_write = 0;
260
+
253
261
  STBIWDEF void stbi_flip_vertically_on_write(int flag)
254
262
  {
255
263
  stbi__flip_vertically_on_write = flag;
@@ -259,6 +267,8 @@ typedef struct
259
267
  {
260
268
  stbi_write_func *func;
261
269
  void *context;
270
+ unsigned char buffer[64];
271
+ int buf_used;
262
272
  } stbi__write_context;
263
273
 
264
274
  // initialize a callback-based context
@@ -275,15 +285,52 @@ static void stbi__stdio_write(void *context, void *data, int size)
275
285
  fwrite(data,1,size,(FILE*) context);
276
286
  }
277
287
 
278
- static int stbi__start_write_file(stbi__write_context *s, const char *filename)
288
+ #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
289
+ #ifdef __cplusplus
290
+ #define STBIW_EXTERN extern "C"
291
+ #else
292
+ #define STBIW_EXTERN extern
293
+ #endif
294
+ STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
295
+ STBIW_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);
296
+
297
+ STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
298
+ {
299
+ return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
300
+ }
301
+ #endif
302
+
303
+ static FILE *stbiw__fopen(char const *filename, char const *mode)
279
304
  {
280
305
  FILE *f;
281
- #ifdef STBI_MSC_SECURE_CRT
282
- if (fopen_s(&f, filename, "wb"))
283
- f = NULL;
306
+ #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
307
+ wchar_t wMode[64];
308
+ wchar_t wFilename[1024];
309
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
310
+ return 0;
311
+
312
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
313
+ return 0;
314
+
315
+ #if _MSC_VER >= 1400
316
+ if (0 != _wfopen_s(&f, wFilename, wMode))
317
+ f = 0;
284
318
  #else
285
- f = fopen(filename, "wb");
319
+ f = _wfopen(wFilename, wMode);
286
320
  #endif
321
+
322
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
323
+ if (0 != fopen_s(&f, filename, mode))
324
+ f=0;
325
+ #else
326
+ f = fopen(filename, mode);
327
+ #endif
328
+ return f;
329
+ }
330
+
331
+ static int stbi__start_write_file(stbi__write_context *s, const char *filename)
332
+ {
333
+ FILE *f = stbiw__fopen(filename, "wb");
287
334
  stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
288
335
  return f != NULL;
289
336
  }
@@ -335,16 +382,36 @@ static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
335
382
  va_end(v);
336
383
  }
337
384
 
385
+ static void stbiw__write_flush(stbi__write_context *s)
386
+ {
387
+ if (s->buf_used) {
388
+ s->func(s->context, &s->buffer, s->buf_used);
389
+ s->buf_used = 0;
390
+ }
391
+ }
392
+
338
393
  static void stbiw__putc(stbi__write_context *s, unsigned char c)
339
394
  {
340
395
  s->func(s->context, &c, 1);
341
396
  }
342
397
 
398
+ static void stbiw__write1(stbi__write_context *s, unsigned char a)
399
+ {
400
+ if (s->buf_used + 1 > sizeof(s->buffer))
401
+ stbiw__write_flush(s);
402
+ s->buffer[s->buf_used++] = a;
403
+ }
404
+
343
405
  static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
344
406
  {
345
- unsigned char arr[3];
346
- arr[0] = a, arr[1] = b, arr[2] = c;
347
- s->func(s->context, arr, 3);
407
+ int n;
408
+ if (s->buf_used + 3 > sizeof(s->buffer))
409
+ stbiw__write_flush(s);
410
+ n = s->buf_used;
411
+ s->buf_used = n+3;
412
+ s->buffer[n+0] = a;
413
+ s->buffer[n+1] = b;
414
+ s->buffer[n+2] = c;
348
415
  }
349
416
 
350
417
  static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
@@ -353,7 +420,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
353
420
  int k;
354
421
 
355
422
  if (write_alpha < 0)
356
- s->func(s->context, &d[comp - 1], 1);
423
+ stbiw__write1(s, d[comp - 1]);
357
424
 
358
425
  switch (comp) {
359
426
  case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
@@ -361,7 +428,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
361
428
  if (expand_mono)
362
429
  stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
363
430
  else
364
- s->func(s->context, d, 1); // monochrome TGA
431
+ stbiw__write1(s, d[0]); // monochrome TGA
365
432
  break;
366
433
  case 4:
367
434
  if (!write_alpha) {
@@ -377,7 +444,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
377
444
  break;
378
445
  }
379
446
  if (write_alpha > 0)
380
- s->func(s->context, &d[comp - 1], 1);
447
+ stbiw__write1(s, d[comp - 1]);
381
448
  }
382
449
 
383
450
  static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
@@ -391,16 +458,18 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
391
458
  if (stbi__flip_vertically_on_write)
392
459
  vdir *= -1;
393
460
 
394
- if (vdir < 0)
395
- j_end = -1, j = y-1;
396
- else
397
- j_end = y, j = 0;
461
+ if (vdir < 0) {
462
+ j_end = -1; j = y-1;
463
+ } else {
464
+ j_end = y; j = 0;
465
+ }
398
466
 
399
467
  for (; j != j_end; j += vdir) {
400
468
  for (i=0; i < x; ++i) {
401
469
  unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
402
470
  stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
403
471
  }
472
+ stbiw__write_flush(s);
404
473
  s->func(s->context, &zero, scanline_pad);
405
474
  }
406
475
  }
@@ -430,7 +499,7 @@ static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, c
430
499
 
431
500
  STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
432
501
  {
433
- stbi__write_context s;
502
+ stbi__write_context s = { 0 };
434
503
  stbi__start_write_callbacks(&s, func, context);
435
504
  return stbi_write_bmp_core(&s, x, y, comp, data);
436
505
  }
@@ -438,7 +507,7 @@ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x,
438
507
  #ifndef STBI_WRITE_NO_STDIO
439
508
  STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
440
509
  {
441
- stbi__write_context s;
510
+ stbi__write_context s = { 0 };
442
511
  if (stbi__start_write_file(&s,filename)) {
443
512
  int r = stbi_write_bmp_core(&s, x, y, comp, data);
444
513
  stbi__end_write_file(&s);
@@ -511,24 +580,25 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v
511
580
 
512
581
  if (diff) {
513
582
  unsigned char header = STBIW_UCHAR(len - 1);
514
- s->func(s->context, &header, 1);
583
+ stbiw__write1(s, header);
515
584
  for (k = 0; k < len; ++k) {
516
585
  stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
517
586
  }
518
587
  } else {
519
588
  unsigned char header = STBIW_UCHAR(len - 129);
520
- s->func(s->context, &header, 1);
589
+ stbiw__write1(s, header);
521
590
  stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
522
591
  }
523
592
  }
524
593
  }
594
+ stbiw__write_flush(s);
525
595
  }
526
596
  return 1;
527
597
  }
528
598
 
529
599
  STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
530
600
  {
531
- stbi__write_context s;
601
+ stbi__write_context s = { 0 };
532
602
  stbi__start_write_callbacks(&s, func, context);
533
603
  return stbi_write_tga_core(&s, x, y, comp, (void *) data);
534
604
  }
@@ -536,7 +606,7 @@ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x,
536
606
  #ifndef STBI_WRITE_NO_STDIO
537
607
  STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
538
608
  {
539
- stbi__write_context s;
609
+ stbi__write_context s = { 0 };
540
610
  if (stbi__start_write_file(&s,filename)) {
541
611
  int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
542
612
  stbi__end_write_file(&s);
@@ -552,7 +622,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
552
622
 
553
623
  #define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
554
624
 
555
- void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
625
+ static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
556
626
  {
557
627
  int exponent;
558
628
  float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
@@ -569,7 +639,7 @@ void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
569
639
  }
570
640
  }
571
641
 
572
- void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
642
+ static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
573
643
  {
574
644
  unsigned char lengthbyte = STBIW_UCHAR(length+128);
575
645
  STBIW_ASSERT(length+128 <= 255);
@@ -577,7 +647,7 @@ void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char dat
577
647
  s->func(s->context, &databyte, 1);
578
648
  }
579
649
 
580
- void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
650
+ static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
581
651
  {
582
652
  unsigned char lengthbyte = STBIW_UCHAR(length);
583
653
  STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
@@ -585,7 +655,7 @@ void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *d
585
655
  s->func(s->context, data, length);
586
656
  }
587
657
 
588
- void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
658
+ static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
589
659
  {
590
660
  unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
591
661
  unsigned char rgbe[4];
@@ -686,15 +756,15 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
686
756
  char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
687
757
  s->func(s->context, header, sizeof(header)-1);
688
758
 
689
- #ifdef STBI_MSC_SECURE_CRT
690
- len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
759
+ #ifdef __STDC_WANT_SECURE_LIB__
760
+ len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
691
761
  #else
692
762
  len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
693
763
  #endif
694
764
  s->func(s->context, buffer, len);
695
765
 
696
766
  for(i=0; i < y; i++)
697
- stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)*x);
767
+ stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i));
698
768
  STBIW_FREE(scratch);
699
769
  return 1;
700
770
  }
@@ -702,7 +772,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
702
772
 
703
773
  STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
704
774
  {
705
- stbi__write_context s;
775
+ stbi__write_context s = { 0 };
706
776
  stbi__start_write_callbacks(&s, func, context);
707
777
  return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
708
778
  }
@@ -710,7 +780,7 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x,
710
780
  #ifndef STBI_WRITE_NO_STDIO
711
781
  STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
712
782
  {
713
- stbi__write_context s;
783
+ stbi__write_context s = { 0 };
714
784
  if (stbi__start_write_file(&s,filename)) {
715
785
  int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
716
786
  stbi__end_write_file(&s);
@@ -728,7 +798,7 @@ STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const
728
798
 
729
799
  #ifndef STBIW_ZLIB_COMPRESS
730
800
  // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
731
- #define stbiw__sbraw(a) ((int *) (a) - 2)
801
+ #define stbiw__sbraw(a) ((int *) (void *) (a) - 2)
732
802
  #define stbiw__sbm(a) stbiw__sbraw(a)[0]
733
803
  #define stbiw__sbn(a) stbiw__sbraw(a)[1]
734
804
 
@@ -809,7 +879,7 @@ static unsigned int stbiw__zhash(unsigned char *data)
809
879
 
810
880
  #endif // STBIW_ZLIB_COMPRESS
811
881
 
812
- unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
882
+ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
813
883
  {
814
884
  #ifdef STBIW_ZLIB_COMPRESS
815
885
  // user provided a zlib compress implementation, use that
@@ -822,7 +892,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
822
892
  unsigned int bitbuf=0;
823
893
  int i,j, bitcount=0;
824
894
  unsigned char *out = NULL;
825
- unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
895
+ unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**));
826
896
  if (hash_table == NULL)
827
897
  return NULL;
828
898
  if (quality < 5) quality = 5;
@@ -845,7 +915,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
845
915
  for (j=0; j < n; ++j) {
846
916
  if (hlist[j]-data > i-32768) { // if entry lies within window
847
917
  int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
848
- if (d >= best) best=d,bestloc=hlist[j];
918
+ if (d >= best) { best=d; bestloc=hlist[j]; }
849
919
  }
850
920
  }
851
921
  // when hash table entry is too long, delete half the entries
@@ -904,8 +974,8 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
904
974
  int blocklen = (int) (data_len % 5552);
905
975
  j=0;
906
976
  while (j < data_len) {
907
- for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
908
- s1 %= 65521, s2 %= 65521;
977
+ for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
978
+ s1 %= 65521; s2 %= 65521;
909
979
  j += blocklen;
910
980
  blocklen = 5552;
911
981
  }
@@ -923,6 +993,9 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
923
993
 
924
994
  static unsigned int stbiw__crc32(unsigned char *buffer, int len)
925
995
  {
996
+ #ifdef STBIW_CRC32
997
+ return STBIW_CRC32(buffer, len);
998
+ #else
926
999
  static unsigned int crc_table[256] =
927
1000
  {
928
1001
  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
@@ -964,6 +1037,7 @@ static unsigned int stbiw__crc32(unsigned char *buffer, int len)
964
1037
  for (i=0; i < len; ++i)
965
1038
  crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
966
1039
  return ~crc;
1040
+ #endif
967
1041
  }
968
1042
 
969
1043
  #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4)
@@ -994,9 +1068,15 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
994
1068
  int type = mymap[filter_type];
995
1069
  unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
996
1070
  int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
1071
+
1072
+ if (type==0) {
1073
+ memcpy(line_buffer, z, width*n);
1074
+ return;
1075
+ }
1076
+
1077
+ // first loop isn't optimized since it's just one pixel
997
1078
  for (i = 0; i < n; ++i) {
998
1079
  switch (type) {
999
- case 0: line_buffer[i] = z[i]; break;
1000
1080
  case 1: line_buffer[i] = z[i]; break;
1001
1081
  case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
1002
1082
  case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
@@ -1005,20 +1085,17 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
1005
1085
  case 6: line_buffer[i] = z[i]; break;
1006
1086
  }
1007
1087
  }
1008
- for (i=n; i < width*n; ++i) {
1009
- switch (type) {
1010
- case 0: line_buffer[i] = z[i]; break;
1011
- case 1: line_buffer[i] = z[i] - z[i-n]; break;
1012
- case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
1013
- case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
1014
- case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break;
1015
- case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
1016
- case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
1017
- }
1088
+ switch (type) {
1089
+ case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break;
1090
+ case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break;
1091
+ case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
1092
+ case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break;
1093
+ case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break;
1094
+ case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
1018
1095
  }
1019
1096
  }
1020
1097
 
1021
- unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
1098
+ STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
1022
1099
  {
1023
1100
  int force_filter = stbi_write_force_png_filter;
1024
1101
  int ctype[5] = { -1, 0, 4, 2, 6 };
@@ -1040,11 +1117,11 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
1040
1117
  int filter_type;
1041
1118
  if (force_filter > -1) {
1042
1119
  filter_type = force_filter;
1043
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, force_filter, line_buffer);
1120
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
1044
1121
  } else { // Estimate the best filter by running through all of them:
1045
1122
  int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
1046
1123
  for (filter_type = 0; filter_type < 5; filter_type++) {
1047
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, filter_type, line_buffer);
1124
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
1048
1125
 
1049
1126
  // Estimate the entropy of the line using this filter; the less, the better.
1050
1127
  est = 0;
@@ -1057,7 +1134,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
1057
1134
  }
1058
1135
  }
1059
1136
  if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it
1060
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, best_filter, line_buffer);
1137
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
1061
1138
  filter_type = best_filter;
1062
1139
  }
1063
1140
  }
@@ -1109,14 +1186,10 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
1109
1186
  {
1110
1187
  FILE *f;
1111
1188
  int len;
1112
- unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
1189
+ unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
1113
1190
  if (png == NULL) return 0;
1114
- #ifdef STBI_MSC_SECURE_CRT
1115
- if (fopen_s(&f, filename, "wb"))
1116
- f = NULL;
1117
- #else
1118
- f = fopen(filename, "wb");
1119
- #endif
1191
+
1192
+ f = stbiw__fopen(filename, "wb");
1120
1193
  if (!f) { STBIW_FREE(png); return 0; }
1121
1194
  fwrite(png, 1, len, f);
1122
1195
  fclose(f);
@@ -1128,7 +1201,7 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
1128
1201
  STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes)
1129
1202
  {
1130
1203
  int len;
1131
- unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
1204
+ unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
1132
1205
  if (png == NULL) return 0;
1133
1206
  func(context, png, len);
1134
1207
  STBIW_FREE(png);
@@ -1222,26 +1295,31 @@ static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) {
1222
1295
  bits[0] = val & ((1<<bits[1])-1);
1223
1296
  }
1224
1297
 
1225
- static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
1298
+ static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, int du_stride, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
1226
1299
  const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
1227
1300
  const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
1228
- int dataOff, i, diff, end0pos;
1301
+ int dataOff, i, j, n, diff, end0pos, x, y;
1229
1302
  int DU[64];
1230
1303
 
1231
1304
  // DCT rows
1232
- for(dataOff=0; dataOff<64; dataOff+=8) {
1305
+ for(dataOff=0, n=du_stride*8; dataOff<n; dataOff+=du_stride) {
1233
1306
  stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+1], &CDU[dataOff+2], &CDU[dataOff+3], &CDU[dataOff+4], &CDU[dataOff+5], &CDU[dataOff+6], &CDU[dataOff+7]);
1234
1307
  }
1235
1308
  // DCT columns
1236
1309
  for(dataOff=0; dataOff<8; ++dataOff) {
1237
- stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+8], &CDU[dataOff+16], &CDU[dataOff+24], &CDU[dataOff+32], &CDU[dataOff+40], &CDU[dataOff+48], &CDU[dataOff+56]);
1310
+ stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+du_stride], &CDU[dataOff+du_stride*2], &CDU[dataOff+du_stride*3], &CDU[dataOff+du_stride*4],
1311
+ &CDU[dataOff+du_stride*5], &CDU[dataOff+du_stride*6], &CDU[dataOff+du_stride*7]);
1238
1312
  }
1239
1313
  // Quantize/descale/zigzag the coefficients
1240
- for(i=0; i<64; ++i) {
1241
- float v = CDU[i]*fdtbl[i];
1242
- // DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
1243
- // ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
1244
- DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
1314
+ for(y = 0, j=0; y < 8; ++y) {
1315
+ for(x = 0; x < 8; ++x,++j) {
1316
+ float v;
1317
+ i = y*du_stride+x;
1318
+ v = CDU[i]*fdtbl[j];
1319
+ // DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
1320
+ // ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
1321
+ DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
1322
+ }
1245
1323
  }
1246
1324
 
1247
1325
  // Encode DC
@@ -1356,10 +1434,10 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
1356
1434
  37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99};
1357
1435
  static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,
1358
1436
  99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99};
1359
- static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
1437
+ static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
1360
1438
  1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
1361
1439
 
1362
- int row, col, i, k;
1440
+ int row, col, i, k, subsample;
1363
1441
  float fdtbl_Y[64], fdtbl_UV[64];
1364
1442
  unsigned char YTable[64], UVTable[64];
1365
1443
 
@@ -1368,6 +1446,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
1368
1446
  }
1369
1447
 
1370
1448
  quality = quality ? quality : 90;
1449
+ subsample = quality <= 90 ? 1 : 0;
1371
1450
  quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
1372
1451
  quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
1373
1452
 
@@ -1390,7 +1469,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
1390
1469
  static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
1391
1470
  static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
1392
1471
  const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width),
1393
- 3,1,0x11,0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
1472
+ 3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
1394
1473
  s->func(s->context, (void*)head0, sizeof(head0));
1395
1474
  s->func(s->context, (void*)YTable, sizeof(YTable));
1396
1475
  stbiw__putc(s, 1);
@@ -1413,38 +1492,74 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
1413
1492
  // Encode 8x8 macroblocks
1414
1493
  {
1415
1494
  static const unsigned short fillBits[] = {0x7F, 7};
1416
- const unsigned char *imageData = (const unsigned char *)data;
1417
1495
  int DCY=0, DCU=0, DCV=0;
1418
1496
  int bitBuf=0, bitCnt=0;
1419
1497
  // comp == 2 is grey+alpha (alpha is ignored)
1420
1498
  int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
1499
+ const unsigned char *dataR = (const unsigned char *)data;
1500
+ const unsigned char *dataG = dataR + ofsG;
1501
+ const unsigned char *dataB = dataR + ofsB;
1421
1502
  int x, y, pos;
1422
- for(y = 0; y < height; y += 8) {
1423
- for(x = 0; x < width; x += 8) {
1424
- float YDU[64], UDU[64], VDU[64];
1425
- for(row = y, pos = 0; row < y+8; ++row) {
1426
- for(col = x; col < x+8; ++col, ++pos) {
1427
- int p = (stbi__flip_vertically_on_write ? height-1-row : row)*width*comp + col*comp;
1428
- float r, g, b;
1429
- if(row >= height) {
1430
- p -= width*comp*(row+1 - height);
1503
+ if(subsample) {
1504
+ for(y = 0; y < height; y += 16) {
1505
+ for(x = 0; x < width; x += 16) {
1506
+ float Y[256], U[256], V[256];
1507
+ for(row = y, pos = 0; row < y+16; ++row) {
1508
+ // row >= height => use last input row
1509
+ int clamped_row = (row < height) ? row : height - 1;
1510
+ int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
1511
+ for(col = x; col < x+16; ++col, ++pos) {
1512
+ // if col >= width => use pixel from last input column
1513
+ int p = base_p + ((col < width) ? col : (width-1))*comp;
1514
+ float r = dataR[p], g = dataG[p], b = dataB[p];
1515
+ Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
1516
+ U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
1517
+ V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
1431
1518
  }
1432
- if(col >= width) {
1433
- p -= comp*(col+1 - width);
1519
+ }
1520
+ DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1521
+ DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1522
+ DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1523
+ DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1524
+
1525
+ // subsample U,V
1526
+ {
1527
+ float subU[64], subV[64];
1528
+ int yy, xx;
1529
+ for(yy = 0, pos = 0; yy < 8; ++yy) {
1530
+ for(xx = 0; xx < 8; ++xx, ++pos) {
1531
+ int j = yy*32+xx*2;
1532
+ subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f;
1533
+ subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f;
1534
+ }
1434
1535
  }
1435
-
1436
- r = imageData[p+0];
1437
- g = imageData[p+ofsG];
1438
- b = imageData[p+ofsB];
1439
- YDU[pos]=+0.29900f*r+0.58700f*g+0.11400f*b-128;
1440
- UDU[pos]=-0.16874f*r-0.33126f*g+0.50000f*b;
1441
- VDU[pos]=+0.50000f*r-0.41869f*g-0.08131f*b;
1536
+ DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1537
+ DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1442
1538
  }
1443
1539
  }
1540
+ }
1541
+ } else {
1542
+ for(y = 0; y < height; y += 8) {
1543
+ for(x = 0; x < width; x += 8) {
1544
+ float Y[64], U[64], V[64];
1545
+ for(row = y, pos = 0; row < y+8; ++row) {
1546
+ // row >= height => use last input row
1547
+ int clamped_row = (row < height) ? row : height - 1;
1548
+ int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
1549
+ for(col = x; col < x+8; ++col, ++pos) {
1550
+ // if col >= width => use pixel from last input column
1551
+ int p = base_p + ((col < width) ? col : (width-1))*comp;
1552
+ float r = dataR[p], g = dataG[p], b = dataB[p];
1553
+ Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
1554
+ U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
1555
+ V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
1556
+ }
1557
+ }
1444
1558
 
1445
- DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1446
- DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1447
- DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1559
+ DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1560
+ DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1561
+ DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1562
+ }
1448
1563
  }
1449
1564
  }
1450
1565
 
@@ -1461,7 +1576,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
1461
1576
 
1462
1577
  STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)
1463
1578
  {
1464
- stbi__write_context s;
1579
+ stbi__write_context s = { 0 };
1465
1580
  stbi__start_write_callbacks(&s, func, context);
1466
1581
  return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality);
1467
1582
  }
@@ -1470,7 +1585,7 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
1470
1585
  #ifndef STBI_WRITE_NO_STDIO
1471
1586
  STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
1472
1587
  {
1473
- stbi__write_context s;
1588
+ stbi__write_context s = { 0 };
1474
1589
  if (stbi__start_write_file(&s,filename)) {
1475
1590
  int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
1476
1591
  stbi__end_write_file(&s);
@@ -1483,6 +1598,13 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
1483
1598
  #endif // STB_IMAGE_WRITE_IMPLEMENTATION
1484
1599
 
1485
1600
  /* Revision history
1601
+ 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels
1602
+ 1.13
1603
+ 1.12
1604
+ 1.11 (2019-08-11)
1605
+
1606
+ 1.10 (2019-02-07)
1607
+ support utf8 filenames in Windows; fix warnings and platform ifdefs
1486
1608
  1.09 (2018-02-11)
1487
1609
  fix typo in zlib quality API, improve STB_I_W_STATIC in C++
1488
1610
  1.08 (2018-01-29)
@@ -1531,38 +1653,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
1531
1653
  ------------------------------------------------------------------------------
1532
1654
  ALTERNATIVE A - MIT License
1533
1655
  Copyright (c) 2017 Sean Barrett
1534
- Permission is hereby granted, free of charge, to any person obtaining a copy of
1535
- this software and associated documentation files (the "Software"), to deal in
1536
- the Software without restriction, including without limitation the rights to
1537
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1538
- of the Software, and to permit persons to whom the Software is furnished to do
1656
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
1657
+ this software and associated documentation files (the "Software"), to deal in
1658
+ the Software without restriction, including without limitation the rights to
1659
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1660
+ of the Software, and to permit persons to whom the Software is furnished to do
1539
1661
  so, subject to the following conditions:
1540
- The above copyright notice and this permission notice shall be included in all
1662
+ The above copyright notice and this permission notice shall be included in all
1541
1663
  copies or substantial portions of the Software.
1542
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1543
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1544
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1545
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1546
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1547
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1664
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1665
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1666
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1667
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1668
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1669
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1548
1670
  SOFTWARE.
1549
1671
  ------------------------------------------------------------------------------
1550
1672
  ALTERNATIVE B - Public Domain (www.unlicense.org)
1551
1673
  This is free and unencumbered software released into the public domain.
1552
- Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
1553
- software, either in source code form or as a compiled binary, for any purpose,
1674
+ Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
1675
+ software, either in source code form or as a compiled binary, for any purpose,
1554
1676
  commercial or non-commercial, and by any means.
1555
- In jurisdictions that recognize copyright laws, the author or authors of this
1556
- software dedicate any and all copyright interest in the software to the public
1557
- domain. We make this dedication for the benefit of the public at large and to
1558
- the detriment of our heirs and successors. We intend this dedication to be an
1559
- overt act of relinquishment in perpetuity of all present and future rights to
1677
+ In jurisdictions that recognize copyright laws, the author or authors of this
1678
+ software dedicate any and all copyright interest in the software to the public
1679
+ domain. We make this dedication for the benefit of the public at large and to
1680
+ the detriment of our heirs and successors. We intend this dedication to be an
1681
+ overt act of relinquishment in perpetuity of all present and future rights to
1560
1682
  this software under copyright law.
1561
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1562
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1563
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1564
- AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1565
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1683
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1684
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1685
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1686
+ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1687
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1566
1688
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1567
1689
  ------------------------------------------------------------------------------
1568
1690
  */