Updated STB libs to latest version

This commit is contained in:
raysan5 2017-04-16 14:06:04 +02:00
parent f5894278b7
commit c67cffea38
8 changed files with 707 additions and 404 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
Do this:
@ -21,7 +21,7 @@
avoid problematic images and only need the trivial interface
JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
PNG 1/2/4/8-bit-per-channel (16 bpc not supported)
PNG 1/2/4/8/16-bit-per-channel
TGA (not sure what subset, if a subset)
BMP non-1bpp, non-RLE
@ -42,110 +42,14 @@
Full documentation under "DOCUMENTATION" below.
Revision 2.00 release notes:
LICENSE
- Progressive JPEG is now supported.
See end of file for license information.
- PPM and PGM binary formats are now supported, thanks to Ken Miller.
RECENT REVISION HISTORY:
- x86 platforms now make use of SSE2 SIMD instructions for
JPEG decoding, and ARM platforms can use NEON SIMD if requested.
This work was done by Fabian "ryg" Giesen. SSE2 is used by
default, but NEON must be enabled explicitly; see docs.
With other JPEG optimizations included in this version, we see
2x speedup on a JPEG on an x86 machine, and a 1.5x speedup
on a JPEG on an ARM machine, relative to previous versions of this
library. The same results will not obtain for all JPGs and for all
x86/ARM machines. (Note that progressive JPEGs are significantly
slower to decode than regular JPEGs.) This doesn't mean that this
is the fastest JPEG decoder in the land; rather, it brings it
closer to parity with standard libraries. If you want the fastest
decode, look elsewhere. (See "Philosophy" section of docs below.)
See final bullet items below for more info on SIMD.
- Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing
the memory allocator. Unlike other STBI libraries, these macros don't
support a context parameter, so if you need to pass a context in to
the allocator, you'll have to store it in a global or a thread-local
variable.
- Split existing STBI_NO_HDR flag into two flags, STBI_NO_HDR and
STBI_NO_LINEAR.
STBI_NO_HDR: suppress implementation of .hdr reader format
STBI_NO_LINEAR: suppress high-dynamic-range light-linear float API
- You can suppress implementation of any of the decoders to reduce
your code footprint by #defining one or more of the following
symbols before creating the implementation.
STBI_NO_JPEG
STBI_NO_PNG
STBI_NO_BMP
STBI_NO_PSD
STBI_NO_TGA
STBI_NO_GIF
STBI_NO_HDR
STBI_NO_PIC
STBI_NO_PNM (.ppm and .pgm)
- You can request *only* certain decoders and suppress all other ones
(this will be more forward-compatible, as addition of new decoders
doesn't require you to disable them explicitly):
STBI_ONLY_JPEG
STBI_ONLY_PNG
STBI_ONLY_BMP
STBI_ONLY_PSD
STBI_ONLY_TGA
STBI_ONLY_GIF
STBI_ONLY_HDR
STBI_ONLY_PIC
STBI_ONLY_PNM (.ppm and .pgm)
Note that you can define multiples of these, and you will get all
of them ("only x" and "only y" is interpreted to mean "only x&y").
- If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
- Compilation of all SIMD code can be suppressed with
#define STBI_NO_SIMD
It should not be necessary to disable SIMD unless you have issues
compiling (e.g. using an x86 compiler which doesn't support SSE
intrinsics or that doesn't support the method used to detect
SSE2 support at run-time), and even those can be reported as
bugs so I can refine the built-in compile-time checking to be
smarter.
- The old STBI_SIMD system which allowed installing a user-defined
IDCT etc. has been removed. If you need this, don't upgrade. My
assumption is that almost nobody was doing this, and those who
were will find the built-in SIMD more satisfactory anyway.
- RGB values computed for JPEG images are slightly different from
previous versions of stb_image. (This is due to using less
integer precision in SIMD.) The C code has been adjusted so
that the same RGB values will be computed regardless of whether
SIMD support is available, so your app should always produce
consistent results. But these results are slightly different from
previous versions. (Specifically, about 3% of available YCbCr values
will compute different RGB results from pre-1.49 versions by +-1;
most of the deviating values are one smaller in the G channel.)
- If you must produce consistent results with previous versions of
stb_image, #define STBI_JPEG_OLD and you will get the same results
you used to; however, you will not get the SIMD speedups for
the YCbCr-to-RGB conversion step (although you should still see
significant JPEG speedup from the other changes).
Please note that STBI_JPEG_OLD is a temporary feature; it will be
removed in future versions of the library. It is only intended for
near-term back-compatibility use.
Latest 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.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.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
@ -174,32 +78,26 @@
Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
github:urraka (animated gif) Junggon Kim (PNM comments)
Daniel Gibson (16-bit TGA)
socks-the-fox (16-bit TGA)
socks-the-fox (16-bit PNG)
Jeremy Sawicki (handle all ImageNet JPGs)
Optimizations & bugfixes
Fabian "ryg" Giesen
Arseny Kapoulkine
Bug & warning fixes
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson
Dave Moore Roy Eltham Hayaki Saito Phil Jordan
Won Chun Luke Graham Johan Duparc Nathan Reed
the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis
Janez Zemva John Bartholomew Michal Cichon github:svdijk
Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson
Laurent Gomila Cort Stratton Sergio Gonzalez github:romigrou
Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan
Ryamond Barbiero Paul Du Bois Engin Manap github:snagar
Michaelangel007@github Oriol Ferrer Mesia Dale Weiler github:Zelex
Philipp Wiesemann Josh Tobin github:rlyeh github:grim210@github
Blazej Dariusz Roszkowski github:sammyhw
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.
Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
Dave Moore Roy Eltham Hayaki Saito Nathan Reed
Won Chun Luke Graham Johan Duparc Nick Verigakis
the Horde3D community Thomas Ruf Ronny Chevalier Baldur Karlsson
Janez Zemva John Bartholomew Michal Cichon github:rlyeh
Jonathan Blow Ken Hamada Tero Hanninen github:romigrou
Laurent Gomila Cort Stratton Sergio Gonzalez github:svdijk
Aruelien Pocheville Thibault Reuille Cass Everitt github:snagar
Ryamond Barbiero Paul Du Bois Engin Manap github:Zelex
Michaelangel007@github Philipp Wiesemann Dale Weiler github:grim210
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:sammyhw
Blazej Dariusz Roszkowski Gregory Mullen github:phprus
*/
@ -274,13 +172,13 @@ publish, and distribute this file as you see fit.
// and for best performance I may provide less-easy-to-use APIs that give higher
// performance, in addition to the easy to use ones. Nevertheless, it's important
// to keep in mind that from the standpoint of you, a client of this library,
// all you care about is #1 and #3, and stb libraries do not emphasize #3 above all.
// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
//
// Some secondary priorities arise directly from the first two, some of which
// make more explicit reasons why performance can't be emphasized.
//
// - Portable ("ease of use")
// - Small footprint ("easy to maintain")
// - Small source code footprint ("easy to maintain")
// - No dependencies ("ease of use")
//
// ===========================================================================
@ -312,13 +210,6 @@ publish, and distribute this file as you see fit.
// (at least this is true for iOS and Android). Therefore, the NEON support is
// toggled by a build flag: define STBI_NEON to get NEON loops.
//
// The output of the JPEG decoder is slightly different from versions where
// SIMD support was introduced (that is, for versions before 1.49). The
// difference is only +-1 in the 8-bit RGB channels, and only on a small
// fraction of pixels. You can force the pre-1.49 behavior by defining
// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path
// and hence cost some performance.
//
// If for some reason you do not want to use any of SIMD code, or if
// you have issues compiling it, you can disable it entirely by
// defining STBI_NO_SIMD.
@ -374,20 +265,47 @@ publish, and distribute this file as you see fit.
// says there's premultiplied data (currently only happens in iPhone images,
// and only if iPhone convert-to-rgb processing is on).
//
// ===========================================================================
//
// ADDITIONAL CONFIGURATION
//
// - You can suppress implementation of any of the decoders to reduce
// your code footprint by #defining one or more of the following
// symbols before creating the implementation.
//
// STBI_NO_JPEG
// STBI_NO_PNG
// STBI_NO_BMP
// STBI_NO_PSD
// STBI_NO_TGA
// STBI_NO_GIF
// STBI_NO_HDR
// STBI_NO_PIC
// STBI_NO_PNM (.ppm and .pgm)
//
// - You can request *only* certain decoders and suppress all other ones
// (this will be more forward-compatible, as addition of new decoders
// doesn't require you to disable them explicitly):
//
// STBI_ONLY_JPEG
// STBI_ONLY_PNG
// STBI_ONLY_BMP
// STBI_ONLY_PSD
// STBI_ONLY_TGA
// STBI_ONLY_GIF
// STBI_ONLY_HDR
// STBI_ONLY_PIC
// STBI_ONLY_PNM (.ppm and .pgm)
//
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
//
#ifndef STBI_NO_STDIO
#include <stdio.h>
#endif // STBI_NO_STDIO
#define STBI_NO_HDR // RaySan: not required by raylib
//#define STBI_NO_SIMD // RaySan: issues when compiling with GCC 4.7.2
// NOTE: Added to work with raylib on Android
#if defined(PLATFORM_ANDROID)
#include "utils.h" // RaySan: Android fopen function map
#endif
#define STBI_VERSION 1
enum
@ -666,12 +584,14 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#define STBI__X86_TARGET
#endif
#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
// NOTE: not clear do we actually need this for the 64-bit path?
#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
// (but compiling with -msse2 allows the compiler to use SSE2 everywhere;
// this is just broken and gcc are jerks for not fixing it properly
// http://www.virtualdub.org/blog/pivot/entry.php?id=363 )
// which in turn means it gets to use SSE2 everywhere. This is unfortunate,
// but previous attempts to provide the SSE2 functions with runtime
// 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
#endif
@ -729,14 +649,10 @@ static int stbi__sse2_available()
static int stbi__sse2_available()
{
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later
// GCC 4.8+ has a nice way to do this
return __builtin_cpu_supports("sse2");
#else
// portable way to do this, preferably without using GCC inline ASM?
// just bail for now.
return 0;
#endif
// If we're even attempting to compile this on GCC/Clang, that means
// -msse2 is on, which means the compiler is allowed to use SSE2
// instructions at will, and so are we.
return 1;
}
#endif
#endif
@ -1738,7 +1654,7 @@ typedef struct
stbi__context *s;
stbi__huffman huff_dc[4];
stbi__huffman huff_ac[4];
stbi_uc dequant[4][64];
stbi__uint16 dequant[4][64];
stbi__int16 fast_ac[4][1 << FAST_BITS];
// sizes for components, interleaved MCUs
@ -1774,6 +1690,8 @@ typedef struct
int succ_high;
int succ_low;
int eob_run;
int jfif;
int app14_color_transform; // Adobe APP14 tag
int rgb;
int scan_n, order[4];
@ -1844,7 +1762,7 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
// magnitude code followed by receive_extend code
int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
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 (k >= -128 && k <= 127)
fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits));
@ -1859,6 +1777,7 @@ static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
int b = j->nomore ? 0 : stbi__get8(j->s);
if (b == 0xff) {
int c = stbi__get8(j->s);
while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes
if (c != 0) {
j->marker = (unsigned char) c;
j->nomore = 1;
@ -1983,7 +1902,7 @@ static stbi_uc stbi__jpeg_dezigzag[64+15] =
};
// decode one 64-entry block--
static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi_uc *dequant)
static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant)
{
int diff,dc,k;
int t;
@ -2692,7 +2611,7 @@ static stbi_uc stbi__get_marker(stbi__jpeg *j)
x = stbi__get8(j->s);
if (x != 0xff) return STBI__MARKER_none;
while (x == 0xff)
x = stbi__get8(j->s);
x = stbi__get8(j->s); // consume repeated 0xff fill bytes
return x;
}
@ -2707,7 +2626,7 @@ static void stbi__jpeg_reset(stbi__jpeg *j)
j->code_bits = 0;
j->code_buffer = 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->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
j->eob_run = 0;
@ -2839,7 +2758,7 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
}
}
static void stbi__jpeg_dequantize(short *data, stbi_uc *dequant)
static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant)
{
int i;
for (i=0; i < 64; ++i)
@ -2881,13 +2800,14 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
L = stbi__get16be(z->s)-2;
while (L > 0) {
int q = stbi__get8(z->s);
int p = q >> 4;
int p = q >> 4, sixteen = (p != 0);
int t = q & 15,i;
if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG");
if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG");
if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG");
for (i=0; i < 64; ++i)
z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s);
L -= 65;
z->dequant[t][stbi__jpeg_dezigzag[i]] = sixteen ? stbi__get16be(z->s) : stbi__get8(z->s);
L -= (sixteen ? 129 : 65);
}
return L==0;
@ -2920,12 +2840,50 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
}
return L==0;
}
// check for comment block or APP blocks
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 0;
return stbi__err("unknown marker","Corrupt JPEG");
}
// after we see SOS
@ -2999,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_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
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;
for (i=0; i < c; ++i) {
z->img_comp[i].data = NULL;
@ -3012,13 +2970,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
for (i=0; i < s->img_n; ++i) {
static unsigned char rgb[3] = { 'R', 'G', 'B' };
z->img_comp[i].id = stbi__get8(s);
if (z->img_comp[i].id != i+1) // JFIF requires
if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files!
// somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format)
if (z->img_comp[i].id != rgb[i])
return stbi__err("bad component ID","Corrupt JPEG");
if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
++z->rgb;
}
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].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
@ -3090,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)
{
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
m = stbi__get_marker(z);
if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
@ -3131,12 +3086,15 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j)
if (x == 255) {
j->marker = stbi__get8(j->s);
break;
} else if (x != 0) {
return stbi__err("junk before marker", "Corrupt JPEG");
}
}
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
}
} else if (stbi__DNL(m)) {
int Ld = stbi__get16be(j->s);
stbi__uint32 NL = stbi__get16be(j->s);
if (Ld != 4) stbi__err("bad DNL len", "Corrupt JPEG");
if (NL != j->s->img_y) stbi__err("bad DNL height", "Corrupt JPEG");
} else {
if (!stbi__process_marker(j, m)) return 0;
}
@ -3355,38 +3313,9 @@ static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_
return out;
}
#ifdef STBI_JPEG_OLD
// this is the same YCbCr-to-RGB calculation that stb_image has used
// historically before the algorithm changes in 1.49
#define float2fixed(x) ((int) ((x) * 65536 + 0.5))
static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
{
int i;
for (i=0; i < count; ++i) {
int y_fixed = (y[i] << 16) + 32768; // rounding
int r,g,b;
int cr = pcr[i] - 128;
int cb = pcb[i] - 128;
r = y_fixed + cr*float2fixed(1.40200f);
g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f);
b = y_fixed + cb*float2fixed(1.77200f);
r >>= 16;
g >>= 16;
b >>= 16;
if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
out[0] = (stbi_uc)r;
out[1] = (stbi_uc)g;
out[2] = (stbi_uc)b;
out[3] = 255;
out += step;
}
}
#else
// this is a reduced-precision calculation of YCbCr-to-RGB introduced
// to make sure the code produces the same results in both SIMD and scalar
#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8)
#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8)
static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
{
int i;
@ -3395,9 +3324,9 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
int r,g,b;
int cr = pcr[i] - 128;
int cb = pcb[i] - 128;
r = y_fixed + cr* float2fixed(1.40200f);
g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000);
b = y_fixed + cb* float2fixed(1.77200f);
r = y_fixed + cr* stbi__float2fixed(1.40200f);
g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
b = y_fixed + cb* stbi__float2fixed(1.77200f);
r >>= 20;
g >>= 20;
b >>= 20;
@ -3411,7 +3340,6 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
out += step;
}
}
#endif
#if defined(STBI_SSE2) || defined(STBI_NEON)
static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step)
@ -3530,9 +3458,9 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
int r,g,b;
int cr = pcr[i] - 128;
int cb = pcb[i] - 128;
r = y_fixed + cr* float2fixed(1.40200f);
g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000);
b = y_fixed + cb* float2fixed(1.77200f);
r = y_fixed + cr* stbi__float2fixed(1.40200f);
g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
b = y_fixed + cb* stbi__float2fixed(1.77200f);
r >>= 20;
g >>= 20;
b >>= 20;
@ -3558,18 +3486,14 @@ static void stbi__setup_jpeg(stbi__jpeg *j)
#ifdef STBI_SSE2
if (stbi__sse2_available()) {
j->idct_block_kernel = stbi__idct_simd;
#ifndef STBI_JPEG_OLD
j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
#endif
j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
}
#endif
#ifdef STBI_NEON
j->idct_block_kernel = stbi__idct_simd;
#ifndef STBI_JPEG_OLD
j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
#endif
j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
#endif
}
@ -3590,9 +3514,16 @@ typedef struct
int ypos; // which pre-expansion row we're on
} 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)
{
int n, decode_n;
int n, decode_n, is_rgb;
z->s->img_n = 0; // make stbi__cleanup_jpeg safe
// validate req_comp
@ -3602,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; }
// 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)
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;
else
decode_n = z->s->img_n;
@ -3664,7 +3597,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
if (n >= 3) {
stbi_uc *y = coutput[0];
if (z->s->img_n == 3) {
if (z->rgb == 3) {
if (is_rgb) {
for (i=0; i < z->s->img_x; ++i) {
out[0] = y[i];
out[1] = coutput[1][i];
@ -3675,12 +3608,61 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
} else {
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
for (i=0; i < z->s->img_x; ++i) {
out[0] = out[1] = out[2] = y[i];
out[3] = 255; // not used if n==3
out += n;
}
} else {
if (is_rgb) {
if (n == 1)
for (i=0; i < z->s->img_x; ++i)
*out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
else {
for (i=0; i < z->s->img_x; ++i, out += 2) {
out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
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 {
stbi_uc *y = coutput[0];
if (n == 1)
@ -3689,10 +3671,11 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
}
}
}
stbi__cleanup_jpeg(z);
*out_x = z->s->img_x;
*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;
}
}
@ -3701,6 +3684,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
{
unsigned char* result;
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
STBI_NOTUSED(ri);
j->s = s;
stbi__setup_jpeg(j);
result = load_jpeg_image(j, x,y,comp,req_comp);
@ -3711,11 +3695,12 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
static int stbi__jpeg_test(stbi__context *s)
{
int r;
stbi__jpeg j;
j.s = s;
stbi__setup_jpeg(&j);
r = stbi__decode_jpeg_header(&j, STBI__SCAN_type);
stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
j->s = s;
stbi__setup_jpeg(j);
r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
stbi__rewind(s);
STBI_FREE(j);
return r;
}
@ -3727,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 (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;
}
@ -3784,7 +3769,7 @@ stbi_inline static int stbi__bit_reverse(int v, int 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 code, next_code[16], sizes[17];
@ -4074,9 +4059,24 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
return 1;
}
// @TODO: should statically initialize these for optimal thread safety
static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32];
static void stbi__init_zdefaults(void)
static const stbi_uc stbi__zdefault_length[288] =
{
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
for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8;
@ -4086,6 +4086,7 @@ static void stbi__init_zdefaults(void)
for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5;
}
*/
static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
{
@ -4104,7 +4105,6 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
} else {
if (type == 1) {
// 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_distance, stbi__zdefault_distance, 32)) return 0;
} else {
@ -4305,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) {
stbi_uc *cur = a->out + stride*j;
stbi_uc *prior = cur - stride;
stbi_uc *prior;
int filter = *raw++;
if (filter > 4)
@ -4317,6 +4317,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
filter_bytes = 1;
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 (j == 0) filter = first_row_filter[filter];
@ -5979,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)
{
stbi_uc *result;
int i, x,y;
int i, x,y, internal_comp;
STBI_NOTUSED(ri);
if (!comp) comp = &internal_comp;
for (i=0; i<92; ++i)
stbi__get8(s);
@ -6600,6 +6603,11 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
char buffer[STBI__HDR_BUFLEN];
char *token;
int valid = 0;
int dummy;
if (!x) x = &dummy;
if (!y) y = &dummy;
if (!comp) comp = &dummy;
if (stbi__hdr_test(s) == 0) {
stbi__rewind( s );
@ -6646,9 +6654,9 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
stbi__rewind( s );
if (p == NULL)
return 0;
*x = s->img_x;
*y = s->img_y;
*comp = info.ma ? 4 : 3;
if (x) *x = s->img_x;
if (y) *y = s->img_y;
if (comp) *comp = info.ma ? 4 : 3;
return 1;
}
#endif
@ -6656,7 +6664,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_PSD
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) {
stbi__rewind( s );
return 0;
@ -6689,9 +6700,13 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_PIC
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];
if (!x) x = &dummy;
if (!y) y = &dummy;
if (!comp) comp = &dummy;
if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
stbi__rewind(s);
return 0;
@ -6777,7 +6792,7 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
*x = s->img_x;
*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))
return stbi__errpuc("too large", "PNM too large");
@ -6831,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)
{
int maxv;
int maxv, dummy;
char c, p, t;
stbi__rewind( s );
if (!x) x = &dummy;
if (!y) y = &dummy;
if (!comp) comp = &dummy;
stbi__rewind(s);
// Get identifier
p = (char) stbi__get8(s);
t = (char) stbi__get8(s);
if (p != 'P' || (t != '5' && t != '6')) {
stbi__rewind( s );
stbi__rewind(s);
return 0;
}
@ -6947,6 +6966,11 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/*
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.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
@ -7108,3 +7132,46 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
0.50 (2006-11-19)
first released version
*/
/*
------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------
*/

View file

@ -1,4 +1,4 @@
/* stb_image_resize - v0.92 - public domain image resizing
/* stb_image_resize - v0.94 - public domain image resizing
by Jorge L Rodriguez (@VinoBS) - 2014
http://github.com/nothings/stb
@ -107,8 +107,8 @@
industry, it is still uncommon in the videogame/real-time world.
If you linearly filter non-premultiplied alpha, strange effects
occur. (For example, the average of 1% opaque bright green
and 99% opaque black produces 50% transparent dark green when
occur. (For example, the 50/50 average of 99% transparent bright green
and 1% transparent black produces 50% transparent dark green when
non-premultiplied, whereas premultiplied it produces 50%
transparent near-black. The former introduces green energy
that doesn't exist in the source image.)
@ -152,20 +152,20 @@
(For example, graphics hardware does not apply sRGB conversion
to the alpha channel.)
ADDITIONAL CONTRIBUTORS
CONTRIBUTORS
Jorge L Rodriguez: Implementation
Sean Barrett: API design, optimizations
Aras Pranckevicius: bugfix
REVISIONS
0.94 (2017-03-18) fixed warnings
0.93 (2017-03-03) fixed bug with certain combinations of heights
0.92 (2017-01-02) fix integer overflow on large (>2GB) images
0.91 (2016-04-02) fix warnings; fix handling of subpixel regions
0.90 (2014-09-17) first released version
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.
TODO
Don't decode all of the image data when only processing a partial tile
@ -534,9 +534,10 @@ typedef struct
int vertical_num_contributors;
int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter)
int ring_buffer_num_entries; // Total number of entries in the ring buffer.
int ring_buffer_first_scanline;
int ring_buffer_last_scanline;
int ring_buffer_begin_index;
int ring_buffer_begin_index; // first_scanline is at this index in the ring buffer
float* ring_buffer;
float* encode_buffer; // A temporary buffer to store floats so we don't lose precision while we do multiply-adds.
@ -551,16 +552,17 @@ typedef struct
int encode_buffer_size;
} stbir__info;
static const float stbir__max_uint8_as_float = 255.0f;
static const float stbir__max_uint16_as_float = 65535.0f;
static const double stbir__max_uint32_as_float = 4294967295.0;
static stbir__inline int stbir__min(int a, int b)
{
return a < b ? a : b;
}
static stbir__inline int stbir__max(int a, int b)
{
return a > b ? a : b;
}
static stbir__inline float stbir__saturate(float x)
{
if (x < 0)
@ -1027,7 +1029,7 @@ static void stbir__calculate_sample_range_downsample(int n, float in_pixels_radi
*out_last_pixel = (int)(floor(out_pixel_influence_upperbound - 0.5));
}
static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group)
static void stbir__calculate_coefficients_upsample(stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group)
{
int i;
float total_filter = 0;
@ -1077,7 +1079,7 @@ static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbi
}
}
static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group)
static void stbir__calculate_coefficients_downsample(stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group)
{
int i;
@ -1107,7 +1109,7 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st
}
}
static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size)
static void stbir__normalize_downsample_coefficients(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, int input_size, int output_size)
{
int num_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size);
int num_coefficients = stbir__get_coefficient_width(filter, scale_ratio);
@ -1184,7 +1186,7 @@ static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, st
// Each scan line uses the same kernel values so we should calculate the kernel
// values once and then we can use them for every scan line.
static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size)
static void stbir__calculate_filters(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size)
{
int n;
int total_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size);
@ -1201,7 +1203,7 @@ static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributor
stbir__calculate_sample_range_upsample(n, out_pixels_radius, scale_ratio, shift, &in_first_pixel, &in_last_pixel, &in_center_of_out);
stbir__calculate_coefficients_upsample(stbir_info, filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
stbir__calculate_coefficients_upsample(filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
}
}
else
@ -1217,10 +1219,10 @@ static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributor
stbir__calculate_sample_range_downsample(n_adjusted, in_pixels_radius, scale_ratio, shift, &out_first_pixel, &out_last_pixel, &out_center_of_in);
stbir__calculate_coefficients_downsample(stbir_info, filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
stbir__calculate_coefficients_downsample(filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
}
stbir__normalize_downsample_coefficients(stbir_info, contributors, coefficients, filter, scale_ratio, shift, input_size, output_size);
stbir__normalize_downsample_coefficients(contributors, coefficients, filter, scale_ratio, input_size, output_size);
}
}
@ -1270,7 +1272,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / 255;
decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / stbir__max_uint8_as_float;
}
break;
@ -1283,7 +1285,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
decode_buffer[decode_pixel_index + c] = stbir__srgb_uchar_to_linear_float[((const unsigned char*)input_data)[input_pixel_index + c]];
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / 255;
decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint8_as_float;
}
break;
@ -1293,7 +1295,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535;
decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float;
}
break;
@ -1303,10 +1305,10 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535);
decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float);
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / 65535;
decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint16_as_float;
}
break;
@ -1316,7 +1318,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295);
decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float);
}
break;
@ -1326,10 +1328,10 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295));
decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float));
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / 4294967295);
decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint32_as_float);
}
break;
@ -1411,6 +1413,8 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n)
int ring_buffer_index;
float* ring_buffer;
stbir_info->ring_buffer_last_scanline = n;
if (stbir_info->ring_buffer_begin_index < 0)
{
ring_buffer_index = stbir_info->ring_buffer_begin_index = 0;
@ -1418,24 +1422,21 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n)
}
else
{
ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline) + 1) % stbir_info->vertical_filter_pixel_width;
ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline)) % stbir_info->ring_buffer_num_entries;
STBIR_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index);
}
ring_buffer = stbir__get_ring_buffer_entry(stbir_info->ring_buffer, ring_buffer_index, stbir_info->ring_buffer_length_bytes / sizeof(float));
memset(ring_buffer, 0, stbir_info->ring_buffer_length_bytes);
stbir_info->ring_buffer_last_scanline = n;
return ring_buffer;
}
static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n, float* output_buffer)
static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, float* output_buffer)
{
int x, k;
int output_w = stbir_info->output_w;
int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width;
int channels = stbir_info->channels;
float* decode_buffer = stbir__get_decode_buffer(stbir_info);
stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors;
@ -1515,12 +1516,10 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
}
}
static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n, float* output_buffer)
static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, float* output_buffer)
{
int x, k;
int input_w = stbir_info->input_w;
int output_w = stbir_info->output_w;
int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width;
int channels = stbir_info->channels;
float* decode_buffer = stbir__get_decode_buffer(stbir_info);
stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors;
@ -1654,9 +1653,9 @@ static void stbir__decode_and_resample_upsample(stbir__info* stbir_info, int n)
// Now resample it into the ring buffer.
if (stbir__use_width_upsampling(stbir_info))
stbir__resample_horizontal_upsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n));
stbir__resample_horizontal_upsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n));
else
stbir__resample_horizontal_downsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n));
stbir__resample_horizontal_downsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n));
// Now it's sitting in the ring buffer ready to be used as source for the vertical sampling.
}
@ -1670,17 +1669,17 @@ static void stbir__decode_and_resample_downsample(stbir__info* stbir_info, int n
// Now resample it into the horizontal buffer.
if (stbir__use_width_upsampling(stbir_info))
stbir__resample_horizontal_upsample(stbir_info, n, stbir_info->horizontal_buffer);
stbir__resample_horizontal_upsample(stbir_info, stbir_info->horizontal_buffer);
else
stbir__resample_horizontal_downsample(stbir_info, n, stbir_info->horizontal_buffer);
stbir__resample_horizontal_downsample(stbir_info, stbir_info->horizontal_buffer);
// Now it's sitting in the horizontal buffer ready to be distributed into the ring buffers.
}
// Get the specified scan line from the ring buffer.
static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_size, int ring_buffer_length)
static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_num_entries, int ring_buffer_length)
{
int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_size;
int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_num_entries;
return stbir__get_ring_buffer_entry(ring_buffer, ring_buffer_index, ring_buffer_length);
}
@ -1715,19 +1714,23 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
// build a table of all channels that need colorspace correction, so
// we don't perform colorspace correction on channels that don't need it.
for (x=0, num_nonalpha=0; x < channels; ++x)
for (x = 0, num_nonalpha = 0; x < channels; ++x)
{
if (x != alpha_channel || (stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE))
nonalpha[num_nonalpha++] = x;
{
nonalpha[num_nonalpha++] = (stbir_uint16)x;
}
}
#define STBIR__ROUND_INT(f) ((int) ((f)+0.5))
#define STBIR__ROUND_UINT(f) ((stbir_uint32) ((f)+0.5))
#ifdef STBIR__SATURATE_INT
#define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * 255 ))
#define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * 65535))
#define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * stbir__max_uint8_as_float ))
#define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * stbir__max_uint16_as_float))
#else
#define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * 255 )
#define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * 65535)
#define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint8_as_float )
#define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint16_as_float)
#endif
switch (decode)
@ -1782,7 +1785,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
for (n = 0; n < num_nonalpha; n++)
{
int index = pixel_index + nonalpha[n];
((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * 65535);
((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * stbir__max_uint16_as_float);
}
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
@ -1799,7 +1802,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
for (n = 0; n < channels; n++)
{
int index = pixel_index + n;
((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * 4294967295);
((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * stbir__max_uint32_as_float);
}
}
break;
@ -1812,11 +1815,11 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
for (n = 0; n < num_nonalpha; n++)
{
int index = pixel_index + nonalpha[n];
((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * 4294967295);
((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * stbir__max_uint32_as_float);
}
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * 4294967295);
((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * stbir__max_uint32_as_float);
}
break;
@ -1855,7 +1858,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
}
}
static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out)
static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n)
{
int x, k;
int output_w = stbir_info->output_w;
@ -1865,7 +1868,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
int alpha_channel = stbir_info->alpha_channel;
int type = stbir_info->type;
int colorspace = stbir_info->colorspace;
int kernel_pixel_width = stbir_info->vertical_filter_pixel_width;
int ring_buffer_entries = stbir_info->ring_buffer_num_entries;
void* output_data = stbir_info->output_data;
float* encode_buffer = stbir_info->encode_buffer;
int decode = STBIR__DECODE(type, colorspace);
@ -1876,7 +1879,6 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
float* ring_buffer = stbir_info->ring_buffer;
int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index;
int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline;
int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline;
int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float);
int n0,n1, output_row_start;
@ -1900,7 +1902,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@ -1913,7 +1915,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@ -1927,7 +1929,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@ -1942,7 +1944,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@ -1958,7 +1960,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@ -1973,16 +1975,14 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, encode_buffer, channels, alpha_channel, decode);
}
static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out)
static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n)
{
int x, k;
int output_w = stbir_info->output_w;
int output_h = stbir_info->output_h;
stbir__contributors* vertical_contributors = stbir_info->vertical_contributors;
float* vertical_coefficients = stbir_info->vertical_coefficients;
int channels = stbir_info->channels;
int kernel_pixel_width = stbir_info->vertical_filter_pixel_width;
void* output_data = stbir_info->output_data;
int ring_buffer_entries = stbir_info->ring_buffer_num_entries;
float* horizontal_buffer = stbir_info->horizontal_buffer;
int coefficient_width = stbir_info->vertical_coefficient_width;
int contributor = n + stbir_info->vertical_filter_pixel_margin;
@ -1990,7 +1990,6 @@ static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n,
float* ring_buffer = stbir_info->ring_buffer;
int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index;
int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline;
int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline;
int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float);
int n0,n1;
@ -2005,7 +2004,7 @@ static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n,
int coefficient_group = coefficient_width * contributor;
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
switch (channels) {
case 1:
@ -2071,7 +2070,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
stbir__calculate_sample_range_upsample(y, out_scanlines_radius, scale_ratio, stbir_info->vertical_shift, &in_first_scanline, &in_last_scanline, &in_center_of_out);
STBIR_ASSERT(in_last_scanline - in_first_scanline <= stbir_info->vertical_filter_pixel_width);
STBIR_ASSERT(in_last_scanline - in_first_scanline + 1 <= stbir_info->ring_buffer_num_entries);
if (stbir_info->ring_buffer_begin_index >= 0)
{
@ -2090,7 +2089,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
else
{
stbir_info->ring_buffer_first_scanline++;
stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width;
stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries;
}
}
}
@ -2103,7 +2102,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
stbir__decode_and_resample_upsample(stbir_info, stbir_info->ring_buffer_last_scanline + 1);
// Now all buffers should be ready to write a row of vertical sampling.
stbir__resample_vertical_upsample(stbir_info, y, in_first_scanline, in_last_scanline, in_center_of_out);
stbir__resample_vertical_upsample(stbir_info, y);
STBIR_PROGRESS_REPORT((float)y / stbir_info->output_h);
}
@ -2148,7 +2147,7 @@ static void stbir__empty_ring_buffer(stbir__info* stbir_info, int first_necessar
else
{
stbir_info->ring_buffer_first_scanline++;
stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width;
stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries;
}
}
}
@ -2172,7 +2171,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
stbir__calculate_sample_range_downsample(y, in_pixels_radius, scale_ratio, stbir_info->vertical_shift, &out_first_scanline, &out_last_scanline, &out_center_of_in);
STBIR_ASSERT(out_last_scanline - out_first_scanline <= stbir_info->vertical_filter_pixel_width);
STBIR_ASSERT(out_last_scanline - out_first_scanline + 1 <= stbir_info->ring_buffer_num_entries);
if (out_last_scanline < 0 || out_first_scanline >= output_h)
continue;
@ -2189,7 +2188,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
stbir__add_empty_ring_buffer_entry(stbir_info, stbir_info->ring_buffer_last_scanline + 1);
// Now the horizontal buffer is ready to write to all ring buffer rows.
stbir__resample_vertical_downsample(stbir_info, y, out_first_scanline, out_last_scanline, out_center_of_in);
stbir__resample_vertical_downsample(stbir_info, y);
}
stbir__empty_ring_buffer(stbir_info, stbir_info->output_h);
@ -2246,13 +2245,16 @@ static stbir_uint32 stbir__calculate_memory(stbir__info *info)
info->horizontal_num_contributors = stbir__get_contributors(info->horizontal_scale, info->horizontal_filter, info->input_w, info->output_w);
info->vertical_num_contributors = stbir__get_contributors(info->vertical_scale , info->vertical_filter , info->input_h, info->output_h);
// One extra entry because floating point precision problems sometimes cause an extra to be necessary.
info->ring_buffer_num_entries = filter_height + 1;
info->horizontal_contributors_size = info->horizontal_num_contributors * sizeof(stbir__contributors);
info->horizontal_coefficients_size = stbir__get_total_horizontal_coefficients(info) * sizeof(float);
info->vertical_contributors_size = info->vertical_num_contributors * sizeof(stbir__contributors);
info->vertical_coefficients_size = stbir__get_total_vertical_coefficients(info) * sizeof(float);
info->decode_buffer_size = (info->input_w + pixel_margin * 2) * info->channels * sizeof(float);
info->horizontal_buffer_size = info->output_w * info->channels * sizeof(float);
info->ring_buffer_size = info->output_w * info->channels * filter_height * sizeof(float);
info->ring_buffer_size = info->output_w * info->channels * info->ring_buffer_num_entries * sizeof(float);
info->encode_buffer_size = info->output_w * info->channels * sizeof(float);
STBIR_ASSERT(info->horizontal_filter != 0);
@ -2390,8 +2392,8 @@ static int stbir__resize_allocated(stbir__info *info,
// This signals that the ring buffer is empty
info->ring_buffer_begin_index = -1;
stbir__calculate_filters(info, info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w);
stbir__calculate_filters(info, info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h);
stbir__calculate_filters(info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w);
stbir__calculate_filters(info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h);
STBIR_PROGRESS_REPORT(0);
@ -2578,3 +2580,45 @@ STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int
}
#endif // STB_IMAGE_RESIZE_IMPLEMENTATION
/*
------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------
*/

View file

@ -1,4 +1,4 @@
/* stb_image_write - v1.03 - public domain - http://nothings.org/stb/stb_image_write.h
/* stb_image_write - v1.05 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015
no warranty implied; use at your own risk
@ -104,12 +104,11 @@ CREDITS:
Filip Wasil
Thatcher Ulrich
github:poppolopoppo
Patrick Boettcher
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.
*/
@ -294,10 +293,8 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
s->func(s->context, &d[comp - 1], 1);
switch (comp) {
case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
case 1:
s->func(s->context,d,1);
break;
case 2:
if (expand_mono)
stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
else
@ -897,6 +894,7 @@ static unsigned char stbiw__paeth(int a, int b, int c)
return STBIW_UCHAR(c);
}
// @OPTIMIZE: provide an option that always forces left-predict or paeth predict
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
{
int ctype[5] = { -1, 0, 4, 2, 6 };
@ -913,10 +911,10 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
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 ? mapping : firstmap;
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) {
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)
@ -1018,6 +1016,9 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x,
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
1.04 (2017-03-03)
monochrome BMP expansion
1.03 ???
1.02 (2016-04-02)
avoid allocating large structures on the stack
1.01 (2016-01-16)
@ -1047,3 +1048,45 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x,
first public release
0.90 first internal release
*/
/*
------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------
*/

View file

@ -1,4 +1,4 @@
// stb_rect_pack.h - v0.10 - public domain - rectangle packing
// stb_rect_pack.h - v0.11 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
@ -27,11 +27,14 @@
// Sean Barrett
// Minor features
// Martins Mozeiko
// github:IntellectualKitty
//
// Bugfixes / warning fixes
// Jeremy Jaussaud
//
// 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)
@ -43,9 +46,7 @@
//
// 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.
//////////////////////////////////////////////////////////////////////////////
//
@ -77,7 +78,7 @@ typedef int stbrp_coord;
typedef unsigned short stbrp_coord;
#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
// 'stbrp_rect' defined below, stored in the array 'rects', and there
// are 'num_rects' many of them.
@ -98,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
// a single time with the full rectangle array, but the option is
// available.
//
// The function returns 1 if all of the rectangles were successfully
// packed and 0 otherwise.
struct stbrp_rect
{
@ -544,9 +548,9 @@ static int rect_original_order(const void *a, const void *b)
#define STBRP__MAXVAL 0xffff
#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
for (i=0; i < num_rects; ++i) {
@ -576,8 +580,56 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
// unsort
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);
if (!rects[i].was_packed)
all_rects_packed = 0;
}
// return the all_rects_packed status
return all_rects_packed;
}
#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.
------------------------------------------------------------------------------
*/

View file

@ -1,4 +1,4 @@
// stb_truetype.h - v1.14 - public domain
// stb_truetype.h - v1.15 - public domain
// authored from 2009-2016 by Sean Barrett / RAD Game Tools
//
// This library processes TrueType files:
@ -50,10 +50,13 @@
// Higor Euripedes
// Thomas Fields
// Derek Vinyard
// Cort Stratton
//
// VERSION HISTORY
//
// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts, num-fonts-in-TTC function
// 1.15 (2017-03-03) make more arguments const
// 1.14 (2017-01-16) num-fonts-in-TTC function
// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
// 1.11 (2016-04-02) fix unused-variable warning
// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
@ -69,9 +72,7 @@
//
// 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.
//
// USAGE
//
@ -494,7 +495,7 @@ typedef struct
float x1,y1,s1,t1; // bottom-right
} stbtt_aligned_quad;
STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above
STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above
int char_index, // character to display
float *xpos, float *ypos, // pointers to current position in screen pixel space
stbtt_aligned_quad *q, // output: quad to draw
@ -594,7 +595,7 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
// To use with PackFontRangesGather etc., you must set it before calls
// call to PackFontRangesGatherRects.
STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
int char_index, // character to display
float *xpos, float *ypos, // pointers to current position in screen pixel space
stbtt_aligned_quad *q, // output: quad to draw
@ -3287,11 +3288,11 @@ static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // fo
return bottom_y;
}
STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
{
float d3d_bias = opengl_fillrule ? 0 : -0.5f;
float ipw = 1.0f / pw, iph = 1.0f / ph;
stbtt_bakedchar *b = chardata + char_index;
const stbtt_bakedchar *b = chardata + char_index;
int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
@ -3735,10 +3736,10 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontda
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
}
STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
{
float ipw = 1.0f / pw, iph = 1.0f / ph;
stbtt_packedchar *b = chardata + char_index;
const stbtt_packedchar *b = chardata + char_index;
if (align_to_integer) {
float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
@ -4016,3 +4017,45 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const
// 0.2 (2009-03-11) Fix unsigned/signed char warnings
// 0.1 (2009-03-09) First public release
//
/*
------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------
*/

View file

@ -162,21 +162,23 @@
#endif
#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:
#ifdef _MSC_VER
#include <malloc.h>
#endif
#if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__)
#include <alloca.h>
#endif
#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
#include <limits.h>
@ -597,6 +599,8 @@ 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 };
if (n < 0) return 0; // signed n returns 0
// 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29)
if (n < (1 << 14))
if (n < (1 << 4)) return 0 + log2_4[n ];
@ -606,8 +610,7 @@ static int ilog(int32 n)
if (n < (1 << 19)) return 15 + log2_4[n >> 15];
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 return 30 + log2_4[n >> 30];
}
#ifndef M_PI
@ -880,13 +883,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
typedef struct
{
uint16 x,y;
} Point;
uint16 x,id;
} stbv__floor_ordering;
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;
}
@ -3095,11 +3098,13 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
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);
return res;
}
#ifndef STB_VORBIS_NO_PUSHDATA_API
@ -3482,7 +3487,7 @@ static int start_decoder(vorb *f)
g->book_list[j] = get_bits(f,8);
return error(f, VORBIS_feature_not_supported);
} else {
Point p[31*8+2];
stbv__floor_ordering p[31*8+2];
Floor1 *g = &f->floor_config[i].floor1;
int max_class = -1;
g->partitions = get_bits(f, 5);
@ -3518,11 +3523,11 @@ static int start_decoder(vorb *f)
// precompute the sorting
for (j=0; j < g->values; ++j) {
p[j].x = g->Xlist[j];
p[j].y = j;
p[j].id = j;
}
qsort(p, g->values, sizeof(p[0]), point_compare);
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
for (j=2; j < g->values; ++j) {
int low,hi;
@ -4226,8 +4231,9 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
// starting from the start is handled differently
if (sample_number <= left.last_decoded_sample) {
stb_vorbis_seek_start(f);
if (stb_vorbis_seek_start(f))
return 1;
return 0;
}
while (left.page_end != right.page_start) {
@ -4328,7 +4334,10 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
skip(f, f->segments[i]);
// 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;
error:
@ -4419,14 +4428,14 @@ int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number)
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);
f->previous_length = 0;
f->first_decode = TRUE;
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)
@ -4591,6 +4600,7 @@ stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *err
if (f) {
*f = p;
vorbis_pump_first_frame(f);
if (error) *error = VORBIS__no_error;
return f;
}
}
@ -4956,6 +4966,7 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
#endif // STB_VORBIS_NO_PULLDATA_API
/* Version history
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.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;
avoid discarding last frame of audio data
@ -5008,3 +5019,46 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
*/
#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.
------------------------------------------------------------------------------
*/

View file

@ -1,4 +1,4 @@
// Ogg Vorbis audio decoder - v1.09 - public domain
// Ogg Vorbis audio decoder - v1.10 - public domain
// http://nothings.org/stb_vorbis/
//
// Original version written by Sean Barrett in 2007.
@ -9,12 +9,7 @@
//
// 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:
//
@ -37,6 +32,7 @@
// manxorist@github saga musix
//
// Partial history:
// 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.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
@ -280,7 +276,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_*,
// 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)
extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f);

View file

@ -196,8 +196,12 @@ Image LoadImage(const char *fileName)
int imgHeight = 0;
int imgBpp = 0;
FILE *imFile = fopen(fileName, "rb");
// NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
image.data = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 0);
image.data = stbi_load_from_file(imFile, &imgWidth, &imgHeight, &imgBpp, 0);
fclose(imFile);
image.width = imgWidth;
image.height = imgHeight;