|
|
|
@ -1,4 +1,4 @@ |
|
|
|
|
/* stb_image - v1.48 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
|
|
|
|
|
/* stb_image - v1.49 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
|
|
|
|
|
when you control the images you're loading |
|
|
|
|
no warranty implied; use at your own risk |
|
|
|
|
|
|
|
|
@ -24,6 +24,7 @@ |
|
|
|
|
GIF (*comp always reports as 4-channel) |
|
|
|
|
HDR (radiance rgbE format) |
|
|
|
|
PIC (Softimage PIC) |
|
|
|
|
PNM (PPM and PGM binary only) |
|
|
|
|
|
|
|
|
|
- decode from memory or through FILE (define STBI_NO_STDIO to remove code) |
|
|
|
|
- decode from arbitrary I/O callbacks |
|
|
|
@ -50,7 +51,7 @@ |
|
|
|
|
intrinsics or that doesn't support the method used to detect |
|
|
|
|
SSE2 support at run-time), and even those can be reported as |
|
|
|
|
bugs so I can refine the built-in compile-time checking to be |
|
|
|
|
smarter.
|
|
|
|
|
smarter. |
|
|
|
|
|
|
|
|
|
- RGB values computed for JPEG images are slightly different from |
|
|
|
|
previous versions of stb_image. (This is due to using less |
|
|
|
@ -72,12 +73,18 @@ |
|
|
|
|
removed in future versions of the library. It is only intended for |
|
|
|
|
back-compatibility use. |
|
|
|
|
|
|
|
|
|
- Added support for PNM images. |
|
|
|
|
|
|
|
|
|
- Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing |
|
|
|
|
the memory allocator. Unlike other STBI libraries, these macros don't |
|
|
|
|
support a context parameter, so if you need to pass a context in to |
|
|
|
|
the allocator, you'll have to store it in a global or a thread-local |
|
|
|
|
variable. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Latest revision history: |
|
|
|
|
1.49 (2014-12-25) optimize JPG, incl. x86 SIMD |
|
|
|
|
PGM/PPM support |
|
|
|
|
allocation macros |
|
|
|
|
stbi_load_into() -- load into pre-defined memory |
|
|
|
|
STBI_MALLOC,STBI_REALLOC,STBI_FREE |
|
|
|
|
1.48 (2014-12-14) fix incorrectly-named assert() |
|
|
|
|
1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted) |
|
|
|
@ -85,16 +92,12 @@ |
|
|
|
|
fix bug in interlaced PNG with user-specified channel count |
|
|
|
|
1.46 (2014-08-26) fix broken tRNS chunk in non-paletted PNG |
|
|
|
|
1.45 (2014-08-16) workaround MSVC-ARM internal compiler error by wrapping malloc |
|
|
|
|
1.44 (2014-08-07) warnings |
|
|
|
|
1.43 (2014-07-15) fix MSVC-only bug in 1.42 |
|
|
|
|
1.42 (2014-07-09) no _CRT_SECURE_NO_WARNINGS; error-path fixes; STBI_ASSERT |
|
|
|
|
1.41 (2014-06-25) fix search&replace that messed up comments/error messages |
|
|
|
|
|
|
|
|
|
See end of file for full revision history. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
============================ Contributors ========================= |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Image formats Bug fixes & warning fixes |
|
|
|
|
Sean Barrett (jpeg, png, bmp) Marc LeBlanc |
|
|
|
|
Nicolas Schulz (hdr, psd) Christpher Lloyd |
|
|
|
@ -102,26 +105,34 @@ |
|
|
|
|
Jean-Marc Lienher (gif) Won Chun |
|
|
|
|
Tom Seddon (pic) the Horde3D community |
|
|
|
|
Thatcher Ulrich (psd) Janez Zemva |
|
|
|
|
Jonathan Blow |
|
|
|
|
Ken Miller (pgm, ppm) Jonathan Blow |
|
|
|
|
Laurent Gomila |
|
|
|
|
Extensions, features Aruelien Pocheville |
|
|
|
|
Jetro Lauha (stbi_info) Ryamond Barbiero |
|
|
|
|
James "moose2000" Brown (iPhone PNG) David Woo |
|
|
|
|
Ben "Disch" Wenger (io callbacks) Roy Eltham |
|
|
|
|
Martin "SpartanJ" Golini Luke Graham |
|
|
|
|
Omar Cornut (1/2/4-bit png) Thomas Ruf |
|
|
|
|
Aruelien Pocheville |
|
|
|
|
Extensions, features Ryamond Barbiero |
|
|
|
|
Jetro Lauha (stbi_info) David Woo |
|
|
|
|
Martin "SpartanJ" Golini (stbi_info) Martin Golini |
|
|
|
|
James "moose2000" Brown (iPhone PNG) Roy Eltham |
|
|
|
|
Ben "Disch" Wenger (io callbacks) Luke Graham |
|
|
|
|
Omar Cornut (1/2/4-bit PNG) Thomas Ruf |
|
|
|
|
John Bartholomew |
|
|
|
|
Optimizations & bugfixes Ken Hamada |
|
|
|
|
Fabian "ryg" Giesen Cort Stratton |
|
|
|
|
Arseny Kapoulkine Blazej Dariusz Roszkowski |
|
|
|
|
Thibault Reuille |
|
|
|
|
Ken Hamada |
|
|
|
|
Optimizations & bugfixes Cort Stratton |
|
|
|
|
Fabian "ryg" Giesen Blazej Dariusz Roszkowski |
|
|
|
|
Arseny Kapoulkine Thibault Reuille |
|
|
|
|
Paul Du Bois |
|
|
|
|
Guillaume George |
|
|
|
|
Jerry Jansson |
|
|
|
|
If your name should be here but Hayaki Saito |
|
|
|
|
isn't, let Sean know. Johan Duparc |
|
|
|
|
If your name should be here but Jerry Jansson |
|
|
|
|
isn't, let Sean know. Hayaki Saito |
|
|
|
|
Johan Duparc |
|
|
|
|
Ronny Chevalier |
|
|
|
|
Michal Cichon |
|
|
|
|
Tero Hanninen |
|
|
|
|
|
|
|
|
|
License: |
|
|
|
|
This software is in the public domain. Where that dedication is not |
|
|
|
|
recognized, you are granted a perpetual, irrevocable license to copy |
|
|
|
|
and modify this file as you see fit. |
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifndef STBI_INCLUDE_STB_IMAGE_H |
|
|
|
@ -139,7 +150,7 @@ |
|
|
|
|
// Basic usage (see HDR discussion below for HDR usage):
|
|
|
|
|
// int x,y,n;
|
|
|
|
|
// unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
|
|
|
|
|
// // ... process data if not NULL ...
|
|
|
|
|
// // ... process data if not NULL ...
|
|
|
|
|
// // ... x = width, y = height, n = # 8-bit components per pixel ...
|
|
|
|
|
// // ... replace '0' with '1'..'4' to force that many components per pixel
|
|
|
|
|
// // ... but 'n' will always be the number that it would have been if you said 0
|
|
|
|
@ -188,7 +199,7 @@ |
|
|
|
|
// I/O callbacks allow you to read from arbitrary sources, like packaged
|
|
|
|
|
// files or some other source. Data read from callbacks are processed
|
|
|
|
|
// through a small internal buffer (currently 128 bytes) to try to reduce
|
|
|
|
|
// overhead.
|
|
|
|
|
// overhead.
|
|
|
|
|
//
|
|
|
|
|
// The three functions you must define are "read" (reads some bytes of data),
|
|
|
|
|
// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end).
|
|
|
|
@ -238,7 +249,7 @@ |
|
|
|
|
// (linear) floats to preserve the full dynamic range:
|
|
|
|
|
//
|
|
|
|
|
// float *data = stbi_loadf(filename, &x, &y, &n, 0);
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// If you load LDR images through this interface, those images will
|
|
|
|
|
// be promoted to floating point values, run through the inverse of
|
|
|
|
|
// constants corresponding to the above:
|
|
|
|
@ -309,7 +320,7 @@ extern "C" { |
|
|
|
|
|
|
|
|
|
typedef struct |
|
|
|
|
{ |
|
|
|
|
int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read
|
|
|
|
|
int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read
|
|
|
|
|
void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
|
|
|
|
|
int (*eof) (void *user); // returns nonzero if we are at end of file/data
|
|
|
|
|
} stbi_io_callbacks; |
|
|
|
@ -352,7 +363,7 @@ STBIDEF int stbi_is_hdr_from_file(FILE *f); |
|
|
|
|
|
|
|
|
|
// get a VERY brief reason for failure
|
|
|
|
|
// NOT THREADSAFE
|
|
|
|
|
STBIDEF const char *stbi_failure_reason (void);
|
|
|
|
|
STBIDEF const char *stbi_failure_reason (void); |
|
|
|
|
|
|
|
|
|
// free the loaded image -- this is just free()
|
|
|
|
|
STBIDEF void stbi_image_free (void *retval_from_stbi_load); |
|
|
|
@ -542,7 +553,7 @@ typedef struct |
|
|
|
|
{ |
|
|
|
|
stbi__uint32 img_x, img_y; |
|
|
|
|
int img_n, img_out_n; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stbi_io_callbacks io; |
|
|
|
|
void *io_user_data; |
|
|
|
|
|
|
|
|
@ -640,6 +651,9 @@ static stbi_uc *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int |
|
|
|
|
static int stbi__gif_test(stbi__context *s); |
|
|
|
|
static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); |
|
|
|
|
static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); |
|
|
|
|
static int stbi__pnm_test(stbi__context *s); |
|
|
|
|
static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); |
|
|
|
|
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// this is not threadsafe
|
|
|
|
@ -694,6 +708,7 @@ static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp |
|
|
|
|
if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp); |
|
|
|
|
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp); |
|
|
|
|
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp); |
|
|
|
|
if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp); |
|
|
|
|
|
|
|
|
|
#ifndef STBI_NO_HDR |
|
|
|
|
if (stbi__hdr_test(s)) { |
|
|
|
@ -923,7 +938,7 @@ stbi_inline static int stbi__at_eof(stbi__context *s) |
|
|
|
|
if (s->read_from_callbacks == 0) return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return s->img_buffer >= s->img_buffer_end;
|
|
|
|
|
return s->img_buffer >= s->img_buffer_end; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void stbi__skip(stbi__context *s, int n) |
|
|
|
@ -947,7 +962,7 @@ static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) |
|
|
|
|
int res, count; |
|
|
|
|
|
|
|
|
|
memcpy(buffer, s->img_buffer, blen); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); |
|
|
|
|
res = (count == (n-blen)); |
|
|
|
|
s->img_buffer = s->img_buffer_end; |
|
|
|
@ -2685,7 +2700,7 @@ typedef struct |
|
|
|
|
resample_row_func resample; |
|
|
|
|
stbi_uc *line0,*line1; |
|
|
|
|
int hs,vs; // expansion factor in each axis
|
|
|
|
|
int w_lores; // horizontal pixels pre-expansion
|
|
|
|
|
int w_lores; // horizontal pixels pre-expansion
|
|
|
|
|
int ystep; // how far through vertical expansion we are
|
|
|
|
|
int ypos; // which pre-expansion row we're on
|
|
|
|
|
} stbi__resample; |
|
|
|
@ -2845,7 +2860,7 @@ typedef struct |
|
|
|
|
int maxcode[17]; |
|
|
|
|
stbi__uint16 firstsymbol[16]; |
|
|
|
|
stbi_uc size[288]; |
|
|
|
|
stbi__uint16 value[288];
|
|
|
|
|
stbi__uint16 value[288]; |
|
|
|
|
} stbi__zhuffman; |
|
|
|
|
|
|
|
|
|
stbi_inline static int stbi__bitreverse16(int n) |
|
|
|
@ -2873,7 +2888,7 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num) |
|
|
|
|
// DEFLATE spec for generating codes
|
|
|
|
|
memset(sizes, 0, sizeof(sizes)); |
|
|
|
|
memset(z->fast, 0, sizeof(z->fast)); |
|
|
|
|
for (i=0; i < num; ++i)
|
|
|
|
|
for (i=0; i < num; ++i) |
|
|
|
|
++sizes[sizelist[i]]; |
|
|
|
|
sizes[0] = 0; |
|
|
|
|
for (i=1; i < 16; ++i) |
|
|
|
@ -2953,7 +2968,7 @@ stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) |
|
|
|
|
k = z->code_buffer & ((1 << n) - 1); |
|
|
|
|
z->code_buffer >>= n; |
|
|
|
|
z->num_bits -= n; |
|
|
|
|
return k;
|
|
|
|
|
return k; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) |
|
|
|
@ -3011,7 +3026,7 @@ static int stbi__zlength_base[31] = { |
|
|
|
|
15,17,19,23,27,31,35,43,51,59, |
|
|
|
|
67,83,99,115,131,163,195,227,258,0,0 }; |
|
|
|
|
|
|
|
|
|
static int stbi__zlength_extra[31]=
|
|
|
|
|
static int stbi__zlength_extra[31]= |
|
|
|
|
{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; |
|
|
|
|
|
|
|
|
|
static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, |
|
|
|
@ -3676,7 +3691,7 @@ static void stbi__de_iphone(stbi__png *z) |
|
|
|
|
} else { |
|
|
|
|
p[0] = p[2]; |
|
|
|
|
p[2] = t; |
|
|
|
|
}
|
|
|
|
|
} |
|
|
|
|
p += 4; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -4143,7 +4158,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int |
|
|
|
|
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); |
|
|
|
|
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); |
|
|
|
|
a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); |
|
|
|
|
if (target == 4) out[z++] = STBI__BYTECAST(a);
|
|
|
|
|
if (target == 4) out[z++] = STBI__BYTECAST(a); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
stbi__skip(s, pad); |
|
|
|
@ -4467,7 +4482,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int |
|
|
|
|
// Read the rows and columns of the image.
|
|
|
|
|
h = stbi__get32be(s); |
|
|
|
|
w = stbi__get32be(s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure the depth is 8 bits.
|
|
|
|
|
if (stbi__get16be(s) != 8) |
|
|
|
|
return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 bit"); |
|
|
|
@ -4509,7 +4524,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int |
|
|
|
|
|
|
|
|
|
// Initialize the data to zero.
|
|
|
|
|
//memset( out, 0, pixelCount * 4 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Finally, the image data.
|
|
|
|
|
if (compression) { |
|
|
|
|
// RLE as used by .PSD and .TIFF
|
|
|
|
@ -4527,7 +4542,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int |
|
|
|
|
// Read the RLE data by channel.
|
|
|
|
|
for (channel = 0; channel < 4; channel++) { |
|
|
|
|
stbi_uc *p; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p = out+channel; |
|
|
|
|
if (channel >= channelCount) { |
|
|
|
|
// Fill this channel with default data.
|
|
|
|
@ -4565,15 +4580,15 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
// We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
|
|
|
|
|
// where each channel consists of an 8-bit value for each pixel in the image.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Read the data by channel.
|
|
|
|
|
for (channel = 0; channel < 4; channel++) { |
|
|
|
|
stbi_uc *p; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p = out + channel; |
|
|
|
|
if (channel > channelCount) { |
|
|
|
|
// Fill this channel with default data.
|
|
|
|
@ -4594,7 +4609,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int |
|
|
|
|
if (comp) *comp = channelCount; |
|
|
|
|
*y = h; |
|
|
|
|
*x = w; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4812,7 +4827,7 @@ static int stbi__pic_test(stbi__context *s) |
|
|
|
|
|
|
|
|
|
// *************************************************************************************************
|
|
|
|
|
// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
|
|
|
|
|
typedef struct
|
|
|
|
|
typedef struct |
|
|
|
|
{ |
|
|
|
|
stbi__int16 prefix; |
|
|
|
|
stbi_uc first; |
|
|
|
@ -4861,7 +4876,7 @@ static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], in |
|
|
|
|
pal[i][1] = stbi__get8(s); |
|
|
|
|
pal[i][0] = stbi__get8(s); |
|
|
|
|
pal[i][3] = transp == i ? 0 : 255; |
|
|
|
|
}
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) |
|
|
|
@ -4872,8 +4887,8 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in |
|
|
|
|
|
|
|
|
|
version = stbi__get8(s); |
|
|
|
|
if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); |
|
|
|
|
if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); |
|
|
|
|
|
|
|
|
|
if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); |
|
|
|
|
|
|
|
|
|
stbi__g_failure_reason = ""; |
|
|
|
|
g->w = stbi__get16le(s); |
|
|
|
|
g->h = stbi__get16le(s); |
|
|
|
@ -4894,7 +4909,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in |
|
|
|
|
|
|
|
|
|
static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) |
|
|
|
|
{ |
|
|
|
|
stbi__gif g;
|
|
|
|
|
stbi__gif g; |
|
|
|
|
if (!stbi__gif_header(s, &g, comp, 1)) { |
|
|
|
|
stbi__rewind( s ); |
|
|
|
|
return 0; |
|
|
|
@ -4914,7 +4929,7 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) |
|
|
|
|
stbi__out_gif_code(g, g->codes[code].prefix); |
|
|
|
|
|
|
|
|
|
if (g->cur_y >= g->max_y) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p = &g->out[g->cur_x + g->cur_y]; |
|
|
|
|
c = &g->color_table[g->codes[code].suffix * 4]; |
|
|
|
|
|
|
|
|
@ -4968,7 +4983,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) |
|
|
|
|
if (valid_bits < codesize) { |
|
|
|
|
if (len == 0) { |
|
|
|
|
len = stbi__get8(s); // start new block
|
|
|
|
|
if (len == 0)
|
|
|
|
|
if (len == 0) |
|
|
|
|
return g->out; |
|
|
|
|
} |
|
|
|
|
--len; |
|
|
|
@ -5013,7 +5028,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) |
|
|
|
|
} else { |
|
|
|
|
return stbi__errpuc("illegal code in raster", "Corrupt GIF"); |
|
|
|
|
} |
|
|
|
|
}
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -5051,7 +5066,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i |
|
|
|
|
memcpy(g->out, old_out, g->w*g->h*4); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
|
switch (stbi__get8(s)) { |
|
|
|
|
case 0x2C: /* Image Descriptor */ |
|
|
|
@ -5086,16 +5101,16 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i |
|
|
|
|
|
|
|
|
|
if (g->lflags & 0x80) { |
|
|
|
|
stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); |
|
|
|
|
g->color_table = (stbi_uc *) g->lpal;
|
|
|
|
|
g->color_table = (stbi_uc *) g->lpal; |
|
|
|
|
} else if (g->flags & 0x80) { |
|
|
|
|
for (i=0; i < 256; ++i) // @OPTIMIZE: stbi__jpeg_reset only the previous transparent
|
|
|
|
|
g->pal[i][3] = 255;
|
|
|
|
|
g->pal[i][3] = 255; |
|
|
|
|
if (g->transparent >= 0 && (g->eflags & 0x01)) |
|
|
|
|
g->pal[g->transparent][3] = 0; |
|
|
|
|
g->color_table = (stbi_uc *) g->pal; |
|
|
|
|
} else |
|
|
|
|
return stbi__errpuc("missing color table", "Corrupt GIF"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
o = stbi__process_gif_raster(s, g); |
|
|
|
|
if (o == NULL) return NULL; |
|
|
|
|
|
|
|
|
@ -5241,7 +5256,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re |
|
|
|
|
// Check identifier
|
|
|
|
|
if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) |
|
|
|
|
return stbi__errpf("not HDR", "Corrupt HDR image"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parse header
|
|
|
|
|
for(;;) { |
|
|
|
|
token = stbi__hdr_gettoken(s,buffer); |
|
|
|
@ -5309,7 +5324,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re |
|
|
|
|
len |= stbi__get8(s); |
|
|
|
|
if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } |
|
|
|
|
if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < 4; ++k) { |
|
|
|
|
i = 0; |
|
|
|
|
while (i < width) { |
|
|
|
@ -5480,6 +5495,112 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// *************************************************************************************************
|
|
|
|
|
// Portable Gray Map and Portable Pixel Map loader
|
|
|
|
|
// by Ken Miller
|
|
|
|
|
//
|
|
|
|
|
// PGM: http://netpbm.sourceforge.net/doc/pgm.html
|
|
|
|
|
// PPM: http://netpbm.sourceforge.net/doc/ppm.html
|
|
|
|
|
//
|
|
|
|
|
// Known limitations:
|
|
|
|
|
// Does not support comments in the header section
|
|
|
|
|
// Does not support ASCII image data (formats P2 and P3)
|
|
|
|
|
// Does not support 16-bit-per-channel
|
|
|
|
|
|
|
|
|
|
static int stbi__pnm_test(stbi__context *s) |
|
|
|
|
{ |
|
|
|
|
char p, t; |
|
|
|
|
p = (char) stbi__get8(s); |
|
|
|
|
t = (char) stbi__get8(s); |
|
|
|
|
if (p != 'P' || (t != '5' && t != '6')) { |
|
|
|
|
stbi__rewind( s ); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) |
|
|
|
|
{ |
|
|
|
|
stbi_uc *out; |
|
|
|
|
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) |
|
|
|
|
return 0; |
|
|
|
|
*x = s->img_x; |
|
|
|
|
*y = s->img_y; |
|
|
|
|
*comp = s->img_n; |
|
|
|
|
|
|
|
|
|
out = (stbi_uc *) stbi__malloc(s->img_n * s->img_x * s->img_y); |
|
|
|
|
if (!out) return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
|
stbi__getn(s, out, s->img_n * s->img_x * s->img_y); |
|
|
|
|
|
|
|
|
|
if (req_comp && req_comp != s->img_n) { |
|
|
|
|
out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); |
|
|
|
|
if (out == NULL) return out; // stbi__convert_format frees input on failure
|
|
|
|
|
} |
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__pnm_isspace(char c) |
|
|
|
|
{ |
|
|
|
|
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) |
|
|
|
|
{ |
|
|
|
|
while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) |
|
|
|
|
*c = (char) stbi__get8(s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__pnm_isdigit(char c) |
|
|
|
|
{ |
|
|
|
|
return c >= '0' && c <= '9'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__pnm_getinteger(stbi__context *s, char *c) |
|
|
|
|
{ |
|
|
|
|
int value = 0; |
|
|
|
|
|
|
|
|
|
while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { |
|
|
|
|
value = value*10 + (*c - '0'); |
|
|
|
|
*c = (char) stbi__get8(s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) |
|
|
|
|
{ |
|
|
|
|
int maxv; |
|
|
|
|
char c, p, t; |
|
|
|
|
|
|
|
|
|
stbi__rewind( s ); |
|
|
|
|
|
|
|
|
|
// Get identifier
|
|
|
|
|
p = (char) stbi__get8(s); |
|
|
|
|
t = (char) stbi__get8(s); |
|
|
|
|
if (p != 'P' || (t != '5' && t != '6')) { |
|
|
|
|
stbi__rewind( s ); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm
|
|
|
|
|
|
|
|
|
|
c = (char) stbi__get8(s); |
|
|
|
|
stbi__pnm_skip_whitespace(s, &c); |
|
|
|
|
|
|
|
|
|
*x = stbi__pnm_getinteger(s, &c); // read width
|
|
|
|
|
stbi__pnm_skip_whitespace(s, &c); |
|
|
|
|
|
|
|
|
|
*y = stbi__pnm_getinteger(s, &c); // read height
|
|
|
|
|
stbi__pnm_skip_whitespace(s, &c); |
|
|
|
|
|
|
|
|
|
maxv = stbi__pnm_getinteger(s, &c); // read max value
|
|
|
|
|
|
|
|
|
|
if (maxv > 255) |
|
|
|
|
return stbi__err("max value > 255", "PPM image not 8-bit"); |
|
|
|
|
else |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) |
|
|
|
|
{ |
|
|
|
|
if (stbi__jpeg_info(s, x, y, comp)) |
|
|
|
@ -5494,6 +5615,8 @@ static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) |
|
|
|
|
return 1; |
|
|
|
|
if (stbi__pic_info(s, x, y, comp)) |
|
|
|
|
return 1; |
|
|
|
|
if (stbi__pnm_info(s, x, y, comp)) |
|
|
|
|
return 1; |
|
|
|
|
#ifndef STBI_NO_HDR |
|
|
|
|
if (stbi__hdr_info(s, x, y, comp)) |
|
|
|
|
return 1; |
|
|
|
@ -5545,6 +5668,10 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
revision history: |
|
|
|
|
1.49 (2014-12-25) optimize JPG, incl. x86 SIMD (ryg) |
|
|
|
|
PGM/PPM support (Ken Miller) |
|
|
|
|
STBI_MALLOC,STBI_REALLOC,STBI_FREE |
|
|
|
|
stbi_load_into() -- load into pre-defined memory |
|
|
|
|
1.48 (2014-12-14) fix incorrectly-named assert() |
|
|
|
|
1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) |
|
|
|
|
optimize PNG (ryg) |
|
|
|
@ -5598,7 +5725,7 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int |
|
|
|
|
error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) |
|
|
|
|
fix inefficiency in decoding 32-bit BMP (David Woo) |
|
|
|
|
1.29 (2010-08-16) |
|
|
|
|
various warning fixes from Aurelien Pocheville
|
|
|
|
|
various warning fixes from Aurelien Pocheville |
|
|
|
|
1.28 (2010-08-01) |
|
|
|
|
fix bug in GIF palette transparency (SpartanJ) |
|
|
|
|
1.27 (2010-08-01) |
|
|
|
|