Updated stb headers

This commit is contained in:
raysan5 2014-11-23 21:58:17 +01:00
parent 05ccc4fd42
commit 7375d0460a
12 changed files with 4758 additions and 4690 deletions

View File

@ -825,4 +825,4 @@ static Wave LoadOGG(char *fileName)
static void UnloadWave(Wave wave)
{
free(wave.data);
}
}

View File

@ -49,7 +49,7 @@ CC = gcc
ifeq ($(PLATFORM),PLATFORM_RPI)
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
else
CFLAGS = -O2 -Wall -std=c99
CFLAGS = -O2 -Wall -std=c99 -fgnu89-inline
endif
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
@ -61,7 +61,7 @@ else
endif
# define all object files required
OBJS = core.o rlgl.o raymath.o shapes.o text.o textures.o models.o audio.o utils.o stb_image.o stb_vorbis.o
OBJS = core.o rlgl.o raymath.o shapes.o text.o textures.o models.o audio.o utils.o stb_vorbis.o
# typing 'make' will invoke the first target entry in the file,
# in this case, the 'default' target entry is raylib
@ -107,10 +107,6 @@ audio.o: audio.c
utils.o: utils.c
$(CC) -c utils.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
# compile stb_image library
stb_image.o: stb_image.c
$(CC) -c stb_image.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
# compile stb_vorbis library
stb_vorbis.o: stb_vorbis.c
$(CC) -c stb_vorbis.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)

View File

@ -179,6 +179,9 @@
// Boolean type
typedef enum { false, true } bool;
// byte type
typedef unsigned char byte;
// Vector2 type
typedef struct Vector2 {
float x;
@ -225,8 +228,13 @@ typedef struct Texture2D {
} Texture2D;
// Character type (one font glyph)
// NOTE: Defined in module: text
typedef struct Character Character;
typedef struct Character {
int value; //char value = ' '; (int)value = 32;
int x;
int y;
int w;
int h;
} Character;
// SpriteFont type, includes texture and charSet array data
typedef struct SpriteFont {

View File

@ -33,6 +33,7 @@
#if defined(GRAPHICS_API_OPENGL_11)
#include <GL/gl.h> // Basic OpenGL include
//#include <OpenGL/gl.h> // Basic OpenGL include (OSX)
#endif
#if defined(GRAPHICS_API_OPENGL_33)

View File

@ -81,8 +81,6 @@
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef unsigned char byte;
typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode;
typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,16 @@
/* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h
/* stb_image_write - v0.95 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
no warranty implied; use at your own risk
Before #including,
Before including,
#define STB_IMAGE_WRITE_IMPLEMENTATION
in the file that you want to have the implementation.
Will probably not work correctly with strict-aliasing optimizations.
ABOUT:
@ -33,23 +35,20 @@ USAGE:
The functions create an image file defined by the parameters. The image
is a rectangle of pixels stored from left-to-right, top-to-bottom.
Each pixel contains 'comp' channels of data stored interleaved with 8-bits
per channel, in the following order: 1=L, 2=LA, 3=RGB, 4=RGBA. (L is
luminance, i.e. monochrome "color", i.e. grey value.) The rectangle is
'w' pixels wide and 'h' pixels tall. The *data pointer points to the
first byte of the top-left-most pixel. For PNG, "stride_in_bytes" is
the distance in bytes from the first byte of a row of pixels to the
first byte of the next row of pixels. Other file formats assume the
first byte of the each row of pixels begins immediately after the last
byte of the previous row.
per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
The *data pointer points to the first byte of the top-left-most pixel.
For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
a row of pixels to the first byte of the next row of pixels.
PNG creates output files with the same number of components as the input.
The BMP and TGA formats expand Y to RGB in the file format. BMP does not
The BMP format expands Y to RGB in the file format and does not
output alpha.
PNG supports writing rectangles of data even when the bytes storing rows of
data are not consecutive in memory (e.g. sub-rectangles of a larger image),
by supplying the stride between the beginning of adjacent rows. The other
formats do not. (Thus you cannot write an in-memory BMP through the BMP
formats do not. (Thus you cannot write a native-format BMP through the BMP
writer, both because it is in BGR order and because it may have padding
at the end of the line.)
*/
@ -129,8 +128,8 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp,
if (write_alpha < 0)
fwrite(&d[comp-1], 1, 1, f);
switch (comp) {
case 1:
case 2: write3(f, d[0],d[0],d[0]);
case 1:
case 2: fwrite(d, 1, 1, f);
break;
case 4:
if (!write_alpha) {
@ -179,48 +178,50 @@ int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *dat
int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
{
int has_alpha = !(comp & 1);
int has_alpha = (comp == 2 || comp == 4);
int colorbytes = has_alpha ? comp-1 : comp;
int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0,
"111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
"111 221 2222 11", 0,0,format, 0,0,0, 0,0,x,y, (colorbytes+has_alpha)*8, has_alpha*8);
}
// stretchy buffer; stbi__sbpush() == vector<>::push_back() -- stbi__sbcount() == vector<>::size()
#define stbi__sbraw(a) ((int *) (a) - 2)
#define stbi__sbm(a) stbi__sbraw(a)[0]
#define stbi__sbn(a) stbi__sbraw(a)[1]
// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
#define stbiw__sbraw(a) ((int *) (a) - 2)
#define stbiw__sbm(a) stbiw__sbraw(a)[0]
#define stbiw__sbn(a) stbiw__sbraw(a)[1]
#define stbi__sbneedgrow(a,n) ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a))
#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0)
#define stbi__sbgrow(a,n) stbi__sbgrowf((void **) &(a), (n), sizeof(*(a)))
#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v))
#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0)
#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)),0 : 0)
#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
#define stbiw__sbfree(a) ((a) ? free(stbiw__sbraw(a)),0 : 0)
static void *stbi__sbgrowf(void **arr, int increment, int itemsize)
static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
{
int m = *arr ? 2*stbi__sbm(*arr)+increment : increment+1;
void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
void *p = realloc(*arr ? stbiw__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
assert(p);
if (p) {
if (!*arr) ((int *) p)[1] = 0;
*arr = (void *) ((int *) p + 2);
stbi__sbm(*arr) = m;
stbiw__sbm(*arr) = m;
}
return *arr;
}
static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
{
while (*bitcount >= 8) {
stbi__sbpush(data, (unsigned char) *bitbuffer);
stbiw__sbpush(data, (unsigned char) *bitbuffer);
*bitbuffer >>= 8;
*bitcount -= 8;
}
return data;
}
static int stbi__zlib_bitrev(int code, int codebits)
static int stbiw__zlib_bitrev(int code, int codebits)
{
int res=0;
while (codebits--) {
@ -230,7 +231,7 @@ static int stbi__zlib_bitrev(int code, int codebits)
return res;
}
static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int limit)
static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
{
int i;
for (i=0; i < limit && i < 258; ++i)
@ -238,7 +239,7 @@ static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int li
return i;
}
static unsigned int stbi__zhash(unsigned char *data)
static unsigned int stbiw__zhash(unsigned char *data)
{
stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
hash ^= hash << 3;
@ -250,19 +251,19 @@ static unsigned int stbi__zhash(unsigned char *data)
return hash;
}
#define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount))
#define stbi__zlib_add(code,codebits) \
(bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush())
#define stbi__zlib_huffa(b,c) stbi__zlib_add(stbi__zlib_bitrev(b,c),c)
#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
#define stbiw__zlib_add(code,codebits) \
(bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
// default huffman tables
#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8)
#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9)
#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256,7)
#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280,8)
#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n))
#define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n))
#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7)
#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8)
#define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n))
#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
#define stbi__ZHASH 16384
#define stbiw__ZHASH 16384
unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
{
@ -273,45 +274,45 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
unsigned int bitbuf=0;
int i,j, bitcount=0;
unsigned char *out = NULL;
unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack!
unsigned char **hash_table[stbiw__ZHASH]; // 64KB on the stack!
if (quality < 5) quality = 5;
stbi__sbpush(out, 0x78); // DEFLATE 32K window
stbi__sbpush(out, 0x5e); // FLEVEL = 1
stbi__zlib_add(1,1); // BFINAL = 1
stbi__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
stbiw__sbpush(out, 0x78); // DEFLATE 32K window
stbiw__sbpush(out, 0x5e); // FLEVEL = 1
stbiw__zlib_add(1,1); // BFINAL = 1
stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
for (i=0; i < stbi__ZHASH; ++i)
for (i=0; i < stbiw__ZHASH; ++i)
hash_table[i] = NULL;
i=0;
while (i < data_len-3) {
// hash next 3 bytes of data to be compressed
int h = stbi__zhash(data+i)&(stbi__ZHASH-1), best=3;
int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
unsigned char *bestloc = 0;
unsigned char **hlist = hash_table[h];
int n = stbi__sbcount(hlist);
int n = stbiw__sbcount(hlist);
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32768) { // if entry lies within window
int d = stbi__zlib_countm(hlist[j], data+i, data_len-i);
int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
if (d >= best) best=d,bestloc=hlist[j];
}
}
// when hash table entry is too long, delete half the entries
if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) {
if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
stbi__sbn(hash_table[h]) = quality;
stbiw__sbn(hash_table[h]) = quality;
}
stbi__sbpush(hash_table[h],data+i);
stbiw__sbpush(hash_table[h],data+i);
if (bestloc) {
// "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
h = stbi__zhash(data+i+1)&(stbi__ZHASH-1);
h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
hlist = hash_table[h];
n = stbi__sbcount(hlist);
n = stbiw__sbcount(hlist);
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32767) {
int e = stbi__zlib_countm(hlist[j], data+i+1, data_len-i-1);
int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
if (e > best) { // if next match is better, bail on current match
bestloc = NULL;
break;
@ -321,30 +322,30 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
}
if (bestloc) {
int d = data+i - bestloc; // distance back
int d = (int) (data+i - bestloc); // distance back
assert(d <= 32767 && best <= 258);
for (j=0; best > lengthc[j+1]-1; ++j);
stbi__zlib_huff(j+257);
if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]);
stbiw__zlib_huff(j+257);
if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
for (j=0; d > distc[j+1]-1; ++j);
stbi__zlib_add(stbi__zlib_bitrev(j,5),5);
if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]);
stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
i += best;
} else {
stbi__zlib_huffb(data[i]);
stbiw__zlib_huffb(data[i]);
++i;
}
}
// write out final bytes
for (;i < data_len; ++i)
stbi__zlib_huffb(data[i]);
stbi__zlib_huff(256); // end of block
stbiw__zlib_huffb(data[i]);
stbiw__zlib_huff(256); // end of block
// pad with 0 bits to byte boundary
while (bitcount)
stbi__zlib_add(0,1);
stbiw__zlib_add(0,1);
for (i=0; i < stbi__ZHASH; ++i)
(void) stbi__sbfree(hash_table[i]);
for (i=0; i < stbiw__ZHASH; ++i)
(void) stbiw__sbfree(hash_table[i]);
{
// compute adler32 on input
@ -356,18 +357,18 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
j += blocklen;
blocklen = 5552;
}
stbi__sbpush(out, (unsigned char) (s2 >> 8));
stbi__sbpush(out, (unsigned char) s2);
stbi__sbpush(out, (unsigned char) (s1 >> 8));
stbi__sbpush(out, (unsigned char) s1);
stbiw__sbpush(out, (unsigned char) (s2 >> 8));
stbiw__sbpush(out, (unsigned char) s2);
stbiw__sbpush(out, (unsigned char) (s1 >> 8));
stbiw__sbpush(out, (unsigned char) s1);
}
*out_len = stbi__sbn(out);
*out_len = stbiw__sbn(out);
// make returned pointer freeable
memmove(stbi__sbraw(out), out, *out_len);
return (unsigned char *) stbi__sbraw(out);
memmove(stbiw__sbraw(out), out, *out_len);
return (unsigned char *) stbiw__sbraw(out);
}
unsigned int stbi__crc32(unsigned char *buffer, int len)
unsigned int stbiw__crc32(unsigned char *buffer, int len)
{
static unsigned int crc_table[256];
unsigned int crc = ~0u;
@ -381,17 +382,17 @@ unsigned int stbi__crc32(unsigned char *buffer, int len)
return ~crc;
}
#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3])
#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
static void stbi__wpcrc(unsigned char **data, int len)
static void stbiw__wpcrc(unsigned char **data, int len)
{
unsigned int crc = stbi__crc32(*data - len - 4, len+4);
stbi__wp32(*data, crc);
unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
stbiw__wp32(*data, crc);
}
static unsigned char stbi__paeth(int a, int b, int c)
static unsigned char stbiw__paeth(int a, int b, int c)
{
int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
if (pa <= pb && pa <= pc) return (unsigned char) a;
@ -427,7 +428,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
case 1: line_buffer[i] = z[i]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break;
case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
case 5: line_buffer[i] = z[i]; break;
case 6: line_buffer[i] = z[i]; break;
}
@ -437,9 +438,9 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
case 1: line_buffer[i] = z[i] - z[i-n]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break;
case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
}
}
if (p) break;
@ -464,25 +465,25 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
o=out;
memcpy(o,sig,8); o+= 8;
stbi__wp32(o, 13); // header length
stbi__wptag(o, "IHDR");
stbi__wp32(o, x);
stbi__wp32(o, y);
stbiw__wp32(o, 13); // header length
stbiw__wptag(o, "IHDR");
stbiw__wp32(o, x);
stbiw__wp32(o, y);
*o++ = 8;
*o++ = (unsigned char) ctype[n];
*o++ = 0;
*o++ = 0;
*o++ = 0;
stbi__wpcrc(&o,13);
stbiw__wpcrc(&o,13);
stbi__wp32(o, zlen);
stbi__wptag(o, "IDAT");
stbiw__wp32(o, zlen);
stbiw__wptag(o, "IDAT");
memcpy(o, zlib, zlen); o += zlen; free(zlib);
stbi__wpcrc(&o, zlen);
stbiw__wpcrc(&o, zlen);
stbi__wp32(o,0);
stbi__wptag(o, "IEND");
stbi__wpcrc(&o,0);
stbiw__wp32(o,0);
stbiw__wptag(o, "IEND");
stbiw__wpcrc(&o,0);
assert(o == out + *out_len);
@ -506,6 +507,12 @@ int stbi_write_png(char const *filename, int x, int y, int comp, const void *dat
/* Revision history
0.95 (2014-08-17)
add monochrome TGA output
0.94 (2014-05-31)
rename private functions to avoid conflicts with stb_image.h
0.93 (2014-05-27)
warning fixes
0.92 (2010-08-01)
casts to unsigned char to fix warnings
0.91 (2010-07-17)

View File

@ -1,36 +1,5 @@
// Ogg Vorbis I audio decoder -- version 0.99996
//
// Written in April 2007 by Sean Barrett, sponsored by RAD Game Tools.
//
// Placed in the public domain April 2007 by the author: no copyright is
// claimed, and you may use it for any purpose you like.
//
// 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.
//
// Get the latest version and other information at:
// http://nothings.org/stb_vorbis/
// Todo:
//
// - seeking (note you can seek yourself using the pushdata API)
//
// Limitations:
//
// - floor 0 not supported (used in old ogg vorbis files)
// - lossless sample-truncation at beginning ignored
// - cannot concatenate multiple vorbis streams
// - sample positions are 32-bit, limiting seekable 192Khz
// files to around 6 hours (Ogg supports 64-bit)
//
// All of these limitations may be removed in future versions.
#include "stb_vorbis.h"
#ifdef __linux
#include <alloca.h>
#endif
#ifndef STB_VORBIS_HEADER_ONLY
@ -488,7 +457,7 @@ extern int my_prof(int slot);
//#define stb_prof my_prof
#ifndef stb_prof
#define stb_prof(x) 0
#define stb_prof(x) ((void) 0)
#endif
#if defined(STB_VORBIS_NO_PUSHDATA_API)
@ -572,7 +541,7 @@ static void *setup_temp_malloc(vorb *f, int sz)
return malloc(sz);
}
static void setup_temp_free(vorb *f, void *p, size_t sz)
static void setup_temp_free(vorb *f, void *p, int sz)
{
if (f->alloc.alloc_buffer) {
f->temp_offset += (sz+3)&~3;
@ -590,7 +559,7 @@ static void crc32_init(void)
uint32 s;
for(i=0; i < 256; i++) {
for (s=i<<24, j=0; j < 8; ++j)
s = (s << 1) ^ (s >= (1<<31) ? CRC32_POLY : 0);
s = (s << 1) ^ (s >= (1U<<31) ? CRC32_POLY : 0);
crc_table[i] = s;
}
}
@ -624,15 +593,15 @@ 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 };
// 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29)
if (n < (1U << 14))
if (n < (1U << 4)) return 0 + log2_4[n ];
else if (n < (1U << 9)) return 5 + log2_4[n >> 5];
if (n < (1 << 14))
if (n < (1 << 4)) return 0 + log2_4[n ];
else if (n < (1 << 9)) return 5 + log2_4[n >> 5];
else return 10 + log2_4[n >> 10];
else if (n < (1U << 24))
if (n < (1U << 19)) return 15 + log2_4[n >> 15];
else if (n < (1 << 24))
if (n < (1 << 19)) return 15 + log2_4[n >> 15];
else return 20 + log2_4[n >> 20];
else if (n < (1U << 29)) return 25 + log2_4[n >> 25];
else if (n < (1U << 31)) return 30 + log2_4[n >> 30];
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
}
@ -745,7 +714,13 @@ static void compute_accelerated_huffman(Codebook *c)
}
}
static int uint32_compare(const void *p, const void *q)
#ifdef _MSC_VER
#define STBV_CDECL __cdecl
#else
#define STBV_CDECL
#endif
static int STBV_CDECL uint32_compare(const void *p, const void *q)
{
uint32 x = * (uint32 *) p;
uint32 y = * (uint32 *) q;
@ -901,7 +876,7 @@ typedef struct
uint16 x,y;
} Point;
int point_compare(const void *p, const void *q)
static int STBV_CDECL point_compare(const void *p, const void *q)
{
Point *a = (Point *) p;
Point *b = (Point *) q;
@ -1027,7 +1002,7 @@ static int capture_pattern(vorb *f)
static int start_page_no_capturepattern(vorb *f)
{
uint32 loc0,loc1,n,i;
uint32 loc0,loc1,n;
// stream structure version
if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version);
// header flag
@ -1050,7 +1025,8 @@ static int start_page_no_capturepattern(vorb *f)
return error(f, VORBIS_unexpected_eof);
// assume we _don't_ know any the sample position of any segments
f->end_seg_with_known_loc = -2;
if (loc0 != ~0 || loc1 != ~0) {
if (loc0 != ~0U || loc1 != ~0U) {
int i;
// determine which packet is the last one that will complete
for (i=f->segment_count-1; i >= 0; --i)
if (f->segments[i] < 255)
@ -1147,9 +1123,10 @@ static int next_segment(vorb *f)
static int get8_packet_raw(vorb *f)
{
if (!f->bytes_in_seg)
if (!f->bytes_in_seg) { // CLANG!
if (f->last_seg) return EOP;
else if (!next_segment(f)) return EOP;
}
assert(f->bytes_in_seg > 0);
--f->bytes_in_seg;
++f->packet_bytes;
@ -1200,14 +1177,6 @@ static uint32 get_bits(vorb *f, int n)
return z;
}
static int32 get_bits_signed(vorb *f, int n)
{
uint32 z = get_bits(f, n);
if (z & (1 << (n-1)))
z += ~((1 << n) - 1);
return (int32) z;
}
// @OPTIMIZE: primary accumulator for huffman
// expand the buffer to as many bits as possible without reading off end of packet
// it might be nice to allow f->valid_bits and f->acc to be stored in registers,
@ -1291,23 +1260,6 @@ static int codebook_decode_scalar_raw(vorb *f, Codebook *c)
return -1;
}
static int codebook_decode_scalar(vorb *f, Codebook *c)
{
int i;
if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH)
prep_huffman(f);
// fast huffman table lookup
i = f->acc & FAST_HUFFMAN_TABLE_MASK;
i = c->fast_huffman[i];
if (i >= 0) {
f->acc >>= c->codeword_lengths[i];
f->valid_bits -= c->codeword_lengths[i];
if (f->valid_bits < 0) { f->valid_bits = 0; return -1; }
return i;
}
return codebook_decode_scalar_raw(f,c);
}
#ifndef STB_VORBIS_NO_INLINE_DECODE
#define DECODE_RAW(var, f,c) \
@ -1326,6 +1278,23 @@ static int codebook_decode_scalar(vorb *f, Codebook *c)
#else
static int codebook_decode_scalar(vorb *f, Codebook *c)
{
int i;
if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH)
prep_huffman(f);
// fast huffman table lookup
i = f->acc & FAST_HUFFMAN_TABLE_MASK;
i = c->fast_huffman[i];
if (i >= 0) {
f->acc >>= c->codeword_lengths[i];
f->valid_bits -= c->codeword_lengths[i];
if (f->valid_bits < 0) { f->valid_bits = 0; return -1; }
return i;
}
return codebook_decode_scalar_raw(f,c);
}
#define DECODE_RAW(var,f,c) var = codebook_decode_scalar(f,c);
#endif
@ -1357,7 +1326,7 @@ static int codebook_decode_scalar(vorb *f, Codebook *c)
#define CODEBOOK_ELEMENT_BASE(c) (0)
#endif
static int codebook_decode_start(vorb *f, Codebook *c, int len)
static int codebook_decode_start(vorb *f, Codebook *c)
{
int z = -1;
@ -1379,7 +1348,7 @@ static int codebook_decode_start(vorb *f, Codebook *c, int len)
static int codebook_decode(vorb *f, Codebook *c, float *output, int len)
{
int i,z = codebook_decode_start(f,c,len);
int i,z = codebook_decode_start(f,c);
if (z < 0) return FALSE;
if (len > c->dimensions) len = c->dimensions;
@ -1418,7 +1387,7 @@ static int codebook_decode(vorb *f, Codebook *c, float *output, int len)
static int codebook_decode_step(vorb *f, Codebook *c, float *output, int len, int step)
{
int i,z = codebook_decode_start(f,c,len);
int i,z = codebook_decode_start(f,c);
float last = CODEBOOK_ELEMENT_BASE(c);
if (z < 0) return FALSE;
if (len > c->dimensions) len = c->dimensions;
@ -1482,7 +1451,8 @@ static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **out
for (i=0; i < effective; ++i) {
int off = (z / div) % c->lookup_values;
float val = CODEBOOK_ELEMENT_FAST(c,off) + last;
outputs[c_inter][p_inter] += val;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
if (++c_inter == ch) { c_inter = 0; ++p_inter; }
if (c->sequence_p) last = val;
div *= c->lookup_values;
@ -1494,14 +1464,16 @@ static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **out
if (c->sequence_p) {
for (i=0; i < effective; ++i) {
float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
outputs[c_inter][p_inter] += val;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
if (++c_inter == ch) { c_inter = 0; ++p_inter; }
last = val;
}
} else {
for (i=0; i < effective; ++i) {
float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
outputs[c_inter][p_inter] += val;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
if (++c_inter == ch) { c_inter = 0; ++p_inter; }
}
}
@ -1549,7 +1521,8 @@ static int codebook_decode_deinterleave_repeat_2(vorb *f, Codebook *c, float **o
// haven't optimized this case because I don't have any examples
for (i=0; i < effective; ++i) {
float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
outputs[c_inter][p_inter] += val;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
if (++c_inter == 2) { c_inter = 0; ++p_inter; }
last = val;
}
@ -1557,7 +1530,8 @@ static int codebook_decode_deinterleave_repeat_2(vorb *f, Codebook *c, float **o
i=0;
if (c_inter == 1) {
float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
outputs[c_inter][p_inter] += val;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
c_inter = 0; ++p_inter;
++i;
}
@ -1565,15 +1539,20 @@ static int codebook_decode_deinterleave_repeat_2(vorb *f, Codebook *c, float **o
float *z0 = outputs[0];
float *z1 = outputs[1];
for (; i+1 < effective;) {
z0[p_inter] += CODEBOOK_ELEMENT_FAST(c,z+i) + last;
z1[p_inter] += CODEBOOK_ELEMENT_FAST(c,z+i+1) + last;
float v0 = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
float v1 = CODEBOOK_ELEMENT_FAST(c,z+i+1) + last;
if (z0)
z0[p_inter] += v0;
if (z1)
z1[p_inter] += v1;
++p_inter;
i += 2;
}
}
if (i < effective) {
float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
outputs[c_inter][p_inter] += val;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
if (++c_inter == 2) { c_inter = 0; ++p_inter; }
}
}
@ -1774,7 +1753,6 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
memset(residue_buffers[i], 0, sizeof(float) * n);
if (rtype == 2 && ch != 1) {
int len = ch * n;
for (j=0; j < ch; ++j)
if (!do_not_decode[j])
break;
@ -2020,7 +1998,7 @@ void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)
}
free(x);
}
#else
#elif 0
// transform to use a slow dct-iv; this is STILL basically trivial,
// but only requires half as many ops
void dct_iv_slow(float *buffer, int n)
@ -2036,10 +2014,8 @@ void dct_iv_slow(float *buffer, int n)
float acc = 0;
for (j=0; j < n; ++j)
acc += x[j] * mcos[((2 * i + 1)*(2*j+1)) & nmask];
//acc += x[j] * cos(M_PI / n * (i + 0.5) * (j + 0.5));
buffer[i] = acc;
}
free(x);
}
void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)
@ -2280,7 +2256,6 @@ static __forceinline void iter_54(float *z)
static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A, int base_n)
{
int k_off = -8;
int a_off = base_n >> 3;
float A2 = A[0+a_off];
float *z = e + i_off;
@ -2326,7 +2301,7 @@ static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A,
static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
{
int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l;
int n3_4 = n - n4, ld;
int ld;
// @OPTIMIZE: reduce register pressure by using fewer variables?
int save_point = temp_alloc_save(f);
float *buf2 = (float *) temp_alloc(f, n2 * sizeof(*buf2));
@ -2860,13 +2835,10 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
int i,j,k,n,n2;
int zero_channel[256];
int really_zero_channel[256];
int window_center;
// WINDOWING
n = f->blocksize[m->blockflag];
window_center = n >> 1;
map = &f->mapping[m->mapping];
// FLOORS
@ -2980,7 +2952,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
// RESIDUE DECODE
for (i=0; i < map->submaps; ++i) {
float *residue_buffers[STB_VORBIS_MAX_CHANNELS];
int r,t;
int r;
uint8 do_not_decode[256];
int ch = 0;
for (j=0; j < f->channels; ++j) {
@ -2996,7 +2968,6 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
}
}
r = map->submap_residue[i];
t = f->residue_types[r];
decode_residue(f, residue_buffers, ch, n2, r, do_not_decode);
}
@ -3238,7 +3209,7 @@ static int is_whole_packet_present(stb_vorbis *f, int end_page)
}
if (end_page)
if (s < n-1) return error(f, VORBIS_invalid_stream);
if (s == f->segment_count)
if (s == n)
s = -1; // set 'crosses page' flag
if (p > f->stream_end) return error(f, VORBIS_need_more_data);
first = FALSE;
@ -3389,7 +3360,6 @@ static int start_decoder(vorb *f)
// compute the size of the sorted tables
if (c->sparse) {
sorted_count = total;
//assert(total != 0);
} else {
sorted_count = 0;
#ifndef STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH
@ -3506,10 +3476,12 @@ static int start_decoder(vorb *f)
#else
for (j=0; j < (int) c->lookup_values; ++j)
c->multiplicands[j] = mults[j] * c->delta_value + c->minimum_value;
setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
#endif
setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
}
#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
skip:;
#endif
#ifdef STB_VORBIS_CODEBOOK_FLOATS
if (c->lookup_type == 2 && c->sequence_p) {
@ -3590,7 +3562,7 @@ static int start_decoder(vorb *f)
g->sorted_order[j] = (uint8) p[j].y;
// precompute the neighbors
for (j=2; j < g->values; ++j) {
int low,hi;
int low = 0,hi = 0;
neighbors(g->Xlist, j, &low,&hi);
g->neighbors[j][0] = low;
g->neighbors[j][1] = hi;
@ -3656,7 +3628,7 @@ static int start_decoder(vorb *f)
if (mapping_type != 0) return error(f, VORBIS_invalid_setup);
m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan));
if (get_bits(f,1))
m->submaps = get_bits(f,4);
m->submaps = get_bits(f,4)+1;
else
m->submaps = 1;
if (m->submaps > max_submaps)
@ -3664,8 +3636,8 @@ static int start_decoder(vorb *f)
if (get_bits(f,1)) {
m->coupling_steps = get_bits(f,8)+1;
for (k=0; k < m->coupling_steps; ++k) {
m->chan[k].magnitude = get_bits(f, ilog(f->channels)-1);
m->chan[k].angle = get_bits(f, ilog(f->channels)-1);
m->chan[k].magnitude = get_bits(f, ilog(f->channels-1));
m->chan[k].angle = get_bits(f, ilog(f->channels-1));
if (m->chan[k].magnitude >= f->channels) return error(f, VORBIS_invalid_setup);
if (m->chan[k].angle >= f->channels) return error(f, VORBIS_invalid_setup);
if (m->chan[k].magnitude == m->chan[k].angle) return error(f, VORBIS_invalid_setup);
@ -3814,6 +3786,7 @@ static void vorbis_deinit(stb_vorbis *p)
setup_free(p, p->B[i]);
setup_free(p, p->C[i]);
setup_free(p, p->window[i]);
setup_free(p, p->bit_reverse[i]);
}
#ifndef STB_VORBIS_NO_STDIO
if (p->close_on_free) fclose(p->f);
@ -3970,7 +3943,7 @@ static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len)
f->next_seg = -1; // start a new page
f->current_loc = f->scan[i].sample_loc; // set the current sample location
// to the amount we'd have decoded had we decoded this page
f->current_loc_valid = f->current_loc != ~0;
f->current_loc_valid = f->current_loc != ~0U;
return data_len;
}
// delete entry
@ -4153,11 +4126,12 @@ static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last)
// invalid-but-useful files?
if (end)
*end = stb_vorbis_get_file_offset(f);
if (last)
if (last) {
if (header[5] & 0x04)
*last = 1;
else
*last = 0;
}
set_file_offset(f, retry_loc-1);
return 1;
}
@ -4190,7 +4164,7 @@ static int vorbis_analyze_page(stb_vorbis *f, ProbedPage *z)
{
uint8 header[27], lacing[255];
uint8 packet_type[255];
int num_packet, packet_start, previous =0;
int num_packet, packet_start;
int i,len;
uint32 samples;
@ -4223,7 +4197,7 @@ static int vorbis_analyze_page(stb_vorbis *f, ProbedPage *z)
// scan through the frames to determine the sample-count of each one...
// our goal is the sample # of the first fully-decoded sample on the
// page, which is the first decoded sample of the 2nd page
// page, which is the first decoded sample of the 2nd packet
num_packet=0;
@ -4231,18 +4205,15 @@ static int vorbis_analyze_page(stb_vorbis *f, ProbedPage *z)
for (i=0; i < header[26]; ++i) {
if (packet_start) {
uint8 n,b,m;
uint8 n,b;
if (lacing[i] == 0) goto bail; // trying to read from zero-length packet
n = get8(f);
// if bottom bit is non-zero, we've got corruption
if (n & 1) goto bail;
n >>= 1;
b = ilog(f->mode_count-1);
m = n >> b;
n &= (1 << b)-1;
if (n >= f->mode_count) goto bail;
if (num_packet == 0 && f->mode_config[n].blockflag)
previous = (m & 1);
packet_type[num_packet++] = f->mode_config[n].blockflag;
skip(f, lacing[i]-1);
} else
@ -4531,7 +4502,7 @@ unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f)
if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing);
if (!f->total_samples) {
int last;
unsigned int last;
uint32 lo,hi;
char header[6];
@ -4549,7 +4520,7 @@ unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f)
// previous_safe is now our candidate 'earliest known place that seeking
// to will lead to the final page'
if (!vorbis_find_page(f, &end, (int unsigned *)&last)) {
if (!vorbis_find_page(f, &end, &last)) {
// if we can't find a page, we're hosed!
f->error = VORBIS_cant_find_last_page;
f->total_samples = 0xffffffff;
@ -4564,7 +4535,7 @@ unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f)
// explicitly checking the length of the section
while (!last) {
set_file_offset(f, end);
if (!vorbis_find_page(f, &end, (int unsigned *)&last)) {
if (!vorbis_find_page(f, &end, &last)) {
// the last page we found didn't have the 'last page' flag
// set. whoops!
break;
@ -4663,7 +4634,7 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, stb
return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len);
}
stb_vorbis * stb_vorbis_open_filename(char *filename, int *error, stb_vorbis_alloc *alloc)
stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, stb_vorbis_alloc *alloc)
{
FILE *f = fopen(filename, "rb");
if (f)
@ -4673,14 +4644,14 @@ stb_vorbis * stb_vorbis_open_filename(char *filename, int *error, stb_vorbis_all
}
#endif // STB_VORBIS_NO_STDIO
stb_vorbis * stb_vorbis_open_memory(unsigned char *data, int len, int *error, stb_vorbis_alloc *alloc)
stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, stb_vorbis_alloc *alloc)
{
stb_vorbis *f, p;
if (data == NULL) return NULL;
vorbis_init(&p, alloc);
p.stream = data;
p.stream_end = data + len;
p.stream_start = p.stream;
p.stream = (uint8 *) data;
p.stream_end = (uint8 *) data + len;
p.stream_start = (uint8 *) p.stream;
p.stream_len = len;
p.push_mode = FALSE;
if (start_decoder(&p)) {
@ -4773,7 +4744,6 @@ static void compute_samples(int mask, short *output, int num_c, float **data, in
}
}
static int channel_selector[3][2] = { {0}, {PLAYBACK_MONO}, {PLAYBACK_LEFT, PLAYBACK_RIGHT} };
static void compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len)
{
#define BUFFER_SIZE 32
@ -4823,7 +4793,7 @@ static void convert_samples_short(int buf_c, short **buffer, int b_offset, int d
} else {
int limit = buf_c < data_c ? buf_c : data_c;
for (i=0; i < limit; ++i)
copy_samples(buffer[i]+b_offset, data[i], samples);
copy_samples(buffer[i]+b_offset, data[i]+d_offset, samples);
for ( ; i < buf_c; ++i)
memset(buffer[i]+b_offset, 0, sizeof(short) * samples);
}
@ -4919,7 +4889,7 @@ int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, in
}
#ifndef STB_VORBIS_NO_STDIO
int stb_vorbis_decode_filename(char *filename, int *channels, short **output)
int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output)
{
int data_len, offset, total, limit, error;
short *data;
@ -4927,6 +4897,8 @@ int stb_vorbis_decode_filename(char *filename, int *channels, short **output)
if (v == NULL) return -1;
limit = v->channels * 4096;
*channels = v->channels;
if (sample_rate)
*sample_rate = v->sample_rate;
offset = data_len = 0;
total = limit;
data = (short *) malloc(total * sizeof(*data));
@ -4952,11 +4924,12 @@ int stb_vorbis_decode_filename(char *filename, int *channels, short **output)
}
}
*output = data;
stb_vorbis_close(v);
return data_len;
}
#endif // NO_STDIO
int stb_vorbis_decode_memory(uint8 *mem, int len, int *channels, short **output)
int stb_vorbis_decode_memory(const uint8 *mem, int len, int *channels, int *sample_rate, short **output)
{
int data_len, offset, total, limit, error;
short *data;
@ -4964,6 +4937,8 @@ int stb_vorbis_decode_memory(uint8 *mem, int len, int *channels, short **output)
if (v == NULL) return -1;
limit = v->channels * 4096;
*channels = v->channels;
if (sample_rate)
*sample_rate = v->sample_rate;
offset = data_len = 0;
total = limit;
data = (short *) malloc(total * sizeof(*data));
@ -4989,9 +4964,10 @@ int stb_vorbis_decode_memory(uint8 *mem, int len, int *channels, short **output)
}
}
*output = data;
stb_vorbis_close(v);
return data_len;
}
#endif
#endif // STB_VORBIS_NO_INTEGER_CONVERSION
int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats)
{
@ -5012,8 +4988,10 @@ int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float
}
n += k;
f->channel_buffer_start += k;
if (n == len) break;
if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break;
if (n == len)
break;
if (!stb_vorbis_get_frame_float(f, NULL, &outputs))
break;
}
return n;
}
@ -5030,17 +5008,63 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
if (n+k >= num_samples) k = num_samples - n;
if (k) {
for (i=0; i < z; ++i)
memcpy(buffer[i]+n, f->channel_buffers+f->channel_buffer_start, sizeof(float)*k);
memcpy(buffer[i]+n, f->channel_buffers[i]+f->channel_buffer_start, sizeof(float)*k);
for ( ; i < channels; ++i)
memset(buffer[i]+n, 0, sizeof(float) * k);
}
n += k;
f->channel_buffer_start += k;
if (n == num_samples) break;
if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break;
if (n == num_samples)
break;
if (!stb_vorbis_get_frame_float(f, NULL, &outputs))
break;
}
return n;
}
#endif // STB_VORBIS_NO_PULLDATA_API
/* Version history
1.04 - 2014/08/27 - fix missing const-correct case in API
1.03 - 2014/08/07 - Warning fixes
1.02 - 2014/07/09 - Declare qsort compare function _cdecl on windows
1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float
1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in multichannel
(API change) report sample rate for decode-full-file funcs
0.99996 - bracket #include <malloc.h> for macintosh compilation by Laurent Gomila
0.99995 - use union instead of pointer-cast for fast-float-to-int to avoid alias-optimization problem
0.99994 - change fast-float-to-int to work in single-precision FPU mode, remove endian-dependence
0.99993 - remove assert that fired on legal files with empty tables
0.99992 - rewind-to-start
0.99991 - bugfix to stb_vorbis_get_samples_short by Bernhard Wodo
0.9999 - (should have been 0.99990) fix no-CRT support, compiling as C++
0.9998 - add a full-decode function with a memory source
0.9997 - fix a bug in the read-from-FILE case in 0.9996 addition
0.9996 - query length of vorbis stream in samples/seconds
0.9995 - bugfix to another optimization that only happened in certain files
0.9994 - bugfix to one of the optimizations that caused significant (but inaudible?) errors
0.9993 - performance improvements; runs in 99% to 104% of time of reference implementation
0.9992 - performance improvement of IMDCT; now performs close to reference implementation
0.9991 - performance improvement of IMDCT
0.999 - (should have been 0.9990) performance improvement of IMDCT
0.998 - no-CRT support from Casey Muratori
0.997 - bugfixes for bugs found by Terje Mathisen
0.996 - bugfix: fast-huffman decode initialized incorrectly for sparse codebooks; fixing gives 10% speedup - found by Terje Mathisen
0.995 - bugfix: fix to 'effective' overrun detection - found by Terje Mathisen
0.994 - bugfix: garbage decode on final VQ symbol of a non-multiple - found by Terje Mathisen
0.993 - bugfix: pushdata API required 1 extra byte for empty page (failed to consume final page if empty) - found by Terje Mathisen
0.992 - fixes for MinGW warning
0.991 - turn fast-float-conversion on by default
0.990 - fix push-mode seek recovery if you seek into the headers
0.98b - fix to bad release of 0.98
0.98 - fix push-mode seek recovery; robustify float-to-int and support non-fast mode
0.97 - builds under c++ (typecasting, don't use 'class' keyword)
0.96 - somehow MY 0.95 was right, but the web one was wrong, so here's my 0.95 rereleased as 0.96, fixes a typo in the clamping code
0.95 - clamping code for 16-bit functions
0.94 - not publically released
0.93 - fixed all-zero-floor case (was decoding garbage)
0.92 - fixed a memory leak
0.91 - conditional compiles to omit parts of the API and the infrastructure to support them: STB_VORBIS_NO_PULLDATA_API, STB_VORBIS_NO_PUSHDATA_API, STB_VORBIS_NO_STDIO, STB_VORBIS_NO_INTEGER_CONVERSION
0.90 - first public release
*/
#endif // STB_VORBIS_HEADER_ONLY

View File

@ -1,30 +1,51 @@
// Ogg Vorbis I audio decoder -- version 0.99996
// Ogg Vorbis audio decoder - v1.04 - public domain
// http://nothings.org/stb_vorbis/
//
// Written in April 2007 by Sean Barrett, sponsored by RAD Game Tools.
// Written by Sean Barrett in 2007, last updated in 2014
// Sponsored by RAD Game Tools.
//
// Placed in the public domain April 2007 by the author: no copyright is
// claimed, and you may use it for any purpose you like.
// Placed in the public domain April 2007 by the author: no copyright
// is claimed, and you may use it for any purpose you like.
//
// 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.
//
// Get the latest version and other information at:
// http://nothings.org/stb_vorbis/
// Todo:
//
// - seeking (note you can seek yourself using the pushdata API)
//
// Limitations:
//
// - floor 0 not supported (used in old ogg vorbis files)
// - seeking not supported except manually via PUSHDATA api
// - floor 0 not supported (used in old ogg vorbis files pre-2004)
// - lossless sample-truncation at beginning ignored
// - cannot concatenate multiple vorbis streams
// - sample positions are 32-bit, limiting seekable 192Khz
// files to around 6 hours (Ogg supports 64-bit)
//
// All of these limitations may be removed in future versions.
//
// Bugfix/warning contributors:
// Terje Mathisen Niklas Frykholm Andy Hill
// Casey Muratori John Bolton Gargaj
// Laurent Gomila Marc LeBlanc Ronny Chevalier
// Bernhard Wodo Evan Balster "alxprd"@github
// Tom Beaumont Ingo Leitgeb
// (If you reported a bug but do not appear in this list, it is because
// someone else reported the bug before you. There were too many of you to
// list them all because I was lax about updating for a long time, sorry.)
//
// Partial history:
// 1.04 - 2014/08/27 - fix missing const-correct case in API
// 1.03 - 2014/08/07 - warning fixes
// 1.02 - 2014/07/09 - declare qsort comparison as explicitly _cdecl in Windows
// 1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float (interleaved was correct)
// 1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in >2-channel;
// (API change) report sample rate for decode-full-file funcs
// 0.99996 - - bracket #include <malloc.h> for macintosh compilation
// 0.99995 - - avoid alias-optimization issue in float-to-int conversion
//
// See end of file for full version history.
//////////////////////////////////////////////////////////////////////////////
//
// HEADER BEGINS HERE
//
#ifndef STB_VORBIS_INCLUDE_STB_VORBIS_H
#define STB_VORBIS_INCLUDE_STB_VORBIS_H
@ -37,9 +58,8 @@
#include <stdio.h>
#endif
// NOTE: Added to work with raylib on Android
#if defined(PLATFORM_ANDROID)
#include "utils.h" // Android fopen function map
#ifdef __linux
#include <alloca.h>
#endif
#ifdef __cplusplus
@ -152,6 +172,7 @@ extern int stb_vorbis_decode_frame_pushdata(
// decode a frame of audio sample data if possible from the passed-in data block
//
// return value: number of bytes we used from datablock
//
// possible cases:
// 0 bytes used, 0 samples output (need more data)
// N bytes used, 0 samples output (resynching the stream, keep going)
@ -196,21 +217,23 @@ extern void stb_vorbis_flush_pushdata(stb_vorbis *f);
// just want to go ahead and use pushdata.)
#if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION)
extern int stb_vorbis_decode_filename(char *filename, int *channels, short **output);
extern int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output);
#endif
#if !defined(STB_VORBIS_NO_INTEGER_CONVERSION)
extern int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *channels, int *sample_rate, short **output);
#endif
extern int stb_vorbis_decode_memory(unsigned char *mem, int len, int *channels, short **output);
// decode an entire file and output the data interleaved into a malloc()ed
// buffer stored in *output. The return value is the number of samples
// decoded, or -1 if the file could not be opened or was not an ogg vorbis file.
// When you're done with it, just free() the pointer returned in *output.
extern stb_vorbis * stb_vorbis_open_memory(unsigned char *data, int len,
extern stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len,
int *error, stb_vorbis_alloc *alloc_buffer);
// create an ogg vorbis decoder from an ogg vorbis stream in memory (note
// this must be the entire stream!). on failure, returns NULL and sets *error
#ifndef STB_VORBIS_NO_STDIO
extern stb_vorbis * stb_vorbis_open_filename(char *filename,
extern stb_vorbis * stb_vorbis_open_filename(const char *filename,
int *error, stb_vorbis_alloc *alloc_buffer);
// create an ogg vorbis decoder from a filename via fopen(). on failure,
// returns NULL and sets *error (possibly to VORBIS_file_open_failure).
@ -349,4 +372,8 @@ enum STBVorbisError
}
#endif
#endif // STB_VORBIS_INCLUDE_STB_VORBIS_H
#endif // STB_VORBIS_INCLUDE_STB_VORBIS_H
//
// HEADER ENDS HERE
//
//////////////////////////////////////////////////////////////////////////////

View File

@ -45,16 +45,7 @@
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef unsigned char byte;
// SpriteFont one Character (Glyph) data
typedef struct Character {
int value; //char value = ' '; (int)value = 32;
int x;
int y;
int w;
int h;
} Character;
// ...
//----------------------------------------------------------------------------------
// Global variables
@ -533,6 +524,8 @@ static SpriteFont LoadRBMF(const char *fileName)
FILE *rbmfFile = fopen(fileName, "rb"); // Define a pointer to bitmap file and open it in read-binary mode
// TODO: Check if file could be loaded! (rbmfFile == NULL)?
fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
TraceLog(INFO, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);

View File

@ -36,6 +36,7 @@
#include "utils.h" // rRES data decompression utility function
// NOTE: Includes Android fopen function map
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" // Used to read image data (multiple formats support)
//----------------------------------------------------------------------------------
@ -46,8 +47,6 @@
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef unsigned char byte;
typedef struct {
unsigned char *data; // Image raw data
int width; // Image base width
@ -104,6 +103,8 @@ Image LoadImage(const char *fileName)
// Force loading to 4 components (RGBA)
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
// TODO: Check if file could be loaded! (imgData == NULL)?
if (imgData != NULL)
{
// Convert array to pixel array for working convenience
@ -127,7 +128,7 @@ Image LoadImage(const char *fileName)
TraceLog(INFO, "[%s] Image loaded successfully", fileName);
}
else TraceLog(WARNING, "[%s] Image could not be loaded", fileName);
else TraceLog(WARNING, "[%s] Image could not be loaded, file format not recognized", fileName);
}
else if (strcmp(GetExtension(fileName),"dds") == 0)
{