actually update stb libraries for real this time

This commit is contained in:
Connor Olding 2017-04-02 02:01:52 +00:00
parent 076d8bae83
commit 5f101288e8
2 changed files with 423 additions and 93 deletions

View File

@ -1,4 +1,4 @@
/* stb_image - v2.14 - public domain image loader - http://nothings.org/stb_image.h /* stb_image - v2.15 - public domain image loader - http://nothings.org/stb_image.h
no warranty implied; use at your own risk no warranty implied; use at your own risk
Do this: Do this:
@ -48,12 +48,13 @@ LICENSE
RECENT REVISION HISTORY: RECENT REVISION HISTORY:
2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
RGB-format JPEG; remove white matting in PSD; RGB-format JPEG; remove white matting in PSD;
allocate large structures on the stack; allocate large structures on the stack;
correct channel count for PNG & BMP correct channel count for PNG & BMP
2.10 (2016-01-22) avoid warning introduced in 2.09 2.10 (2016-01-22) avoid warning introduced in 2.09
2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
@ -77,7 +78,7 @@ RECENT REVISION HISTORY:
Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
github:urraka (animated gif) Junggon Kim (PNM comments) github:urraka (animated gif) Junggon Kim (PNM comments)
Daniel Gibson (16-bit TGA) Daniel Gibson (16-bit TGA)
socks-the-fox (16-bit TGA) socks-the-fox (16-bit PNG)
Jeremy Sawicki (handle all ImageNet JPGs) Jeremy Sawicki (handle all ImageNet JPGs)
Optimizations & bugfixes Optimizations & bugfixes
Fabian "ryg" Giesen Fabian "ryg" Giesen
@ -85,18 +86,18 @@ RECENT REVISION HISTORY:
Bug & warning fixes Bug & warning fixes
Marc LeBlanc David Woo Guillaume George Martins Mozeiko Marc LeBlanc David Woo Guillaume George Martins Mozeiko
Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
Dave Moore Roy Eltham Hayaki Saito Phil Jordan Dave Moore Roy Eltham Hayaki Saito Nathan Reed
Won Chun Luke Graham Johan Duparc Nathan Reed Won Chun Luke Graham Johan Duparc Nick Verigakis
the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis the Horde3D community Thomas Ruf Ronny Chevalier Baldur Karlsson
Janez Zemva John Bartholomew Michal Cichon github:svdijk Janez Zemva John Bartholomew Michal Cichon github:rlyeh
Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson Jonathan Blow Ken Hamada Tero Hanninen github:romigrou
Laurent Gomila Cort Stratton Sergio Gonzalez github:romigrou Laurent Gomila Cort Stratton Sergio Gonzalez github:svdijk
Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan Aruelien Pocheville Thibault Reuille Cass Everitt github:snagar
Ryamond Barbiero Paul Du Bois Engin Manap github:snagar Ryamond Barbiero Paul Du Bois Engin Manap github:Zelex
Michaelangel007@github Oriol Ferrer Mesia Dale Weiler github:Zelex Michaelangel007@github Philipp Wiesemann Dale Weiler github:grim210
Philipp Wiesemann Josh Tobin github:rlyeh github:grim210@github Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:sammyhw
Blazej Dariusz Roszkowski github:sammyhw Blazej Dariusz Roszkowski Gregory Mullen github:phprus
*/ */
@ -267,11 +268,11 @@ RECENT REVISION HISTORY:
// =========================================================================== // ===========================================================================
// //
// ADDITIONAL CONFIGURATION // ADDITIONAL CONFIGURATION
// //
// - You can suppress implementation of any of the decoders to reduce // - You can suppress implementation of any of the decoders to reduce
// your code footprint by #defining one or more of the following // your code footprint by #defining one or more of the following
// symbols before creating the implementation. // symbols before creating the implementation.
// //
// STBI_NO_JPEG // STBI_NO_JPEG
// STBI_NO_PNG // STBI_NO_PNG
// STBI_NO_BMP // STBI_NO_BMP
@ -281,11 +282,11 @@ RECENT REVISION HISTORY:
// STBI_NO_HDR // STBI_NO_HDR
// STBI_NO_PIC // STBI_NO_PIC
// STBI_NO_PNM (.ppm and .pgm) // STBI_NO_PNM (.ppm and .pgm)
// //
// - You can request *only* certain decoders and suppress all other ones // - You can request *only* certain decoders and suppress all other ones
// (this will be more forward-compatible, as addition of new decoders // (this will be more forward-compatible, as addition of new decoders
// doesn't require you to disable them explicitly): // doesn't require you to disable them explicitly):
// //
// STBI_ONLY_JPEG // STBI_ONLY_JPEG
// STBI_ONLY_PNG // STBI_ONLY_PNG
// STBI_ONLY_BMP // STBI_ONLY_BMP
@ -295,7 +296,7 @@ RECENT REVISION HISTORY:
// STBI_ONLY_HDR // STBI_ONLY_HDR
// STBI_ONLY_PIC // STBI_ONLY_PIC
// STBI_ONLY_PNM (.ppm and .pgm) // STBI_ONLY_PNM (.ppm and .pgm)
// //
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still // - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB // want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
// //
@ -583,12 +584,14 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#define STBI__X86_TARGET #define STBI__X86_TARGET
#endif #endif
#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) #if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
// NOTE: not clear do we actually need this for the 64-bit path?
// gcc doesn't support sse2 intrinsics unless you compile with -msse2, // gcc doesn't support sse2 intrinsics unless you compile with -msse2,
// (but compiling with -msse2 allows the compiler to use SSE2 everywhere; // which in turn means it gets to use SSE2 everywhere. This is unfortunate,
// this is just broken and gcc are jerks for not fixing it properly // but previous attempts to provide the SSE2 functions with runtime
// http://www.virtualdub.org/blog/pivot/entry.php?id=363 ) // detection caused numerous issues. The way architecture extensions are
// exposed in GCC/Clang is, sadly, not really suited for one-file libs.
// New behavior: if compiled with -msse2, we use SSE2 without any
// detection; if not, we don't use it at all.
#define STBI_NO_SIMD #define STBI_NO_SIMD
#endif #endif
@ -646,14 +649,10 @@ static int stbi__sse2_available()
static int stbi__sse2_available() static int stbi__sse2_available()
{ {
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later // If we're even attempting to compile this on GCC/Clang, that means
// GCC 4.8+ has a nice way to do this // -msse2 is on, which means the compiler is allowed to use SSE2
return __builtin_cpu_supports("sse2"); // instructions at will, and so are we.
#else return 1;
// portable way to do this, preferably without using GCC inline ASM?
// just bail for now.
return 0;
#endif
} }
#endif #endif
#endif #endif
@ -1691,6 +1690,8 @@ typedef struct
int succ_high; int succ_high;
int succ_low; int succ_low;
int eob_run; int eob_run;
int jfif;
int app14_color_transform; // Adobe APP14 tag
int rgb; int rgb;
int scan_n, order[4]; int scan_n, order[4];
@ -1761,7 +1762,7 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
// magnitude code followed by receive_extend code // magnitude code followed by receive_extend code
int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
int m = 1 << (magbits - 1); int m = 1 << (magbits - 1);
if (k < m) k += (-1 << magbits) + 1; if (k < m) k += (~0U << magbits) + 1;
// if the result is small enough, we can fit it in fast_ac table // if the result is small enough, we can fit it in fast_ac table
if (k >= -128 && k <= 127) if (k >= -128 && k <= 127)
fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits)); fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits));
@ -2625,7 +2626,7 @@ static void stbi__jpeg_reset(stbi__jpeg *j)
j->code_bits = 0; j->code_bits = 0;
j->code_buffer = 0; j->code_buffer = 0;
j->nomore = 0; j->nomore = 0;
j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0;
j->marker = STBI__MARKER_none; j->marker = STBI__MARKER_none;
j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
j->eob_run = 0; j->eob_run = 0;
@ -2839,11 +2840,49 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
} }
return L==0; return L==0;
} }
// check for comment block or APP blocks // check for comment block or APP blocks
if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
stbi__skip(z->s, stbi__get16be(z->s)-2); L = stbi__get16be(z->s);
if (L < 2) {
if (m == 0xFE)
return stbi__err("bad COM len","Corrupt JPEG");
else
return stbi__err("bad APP len","Corrupt JPEG");
}
L -= 2;
if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
static const unsigned char tag[5] = {'J','F','I','F','\0'};
int ok = 1;
int i;
for (i=0; i < 5; ++i)
if (stbi__get8(z->s) != tag[i])
ok = 0;
L -= 5;
if (ok)
z->jfif = 1;
} else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
static const unsigned char tag[6] = {'A','d','o','b','e','\0'};
int ok = 1;
int i;
for (i=0; i < 6; ++i)
if (stbi__get8(z->s) != tag[i])
ok = 0;
L -= 6;
if (ok) {
stbi__get8(z->s); // version
stbi__get16be(z->s); // flags0
stbi__get16be(z->s); // flags1
z->app14_color_transform = stbi__get8(z->s); // color transform
L -= 6;
}
}
stbi__skip(z->s, L);
return 1; return 1;
} }
return stbi__err("unknown marker","Corrupt JPEG"); return stbi__err("unknown marker","Corrupt JPEG");
} }
@ -2918,7 +2957,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
c = stbi__get8(s); c = stbi__get8(s);
if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG"); // JFIF requires if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
s->img_n = c; s->img_n = c;
for (i=0; i < c; ++i) { for (i=0; i < c; ++i) {
z->img_comp[i].data = NULL; z->img_comp[i].data = NULL;
@ -2931,7 +2970,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
for (i=0; i < s->img_n; ++i) { for (i=0; i < s->img_n; ++i) {
static unsigned char rgb[3] = { 'R', 'G', 'B' }; static unsigned char rgb[3] = { 'R', 'G', 'B' };
z->img_comp[i].id = stbi__get8(s); z->img_comp[i].id = stbi__get8(s);
if (z->img_comp[i].id == rgb[i]) if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
++z->rgb; ++z->rgb;
q = stbi__get8(s); q = stbi__get8(s);
z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
@ -3004,6 +3043,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
{ {
int m; int m;
z->jfif = 0;
z->app14_color_transform = -1; // valid values are 0,1,2
z->marker = STBI__MARKER_none; // initialize cached marker to empty z->marker = STBI__MARKER_none; // initialize cached marker to empty
m = stbi__get_marker(z); m = stbi__get_marker(z);
if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
@ -3473,9 +3514,16 @@ typedef struct
int ypos; // which pre-expansion row we're on int ypos; // which pre-expansion row we're on
} stbi__resample; } stbi__resample;
// fast 0..255 * 0..255 => 0..255 rounded multiplication
static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y)
{
unsigned int t = x*y + 128;
return (stbi_uc) ((t + (t >>8)) >> 8);
}
static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
{ {
int n, decode_n; int n, decode_n, is_rgb;
z->s->img_n = 0; // make stbi__cleanup_jpeg safe z->s->img_n = 0; // make stbi__cleanup_jpeg safe
// validate req_comp // validate req_comp
@ -3485,9 +3533,11 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
// determine actual number of components to generate // determine actual number of components to generate
n = req_comp ? req_comp : z->s->img_n; n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
if (z->s->img_n == 3 && n < 3 && z->rgb != 3) is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
if (z->s->img_n == 3 && n < 3 && !is_rgb)
decode_n = 1; decode_n = 1;
else else
decode_n = z->s->img_n; decode_n = z->s->img_n;
@ -3547,7 +3597,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
if (n >= 3) { if (n >= 3) {
stbi_uc *y = coutput[0]; stbi_uc *y = coutput[0];
if (z->s->img_n == 3) { if (z->s->img_n == 3) {
if (z->rgb == 3) { if (is_rgb) {
for (i=0; i < z->s->img_x; ++i) { for (i=0; i < z->s->img_x; ++i) {
out[0] = y[i]; out[0] = y[i];
out[1] = coutput[1][i]; out[1] = coutput[1][i];
@ -3558,6 +3608,28 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
} else { } else {
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
} }
} else if (z->s->img_n == 4) {
if (z->app14_color_transform == 0) { // CMYK
for (i=0; i < z->s->img_x; ++i) {
stbi_uc k = coutput[3][i];
out[0] = stbi__blinn_8x8(coutput[0][i], k);
out[1] = stbi__blinn_8x8(coutput[1][i], k);
out[2] = stbi__blinn_8x8(coutput[2][i], k);
out[3] = 255;
out += n;
}
} else if (z->app14_color_transform == 2) { // YCCK
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
for (i=0; i < z->s->img_x; ++i) {
stbi_uc k = coutput[3][i];
out[0] = stbi__blinn_8x8(255 - out[0], k);
out[1] = stbi__blinn_8x8(255 - out[1], k);
out[2] = stbi__blinn_8x8(255 - out[2], k);
out += n;
}
} else { // YCbCr + alpha? Ignore the fourth channel for now
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
}
} else } else
for (i=0; i < z->s->img_x; ++i) { for (i=0; i < z->s->img_x; ++i) {
out[0] = out[1] = out[2] = y[i]; out[0] = out[1] = out[2] = y[i];
@ -3565,7 +3637,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
out += n; out += n;
} }
} else { } else {
if (z->rgb == 3) { if (is_rgb) {
if (n == 1) if (n == 1)
for (i=0; i < z->s->img_x; ++i) for (i=0; i < z->s->img_x; ++i)
*out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
@ -3575,6 +3647,22 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
out[1] = 255; out[1] = 255;
} }
} }
} else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
for (i=0; i < z->s->img_x; ++i) {
stbi_uc k = coutput[3][i];
stbi_uc r = stbi__blinn_8x8(coutput[0][i], k);
stbi_uc g = stbi__blinn_8x8(coutput[1][i], k);
stbi_uc b = stbi__blinn_8x8(coutput[2][i], k);
out[0] = stbi__compute_y(r, g, b);
out[1] = 255;
out += n;
}
} else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
for (i=0; i < z->s->img_x; ++i) {
out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
out[1] = 255;
out += n;
}
} else { } else {
stbi_uc *y = coutput[0]; stbi_uc *y = coutput[0];
if (n == 1) if (n == 1)
@ -3587,7 +3675,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
stbi__cleanup_jpeg(z); stbi__cleanup_jpeg(z);
*out_x = z->s->img_x; *out_x = z->s->img_x;
*out_y = z->s->img_y; *out_y = z->s->img_y;
if (comp) *comp = z->s->img_n; // report original components, not output if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
return output; return output;
} }
} }
@ -3596,6 +3684,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
{ {
unsigned char* result; unsigned char* result;
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
STBI_NOTUSED(ri);
j->s = s; j->s = s;
stbi__setup_jpeg(j); stbi__setup_jpeg(j);
result = load_jpeg_image(j, x,y,comp,req_comp); result = load_jpeg_image(j, x,y,comp,req_comp);
@ -3623,7 +3712,7 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
} }
if (x) *x = j->s->img_x; if (x) *x = j->s->img_x;
if (y) *y = j->s->img_y; if (y) *y = j->s->img_y;
if (comp) *comp = j->s->img_n; if (comp) *comp = j->s->img_n >= 3 ? 3 : 1;
return 1; return 1;
} }
@ -3680,7 +3769,7 @@ stbi_inline static int stbi__bit_reverse(int v, int bits)
return stbi__bitreverse16(v) >> (16-bits); return stbi__bitreverse16(v) >> (16-bits);
} }
static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num) static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num)
{ {
int i,k=0; int i,k=0;
int code, next_code[16], sizes[17]; int code, next_code[16], sizes[17];
@ -3970,9 +4059,24 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
return 1; return 1;
} }
// @TODO: should statically initialize these for optimal thread safety static const stbi_uc stbi__zdefault_length[288] =
static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32]; {
static void stbi__init_zdefaults(void) 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8
};
static const stbi_uc stbi__zdefault_distance[32] =
{
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
};
/*
Init algorithm:
{ {
int i; // use <= to match clearly with spec int i; // use <= to match clearly with spec
for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8;
@ -3982,6 +4086,7 @@ static void stbi__init_zdefaults(void)
for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5;
} }
*/
static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
{ {
@ -4000,7 +4105,6 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
} else { } else {
if (type == 1) { if (type == 1) {
// use fixed code lengths // use fixed code lengths
if (!stbi__zdefault_distance[31]) stbi__init_zdefaults();
if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0;
if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0;
} else { } else {
@ -4201,7 +4305,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
for (j=0; j < y; ++j) { for (j=0; j < y; ++j) {
stbi_uc *cur = a->out + stride*j; stbi_uc *cur = a->out + stride*j;
stbi_uc *prior = cur - stride; stbi_uc *prior;
int filter = *raw++; int filter = *raw++;
if (filter > 4) if (filter > 4)
@ -4213,6 +4317,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
filter_bytes = 1; filter_bytes = 1;
width = img_width_bytes; width = img_width_bytes;
} }
prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
// if first row, use special filter that doesn't sample previous row // if first row, use special filter that doesn't sample previous row
if (j == 0) filter = first_row_filter[filter]; if (j == 0) filter = first_row_filter[filter];
@ -4605,7 +4710,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG");
@ -4888,7 +4993,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
info->offset = stbi__get32le(s); info->offset = stbi__get32le(s);
info->hsz = hsz = stbi__get32le(s); info->hsz = hsz = stbi__get32le(s);
info->mr = info->mg = info->mb = info->ma = 0; info->mr = info->mg = info->mb = info->ma = 0;
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
if (hsz == 12) { if (hsz == 12) {
s->img_x = stbi__get16le(s); s->img_x = stbi__get16le(s);
@ -4973,7 +5078,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi__bmp_data info; stbi__bmp_data info;
STBI_NOTUSED(ri); STBI_NOTUSED(ri);
info.all_a = 255; info.all_a = 255;
if (stbi__bmp_parse_header(s, &info) == NULL) if (stbi__bmp_parse_header(s, &info) == NULL)
return NULL; // error code already set return NULL; // error code already set
@ -5092,7 +5197,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi__skip(s, pad); stbi__skip(s, pad);
} }
} }
// if alpha channel is all 0s, replace with all 255s // if alpha channel is all 0s, replace with all 255s
if (target == 4 && all_a == 0) if (target == 4 && all_a == 0)
for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
@ -5875,9 +5980,11 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c
static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri)
{ {
stbi_uc *result; stbi_uc *result;
int i, x,y; int i, x,y, internal_comp;
STBI_NOTUSED(ri); STBI_NOTUSED(ri);
if (!comp) comp = &internal_comp;
for (i=0; i<92; ++i) for (i=0; i<92; ++i)
stbi__get8(s); stbi__get8(s);
@ -6496,6 +6603,11 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
char buffer[STBI__HDR_BUFLEN]; char buffer[STBI__HDR_BUFLEN];
char *token; char *token;
int valid = 0; int valid = 0;
int dummy;
if (!x) x = &dummy;
if (!y) y = &dummy;
if (!comp) comp = &dummy;
if (stbi__hdr_test(s) == 0) { if (stbi__hdr_test(s) == 0) {
stbi__rewind( s ); stbi__rewind( s );
@ -6537,14 +6649,14 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
void *p; void *p;
stbi__bmp_data info; stbi__bmp_data info;
info.all_a = 255; info.all_a = 255;
p = stbi__bmp_parse_header(s, &info); p = stbi__bmp_parse_header(s, &info);
stbi__rewind( s ); stbi__rewind( s );
if (p == NULL) if (p == NULL)
return 0; return 0;
*x = s->img_x; if (x) *x = s->img_x;
*y = s->img_y; if (y) *y = s->img_y;
*comp = info.ma ? 4 : 3; if (comp) *comp = info.ma ? 4 : 3;
return 1; return 1;
} }
#endif #endif
@ -6552,7 +6664,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_PSD #ifndef STBI_NO_PSD
static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
{ {
int channelCount; int channelCount, dummy;
if (!x) x = &dummy;
if (!y) y = &dummy;
if (!comp) comp = &dummy;
if (stbi__get32be(s) != 0x38425053) { if (stbi__get32be(s) != 0x38425053) {
stbi__rewind( s ); stbi__rewind( s );
return 0; return 0;
@ -6585,9 +6700,13 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_PIC #ifndef STBI_NO_PIC
static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
{ {
int act_comp=0,num_packets=0,chained; int act_comp=0,num_packets=0,chained,dummy;
stbi__pic_packet packets[10]; stbi__pic_packet packets[10];
if (!x) x = &dummy;
if (!y) y = &dummy;
if (!comp) comp = &dummy;
if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
stbi__rewind(s); stbi__rewind(s);
return 0; return 0;
@ -6673,7 +6792,7 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
*x = s->img_x; *x = s->img_x;
*y = s->img_y; *y = s->img_y;
*comp = s->img_n; if (comp) *comp = s->img_n;
if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
return stbi__errpuc("too large", "PNM too large"); return stbi__errpuc("too large", "PNM too large");
@ -6727,16 +6846,20 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c)
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
{ {
int maxv; int maxv, dummy;
char c, p, t; char c, p, t;
stbi__rewind( s ); if (!x) x = &dummy;
if (!y) y = &dummy;
if (!comp) comp = &dummy;
stbi__rewind(s);
// Get identifier // Get identifier
p = (char) stbi__get8(s); p = (char) stbi__get8(s);
t = (char) stbi__get8(s); t = (char) stbi__get8(s);
if (p != 'P' || (t != '5' && t != '6')) { if (p != 'P' || (t != '5' && t != '6')) {
stbi__rewind( s ); stbi__rewind(s);
return 0; return 0;
} }
@ -6843,6 +6966,11 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/* /*
revision history: revision history:
2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
warning fixes; disable run-time SSE detection on gcc;
uniform handling of optional "return" values;
thread-safe initialization of zlib tables
2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
2.13 (2016-11-29) add 16-bit API, only supported for PNG right now 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
2.11 (2016-04-02) allocate large structures on the stack 2.11 (2016-04-02) allocate large structures on the stack
@ -7012,38 +7140,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
ALTERNATIVE A - MIT License ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of 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 this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 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 of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions: so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org) ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain. This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 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, software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means. commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this 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 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 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 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 overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law. this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 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 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 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. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*/ */

View File

@ -1,11 +1,170 @@
// stretchy_buffer.h - v1.02 - public domain - nothings.org/stb // stretchy_buffer.h - v1.02 - public domain - nothings.org/stb
// a vector<>-like dynamic array for C // a vector<>-like dynamic array for C
// //
// version history:
// 1.02 - tweaks to syntax for no good reason
// 1.01 - added a "common uses" documentation section
// 1.0 - fixed bug in the version I posted prematurely
// 0.9 - rewrite to try to avoid strict-aliasing optimization
// issues, but won't compile as C++
//
// Will probably not work correctly with strict-aliasing optimizations.
//
// The idea:
//
// This implements an approximation to C++ vector<> for C, in that it
// provides a generic definition for dynamic arrays which you can
// still access in a typesafe way using arr[i] or *(arr+i). However,
// it is simply a convenience wrapper around the common idiom of
// of keeping a set of variables (in a struct or globals) which store
// - pointer to array
// - the length of the "in-use" part of the array
// - the current size of the allocated array
//
// I find it to be the single most useful non-built-in-structure when
// programming in C (hash tables a close second), but to be clear
// it lacks many of the capabilities of C++ vector<>: there is no
// range checking, the object address isn't stable (see next section
// for details), the set of methods available is small (although
// the file stb.h has another implementation of stretchy buffers
// called 'stb_arr' which provides more methods, e.g. for insertion
// and deletion).
//
// How to use:
//
// Unlike other stb header file libraries, there is no need to
// define an _IMPLEMENTATION symbol. Every #include creates as
// much implementation is needed.
//
// stretchy_buffer.h does not define any types, so you do not
// need to #include it to before defining data types that are
// stretchy buffers, only in files that *manipulate* stretchy
// buffers.
//
// If you want a stretchy buffer aka dynamic array containing
// objects of TYPE, declare such an array as:
//
// TYPE *myarray = NULL;
//
// (There is no typesafe way to distinguish between stretchy
// buffers and regular arrays/pointers; this is necessary to
// make ordinary array indexing work on these objects.)
//
// Unlike C++ vector<>, the stretchy_buffer has the same
// semantics as an object that you manually malloc and realloc.
// The pointer may relocate every time you add a new object
// to it, so you:
//
// 1. can't take long-term pointers to elements of the array
// 2. have to return the pointer from functions which might expand it
// (either as a return value or by storing it to a ptr-to-ptr)
//
// Now you can do the following things with this array:
//
// sb_free(TYPE *a) free the array
// sb_count(TYPE *a) the number of elements in the array
// sb_push(TYPE *a, TYPE v) adds v on the end of the array, a la push_back
// sb_add(TYPE *a, int n) adds n uninitialized elements at end of array & returns pointer to first added
// sb_last(TYPE *a) returns an lvalue of the last item in the array
// a[n] access the nth (counting from 0) element of the array
//
// #define STRETCHY_BUFFER_NO_SHORT_NAMES to only export
// names of the form 'stb_sb_' if you have a name that would
// otherwise collide.
//
// Note that these are all macros and many of them evaluate
// their arguments more than once, so the arguments should
// be side-effect-free.
//
// Note that 'TYPE *a' in sb_push and sb_add must be lvalues
// so that the library can overwrite the existing pointer if
// the object has to be reallocated.
//
// In an out-of-memory condition, the code will try to
// set up a null-pointer or otherwise-invalid-pointer
// exception to happen later. It's possible optimizing
// compilers could detect this write-to-null statically
// and optimize away some of the code, but it should only
// be along the failure path. Nevertheless, for more security
// in the face of such compilers, #define STRETCHY_BUFFER_OUT_OF_MEMORY
// to a statement such as assert(0) or exit(1) or something
// to force a failure when out-of-memory occurs.
//
// Common use:
//
// The main application for this is when building a list of
// things with an unknown quantity, either due to loading from
// a file or through a process which produces an unpredictable
// number.
//
// My most common idiom is something like:
//
// SomeStruct *arr = NULL;
// while (something)
// {
// SomeStruct new_one;
// new_one.whatever = whatever;
// new_one.whatup = whatup;
// new_one.foobar = barfoo;
// sb_push(arr, new_one);
// }
//
// and various closely-related factorings of that. For example,
// you might have several functions to create/init new SomeStructs,
// and if you use the above idiom, you might prefer to make them
// return structs rather than take non-const-pointers-to-structs,
// so you can do things like:
//
// SomeStruct *arr = NULL;
// while (something)
// {
// if (case_A) {
// sb_push(arr, some_func1());
// } else if (case_B) {
// sb_push(arr, some_func2());
// } else {
// sb_push(arr, some_func3());
// }
// }
//
// Note that the above relies on the fact that sb_push doesn't
// evaluate its second argument more than once. The macros do
// evaluate the *array* argument multiple times, and numeric
// arguments may be evaluated multiple times, but you can rely
// on the second argument of sb_push being evaluated only once.
//
// Of course, you don't have to store bare objects in the array;
// if you need the objects to have stable pointers, store an array
// of pointers instead:
//
// SomeStruct **arr = NULL;
// while (something)
// {
// SomeStruct *new_one = malloc(sizeof(*new_one));
// new_one->whatever = whatever;
// new_one->whatup = whatup;
// new_one->foobar = barfoo;
// sb_push(arr, new_one);
// }
//
// How it works:
//
// A long-standing tradition in things like malloc implementations
// is to store extra data before the beginning of the block returned
// to the user. The stretchy buffer implementation here uses the
// same trick; the current-count and current-allocation-size are
// stored before the beginning of the array returned to the user.
// (This means you can't directly free() the pointer, because the
// allocated pointer is different from the type-safe pointer provided
// to the user.)
//
// The details are trivial and implementation is straightforward;
// the main trick is in realizing in the first place that it's
// possible to do this in a generic, type-safe way in C.
//
// LICENSE // LICENSE
// //
// This software is dual-licensed to the public domain and under the following // See end of file for license information.
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
#ifndef STB_STRETCHY_BUFFER_H_INCLUDED #ifndef STB_STRETCHY_BUFFER_H_INCLUDED
#define STB_STRETCHY_BUFFER_H_INCLUDED #define STB_STRETCHY_BUFFER_H_INCLUDED
@ -53,3 +212,46 @@ static void * stb__sbgrowf(void *arr, int increment, int itemsize)
} }
} }
#endif // STB_STRETCHY_BUFFER_H_INCLUDED #endif // STB_STRETCHY_BUFFER_H_INCLUDED
/*
------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------
*/