Browse Source

Merge commit 'b597fc956489b2fb3fc651986db0de0cc41cfc32'.

Yao Wei Tjong 姚伟忠 7 years ago
parent
commit
c2ca48c410

+ 28 - 0
Source/ThirdParty/STB/.github/CONTRIBUTING.md

@@ -0,0 +1,28 @@
+Pull Requests and Issues are both welcome.
+
+# Responsiveness
+
+General priority order is:
+
+* Crashes
+* Bugs
+* Warnings
+* Enhancements (new features, performance improvement, etc)
+
+Pull requests get priority over Issues. Some pull requests I take
+as written; some I modify myself; some I will request changes before
+accepting them. Because I've ended up supporting a lot of libraries
+(20 as I write this, with more on the way), I am somewhat slow to
+address things. Many issues have been around for a long time.
+
+# Pull requests
+
+* Do NOT update the version number in the file. (This just causes conflicts.)
+* Do add your name to the list of contributors. (Don't worry about the formatting.) I'll try to remember to add it if you don't, but I sometimes forget as it's an extra step.
+
+# Specific libraries
+
+I generally do not want new file formats for stb_image because
+we are trying to improve its security, so increasing its attack
+surface is counter-productive.
+

+ 6 - 0
Source/ThirdParty/STB/.github/PULL_REQUEST_TEMPLATE.md

@@ -0,0 +1,6 @@
+* Delete this list before clicking CREATE PULL REQUEST
+* Make sure you're using a special branch just for this pull request. (Sometimes people unknowingly use a default branch, then later update that branch, which updates the pull request with the other changes if it hasn't been merged yet.)
+* Do NOT update the version number in the file. (This just causes conflicts.)
+* Do add your name to the list of contributors. (Don't worry about the formatting.) I'll try to remember to add it if you don't, but I sometimes forget as it's an extra step.
+
+If you get something above wrong, don't fret it, it's not the end of the world.

+ 5 - 0
Source/ThirdParty/STB/.travis.yml

@@ -0,0 +1,5 @@
+language: C
+install: true
+script:
+  - cd tests
+  - make all

+ 55 - 29
Source/ThirdParty/STB/README.md

@@ -3,32 +3,37 @@
 stb
 stb
 ===
 ===
 
 
-single-file public domain libraries for C/C++ <a name="stb_libs"></a>
+single-file public domain (or MIT licensed) libraries for C/C++ <a name="stb_libs"></a>
+
+Most libraries by stb, except: stb_dxt by Fabian "ryg" Giesen, stb_image_resize
+by Jorge L. "VinoBS" Rodriguez, and stb_sprintf by Jeff Roberts.
+
 
 
 library    | lastest version | category | LoC | description
 library    | lastest version | category | LoC | description
 --------------------- | ---- | -------- | --- | --------------------------------
 --------------------- | ---- | -------- | --- | --------------------------------
-**stb_vorbis.c** | 1.09 | audio | 5397 | decode ogg vorbis files from file/memory to float/16-bit signed output
-**stb_image.h** | 2.12 | graphics | 6755 | image loading/decoding from file/memory: JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC
-**stb_truetype.h** | 1.11 | graphics | 3267 | parse, decode, and rasterize characters from truetype fonts
-**stb_image_write.h** | 1.02 | graphics | 1048 | image writing to disk: PNG, TGA, BMP
-**stb_image_resize.h** | 0.91 | graphics | 2578 | resize images larger/smaller with good quality
-**stb_rect_pack.h** | 0.08 | graphics | 572 | simple 2D rectangle packer with decent quality
-**stretchy_buffer.h** | 1.02 | utility | 216 | typesafe dynamic array for C (i.e. approximation to vector<>), doesn't compile as C++
-**stb_textedit.h** | 1.8 | user&nbsp;interface | 1304 | guts of a text editor for games etc implementing them from scratch
-**stb_voxel_render.h** | 0.84 | 3D&nbsp;graphics | 3752 | Minecraft-esque voxel rendering "engine" with many more features
-**stb_dxt.h** | 1.04 | 3D&nbsp;graphics | 630 | Fabian "ryg" Giesen's real-time DXT compressor
-**stb_perlin.h** | 0.2 | 3D&nbsp;graphics | 182 | revised Perlin noise (3D input, 1D output)
-**stb_easy_font.h** | 0.7 | 3D&nbsp;graphics | 258 | quick-and-dirty easy-to-deploy bitmap font for printing frame rate, etc
-**stb_tilemap_editor.h** | 0.37 | game&nbsp;dev | 4131 | embeddable tilemap editor
-**stb_herringbone_wa...** | 0.6 | game&nbsp;dev | 1220 | herringbone Wang tile map generator
-**stb_c_lexer.h** | 0.07 | parsing | 816 | simplify writing parsers for C-like languages
-**stb_divide.h** | 0.91 | math | 379 | more useful 32-bit modulus e.g. "euclidean divide"
-**stb_connected_comp...** | 0.94 | misc | 1000 | incrementally compute reachability on grids
-**stb.h** | 2.27 | misc | 14185 | helper functions for C, mostly redundant in C++; basically author's personal stuff
-**stb_leakcheck.h** | 0.2 | misc | 124 | quick-and-dirty malloc/free leak-checking
-
-Total libraries: 19  
-Total lines of C code: 47814
+**[stb_vorbis.c](stb_vorbis.c)** | 1.13b | audio | 5463 | decode ogg vorbis files from file/memory to float/16-bit signed output
+**[stb_image.h](stb_image.h)** | 2.18 | graphics | 7459 | image loading/decoding from file/memory: JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC
+**[stb_truetype.h](stb_truetype.h)** | 1.18 | graphics | 4589 | parse, decode, and rasterize characters from truetype fonts
+**[stb_image_write.h](stb_image_write.h)** | 1.08 | graphics | 1559 | image writing to disk: PNG, TGA, BMP
+**[stb_image_resize.h](stb_image_resize.h)** | 0.95 | graphics | 2627 | resize images larger/smaller with good quality
+**[stb_rect_pack.h](stb_rect_pack.h)** | 0.11 | graphics | 624 | simple 2D rectangle packer with decent quality
+**[stb_sprintf.h](stb_sprintf.h)** | 1.05 | utility | 1833 | fast sprintf, snprintf for C/C++
+**[stretchy_buffer.h](stretchy_buffer.h)** | 1.03 | utility | 262 | typesafe dynamic array for C (i.e. approximation to vector<>), doesn't compile as C++
+**[stb_textedit.h](stb_textedit.h)** | 1.12 | user&nbsp;interface | 1404 | guts of a text editor for games etc implementing them from scratch
+**[stb_voxel_render.h](stb_voxel_render.h)** | 0.85 | 3D&nbsp;graphics | 3803 | Minecraft-esque voxel rendering "engine" with many more features
+**[stb_dxt.h](stb_dxt.h)** | 1.08b | 3D&nbsp;graphics | 728 | Fabian "ryg" Giesen's real-time DXT compressor
+**[stb_perlin.h](stb_perlin.h)** | 0.3 | 3D&nbsp;graphics | 316 | revised Perlin noise (3D input, 1D output)
+**[stb_easy_font.h](stb_easy_font.h)** | 1.0 | 3D&nbsp;graphics | 303 | quick-and-dirty easy-to-deploy bitmap font for printing frame rate, etc
+**[stb_tilemap_editor.h](stb_tilemap_editor.h)** | 0.38 | game&nbsp;dev | 4172 | embeddable tilemap editor
+**[stb_herringbone_wa...](stb_herringbone_wang_tile.h)** | 0.6 | game&nbsp;dev | 1220 | herringbone Wang tile map generator
+**[stb_c_lexer.h](stb_c_lexer.h)** | 0.09 | parsing | 962 | simplify writing parsers for C-like languages
+**[stb_divide.h](stb_divide.h)** | 0.91 | math | 419 | more useful 32-bit modulus e.g. "euclidean divide"
+**[stb_connected_comp...](stb_connected_components.h)** | 0.95 | misc | 1045 | incrementally compute reachability on grids
+**[stb.h](stb.h)** | 2.31 | misc | 14405 | helper functions for C, mostly redundant in C++; basically author's personal stuff
+**[stb_leakcheck.h](stb_leakcheck.h)** | 0.4 | misc | 186 | quick-and-dirty malloc/free leak-checking
+
+Total libraries: 20  
+Total lines of C code: 53379
 
 
 
 
 FAQ
 FAQ
@@ -36,17 +41,38 @@ FAQ
 
 
 #### What's the license?
 #### What's the license?
 
 
-These libraries are in the public domain (or the equivalent where that is not
-possible). You can do anything you want with them. You have no legal obligation
+These libraries are in the public domain. You can do anything you
+want with them. You have no legal obligation
 to do anything else, although I appreciate attribution.
 to do anything else, although I appreciate attribution.
 
 
+They are also licensed under the MIT open source license, if you have lawyers
+who are unhappy with public domain. Every source file includes an explicit
+dual-license for you to choose from.
+
 #### <a name="other_libs"></a> Are there other single-file public-domain/open source libraries with minimal dependencies out there?
 #### <a name="other_libs"></a> Are there other single-file public-domain/open source libraries with minimal dependencies out there?
 
 
-[Yes.](https://github.com/nothings/stb/blob/master/docs/other_libs.md)
+[Yes.](https://github.com/nothings/single_file_libs)
+
+#### If I wrap an stb library in a new library, does the new library have to be public domain/MIT?
+
+No, because it's public domain you can freely relicense it to whatever license your new
+library wants to be.
+
+#### What's the deal with SSE support in GCC-based compilers?
 
 
-#### If I wrap an stb library in a new library, does the new library have to be public domain?
+stb_image will either use SSE2 (if you compile with -msse2) or
+will not use any SIMD at all, rather than trying to detect the
+processor at runtime and handle it correctly. As I understand it,
+the approved path in GCC for runtime-detection require
+you to use multiple source files, one for each CPU configuration.
+Because stb_image is a header-file library that compiles in only
+one source file, there's no approved way to build both an
+SSE-enabled and a non-SSE-enabled variation.
 
 
-No.
+While we've tried to work around it, we've had multiple issues over
+the years due to specific versions of gcc breaking what we're doing,
+so we've given up on it. See https://github.com/nothings/stb/issues/280
+and https://github.com/nothings/stb/issues/410 for examples.
 
 
 #### Some of these libraries seem redundant to existing open source libraries. Are they better somehow?
 #### Some of these libraries seem redundant to existing open source libraries. Are they better somehow?
 
 
@@ -56,7 +82,7 @@ attribution requirement). They may be less featureful, slower,
 and/or use more memory. If you're already using an equivalent
 and/or use more memory. If you're already using an equivalent
 library, there's probably no good reason to switch.
 library, there's probably no good reason to switch.
 
 
-###### Can I link directly to the table of stb libraries?
+#### Can I link directly to the table of stb libraries?
 
 
 You can use [this URL](https://github.com/nothings/stb#stb_libs) to link directly to that list.
 You can use [this URL](https://github.com/nothings/stb#stb_libs) to link directly to that list.
 
 

+ 1055 - 0
Source/ThirdParty/STB/deprecated/rrsprintf.h

@@ -0,0 +1,1055 @@
+#ifndef RR_SPRINTF_H_INCLUDE
+#define RR_SPRINTF_H_INCLUDE
+
+/*
+Single file sprintf replacement.
+
+Originally written by Jeff Roberts at RAD Game Tools - 2015/10/20. 
+Hereby placed in public domain.
+
+This is a full sprintf replacement that supports everything that
+the C runtime sprintfs support, including float/double, 64-bit integers,
+hex floats, field parameters (%*.*d stuff), length reads backs, etc.
+
+Why would you need this if sprintf already exists?  Well, first off,
+it's *much* faster (see below). It's also much smaller than the CRT
+versions code-space-wise. We've also added some simple improvements 
+that are super handy (commas in thousands, callbacks at buffer full,
+for example). Finally, the format strings for MSVC and GCC differ 
+for 64-bit integers (among other small things), so this lets you use 
+the same format strings in cross platform code.
+
+It uses the standard single file trick of being both the header file
+and the source itself. If you just include it normally, you just get 
+the header file function definitions. To get the code, you include
+it from a C or C++ file and define RR_SPRINTF_IMPLEMENTATION first.
+
+It only uses va_args macros from the C runtime to do it's work. It
+does cast doubles to S64s and shifts and divides U64s, which does 
+drag in CRT code on most platforms.
+
+It compiles to roughly 8K with float support, and 4K without.
+As a comparison, when using MSVC static libs, calling sprintf drags
+in 16K.
+
+API:
+====
+int rrsprintf( char * buf, char const * fmt, ... )
+int rrsnprintf( char * buf, int count, char const * fmt, ... )
+  Convert an arg list into a buffer.  rrsnprintf always returns
+  a zero-terminated string (unlike regular snprintf).
+
+int rrvsprintf( char * buf, char const * fmt, va_list va )
+int rrvsnprintf( char * buf, int count, char const * fmt, va_list va )
+  Convert a va_list arg list into a buffer.  rrvsnprintf always returns
+  a zero-terminated string (unlike regular snprintf).
+
+int rrvsprintfcb( RRSPRINTFCB * callback, void * user, char * buf, char const * fmt, va_list va )
+    typedef char * RRSPRINTFCB( char const * buf, void * user, int len );
+  Convert into a buffer, calling back every RR_SPRINTF_MIN chars.
+  Your callback can then copy the chars out, print them or whatever.
+  This function is actually the workhorse for everything else.
+  The buffer you pass in must hold at least RR_SPRINTF_MIN characters.
+    // you return the next buffer to use or 0 to stop converting
+
+void rrsetseparators( char comma, char period )
+  Set the comma and period characters to use.
+
+FLOATS/DOUBLES:
+===============
+This code uses a internal float->ascii conversion method that uses
+doubles with error correction (double-doubles, for ~105 bits of
+precision).  This conversion is round-trip perfect - that is, an atof
+of the values output here will give you the bit-exact double back.
+
+One difference is that our insignificant digits will be different than 
+with MSVC or GCC (but they don't match each other either).  We also 
+don't attempt to find the minimum length matching float (pre-MSVC15 
+doesn't either).
+
+If you don't need float or doubles at all, define RR_SPRINTF_NOFLOAT
+and you'll save 4K of code space.
+
+64-BIT INTS:
+============
+This library also supports 64-bit integers and you can use MSVC style or
+GCC style indicators (%I64d or %lld).  It supports the C99 specifiers
+for size_t and ptr_diff_t (%jd %zd) as well.
+
+EXTRAS:
+=======
+Like some GCCs, for integers and floats, you can use a ' (single quote)
+specifier and commas will be inserted on the thousands: "%'d" on 12345 
+would print 12,345.
+
+For integers and floats, you can use a "$" specifier and the number 
+will be converted to float and then divided to get kilo, mega, giga or
+tera and then printed, so "%$d" 1024 is "1.0 k", "%$.2d" 2536000 is 
+"2.42 m", etc.
+
+In addition to octal and hexadecimal conversions, you can print 
+integers in binary: "%b" for 256 would print 100.
+
+PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC):
+===================================================================
+"%d" across all 32-bit ints (4.8x/4.0x faster than 32-/64-bit MSVC)
+"%24d" across all 32-bit ints (4.5x/4.2x faster)
+"%x" across all 32-bit ints (4.5x/3.8x faster)
+"%08x" across all 32-bit ints (4.3x/3.8x faster)
+"%f" across e-10 to e+10 floats (7.3x/6.0x faster)
+"%e" across e-10 to e+10 floats (8.1x/6.0x faster)
+"%g" across e-10 to e+10 floats (10.0x/7.1x faster)
+"%f" for values near e-300 (7.9x/6.5x faster)
+"%f" for values near e+300 (10.0x/9.1x faster)
+"%e" for values near e-300 (10.1x/7.0x faster)
+"%e" for values near e+300 (9.2x/6.0x faster)
+"%.320f" for values near e-300 (12.6x/11.2x faster)
+"%a" for random values (8.6x/4.3x faster)
+"%I64d" for 64-bits with 32-bit values (4.8x/3.4x faster)
+"%I64d" for 64-bits > 32-bit values (4.9x/5.5x faster)
+"%s%s%s" for 64 char strings (7.1x/7.3x faster)
+"...512 char string..." ( 35.0x/32.5x faster!)
+*/
+
+#ifdef RR_SPRINTF_STATIC
+#define RRPUBLIC_DEC static
+#define RRPUBLIC_DEF static
+#else
+#ifdef __cplusplus
+#define RRPUBLIC_DEC extern "C"
+#define RRPUBLIC_DEF extern "C"
+#else
+#define RRPUBLIC_DEC extern 
+#define RRPUBLIC_DEF
+#endif
+#endif
+
+#include <stdarg.h>  // for va_list()
+
+#ifndef RR_SPRINTF_MIN
+#define RR_SPRINTF_MIN 512 // how many characters per callback
+#endif
+typedef char * RRSPRINTFCB( char * buf, void * user, int len );
+
+#ifndef RR_SPRINTF_DECORATE
+#define RR_SPRINTF_DECORATE(name) rr##name  // define this before including if you want to change the names
+#endif
+
+#ifndef RR_SPRINTF_IMPLEMENTATION
+
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( vsprintf )( char * buf, char const * fmt, va_list va );
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, char const * fmt, va_list va );
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( sprintf ) ( char * buf, char const * fmt, ... );
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( snprintf )( char * buf, int count, char const * fmt, ... );
+
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( vsprintfcb )( RRSPRINTFCB * callback, void * user, char * buf, char const * fmt, va_list va );
+RRPUBLIC_DEF void RR_SPRINTF_DECORATE( setseparators )( char comma, char period );
+
+#else
+
+#include <stdlib.h>  // for va_arg()
+
+#define rU32 unsigned int
+#define rS32 signed int
+
+#ifdef _MSC_VER
+#define rU64 unsigned __int64
+#define rS64 signed __int64
+#else
+#define rU64 unsigned long long
+#define rS64 signed long long
+#endif
+#define rU16 unsigned short
+
+#ifndef rUINTa 
+#if defined(__ppc64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64)
+#define rUINTa rU64
+#else
+#define rUINTa rU32
+#endif
+#endif
+
+#ifndef RR_SPRINTF_MSVC_MODE  // used for MSVC2013 and earlier (MSVC2015 matches GCC)
+#if defined(_MSC_VER) && (_MSC_VER<1900)
+#define RR_SPRINTF_MSVC_MODE
+#endif
+#endif
+
+#ifdef RR_SPRINTF_NOUNALIGNED  // define this before inclusion to force rrsprint to always use aligned accesses
+#define RR_UNALIGNED(code)
+#else
+#define RR_UNALIGNED(code) code
+#endif
+
+#ifndef RR_SPRINTF_NOFLOAT
+// internal float utility functions
+static rS32 rrreal_to_str( char const * * start, rU32 * len, char *out, rS32 * decimal_pos, double value, rU32 frac_digits );
+static rS32 rrreal_to_parts( rS64 * bits, rS32 * expo, double value );
+#define RRSPECIAL 0x7000
+#endif
+
+static char RRperiod='.';
+static char RRcomma=',';
+static char rrdiglookup[201]="00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899";
+
+RRPUBLIC_DEF void RR_SPRINTF_DECORATE( setseparators )( char pcomma, char pperiod )
+{
+  RRperiod=pperiod;
+  RRcomma=pcomma;
+}
+
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( vsprintfcb )( RRSPRINTFCB * callback, void * user, char * buf, char const * fmt, va_list va )
+{
+  static char hex[]="0123456789abcdefxp";
+  static char hexu[]="0123456789ABCDEFXP";
+  char * bf;
+  char const * f;
+  int tlen = 0;
+
+  bf = buf;
+  f = fmt;
+  for(;;)
+  {
+    rS32 fw,pr,tz; rU32 fl;
+
+    #define LJ 1
+    #define LP 2
+    #define LS 4
+    #define LX 8
+    #define LZ 16
+    #define BI 32
+    #define CS 64
+    #define NG 128
+    #define KI 256
+    #define HW 512
+ 
+    // macros for the callback buffer stuff
+    #define chk_cb_bufL(bytes) { int len = (int)(bf-buf); if ((len+(bytes))>=RR_SPRINTF_MIN) { tlen+=len; if (0==(bf=buf=callback(buf,user,len))) goto done; } }
+    #define chk_cb_buf(bytes) { if ( callback ) { chk_cb_bufL(bytes); } }
+    #define flush_cb() { chk_cb_bufL(RR_SPRINTF_MIN-1); } //flush if there is even one byte in the buffer
+    #define cb_buf_clamp(cl,v) cl = v; if ( callback ) { int lg = RR_SPRINTF_MIN-(int)(bf-buf); if (cl>lg) cl=lg; }
+
+    // fast copy everything up to the next % (or end of string)
+    for(;;)
+    { 
+      while (((rUINTa)f)&3)
+      {
+       schk1: if (f[0]=='%') goto scandd;
+       schk2: if (f[0]==0) goto endfmt;
+        chk_cb_buf(1); *bf++=f[0]; ++f;
+      } 
+      for(;;)
+      { 
+        rU32 v,c;
+        v=*(rU32*)f; c=(~v)&0x80808080;
+        if ((v-0x26262626)&c) goto schk1; 
+        if ((v-0x01010101)&c) goto schk2; 
+        if (callback) if ((RR_SPRINTF_MIN-(int)(bf-buf))<4) goto schk1;
+        *(rU32*)bf=v; bf+=4; f+=4;
+      }
+    } scandd:
+
+    ++f;
+
+    // ok, we have a percent, read the modifiers first
+    fw = 0; pr = -1; fl = 0; tz = 0;
+    
+    // flags
+    for(;;)
+    {
+      switch(f[0])
+      {
+        // if we have left just
+        case '-': fl|=LJ; ++f; continue;
+        // if we have leading plus
+        case '+': fl|=LP; ++f; continue; 
+        // if we have leading space
+        case ' ': fl|=LS; ++f; continue; 
+        // if we have leading 0x
+        case '#': fl|=LX; ++f; continue; 
+        // if we have thousand commas
+        case '\'': fl|=CS; ++f; continue; 
+        // if we have kilo marker
+        case '$': fl|=KI; ++f; continue; 
+        // if we have leading zero
+        case '0': fl|=LZ; ++f; goto flags_done; 
+        default: goto flags_done;
+      }
+    }
+    flags_done:
+   
+    // get the field width
+    if ( f[0] == '*' ) {fw = va_arg(va,rU32); ++f;} else { while (( f[0] >= '0' ) && ( f[0] <= '9' )) { fw = fw * 10 + f[0] - '0'; f++; } }
+    // get the precision
+    if ( f[0]=='.' ) { ++f; if ( f[0] == '*' ) {pr = va_arg(va,rU32); ++f;} else { pr = 0; while (( f[0] >= '0' ) && ( f[0] <= '9' )) { pr = pr * 10 + f[0] - '0'; f++; } } } 
+    
+    // handle integer size overrides
+    switch(f[0])
+    {
+      // are we halfwidth?
+      case 'h': fl|=HW; ++f; break;
+      // are we 64-bit (unix style)
+      case 'l': ++f; if ( f[0]=='l') { fl|=BI; ++f; } break;
+      // are we 64-bit on intmax? (c99)
+      case 'j': fl|=BI; ++f; break; 
+      // are we 64-bit on size_t or ptrdiff_t? (c99)
+      case 'z': case 't': fl|=((sizeof(char*)==8)?BI:0); ++f; break; 
+      // are we 64-bit (msft style)
+      case 'I': if ( ( f[1]=='6') && ( f[2]=='4') ) { fl|=BI; f+=3; } else if ( ( f[1]=='3') && ( f[2]=='2') ) { f+=3; } else { fl|=((sizeof(void*)==8)?BI:0); ++f; } break;
+      default: break;
+    }
+
+    // handle each replacement
+    switch( f[0] )
+    {
+      #define NUMSZ 512 // big enough for e308 (with commas) or e-307 
+      char num[NUMSZ]; 
+      char lead[8]; 
+      char tail[8]; 
+      char *s;
+      char const *h;
+      rU32 l,n,cs;
+      rU64 n64;
+      #ifndef RR_SPRINTF_NOFLOAT      
+      double fv; 
+      #endif
+      rS32 dp; char const * sn;
+
+      case 's':
+        // get the string
+        s = va_arg(va,char*); if (s==0) s = (char*)"null";
+        // get the length
+        sn = s;
+        for(;;)
+        { 
+          if ((((rUINTa)sn)&3)==0) break;
+         lchk:
+          if (sn[0]==0) goto ld;
+          ++sn;
+        }
+        n = 0xffffffff;
+        if (pr>=0) { n=(rU32)(sn-s); if (n>=(rU32)pr) goto ld; n=((rU32)(pr-n))>>2; }
+        while(n) 
+        { 
+          rU32 v=*(rU32*)sn;
+          if ((v-0x01010101)&(~v)&0x80808080UL) goto lchk; 
+          sn+=4; 
+          --n;
+        }
+        goto lchk;
+       ld:
+
+        l = (rU32) ( sn - s );
+        // clamp to precision
+        if ( l > (rU32)pr ) l = pr;
+        lead[0]=0; tail[0]=0; pr = 0; dp = 0; cs = 0;
+        // copy the string in
+        goto scopy;
+
+      case 'c': // char
+        // get the character
+        s = num + NUMSZ -1; *s = (char)va_arg(va,int);
+        l = 1;
+        lead[0]=0; tail[0]=0; pr = 0; dp = 0; cs = 0;
+        goto scopy;
+
+      case 'n': // weird write-bytes specifier
+        { int * d = va_arg(va,int*);
+        *d = tlen + (int)( bf - buf ); }
+        break;
+
+#ifdef RR_SPRINTF_NOFLOAT
+      case 'A': // float
+      case 'a': // hex float
+      case 'G': // float
+      case 'g': // float
+      case 'E': // float
+      case 'e': // float
+      case 'f': // float
+        va_arg(va,double); // eat it
+        s = (char*)"No float";
+        l = 8;
+        lead[0]=0; tail[0]=0; pr = 0; dp = 0; cs = 0;
+        goto scopy;
+#else
+      case 'A': // float
+        h=hexu;  
+        goto hexfloat;
+
+      case 'a': // hex float
+        h=hex;
+       hexfloat: 
+        fv = va_arg(va,double);
+        if (pr==-1) pr=6; // default is 6
+        // read the double into a string
+        if ( rrreal_to_parts( (rS64*)&n64, &dp, fv ) )
+          fl |= NG;
+  
+        s = num+64;
+
+        // sign
+        lead[0]=0; if (fl&NG) { lead[0]=1; lead[1]='-'; } else if (fl&LS) { lead[0]=1; lead[1]=' '; } else if (fl&LP) { lead[0]=1; lead[1]='+'; };
+
+        if (dp==-1023) dp=(n64)?-1022:0; else n64|=(((rU64)1)<<52);
+        n64<<=(64-56);
+        if (pr<15) n64+=((((rU64)8)<<56)>>(pr*4));
+        // add leading chars
+        
+        #ifdef RR_SPRINTF_MSVC_MODE
+        *s++='0';*s++='x';
+        #else
+        lead[1+lead[0]]='0'; lead[2+lead[0]]='x'; lead[0]+=2;
+        #endif
+        *s++=h[(n64>>60)&15]; n64<<=4;
+        if ( pr ) *s++=RRperiod;
+        sn = s;
+
+        // print the bits
+        n = pr; if (n>13) n = 13; if (pr>(rS32)n) tz=pr-n; pr = 0;
+        while(n--) { *s++=h[(n64>>60)&15]; n64<<=4; }
+
+        // print the expo
+        tail[1]=h[17];
+        if (dp<0) { tail[2]='-'; dp=-dp;} else tail[2]='+';
+        n = (dp>=1000)?6:((dp>=100)?5:((dp>=10)?4:3));
+        tail[0]=(char)n;
+        for(;;) { tail[n]='0'+dp%10; if (n<=3) break; --n; dp/=10; }
+
+        dp = (int)(s-sn);
+        l = (int)(s-(num+64));
+        s = num+64;
+        cs = 1 + (3<<24);
+        goto scopy;
+
+      case 'G': // float
+        h=hexu;
+        goto dosmallfloat;
+
+      case 'g': // float
+        h=hex;
+       dosmallfloat:   
+        fv = va_arg(va,double);
+        if (pr==-1) pr=6; else if (pr==0) pr = 1; // default is 6
+        // read the double into a string
+        if ( rrreal_to_str( &sn, &l, num, &dp, fv, (pr-1)|0x80000000 ) )
+          fl |= NG;
+
+        // clamp the precision and delete extra zeros after clamp
+        n = pr;
+        if ( l > (rU32)pr ) l = pr; while ((l>1)&&(pr)&&(sn[l-1]=='0')) { --pr; --l; }
+
+        // should we use %e
+        if ((dp<=-4)||(dp>(rS32)n))
+        {
+          if ( pr > (rS32)l ) pr = l-1; else if ( pr ) --pr; // when using %e, there is one digit before the decimal
+          goto doexpfromg;
+        }
+        // this is the insane action to get the pr to match %g sematics for %f
+        if(dp>0) { pr=(dp<(rS32)l)?l-dp:0; } else { pr = -dp+((pr>(rS32)l)?l:pr); }
+        goto dofloatfromg;
+
+      case 'E': // float
+        h=hexu;  
+        goto doexp;
+
+      case 'e': // float
+        h=hex;
+       doexp:   
+        fv = va_arg(va,double);
+        if (pr==-1) pr=6; // default is 6
+        // read the double into a string
+        if ( rrreal_to_str( &sn, &l, num, &dp, fv, pr|0x80000000 ) )
+          fl |= NG;
+       doexpfromg: 
+        tail[0]=0; 
+        lead[0]=0; if (fl&NG) { lead[0]=1; lead[1]='-'; } else if (fl&LS) { lead[0]=1; lead[1]=' '; } else if (fl&LP) { lead[0]=1; lead[1]='+'; };
+        if ( dp == RRSPECIAL ) { s=(char*)sn; cs=0; pr=0; goto scopy; }
+        s=num+64; 
+        // handle leading chars
+        *s++=sn[0];
+
+        if (pr) *s++=RRperiod;
+
+        // handle after decimal
+        if ((l-1)>(rU32)pr) l=pr+1;
+        for(n=1;n<l;n++) *s++=sn[n];
+        // trailing zeros
+        tz = pr-(l-1); pr=0;
+        // dump expo
+        tail[1]=h[0xe];
+        dp -= 1;
+        if (dp<0) { tail[2]='-'; dp=-dp;} else tail[2]='+';
+        #ifdef RR_SPRINTF_MSVC_MODE
+        n = 5;
+        #else
+        n = (dp>=100)?5:4;
+        #endif
+        tail[0]=(char)n;
+        for(;;) { tail[n]='0'+dp%10; if (n<=3) break; --n; dp/=10; }
+        cs = 1 + (3<<24); // how many tens
+        goto flt_lead;   
+
+      case 'f': // float
+        fv = va_arg(va,double);
+       doafloat: 
+        // do kilos
+        if (fl&KI) {while(fl<0x4000000) { if ((fv<1024.0) && (fv>-1024.0)) break; fv/=1024.0; fl+=0x1000000; }} 
+        if (pr==-1) pr=6; // default is 6
+        // read the double into a string
+        if ( rrreal_to_str( &sn, &l, num, &dp, fv, pr ) )
+          fl |= NG;
+        dofloatfromg:
+        tail[0]=0;
+        // sign
+        lead[0]=0; if (fl&NG) { lead[0]=1; lead[1]='-'; } else if (fl&LS) { lead[0]=1; lead[1]=' '; } else if (fl&LP) { lead[0]=1; lead[1]='+'; };
+        if ( dp == RRSPECIAL ) { s=(char*)sn; cs=0; pr=0; goto scopy; }
+        s=num+64; 
+
+        // handle the three decimal varieties
+        if (dp<=0) 
+        { 
+          rS32 i;
+          // handle 0.000*000xxxx
+          *s++='0'; if (pr) *s++=RRperiod; 
+          n=-dp; if((rS32)n>pr) n=pr; i=n; while(i) { if ((((rUINTa)s)&3)==0) break; *s++='0'; --i; } while(i>=4) { *(rU32*)s=0x30303030; s+=4; i-=4; } while(i) { *s++='0'; --i; }
+          if ((rS32)(l+n)>pr) l=pr-n; i=l; while(i) { *s++=*sn++; --i; }
+          tz = pr-(n+l);
+          cs = 1 + (3<<24); // how many tens did we write (for commas below)
+        }
+        else
+        {
+          cs = (fl&CS)?((600-(rU32)dp)%3):0;
+          if ((rU32)dp>=l)
+          {
+            // handle xxxx000*000.0
+            n=0; for(;;) { if ((fl&CS) && (++cs==4)) { cs = 0; *s++=RRcomma; } else { *s++=sn[n]; ++n; if (n>=l) break; } }
+            if (n<(rU32)dp)
+            {
+              n = dp - n;
+              if ((fl&CS)==0) { while(n) { if ((((rUINTa)s)&3)==0) break; *s++='0'; --n; }  while(n>=4) { *(rU32*)s=0x30303030; s+=4; n-=4; } }
+              while(n) { if ((fl&CS) && (++cs==4)) { cs = 0; *s++=RRcomma; } else { *s++='0'; --n; } }
+            }
+            cs = (int)(s-(num+64)) + (3<<24); // cs is how many tens
+            if (pr) { *s++=RRperiod; tz=pr;}
+          }
+          else
+          {
+            // handle xxxxx.xxxx000*000
+            n=0; for(;;) { if ((fl&CS) && (++cs==4)) { cs = 0; *s++=RRcomma; } else { *s++=sn[n]; ++n; if (n>=(rU32)dp) break; } }
+            cs = (int)(s-(num+64)) + (3<<24); // cs is how many tens
+            if (pr) *s++=RRperiod;
+            if ((l-dp)>(rU32)pr) l=pr+dp;
+            while(n<l) { *s++=sn[n]; ++n; }
+            tz = pr-(l-dp);
+          }
+        }
+        pr = 0;
+        
+        // handle k,m,g,t
+        if (fl&KI) { tail[0]=1; tail[1]=' '; { if (fl>>24) { tail[2]="_kmgt"[fl>>24]; tail[0]=2; } } };
+
+        flt_lead:
+        // get the length that we copied
+        l = (rU32) ( s-(num+64) );
+        s=num+64; 
+        goto scopy;
+#endif
+
+      case 'B': // upper binary
+        h = hexu;
+        goto binary;
+
+      case 'b': // lower binary
+        h = hex;
+        binary:
+        lead[0]=0;
+        if (fl&LX) { lead[0]=2;lead[1]='0';lead[2]=h[0xb]; }
+        l=(8<<4)|(1<<8);
+        goto radixnum;
+
+      case 'o': // octal
+        h = hexu;
+        lead[0]=0;
+        if (fl&LX) { lead[0]=1;lead[1]='0'; }
+        l=(3<<4)|(3<<8);
+        goto radixnum;
+
+      case 'p': // pointer
+        fl |= (sizeof(void*)==8)?BI:0;
+        pr = sizeof(void*)*2;
+        fl &= ~LZ; // 'p' only prints the pointer with zeros
+        // drop through to X
+      
+      case 'X': // upper binary
+        h = hexu;
+        goto dohexb;
+
+      case 'x': // lower binary
+        h = hex; dohexb:
+        l=(4<<4)|(4<<8);
+        lead[0]=0;
+        if (fl&LX) { lead[0]=2;lead[1]='0';lead[2]=h[16]; }
+       radixnum: 
+        // get the number
+        if ( fl&BI )
+          n64 = va_arg(va,rU64);
+        else
+          n64 = va_arg(va,rU32);
+
+        s = num + NUMSZ; dp = 0;
+        // clear tail, and clear leading if value is zero
+        tail[0]=0; if (n64==0) { lead[0]=0; if (pr==0) { l=0; cs = ( ((l>>4)&15)) << 24; goto scopy; } }
+        // convert to string
+        for(;;) { *--s = h[n64&((1<<(l>>8))-1)]; n64>>=(l>>8); if ( ! ( (n64) || ((rS32) ( (num+NUMSZ) - s ) < pr ) ) ) break; if ( fl&CS) { ++l; if ((l&15)==((l>>4)&15)) { l&=~15; *--s=RRcomma; } } };
+        // get the tens and the comma pos
+        cs = (rU32) ( (num+NUMSZ) - s ) + ( ( ((l>>4)&15)) << 24 );
+        // get the length that we copied
+        l = (rU32) ( (num+NUMSZ) - s );
+        // copy it
+        goto scopy;
+
+      case 'u': // unsigned
+      case 'i':
+      case 'd': // integer
+        // get the integer and abs it
+        if ( fl&BI )
+        {
+          rS64 i64 = va_arg(va,rS64); n64 = (rU64)i64; if ((f[0]!='u') && (i64<0)) { n64=(rU64)-i64; fl|=NG; }
+        }
+        else
+        {
+          rS32 i = va_arg(va,rS32); n64 = (rU32)i; if ((f[0]!='u') && (i<0)) { n64=(rU32)-i; fl|=NG; }
+        }
+
+        #ifndef RR_SPRINTF_NOFLOAT
+        if (fl&KI) { if (n64<1024) pr=0; else if (pr==-1) pr=1; fv=(double)(rS64)n64; goto doafloat; } 
+        #endif
+
+        // convert to string
+        s = num+NUMSZ; l=0; 
+        
+        for(;;)
+        {
+          // do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators)
+          char * o=s-8;
+          if (n64>=100000000) { n = (rU32)( n64 % 100000000);  n64 /= 100000000; } else {n = (rU32)n64; n64 = 0; }
+          if((fl&CS)==0) { while(n) { s-=2; *(rU16*)s=*(rU16*)&rrdiglookup[(n%100)*2]; n/=100; } }
+          while (n) { if ( ( fl&CS) && (l++==3) ) { l=0; *--s=RRcomma; --o; } else { *--s=(char)(n%10)+'0'; n/=10; } }
+          if (n64==0) { if ((s[0]=='0') && (s!=(num+NUMSZ))) ++s; break; }
+          while (s!=o) if ( ( fl&CS) && (l++==3) ) { l=0; *--s=RRcomma; --o; } else { *--s='0'; }
+        }
+
+        tail[0]=0;
+        // sign
+        lead[0]=0; if (fl&NG) { lead[0]=1; lead[1]='-'; } else if (fl&LS) { lead[0]=1; lead[1]=' '; } else if (fl&LP) { lead[0]=1; lead[1]='+'; };
+
+        // get the length that we copied
+        l = (rU32) ( (num+NUMSZ) - s ); if ( l == 0 ) { *--s='0'; l = 1; }
+        cs = l + (3<<24);
+        if (pr<0) pr = 0;
+
+       scopy: 
+        // get fw=leading/trailing space, pr=leading zeros
+        if (pr<(rS32)l) pr = l;
+        n = pr + lead[0] + tail[0] + tz;
+        if (fw<(rS32)n) fw = n;
+        fw -= n;
+        pr -= l;
+
+        // handle right justify and leading zeros
+        if ( (fl&LJ)==0 )
+        {
+          if (fl&LZ) // if leading zeros, everything is in pr
+          { 
+            pr = (fw>pr)?fw:pr;
+            fw = 0;
+          }
+          else
+          {
+            fl &= ~CS; // if no leading zeros, then no commas
+          }
+        }
+
+        // copy the spaces and/or zeros
+        if (fw+pr)
+        {
+          rS32 i; rU32 c; 
+
+          // copy leading spaces (or when doing %8.4d stuff)
+          if ( (fl&LJ)==0 ) while(fw>0) { cb_buf_clamp(i,fw); fw -= i; while(i) { if ((((rUINTa)bf)&3)==0) break; *bf++=' '; --i; } while(i>=4) { *(rU32*)bf=0x20202020; bf+=4; i-=4; } while (i) {*bf++=' '; --i;} chk_cb_buf(1); }
+        
+          // copy leader
+          sn=lead+1; while(lead[0]) { cb_buf_clamp(i,lead[0]); lead[0] -= (char)i; while (i) {*bf++=*sn++; --i;} chk_cb_buf(1); }
+          
+          // copy leading zeros
+          c = cs >> 24; cs &= 0xffffff;
+          cs = (fl&CS)?((rU32)(c-((pr+cs)%(c+1)))):0;
+          while(pr>0) { cb_buf_clamp(i,pr); pr -= i; if((fl&CS)==0) { while(i) { if ((((rUINTa)bf)&3)==0) break; *bf++='0'; --i; } while(i>=4) { *(rU32*)bf=0x30303030; bf+=4; i-=4; } } while (i) { if((fl&CS) && (cs++==c)) { cs = 0; *bf++=RRcomma; } else *bf++='0'; --i; } chk_cb_buf(1); }
+        }
+
+        // copy leader if there is still one
+        sn=lead+1; while(lead[0]) { rS32 i; cb_buf_clamp(i,lead[0]); lead[0] -= (char)i; while (i) {*bf++=*sn++; --i;} chk_cb_buf(1); }
+
+        // copy the string
+        n = l; while (n) { rS32 i; cb_buf_clamp(i,n); n-=i; RR_UNALIGNED( while(i>=4) { *(rU32*)bf=*(rU32*)s; bf+=4; s+=4; i-=4; } ) while (i) {*bf++=*s++; --i;} chk_cb_buf(1); }
+
+        // copy trailing zeros
+        while(tz) { rS32 i; cb_buf_clamp(i,tz); tz -= i; while(i) { if ((((rUINTa)bf)&3)==0) break; *bf++='0'; --i; } while(i>=4) { *(rU32*)bf=0x30303030; bf+=4; i-=4; } while (i) {*bf++='0'; --i;} chk_cb_buf(1); }
+
+        // copy tail if there is one
+        sn=tail+1; while(tail[0]) { rS32 i; cb_buf_clamp(i,tail[0]); tail[0] -= (char)i; while (i) {*bf++=*sn++; --i;} chk_cb_buf(1); }
+
+        // handle the left justify
+        if (fl&LJ) if (fw>0) { while (fw) { rS32 i; cb_buf_clamp(i,fw); fw-=i; while(i) { if ((((rUINTa)bf)&3)==0) break; *bf++=' '; --i; } while(i>=4) { *(rU32*)bf=0x20202020; bf+=4; i-=4; } while (i--) *bf++=' '; chk_cb_buf(1); } }
+        break;
+
+      default: // unknown, just copy code
+        s = num + NUMSZ -1; *s = f[0];
+        l = 1;
+        fw=pr=fl=0;
+        lead[0]=0; tail[0]=0; pr = 0; dp = 0; cs = 0;
+        goto scopy;
+    }
+    ++f;
+  }
+ endfmt:
+
+  if (!callback) 
+    *bf = 0;
+  else
+    flush_cb();
+ 
+ done:
+  return tlen + (int)(bf-buf);
+}
+
+// cleanup
+#undef LJ
+#undef LP
+#undef LS
+#undef LX
+#undef LZ
+#undef BI
+#undef CS
+#undef NG
+#undef KI
+#undef NUMSZ
+#undef chk_cb_bufL
+#undef chk_cb_buf
+#undef flush_cb
+#undef cb_buf_clamp
+
+// ============================================================================
+//   wrapper functions
+
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( sprintf )( char * buf, char const * fmt, ... )
+{
+  va_list va;
+  va_start( va, fmt );
+  return RR_SPRINTF_DECORATE( vsprintfcb )( 0, 0, buf, fmt, va );
+}
+
+typedef struct RRCCS
+{
+  char * buf;
+  int count;
+  char tmp[ RR_SPRINTF_MIN ];
+} RRCCS;
+
+static char * rrclampcallback( char * buf, void * user, int len )
+{
+  RRCCS * c = (RRCCS*)user;
+
+  if ( len > c->count ) len = c->count;
+
+  if (len)
+  {
+    if ( buf != c->buf )
+    {
+      char * s, * d, * se;
+      d = c->buf; s = buf; se = buf+len;
+      do{ *d++ = *s++; } while (s<se);
+    }
+    c->buf += len;
+    c->count -= len;
+  }
+  
+  if ( c->count <= 0 ) return 0;
+  return ( c->count >= RR_SPRINTF_MIN ) ? c->buf : c->tmp; // go direct into buffer if you can
+}
+
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, char const * fmt, va_list va )
+{
+  RRCCS c;
+  int l;
+
+  if ( count == 0 )
+    return 0;
+
+  c.buf = buf;
+  c.count = count;
+
+  RR_SPRINTF_DECORATE( vsprintfcb )( rrclampcallback, &c, rrclampcallback(0,&c,0), fmt, va );
+  
+  // zero-terminate
+  l = (int)( c.buf - buf );
+  if ( l >= count ) // should never be greater, only equal (or less) than count
+    l = count - 1;
+  buf[l] = 0;
+
+  return l;
+}
+
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( snprintf )( char * buf, int count, char const * fmt, ... )
+{
+  va_list va;
+  va_start( va, fmt );
+
+  return RR_SPRINTF_DECORATE( vsnprintf )( buf, count, fmt, va );
+}
+
+RRPUBLIC_DEF int RR_SPRINTF_DECORATE( vsprintf )( char * buf, char const * fmt, va_list va )
+{
+  return RR_SPRINTF_DECORATE( vsprintfcb )( 0, 0, buf, fmt, va );
+}
+
+// =======================================================================
+//   low level float utility functions
+
+#ifndef RR_SPRINTF_NOFLOAT
+
+ // copies d to bits w/ strict aliasing (this compiles to nothing on /Ox)
+ #define RRCOPYFP(dest,src) { int cn; for(cn=0;cn<8;cn++) ((char*)&dest)[cn]=((char*)&src)[cn]; }
+ 
+// get float info
+static rS32 rrreal_to_parts( rS64 * bits, rS32 * expo, double value )
+{
+  double d;
+  rS64 b = 0;
+
+  // load value and round at the frac_digits
+  d = value;
+
+  RRCOPYFP( b, d );
+
+  *bits = b & ((((rU64)1)<<52)-1);
+  *expo = ((b >> 52) & 2047)-1023;
+    
+  return (rS32)(b >> 63);
+}
+
+static double const rrbot[23]={1e+000,1e+001,1e+002,1e+003,1e+004,1e+005,1e+006,1e+007,1e+008,1e+009,1e+010,1e+011,1e+012,1e+013,1e+014,1e+015,1e+016,1e+017,1e+018,1e+019,1e+020,1e+021,1e+022};
+static double const rrnegbot[22]={1e-001,1e-002,1e-003,1e-004,1e-005,1e-006,1e-007,1e-008,1e-009,1e-010,1e-011,1e-012,1e-013,1e-014,1e-015,1e-016,1e-017,1e-018,1e-019,1e-020,1e-021,1e-022};
+static double const rrnegboterr[22]={-5.551115123125783e-018,-2.0816681711721684e-019,-2.0816681711721686e-020,-4.7921736023859299e-021,-8.1803053914031305e-022,4.5251888174113741e-023,4.5251888174113739e-024,-2.0922560830128471e-025,-6.2281591457779853e-026,-3.6432197315497743e-027,6.0503030718060191e-028,2.0113352370744385e-029,-3.0373745563400371e-030,1.1806906454401013e-032,-7.7705399876661076e-032,2.0902213275965398e-033,-7.1542424054621921e-034,-7.1542424054621926e-035,2.4754073164739869e-036,5.4846728545790429e-037,9.2462547772103625e-038,-4.8596774326570872e-039};
+static double const rrtop[13]={1e+023,1e+046,1e+069,1e+092,1e+115,1e+138,1e+161,1e+184,1e+207,1e+230,1e+253,1e+276,1e+299};
+static double const rrnegtop[13]={1e-023,1e-046,1e-069,1e-092,1e-115,1e-138,1e-161,1e-184,1e-207,1e-230,1e-253,1e-276,1e-299};
+static double const rrtoperr[13]={8388608,6.8601809640529717e+028,-7.253143638152921e+052,-4.3377296974619174e+075,-1.5559416129466825e+098,-3.2841562489204913e+121,-3.7745893248228135e+144,-1.7356668416969134e+167,-3.8893577551088374e+190,-9.9566444326005119e+213,6.3641293062232429e+236,-5.2069140800249813e+259,-5.2504760255204387e+282};
+static double const rrnegtoperr[13]={3.9565301985100693e-040,-2.299904345391321e-063,3.6506201437945798e-086,1.1875228833981544e-109,-5.0644902316928607e-132,-6.7156837247865426e-155,-2.812077463003139e-178,-5.7778912386589953e-201,7.4997100559334532e-224,-4.6439668915134491e-247,-6.3691100762962136e-270,-9.436808465446358e-293,8.0970921678014997e-317};
+
+#if defined(_MSC_VER) && (_MSC_VER<=1200)                                                                                                                                                                                       
+static rU64 const rrpot[20]={1,10,100,1000, 10000,100000,1000000,10000000, 100000000,1000000000,10000000000,100000000000,  1000000000000,10000000000000,100000000000000,1000000000000000,  10000000000000000,100000000000000000,1000000000000000000,10000000000000000000U };
+#define rrtento19th ((rU64)1000000000000000000)
+#else
+static rU64 const rrpot[20]={1,10,100,1000, 10000,100000,1000000,10000000, 100000000,1000000000,10000000000ULL,100000000000ULL,  1000000000000ULL,10000000000000ULL,100000000000000ULL,1000000000000000ULL,  10000000000000000ULL,100000000000000000ULL,1000000000000000000ULL,10000000000000000000ULL };
+#define rrtento19th (1000000000000000000ULL)
+#endif
+
+#define rrddmulthi(oh,ol,xh,yh) \
+{ \
+  double ahi=0,alo,bhi=0,blo; \
+  rS64 bt; \
+  oh = xh * yh; \
+  RRCOPYFP(bt,xh); bt&=((~(rU64)0)<<27); RRCOPYFP(ahi,bt); alo = xh-ahi; \
+  RRCOPYFP(bt,yh); bt&=((~(rU64)0)<<27); RRCOPYFP(bhi,bt); blo = yh-bhi; \
+  ol = ((ahi*bhi-oh)+ahi*blo+alo*bhi)+alo*blo; \
+}
+
+#define rrddtoS64(ob,xh,xl) \
+{ \
+  double ahi=0,alo,vh,t;\
+  ob = (rS64)ph;\
+  vh=(double)ob;\
+  ahi = ( xh - vh );\
+  t = ( ahi - xh );\
+  alo = (xh-(ahi-t))-(vh+t);\
+  ob += (rS64)(ahi+alo+xl);\
+}
+
+
+#define rrddrenorm(oh,ol) { double s; s=oh+ol; ol=ol-(s-oh); oh=s; }
+
+#define rrddmultlo(oh,ol,xh,xl,yh,yl) \
+  ol = ol + ( xh*yl + xl*yh ); \
+
+#define rrddmultlos(oh,ol,xh,yl) \
+  ol = ol + ( xh*yl ); \
+
+static void rrraise_to_power10( double *ohi, double *olo, double d, rS32 power )  // power can be -323 to +350
+{
+  double ph, pl;
+  if ((power>=0) && (power<=22))
+  {
+    rrddmulthi(ph,pl,d,rrbot[power]);
+  }
+  else
+  {
+    rS32 e,et,eb;
+    double p2h,p2l;
+
+    e=power; if (power<0) e=-e; 
+    et = (e*0x2c9)>>14;/* %23 */ if (et>13) et=13; eb = e-(et*23);
+
+    ph = d; pl = 0.0;
+    if (power<0)
+    {
+      if (eb) { --eb; rrddmulthi(ph,pl,d,rrnegbot[eb]); rrddmultlos(ph,pl,d,rrnegboterr[eb]); }
+      if (et)
+      { 
+        rrddrenorm(ph,pl);
+        --et; rrddmulthi(p2h,p2l,ph,rrnegtop[et]); rrddmultlo(p2h,p2l,ph,pl,rrnegtop[et],rrnegtoperr[et]); ph=p2h;pl=p2l;
+      }
+    }
+    else
+    {
+      if (eb) 
+      { 
+        e = eb; if (eb>22) eb=22; e -= eb;
+        rrddmulthi(ph,pl,d,rrbot[eb]); 
+        if ( e ) { rrddrenorm(ph,pl); rrddmulthi(p2h,p2l,ph,rrbot[e]); rrddmultlos(p2h,p2l,rrbot[e],pl); ph=p2h;pl=p2l; }
+      }
+      if (et)
+      {
+        rrddrenorm(ph,pl);
+        --et; rrddmulthi(p2h,p2l,ph,rrtop[et]); rrddmultlo(p2h,p2l,ph,pl,rrtop[et],rrtoperr[et]); ph=p2h;pl=p2l;
+      }
+    }
+  }
+  rrddrenorm(ph,pl);
+  *ohi = ph; *olo = pl;
+}
+
+// given a float value, returns the significant bits in bits, and the position of the
+//   decimal point in decimal_pos.  +/-INF and NAN are specified by special values
+//   returned in the decimal_pos parameter.
+// frac_digits is absolute normally, but if you want from first significant digits (got %g and %e), or in 0x80000000
+static rS32 rrreal_to_str( char const * * start, rU32 * len, char *out, rS32 * decimal_pos, double value, rU32 frac_digits )
+{
+  double d;
+  rS64 bits = 0;
+  rS32 expo, e, ng, tens;
+
+  d = value;
+  RRCOPYFP(bits,d);
+  expo = (bits >> 52) & 2047;
+  ng = (rS32)(bits >> 63);
+  if (ng) d=-d;
+
+  if ( expo == 2047 ) // is nan or inf?
+  {
+    *start = (bits&((((rU64)1)<<52)-1)) ? "NaN" : "Inf";
+    *decimal_pos =  RRSPECIAL;
+    *len = 3;
+    return ng;
+  } 
+
+  if ( expo == 0 ) // is zero or denormal
+  {
+    if ((bits<<1)==0) // do zero
+    {
+      *decimal_pos = 1; 
+      *start = out;
+      out[0] = '0'; *len = 1;
+      return ng;
+    }
+    // find the right expo for denormals
+    {
+      rS64 v = ((rU64)1)<<51;
+      while ((bits&v)==0) { --expo; v >>= 1; }
+    }
+  }
+
+  // find the decimal exponent as well as the decimal bits of the value
+  {
+    double ph,pl;
+
+    // log10 estimate - very specifically tweaked to hit or undershoot by no more than 1 of log10 of all expos 1..2046
+    tens=expo-1023; tens = (tens<0)?((tens*617)/2048):(((tens*1233)/4096)+1);
+
+    // move the significant bits into position and stick them into an int 
+    rrraise_to_power10( &ph, &pl, d, 18-tens );
+
+    // get full as much precision from double-double as possible
+    rrddtoS64( bits, ph,pl );
+
+    // check if we undershot
+    if ( ((rU64)bits) >= rrtento19th ) ++tens; 
+  }
+
+  // now do the rounding in integer land
+  frac_digits = ( frac_digits & 0x80000000 ) ? ( (frac_digits&0x7ffffff) + 1 ) : ( tens + frac_digits );
+  if ( ( frac_digits < 24 ) )
+  {
+    rU32 dg = 1; if ((rU64)bits >= rrpot[9] ) dg=10; while( (rU64)bits >= rrpot[dg] ) { ++dg; if (dg==20) goto noround; }
+    if ( frac_digits < dg )
+    {
+      rU64 r;
+      // add 0.5 at the right position and round
+      e = dg - frac_digits;
+      if ( (rU32)e >= 24 ) goto noround;
+      r = rrpot[e];
+      bits = bits + (r/2);
+      if ( (rU64)bits >= rrpot[dg] ) ++tens;
+      bits /= r;
+    } 
+    noround:;
+  }
+
+  // kill long trailing runs of zeros
+  if ( bits )
+  {
+    rU32 n; for(;;) { if ( bits<=0xffffffff ) break; if (bits%1000) goto donez; bits/=1000; } n = (rU32)bits; while ((n%1000)==0) n/=1000; bits=n; donez:;
+  }
+
+  // convert to string
+  out += 64;
+  e = 0; 
+  for(;;)
+  {
+    rU32 n;
+    char * o = out-8;
+    // do the conversion in chunks of U32s (avoid most 64-bit divides, worth it, constant denomiators be damned)
+    if (bits>=100000000) { n = (rU32)( bits % 100000000);  bits /= 100000000; } else {n = (rU32)bits; bits = 0; }
+    while(n) { out-=2; *(rU16*)out=*(rU16*)&rrdiglookup[(n%100)*2]; n/=100; e+=2; }
+    if (bits==0) { if ((e) && (out[0]=='0')) { ++out; --e; } break; }
+    while( out!=o ) { *--out ='0'; ++e; }
+  }
+  
+  *decimal_pos = tens;
+  *start = out;
+  *len = e;
+  return ng;
+}
+
+#undef rrddmulthi
+#undef rrddrenorm
+#undef rrddmultlo
+#undef rrddmultlos
+#undef RRSPECIAL 
+#undef RRCOPYFP
+ 
+#endif
+
+// clean up
+#undef rU16
+#undef rU32 
+#undef rS32 
+#undef rU64
+#undef rS64
+#undef RRPUBLIC_DEC
+#undef RRPUBLIC_DEF
+#undef RR_SPRINTF_DECORATE
+#undef RR_UNALIGNED
+
+#endif
+
+#endif

+ 0 - 26
Source/ThirdParty/STB/release_notes.md

@@ -1,26 +0,0 @@
-----
-
-2016-04-02:
-
-- other_libs: cro_mipmap, greatest, munit, parg, dr_flac
-- stb_image_write: allocate large structures on stack for embedded (Thatcher Ulrich)
-- stb_image: allocate large structures on stack for embedded (Thatcher Ulrich)
-- stb_image: remove white matting for transparent PSD (stb, Oriol Ferrer Mesia)
-- stb_image: fix reported channel count in PNG when req_comp is non-zero
-- stb_image: re-enable SSE2 in x64 (except in gcc)
-- stb_image: fix harmless typo in name (Matthew Gregan)
-- stb_image: support JPEG images coded as RGB
-- stb_image: bmp could return wrong channel count (snagar@github)
-- stb_image: read 16-bit PNGs as 8-bit (socks-the-fox)
-- stb_image_resize: fix handling of subpixel regions
-- stb_image_resize: avoid warnings on asserts (Wu Shuang)
-- stb_truetype: allow fabs() to be supplied by user (Simon Glass)
-- stb_truetype: duplicate typedef
-- stb_truetype: don't leak memory if fontsize=0
-- stb_vorbis: warnings (Thiago Goulart)
-- stb_vorbis: fix multiple memory leaks of setup-memory (manxorist@github)
-- stb_vorbis: avoid dropping final frame of audio data
-- stb_textedit: better support for keying while holding mouse drag button (ocornut)
-- stb_voxel_render: fix type of glModelview matrix (Stephen Olsen)
-- stb_leakcheck: typo in comment (Lukas Meller)
-- stb.h: fix _WIN32 when defining STB_THREADS

File diff suppressed because it is too large
+ 440 - 263
Source/ThirdParty/STB/stb_image.h


+ 181 - 74
Source/ThirdParty/STB/stb_image_write.h

@@ -1,4 +1,4 @@
-/* stb_image_write - v1.07 - public domain - http://nothings.org/stb/stb_image_write.h
+/* stb_image_write - v1.08 - public domain - http://nothings.org/stb/stb_image_write.h
    writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
    writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
                                      no warranty implied; use at your own risk
                                      no warranty implied; use at your own risk
 
 
@@ -10,34 +10,47 @@
 
 
    Will probably not work correctly with strict-aliasing optimizations.
    Will probably not work correctly with strict-aliasing optimizations.
 
 
+   If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause 
+   compilation warnings or even errors. To avoid this, also before #including,
+
+       #define STBI_MSC_SECURE_CRT
+
 ABOUT:
 ABOUT:
 
 
    This header file is a library for writing images to C stdio. It could be
    This header file is a library for writing images to C stdio. It could be
    adapted to write to memory or a general streaming interface; let me know.
    adapted to write to memory or a general streaming interface; let me know.
 
 
    The PNG output is not optimal; it is 20-50% larger than the file
    The PNG output is not optimal; it is 20-50% larger than the file
-   written by a decent optimizing implementation. This library is designed
-   for source code compactness and simplicity, not optimal image file size
-   or run-time performance.
+   written by a decent optimizing implementation; though providing a custom
+   zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that.
+   This library is designed for source code compactness and simplicity,
+   not optimal image file size or run-time performance.
 
 
 BUILDING:
 BUILDING:
 
 
    You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
    You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
    You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
    You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
    malloc,realloc,free.
    malloc,realloc,free.
-   You can define STBIW_MEMMOVE() to replace memmove()
+   You can #define STBIW_MEMMOVE() to replace memmove()
+   You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function
+   for PNG compression (instead of the builtin one), it must have the following signature:
+   unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality);
+   The returned data will be freed with STBIW_FREE() (free() by default),
+   so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
 
 
 USAGE:
 USAGE:
 
 
-   There are four functions, one for each image file format:
+   There are five functions, one for each image file format:
 
 
      int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
      int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
      int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
      int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
      int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
      int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
      int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
      int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
-     int stbi_write_jpg(char const *filename, int w, int h, int comp, const float *data);
+     int stbi_write_jpg(char const *filename, int w, int h, int comp, const float *data, int quality);
 
 
-   There are also four equivalent functions that use an arbitrary write function. You are
+     void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
+
+   There are also five equivalent functions that use an arbitrary write function. You are
    expected to open/close your file-equivalent before and after calling these:
    expected to open/close your file-equivalent before and after calling these:
 
 
      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);
      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:
    where the callback is:
    where the callback is:
       void stbi_write_func(void *context, void *data, int size);
       void stbi_write_func(void *context, void *data, int size);
 
 
+   You can configure it with these global variables:
+      int stbi_write_tga_with_rle;             // defaults to true; set to 0 to disable RLE
+      int stbi_write_png_compression_level;    // defaults to 8; set to higher for more compression
+      int stbi_write_force_png_filter;         // defaults to -1; set to 0..5 to force a filter mode
+
+
    You can define STBI_WRITE_NO_STDIO to disable the file variant of these
    You can define STBI_WRITE_NO_STDIO to disable the file variant of these
    functions, so the library will not use stdio.h at all. However, this will
    functions, so the library will not use stdio.h at all. However, this will
    also disable HDR writing, because it requires stdio for formatted output.
    also disable HDR writing, because it requires stdio for formatted output.
@@ -75,6 +94,9 @@ USAGE:
    writer, both because it is in BGR order and because it may have padding
    writer, both because it is in BGR order and because it may have padding
    at the end of the line.)
    at the end of the line.)
 
 
+   PNG allows you to set the deflate compression level by setting the global
+   variable 'stbi_write_png_level' (it defaults to 8).
+
    HDR expects linear float data. Since the format is always 32-bit rgb(e)
    HDR expects linear float data. Since the format is always 32-bit rgb(e)
    data, alpha (if provided) is discarded, and for monochrome data it is
    data, alpha (if provided) is discarded, and for monochrome data it is
    replicated across all three channels.
    replicated across all three channels.
@@ -88,21 +110,17 @@ USAGE:
 
 
 CREDITS:
 CREDITS:
 
 
-   PNG/BMP/TGA
-      Sean Barrett
-   HDR
-      Baldur Karlsson
-   TGA monochrome:
-      Jean-Sebastien Guay
-   misc enhancements:
-      Tim Kelsey
-   TGA RLE
-      Alan Hickman
-   initial file IO callback implementation
-      Emmanuel Julien
-   JPEG
-      Jon Olick (original jo_jpeg.cpp code)
-      Daniel Gibson
+
+   Sean Barrett           -    PNG/BMP/TGA 
+   Baldur Karlsson        -    HDR
+   Jean-Sebastien Guay    -    TGA monochrome
+   Tim Kelsey             -    misc enhancements
+   Alan Hickman           -    TGA RLE
+   Emmanuel Julien        -    initial file IO callback implementation
+   Jon Olick              -    original jo_jpeg.cpp code
+   Daniel Gibson          -    integrate JPEG, allow external zlib
+   Aarni Koskela          -    allow choosing PNG filter
+
    bugfixes:
    bugfixes:
       github:Chribba
       github:Chribba
       Guillaume Chereau
       Guillaume Chereau
@@ -114,6 +132,7 @@ CREDITS:
       Thatcher Ulrich
       Thatcher Ulrich
       github:poppolopoppo
       github:poppolopoppo
       Patrick Boettcher
       Patrick Boettcher
+      github:xeekworx
       
       
 LICENSE
 LICENSE
 
 
@@ -121,7 +140,7 @@ LICENSE
 
 
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
+// Modified by Lasse Oorni and Yao Wei Tjong for Urho3D
 
 
 #ifndef INCLUDE_STB_IMAGE_WRITE_H
 #ifndef INCLUDE_STB_IMAGE_WRITE_H
 #define INCLUDE_STB_IMAGE_WRITE_H
 #define INCLUDE_STB_IMAGE_WRITE_H
@@ -134,9 +153,12 @@ extern "C" {
 #define STBIWDEF static
 #define STBIWDEF static
 #else
 #else
 #define STBIWDEF extern
 #define STBIWDEF extern
-extern int stbi_write_tga_with_rle;
 #endif
 #endif
 
 
+STBIWDEF int stbi_write_tga_with_rle;
+STBIWDEF int stbi_write_png_comperssion_level;
+STBIWDEF int stbi_write_force_png_filter;
+
 #ifndef STBI_WRITE_NO_STDIO
 #ifndef STBI_WRITE_NO_STDIO
 STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void  *data, int stride_in_bytes);
 STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void  *data, int stride_in_bytes);
 STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void  *data);
 STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void  *data);
@@ -153,6 +175,8 @@ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w,
 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
 STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void  *data, int quality);
 STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void  *data, int quality);
 
 
+STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif
@@ -210,6 +234,23 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
 
 
 #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
 #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
 
 
+#ifdef STB_IMAGE_WRITE_STATIC
+static stbi__flip_vertically_on_write=0;
+static int stbi_write_png_compression level = 8;
+static int stbi_write_tga_with_rle = 1;
+static int stbi_write_force_png_filter = -1;
+#else
+int stbi_write_png_compression_level = 8;
+int stbi__flip_vertically_on_write=0;
+int stbi_write_tga_with_rle = 1;
+int stbi_write_force_png_filter = -1;
+#endif
+
+STBIWDEF void stbi_flip_vertically_on_write(int flag)
+{
+   stbi__flip_vertically_on_write = flag;
+}
+
 typedef struct
 typedef struct
 {
 {
    stbi_write_func *func;
    stbi_write_func *func;
@@ -232,12 +273,18 @@ static void stbi__stdio_write(void *context, void *data, int size)
 
 
 static int stbi__start_write_file(stbi__write_context *s, const char *filename)
 static int stbi__start_write_file(stbi__write_context *s, const char *filename)
 {
 {
+   FILE *f;
    // Urho3D: proper UTF8 handling for Windows, requires Urho3D WString class
    // Urho3D: proper UTF8 handling for Windows, requires Urho3D WString class
 #ifndef _WIN32
 #ifndef _WIN32
-   FILE *f = fopen(filename, "wb");
+   f = fopen(filename, "wb");
+#else
+   Urho3D::WString wstr(filename);
+#ifdef STBI_MSC_SECURE_CRT
+   if (_wfopen_s(&f, wstr.CString(), L"wb")
+      f = NULL;
 #else
 #else
-    Urho3D::WString wstr(filename);
-    FILE *f = _wfopen(wstr.CString(), L"wb");
+   f = _wfopen(wstr.CString(), L"wb");
+#endif
 #endif
 #endif
    stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
    stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
    return f != NULL;
    return f != NULL;
@@ -253,12 +300,6 @@ static void stbi__end_write_file(stbi__write_context *s)
 typedef unsigned int stbiw_uint32;
 typedef unsigned int stbiw_uint32;
 typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
 typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
 
 
-#ifdef STB_IMAGE_WRITE_STATIC
-static int stbi_write_tga_with_rle = 1;
-#else
-int stbi_write_tga_with_rle = 1;
-#endif
-
 static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
 static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
 {
 {
    while (*fmt) {
    while (*fmt) {
@@ -349,6 +390,9 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
    if (y <= 0)
    if (y <= 0)
       return;
       return;
 
 
+   if (stbi__flip_vertically_on_write)
+      vdir *= -1;
+
    if (vdir < 0)
    if (vdir < 0)
       j_end = -1, j = y-1;
       j_end = -1, j = y-1;
    else
    else
@@ -420,11 +464,21 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v
          "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
          "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
    } else {
    } else {
       int i,j,k;
       int i,j,k;
+      int jend, jdir;
 
 
       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);
       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);
 
 
-      for (j = y - 1; j >= 0; --j) {
-          unsigned char *row = (unsigned char *) data + j * x * comp;
+      if (stbi__flip_vertically_on_write) {
+         j = 0;
+         jend = y;
+         jdir = 1;
+      } else {
+         j = y-1;
+         jend = -1;
+         jdir = -1;
+      }
+      for (; j != jend; j += jdir) {
+         unsigned char *row = (unsigned char *) data + j * x * comp;
          int len;
          int len;
 
 
          for (i = 0; i < x; i += len) {
          for (i = 0; i < x; i += len) {
@@ -634,11 +688,15 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
       char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
       char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
       s->func(s->context, header, sizeof(header)-1);
       s->func(s->context, header, sizeof(header)-1);
 
 
+#ifdef STBI_MSC_SECURE_CRT
+      len = sprintf_s(buffer, "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
+#else
       len = sprintf(buffer, "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
       len = sprintf(buffer, "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
+#endif
       s->func(s->context, buffer, len);
       s->func(s->context, buffer, len);
 
 
       for(i=0; i < y; i++)
       for(i=0; i < y; i++)
-         stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x);
+         stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)*x);
       STBIW_FREE(scratch);
       STBIW_FREE(scratch);
       return 1;
       return 1;
    }
    }
@@ -670,6 +728,7 @@ STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const
 // PNG writer
 // PNG writer
 //
 //
 
 
+#ifndef STBIW_ZLIB_COMPRESS
 // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
 // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
 #define stbiw__sbraw(a) ((int *) (a) - 2)
 #define stbiw__sbraw(a) ((int *) (a) - 2)
 #define stbiw__sbm(a)   stbiw__sbraw(a)[0]
 #define stbiw__sbm(a)   stbiw__sbraw(a)[0]
@@ -750,8 +809,14 @@ static unsigned int stbiw__zhash(unsigned char *data)
 
 
 #define stbiw__ZHASH   16384
 #define stbiw__ZHASH   16384
 
 
+#endif // STBIW_ZLIB_COMPRESS
+
 unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
 unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
 {
 {
+#ifdef STBIW_ZLIB_COMPRESS
+   // user provided a zlib compress implementation, use that
+   return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
+#else // use builtin
    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 };
    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 };
    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 };
    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 };
    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 };
    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 };
@@ -760,6 +825,8 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
    int i,j, bitcount=0;
    int i,j, bitcount=0;
    unsigned char *out = NULL;
    unsigned char *out = NULL;
    unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
    unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
+   if (hash_table == NULL)
+      return NULL;
    if (quality < 5) quality = 5;
    if (quality < 5) quality = 5;
 
 
    stbiw__sbpush(out, 0x78);   // DEFLATE 32K window
    stbiw__sbpush(out, 0x78);   // DEFLATE 32K window
@@ -853,6 +920,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
    // make returned pointer freeable
    // make returned pointer freeable
    STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
    STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
    return (unsigned char *) stbiw__sbraw(out);
    return (unsigned char *) stbiw__sbraw(out);
+#endif // STBIW_ZLIB_COMPRESS
 }
 }
 
 
 static unsigned int stbiw__crc32(unsigned char *buffer, int len)
 static unsigned int stbiw__crc32(unsigned char *buffer, int len)
@@ -919,61 +987,87 @@ static unsigned char stbiw__paeth(int a, int b, int c)
 }
 }
 
 
 // @OPTIMIZE: provide an option that always forces left-predict or paeth predict
 // @OPTIMIZE: provide an option that always forces left-predict or paeth predict
+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)
+{
+   static int mapping[] = { 0,1,2,3,4 };
+   static int firstmap[] = { 0,1,0,5,6 };
+   int *mymap = (y != 0) ? mapping : firstmap;
+   int i;
+   int type = mymap[filter_type];
+   unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
+   for (i = 0; i < n; ++i) {
+      switch (type) {
+         case 0: line_buffer[i] = z[i]; break;
+         case 1: line_buffer[i] = z[i]; break;
+         case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
+         case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
+         case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
+         case 5: line_buffer[i] = z[i]; break;
+         case 6: line_buffer[i] = z[i]; break;
+      }
+   }
+   for (i=n; i < width*n; ++i) {
+      switch (type) {
+         case 0: line_buffer[i] = z[i]; break;
+         case 1: line_buffer[i] = z[i] - z[i-n]; break;
+         case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
+         case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
+         case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
+         case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
+         case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
+      }
+   }
+}
+
 unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
 unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
 {
 {
+   int force_filter = stbi_write_force_png_filter;
    int ctype[5] = { -1, 0, 4, 2, 6 };
    int ctype[5] = { -1, 0, 4, 2, 6 };
    unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
    unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
    unsigned char *out,*o, *filt, *zlib;
    unsigned char *out,*o, *filt, *zlib;
    signed char *line_buffer;
    signed char *line_buffer;
-   int i,j,k,p,zlen;
+   int j,zlen;
 
 
    if (stride_bytes == 0)
    if (stride_bytes == 0)
       stride_bytes = x * n;
       stride_bytes = x * n;
 
 
+   if (force_filter >= 5) {
+      force_filter = -1;
+   }
+
    filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
    filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
    line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
    line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
    for (j=0; j < y; ++j) {
    for (j=0; j < y; ++j) {
-      static int mapping[] = { 0,1,2,3,4 };
-      static int firstmap[] = { 0,1,0,5,6 };
-      int *mymap = (j != 0) ? mapping : firstmap;
-      int best = 0, bestval = 0x7fffffff;
-      for (p=0; p < 2; ++p) {
-         for (k= p?best:0; k < 5; ++k) { // @TODO: clarity: rewrite this to go 0..5, and 'continue' the unwanted ones during 2nd pass
-            int type = mymap[k],est=0;
-            unsigned char *z = pixels + stride_bytes*j;
-            for (i=0; i < n; ++i)
-               switch (type) {
-                  case 0: line_buffer[i] = z[i]; break;
-                  case 1: line_buffer[i] = z[i]; break;
-                  case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
-                  case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
-                  case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
-                  case 5: line_buffer[i] = z[i]; break;
-                  case 6: line_buffer[i] = z[i]; break;
-               }
-            for (i=n; i < x*n; ++i) {
-               switch (type) {
-                  case 0: line_buffer[i] = z[i]; break;
-                  case 1: line_buffer[i] = z[i] - z[i-n]; break;
-                  case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
-                  case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
-                  case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
-                  case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
-                  case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
-               }
-            }
-            if (p) break;
-            for (i=0; i < x*n; ++i)
+      int filter_type;
+      if (force_filter > -1) {
+         filter_type = force_filter;
+         stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, force_filter, line_buffer);
+      } else { // Estimate the best filter by running through all of them:
+         int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
+         for (filter_type = 0; filter_type < 5; filter_type++) {
+            stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, filter_type, line_buffer);
+
+            // Estimate the entropy of the line using this filter; the less, the better.
+            est = 0;
+            for (i = 0; i < x*n; ++i) {
                est += abs((signed char) line_buffer[i]);
                est += abs((signed char) line_buffer[i]);
-            if (est < bestval) { bestval = est; best = k; }
+            }
+            if (est < best_filter_val) {
+               best_filter_val = est;
+               best_filter = filter_type;
+            }
+         }
+         if (filter_type != best_filter) {  // If the last iteration already got us the best filter, don't redo it
+            stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, best_filter, line_buffer);
+            filter_type = best_filter;
          }
          }
       }
       }
-      // when we get here, best contains the filter type, and line_buffer contains the data
-      filt[j*(x*n+1)] = (unsigned char) best;
+      // when we get here, filter_type contains the filter type, and line_buffer contains the data
+      filt[j*(x*n+1)] = (unsigned char) filter_type;
       STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
       STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
    }
    }
    STBIW_FREE(line_buffer);
    STBIW_FREE(line_buffer);
-   zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
+   zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level);
    STBIW_FREE(filt);
    STBIW_FREE(filt);
    if (!zlib) return 0;
    if (!zlib) return 0;
 
 
@@ -1018,7 +1112,18 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
    int len;
    int len;
    unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
    unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
    if (png == NULL) return 0;
    if (png == NULL) return 0;
+   // Urho3D: proper UTF8 handling for Windows, requires Urho3D WString class
+#ifndef _WIN32
    f = fopen(filename, "wb");
    f = fopen(filename, "wb");
+#else
+   Urho3D::WString wstr(filename);
+#ifdef STBI_MSC_SECURE_CRT
+   if (_wfopen_s(&f, wstr.CString(), L"wb")
+      f = NULL;
+#else
+   f = _wfopen(wstr.CString(), L"wb");
+#endif
+#endif
    if (!f) { STBIW_FREE(png); return 0; }
    if (!f) { STBIW_FREE(png); return 0; }
    fwrite(png, 1, len, f);
    fwrite(png, 1, len, f);
    fclose(f);
    fclose(f);
@@ -1326,7 +1431,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
             float YDU[64], UDU[64], VDU[64];
             float YDU[64], UDU[64], VDU[64];
             for(row = y, pos = 0; row < y+8; ++row) {
             for(row = y, pos = 0; row < y+8; ++row) {
                for(col = x; col < x+8; ++col, ++pos) {
                for(col = x; col < x+8; ++col, ++pos) {
-                  int p = row*width*comp + col*comp;
+                  int p = (stbi__flip_vertically_on_write ? height-1-row : row)*width*comp + col*comp;
                   float r, g, b;
                   float r, g, b;
                   if(row >= height) {
                   if(row >= height) {
                      p -= width*comp*(row+1 - height);
                      p -= width*comp*(row+1 - height);
@@ -1385,6 +1490,8 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
 
 
 /* Revision history
 /* Revision history
+      1.08  (2018-01-29)
+             add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
       1.07  (2017-07-24)
       1.07  (2017-07-24)
              doc fix
              doc fix
       1.06 (2017-07-23)
       1.06 (2017-07-23)

+ 78 - 26
Source/ThirdParty/STB/stb_rect_pack.h

@@ -1,4 +1,4 @@
-// stb_rect_pack.h - v0.08 - public domain - rectangle packing
+// stb_rect_pack.h - v0.11 - public domain - rectangle packing
 // Sean Barrett 2014
 // Sean Barrett 2014
 //
 //
 // Useful for e.g. packing rectangular textures into an atlas.
 // Useful for e.g. packing rectangular textures into an atlas.
@@ -27,11 +27,16 @@
 //    Sean Barrett
 //    Sean Barrett
 //  Minor features
 //  Minor features
 //    Martins Mozeiko
 //    Martins Mozeiko
+//    github:IntellectualKitty
+//    
 //  Bugfixes / warning fixes
 //  Bugfixes / warning fixes
 //    Jeremy Jaussaud
 //    Jeremy Jaussaud
 //
 //
 // Version history:
 // Version history:
 //
 //
+//     0.11  (2017-03-03)  return packing success/fail result
+//     0.10  (2016-10-25)  remove cast-away-const to avoid warnings
+//     0.09  (2016-08-27)  fix compiler warnings
 //     0.08  (2015-09-13)  really fix bug with empty rects (w=0 or h=0)
 //     0.08  (2015-09-13)  really fix bug with empty rects (w=0 or h=0)
 //     0.07  (2015-09-13)  fix bug with empty rects (w=0 or h=0)
 //     0.07  (2015-09-13)  fix bug with empty rects (w=0 or h=0)
 //     0.06  (2015-04-15)  added STBRP_SORT to allow replacing qsort
 //     0.06  (2015-04-15)  added STBRP_SORT to allow replacing qsort
@@ -41,9 +46,7 @@
 //
 //
 // LICENSE
 // LICENSE
 //
 //
-//   This software is dual-licensed to the public domain and under the following
-//   license: you are granted a perpetual, irrevocable license to copy, modify,
-//   publish, and distribute this file as you see fit.
+//   See end of file for license information.
 
 
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 //
 //
@@ -75,7 +78,7 @@ typedef int            stbrp_coord;
 typedef unsigned short stbrp_coord;
 typedef unsigned short stbrp_coord;
 #endif
 #endif
 
 
-STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
+STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
 // Assign packed locations to rectangles. The rectangles are of type
 // Assign packed locations to rectangles. The rectangles are of type
 // 'stbrp_rect' defined below, stored in the array 'rects', and there
 // 'stbrp_rect' defined below, stored in the array 'rects', and there
 // are 'num_rects' many of them.
 // are 'num_rects' many of them.
@@ -96,6 +99,9 @@ STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int
 // arrays will probably produce worse packing results than calling it
 // arrays will probably produce worse packing results than calling it
 // a single time with the full rectangle array, but the option is
 // a single time with the full rectangle array, but the option is
 // available.
 // available.
+//
+// The function returns 1 if all of the rectangles were successfully
+// packed and 0 otherwise.
 
 
 struct stbrp_rect
 struct stbrp_rect
 {
 {
@@ -148,7 +154,7 @@ enum
 {
 {
    STBRP_HEURISTIC_Skyline_default=0,
    STBRP_HEURISTIC_Skyline_default=0,
    STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
    STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
-   STBRP_HEURISTIC_Skyline_BF_sortHeight,
+   STBRP_HEURISTIC_Skyline_BF_sortHeight
 };
 };
 
 
 
 
@@ -198,9 +204,15 @@ struct stbrp_context
 #define STBRP_ASSERT assert
 #define STBRP_ASSERT assert
 #endif
 #endif
 
 
+#ifdef _MSC_VER
+#define STBRP__NOTUSED(v)  (void)(v)
+#else
+#define STBRP__NOTUSED(v)  (void)sizeof(v)
+#endif
+
 enum
 enum
 {
 {
-   STBRP__INIT_skyline = 1,
+   STBRP__INIT_skyline = 1
 };
 };
 
 
 STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
 STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
@@ -273,6 +285,9 @@ static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0
    stbrp_node *node = first;
    stbrp_node *node = first;
    int x1 = x0 + width;
    int x1 = x0 + width;
    int min_y, visited_width, waste_area;
    int min_y, visited_width, waste_area;
+
+   STBRP__NOTUSED(c);
+
    STBRP_ASSERT(first->x <= x0);
    STBRP_ASSERT(first->x <= x0);
 
 
    #if 0
    #if 0
@@ -500,8 +515,8 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
 
 
 static int rect_height_compare(const void *a, const void *b)
 static int rect_height_compare(const void *a, const void *b)
 {
 {
-   stbrp_rect *p = (stbrp_rect *) a;
-   stbrp_rect *q = (stbrp_rect *) b;
+   const stbrp_rect *p = (const stbrp_rect *) a;
+   const stbrp_rect *q = (const stbrp_rect *) b;
    if (p->h > q->h)
    if (p->h > q->h)
       return -1;
       return -1;
    if (p->h < q->h)
    if (p->h < q->h)
@@ -509,21 +524,10 @@ static int rect_height_compare(const void *a, const void *b)
    return (p->w > q->w) ? -1 : (p->w < q->w);
    return (p->w > q->w) ? -1 : (p->w < q->w);
 }
 }
 
 
-static int rect_width_compare(const void *a, const void *b)
-{
-   stbrp_rect *p = (stbrp_rect *) a;
-   stbrp_rect *q = (stbrp_rect *) b;
-   if (p->w > q->w)
-      return -1;
-   if (p->w < q->w)
-      return  1;
-   return (p->h > q->h) ? -1 : (p->h < q->h);
-}
-
 static int rect_original_order(const void *a, const void *b)
 static int rect_original_order(const void *a, const void *b)
 {
 {
-   stbrp_rect *p = (stbrp_rect *) a;
-   stbrp_rect *q = (stbrp_rect *) b;
+   const stbrp_rect *p = (const stbrp_rect *) a;
+   const stbrp_rect *q = (const stbrp_rect *) b;
    return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
    return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
 }
 }
 
 
@@ -533,9 +537,9 @@ static int rect_original_order(const void *a, const void *b)
 #define STBRP__MAXVAL  0xffff
 #define STBRP__MAXVAL  0xffff
 #endif
 #endif
 
 
-STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
+STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
 {
 {
-   int i;
+   int i, all_rects_packed = 1;
 
 
    // we use the 'was_packed' field internally to allow sorting/unsorting
    // we use the 'was_packed' field internally to allow sorting/unsorting
    for (i=0; i < num_rects; ++i) {
    for (i=0; i < num_rects; ++i) {
@@ -565,8 +569,56 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
    // unsort
    // unsort
    STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
    STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
 
 
-   // set was_packed flags
-   for (i=0; i < num_rects; ++i)
+   // set was_packed flags and all_rects_packed status
+   for (i=0; i < num_rects; ++i) {
       rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
       rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
+      if (!rects[i].was_packed)
+         all_rects_packed = 0;
+   }
+
+   // return the all_rects_packed status
+   return all_rects_packed;
 }
 }
 #endif
 #endif
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 
+software, either in source code form or as a compiled binary, for any purpose, 
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this 
+software dedicate any and all copyright interest in the software to the public 
+domain. We make this dedication for the benefit of the public at large and to 
+the detriment of our heirs and successors. We intend this dedication to be an 
+overt act of relinquishment in perpetuity of all present and future rights to 
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/

+ 118 - 52
Source/ThirdParty/STB/stb_vorbis.h

@@ -1,20 +1,15 @@
-// Ogg Vorbis audio decoder - v1.09 - public domain
+// Ogg Vorbis audio decoder - v1.13b - public domain
 // http://nothings.org/stb_vorbis/
 // http://nothings.org/stb_vorbis/
 //
 //
 // Original version written by Sean Barrett in 2007.
 // Original version written by Sean Barrett in 2007.
 //
 //
-// Originally sponsored by RAD Game Tools. Seeking sponsored
-// by Phillip Bennefall, Marc Andersen, Aaron Baker, Elias Software,
-// Aras Pranckevicius, and Sean Barrett.
+// Originally sponsored by RAD Game Tools. Seeking implementation
+// sponsored by Phillip Bennefall, Marc Andersen, Aaron Baker,
+// Elias Software, Aras Pranckevicius, and Sean Barrett.
 //
 //
 // LICENSE
 // LICENSE
 //
 //
-//   This software is dual-licensed to the public domain and under the following
-//   license: you are granted a perpetual, irrevocable license to copy, modify,
-//   publish, and distribute this file as you see fit.
-//
-// No warranty for any purpose is expressed or implied by the author (nor
-// by RAD Game Tools). Report bugs and send enhancements to the author.
+//   See end of file for license information.
 //
 //
 // Limitations:
 // Limitations:
 //
 //
@@ -34,9 +29,13 @@
 //    Bernhard Wodo      Evan Balster        alxprd@github
 //    Bernhard Wodo      Evan Balster        alxprd@github
 //    Tom Beaumont       Ingo Leitgeb        Nicolas Guillemot
 //    Tom Beaumont       Ingo Leitgeb        Nicolas Guillemot
 //    Phillip Bennefall  Rohit               Thiago Goulart
 //    Phillip Bennefall  Rohit               Thiago Goulart
-//    manxorist@github   saga musix
+//    manxorist@github   saga musix          github:infatum
 //
 //
 // Partial history:
 // Partial history:
+//    1.13    - 2018/01/29 - fix truncation of last frame (hopefully)
+//    1.12    - 2017/11/21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
+//    1.11    - 2017/07/23 - fix MinGW compilation 
+//    1.10    - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
 //    1.09    - 2016/04/04 - back out 'truncation of last frame' fix from previous version
 //    1.09    - 2016/04/04 - back out 'truncation of last frame' fix from previous version
 //    1.08    - 2016/04/02 - warnings; setup memory leaks; truncation of last frame
 //    1.08    - 2016/04/02 - warnings; setup memory leaks; truncation of last frame
 //    1.07    - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const
 //    1.07    - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const
@@ -275,7 +274,7 @@ extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number);
 // do not need to seek to EXACTLY the target sample when using get_samples_*,
 // do not need to seek to EXACTLY the target sample when using get_samples_*,
 // you can also use seek_frame().
 // you can also use seek_frame().
 
 
-extern void stb_vorbis_seek_start(stb_vorbis *f);
+extern int stb_vorbis_seek_start(stb_vorbis *f);
 // this function is equivalent to stb_vorbis_seek(f,0)
 // this function is equivalent to stb_vorbis_seek(f,0)
 
 
 extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f);
 extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f);
@@ -549,21 +548,23 @@ enum STBVorbisError
 #endif
 #endif
 
 
 #ifndef STB_VORBIS_NO_CRT
 #ifndef STB_VORBIS_NO_CRT
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <math.h>
-#if !(defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh))
-#include <malloc.h>
-#if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__)
-#include <alloca.h>
-#endif
-#endif
+   #include <stdlib.h>
+   #include <string.h>
+   #include <assert.h>
+   #include <math.h>
+
+   // find definition of alloca if it's not in stdlib.h:
+   #if defined(_MSC_VER) || defined(__MINGW32__)
+      #include <malloc.h>
+   #endif
+   #if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__)
+      #include <alloca.h>
+   #endif
 #else // STB_VORBIS_NO_CRT
 #else // STB_VORBIS_NO_CRT
-#define NULL 0
-#define malloc(s)   0
-#define free(s)     ((void) 0)
-#define realloc(s)  0
+   #define NULL 0
+   #define malloc(s)   0
+   #define free(s)     ((void) 0)
+   #define realloc(s)  0
 #endif // STB_VORBIS_NO_CRT
 #endif // STB_VORBIS_NO_CRT
 
 
 #include <limits.h>
 #include <limits.h>
@@ -578,6 +579,7 @@ enum STBVorbisError
    #undef __forceinline
    #undef __forceinline
    #endif
    #endif
    #define __forceinline
    #define __forceinline
+   #define alloca __builtin_alloca
 #elif !defined(_MSC_VER)
 #elif !defined(_MSC_VER)
    #if __GNUC__
    #if __GNUC__
       #define __forceinline inline
       #define __forceinline inline
@@ -984,17 +986,18 @@ static int ilog(int32 n)
 {
 {
    static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 };
    static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 };
 
 
+   if (n < 0) return 0; // signed n returns 0
+
    // 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29)
    // 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29)
    if (n < (1 << 14))
    if (n < (1 << 14))
-        if (n < (1 <<  4))        return     0 + log2_4[n      ];
-        else if (n < (1 <<  9))      return  5 + log2_4[n >>  5];
+        if (n < (1 <<  4))            return  0 + log2_4[n      ];
+        else if (n < (1 <<  9))       return  5 + log2_4[n >>  5];
              else                     return 10 + log2_4[n >> 10];
              else                     return 10 + log2_4[n >> 10];
    else if (n < (1 << 24))
    else if (n < (1 << 24))
-             if (n < (1 << 19))      return 15 + log2_4[n >> 15];
+             if (n < (1 << 19))       return 15 + log2_4[n >> 15];
              else                     return 20 + log2_4[n >> 20];
              else                     return 20 + log2_4[n >> 20];
-        else if (n < (1 << 29))      return 25 + log2_4[n >> 25];
-             else if (n < (1 << 31)) return 30 + log2_4[n >> 30];
-                  else                return 0; // signed n returns 0
+        else if (n < (1 << 29))       return 25 + log2_4[n >> 25];
+             else                     return 30 + log2_4[n >> 30];
 }
 }
 
 
 #ifndef M_PI
 #ifndef M_PI
@@ -1267,13 +1270,13 @@ static void neighbors(uint16 *x, int n, int *plow, int *phigh)
 // this has been repurposed so y is now the original index instead of y
 // this has been repurposed so y is now the original index instead of y
 typedef struct
 typedef struct
 {
 {
-   uint16 x,y;
-} Point;
+   uint16 x,id;
+} stbv__floor_ordering;
 
 
 static int STBV_CDECL point_compare(const void *p, const void *q)
 static int STBV_CDECL point_compare(const void *p, const void *q)
 {
 {
-   Point *a = (Point *) p;
-   Point *b = (Point *) q;
+   stbv__floor_ordering *a = (stbv__floor_ordering *) p;
+   stbv__floor_ordering *b = (stbv__floor_ordering *) q;
    return a->x < b->x ? -1 : a->x > b->x;
    return a->x < b->x ? -1 : a->x > b->x;
 }
 }
 
 
@@ -2041,6 +2044,8 @@ static int residue_decode(vorb *f, Codebook *book, float *target, int offset, in
    return TRUE;
    return TRUE;
 }
 }
 
 
+// n is 1/2 of the blocksize --
+// specification: "Correct per-vector decode length is [n]/2"
 static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode)
 static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode)
 {
 {
    int i,j,pass;
    int i,j,pass;
@@ -2048,7 +2053,10 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
    int rtype = f->residue_types[rn];
    int rtype = f->residue_types[rn];
    int c = r->classbook;
    int c = r->classbook;
    int classwords = f->codebooks[c].dimensions;
    int classwords = f->codebooks[c].dimensions;
-   int n_read = r->end - r->begin;
+   unsigned int actual_size = rtype == 2 ? n*2 : n;
+   unsigned int limit_r_begin = (r->begin < actual_size ? r->begin : actual_size);
+   unsigned int limit_r_end   = (r->end   < actual_size ? r->end   : actual_size);
+   int n_read = limit_r_end - limit_r_begin;
    int part_read = n_read / r->part_size;
    int part_read = n_read / r->part_size;
    int temp_alloc_point = temp_alloc_save(f);
    int temp_alloc_point = temp_alloc_save(f);
    #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
    #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
@@ -3390,7 +3398,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
    if (f->last_seg_which == f->end_seg_with_known_loc) {
    if (f->last_seg_which == f->end_seg_with_known_loc) {
       // if we have a valid current loc, and this is final:
       // if we have a valid current loc, and this is final:
       if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) {
       if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) {
-         uint32 current_end = f->known_loc_for_packet - (n-right_end);
+         uint32 current_end = f->known_loc_for_packet;
          // then let's infer the size of the (probably) short final frame
          // then let's infer the size of the (probably) short final frame
          if (current_end < f->current_loc + (right_end-left_start)) {
          if (current_end < f->current_loc + (right_end-left_start)) {
             if (current_end < f->current_loc) {
             if (current_end < f->current_loc) {
@@ -3399,7 +3407,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
             } else {
             } else {
                *len = current_end - f->current_loc;
                *len = current_end - f->current_loc;
             }
             }
-            *len += left_start;
+            *len += left_start; // this doesn't seem right, but has no ill effect on my test files
             if (*len > right_end) *len = right_end; // this should never happen
             if (*len > right_end) *len = right_end; // this should never happen
             f->current_loc += *len;
             f->current_loc += *len;
             return TRUE;
             return TRUE;
@@ -3482,11 +3490,13 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
    return right - left;
    return right - left;
 }
 }
 
 
-static void vorbis_pump_first_frame(stb_vorbis *f)
+static int vorbis_pump_first_frame(stb_vorbis *f)
 {
 {
-   int len, right, left;
-   if (vorbis_decode_packet(f, &len, &left, &right))
+   int len, right, left, res;
+   res = vorbis_decode_packet(f, &len, &left, &right);
+   if (res)
       vorbis_finish_frame(f, len, left, right);
       vorbis_finish_frame(f, len, left, right);
+   return res;
 }
 }
 
 
 #ifndef STB_VORBIS_NO_PUSHDATA_API
 #ifndef STB_VORBIS_NO_PUSHDATA_API
@@ -3869,7 +3879,7 @@ static int start_decoder(vorb *f)
             g->book_list[j] = get_bits(f,8);
             g->book_list[j] = get_bits(f,8);
          return error(f, VORBIS_feature_not_supported);
          return error(f, VORBIS_feature_not_supported);
       } else {
       } else {
-         Point p[31*8+2];
+         stbv__floor_ordering p[31*8+2];
          Floor1 *g = &f->floor_config[i].floor1;
          Floor1 *g = &f->floor_config[i].floor1;
          int max_class = -1; 
          int max_class = -1; 
          g->partitions = get_bits(f, 5);
          g->partitions = get_bits(f, 5);
@@ -3905,11 +3915,11 @@ static int start_decoder(vorb *f)
          // precompute the sorting
          // precompute the sorting
          for (j=0; j < g->values; ++j) {
          for (j=0; j < g->values; ++j) {
             p[j].x = g->Xlist[j];
             p[j].x = g->Xlist[j];
-            p[j].y = j;
+            p[j].id = j;
          }
          }
          qsort(p, g->values, sizeof(p[0]), point_compare);
          qsort(p, g->values, sizeof(p[0]), point_compare);
          for (j=0; j < g->values; ++j)
          for (j=0; j < g->values; ++j)
-            g->sorted_order[j] = (uint8) p[j].y;
+            g->sorted_order[j] = (uint8) p[j].id;
          // precompute the neighbors
          // precompute the neighbors
          for (j=2; j < g->values; ++j) {
          for (j=2; j < g->values; ++j) {
             int low,hi;
             int low,hi;
@@ -4074,7 +4084,10 @@ static int start_decoder(vorb *f)
       int i,max_part_read=0;
       int i,max_part_read=0;
       for (i=0; i < f->residue_count; ++i) {
       for (i=0; i < f->residue_count; ++i) {
          Residue *r = f->residue_config + i;
          Residue *r = f->residue_config + i;
-         int n_read = r->end - r->begin;
+         unsigned int actual_size = f->blocksize_1 / 2;
+         unsigned int limit_r_begin = r->begin < actual_size ? r->begin : actual_size;
+         unsigned int limit_r_end   = r->end   < actual_size ? r->end   : actual_size;
+         int n_read = limit_r_end - limit_r_begin;
          int part_read = n_read / r->part_size;
          int part_read = n_read / r->part_size;
          if (part_read > max_part_read)
          if (part_read > max_part_read)
             max_part_read = part_read;
             max_part_read = part_read;
@@ -4085,6 +4098,8 @@ static int start_decoder(vorb *f)
       classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *));
       classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *));
       #endif
       #endif
 
 
+      // maximum reasonable partition size is f->blocksize_1
+
       f->temp_memory_required = classify_mem;
       f->temp_memory_required = classify_mem;
       if (imdct_mem > f->temp_memory_required)
       if (imdct_mem > f->temp_memory_required)
          f->temp_memory_required = imdct_mem;
          f->temp_memory_required = imdct_mem;
@@ -4613,8 +4628,9 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
 
 
    // starting from the start is handled differently
    // starting from the start is handled differently
    if (sample_number <= left.last_decoded_sample) {
    if (sample_number <= left.last_decoded_sample) {
-      stb_vorbis_seek_start(f);
-      return 1;
+      if (stb_vorbis_seek_start(f))
+         return 1;
+      return 0;
    }
    }
 
 
    while (left.page_end != right.page_start) {
    while (left.page_end != right.page_start) {
@@ -4715,7 +4731,10 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
       skip(f, f->segments[i]);
       skip(f, f->segments[i]);
 
 
    // start decoding (optimizable - this frame is generally discarded)
    // start decoding (optimizable - this frame is generally discarded)
-   vorbis_pump_first_frame(f);
+   if (!vorbis_pump_first_frame(f))
+      return 0;
+   if (f->current_loc > sample_number)
+      return error(f, VORBIS_seek_failed);
    return 1;
    return 1;
 
 
 error:
 error:
@@ -4806,14 +4825,14 @@ int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number)
    return 1;
    return 1;
 }
 }
 
 
-void stb_vorbis_seek_start(stb_vorbis *f)
+int stb_vorbis_seek_start(stb_vorbis *f)
 {
 {
-   if (IS_PUSH_MODE(f)) { error(f, VORBIS_invalid_api_mixing); return; }
+   if (IS_PUSH_MODE(f)) { return error(f, VORBIS_invalid_api_mixing); }
    set_file_offset(f, f->first_audio_page_offset);
    set_file_offset(f, f->first_audio_page_offset);
    f->previous_length = 0;
    f->previous_length = 0;
    f->first_decode = TRUE;
    f->first_decode = TRUE;
    f->next_seg = -1;
    f->next_seg = -1;
-   vorbis_pump_first_frame(f);
+   return vorbis_pump_first_frame(f);
 }
 }
 
 
 unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f)
 unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f)
@@ -4978,6 +4997,7 @@ stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *err
       if (f) {
       if (f) {
          *f = p;
          *f = p;
          vorbis_pump_first_frame(f);
          vorbis_pump_first_frame(f);
+         if (error) *error = VORBIS__no_error;
          return f;
          return f;
       }
       }
    }
    }
@@ -5343,6 +5363,9 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
 #endif // STB_VORBIS_NO_PULLDATA_API
 #endif // STB_VORBIS_NO_PULLDATA_API
 
 
 /* Version history
 /* Version history
+    1.12    - 2017/11/21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
+    1.11    - 2017/07/23 - fix MinGW compilation 
+    1.10    - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
     1.09    - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version
     1.09    - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version
     1.08    - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;
     1.08    - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;
                            avoid discarding last frame of audio data
                            avoid discarding last frame of audio data
@@ -5395,3 +5418,46 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
 */
 */
 
 
 #endif // STB_VORBIS_HEADER_ONLY
 #endif // STB_VORBIS_HEADER_ONLY
+
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+Permission is hereby granted, free of charge, to any person obtaining a copy of 
+this software and associated documentation files (the "Software"), to deal in 
+the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+of the Software, and to permit persons to whom the Software is furnished to do 
+so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 
+software, either in source code form or as a compiled binary, for any purpose, 
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this 
+software dedicate any and all copyright interest in the software to the public 
+domain. We make this dedication for the benefit of the public at large and to 
+the detriment of our heirs and successors. We intend this dedication to be an 
+overt act of relinquishment in perpetuity of all present and future rights to 
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/

Some files were not shown because too many files changed in this diff