Updated stb headers
This commit is contained in:
parent
05ccc4fd42
commit
7375d0460a
@ -825,4 +825,4 @@ static Wave LoadOGG(char *fileName)
|
||||
static void UnloadWave(Wave wave)
|
||||
{
|
||||
free(wave.data);
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
12
src/raylib.h
12
src/raylib.h
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
4342
src/stb_image.c
4342
src/stb_image.c
File diff suppressed because it is too large
Load Diff
4503
src/stb_image.h
4503
src/stb_image.h
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
|
276
src/stb_vorbis.c
276
src/stb_vorbis.c
@ -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
|
||||
|
@ -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
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
13
src/text.c
13
src/text.c
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user