gosu 0.13.2 → 0.13.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- /* stb_image_write - v1.07 - public domain - http://nothings.org/stb/stb_image_write.h
1
+ /* stb_image_write - v1.08 - public domain - http://nothings.org/stb/stb_image_write.h
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,34 +10,47 @@
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
+
13
18
  ABOUT:
14
19
 
15
20
  This header file is a library for writing images to C stdio. It could be
16
21
  adapted to write to memory or a general streaming interface; let me know.
17
22
 
18
23
  The PNG output is not optimal; it is 20-50% larger than the file
19
- written by a decent optimizing implementation. This library is designed
20
- for source code compactness and simplicity, not optimal image file size
21
- or run-time performance.
24
+ written by a decent optimizing implementation; though providing a custom
25
+ zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that.
26
+ This library is designed for source code compactness and simplicity,
27
+ not optimal image file size or run-time performance.
22
28
 
23
29
  BUILDING:
24
30
 
25
31
  You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
26
32
  You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
27
33
  malloc,realloc,free.
28
- You can define STBIW_MEMMOVE() to replace memmove()
34
+ You can #define STBIW_MEMMOVE() to replace memmove()
35
+ You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function
36
+ for PNG compression (instead of the builtin one), it must have the following signature:
37
+ unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality);
38
+ The returned data will be freed with STBIW_FREE() (free() by default),
39
+ so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
29
40
 
30
41
  USAGE:
31
42
 
32
- There are four functions, one for each image file format:
43
+ There are five functions, one for each image file format:
33
44
 
34
45
  int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
35
46
  int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
36
47
  int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
37
48
  int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
38
- int stbi_write_jpg(char const *filename, int w, int h, int comp, const float *data);
49
+ int stbi_write_jpg(char const *filename, int w, int h, int comp, const float *data, int quality);
39
50
 
40
- There are also four equivalent functions that use an arbitrary write function. You are
51
+ void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
52
+
53
+ There are also five equivalent functions that use an arbitrary write function. You are
41
54
  expected to open/close your file-equivalent before and after calling these:
42
55
 
43
56
  int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes);
@@ -49,6 +62,12 @@ USAGE:
49
62
  where the callback is:
50
63
  void stbi_write_func(void *context, void *data, int size);
51
64
 
65
+ You can configure it with these global variables:
66
+ int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE
67
+ int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression
68
+ int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode
69
+
70
+
52
71
  You can define STBI_WRITE_NO_STDIO to disable the file variant of these
53
72
  functions, so the library will not use stdio.h at all. However, this will
54
73
  also disable HDR writing, because it requires stdio for formatted output.
@@ -75,6 +94,9 @@ USAGE:
75
94
  writer, both because it is in BGR order and because it may have padding
76
95
  at the end of the line.)
77
96
 
97
+ PNG allows you to set the deflate compression level by setting the global
98
+ variable 'stbi_write_png_level' (it defaults to 8).
99
+
78
100
  HDR expects linear float data. Since the format is always 32-bit rgb(e)
79
101
  data, alpha (if provided) is discarded, and for monochrome data it is
80
102
  replicated across all three channels.
@@ -88,21 +110,17 @@ USAGE:
88
110
 
89
111
  CREDITS:
90
112
 
91
- PNG/BMP/TGA
92
- Sean Barrett
93
- HDR
94
- Baldur Karlsson
95
- TGA monochrome:
96
- Jean-Sebastien Guay
97
- misc enhancements:
98
- Tim Kelsey
99
- TGA RLE
100
- Alan Hickman
101
- initial file IO callback implementation
102
- Emmanuel Julien
103
- JPEG
104
- Jon Olick (original jo_jpeg.cpp code)
105
- Daniel Gibson
113
+
114
+ Sean Barrett - PNG/BMP/TGA
115
+ Baldur Karlsson - HDR
116
+ Jean-Sebastien Guay - TGA monochrome
117
+ Tim Kelsey - misc enhancements
118
+ Alan Hickman - TGA RLE
119
+ Emmanuel Julien - initial file IO callback implementation
120
+ Jon Olick - original jo_jpeg.cpp code
121
+ Daniel Gibson - integrate JPEG, allow external zlib
122
+ Aarni Koskela - allow choosing PNG filter
123
+
106
124
  bugfixes:
107
125
  github:Chribba
108
126
  Guillaume Chereau
@@ -114,6 +132,7 @@ CREDITS:
114
132
  Thatcher Ulrich
115
133
  github:poppolopoppo
116
134
  Patrick Boettcher
135
+ github:xeekworx
117
136
 
118
137
  LICENSE
119
138
 
@@ -132,9 +151,12 @@ extern "C" {
132
151
  #define STBIWDEF static
133
152
  #else
134
153
  #define STBIWDEF extern
135
- extern int stbi_write_tga_with_rle;
136
154
  #endif
137
155
 
156
+ STBIWDEF int stbi_write_tga_with_rle;
157
+ STBIWDEF int stbi_write_png_comperssion_level;
158
+ STBIWDEF int stbi_write_force_png_filter;
159
+
138
160
  #ifndef STBI_WRITE_NO_STDIO
139
161
  STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
140
162
  STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
@@ -151,6 +173,8 @@ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w,
151
173
  STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
152
174
  STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality);
153
175
 
176
+ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
177
+
154
178
  #ifdef __cplusplus
155
179
  }
156
180
  #endif
@@ -208,6 +232,23 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
208
232
 
209
233
  #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
210
234
 
235
+ #ifdef STB_IMAGE_WRITE_STATIC
236
+ static stbi__flip_vertically_on_write=0;
237
+ static int stbi_write_png_compression level = 8;
238
+ static int stbi_write_tga_with_rle = 1;
239
+ static int stbi_write_force_png_filter = -1;
240
+ #else
241
+ int stbi_write_png_compression_level = 8;
242
+ int stbi__flip_vertically_on_write=0;
243
+ int stbi_write_tga_with_rle = 1;
244
+ int stbi_write_force_png_filter = -1;
245
+ #endif
246
+
247
+ STBIWDEF void stbi_flip_vertically_on_write(int flag)
248
+ {
249
+ stbi__flip_vertically_on_write = flag;
250
+ }
251
+
211
252
  typedef struct
212
253
  {
213
254
  stbi_write_func *func;
@@ -230,7 +271,13 @@ static void stbi__stdio_write(void *context, void *data, int size)
230
271
 
231
272
  static int stbi__start_write_file(stbi__write_context *s, const char *filename)
232
273
  {
233
- FILE *f = fopen(filename, "wb");
274
+ FILE *f;
275
+ #ifdef STBI_MSC_SECURE_CRT
276
+ if (fopen_s(&f, filename, "wb"))
277
+ f = NULL;
278
+ #else
279
+ f = fopen(filename, "wb");
280
+ #endif
234
281
  stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
235
282
  return f != NULL;
236
283
  }
@@ -245,12 +292,6 @@ static void stbi__end_write_file(stbi__write_context *s)
245
292
  typedef unsigned int stbiw_uint32;
246
293
  typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
247
294
 
248
- #ifdef STB_IMAGE_WRITE_STATIC
249
- static int stbi_write_tga_with_rle = 1;
250
- #else
251
- int stbi_write_tga_with_rle = 1;
252
- #endif
253
-
254
295
  static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
255
296
  {
256
297
  while (*fmt) {
@@ -341,6 +382,9 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
341
382
  if (y <= 0)
342
383
  return;
343
384
 
385
+ if (stbi__flip_vertically_on_write)
386
+ vdir *= -1;
387
+
344
388
  if (vdir < 0)
345
389
  j_end = -1, j = y-1;
346
390
  else
@@ -412,11 +456,21 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v
412
456
  "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
413
457
  } else {
414
458
  int i,j,k;
459
+ int jend, jdir;
415
460
 
416
461
  stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8);
417
462
 
418
- for (j = y - 1; j >= 0; --j) {
419
- unsigned char *row = (unsigned char *) data + j * x * comp;
463
+ if (stbi__flip_vertically_on_write) {
464
+ j = 0;
465
+ jend = y;
466
+ jdir = 1;
467
+ } else {
468
+ j = y-1;
469
+ jend = -1;
470
+ jdir = -1;
471
+ }
472
+ for (; j != jend; j += jdir) {
473
+ unsigned char *row = (unsigned char *) data + j * x * comp;
420
474
  int len;
421
475
 
422
476
  for (i = 0; i < x; i += len) {
@@ -626,11 +680,15 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
626
680
  char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
627
681
  s->func(s->context, header, sizeof(header)-1);
628
682
 
683
+ #ifdef STBI_MSC_SECURE_CRT
684
+ len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
685
+ #else
629
686
  len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
687
+ #endif
630
688
  s->func(s->context, buffer, len);
631
689
 
632
690
  for(i=0; i < y; i++)
633
- stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x);
691
+ stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)*x);
634
692
  STBIW_FREE(scratch);
635
693
  return 1;
636
694
  }
@@ -662,6 +720,7 @@ STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const
662
720
  // PNG writer
663
721
  //
664
722
 
723
+ #ifndef STBIW_ZLIB_COMPRESS
665
724
  // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
666
725
  #define stbiw__sbraw(a) ((int *) (a) - 2)
667
726
  #define stbiw__sbm(a) stbiw__sbraw(a)[0]
@@ -742,8 +801,14 @@ static unsigned int stbiw__zhash(unsigned char *data)
742
801
 
743
802
  #define stbiw__ZHASH 16384
744
803
 
804
+ #endif // STBIW_ZLIB_COMPRESS
805
+
745
806
  unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
746
807
  {
808
+ #ifdef STBIW_ZLIB_COMPRESS
809
+ // user provided a zlib compress implementation, use that
810
+ return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
811
+ #else // use builtin
747
812
  static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
748
813
  static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 };
749
814
  static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
@@ -752,6 +817,8 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
752
817
  int i,j, bitcount=0;
753
818
  unsigned char *out = NULL;
754
819
  unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
820
+ if (hash_table == NULL)
821
+ return NULL;
755
822
  if (quality < 5) quality = 5;
756
823
 
757
824
  stbiw__sbpush(out, 0x78); // DEFLATE 32K window
@@ -845,6 +912,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
845
912
  // make returned pointer freeable
846
913
  STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
847
914
  return (unsigned char *) stbiw__sbraw(out);
915
+ #endif // STBIW_ZLIB_COMPRESS
848
916
  }
849
917
 
850
918
  static unsigned int stbiw__crc32(unsigned char *buffer, int len)
@@ -911,61 +979,87 @@ static unsigned char stbiw__paeth(int a, int b, int c)
911
979
  }
912
980
 
913
981
  // @OPTIMIZE: provide an option that always forces left-predict or paeth predict
982
+ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer)
983
+ {
984
+ static int mapping[] = { 0,1,2,3,4 };
985
+ static int firstmap[] = { 0,1,0,5,6 };
986
+ int *mymap = (y != 0) ? mapping : firstmap;
987
+ int i;
988
+ int type = mymap[filter_type];
989
+ unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
990
+ for (i = 0; i < n; ++i) {
991
+ switch (type) {
992
+ case 0: line_buffer[i] = z[i]; break;
993
+ case 1: line_buffer[i] = z[i]; break;
994
+ case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
995
+ case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
996
+ case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
997
+ case 5: line_buffer[i] = z[i]; break;
998
+ case 6: line_buffer[i] = z[i]; break;
999
+ }
1000
+ }
1001
+ for (i=n; i < width*n; ++i) {
1002
+ switch (type) {
1003
+ case 0: line_buffer[i] = z[i]; break;
1004
+ case 1: line_buffer[i] = z[i] - z[i-n]; break;
1005
+ case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
1006
+ case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
1007
+ case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
1008
+ case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
1009
+ case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
1010
+ }
1011
+ }
1012
+ }
1013
+
914
1014
  unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
915
1015
  {
1016
+ int force_filter = stbi_write_force_png_filter;
916
1017
  int ctype[5] = { -1, 0, 4, 2, 6 };
917
1018
  unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
918
1019
  unsigned char *out,*o, *filt, *zlib;
919
1020
  signed char *line_buffer;
920
- int i,j,k,p,zlen;
1021
+ int j,zlen;
921
1022
 
922
1023
  if (stride_bytes == 0)
923
1024
  stride_bytes = x * n;
924
1025
 
1026
+ if (force_filter >= 5) {
1027
+ force_filter = -1;
1028
+ }
1029
+
925
1030
  filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
926
1031
  line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
927
1032
  for (j=0; j < y; ++j) {
928
- static int mapping[] = { 0,1,2,3,4 };
929
- static int firstmap[] = { 0,1,0,5,6 };
930
- int *mymap = (j != 0) ? mapping : firstmap;
931
- int best = 0, bestval = 0x7fffffff;
932
- for (p=0; p < 2; ++p) {
933
- for (k= p?best:0; k < 5; ++k) { // @TODO: clarity: rewrite this to go 0..5, and 'continue' the unwanted ones during 2nd pass
934
- int type = mymap[k],est=0;
935
- unsigned char *z = pixels + stride_bytes*j;
936
- for (i=0; i < n; ++i)
937
- switch (type) {
938
- case 0: line_buffer[i] = z[i]; break;
939
- case 1: line_buffer[i] = z[i]; break;
940
- case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
941
- case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
942
- case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
943
- case 5: line_buffer[i] = z[i]; break;
944
- case 6: line_buffer[i] = z[i]; break;
945
- }
946
- for (i=n; i < x*n; ++i) {
947
- switch (type) {
948
- case 0: line_buffer[i] = z[i]; break;
949
- case 1: line_buffer[i] = z[i] - z[i-n]; break;
950
- case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
951
- case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
952
- case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
953
- case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
954
- case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
955
- }
956
- }
957
- if (p) break;
958
- for (i=0; i < x*n; ++i)
1033
+ int filter_type;
1034
+ if (force_filter > -1) {
1035
+ filter_type = force_filter;
1036
+ stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, force_filter, line_buffer);
1037
+ } else { // Estimate the best filter by running through all of them:
1038
+ int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
1039
+ for (filter_type = 0; filter_type < 5; filter_type++) {
1040
+ stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, filter_type, line_buffer);
1041
+
1042
+ // Estimate the entropy of the line using this filter; the less, the better.
1043
+ est = 0;
1044
+ for (i = 0; i < x*n; ++i) {
959
1045
  est += abs((signed char) line_buffer[i]);
960
- if (est < bestval) { bestval = est; best = k; }
1046
+ }
1047
+ if (est < best_filter_val) {
1048
+ best_filter_val = est;
1049
+ best_filter = filter_type;
1050
+ }
1051
+ }
1052
+ if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it
1053
+ stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, best_filter, line_buffer);
1054
+ filter_type = best_filter;
961
1055
  }
962
1056
  }
963
- // when we get here, best contains the filter type, and line_buffer contains the data
964
- filt[j*(x*n+1)] = (unsigned char) best;
1057
+ // when we get here, filter_type contains the filter type, and line_buffer contains the data
1058
+ filt[j*(x*n+1)] = (unsigned char) filter_type;
965
1059
  STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
966
1060
  }
967
1061
  STBIW_FREE(line_buffer);
968
- zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
1062
+ zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level);
969
1063
  STBIW_FREE(filt);
970
1064
  if (!zlib) return 0;
971
1065
 
@@ -1010,7 +1104,12 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
1010
1104
  int len;
1011
1105
  unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
1012
1106
  if (png == NULL) return 0;
1107
+ #ifdef STBI_MSC_SECURE_CRT
1108
+ if (fopen_s(&f, filename, "wb"))
1109
+ f = NULL;
1110
+ #else
1013
1111
  f = fopen(filename, "wb");
1112
+ #endif
1014
1113
  if (!f) { STBIW_FREE(png); return 0; }
1015
1114
  fwrite(png, 1, len, f);
1016
1115
  fclose(f);
@@ -1318,7 +1417,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
1318
1417
  float YDU[64], UDU[64], VDU[64];
1319
1418
  for(row = y, pos = 0; row < y+8; ++row) {
1320
1419
  for(col = x; col < x+8; ++col, ++pos) {
1321
- int p = row*width*comp + col*comp;
1420
+ int p = (stbi__flip_vertically_on_write ? height-1-row : row)*width*comp + col*comp;
1322
1421
  float r, g, b;
1323
1422
  if(row >= height) {
1324
1423
  p -= width*comp*(row+1 - height);
@@ -1377,6 +1476,8 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
1377
1476
  #endif // STB_IMAGE_WRITE_IMPLEMENTATION
1378
1477
 
1379
1478
  /* Revision history
1479
+ 1.08 (2018-01-29)
1480
+ add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
1380
1481
  1.07 (2017-07-24)
1381
1482
  doc fix
1382
1483
  1.06 (2017-07-23)
@@ -1,11 +1,11 @@
1
- // Ogg Vorbis audio decoder - v1.11 - public domain
1
+ // Ogg Vorbis audio decoder - v1.13b - public domain
2
2
  // http://nothings.org/stb_vorbis/
3
3
  //
4
4
  // Original version written by Sean Barrett in 2007.
5
5
  //
6
- // Originally sponsored by RAD Game Tools. Seeking sponsored
7
- // by Phillip Bennefall, Marc Andersen, Aaron Baker, Elias Software,
8
- // Aras Pranckevicius, and Sean Barrett.
6
+ // Originally sponsored by RAD Game Tools. Seeking implementation
7
+ // sponsored by Phillip Bennefall, Marc Andersen, Aaron Baker,
8
+ // Elias Software, Aras Pranckevicius, and Sean Barrett.
9
9
  //
10
10
  // LICENSE
11
11
  //
@@ -32,6 +32,8 @@
32
32
  // manxorist@github saga musix github:infatum
33
33
  //
34
34
  // Partial history:
35
+ // 1.13 - 2018/01/29 - fix truncation of last frame (hopefully)
36
+ // 1.12 - 2017/11/21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
35
37
  // 1.11 - 2017/07/23 - fix MinGW compilation
36
38
  // 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
37
39
  // 1.09 - 2016/04/04 - back out 'truncation of last frame' fix from previous version
@@ -2042,6 +2044,8 @@ static int residue_decode(vorb *f, Codebook *book, float *target, int offset, in
2042
2044
  return TRUE;
2043
2045
  }
2044
2046
 
2047
+ // n is 1/2 of the blocksize --
2048
+ // specification: "Correct per-vector decode length is [n]/2"
2045
2049
  static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode)
2046
2050
  {
2047
2051
  int i,j,pass;
@@ -2049,7 +2053,10 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
2049
2053
  int rtype = f->residue_types[rn];
2050
2054
  int c = r->classbook;
2051
2055
  int classwords = f->codebooks[c].dimensions;
2052
- int n_read = r->end - r->begin;
2056
+ unsigned int actual_size = rtype == 2 ? n*2 : n;
2057
+ unsigned int limit_r_begin = (r->begin < actual_size ? r->begin : actual_size);
2058
+ unsigned int limit_r_end = (r->end < actual_size ? r->end : actual_size);
2059
+ int n_read = limit_r_end - limit_r_begin;
2053
2060
  int part_read = n_read / r->part_size;
2054
2061
  int temp_alloc_point = temp_alloc_save(f);
2055
2062
  #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
@@ -3391,7 +3398,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
3391
3398
  if (f->last_seg_which == f->end_seg_with_known_loc) {
3392
3399
  // if we have a valid current loc, and this is final:
3393
3400
  if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) {
3394
- uint32 current_end = f->known_loc_for_packet - (n-right_end);
3401
+ uint32 current_end = f->known_loc_for_packet;
3395
3402
  // then let's infer the size of the (probably) short final frame
3396
3403
  if (current_end < f->current_loc + (right_end-left_start)) {
3397
3404
  if (current_end < f->current_loc) {
@@ -3400,7 +3407,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
3400
3407
  } else {
3401
3408
  *len = current_end - f->current_loc;
3402
3409
  }
3403
- *len += left_start;
3410
+ *len += left_start; // this doesn't seem right, but has no ill effect on my test files
3404
3411
  if (*len > right_end) *len = right_end; // this should never happen
3405
3412
  f->current_loc += *len;
3406
3413
  return TRUE;
@@ -4077,7 +4084,10 @@ static int start_decoder(vorb *f)
4077
4084
  int i,max_part_read=0;
4078
4085
  for (i=0; i < f->residue_count; ++i) {
4079
4086
  Residue *r = f->residue_config + i;
4080
- int n_read = r->end - r->begin;
4087
+ unsigned int actual_size = f->blocksize_1 / 2;
4088
+ unsigned int limit_r_begin = r->begin < actual_size ? r->begin : actual_size;
4089
+ unsigned int limit_r_end = r->end < actual_size ? r->end : actual_size;
4090
+ int n_read = limit_r_end - limit_r_begin;
4081
4091
  int part_read = n_read / r->part_size;
4082
4092
  if (part_read > max_part_read)
4083
4093
  max_part_read = part_read;
@@ -4088,6 +4098,8 @@ static int start_decoder(vorb *f)
4088
4098
  classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *));
4089
4099
  #endif
4090
4100
 
4101
+ // maximum reasonable partition size is f->blocksize_1
4102
+
4091
4103
  f->temp_memory_required = classify_mem;
4092
4104
  if (imdct_mem > f->temp_memory_required)
4093
4105
  f->temp_memory_required = imdct_mem;
@@ -5351,6 +5363,8 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
5351
5363
  #endif // STB_VORBIS_NO_PULLDATA_API
5352
5364
 
5353
5365
  /* Version history
5366
+ 1.12 - 2017/11/21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
5367
+ 1.11 - 2017/07/23 - fix MinGW compilation
5354
5368
  1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
5355
5369
  1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version
5356
5370
  1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;