| File: | c:\siege\siege/src/siege/internal/stb/stb_image.c |
| Location: | line 2372, column 7 |
| Description: | Potential leak of memory pointed to by 'a.zout_start' |
| 1 | /* stbi-1.33 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c | |||
| 2 | when you control the images you're loading | |||
| 3 | no warranty implied; use at your own risk | |||
| 4 | ||||
| 5 | QUICK NOTES: | |||
| 6 | Primarily of interest to game developers and other people who can | |||
| 7 | avoid problematic images and only need the trivial interface | |||
| 8 | ||||
| 9 | JPEG baseline (no JPEG progressive) | |||
| 10 | PNG 8-bit only | |||
| 11 | ||||
| 12 | TGA (not sure what subset, if a subset) | |||
| 13 | BMP non-1bpp, non-RLE | |||
| 14 | PSD (composited view only, no extra channels) | |||
| 15 | ||||
| 16 | GIF (*comp always reports as 4-channel) | |||
| 17 | HDR (radiance rgbE format) | |||
| 18 | PIC (Softimage PIC) | |||
| 19 | ||||
| 20 | - decode from memory or through FILE (define STBI_NO_STDIO to remove code) | |||
| 21 | - decode from arbitrary I/O callbacks | |||
| 22 | - overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD) | |||
| 23 | ||||
| 24 | Latest revisions: | |||
| 25 | 1.33 (2011-07-14) minor fixes suggested by Dave Moore | |||
| 26 | 1.32 (2011-07-13) info support for all filetypes (SpartanJ) | |||
| 27 | 1.31 (2011-06-19) a few more leak fixes, bug in PNG handling (SpartanJ) | |||
| 28 | 1.30 (2011-06-11) added ability to load files via io callbacks (Ben Wenger) | |||
| 29 | 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville | |||
| 30 | 1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ) | |||
| 31 | 1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila) | |||
| 32 | allow trailing 0s at end of image data (Laurent Gomila) | |||
| 33 | 1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ | |||
| 34 | ||||
| 35 | See end of file for full revision history. | |||
| 36 | ||||
| 37 | TODO: | |||
| 38 | stbi_info support for BMP,PSD,HDR,PIC | |||
| 39 | ||||
| 40 | ||||
| 41 | ============================ Contributors ========================= | |||
| 42 | ||||
| 43 | Image formats Optimizations & bugfixes | |||
| 44 | Sean Barrett (jpeg, png, bmp) Fabian "ryg" Giesen | |||
| 45 | Nicolas Schulz (hdr, psd) | |||
| 46 | Jonathan Dummer (tga) Bug fixes & warning fixes | |||
| 47 | Jean-Marc Lienher (gif) Marc LeBlanc | |||
| 48 | Tom Seddon (pic) Christpher Lloyd | |||
| 49 | Thatcher Ulrich (psd) Dave Moore | |||
| 50 | Won Chun | |||
| 51 | the Horde3D community | |||
| 52 | Extensions, features Janez Zemva | |||
| 53 | Jetro Lauha (stbi_info) Jonathan Blow | |||
| 54 | James "moose2000" Brown (iPhone PNG) Laurent Gomila | |||
| 55 | Ben "Disch" Wenger (io callbacks) Aruelien Pocheville | |||
| 56 | Martin "SpartanJ" Golini Ryamond Barbiero | |||
| 57 | David Woo | |||
| 58 | ||||
| 59 | ||||
| 60 | If your name should be here but isn't, let Sean know. | |||
| 61 | ||||
| 62 | */ | |||
| 63 | ||||
| 64 | #ifndef STBI_INCLUDE_STB_IMAGE_H | |||
| 65 | #define STBI_INCLUDE_STB_IMAGE_H | |||
| 66 | ||||
| 67 | // To get a header file for this, either cut and paste the header, | |||
| 68 | // or create stb_image.h, #define STBI_HEADER_FILE_ONLY, and | |||
| 69 | // then include stb_image.c from it. | |||
| 70 | ||||
| 71 | //// begin header file //////////////////////////////////////////////////// | |||
| 72 | // | |||
| 73 | // Limitations: | |||
| 74 | // - no jpeg progressive support | |||
| 75 | // - non-HDR formats support 8-bit samples only (jpeg, png) | |||
| 76 | // - no delayed line count (jpeg) -- IJG doesn't support either | |||
| 77 | // - no 1-bit BMP | |||
| 78 | // - GIF always returns *comp=4 | |||
| 79 | // | |||
| 80 | // Basic usage (see HDR discussion below): | |||
| 81 | // int x,y,n; | |||
| 82 | // unsigned char *data = stbi_load(filename, &x, &y, &n, 0); | |||
| 83 | // // ... process data if not NULL ... | |||
| 84 | // // ... x = width, y = height, n = # 8-bit components per pixel ... | |||
| 85 | // // ... replace '0' with '1'..'4' to force that many components per pixel | |||
| 86 | // // ... but 'n' will always be the number that it would have been if you said 0 | |||
| 87 | // stbi_image_free(data) | |||
| 88 | // | |||
| 89 | // Standard parameters: | |||
| 90 | // int *x -- outputs image width in pixels | |||
| 91 | // int *y -- outputs image height in pixels | |||
| 92 | // int *comp -- outputs # of image components in image file | |||
| 93 | // int req_comp -- if non-zero, # of image components requested in result | |||
| 94 | // | |||
| 95 | // The return value from an image loader is an 'unsigned char *' which points | |||
| 96 | // to the pixel data. The pixel data consists of *y scanlines of *x pixels, | |||
| 97 | // with each pixel consisting of N interleaved 8-bit components; the first | |||
| 98 | // pixel pointed to is top-left-most in the image. There is no padding between | |||
| 99 | // image scanlines or between pixels, regardless of format. The number of | |||
| 100 | // components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. | |||
| 101 | // If req_comp is non-zero, *comp has the number of components that _would_ | |||
| 102 | // have been output otherwise. E.g. if you set req_comp to 4, you will always | |||
| 103 | // get RGBA output, but you can check *comp to easily see if it's opaque. | |||
| 104 | // | |||
| 105 | // An output image with N components has the following components interleaved | |||
| 106 | // in this order in each pixel: | |||
| 107 | // | |||
| 108 | // N=#comp components | |||
| 109 | // 1 grey | |||
| 110 | // 2 grey, alpha | |||
| 111 | // 3 red, green, blue | |||
| 112 | // 4 red, green, blue, alpha | |||
| 113 | // | |||
| 114 | // If image loading fails for any reason, the return value will be NULL, | |||
| 115 | // and *x, *y, *comp will be unchanged. The function stbi_failure_reason() | |||
| 116 | // can be queried for an extremely brief, end-user unfriendly explanation | |||
| 117 | // of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid | |||
| 118 | // compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly | |||
| 119 | // more user-friendly ones. | |||
| 120 | // | |||
| 121 | // Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. | |||
| 122 | // | |||
| 123 | // =========================================================================== | |||
| 124 | // | |||
| 125 | // iPhone PNG support: | |||
| 126 | // | |||
| 127 | // By default we convert iphone-formatted PNGs back to RGB; nominally they | |||
| 128 | // would silently load as BGR, except the existing code should have just | |||
| 129 | // failed on such iPhone PNGs. But you can disable this conversion by | |||
| 130 | // by calling stbi_convert_iphone_png_to_rgb(0), in which case | |||
| 131 | // you will always just get the native iphone "format" through. | |||
| 132 | // | |||
| 133 | // Call stbi_set_unpremultiply_on_load(1) as well to force a divide per | |||
| 134 | // pixel to remove any premultiplied alpha *only* if the image file explicitly | |||
| 135 | // says there's premultiplied data (currently only happens in iPhone images, | |||
| 136 | // and only if iPhone convert-to-rgb processing is on). | |||
| 137 | // | |||
| 138 | // =========================================================================== | |||
| 139 | // | |||
| 140 | // HDR image support (disable by defining STBI_NO_HDR) | |||
| 141 | // | |||
| 142 | // stb_image now supports loading HDR images in general, and currently | |||
| 143 | // the Radiance .HDR file format, although the support is provided | |||
| 144 | // generically. You can still load any file through the existing interface; | |||
| 145 | // if you attempt to load an HDR file, it will be automatically remapped to | |||
| 146 | // LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; | |||
| 147 | // both of these constants can be reconfigured through this interface: | |||
| 148 | // | |||
| 149 | // stbi_hdr_to_ldr_gamma(2.2f); | |||
| 150 | // stbi_hdr_to_ldr_scale(1.0f); | |||
| 151 | // | |||
| 152 | // (note, do not use _inverse_ constants; stbi_image will invert them | |||
| 153 | // appropriately). | |||
| 154 | // | |||
| 155 | // Additionally, there is a new, parallel interface for loading files as | |||
| 156 | // (linear) floats to preserve the full dynamic range: | |||
| 157 | // | |||
| 158 | // float *data = stbi_loadf(filename, &x, &y, &n, 0); | |||
| 159 | // | |||
| 160 | // If you load LDR images through this interface, those images will | |||
| 161 | // be promoted to floating point values, run through the inverse of | |||
| 162 | // constants corresponding to the above: | |||
| 163 | // | |||
| 164 | // stbi_ldr_to_hdr_scale(1.0f); | |||
| 165 | // stbi_ldr_to_hdr_gamma(2.2f); | |||
| 166 | // | |||
| 167 | // Finally, given a filename (or an open file or memory block--see header | |||
| 168 | // file for details) containing image data, you can query for the "most | |||
| 169 | // appropriate" interface to use (that is, whether the image is HDR or | |||
| 170 | // not), using: | |||
| 171 | // | |||
| 172 | // stbi_is_hdr(char *filename); | |||
| 173 | // | |||
| 174 | // =========================================================================== | |||
| 175 | // | |||
| 176 | // I/O callbacks | |||
| 177 | // | |||
| 178 | // I/O callbacks allow you to read from arbitrary sources, like packaged | |||
| 179 | // files or some other source. Data read from callbacks are processed | |||
| 180 | // through a small internal buffer (currently 128 bytes) to try to reduce | |||
| 181 | // overhead. | |||
| 182 | // | |||
| 183 | // The three functions you must define are "read" (reads some bytes of data), | |||
| 184 | // "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). | |||
| 185 | ||||
| 186 | ||||
| 187 | #ifndef STBI_NO_STDIO | |||
| 188 | ||||
| 189 | #if defined(_MSC_VER) && _MSC_VER >= 0x1400 | |||
| 190 | #define _CRT_SECURE_NO_WARNINGS // suppress bogus warnings about fopen() | |||
| 191 | #endif | |||
| 192 | ||||
| 193 | #include <stdio.h> | |||
| 194 | #endif | |||
| 195 | ||||
| 196 | #define STBI_VERSION1 1 | |||
| 197 | ||||
| 198 | enum | |||
| 199 | { | |||
| 200 | STBI_default = 0, // only used for req_comp | |||
| 201 | ||||
| 202 | STBI_grey = 1, | |||
| 203 | STBI_grey_alpha = 2, | |||
| 204 | STBI_rgb = 3, | |||
| 205 | STBI_rgb_alpha = 4 | |||
| 206 | }; | |||
| 207 | ||||
| 208 | typedef unsigned char stbi_uc; | |||
| 209 | ||||
| 210 | #ifdef __cplusplus | |||
| 211 | extern "C" { | |||
| 212 | #endif | |||
| 213 | ||||
| 214 | ////////////////////////////////////////////////////////////////////////////// | |||
| 215 | // | |||
| 216 | // PRIMARY API - works on images of any type | |||
| 217 | // | |||
| 218 | ||||
| 219 | // | |||
| 220 | // load image by filename, open file, or memory buffer | |||
| 221 | // | |||
| 222 | ||||
| 223 | extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); | |||
| 224 | ||||
| 225 | #ifndef STBI_NO_STDIO | |||
| 226 | extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); | |||
| 227 | extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); | |||
| 228 | // for stbi_load_from_file, file pointer is left pointing immediately after image | |||
| 229 | #endif | |||
| 230 | ||||
| 231 | typedef struct | |||
| 232 | { | |||
| 233 | int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read | |||
| 234 | void (*skip) (void *user,unsigned n); // skip the next 'n' bytes | |||
| 235 | int (*eof) (void *user); // returns nonzero if we are at end of file/data | |||
| 236 | } stbi_io_callbacks; | |||
| 237 | ||||
| 238 | extern stbi_uc *stbi_load_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); | |||
| 239 | ||||
| 240 | #ifndef STBI_NO_HDR | |||
| 241 | extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); | |||
| 242 | ||||
| 243 | #ifndef STBI_NO_STDIO | |||
| 244 | extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); | |||
| 245 | extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); | |||
| 246 | #endif | |||
| 247 | ||||
| 248 | extern float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); | |||
| 249 | ||||
| 250 | extern void stbi_hdr_to_ldr_gamma(float gamma); | |||
| 251 | extern void stbi_hdr_to_ldr_scale(float scale); | |||
| 252 | ||||
| 253 | extern void stbi_ldr_to_hdr_gamma(float gamma); | |||
| 254 | extern void stbi_ldr_to_hdr_scale(float scale); | |||
| 255 | #endif // STBI_NO_HDR | |||
| 256 | ||||
| 257 | // stbi_is_hdr is always defined | |||
| 258 | extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); | |||
| 259 | extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); | |||
| 260 | #ifndef STBI_NO_STDIO | |||
| 261 | extern int stbi_is_hdr (char const *filename); | |||
| 262 | extern int stbi_is_hdr_from_file(FILE *f); | |||
| 263 | #endif // STBI_NO_STDIO | |||
| 264 | ||||
| 265 | ||||
| 266 | // get a VERY brief reason for failure | |||
| 267 | // NOT THREADSAFE | |||
| 268 | extern const char *stbi_failure_reason (void); | |||
| 269 | ||||
| 270 | // free the loaded image -- this is just free() | |||
| 271 | extern void stbi_image_free (void *retval_from_stbi_load); | |||
| 272 | ||||
| 273 | // get image dimensions & components without fully decoding | |||
| 274 | extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); | |||
| 275 | extern int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); | |||
| 276 | ||||
| 277 | #ifndef STBI_NO_STDIO | |||
| 278 | extern int stbi_info (char const *filename, int *x, int *y, int *comp); | |||
| 279 | extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); | |||
| 280 | ||||
| 281 | #endif | |||
| 282 | ||||
| 283 | ||||
| 284 | ||||
| 285 | // for image formats that explicitly notate that they have premultiplied alpha, | |||
| 286 | // we just return the colors as stored in the file. set this flag to force | |||
| 287 | // unpremultiplication. results are undefined if the unpremultiply overflow. | |||
| 288 | extern void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); | |||
| 289 | ||||
| 290 | // indicate whether we should process iphone images back to canonical format, | |||
| 291 | // or just pass them through "as-is" | |||
| 292 | extern void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); | |||
| 293 | ||||
| 294 | ||||
| 295 | // ZLIB client - used by PNG, available for other purposes | |||
| 296 | ||||
| 297 | extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); | |||
| 298 | extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); | |||
| 299 | extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); | |||
| 300 | ||||
| 301 | extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); | |||
| 302 | extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); | |||
| 303 | ||||
| 304 | ||||
| 305 | // define faster low-level operations (typically SIMD support) | |||
| 306 | #ifdef STBI_SIMD | |||
| 307 | typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize); | |||
| 308 | // compute an integer IDCT on "input" | |||
| 309 | // input[x] = data[x] * dequantize[x] | |||
| 310 | // write results to 'out': 64 samples, each run of 8 spaced by 'out_stride' | |||
| 311 | // CLAMP results to 0..255 | |||
| 312 | typedef void (*stbi_YCbCr_to_RGB_run)(stbi_uc *output, stbi_uc const *y, stbi_uc const *cb, stbi_uc const *cr, int count, int step); | |||
| 313 | // compute a conversion from YCbCr to RGB | |||
| 314 | // 'count' pixels | |||
| 315 | // write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B | |||
| 316 | // y: Y input channel | |||
| 317 | // cb: Cb input channel; scale/biased to be 0..255 | |||
| 318 | // cr: Cr input channel; scale/biased to be 0..255 | |||
| 319 | ||||
| 320 | extern void stbi_install_idct(stbi_idct_8x8 func); | |||
| 321 | extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func); | |||
| 322 | #endif // STBI_SIMD | |||
| 323 | ||||
| 324 | ||||
| 325 | #ifdef __cplusplus | |||
| 326 | } | |||
| 327 | #endif | |||
| 328 | ||||
| 329 | // | |||
| 330 | // | |||
| 331 | //// end header file ///////////////////////////////////////////////////// | |||
| 332 | #endif // STBI_INCLUDE_STB_IMAGE_H | |||
| 333 | ||||
| 334 | #ifndef STBI_HEADER_FILE_ONLY | |||
| 335 | ||||
| 336 | #ifndef STBI_NO_HDR | |||
| 337 | #include <math.h> // ldexp | |||
| 338 | #include <string.h> // strcmp, strtok | |||
| 339 | #endif | |||
| 340 | ||||
| 341 | #ifndef STBI_NO_STDIO | |||
| 342 | #include <stdio.h> | |||
| 343 | #endif | |||
| 344 | #include <stdlib.h> | |||
| 345 | #include <memory.h> | |||
| 346 | #include <assert.h> | |||
| 347 | #include <stdarg.h> | |||
| 348 | ||||
| 349 | #ifndef _MSC_VER | |||
| 350 | #ifdef __cplusplus | |||
| 351 | #define stbi_inline inline | |||
| 352 | #else | |||
| 353 | #define stbi_inline | |||
| 354 | #endif | |||
| 355 | #else | |||
| 356 | #define stbi_inline __forceinline | |||
| 357 | #endif | |||
| 358 | ||||
| 359 | ||||
| 360 | // implementation: | |||
| 361 | typedef unsigned char uint8; | |||
| 362 | typedef unsigned short uint16; | |||
| 363 | typedef signed short int16; | |||
| 364 | typedef unsigned int uint32; | |||
| 365 | typedef signed int int32; | |||
| 366 | typedef unsigned int uint; | |||
| 367 | ||||
| 368 | // should produce compiler error if size is wrong | |||
| 369 | typedef unsigned char validate_uint32[sizeof(uint32)==4 ? 1 : -1]; | |||
| 370 | ||||
| 371 | #if defined(STBI_NO_STDIO) && !defined(STBI_NO_WRITE) | |||
| 372 | #define STBI_NO_WRITE | |||
| 373 | #endif | |||
| 374 | ||||
| 375 | #define STBI_NOTUSED(v)(void)sizeof(v) (void)sizeof(v) | |||
| 376 | ||||
| 377 | #ifdef _MSC_VER | |||
| 378 | #define STBI_HAS_LROTL | |||
| 379 | #endif | |||
| 380 | ||||
| 381 | #ifdef STBI_HAS_LROTL | |||
| 382 | #define stbi_lrot(x,y)(((x) << (y)) | ((x) >> (32 - (y)))) _lrotl(x,y) | |||
| 383 | #else | |||
| 384 | #define stbi_lrot(x,y)(((x) << (y)) | ((x) >> (32 - (y)))) (((x) << (y)) | ((x) >> (32 - (y)))) | |||
| 385 | #endif | |||
| 386 | ||||
| 387 | /////////////////////////////////////////////// | |||
| 388 | // | |||
| 389 | // stbi struct and start_xxx functions | |||
| 390 | ||||
| 391 | // stbi structure is our basic context used by all images, so it | |||
| 392 | // contains all the IO context, plus some basic image information | |||
| 393 | typedef struct | |||
| 394 | { | |||
| 395 | uint32 img_x, img_y; | |||
| 396 | int img_n, img_out_n; | |||
| 397 | ||||
| 398 | stbi_io_callbacks io; | |||
| 399 | void *io_user_data; | |||
| 400 | ||||
| 401 | int read_from_callbacks; | |||
| 402 | int buflen; | |||
| 403 | uint8 buffer_start[128]; | |||
| 404 | ||||
| 405 | uint8 *img_buffer, *img_buffer_end; | |||
| 406 | uint8 *img_buffer_original; | |||
| 407 | } stbi; | |||
| 408 | ||||
| 409 | ||||
| 410 | static void refill_buffer(stbi *s); | |||
| 411 | ||||
| 412 | // initialize a memory-decode context | |||
| 413 | static void start_mem(stbi *s, uint8 const *buffer, int len) | |||
| 414 | { | |||
| 415 | s->io.read = NULL((void*)0); | |||
| 416 | s->read_from_callbacks = 0; | |||
| 417 | s->img_buffer = s->img_buffer_original = (uint8 *) buffer; | |||
| 418 | s->img_buffer_end = (uint8 *) buffer+len; | |||
| 419 | } | |||
| 420 | ||||
| 421 | // initialize a callback-based context | |||
| 422 | static void start_callbacks(stbi *s, stbi_io_callbacks *c, void *user) | |||
| 423 | { | |||
| 424 | s->io = *c; | |||
| 425 | s->io_user_data = user; | |||
| 426 | s->buflen = sizeof(s->buffer_start); | |||
| 427 | s->read_from_callbacks = 1; | |||
| 428 | s->img_buffer_original = s->buffer_start; | |||
| 429 | refill_buffer(s); | |||
| 430 | } | |||
| 431 | ||||
| 432 | #ifndef STBI_NO_STDIO | |||
| 433 | ||||
| 434 | static int stdio_read(void *user, char *data, int size) | |||
| 435 | { | |||
| 436 | return (int) fread(data,1,size,(FILE*) user); | |||
| 437 | } | |||
| 438 | ||||
| 439 | static void stdio_skip(void *user, unsigned n) | |||
| 440 | { | |||
| 441 | fseek((FILE*) user, n, SEEK_CUR1); | |||
| 442 | } | |||
| 443 | ||||
| 444 | static int stdio_eof(void *user) | |||
| 445 | { | |||
| 446 | return feof((FILE*) user)(((FILE*) user)->_flag & 0x0010); | |||
| 447 | } | |||
| 448 | ||||
| 449 | static stbi_io_callbacks stbi_stdio_callbacks = | |||
| 450 | { | |||
| 451 | stdio_read, | |||
| 452 | stdio_skip, | |||
| 453 | stdio_eof, | |||
| 454 | }; | |||
| 455 | ||||
| 456 | static void start_file(stbi *s, FILE *f) | |||
| 457 | { | |||
| 458 | start_callbacks(s, &stbi_stdio_callbacks, (void *) f); | |||
| 459 | } | |||
| 460 | ||||
| 461 | //static void stop_file(stbi *s) { } | |||
| 462 | ||||
| 463 | #endif // !STBI_NO_STDIO | |||
| 464 | ||||
| 465 | static void stbi_rewind(stbi *s) | |||
| 466 | { | |||
| 467 | // conceptually rewind SHOULD rewind to the beginning of the stream, | |||
| 468 | // but we just rewind to the beginning of the initial buffer, because | |||
| 469 | // we only use it after doing 'test', which only ever looks at at most 92 bytes | |||
| 470 | s->img_buffer = s->img_buffer_original; | |||
| 471 | } | |||
| 472 | ||||
| 473 | static int stbi_jpeg_test(stbi *s); | |||
| 474 | static stbi_uc *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp); | |||
| 475 | static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp); | |||
| 476 | static int stbi_png_test(stbi *s); | |||
| 477 | static stbi_uc *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp); | |||
| 478 | static int stbi_png_info(stbi *s, int *x, int *y, int *comp); | |||
| 479 | static int stbi_bmp_test(stbi *s); | |||
| 480 | static stbi_uc *stbi_bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp); | |||
| 481 | static int stbi_tga_test(stbi *s); | |||
| 482 | static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp); | |||
| 483 | static int stbi_tga_info(stbi *s, int *x, int *y, int *comp); | |||
| 484 | static int stbi_psd_test(stbi *s); | |||
| 485 | static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp); | |||
| 486 | static int stbi_hdr_test(stbi *s); | |||
| 487 | static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp); | |||
| 488 | static int stbi_pic_test(stbi *s); | |||
| 489 | static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp); | |||
| 490 | static int stbi_gif_test(stbi *s); | |||
| 491 | static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp); | |||
| 492 | static int stbi_gif_info(stbi *s, int *x, int *y, int *comp); | |||
| 493 | ||||
| 494 | ||||
| 495 | // this is not threadsafe | |||
| 496 | static const char *failure_reason; | |||
| 497 | ||||
| 498 | const char *stbi_failure_reason(void) | |||
| 499 | { | |||
| 500 | return failure_reason; | |||
| 501 | } | |||
| 502 | ||||
| 503 | static int e(const char *str) | |||
| 504 | { | |||
| 505 | failure_reason = str; | |||
| 506 | return 0; | |||
| 507 | } | |||
| 508 | ||||
| 509 | // e - error | |||
| 510 | // epf - error returning pointer to float | |||
| 511 | // epuc - error returning pointer to unsigned char | |||
| 512 | ||||
| 513 | #ifdef STBI_NO_FAILURE_STRINGS | |||
| 514 | #define e(x,y)e(x) 0 | |||
| 515 | #elif defined(STBI_FAILURE_USERMSG) | |||
| 516 | #define e(x,y)e(x) e(y) | |||
| 517 | #else | |||
| 518 | #define e(x,y)e(x) e(x) | |||
| 519 | #endif | |||
| 520 | ||||
| 521 | #define epf(x,y)((float *) (e(x)?((void*)0):((void*)0))) ((float *) (e(x,y)e(x)?NULL((void*)0):NULL((void*)0))) | |||
| 522 | #define epuc(x,y)((unsigned char *) (e(x)?((void*)0):((void*)0))) ((unsigned char *) (e(x,y)e(x)?NULL((void*)0):NULL((void*)0))) | |||
| 523 | ||||
| 524 | void stbi_image_free(void *retval_from_stbi_load) | |||
| 525 | { | |||
| 526 | free(retval_from_stbi_load); | |||
| 527 | } | |||
| 528 | ||||
| 529 | #ifndef STBI_NO_HDR | |||
| 530 | static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp); | |||
| 531 | static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp); | |||
| 532 | #endif | |||
| 533 | ||||
| 534 | static unsigned char *stbi_load_main(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 535 | { | |||
| 536 | if (stbi_jpeg_test(s)) return stbi_jpeg_load(s,x,y,comp,req_comp); | |||
| 537 | if (stbi_png_test(s)) return stbi_png_load(s,x,y,comp,req_comp); | |||
| 538 | if (stbi_bmp_test(s)) return stbi_bmp_load(s,x,y,comp,req_comp); | |||
| 539 | if (stbi_gif_test(s)) return stbi_gif_load(s,x,y,comp,req_comp); | |||
| 540 | if (stbi_psd_test(s)) return stbi_psd_load(s,x,y,comp,req_comp); | |||
| 541 | if (stbi_pic_test(s)) return stbi_pic_load(s,x,y,comp,req_comp); | |||
| 542 | ||||
| 543 | #ifndef STBI_NO_HDR | |||
| 544 | if (stbi_hdr_test(s)) { | |||
| 545 | float *hdr = stbi_hdr_load(s, x,y,comp,req_comp); | |||
| 546 | return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); | |||
| 547 | } | |||
| 548 | #endif | |||
| 549 | ||||
| 550 | // test tga last because it's a crappy test! | |||
| 551 | if (stbi_tga_test(s)) | |||
| 552 | return stbi_tga_load(s,x,y,comp,req_comp); | |||
| 553 | return epuc("unknown image type", "Image not of any known type, or corrupt")((unsigned char *) (e("unknown image type")?((void*)0):((void *)0))); | |||
| 554 | } | |||
| 555 | ||||
| 556 | #ifndef STBI_NO_STDIO | |||
| 557 | unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) | |||
| 558 | { | |||
| 559 | FILE *f = fopen(filename, "rb"); | |||
| 560 | unsigned char *result; | |||
| 561 | if (!f) return epuc("can't fopen", "Unable to open file")((unsigned char *) (e("can't fopen")?((void*)0):((void*)0))); | |||
| 562 | result = stbi_load_from_file(f,x,y,comp,req_comp); | |||
| 563 | fclose(f); | |||
| 564 | return result; | |||
| 565 | } | |||
| 566 | ||||
| 567 | unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) | |||
| 568 | { | |||
| 569 | stbi s; | |||
| 570 | start_file(&s,f); | |||
| 571 | return stbi_load_main(&s,x,y,comp,req_comp); | |||
| 572 | } | |||
| 573 | #endif //!STBI_NO_STDIO | |||
| 574 | ||||
| 575 | unsigned char *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) | |||
| 576 | { | |||
| 577 | stbi s; | |||
| 578 | start_mem(&s,buffer,len); | |||
| 579 | return stbi_load_main(&s,x,y,comp,req_comp); | |||
| 580 | } | |||
| 581 | ||||
| 582 | unsigned char *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) | |||
| 583 | { | |||
| 584 | stbi s; | |||
| 585 | start_callbacks(&s, (stbi_io_callbacks *) clbk, user); | |||
| 586 | return stbi_load_main(&s,x,y,comp,req_comp); | |||
| 587 | } | |||
| 588 | ||||
| 589 | #ifndef STBI_NO_HDR | |||
| 590 | ||||
| 591 | float *stbi_loadf_main(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 592 | { | |||
| 593 | unsigned char *data; | |||
| 594 | #ifndef STBI_NO_HDR | |||
| 595 | if (stbi_hdr_test(s)) | |||
| 596 | return stbi_hdr_load(s,x,y,comp,req_comp); | |||
| 597 | #endif | |||
| 598 | data = stbi_load_main(s, x, y, comp, req_comp); | |||
| 599 | if (data) | |||
| 600 | return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); | |||
| 601 | return epf("unknown image type", "Image not of any known type, or corrupt")((float *) (e("unknown image type")?((void*)0):((void*)0))); | |||
| 602 | } | |||
| 603 | ||||
| 604 | float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) | |||
| 605 | { | |||
| 606 | stbi s; | |||
| 607 | start_mem(&s,buffer,len); | |||
| 608 | return stbi_loadf_main(&s,x,y,comp,req_comp); | |||
| 609 | } | |||
| 610 | ||||
| 611 | float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) | |||
| 612 | { | |||
| 613 | stbi s; | |||
| 614 | start_callbacks(&s, (stbi_io_callbacks *) clbk, user); | |||
| 615 | return stbi_loadf_main(&s,x,y,comp,req_comp); | |||
| 616 | } | |||
| 617 | ||||
| 618 | #ifndef STBI_NO_STDIO | |||
| 619 | float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) | |||
| 620 | { | |||
| 621 | FILE *f = fopen(filename, "rb"); | |||
| 622 | float *result; | |||
| 623 | if (!f) return epf("can't fopen", "Unable to open file")((float *) (e("can't fopen")?((void*)0):((void*)0))); | |||
| 624 | result = stbi_loadf_from_file(f,x,y,comp,req_comp); | |||
| 625 | fclose(f); | |||
| 626 | return result; | |||
| 627 | } | |||
| 628 | ||||
| 629 | float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) | |||
| 630 | { | |||
| 631 | stbi s; | |||
| 632 | start_file(&s,f); | |||
| 633 | return stbi_loadf_main(&s,x,y,comp,req_comp); | |||
| 634 | } | |||
| 635 | #endif // !STBI_NO_STDIO | |||
| 636 | ||||
| 637 | #endif // !STBI_NO_HDR | |||
| 638 | ||||
| 639 | // these is-hdr-or-not is defined independent of whether STBI_NO_HDR is | |||
| 640 | // defined, for API simplicity; if STBI_NO_HDR is defined, it always | |||
| 641 | // reports false! | |||
| 642 | ||||
| 643 | int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) | |||
| 644 | { | |||
| 645 | #ifndef STBI_NO_HDR | |||
| 646 | stbi s; | |||
| 647 | start_mem(&s,buffer,len); | |||
| 648 | return stbi_hdr_test(&s); | |||
| 649 | #else | |||
| 650 | STBI_NOTUSED(buffer)(void)sizeof(buffer); | |||
| 651 | STBI_NOTUSED(len)(void)sizeof(len); | |||
| 652 | return 0; | |||
| 653 | #endif | |||
| 654 | } | |||
| 655 | ||||
| 656 | #ifndef STBI_NO_STDIO | |||
| 657 | extern int stbi_is_hdr (char const *filename) | |||
| 658 | { | |||
| 659 | FILE *f = fopen(filename, "rb"); | |||
| 660 | int result=0; | |||
| 661 | if (f) { | |||
| 662 | result = stbi_is_hdr_from_file(f); | |||
| 663 | fclose(f); | |||
| 664 | } | |||
| 665 | return result; | |||
| 666 | } | |||
| 667 | ||||
| 668 | extern int stbi_is_hdr_from_file(FILE *f) | |||
| 669 | { | |||
| 670 | #ifndef STBI_NO_HDR | |||
| 671 | stbi s; | |||
| 672 | start_file(&s,f); | |||
| 673 | return stbi_hdr_test(&s); | |||
| 674 | #else | |||
| 675 | return 0; | |||
| 676 | #endif | |||
| 677 | } | |||
| 678 | #endif // !STBI_NO_STDIO | |||
| 679 | ||||
| 680 | extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) | |||
| 681 | { | |||
| 682 | #ifndef STBI_NO_HDR | |||
| 683 | stbi s; | |||
| 684 | start_callbacks(&s, (stbi_io_callbacks *) clbk, user); | |||
| 685 | return stbi_hdr_test(&s); | |||
| 686 | #else | |||
| 687 | return 0; | |||
| 688 | #endif | |||
| 689 | } | |||
| 690 | ||||
| 691 | #ifndef STBI_NO_HDR | |||
| 692 | static float h2l_gamma_i=1.0f/2.2f, h2l_scale_i=1.0f; | |||
| 693 | static float l2h_gamma=2.2f, l2h_scale=1.0f; | |||
| 694 | ||||
| 695 | void stbi_hdr_to_ldr_gamma(float gamma) { h2l_gamma_i = 1/gamma; } | |||
| 696 | void stbi_hdr_to_ldr_scale(float scale) { h2l_scale_i = 1/scale; } | |||
| 697 | ||||
| 698 | void stbi_ldr_to_hdr_gamma(float gamma) { l2h_gamma = gamma; } | |||
| 699 | void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; } | |||
| 700 | #endif | |||
| 701 | ||||
| 702 | ||||
| 703 | ////////////////////////////////////////////////////////////////////////////// | |||
| 704 | // | |||
| 705 | // Common code used by all image loaders | |||
| 706 | // | |||
| 707 | ||||
| 708 | enum | |||
| 709 | { | |||
| 710 | SCAN_load=0, | |||
| 711 | SCAN_type, | |||
| 712 | SCAN_header | |||
| 713 | }; | |||
| 714 | ||||
| 715 | static void refill_buffer(stbi *s) | |||
| 716 | { | |||
| 717 | int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); | |||
| 718 | if (n == 0) { | |||
| 719 | // at end of file, treat same as if from memory | |||
| 720 | s->read_from_callbacks = 0; | |||
| 721 | s->img_buffer = s->img_buffer_end-1; | |||
| 722 | *s->img_buffer = 0; | |||
| 723 | } else { | |||
| 724 | s->img_buffer = s->buffer_start; | |||
| 725 | s->img_buffer_end = s->buffer_start + n; | |||
| 726 | } | |||
| 727 | } | |||
| 728 | ||||
| 729 | stbi_inline static int get8(stbi *s) | |||
| 730 | { | |||
| 731 | if (s->img_buffer < s->img_buffer_end) | |||
| 732 | return *s->img_buffer++; | |||
| 733 | if (s->read_from_callbacks) { | |||
| 734 | refill_buffer(s); | |||
| 735 | return *s->img_buffer++; | |||
| 736 | } | |||
| 737 | return 0; | |||
| 738 | } | |||
| 739 | ||||
| 740 | stbi_inline static int at_eof(stbi *s) | |||
| 741 | { | |||
| 742 | if (s->io.read) { | |||
| 743 | if (!(s->io.eof)(s->io_user_data)) return 0; | |||
| 744 | // if feof() is true, check if buffer = end | |||
| 745 | // special case: we've only got the special 0 character at the end | |||
| 746 | if (s->read_from_callbacks == 0) return 1; | |||
| 747 | } | |||
| 748 | ||||
| 749 | return s->img_buffer >= s->img_buffer_end; | |||
| 750 | } | |||
| 751 | ||||
| 752 | stbi_inline static uint8 get8u(stbi *s) | |||
| 753 | { | |||
| 754 | return (uint8) get8(s); | |||
| 755 | } | |||
| 756 | ||||
| 757 | static void skip(stbi *s, int n) | |||
| 758 | { | |||
| 759 | if (s->io.read) { | |||
| 760 | int blen = s->img_buffer_end - s->img_buffer; | |||
| 761 | if (blen < n) { | |||
| 762 | s->img_buffer = s->img_buffer_end; | |||
| 763 | (s->io.skip)(s->io_user_data, n - blen); | |||
| 764 | return; | |||
| 765 | } | |||
| 766 | } | |||
| 767 | s->img_buffer += n; | |||
| 768 | } | |||
| 769 | ||||
| 770 | static int getn(stbi *s, stbi_uc *buffer, int n) | |||
| 771 | { | |||
| 772 | if (s->io.read) { | |||
| 773 | int blen = s->img_buffer_end - s->img_buffer; | |||
| 774 | if (blen < n) { | |||
| 775 | int res, count; | |||
| 776 | ||||
| 777 | memcpy(buffer, s->img_buffer, blen); | |||
| 778 | ||||
| 779 | count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); | |||
| 780 | res = (count == (n-blen)); | |||
| 781 | s->img_buffer = s->img_buffer_end; | |||
| 782 | return res; | |||
| 783 | } | |||
| 784 | } | |||
| 785 | ||||
| 786 | if (s->img_buffer+n <= s->img_buffer_end) { | |||
| 787 | memcpy(buffer, s->img_buffer, n); | |||
| 788 | s->img_buffer += n; | |||
| 789 | return 1; | |||
| 790 | } else | |||
| 791 | return 0; | |||
| 792 | } | |||
| 793 | ||||
| 794 | static int get16(stbi *s) | |||
| 795 | { | |||
| 796 | int z = get8(s); | |||
| 797 | return (z << 8) + get8(s); | |||
| 798 | } | |||
| 799 | ||||
| 800 | static uint32 get32(stbi *s) | |||
| 801 | { | |||
| 802 | uint32 z = get16(s); | |||
| 803 | return (z << 16) + get16(s); | |||
| 804 | } | |||
| 805 | ||||
| 806 | static int get16le(stbi *s) | |||
| 807 | { | |||
| 808 | int z = get8(s); | |||
| 809 | return z + (get8(s) << 8); | |||
| 810 | } | |||
| 811 | ||||
| 812 | static uint32 get32le(stbi *s) | |||
| 813 | { | |||
| 814 | uint32 z = get16le(s); | |||
| 815 | return z + (get16le(s) << 16); | |||
| 816 | } | |||
| 817 | ||||
| 818 | ////////////////////////////////////////////////////////////////////////////// | |||
| 819 | // | |||
| 820 | // generic converter from built-in img_n to req_comp | |||
| 821 | // individual types do this automatically as much as possible (e.g. jpeg | |||
| 822 | // does all cases internally since it needs to colorspace convert anyway, | |||
| 823 | // and it never has alpha, so very few cases ). png can automatically | |||
| 824 | // interleave an alpha=255 channel, but falls back to this for other cases | |||
| 825 | // | |||
| 826 | // assume data buffer is malloced, so malloc a new one and free that one | |||
| 827 | // only failure mode is malloc failing | |||
| 828 | ||||
| 829 | static uint8 compute_y(int r, int g, int b) | |||
| 830 | { | |||
| 831 | return (uint8) (((r*77) + (g*150) + (29*b)) >> 8); | |||
| 832 | } | |||
| 833 | ||||
| 834 | static unsigned char *convert_format(unsigned char *data, int img_n, int req_comp, uint x, uint y) | |||
| 835 | { | |||
| 836 | int i,j; | |||
| 837 | unsigned char *good; | |||
| 838 | ||||
| 839 | if (req_comp == img_n) return data; | |||
| 840 | assert(req_comp >= 1 && req_comp <= 4)((req_comp >= 1 && req_comp <= 4) ? (void)0 : _assert ("req_comp >= 1 && req_comp <= 4", "src/siege/internal/stb/stb_image.c" , 840)); | |||
| 841 | ||||
| 842 | good = (unsigned char *) malloc(req_comp * x * y); | |||
| 843 | if (good == NULL((void*)0)) { | |||
| 844 | free(data); | |||
| 845 | return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); | |||
| 846 | } | |||
| 847 | ||||
| 848 | for (j=0; j < (int) y; ++j) { | |||
| 849 | unsigned char *src = data + j * x * img_n ; | |||
| 850 | unsigned char *dest = good + j * x * req_comp; | |||
| 851 | ||||
| 852 | #define COMBO(a,b)((a)*8+(b)) ((a)*8+(b)) | |||
| 853 | #define CASE(a,b) case COMBO(a,b)((a)*8+(b)): for(i=x-1; i >= 0; --i, src += a, dest += b) | |||
| 854 | // convert source image with img_n components to one with req_comp components; | |||
| 855 | // avoid switch per pixel, so use switch per scanline and massive macros | |||
| 856 | switch (COMBO(img_n, req_comp)((img_n)*8+(req_comp))) { | |||
| 857 | CASE(1,2) dest[0]=src[0], dest[1]=255; break; | |||
| 858 | CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; | |||
| 859 | CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; | |||
| 860 | CASE(2,1) dest[0]=src[0]; break; | |||
| 861 | CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; | |||
| 862 | CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; | |||
| 863 | CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; | |||
| 864 | CASE(3,1) dest[0]=compute_y(src[0],src[1],src[2]); break; | |||
| 865 | CASE(3,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = 255; break; | |||
| 866 | CASE(4,1) dest[0]=compute_y(src[0],src[1],src[2]); break; | |||
| 867 | CASE(4,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; | |||
| 868 | CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; | |||
| 869 | default: assert(0)((0) ? (void)0 : _assert("0", "src/siege/internal/stb/stb_image.c" , 869)); | |||
| 870 | } | |||
| 871 | #undef CASE | |||
| 872 | } | |||
| 873 | ||||
| 874 | free(data); | |||
| 875 | return good; | |||
| 876 | } | |||
| 877 | ||||
| 878 | #ifndef STBI_NO_HDR | |||
| 879 | static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp) | |||
| 880 | { | |||
| 881 | int i,k,n; | |||
| 882 | float *output = (float *) malloc(x * y * comp * sizeof(float)); | |||
| 883 | if (output == NULL((void*)0)) { free(data); return epf("outofmem", "Out of memory")((float *) (e("outofmem")?((void*)0):((void*)0))); } | |||
| 884 | // compute number of non-alpha components | |||
| 885 | if (comp & 1) n = comp; else n = comp-1; | |||
| 886 | for (i=0; i < x*y; ++i) { | |||
| 887 | for (k=0; k < n; ++k) { | |||
| 888 | output[i*comp + k] = (float) pow(data[i*comp+k]/255.0f, l2h_gamma) * l2h_scale; | |||
| 889 | } | |||
| 890 | if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; | |||
| 891 | } | |||
| 892 | free(data); | |||
| 893 | return output; | |||
| 894 | } | |||
| 895 | ||||
| 896 | #define float2int(x)((int) (x)) ((int) (x)) | |||
| 897 | static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp) | |||
| 898 | { | |||
| 899 | int i,k,n; | |||
| 900 | stbi_uc *output = (stbi_uc *) malloc(x * y * comp); | |||
| 901 | if (output == NULL((void*)0)) { free(data); return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); } | |||
| 902 | // compute number of non-alpha components | |||
| 903 | if (comp & 1) n = comp; else n = comp-1; | |||
| 904 | for (i=0; i < x*y; ++i) { | |||
| 905 | for (k=0; k < n; ++k) { | |||
| 906 | float z = (float) pow(data[i*comp+k]*h2l_scale_i, h2l_gamma_i) * 255 + 0.5f; | |||
| 907 | if (z < 0) z = 0; | |||
| 908 | if (z > 255) z = 255; | |||
| 909 | output[i*comp + k] = (uint8) float2int(z)((int) (z)); | |||
| 910 | } | |||
| 911 | if (k < comp) { | |||
| 912 | float z = data[i*comp+k] * 255 + 0.5f; | |||
| 913 | if (z < 0) z = 0; | |||
| 914 | if (z > 255) z = 255; | |||
| 915 | output[i*comp + k] = (uint8) float2int(z)((int) (z)); | |||
| 916 | } | |||
| 917 | } | |||
| 918 | free(data); | |||
| 919 | return output; | |||
| 920 | } | |||
| 921 | #endif | |||
| 922 | ||||
| 923 | ////////////////////////////////////////////////////////////////////////////// | |||
| 924 | // | |||
| 925 | // "baseline" JPEG/JFIF decoder (not actually fully baseline implementation) | |||
| 926 | // | |||
| 927 | // simple implementation | |||
| 928 | // - channel subsampling of at most 2 in each dimension | |||
| 929 | // - doesn't support delayed output of y-dimension | |||
| 930 | // - simple interface (only one output format: 8-bit interleaved RGB) | |||
| 931 | // - doesn't try to recover corrupt jpegs | |||
| 932 | // - doesn't allow partial loading, loading multiple at once | |||
| 933 | // - still fast on x86 (copying globals into locals doesn't help x86) | |||
| 934 | // - allocates lots of intermediate memory (full size of all components) | |||
| 935 | // - non-interleaved case requires this anyway | |||
| 936 | // - allows good upsampling (see next) | |||
| 937 | // high-quality | |||
| 938 | // - upsampled channels are bilinearly interpolated, even across blocks | |||
| 939 | // - quality integer IDCT derived from IJG's 'slow' | |||
| 940 | // performance | |||
| 941 | // - fast huffman; reasonable integer IDCT | |||
| 942 | // - uses a lot of intermediate memory, could cache poorly | |||
| 943 | // - load http://nothings.org/remote/anemones.jpg 3 times on 2.8Ghz P4 | |||
| 944 | // stb_jpeg: 1.34 seconds (MSVC6, default release build) | |||
| 945 | // stb_jpeg: 1.06 seconds (MSVC6, processor = Pentium Pro) | |||
| 946 | // IJL11.dll: 1.08 seconds (compiled by intel) | |||
| 947 | // IJG 1998: 0.98 seconds (MSVC6, makefile provided by IJG) | |||
| 948 | // IJG 1998: 0.95 seconds (MSVC6, makefile + proc=PPro) | |||
| 949 | ||||
| 950 | // huffman decoding acceleration | |||
| 951 | #define FAST_BITS9 9 // larger handles more cases; smaller stomps less cache | |||
| 952 | ||||
| 953 | typedef struct | |||
| 954 | { | |||
| 955 | uint8 fast[1 << FAST_BITS9]; | |||
| 956 | // weirdly, repacking this into AoS is a 10% speed loss, instead of a win | |||
| 957 | uint16 code[256]; | |||
| 958 | uint8 values[256]; | |||
| 959 | uint8 size[257]; | |||
| 960 | unsigned int maxcode[18]; | |||
| 961 | int delta[17]; // old 'firstsymbol' - old 'firstcode' | |||
| 962 | } huffman; | |||
| 963 | ||||
| 964 | typedef struct | |||
| 965 | { | |||
| 966 | #ifdef STBI_SIMD | |||
| 967 | unsigned short dequant2[4][64]; | |||
| 968 | #endif | |||
| 969 | stbi *s; | |||
| 970 | huffman huff_dc[4]; | |||
| 971 | huffman huff_ac[4]; | |||
| 972 | uint8 dequant[4][64]; | |||
| 973 | ||||
| 974 | // sizes for components, interleaved MCUs | |||
| 975 | int img_h_max, img_v_max; | |||
| 976 | int img_mcu_x, img_mcu_y; | |||
| 977 | int img_mcu_w, img_mcu_h; | |||
| 978 | ||||
| 979 | // definition of jpeg image component | |||
| 980 | struct | |||
| 981 | { | |||
| 982 | int id; | |||
| 983 | int h,v; | |||
| 984 | int tq; | |||
| 985 | int hd,ha; | |||
| 986 | int dc_pred; | |||
| 987 | ||||
| 988 | int x,y,w2,h2; | |||
| 989 | uint8 *data; | |||
| 990 | void *raw_data; | |||
| 991 | uint8 *linebuf; | |||
| 992 | } img_comp[4]; | |||
| 993 | ||||
| 994 | uint32 code_buffer; // jpeg entropy-coded buffer | |||
| 995 | int code_bits; // number of valid bits | |||
| 996 | unsigned char marker; // marker seen while filling entropy buffer | |||
| 997 | int nomore; // flag if we saw a marker so must stop | |||
| 998 | ||||
| 999 | int scan_n, order[4]; | |||
| 1000 | int restart_interval, todo; | |||
| 1001 | } jpeg; | |||
| 1002 | ||||
| 1003 | static int build_huffman(huffman *h, int *count) | |||
| 1004 | { | |||
| 1005 | int i,j,k=0,code; | |||
| 1006 | // build size list for each symbol (from JPEG spec) | |||
| 1007 | for (i=0; i < 16; ++i) | |||
| 1008 | for (j=0; j < count[i]; ++j) | |||
| 1009 | h->size[k++] = (uint8) (i+1); | |||
| 1010 | h->size[k] = 0; | |||
| 1011 | ||||
| 1012 | // compute actual symbols (from jpeg spec) | |||
| 1013 | code = 0; | |||
| 1014 | k = 0; | |||
| 1015 | for(j=1; j <= 16; ++j) { | |||
| 1016 | // compute delta to add to code to compute symbol id | |||
| 1017 | h->delta[j] = k - code; | |||
| 1018 | if (h->size[k] == j) { | |||
| 1019 | while (h->size[k] == j) | |||
| 1020 | h->code[k++] = (uint16) (code++); | |||
| 1021 | if (code-1 >= (1 << j)) return e("bad code lengths","Corrupt JPEG")e("bad code lengths"); | |||
| 1022 | } | |||
| 1023 | // compute largest code + 1 for this size, preshifted as needed later | |||
| 1024 | h->maxcode[j] = code << (16-j); | |||
| 1025 | code <<= 1; | |||
| 1026 | } | |||
| 1027 | h->maxcode[j] = 0xffffffff; | |||
| 1028 | ||||
| 1029 | // build non-spec acceleration table; 255 is flag for not-accelerated | |||
| 1030 | memset(h->fast, 255, 1 << FAST_BITS9); | |||
| 1031 | for (i=0; i < k; ++i) { | |||
| 1032 | int s = h->size[i]; | |||
| 1033 | if (s <= FAST_BITS9) { | |||
| 1034 | int c = h->code[i] << (FAST_BITS9-s); | |||
| 1035 | int m = 1 << (FAST_BITS9-s); | |||
| 1036 | for (j=0; j < m; ++j) { | |||
| 1037 | h->fast[c+j] = (uint8) i; | |||
| 1038 | } | |||
| 1039 | } | |||
| 1040 | } | |||
| 1041 | return 1; | |||
| 1042 | } | |||
| 1043 | ||||
| 1044 | static void grow_buffer_unsafe(jpeg *j) | |||
| 1045 | { | |||
| 1046 | do { | |||
| 1047 | int b = j->nomore ? 0 : get8(j->s); | |||
| 1048 | if (b == 0xff) { | |||
| 1049 | int c = get8(j->s); | |||
| 1050 | if (c != 0) { | |||
| 1051 | j->marker = (unsigned char) c; | |||
| 1052 | j->nomore = 1; | |||
| 1053 | return; | |||
| 1054 | } | |||
| 1055 | } | |||
| 1056 | j->code_buffer |= b << (24 - j->code_bits); | |||
| 1057 | j->code_bits += 8; | |||
| 1058 | } while (j->code_bits <= 24); | |||
| 1059 | } | |||
| 1060 | ||||
| 1061 | // (1 << n) - 1 | |||
| 1062 | static uint32 bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; | |||
| 1063 | ||||
| 1064 | // decode a jpeg huffman value from the bitstream | |||
| 1065 | stbi_inline static int decode(jpeg *j, huffman *h) | |||
| 1066 | { | |||
| 1067 | unsigned int temp; | |||
| 1068 | int c,k; | |||
| 1069 | ||||
| 1070 | if (j->code_bits < 16) grow_buffer_unsafe(j); | |||
| 1071 | ||||
| 1072 | // look at the top FAST_BITS and determine what symbol ID it is, | |||
| 1073 | // if the code is <= FAST_BITS | |||
| 1074 | c = (j->code_buffer >> (32 - FAST_BITS9)) & ((1 << FAST_BITS9)-1); | |||
| 1075 | k = h->fast[c]; | |||
| 1076 | if (k < 255) { | |||
| 1077 | int s = h->size[k]; | |||
| 1078 | if (s > j->code_bits) | |||
| 1079 | return -1; | |||
| 1080 | j->code_buffer <<= s; | |||
| 1081 | j->code_bits -= s; | |||
| 1082 | return h->values[k]; | |||
| 1083 | } | |||
| 1084 | ||||
| 1085 | // naive test is to shift the code_buffer down so k bits are | |||
| 1086 | // valid, then test against maxcode. To speed this up, we've | |||
| 1087 | // preshifted maxcode left so that it has (16-k) 0s at the | |||
| 1088 | // end; in other words, regardless of the number of bits, it | |||
| 1089 | // wants to be compared against something shifted to have 16; | |||
| 1090 | // that way we don't need to shift inside the loop. | |||
| 1091 | temp = j->code_buffer >> 16; | |||
| 1092 | for (k=FAST_BITS9+1 ; ; ++k) | |||
| 1093 | if (temp < h->maxcode[k]) | |||
| 1094 | break; | |||
| 1095 | if (k == 17) { | |||
| 1096 | // error! code not found | |||
| 1097 | j->code_bits -= 16; | |||
| 1098 | return -1; | |||
| 1099 | } | |||
| 1100 | ||||
| 1101 | if (k > j->code_bits) | |||
| 1102 | return -1; | |||
| 1103 | ||||
| 1104 | // convert the huffman code to the symbol id | |||
| 1105 | c = ((j->code_buffer >> (32 - k)) & bmask[k]) + h->delta[k]; | |||
| 1106 | assert((((j->code_buffer) >> (32 - h->size[c])) & bmask[h->size[c]]) == h->code[c])(((((j->code_buffer) >> (32 - h->size[c])) & bmask [h->size[c]]) == h->code[c]) ? (void)0 : _assert("(((j->code_buffer) >> (32 - h->size[c])) & bmask[h->size[c]]) == h->code[c]" , "src/siege/internal/stb/stb_image.c", 1106)); | |||
| 1107 | ||||
| 1108 | // convert the id to a symbol | |||
| 1109 | j->code_bits -= k; | |||
| 1110 | j->code_buffer <<= k; | |||
| 1111 | return h->values[c]; | |||
| 1112 | } | |||
| 1113 | ||||
| 1114 | // combined JPEG 'receive' and JPEG 'extend', since baseline | |||
| 1115 | // always extends everything it receives. | |||
| 1116 | stbi_inline static int extend_receive(jpeg *j, int n) | |||
| 1117 | { | |||
| 1118 | unsigned int m = 1 << (n-1); | |||
| 1119 | unsigned int k; | |||
| 1120 | if (j->code_bits < n) grow_buffer_unsafe(j); | |||
| 1121 | ||||
| 1122 | #if 1 | |||
| 1123 | k = stbi_lrot(j->code_buffer, n)(((j->code_buffer) << (n)) | ((j->code_buffer) >> (32 - (n)))); | |||
| 1124 | j->code_buffer = k & ~bmask[n]; | |||
| 1125 | k &= bmask[n]; | |||
| 1126 | j->code_bits -= n; | |||
| 1127 | #else | |||
| 1128 | k = (j->code_buffer >> (32 - n)) & bmask[n]; | |||
| 1129 | j->code_bits -= n; | |||
| 1130 | j->code_buffer <<= n; | |||
| 1131 | #endif | |||
| 1132 | // the following test is probably a random branch that won't | |||
| 1133 | // predict well. I tried to table accelerate it but failed. | |||
| 1134 | // maybe it's compiling as a conditional move? | |||
| 1135 | if (k < m) | |||
| 1136 | return (-1 << n) + k + 1; | |||
| 1137 | else | |||
| 1138 | return k; | |||
| 1139 | } | |||
| 1140 | ||||
| 1141 | // given a value that's at position X in the zigzag stream, | |||
| 1142 | // where does it appear in the 8x8 matrix coded as row-major? | |||
| 1143 | static uint8 dezigzag[64+15] = | |||
| 1144 | { | |||
| 1145 | 0, 1, 8, 16, 9, 2, 3, 10, | |||
| 1146 | 17, 24, 32, 25, 18, 11, 4, 5, | |||
| 1147 | 12, 19, 26, 33, 40, 48, 41, 34, | |||
| 1148 | 27, 20, 13, 6, 7, 14, 21, 28, | |||
| 1149 | 35, 42, 49, 56, 57, 50, 43, 36, | |||
| 1150 | 29, 22, 15, 23, 30, 37, 44, 51, | |||
| 1151 | 58, 59, 52, 45, 38, 31, 39, 46, | |||
| 1152 | 53, 60, 61, 54, 47, 55, 62, 63, | |||
| 1153 | // let corrupt input sample past end | |||
| 1154 | 63, 63, 63, 63, 63, 63, 63, 63, | |||
| 1155 | 63, 63, 63, 63, 63, 63, 63 | |||
| 1156 | }; | |||
| 1157 | ||||
| 1158 | // decode one 64-entry block-- | |||
| 1159 | static int decode_block(jpeg *j, short data[64], huffman *hdc, huffman *hac, int b) | |||
| 1160 | { | |||
| 1161 | int diff,dc,k; | |||
| 1162 | int t = decode(j, hdc); | |||
| 1163 | if (t < 0) return e("bad huffman code","Corrupt JPEG")e("bad huffman code"); | |||
| 1164 | ||||
| 1165 | // 0 all the ac values now so we can do it 32-bits at a time | |||
| 1166 | memset(data,0,64*sizeof(data[0])); | |||
| 1167 | ||||
| 1168 | diff = t ? extend_receive(j, t) : 0; | |||
| 1169 | dc = j->img_comp[b].dc_pred + diff; | |||
| 1170 | j->img_comp[b].dc_pred = dc; | |||
| 1171 | data[0] = (short) dc; | |||
| 1172 | ||||
| 1173 | // decode AC components, see JPEG spec | |||
| 1174 | k = 1; | |||
| 1175 | do { | |||
| 1176 | int r,s; | |||
| 1177 | int rs = decode(j, hac); | |||
| 1178 | if (rs < 0) return e("bad huffman code","Corrupt JPEG")e("bad huffman code"); | |||
| 1179 | s = rs & 15; | |||
| 1180 | r = rs >> 4; | |||
| 1181 | if (s == 0) { | |||
| 1182 | if (rs != 0xf0) break; // end block | |||
| 1183 | k += 16; | |||
| 1184 | } else { | |||
| 1185 | k += r; | |||
| 1186 | // decode into unzigzag'd location | |||
| 1187 | data[dezigzag[k++]] = (short) extend_receive(j,s); | |||
| 1188 | } | |||
| 1189 | } while (k < 64); | |||
| 1190 | return 1; | |||
| 1191 | } | |||
| 1192 | ||||
| 1193 | // take a -128..127 value and clamp it and convert to 0..255 | |||
| 1194 | stbi_inline static uint8 clamp(int x) | |||
| 1195 | { | |||
| 1196 | // trick to use a single test to catch both cases | |||
| 1197 | if ((unsigned int) x > 255) { | |||
| 1198 | if (x < 0) return 0; | |||
| 1199 | if (x > 255) return 255; | |||
| 1200 | } | |||
| 1201 | return (uint8) x; | |||
| 1202 | } | |||
| 1203 | ||||
| 1204 | #define f2f(x)(int) (((x) * 4096 + 0.5)) (int) (((x) * 4096 + 0.5)) | |||
| 1205 | #define fsh(x)((x) << 12) ((x) << 12) | |||
| 1206 | ||||
| 1207 | // derived from jidctint -- DCT_ISLOW | |||
| 1208 | #define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7)int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; p2 = s2; p3 = s6; p1 = (p2+p3) * (int) (((0.5411961f) * 4096 + 0.5)); t2 = p1 + p3*(int) (((-1.847759065f) * 4096 + 0.5)); t3 = p1 + p2*(int ) (((0.765366865f) * 4096 + 0.5)); p2 = s0; p3 = s4; t0 = ((p2 +p3) << 12); t1 = ((p2-p3) << 12); x0 = t0+t3; x3 = t0-t3; x1 = t1+t2; x2 = t1-t2; t0 = s7; t1 = s5; t2 = s3; t3 = s1; p3 = t0+t2; p4 = t1+t3; p1 = t0+t3; p2 = t1+t2; p5 = ( p3+p4)*(int) (((1.175875602f) * 4096 + 0.5)); t0 = t0*(int) ( ((0.298631336f) * 4096 + 0.5)); t1 = t1*(int) (((2.053119869f ) * 4096 + 0.5)); t2 = t2*(int) (((3.072711026f) * 4096 + 0.5 )); t3 = t3*(int) (((1.501321110f) * 4096 + 0.5)); p1 = p5 + p1 *(int) (((-0.899976223f) * 4096 + 0.5)); p2 = p5 + p2*(int) ( ((-2.562915447f) * 4096 + 0.5)); p3 = p3*(int) (((-1.961570560f ) * 4096 + 0.5)); p4 = p4*(int) (((-0.390180644f) * 4096 + 0.5 )); t3 += p1+p4; t2 += p2+p3; t1 += p2+p4; t0 += p1+p3; \ | |||
| 1209 | int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ | |||
| 1210 | p2 = s2; \ | |||
| 1211 | p3 = s6; \ | |||
| 1212 | p1 = (p2+p3) * f2f(0.5411961f)(int) (((0.5411961f) * 4096 + 0.5)); \ | |||
| 1213 | t2 = p1 + p3*f2f(-1.847759065f)(int) (((-1.847759065f) * 4096 + 0.5)); \ | |||
| 1214 | t3 = p1 + p2*f2f( 0.765366865f)(int) (((0.765366865f) * 4096 + 0.5)); \ | |||
| 1215 | p2 = s0; \ | |||
| 1216 | p3 = s4; \ | |||
| 1217 | t0 = fsh(p2+p3)((p2+p3) << 12); \ | |||
| 1218 | t1 = fsh(p2-p3)((p2-p3) << 12); \ | |||
| 1219 | x0 = t0+t3; \ | |||
| 1220 | x3 = t0-t3; \ | |||
| 1221 | x1 = t1+t2; \ | |||
| 1222 | x2 = t1-t2; \ | |||
| 1223 | t0 = s7; \ | |||
| 1224 | t1 = s5; \ | |||
| 1225 | t2 = s3; \ | |||
| 1226 | t3 = s1; \ | |||
| 1227 | p3 = t0+t2; \ | |||
| 1228 | p4 = t1+t3; \ | |||
| 1229 | p1 = t0+t3; \ | |||
| 1230 | p2 = t1+t2; \ | |||
| 1231 | p5 = (p3+p4)*f2f( 1.175875602f)(int) (((1.175875602f) * 4096 + 0.5)); \ | |||
| 1232 | t0 = t0*f2f( 0.298631336f)(int) (((0.298631336f) * 4096 + 0.5)); \ | |||
| 1233 | t1 = t1*f2f( 2.053119869f)(int) (((2.053119869f) * 4096 + 0.5)); \ | |||
| 1234 | t2 = t2*f2f( 3.072711026f)(int) (((3.072711026f) * 4096 + 0.5)); \ | |||
| 1235 | t3 = t3*f2f( 1.501321110f)(int) (((1.501321110f) * 4096 + 0.5)); \ | |||
| 1236 | p1 = p5 + p1*f2f(-0.899976223f)(int) (((-0.899976223f) * 4096 + 0.5)); \ | |||
| 1237 | p2 = p5 + p2*f2f(-2.562915447f)(int) (((-2.562915447f) * 4096 + 0.5)); \ | |||
| 1238 | p3 = p3*f2f(-1.961570560f)(int) (((-1.961570560f) * 4096 + 0.5)); \ | |||
| 1239 | p4 = p4*f2f(-0.390180644f)(int) (((-0.390180644f) * 4096 + 0.5)); \ | |||
| 1240 | t3 += p1+p4; \ | |||
| 1241 | t2 += p2+p3; \ | |||
| 1242 | t1 += p2+p4; \ | |||
| 1243 | t0 += p1+p3; | |||
| 1244 | ||||
| 1245 | #ifdef STBI_SIMD | |||
| 1246 | typedef unsigned short stbi_dequantize_t; | |||
| 1247 | #else | |||
| 1248 | typedef uint8 stbi_dequantize_t; | |||
| 1249 | #endif | |||
| 1250 | ||||
| 1251 | // .344 seconds on 3*anemones.jpg | |||
| 1252 | static void idct_block(uint8 *out, int out_stride, short data[64], stbi_dequantize_t *dequantize) | |||
| 1253 | { | |||
| 1254 | int i,val[64],*v=val; | |||
| 1255 | stbi_dequantize_t *dq = dequantize; | |||
| 1256 | uint8 *o; | |||
| 1257 | short *d = data; | |||
| 1258 | ||||
| 1259 | // columns | |||
| 1260 | for (i=0; i < 8; ++i,++d,++dq, ++v) { | |||
| 1261 | // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing | |||
| 1262 | if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 | |||
| 1263 | && d[40]==0 && d[48]==0 && d[56]==0) { | |||
| 1264 | // no shortcut 0 seconds | |||
| 1265 | // (1|2|3|4|5|6|7)==0 0 seconds | |||
| 1266 | // all separate -0.047 seconds | |||
| 1267 | // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds | |||
| 1268 | int dcterm = d[0] * dq[0] << 2; | |||
| 1269 | v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; | |||
| 1270 | } else { | |||
| 1271 | IDCT_1D(d[ 0]*dq[ 0],d[ 8]*dq[ 8],d[16]*dq[16],d[24]*dq[24],int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; p2 = d[16]*dq[16] ; p3 = d[48]*dq[48]; p1 = (p2+p3) * (int) (((0.5411961f) * 4096 + 0.5)); t2 = p1 + p3*(int) (((-1.847759065f) * 4096 + 0.5)) ; t3 = p1 + p2*(int) (((0.765366865f) * 4096 + 0.5)); p2 = d[ 0]*dq[ 0]; p3 = d[32]*dq[32]; t0 = ((p2+p3) << 12); t1 = ((p2-p3) << 12); x0 = t0+t3; x3 = t0-t3; x1 = t1+t2; x2 = t1-t2; t0 = d[56]*dq[56]; t1 = d[40]*dq[40]; t2 = d[24] *dq[24]; t3 = d[ 8]*dq[ 8]; p3 = t0+t2; p4 = t1+t3; p1 = t0+t3 ; p2 = t1+t2; p5 = (p3+p4)*(int) (((1.175875602f) * 4096 + 0.5 )); t0 = t0*(int) (((0.298631336f) * 4096 + 0.5)); t1 = t1*(int ) (((2.053119869f) * 4096 + 0.5)); t2 = t2*(int) (((3.072711026f ) * 4096 + 0.5)); t3 = t3*(int) (((1.501321110f) * 4096 + 0.5 )); p1 = p5 + p1*(int) (((-0.899976223f) * 4096 + 0.5)); p2 = p5 + p2*(int) (((-2.562915447f) * 4096 + 0.5)); p3 = p3*(int ) (((-1.961570560f) * 4096 + 0.5)); p4 = p4*(int) (((-0.390180644f ) * 4096 + 0.5)); t3 += p1+p4; t2 += p2+p3; t1 += p2+p4; t0 += p1+p3; | |||
| 1272 | d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56])int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; p2 = d[16]*dq[16] ; p3 = d[48]*dq[48]; p1 = (p2+p3) * (int) (((0.5411961f) * 4096 + 0.5)); t2 = p1 + p3*(int) (((-1.847759065f) * 4096 + 0.5)) ; t3 = p1 + p2*(int) (((0.765366865f) * 4096 + 0.5)); p2 = d[ 0]*dq[ 0]; p3 = d[32]*dq[32]; t0 = ((p2+p3) << 12); t1 = ((p2-p3) << 12); x0 = t0+t3; x3 = t0-t3; x1 = t1+t2; x2 = t1-t2; t0 = d[56]*dq[56]; t1 = d[40]*dq[40]; t2 = d[24] *dq[24]; t3 = d[ 8]*dq[ 8]; p3 = t0+t2; p4 = t1+t3; p1 = t0+t3 ; p2 = t1+t2; p5 = (p3+p4)*(int) (((1.175875602f) * 4096 + 0.5 )); t0 = t0*(int) (((0.298631336f) * 4096 + 0.5)); t1 = t1*(int ) (((2.053119869f) * 4096 + 0.5)); t2 = t2*(int) (((3.072711026f ) * 4096 + 0.5)); t3 = t3*(int) (((1.501321110f) * 4096 + 0.5 )); p1 = p5 + p1*(int) (((-0.899976223f) * 4096 + 0.5)); p2 = p5 + p2*(int) (((-2.562915447f) * 4096 + 0.5)); p3 = p3*(int ) (((-1.961570560f) * 4096 + 0.5)); p4 = p4*(int) (((-0.390180644f ) * 4096 + 0.5)); t3 += p1+p4; t2 += p2+p3; t1 += p2+p4; t0 += p1+p3; | |||
| 1273 | // constants scaled things up by 1<<12; let's bring them back | |||
| 1274 | // down, but keep 2 extra bits of precision | |||
| 1275 | x0 += 512; x1 += 512; x2 += 512; x3 += 512; | |||
| 1276 | v[ 0] = (x0+t3) >> 10; | |||
| 1277 | v[56] = (x0-t3) >> 10; | |||
| 1278 | v[ 8] = (x1+t2) >> 10; | |||
| 1279 | v[48] = (x1-t2) >> 10; | |||
| 1280 | v[16] = (x2+t1) >> 10; | |||
| 1281 | v[40] = (x2-t1) >> 10; | |||
| 1282 | v[24] = (x3+t0) >> 10; | |||
| 1283 | v[32] = (x3-t0) >> 10; | |||
| 1284 | } | |||
| 1285 | } | |||
| 1286 | ||||
| 1287 | for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { | |||
| 1288 | // no fast case since the first 1D IDCT spread components out | |||
| 1289 | IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; p2 = v[2]; p3 = v [6]; p1 = (p2+p3) * (int) (((0.5411961f) * 4096 + 0.5)); t2 = p1 + p3*(int) (((-1.847759065f) * 4096 + 0.5)); t3 = p1 + p2 *(int) (((0.765366865f) * 4096 + 0.5)); p2 = v[0]; p3 = v[4]; t0 = ((p2+p3) << 12); t1 = ((p2-p3) << 12); x0 = t0+t3; x3 = t0-t3; x1 = t1+t2; x2 = t1-t2; t0 = v[7]; t1 = v [5]; t2 = v[3]; t3 = v[1]; p3 = t0+t2; p4 = t1+t3; p1 = t0+t3 ; p2 = t1+t2; p5 = (p3+p4)*(int) (((1.175875602f) * 4096 + 0.5 )); t0 = t0*(int) (((0.298631336f) * 4096 + 0.5)); t1 = t1*(int ) (((2.053119869f) * 4096 + 0.5)); t2 = t2*(int) (((3.072711026f ) * 4096 + 0.5)); t3 = t3*(int) (((1.501321110f) * 4096 + 0.5 )); p1 = p5 + p1*(int) (((-0.899976223f) * 4096 + 0.5)); p2 = p5 + p2*(int) (((-2.562915447f) * 4096 + 0.5)); p3 = p3*(int ) (((-1.961570560f) * 4096 + 0.5)); p4 = p4*(int) (((-0.390180644f ) * 4096 + 0.5)); t3 += p1+p4; t2 += p2+p3; t1 += p2+p4; t0 += p1+p3; | |||
| 1290 | // constants scaled things up by 1<<12, plus we had 1<<2 from first | |||
| 1291 | // loop, plus horizontal and vertical each scale by sqrt(8) so together | |||
| 1292 | // we've got an extra 1<<3, so 1<<17 total we need to remove. | |||
| 1293 | // so we want to round that, which means adding 0.5 * 1<<17, | |||
| 1294 | // aka 65536. Also, we'll end up with -128 to 127 that we want | |||
| 1295 | // to encode as 0..255 by adding 128, so we'll add that before the shift | |||
| 1296 | x0 += 65536 + (128<<17); | |||
| 1297 | x1 += 65536 + (128<<17); | |||
| 1298 | x2 += 65536 + (128<<17); | |||
| 1299 | x3 += 65536 + (128<<17); | |||
| 1300 | // tried computing the shifts into temps, or'ing the temps to see | |||
| 1301 | // if any were out of range, but that was slower | |||
| 1302 | o[0] = clamp((x0+t3) >> 17); | |||
| 1303 | o[7] = clamp((x0-t3) >> 17); | |||
| 1304 | o[1] = clamp((x1+t2) >> 17); | |||
| 1305 | o[6] = clamp((x1-t2) >> 17); | |||
| 1306 | o[2] = clamp((x2+t1) >> 17); | |||
| 1307 | o[5] = clamp((x2-t1) >> 17); | |||
| 1308 | o[3] = clamp((x3+t0) >> 17); | |||
| 1309 | o[4] = clamp((x3-t0) >> 17); | |||
| 1310 | } | |||
| 1311 | } | |||
| 1312 | ||||
| 1313 | #ifdef STBI_SIMD | |||
| 1314 | static stbi_idct_8x8 stbi_idct_installed = idct_block; | |||
| 1315 | ||||
| 1316 | void stbi_install_idct(stbi_idct_8x8 func) | |||
| 1317 | { | |||
| 1318 | stbi_idct_installed = func; | |||
| 1319 | } | |||
| 1320 | #endif | |||
| 1321 | ||||
| 1322 | #define MARKER_none0xff 0xff | |||
| 1323 | // if there's a pending marker from the entropy stream, return that | |||
| 1324 | // otherwise, fetch from the stream and get a marker. if there's no | |||
| 1325 | // marker, return 0xff, which is never a valid marker value | |||
| 1326 | static uint8 get_marker(jpeg *j) | |||
| 1327 | { | |||
| 1328 | uint8 x; | |||
| 1329 | if (j->marker != MARKER_none0xff) { x = j->marker; j->marker = MARKER_none0xff; return x; } | |||
| 1330 | x = get8u(j->s); | |||
| 1331 | if (x != 0xff) return MARKER_none0xff; | |||
| 1332 | while (x == 0xff) | |||
| 1333 | x = get8u(j->s); | |||
| 1334 | return x; | |||
| 1335 | } | |||
| 1336 | ||||
| 1337 | // in each scan, we'll have scan_n components, and the order | |||
| 1338 | // of the components is specified by order[] | |||
| 1339 | #define RESTART(x)((x) >= 0xd0 && (x) <= 0xd7) ((x) >= 0xd0 && (x) <= 0xd7) | |||
| 1340 | ||||
| 1341 | // after a restart interval, reset the entropy decoder and | |||
| 1342 | // the dc prediction | |||
| 1343 | static void reset(jpeg *j) | |||
| 1344 | { | |||
| 1345 | j->code_bits = 0; | |||
| 1346 | j->code_buffer = 0; | |||
| 1347 | j->nomore = 0; | |||
| 1348 | j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; | |||
| 1349 | j->marker = MARKER_none0xff; | |||
| 1350 | j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; | |||
| 1351 | // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, | |||
| 1352 | // since we don't even allow 1<<30 pixels | |||
| 1353 | } | |||
| 1354 | ||||
| 1355 | static int parse_entropy_coded_data(jpeg *z) | |||
| 1356 | { | |||
| 1357 | reset(z); | |||
| 1358 | if (z->scan_n == 1) { | |||
| 1359 | int i,j; | |||
| 1360 | #ifdef STBI_SIMD | |||
| 1361 | __declspec(align(16))__attribute__((align(16))) | |||
| 1362 | #endif | |||
| 1363 | short data[64]; | |||
| 1364 | int n = z->order[0]; | |||
| 1365 | // non-interleaved data, we just need to process one block at a time, | |||
| 1366 | // in trivial scanline order | |||
| 1367 | // number of blocks to do just depends on how many actual "pixels" this | |||
| 1368 | // component has, independent of interleaved MCU blocking and such | |||
| 1369 | int w = (z->img_comp[n].x+7) >> 3; | |||
| 1370 | int h = (z->img_comp[n].y+7) >> 3; | |||
| 1371 | for (j=0; j < h; ++j) { | |||
| 1372 | for (i=0; i < w; ++i) { | |||
| 1373 | if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; | |||
| 1374 | #ifdef STBI_SIMD | |||
| 1375 | stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); | |||
| 1376 | #else | |||
| 1377 | idct_block(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); | |||
| 1378 | #endif | |||
| 1379 | // every data block is an MCU, so countdown the restart interval | |||
| 1380 | if (--z->todo <= 0) { | |||
| 1381 | if (z->code_bits < 24) grow_buffer_unsafe(z); | |||
| 1382 | // if it's NOT a restart, then just bail, so we get corrupt data | |||
| 1383 | // rather than no data | |||
| 1384 | if (!RESTART(z->marker)((z->marker) >= 0xd0 && (z->marker) <= 0xd7 )) return 1; | |||
| 1385 | reset(z); | |||
| 1386 | } | |||
| 1387 | } | |||
| 1388 | } | |||
| 1389 | } else { // interleaved! | |||
| 1390 | int i,j,k,x,y; | |||
| 1391 | short data[64]; | |||
| 1392 | for (j=0; j < z->img_mcu_y; ++j) { | |||
| 1393 | for (i=0; i < z->img_mcu_x; ++i) { | |||
| 1394 | // scan an interleaved mcu... process scan_n components in order | |||
| 1395 | for (k=0; k < z->scan_n; ++k) { | |||
| 1396 | int n = z->order[k]; | |||
| 1397 | // scan out an mcu's worth of this component; that's just determined | |||
| 1398 | // by the basic H and V specified for the component | |||
| 1399 | for (y=0; y < z->img_comp[n].v; ++y) { | |||
| 1400 | for (x=0; x < z->img_comp[n].h; ++x) { | |||
| 1401 | int x2 = (i*z->img_comp[n].h + x)*8; | |||
| 1402 | int y2 = (j*z->img_comp[n].v + y)*8; | |||
| 1403 | if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; | |||
| 1404 | #ifdef STBI_SIMD | |||
| 1405 | stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); | |||
| 1406 | #else | |||
| 1407 | idct_block(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); | |||
| 1408 | #endif | |||
| 1409 | } | |||
| 1410 | } | |||
| 1411 | } | |||
| 1412 | // after all interleaved components, that's an interleaved MCU, | |||
| 1413 | // so now count down the restart interval | |||
| 1414 | if (--z->todo <= 0) { | |||
| 1415 | if (z->code_bits < 24) grow_buffer_unsafe(z); | |||
| 1416 | // if it's NOT a restart, then just bail, so we get corrupt data | |||
| 1417 | // rather than no data | |||
| 1418 | if (!RESTART(z->marker)((z->marker) >= 0xd0 && (z->marker) <= 0xd7 )) return 1; | |||
| 1419 | reset(z); | |||
| 1420 | } | |||
| 1421 | } | |||
| 1422 | } | |||
| 1423 | } | |||
| 1424 | return 1; | |||
| 1425 | } | |||
| 1426 | ||||
| 1427 | static int process_marker(jpeg *z, int m) | |||
| 1428 | { | |||
| 1429 | int L; | |||
| 1430 | switch (m) { | |||
| 1431 | case MARKER_none0xff: // no marker found | |||
| 1432 | return e("expected marker","Corrupt JPEG")e("expected marker"); | |||
| 1433 | ||||
| 1434 | case 0xC2: // SOF - progressive | |||
| 1435 | return e("progressive jpeg","JPEG format not supported (progressive)")e("progressive jpeg"); | |||
| 1436 | ||||
| 1437 | case 0xDD: // DRI - specify restart interval | |||
| 1438 | if (get16(z->s) != 4) return e("bad DRI len","Corrupt JPEG")e("bad DRI len"); | |||
| 1439 | z->restart_interval = get16(z->s); | |||
| 1440 | return 1; | |||
| 1441 | ||||
| 1442 | case 0xDB: // DQT - define quantization table | |||
| 1443 | L = get16(z->s)-2; | |||
| 1444 | while (L > 0) { | |||
| 1445 | int q = get8(z->s); | |||
| 1446 | int p = q >> 4; | |||
| 1447 | int t = q & 15,i; | |||
| 1448 | if (p != 0) return e("bad DQT type","Corrupt JPEG")e("bad DQT type"); | |||
| 1449 | if (t > 3) return e("bad DQT table","Corrupt JPEG")e("bad DQT table"); | |||
| 1450 | for (i=0; i < 64; ++i) | |||
| 1451 | z->dequant[t][dezigzag[i]] = get8u(z->s); | |||
| 1452 | #ifdef STBI_SIMD | |||
| 1453 | for (i=0; i < 64; ++i) | |||
| 1454 | z->dequant2[t][i] = z->dequant[t][i]; | |||
| 1455 | #endif | |||
| 1456 | L -= 65; | |||
| 1457 | } | |||
| 1458 | return L==0; | |||
| 1459 | ||||
| 1460 | case 0xC4: // DHT - define huffman table | |||
| 1461 | L = get16(z->s)-2; | |||
| 1462 | while (L > 0) { | |||
| 1463 | uint8 *v; | |||
| 1464 | int sizes[16],i,m=0; | |||
| 1465 | int q = get8(z->s); | |||
| 1466 | int tc = q >> 4; | |||
| 1467 | int th = q & 15; | |||
| 1468 | if (tc > 1 || th > 3) return e("bad DHT header","Corrupt JPEG")e("bad DHT header"); | |||
| 1469 | for (i=0; i < 16; ++i) { | |||
| 1470 | sizes[i] = get8(z->s); | |||
| 1471 | m += sizes[i]; | |||
| 1472 | } | |||
| 1473 | L -= 17; | |||
| 1474 | if (tc == 0) { | |||
| 1475 | if (!build_huffman(z->huff_dc+th, sizes)) return 0; | |||
| 1476 | v = z->huff_dc[th].values; | |||
| 1477 | } else { | |||
| 1478 | if (!build_huffman(z->huff_ac+th, sizes)) return 0; | |||
| 1479 | v = z->huff_ac[th].values; | |||
| 1480 | } | |||
| 1481 | for (i=0; i < m; ++i) | |||
| 1482 | v[i] = get8u(z->s); | |||
| 1483 | L -= m; | |||
| 1484 | } | |||
| 1485 | return L==0; | |||
| 1486 | } | |||
| 1487 | // check for comment block or APP blocks | |||
| 1488 | if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { | |||
| 1489 | skip(z->s, get16(z->s)-2); | |||
| 1490 | return 1; | |||
| 1491 | } | |||
| 1492 | return 0; | |||
| 1493 | } | |||
| 1494 | ||||
| 1495 | // after we see SOS | |||
| 1496 | static int process_scan_header(jpeg *z) | |||
| 1497 | { | |||
| 1498 | int i; | |||
| 1499 | int Ls = get16(z->s); | |||
| 1500 | z->scan_n = get8(z->s); | |||
| 1501 | if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return e("bad SOS component count","Corrupt JPEG")e("bad SOS component count"); | |||
| 1502 | if (Ls != 6+2*z->scan_n) return e("bad SOS len","Corrupt JPEG")e("bad SOS len"); | |||
| 1503 | for (i=0; i < z->scan_n; ++i) { | |||
| 1504 | int id = get8(z->s), which; | |||
| 1505 | int q = get8(z->s); | |||
| 1506 | for (which = 0; which < z->s->img_n; ++which) | |||
| 1507 | if (z->img_comp[which].id == id) | |||
| 1508 | break; | |||
| 1509 | if (which == z->s->img_n) return 0; | |||
| 1510 | z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return e("bad DC huff","Corrupt JPEG")e("bad DC huff"); | |||
| 1511 | z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return e("bad AC huff","Corrupt JPEG")e("bad AC huff"); | |||
| 1512 | z->order[i] = which; | |||
| 1513 | } | |||
| 1514 | if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG")e("bad SOS"); | |||
| 1515 | get8(z->s); // should be 63, but might be 0 | |||
| 1516 | if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG")e("bad SOS"); | |||
| 1517 | ||||
| 1518 | return 1; | |||
| 1519 | } | |||
| 1520 | ||||
| 1521 | static int process_frame_header(jpeg *z, int scan) | |||
| 1522 | { | |||
| 1523 | stbi *s = z->s; | |||
| 1524 | int Lf,p,i,q, h_max=1,v_max=1,c; | |||
| 1525 | Lf = get16(s); if (Lf < 11) return e("bad SOF len","Corrupt JPEG")e("bad SOF len"); // JPEG | |||
| 1526 | p = get8(s); if (p != 8) return e("only 8-bit","JPEG format not supported: 8-bit only")e("only 8-bit"); // JPEG baseline | |||
| 1527 | s->img_y = get16(s); if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed height")e("no header height"); // Legal, but we don't handle it--but neither does IJG | |||
| 1528 | s->img_x = get16(s); if (s->img_x == 0) return e("0 width","Corrupt JPEG")e("0 width"); // JPEG requires | |||
| 1529 | c = get8(s); | |||
| 1530 | if (c != 3 && c != 1) return e("bad component count","Corrupt JPEG")e("bad component count"); // JFIF requires | |||
| 1531 | s->img_n = c; | |||
| 1532 | for (i=0; i < c; ++i) { | |||
| 1533 | z->img_comp[i].data = NULL((void*)0); | |||
| 1534 | z->img_comp[i].linebuf = NULL((void*)0); | |||
| 1535 | } | |||
| 1536 | ||||
| 1537 | if (Lf != 8+3*s->img_n) return e("bad SOF len","Corrupt JPEG")e("bad SOF len"); | |||
| 1538 | ||||
| 1539 | for (i=0; i < s->img_n; ++i) { | |||
| 1540 | z->img_comp[i].id = get8(s); | |||
| 1541 | if (z->img_comp[i].id != i+1) // JFIF requires | |||
| 1542 | if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! | |||
| 1543 | return e("bad component ID","Corrupt JPEG")e("bad component ID"); | |||
| 1544 | q = get8(s); | |||
| 1545 | z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return e("bad H","Corrupt JPEG")e("bad H"); | |||
| 1546 | z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return e("bad V","Corrupt JPEG")e("bad V"); | |||
| 1547 | z->img_comp[i].tq = get8(s); if (z->img_comp[i].tq > 3) return e("bad TQ","Corrupt JPEG")e("bad TQ"); | |||
| 1548 | } | |||
| 1549 | ||||
| 1550 | if (scan != SCAN_load) return 1; | |||
| 1551 | ||||
| 1552 | if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode")e("too large"); | |||
| 1553 | ||||
| 1554 | for (i=0; i < s->img_n; ++i) { | |||
| 1555 | if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; | |||
| 1556 | if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; | |||
| 1557 | } | |||
| 1558 | ||||
| 1559 | // compute interleaved mcu info | |||
| 1560 | z->img_h_max = h_max; | |||
| 1561 | z->img_v_max = v_max; | |||
| 1562 | z->img_mcu_w = h_max * 8; | |||
| 1563 | z->img_mcu_h = v_max * 8; | |||
| 1564 | z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; | |||
| 1565 | z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; | |||
| 1566 | ||||
| 1567 | for (i=0; i < s->img_n; ++i) { | |||
| 1568 | // number of effective pixels (e.g. for non-interleaved MCU) | |||
| 1569 | z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; | |||
| 1570 | z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; | |||
| 1571 | // to simplify generation, we'll allocate enough memory to decode | |||
| 1572 | // the bogus oversized data from using interleaved MCUs and their | |||
| 1573 | // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't | |||
| 1574 | // discard the extra data until colorspace conversion | |||
| 1575 | z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; | |||
| 1576 | z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; | |||
| 1577 | z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); | |||
| 1578 | if (z->img_comp[i].raw_data == NULL((void*)0)) { | |||
| 1579 | for(--i; i >= 0; --i) { | |||
| 1580 | free(z->img_comp[i].raw_data); | |||
| 1581 | z->img_comp[i].data = NULL((void*)0); | |||
| 1582 | } | |||
| 1583 | return e("outofmem", "Out of memory")e("outofmem"); | |||
| 1584 | } | |||
| 1585 | // align blocks for installable-idct using mmx/sse | |||
| 1586 | z->img_comp[i].data = (uint8*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); | |||
| 1587 | z->img_comp[i].linebuf = NULL((void*)0); | |||
| 1588 | } | |||
| 1589 | ||||
| 1590 | return 1; | |||
| 1591 | } | |||
| 1592 | ||||
| 1593 | // use comparisons since in some cases we handle more than one case (e.g. SOF) | |||
| 1594 | #define DNL(x)((x) == 0xdc) ((x) == 0xdc) | |||
| 1595 | #define SOI(x)((x) == 0xd8) ((x) == 0xd8) | |||
| 1596 | #define EOI(x)((x) == 0xd9) ((x) == 0xd9) | |||
| 1597 | #define SOF(x)((x) == 0xc0 || (x) == 0xc1) ((x) == 0xc0 || (x) == 0xc1) | |||
| 1598 | #define SOS(x)((x) == 0xda) ((x) == 0xda) | |||
| 1599 | ||||
| 1600 | static int decode_jpeg_header(jpeg *z, int scan) | |||
| 1601 | { | |||
| 1602 | int m; | |||
| 1603 | z->marker = MARKER_none0xff; // initialize cached marker to empty | |||
| 1604 | m = get_marker(z); | |||
| 1605 | if (!SOI(m)((m) == 0xd8)) return e("no SOI","Corrupt JPEG")e("no SOI"); | |||
| 1606 | if (scan == SCAN_type) return 1; | |||
| 1607 | m = get_marker(z); | |||
| 1608 | while (!SOF(m)((m) == 0xc0 || (m) == 0xc1)) { | |||
| 1609 | if (!process_marker(z,m)) return 0; | |||
| 1610 | m = get_marker(z); | |||
| 1611 | while (m == MARKER_none0xff) { | |||
| 1612 | // some files have extra padding after their blocks, so ok, we'll scan | |||
| 1613 | if (at_eof(z->s)) return e("no SOF", "Corrupt JPEG")e("no SOF"); | |||
| 1614 | m = get_marker(z); | |||
| 1615 | } | |||
| 1616 | } | |||
| 1617 | if (!process_frame_header(z, scan)) return 0; | |||
| 1618 | return 1; | |||
| 1619 | } | |||
| 1620 | ||||
| 1621 | static int decode_jpeg_image(jpeg *j) | |||
| 1622 | { | |||
| 1623 | int m; | |||
| 1624 | j->restart_interval = 0; | |||
| 1625 | if (!decode_jpeg_header(j, SCAN_load)) return 0; | |||
| 1626 | m = get_marker(j); | |||
| 1627 | while (!EOI(m)((m) == 0xd9)) { | |||
| 1628 | if (SOS(m)((m) == 0xda)) { | |||
| 1629 | if (!process_scan_header(j)) return 0; | |||
| 1630 | if (!parse_entropy_coded_data(j)) return 0; | |||
| 1631 | if (j->marker == MARKER_none0xff ) { | |||
| 1632 | // handle 0s at the end of image data from IP Kamera 9060 | |||
| 1633 | while (!at_eof(j->s)) { | |||
| 1634 | int x = get8(j->s); | |||
| 1635 | if (x == 255) { | |||
| 1636 | j->marker = get8u(j->s); | |||
| 1637 | break; | |||
| 1638 | } else if (x != 0) { | |||
| 1639 | return 0; | |||
| 1640 | } | |||
| 1641 | } | |||
| 1642 | // if we reach eof without hitting a marker, get_marker() below will fail and we'll eventually return 0 | |||
| 1643 | } | |||
| 1644 | } else { | |||
| 1645 | if (!process_marker(j, m)) return 0; | |||
| 1646 | } | |||
| 1647 | m = get_marker(j); | |||
| 1648 | } | |||
| 1649 | return 1; | |||
| 1650 | } | |||
| 1651 | ||||
| 1652 | // static jfif-centered resampling (across block boundaries) | |||
| 1653 | ||||
| 1654 | typedef uint8 *(*resample_row_func)(uint8 *out, uint8 *in0, uint8 *in1, | |||
| 1655 | int w, int hs); | |||
| 1656 | ||||
| 1657 | #define div4(x)((uint8) ((x) >> 2)) ((uint8) ((x) >> 2)) | |||
| 1658 | ||||
| 1659 | static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) | |||
| 1660 | { | |||
| 1661 | STBI_NOTUSED(out)(void)sizeof(out); | |||
| 1662 | STBI_NOTUSED(in_far)(void)sizeof(in_far); | |||
| 1663 | STBI_NOTUSED(w)(void)sizeof(w); | |||
| 1664 | STBI_NOTUSED(hs)(void)sizeof(hs); | |||
| 1665 | return in_near; | |||
| 1666 | } | |||
| 1667 | ||||
| 1668 | static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) | |||
| 1669 | { | |||
| 1670 | // need to generate two samples vertically for every one in input | |||
| 1671 | int i; | |||
| 1672 | STBI_NOTUSED(hs)(void)sizeof(hs); | |||
| 1673 | for (i=0; i < w; ++i) | |||
| 1674 | out[i] = div4(3*in_near[i] + in_far[i] + 2)((uint8) ((3*in_near[i] + in_far[i] + 2) >> 2)); | |||
| 1675 | return out; | |||
| 1676 | } | |||
| 1677 | ||||
| 1678 | static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) | |||
| 1679 | { | |||
| 1680 | // need to generate two samples horizontally for every one in input | |||
| 1681 | int i; | |||
| 1682 | uint8 *input = in_near; | |||
| 1683 | ||||
| 1684 | if (w == 1) { | |||
| 1685 | // if only one sample, can't do any interpolation | |||
| 1686 | out[0] = out[1] = input[0]; | |||
| 1687 | return out; | |||
| 1688 | } | |||
| 1689 | ||||
| 1690 | out[0] = input[0]; | |||
| 1691 | out[1] = div4(input[0]*3 + input[1] + 2)((uint8) ((input[0]*3 + input[1] + 2) >> 2)); | |||
| 1692 | for (i=1; i < w-1; ++i) { | |||
| 1693 | int n = 3*input[i]+2; | |||
| 1694 | out[i*2+0] = div4(n+input[i-1])((uint8) ((n+input[i-1]) >> 2)); | |||
| 1695 | out[i*2+1] = div4(n+input[i+1])((uint8) ((n+input[i+1]) >> 2)); | |||
| 1696 | } | |||
| 1697 | out[i*2+0] = div4(input[w-2]*3 + input[w-1] + 2)((uint8) ((input[w-2]*3 + input[w-1] + 2) >> 2)); | |||
| 1698 | out[i*2+1] = input[w-1]; | |||
| 1699 | ||||
| 1700 | STBI_NOTUSED(in_far)(void)sizeof(in_far); | |||
| 1701 | STBI_NOTUSED(hs)(void)sizeof(hs); | |||
| 1702 | ||||
| 1703 | return out; | |||
| 1704 | } | |||
| 1705 | ||||
| 1706 | #define div16(x)((uint8) ((x) >> 4)) ((uint8) ((x) >> 4)) | |||
| 1707 | ||||
| 1708 | static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) | |||
| 1709 | { | |||
| 1710 | // need to generate 2x2 samples for every one in input | |||
| 1711 | int i,t0,t1; | |||
| 1712 | if (w == 1) { | |||
| 1713 | out[0] = out[1] = div4(3*in_near[0] + in_far[0] + 2)((uint8) ((3*in_near[0] + in_far[0] + 2) >> 2)); | |||
| 1714 | return out; | |||
| 1715 | } | |||
| 1716 | ||||
| 1717 | t1 = 3*in_near[0] + in_far[0]; | |||
| 1718 | out[0] = div4(t1+2)((uint8) ((t1+2) >> 2)); | |||
| 1719 | for (i=1; i < w; ++i) { | |||
| 1720 | t0 = t1; | |||
| 1721 | t1 = 3*in_near[i]+in_far[i]; | |||
| 1722 | out[i*2-1] = div16(3*t0 + t1 + 8)((uint8) ((3*t0 + t1 + 8) >> 4)); | |||
| 1723 | out[i*2 ] = div16(3*t1 + t0 + 8)((uint8) ((3*t1 + t0 + 8) >> 4)); | |||
| 1724 | } | |||
| 1725 | out[w*2-1] = div4(t1+2)((uint8) ((t1+2) >> 2)); | |||
| 1726 | ||||
| 1727 | STBI_NOTUSED(hs)(void)sizeof(hs); | |||
| 1728 | ||||
| 1729 | return out; | |||
| 1730 | } | |||
| 1731 | ||||
| 1732 | static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) | |||
| 1733 | { | |||
| 1734 | // resample with nearest-neighbor | |||
| 1735 | int i,j; | |||
| 1736 | for (i=0; i < w; ++i) | |||
| 1737 | for (j=0; j < hs; ++j) | |||
| 1738 | out[i*hs+j] = in_near[i]; | |||
| 1739 | return out; | |||
| 1740 | } | |||
| 1741 | ||||
| 1742 | #define float2fixed(x)((int) ((x) * 65536 + 0.5)) ((int) ((x) * 65536 + 0.5)) | |||
| 1743 | ||||
| 1744 | // 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro) | |||
| 1745 | // VC6 without processor=Pro is generating multiple LEAs per multiply! | |||
| 1746 | static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step) | |||
| 1747 | { | |||
| 1748 | int i; | |||
| 1749 | for (i=0; i < count; ++i) { | |||
| 1750 | int y_fixed = (y[i] << 16) + 32768; // rounding | |||
| 1751 | int r,g,b; | |||
| 1752 | int cr = pcr[i] - 128; | |||
| 1753 | int cb = pcb[i] - 128; | |||
| 1754 | r = y_fixed + cr*float2fixed(1.40200f)((int) ((1.40200f) * 65536 + 0.5)); | |||
| 1755 | g = y_fixed - cr*float2fixed(0.71414f)((int) ((0.71414f) * 65536 + 0.5)) - cb*float2fixed(0.34414f)((int) ((0.34414f) * 65536 + 0.5)); | |||
| 1756 | b = y_fixed + cb*float2fixed(1.77200f)((int) ((1.77200f) * 65536 + 0.5)); | |||
| 1757 | r >>= 16; | |||
| 1758 | g >>= 16; | |||
| 1759 | b >>= 16; | |||
| 1760 | if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } | |||
| 1761 | if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } | |||
| 1762 | if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } | |||
| 1763 | out[0] = (uint8)r; | |||
| 1764 | out[1] = (uint8)g; | |||
| 1765 | out[2] = (uint8)b; | |||
| 1766 | out[3] = 255; | |||
| 1767 | out += step; | |||
| 1768 | } | |||
| 1769 | } | |||
| 1770 | ||||
| 1771 | #ifdef STBI_SIMD | |||
| 1772 | static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row; | |||
| 1773 | ||||
| 1774 | void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func) | |||
| 1775 | { | |||
| 1776 | stbi_YCbCr_installed = func; | |||
| 1777 | } | |||
| 1778 | #endif | |||
| 1779 | ||||
| 1780 | ||||
| 1781 | // clean up the temporary component buffers | |||
| 1782 | static void cleanup_jpeg(jpeg *j) | |||
| 1783 | { | |||
| 1784 | int i; | |||
| 1785 | for (i=0; i < j->s->img_n; ++i) { | |||
| 1786 | if (j->img_comp[i].data) { | |||
| 1787 | free(j->img_comp[i].raw_data); | |||
| 1788 | j->img_comp[i].data = NULL((void*)0); | |||
| 1789 | } | |||
| 1790 | if (j->img_comp[i].linebuf) { | |||
| 1791 | free(j->img_comp[i].linebuf); | |||
| 1792 | j->img_comp[i].linebuf = NULL((void*)0); | |||
| 1793 | } | |||
| 1794 | } | |||
| 1795 | } | |||
| 1796 | ||||
| 1797 | typedef struct | |||
| 1798 | { | |||
| 1799 | resample_row_func resample; | |||
| 1800 | uint8 *line0,*line1; | |||
| 1801 | int hs,vs; // expansion factor in each axis | |||
| 1802 | int w_lores; // horizontal pixels pre-expansion | |||
| 1803 | int ystep; // how far through vertical expansion we are | |||
| 1804 | int ypos; // which pre-expansion row we're on | |||
| 1805 | } stbi_resample; | |||
| 1806 | ||||
| 1807 | static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) | |||
| 1808 | { | |||
| 1809 | int n, decode_n; | |||
| 1810 | // validate req_comp | |||
| 1811 | if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error")((unsigned char *) (e("bad req_comp")?((void*)0):((void*)0))); | |||
| 1812 | z->s->img_n = 0; | |||
| 1813 | ||||
| 1814 | // load a jpeg image from whichever source | |||
| 1815 | if (!decode_jpeg_image(z)) { cleanup_jpeg(z); return NULL((void*)0); } | |||
| 1816 | ||||
| 1817 | // determine actual number of components to generate | |||
| 1818 | n = req_comp ? req_comp : z->s->img_n; | |||
| 1819 | ||||
| 1820 | if (z->s->img_n == 3 && n < 3) | |||
| 1821 | decode_n = 1; | |||
| 1822 | else | |||
| 1823 | decode_n = z->s->img_n; | |||
| 1824 | ||||
| 1825 | // resample and color-convert | |||
| 1826 | { | |||
| 1827 | int k; | |||
| 1828 | uint i,j; | |||
| 1829 | uint8 *output; | |||
| 1830 | uint8 *coutput[4]; | |||
| 1831 | ||||
| 1832 | stbi_resample res_comp[4]; | |||
| 1833 | ||||
| 1834 | for (k=0; k < decode_n; ++k) { | |||
| 1835 | stbi_resample *r = &res_comp[k]; | |||
| 1836 | ||||
| 1837 | // allocate line buffer big enough for upsampling off the edges | |||
| 1838 | // with upsample factor of 4 | |||
| 1839 | z->img_comp[k].linebuf = (uint8 *) malloc(z->s->img_x + 3); | |||
| 1840 | if (!z->img_comp[k].linebuf) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); } | |||
| 1841 | ||||
| 1842 | r->hs = z->img_h_max / z->img_comp[k].h; | |||
| 1843 | r->vs = z->img_v_max / z->img_comp[k].v; | |||
| 1844 | r->ystep = r->vs >> 1; | |||
| 1845 | r->w_lores = (z->s->img_x + r->hs-1) / r->hs; | |||
| 1846 | r->ypos = 0; | |||
| 1847 | r->line0 = r->line1 = z->img_comp[k].data; | |||
| 1848 | ||||
| 1849 | if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; | |||
| 1850 | else if (r->hs == 1 && r->vs == 2) r->resample = resample_row_v_2; | |||
| 1851 | else if (r->hs == 2 && r->vs == 1) r->resample = resample_row_h_2; | |||
| 1852 | else if (r->hs == 2 && r->vs == 2) r->resample = resample_row_hv_2; | |||
| 1853 | else r->resample = resample_row_generic; | |||
| 1854 | } | |||
| 1855 | ||||
| 1856 | // can't error after this so, this is safe | |||
| 1857 | output = (uint8 *) malloc(n * z->s->img_x * z->s->img_y + 1); | |||
| 1858 | if (!output) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); } | |||
| 1859 | ||||
| 1860 | // now go ahead and resample | |||
| 1861 | for (j=0; j < z->s->img_y; ++j) { | |||
| 1862 | uint8 *out = output + n * z->s->img_x * j; | |||
| 1863 | for (k=0; k < decode_n; ++k) { | |||
| 1864 | stbi_resample *r = &res_comp[k]; | |||
| 1865 | int y_bot = r->ystep >= (r->vs >> 1); | |||
| 1866 | coutput[k] = r->resample(z->img_comp[k].linebuf, | |||
| 1867 | y_bot ? r->line1 : r->line0, | |||
| 1868 | y_bot ? r->line0 : r->line1, | |||
| 1869 | r->w_lores, r->hs); | |||
| 1870 | if (++r->ystep >= r->vs) { | |||
| 1871 | r->ystep = 0; | |||
| 1872 | r->line0 = r->line1; | |||
| 1873 | if (++r->ypos < z->img_comp[k].y) | |||
| 1874 | r->line1 += z->img_comp[k].w2; | |||
| 1875 | } | |||
| 1876 | } | |||
| 1877 | if (n >= 3) { | |||
| 1878 | uint8 *y = coutput[0]; | |||
| 1879 | if (z->s->img_n == 3) { | |||
| 1880 | #ifdef STBI_SIMD | |||
| 1881 | stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n); | |||
| 1882 | #else | |||
| 1883 | YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s->img_x, n); | |||
| 1884 | #endif | |||
| 1885 | } else | |||
| 1886 | for (i=0; i < z->s->img_x; ++i) { | |||
| 1887 | out[0] = out[1] = out[2] = y[i]; | |||
| 1888 | out[3] = 255; // not used if n==3 | |||
| 1889 | out += n; | |||
| 1890 | } | |||
| 1891 | } else { | |||
| 1892 | uint8 *y = coutput[0]; | |||
| 1893 | if (n == 1) | |||
| 1894 | for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; | |||
| 1895 | else | |||
| 1896 | for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; | |||
| 1897 | } | |||
| 1898 | } | |||
| 1899 | cleanup_jpeg(z); | |||
| 1900 | *out_x = z->s->img_x; | |||
| 1901 | *out_y = z->s->img_y; | |||
| 1902 | if (comp) *comp = z->s->img_n; // report original components, not output | |||
| 1903 | return output; | |||
| 1904 | } | |||
| 1905 | } | |||
| 1906 | ||||
| 1907 | static unsigned char *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 1908 | { | |||
| 1909 | jpeg j; | |||
| 1910 | j.s = s; | |||
| 1911 | return load_jpeg_image(&j, x,y,comp,req_comp); | |||
| 1912 | } | |||
| 1913 | ||||
| 1914 | static int stbi_jpeg_test(stbi *s) | |||
| 1915 | { | |||
| 1916 | int r; | |||
| 1917 | jpeg j; | |||
| 1918 | j.s = s; | |||
| 1919 | r = decode_jpeg_header(&j, SCAN_type); | |||
| 1920 | stbi_rewind(s); | |||
| 1921 | return r; | |||
| 1922 | } | |||
| 1923 | ||||
| 1924 | static int stbi_jpeg_info_raw(jpeg *j, int *x, int *y, int *comp) | |||
| 1925 | { | |||
| 1926 | if (!decode_jpeg_header(j, SCAN_header)) { | |||
| 1927 | stbi_rewind( j->s ); | |||
| 1928 | return 0; | |||
| 1929 | } | |||
| 1930 | if (x) *x = j->s->img_x; | |||
| 1931 | if (y) *y = j->s->img_y; | |||
| 1932 | if (comp) *comp = j->s->img_n; | |||
| 1933 | return 1; | |||
| 1934 | } | |||
| 1935 | ||||
| 1936 | static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp) | |||
| 1937 | { | |||
| 1938 | jpeg j; | |||
| 1939 | j.s = s; | |||
| 1940 | return stbi_jpeg_info_raw(&j, x, y, comp); | |||
| 1941 | } | |||
| 1942 | ||||
| 1943 | // public domain zlib decode v0.2 Sean Barrett 2006-11-18 | |||
| 1944 | // simple implementation | |||
| 1945 | // - all input must be provided in an upfront buffer | |||
| 1946 | // - all output is written to a single output buffer (can malloc/realloc) | |||
| 1947 | // performance | |||
| 1948 | // - fast huffman | |||
| 1949 | ||||
| 1950 | // fast-way is faster to check than jpeg huffman, but slow way is slower | |||
| 1951 | #define ZFAST_BITS9 9 // accelerate all cases in default tables | |||
| 1952 | #define ZFAST_MASK((1 << 9) - 1) ((1 << ZFAST_BITS9) - 1) | |||
| 1953 | ||||
| 1954 | // zlib-style huffman encoding | |||
| 1955 | // (jpegs packs from left, zlib from right, so can't share code) | |||
| 1956 | typedef struct | |||
| 1957 | { | |||
| 1958 | uint16 fast[1 << ZFAST_BITS9]; | |||
| 1959 | uint16 firstcode[16]; | |||
| 1960 | int maxcode[17]; | |||
| 1961 | uint16 firstsymbol[16]; | |||
| 1962 | uint8 size[288]; | |||
| 1963 | uint16 value[288]; | |||
| 1964 | } zhuffman; | |||
| 1965 | ||||
| 1966 | stbi_inline static int bitreverse16(int n) | |||
| 1967 | { | |||
| 1968 | n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); | |||
| 1969 | n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); | |||
| 1970 | n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); | |||
| 1971 | n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); | |||
| 1972 | return n; | |||
| 1973 | } | |||
| 1974 | ||||
| 1975 | stbi_inline static int bit_reverse(int v, int bits) | |||
| 1976 | { | |||
| 1977 | assert(bits <= 16)((bits <= 16) ? (void)0 : _assert("bits <= 16", "src/siege/internal/stb/stb_image.c" , 1977)); | |||
| 1978 | // to bit reverse n bits, reverse 16 and shift | |||
| 1979 | // e.g. 11 bits, bit reverse and shift away 5 | |||
| 1980 | return bitreverse16(v) >> (16-bits); | |||
| 1981 | } | |||
| 1982 | ||||
| 1983 | static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num) | |||
| 1984 | { | |||
| 1985 | int i,k=0; | |||
| 1986 | int code, next_code[16], sizes[17]; | |||
| 1987 | ||||
| 1988 | // DEFLATE spec for generating codes | |||
| 1989 | memset(sizes, 0, sizeof(sizes)); | |||
| 1990 | memset(z->fast, 255, sizeof(z->fast)); | |||
| 1991 | for (i=0; i < num; ++i) | |||
| 1992 | ++sizes[sizelist[i]]; | |||
| 1993 | sizes[0] = 0; | |||
| 1994 | for (i=1; i < 16; ++i) | |||
| 1995 | assert(sizes[i] <= (1 << i))((sizes[i] <= (1 << i)) ? (void)0 : _assert("sizes[i] <= (1 << i)" , "src/siege/internal/stb/stb_image.c", 1995)); | |||
| 1996 | code = 0; | |||
| 1997 | for (i=1; i < 16; ++i) { | |||
| 1998 | next_code[i] = code; | |||
| 1999 | z->firstcode[i] = (uint16) code; | |||
| 2000 | z->firstsymbol[i] = (uint16) k; | |||
| 2001 | code = (code + sizes[i]); | |||
| 2002 | if (sizes[i]) | |||
| 2003 | if (code-1 >= (1 << i)) return e("bad codelengths","Corrupt JPEG")e("bad codelengths"); | |||
| 2004 | z->maxcode[i] = code << (16-i); // preshift for inner loop | |||
| 2005 | code <<= 1; | |||
| 2006 | k += sizes[i]; | |||
| 2007 | } | |||
| 2008 | z->maxcode[16] = 0x10000; // sentinel | |||
| 2009 | for (i=0; i < num; ++i) { | |||
| 2010 | int s = sizelist[i]; | |||
| 2011 | if (s) { | |||
| 2012 | int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; | |||
| 2013 | z->size[c] = (uint8)s; | |||
| 2014 | z->value[c] = (uint16)i; | |||
| 2015 | if (s <= ZFAST_BITS9) { | |||
| 2016 | int k = bit_reverse(next_code[s],s); | |||
| 2017 | while (k < (1 << ZFAST_BITS9)) { | |||
| 2018 | z->fast[k] = (uint16) c; | |||
| 2019 | k += (1 << s); | |||
| 2020 | } | |||
| 2021 | } | |||
| 2022 | ++next_code[s]; | |||
| 2023 | } | |||
| 2024 | } | |||
| 2025 | return 1; | |||
| 2026 | } | |||
| 2027 | ||||
| 2028 | // zlib-from-memory implementation for PNG reading | |||
| 2029 | // because PNG allows splitting the zlib stream arbitrarily, | |||
| 2030 | // and it's annoying structurally to have PNG call ZLIB call PNG, | |||
| 2031 | // we require PNG read all the IDATs and combine them into a single | |||
| 2032 | // memory buffer | |||
| 2033 | ||||
| 2034 | typedef struct | |||
| 2035 | { | |||
| 2036 | uint8 *zbuffer, *zbuffer_end; | |||
| 2037 | int num_bits; | |||
| 2038 | uint32 code_buffer; | |||
| 2039 | ||||
| 2040 | char *zout; | |||
| 2041 | char *zout_start; | |||
| 2042 | char *zout_end; | |||
| 2043 | int z_expandable; | |||
| 2044 | ||||
| 2045 | zhuffman z_length, z_distance; | |||
| 2046 | } zbuf; | |||
| 2047 | ||||
| 2048 | stbi_inline static int zget8(zbuf *z) | |||
| 2049 | { | |||
| 2050 | if (z->zbuffer >= z->zbuffer_end) return 0; | |||
| 2051 | return *z->zbuffer++; | |||
| 2052 | } | |||
| 2053 | ||||
| 2054 | static void fill_bits(zbuf *z) | |||
| 2055 | { | |||
| 2056 | do { | |||
| 2057 | assert(z->code_buffer < (1U << z->num_bits))((z->code_buffer < (1U << z->num_bits)) ? (void )0 : _assert("z->code_buffer < (1U << z->num_bits)" , "src/siege/internal/stb/stb_image.c", 2057)); | |||
| 2058 | z->code_buffer |= zget8(z) << z->num_bits; | |||
| 2059 | z->num_bits += 8; | |||
| 2060 | } while (z->num_bits <= 24); | |||
| 2061 | } | |||
| 2062 | ||||
| 2063 | stbi_inline static unsigned int zreceive(zbuf *z, int n) | |||
| 2064 | { | |||
| 2065 | unsigned int k; | |||
| 2066 | if (z->num_bits < n) fill_bits(z); | |||
| 2067 | k = z->code_buffer & ((1 << n) - 1); | |||
| 2068 | z->code_buffer >>= n; | |||
| 2069 | z->num_bits -= n; | |||
| 2070 | return k; | |||
| 2071 | } | |||
| 2072 | ||||
| 2073 | stbi_inline static int zhuffman_decode(zbuf *a, zhuffman *z) | |||
| 2074 | { | |||
| 2075 | int b,s,k; | |||
| 2076 | if (a->num_bits < 16) fill_bits(a); | |||
| 2077 | b = z->fast[a->code_buffer & ZFAST_MASK((1 << 9) - 1)]; | |||
| 2078 | if (b < 0xffff) { | |||
| 2079 | s = z->size[b]; | |||
| 2080 | a->code_buffer >>= s; | |||
| 2081 | a->num_bits -= s; | |||
| 2082 | return z->value[b]; | |||
| 2083 | } | |||
| 2084 | ||||
| 2085 | // not resolved by fast table, so compute it the slow way | |||
| 2086 | // use jpeg approach, which requires MSbits at top | |||
| 2087 | k = bit_reverse(a->code_buffer, 16); | |||
| 2088 | for (s=ZFAST_BITS9+1; ; ++s) | |||
| 2089 | if (k < z->maxcode[s]) | |||
| 2090 | break; | |||
| 2091 | if (s == 16) return -1; // invalid code! | |||
| 2092 | // code size is s, so: | |||
| 2093 | b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; | |||
| 2094 | assert(z->size[b] == s)((z->size[b] == s) ? (void)0 : _assert("z->size[b] == s" , "src/siege/internal/stb/stb_image.c", 2094)); | |||
| 2095 | a->code_buffer >>= s; | |||
| 2096 | a->num_bits -= s; | |||
| 2097 | return z->value[b]; | |||
| 2098 | } | |||
| 2099 | ||||
| 2100 | static int expand(zbuf *z, int n) // need to make room for n bytes | |||
| 2101 | { | |||
| 2102 | char *q; | |||
| 2103 | int cur, limit; | |||
| 2104 | if (!z->z_expandable) return e("output buffer limit","Corrupt PNG")e("output buffer limit"); | |||
| 2105 | cur = (int) (z->zout - z->zout_start); | |||
| 2106 | limit = (int) (z->zout_end - z->zout_start); | |||
| 2107 | while (cur + n > limit) | |||
| 2108 | limit *= 2; | |||
| 2109 | q = (char *) realloc(z->zout_start, limit); | |||
| 2110 | if (q == NULL((void*)0)) return e("outofmem", "Out of memory")e("outofmem"); | |||
| 2111 | z->zout_start = q; | |||
| 2112 | z->zout = q + cur; | |||
| 2113 | z->zout_end = q + limit; | |||
| 2114 | return 1; | |||
| 2115 | } | |||
| 2116 | ||||
| 2117 | static int length_base[31] = { | |||
| 2118 | 3,4,5,6,7,8,9,10,11,13, | |||
| 2119 | 15,17,19,23,27,31,35,43,51,59, | |||
| 2120 | 67,83,99,115,131,163,195,227,258,0,0 }; | |||
| 2121 | ||||
| 2122 | static int length_extra[31]= | |||
| 2123 | { 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 }; | |||
| 2124 | ||||
| 2125 | static int dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, | |||
| 2126 | 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; | |||
| 2127 | ||||
| 2128 | static int dist_extra[32] = | |||
| 2129 | { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; | |||
| 2130 | ||||
| 2131 | static int parse_huffman_block(zbuf *a) | |||
| 2132 | { | |||
| 2133 | for(;;) { | |||
| 2134 | int z = zhuffman_decode(a, &a->z_length); | |||
| 2135 | if (z < 256) { | |||
| 2136 | if (z < 0) return e("bad huffman code","Corrupt PNG")e("bad huffman code"); // error in huffman codes | |||
| 2137 | if (a->zout >= a->zout_end) if (!expand(a, 1)) return 0; | |||
| 2138 | *a->zout++ = (char) z; | |||
| 2139 | } else { | |||
| 2140 | uint8 *p; | |||
| 2141 | int len,dist; | |||
| 2142 | if (z == 256) return 1; | |||
| 2143 | z -= 257; | |||
| 2144 | len = length_base[z]; | |||
| 2145 | if (length_extra[z]) len += zreceive(a, length_extra[z]); | |||
| 2146 | z = zhuffman_decode(a, &a->z_distance); | |||
| 2147 | if (z < 0) return e("bad huffman code","Corrupt PNG")e("bad huffman code"); | |||
| 2148 | dist = dist_base[z]; | |||
| 2149 | if (dist_extra[z]) dist += zreceive(a, dist_extra[z]); | |||
| 2150 | if (a->zout - a->zout_start < dist) return e("bad dist","Corrupt PNG")e("bad dist"); | |||
| 2151 | if (a->zout + len > a->zout_end) if (!expand(a, len)) return 0; | |||
| 2152 | p = (uint8 *) (a->zout - dist); | |||
| 2153 | while (len--) | |||
| 2154 | *a->zout++ = *p++; | |||
| 2155 | } | |||
| 2156 | } | |||
| 2157 | } | |||
| 2158 | ||||
| 2159 | static int compute_huffman_codes(zbuf *a) | |||
| 2160 | { | |||
| 2161 | static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; | |||
| 2162 | zhuffman z_codelength; | |||
| 2163 | uint8 lencodes[286+32+137];//padding for maximum single op | |||
| 2164 | uint8 codelength_sizes[19]; | |||
| 2165 | int i,n; | |||
| 2166 | ||||
| 2167 | int hlit = zreceive(a,5) + 257; | |||
| 2168 | int hdist = zreceive(a,5) + 1; | |||
| 2169 | int hclen = zreceive(a,4) + 4; | |||
| 2170 | ||||
| 2171 | memset(codelength_sizes, 0, sizeof(codelength_sizes)); | |||
| 2172 | for (i=0; i < hclen; ++i) { | |||
| 2173 | int s = zreceive(a,3); | |||
| 2174 | codelength_sizes[length_dezigzag[i]] = (uint8) s; | |||
| 2175 | } | |||
| 2176 | if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; | |||
| 2177 | ||||
| 2178 | n = 0; | |||
| 2179 | while (n < hlit + hdist) { | |||
| 2180 | int c = zhuffman_decode(a, &z_codelength); | |||
| 2181 | assert(c >= 0 && c < 19)((c >= 0 && c < 19) ? (void)0 : _assert("c >= 0 && c < 19" , "src/siege/internal/stb/stb_image.c", 2181)); | |||
| 2182 | if (c < 16) | |||
| 2183 | lencodes[n++] = (uint8) c; | |||
| 2184 | else if (c == 16) { | |||
| 2185 | c = zreceive(a,2)+3; | |||
| 2186 | memset(lencodes+n, lencodes[n-1], c); | |||
| 2187 | n += c; | |||
| 2188 | } else if (c == 17) { | |||
| 2189 | c = zreceive(a,3)+3; | |||
| 2190 | memset(lencodes+n, 0, c); | |||
| 2191 | n += c; | |||
| 2192 | } else { | |||
| 2193 | assert(c == 18)((c == 18) ? (void)0 : _assert("c == 18", "src/siege/internal/stb/stb_image.c" , 2193)); | |||
| 2194 | c = zreceive(a,7)+11; | |||
| 2195 | memset(lencodes+n, 0, c); | |||
| 2196 | n += c; | |||
| 2197 | } | |||
| 2198 | } | |||
| 2199 | if (n != hlit+hdist) return e("bad codelengths","Corrupt PNG")e("bad codelengths"); | |||
| 2200 | if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; | |||
| 2201 | if (!zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; | |||
| 2202 | return 1; | |||
| 2203 | } | |||
| 2204 | ||||
| 2205 | static int parse_uncompressed_block(zbuf *a) | |||
| 2206 | { | |||
| 2207 | uint8 header[4]; | |||
| 2208 | int len,nlen,k; | |||
| 2209 | if (a->num_bits & 7) | |||
| 2210 | zreceive(a, a->num_bits & 7); // discard | |||
| 2211 | // drain the bit-packed data into header | |||
| 2212 | k = 0; | |||
| 2213 | while (a->num_bits > 0) { | |||
| 2214 | header[k++] = (uint8) (a->code_buffer & 255); // wtf this warns? | |||
| 2215 | a->code_buffer >>= 8; | |||
| 2216 | a->num_bits -= 8; | |||
| 2217 | } | |||
| 2218 | assert(a->num_bits == 0)((a->num_bits == 0) ? (void)0 : _assert("a->num_bits == 0" , "src/siege/internal/stb/stb_image.c", 2218)); | |||
| 2219 | // now fill header the normal way | |||
| 2220 | while (k < 4) | |||
| 2221 | header[k++] = (uint8) zget8(a); | |||
| 2222 | len = header[1] * 256 + header[0]; | |||
| 2223 | nlen = header[3] * 256 + header[2]; | |||
| 2224 | if (nlen != (len ^ 0xffff)) return e("zlib corrupt","Corrupt PNG")e("zlib corrupt"); | |||
| 2225 | if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer","Corrupt PNG")e("read past buffer"); | |||
| 2226 | if (a->zout + len > a->zout_end) | |||
| 2227 | if (!expand(a, len)) return 0; | |||
| 2228 | memcpy(a->zout, a->zbuffer, len); | |||
| 2229 | a->zbuffer += len; | |||
| 2230 | a->zout += len; | |||
| 2231 | return 1; | |||
| 2232 | } | |||
| 2233 | ||||
| 2234 | static int parse_zlib_header(zbuf *a) | |||
| 2235 | { | |||
| 2236 | int cmf = zget8(a); | |||
| 2237 | int cm = cmf & 15; | |||
| 2238 | /* int cinfo = cmf >> 4; */ | |||
| 2239 | int flg = zget8(a); | |||
| 2240 | if ((cmf*256+flg) % 31 != 0) return e("bad zlib header","Corrupt PNG")e("bad zlib header"); // zlib spec | |||
| 2241 | if (flg & 32) return e("no preset dict","Corrupt PNG")e("no preset dict"); // preset dictionary not allowed in png | |||
| 2242 | if (cm != 8) return e("bad compression","Corrupt PNG")e("bad compression"); // DEFLATE required for png | |||
| 2243 | // window = 1 << (8 + cinfo)... but who cares, we fully buffer output | |||
| 2244 | return 1; | |||
| 2245 | } | |||
| 2246 | ||||
| 2247 | // @TODO: should statically initialize these for optimal thread safety | |||
| 2248 | static uint8 default_length[288], default_distance[32]; | |||
| 2249 | static void init_defaults(void) | |||
| 2250 | { | |||
| 2251 | int i; // use <= to match clearly with spec | |||
| 2252 | for (i=0; i <= 143; ++i) default_length[i] = 8; | |||
| 2253 | for ( ; i <= 255; ++i) default_length[i] = 9; | |||
| 2254 | for ( ; i <= 279; ++i) default_length[i] = 7; | |||
| 2255 | for ( ; i <= 287; ++i) default_length[i] = 8; | |||
| 2256 | ||||
| 2257 | for (i=0; i <= 31; ++i) default_distance[i] = 5; | |||
| 2258 | } | |||
| 2259 | ||||
| 2260 | int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead | |||
| 2261 | static int parse_zlib(zbuf *a, int parse_header) | |||
| 2262 | { | |||
| 2263 | int final, type; | |||
| 2264 | if (parse_header) | |||
| 2265 | if (!parse_zlib_header(a)) return 0; | |||
| 2266 | a->num_bits = 0; | |||
| 2267 | a->code_buffer = 0; | |||
| 2268 | do { | |||
| 2269 | final = zreceive(a,1); | |||
| 2270 | type = zreceive(a,2); | |||
| 2271 | if (type == 0) { | |||
| 2272 | if (!parse_uncompressed_block(a)) return 0; | |||
| 2273 | } else if (type == 3) { | |||
| 2274 | return 0; | |||
| 2275 | } else { | |||
| 2276 | if (type == 1) { | |||
| 2277 | // use fixed code lengths | |||
| 2278 | if (!default_distance[31]) init_defaults(); | |||
| 2279 | if (!zbuild_huffman(&a->z_length , default_length , 288)) return 0; | |||
| 2280 | if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0; | |||
| 2281 | } else { | |||
| 2282 | if (!compute_huffman_codes(a)) return 0; | |||
| 2283 | } | |||
| 2284 | if (!parse_huffman_block(a)) return 0; | |||
| 2285 | } | |||
| 2286 | if (stbi_png_partial && a->zout - a->zout_start > 65536) | |||
| 2287 | break; | |||
| 2288 | } while (!final); | |||
| 2289 | return 1; | |||
| 2290 | } | |||
| 2291 | ||||
| 2292 | static int do_zlib(zbuf *a, char *obuf, int olen, int exp, int parse_header) | |||
| 2293 | { | |||
| 2294 | a->zout_start = obuf; | |||
| 2295 | a->zout = obuf; | |||
| 2296 | a->zout_end = obuf + olen; | |||
| 2297 | a->z_expandable = exp; | |||
| 2298 | ||||
| 2299 | return parse_zlib(a, parse_header); | |||
| 2300 | } | |||
| 2301 | ||||
| 2302 | char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) | |||
| 2303 | { | |||
| 2304 | zbuf a; | |||
| 2305 | char *p = (char *) malloc(initial_size); | |||
| 2306 | if (p == NULL((void*)0)) return NULL((void*)0); | |||
| 2307 | a.zbuffer = (uint8 *) buffer; | |||
| 2308 | a.zbuffer_end = (uint8 *) buffer + len; | |||
| 2309 | if (do_zlib(&a, p, initial_size, 1, 1)) { | |||
| 2310 | if (outlen) *outlen = (int) (a.zout - a.zout_start); | |||
| 2311 | return a.zout_start; | |||
| 2312 | } else { | |||
| 2313 | free(a.zout_start); | |||
| 2314 | return NULL((void*)0); | |||
| 2315 | } | |||
| 2316 | } | |||
| 2317 | ||||
| 2318 | char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) | |||
| 2319 | { | |||
| 2320 | return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); | |||
| 2321 | } | |||
| 2322 | ||||
| 2323 | char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) | |||
| 2324 | { | |||
| 2325 | zbuf a; | |||
| 2326 | char *p = (char *) malloc(initial_size); | |||
| 2327 | if (p == NULL((void*)0)) return NULL((void*)0); | |||
| 2328 | a.zbuffer = (uint8 *) buffer; | |||
| 2329 | a.zbuffer_end = (uint8 *) buffer + len; | |||
| 2330 | if (do_zlib(&a, p, initial_size, 1, parse_header)) { | |||
| 2331 | if (outlen) *outlen = (int) (a.zout - a.zout_start); | |||
| 2332 | return a.zout_start; | |||
| 2333 | } else { | |||
| 2334 | free(a.zout_start); | |||
| 2335 | return NULL((void*)0); | |||
| 2336 | } | |||
| 2337 | } | |||
| 2338 | ||||
| 2339 | int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) | |||
| 2340 | { | |||
| 2341 | zbuf a; | |||
| 2342 | a.zbuffer = (uint8 *) ibuffer; | |||
| 2343 | a.zbuffer_end = (uint8 *) ibuffer + ilen; | |||
| 2344 | if (do_zlib(&a, obuffer, olen, 0, 1)) | |||
| 2345 | return (int) (a.zout - a.zout_start); | |||
| 2346 | else | |||
| 2347 | return -1; | |||
| 2348 | } | |||
| 2349 | ||||
| 2350 | char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) | |||
| 2351 | { | |||
| 2352 | zbuf a; | |||
| 2353 | char *p = (char *) malloc(16384); | |||
| 2354 | if (p == NULL((void*)0)) return NULL((void*)0); | |||
| 2355 | a.zbuffer = (uint8 *) buffer; | |||
| 2356 | a.zbuffer_end = (uint8 *) buffer+len; | |||
| 2357 | if (do_zlib(&a, p, 16384, 1, 0)) { | |||
| 2358 | if (outlen) *outlen = (int) (a.zout - a.zout_start); | |||
| 2359 | return a.zout_start; | |||
| 2360 | } else { | |||
| 2361 | free(a.zout_start); | |||
| 2362 | return NULL((void*)0); | |||
| 2363 | } | |||
| 2364 | } | |||
| 2365 | ||||
| 2366 | int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) | |||
| 2367 | { | |||
| 2368 | zbuf a; | |||
| 2369 | a.zbuffer = (uint8 *) ibuffer; | |||
| 2370 | a.zbuffer_end = (uint8 *) ibuffer + ilen; | |||
| 2371 | if (do_zlib(&a, obuffer, olen, 0, 0)) | |||
| ||||
| 2372 | return (int) (a.zout - a.zout_start); | |||
| ||||
| 2373 | else | |||
| 2374 | return -1; | |||
| 2375 | } | |||
| 2376 | ||||
| 2377 | // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 | |||
| 2378 | // simple implementation | |||
| 2379 | // - only 8-bit samples | |||
| 2380 | // - no CRC checking | |||
| 2381 | // - allocates lots of intermediate memory | |||
| 2382 | // - avoids problem of streaming data between subsystems | |||
| 2383 | // - avoids explicit window management | |||
| 2384 | // performance | |||
| 2385 | // - uses stb_zlib, a PD zlib implementation with fast huffman decoding | |||
| 2386 | ||||
| 2387 | ||||
| 2388 | typedef struct | |||
| 2389 | { | |||
| 2390 | uint32 length; | |||
| 2391 | uint32 type; | |||
| 2392 | } chunk; | |||
| 2393 | ||||
| 2394 | #define PNG_TYPE(a,b,c,d)(((a) << 24) + ((b) << 16) + ((c) << 8) + ( d)) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) | |||
| 2395 | ||||
| 2396 | static chunk get_chunk_header(stbi *s) | |||
| 2397 | { | |||
| 2398 | chunk c; | |||
| 2399 | c.length = get32(s); | |||
| 2400 | c.type = get32(s); | |||
| 2401 | return c; | |||
| 2402 | } | |||
| 2403 | ||||
| 2404 | static int check_png_header(stbi *s) | |||
| 2405 | { | |||
| 2406 | static uint8 png_sig[8] = { 137,80,78,71,13,10,26,10 }; | |||
| 2407 | int i; | |||
| 2408 | for (i=0; i < 8; ++i) | |||
| 2409 | if (get8u(s) != png_sig[i]) return e("bad png sig","Not a PNG")e("bad png sig"); | |||
| 2410 | return 1; | |||
| 2411 | } | |||
| 2412 | ||||
| 2413 | typedef struct | |||
| 2414 | { | |||
| 2415 | stbi *s; | |||
| 2416 | uint8 *idata, *expanded, *out; | |||
| 2417 | } png; | |||
| 2418 | ||||
| 2419 | ||||
| 2420 | enum { | |||
| 2421 | F_none=0, F_sub=1, F_up=2, F_avg=3, F_paeth=4, | |||
| 2422 | F_avg_first, F_paeth_first | |||
| 2423 | }; | |||
| 2424 | ||||
| 2425 | static uint8 first_row_filter[5] = | |||
| 2426 | { | |||
| 2427 | F_none, F_sub, F_none, F_avg_first, F_paeth_first | |||
| 2428 | }; | |||
| 2429 | ||||
| 2430 | static int paeth(int a, int b, int c) | |||
| 2431 | { | |||
| 2432 | int p = a + b - c; | |||
| 2433 | int pa = abs(p-a); | |||
| 2434 | int pb = abs(p-b); | |||
| 2435 | int pc = abs(p-c); | |||
| 2436 | if (pa <= pb && pa <= pc) return a; | |||
| 2437 | if (pb <= pc) return b; | |||
| 2438 | return c; | |||
| 2439 | } | |||
| 2440 | ||||
| 2441 | // create the png data from post-deflated data | |||
| 2442 | static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y) | |||
| 2443 | { | |||
| 2444 | stbi *s = a->s; | |||
| 2445 | uint32 i,j,stride = x*out_n; | |||
| 2446 | int k; | |||
| 2447 | int img_n = s->img_n; // copy it into a local for later | |||
| 2448 | assert(out_n == s->img_n || out_n == s->img_n+1)((out_n == s->img_n || out_n == s->img_n+1) ? (void)0 : _assert("out_n == s->img_n || out_n == s->img_n+1", "src/siege/internal/stb/stb_image.c" , 2448)); | |||
| 2449 | if (stbi_png_partial) y = 1; | |||
| 2450 | a->out = (uint8 *) malloc(x * y * out_n); | |||
| 2451 | if (!a->out) return e("outofmem", "Out of memory")e("outofmem"); | |||
| 2452 | if (!stbi_png_partial) { | |||
| 2453 | if (s->img_x == x && s->img_y == y) { | |||
| 2454 | if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG")e("not enough pixels"); | |||
| 2455 | } else { // interlaced: | |||
| 2456 | if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG")e("not enough pixels"); | |||
| 2457 | } | |||
| 2458 | } | |||
| 2459 | for (j=0; j < y; ++j) { | |||
| 2460 | uint8 *cur = a->out + stride*j; | |||
| 2461 | uint8 *prior = cur - stride; | |||
| 2462 | int filter = *raw++; | |||
| 2463 | if (filter > 4) return e("invalid filter","Corrupt PNG")e("invalid filter"); | |||
| 2464 | // if first row, use special filter that doesn't sample previous row | |||
| 2465 | if (j == 0) filter = first_row_filter[filter]; | |||
| 2466 | // handle first pixel explicitly | |||
| 2467 | for (k=0; k < img_n; ++k) { | |||
| 2468 | switch (filter) { | |||
| 2469 | case F_none : cur[k] = raw[k]; break; | |||
| 2470 | case F_sub : cur[k] = raw[k]; break; | |||
| 2471 | case F_up : cur[k] = raw[k] + prior[k]; break; | |||
| 2472 | case F_avg : cur[k] = raw[k] + (prior[k]>>1); break; | |||
| 2473 | case F_paeth : cur[k] = (uint8) (raw[k] + paeth(0,prior[k],0)); break; | |||
| 2474 | case F_avg_first : cur[k] = raw[k]; break; | |||
| 2475 | case F_paeth_first: cur[k] = raw[k]; break; | |||
| 2476 | } | |||
| 2477 | } | |||
| 2478 | if (img_n != out_n) cur[img_n] = 255; | |||
| 2479 | raw += img_n; | |||
| 2480 | cur += out_n; | |||
| 2481 | prior += out_n; | |||
| 2482 | // this is a little gross, so that we don't switch per-pixel or per-component | |||
| 2483 | if (img_n == out_n) { | |||
| 2484 | #define CASE(f) \ | |||
| 2485 | case f: \ | |||
| 2486 | for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ | |||
| 2487 | for (k=0; k < img_n; ++k) | |||
| 2488 | switch (filter) { | |||
| 2489 | CASE(F_none) cur[k] = raw[k]; break; | |||
| 2490 | CASE(F_sub) cur[k] = raw[k] + cur[k-img_n]; break; | |||
| 2491 | CASE(F_up) cur[k] = raw[k] + prior[k]; break; | |||
| 2492 | CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-img_n])>>1); break; | |||
| 2493 | CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],prior[k],prior[k-img_n])); break; | |||
| 2494 | CASE(F_avg_first) cur[k] = raw[k] + (cur[k-img_n] >> 1); break; | |||
| 2495 | CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],0,0)); break; | |||
| 2496 | } | |||
| 2497 | #undef CASE | |||
| 2498 | } else { | |||
| 2499 | assert(img_n+1 == out_n)((img_n+1 == out_n) ? (void)0 : _assert("img_n+1 == out_n", "src/siege/internal/stb/stb_image.c" , 2499)); | |||
| 2500 | #define CASE(f) \ | |||
| 2501 | case f: \ | |||
| 2502 | for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ | |||
| 2503 | for (k=0; k < img_n; ++k) | |||
| 2504 | switch (filter) { | |||
| 2505 | CASE(F_none) cur[k] = raw[k]; break; | |||
| 2506 | CASE(F_sub) cur[k] = raw[k] + cur[k-out_n]; break; | |||
| 2507 | CASE(F_up) cur[k] = raw[k] + prior[k]; break; | |||
| 2508 | CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-out_n])>>1); break; | |||
| 2509 | CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; | |||
| 2510 | CASE(F_avg_first) cur[k] = raw[k] + (cur[k-out_n] >> 1); break; | |||
| 2511 | CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],0,0)); break; | |||
| 2512 | } | |||
| 2513 | #undef CASE | |||
| 2514 | } | |||
| 2515 | } | |||
| 2516 | return 1; | |||
| 2517 | } | |||
| 2518 | ||||
| 2519 | static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced) | |||
| 2520 | { | |||
| 2521 | uint8 *final; | |||
| 2522 | int p; | |||
| 2523 | int save; | |||
| 2524 | if (!interlaced) | |||
| 2525 | return create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y); | |||
| 2526 | save = stbi_png_partial; | |||
| 2527 | stbi_png_partial = 0; | |||
| 2528 | ||||
| 2529 | // de-interlacing | |||
| 2530 | final = (uint8 *) malloc(a->s->img_x * a->s->img_y * out_n); | |||
| 2531 | for (p=0; p < 7; ++p) { | |||
| 2532 | int xorig[] = { 0,4,0,2,0,1,0 }; | |||
| 2533 | int yorig[] = { 0,0,4,0,2,0,1 }; | |||
| 2534 | int xspc[] = { 8,8,4,4,2,2,1 }; | |||
| 2535 | int yspc[] = { 8,8,8,4,4,2,2 }; | |||
| 2536 | int i,j,x,y; | |||
| 2537 | // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 | |||
| 2538 | x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; | |||
| 2539 | y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; | |||
| 2540 | if (x && y) { | |||
| 2541 | if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) { | |||
| 2542 | free(final); | |||
| 2543 | return 0; | |||
| 2544 | } | |||
| 2545 | for (j=0; j < y; ++j) | |||
| 2546 | for (i=0; i < x; ++i) | |||
| 2547 | memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n, | |||
| 2548 | a->out + (j*x+i)*out_n, out_n); | |||
| 2549 | free(a->out); | |||
| 2550 | raw += (x*out_n+1)*y; | |||
| 2551 | raw_len -= (x*out_n+1)*y; | |||
| 2552 | } | |||
| 2553 | } | |||
| 2554 | a->out = final; | |||
| 2555 | ||||
| 2556 | stbi_png_partial = save; | |||
| 2557 | return 1; | |||
| 2558 | } | |||
| 2559 | ||||
| 2560 | static int compute_transparency(png *z, uint8 tc[3], int out_n) | |||
| 2561 | { | |||
| 2562 | stbi *s = z->s; | |||
| 2563 | uint32 i, pixel_count = s->img_x * s->img_y; | |||
| 2564 | uint8 *p = z->out; | |||
| 2565 | ||||
| 2566 | // compute color-based transparency, assuming we've | |||
| 2567 | // already got 255 as the alpha value in the output | |||
| 2568 | assert(out_n == 2 || out_n == 4)((out_n == 2 || out_n == 4) ? (void)0 : _assert("out_n == 2 || out_n == 4" , "src/siege/internal/stb/stb_image.c", 2568)); | |||
| 2569 | ||||
| 2570 | if (out_n == 2) { | |||
| 2571 | for (i=0; i < pixel_count; ++i) { | |||
| 2572 | p[1] = (p[0] == tc[0] ? 0 : 255); | |||
| 2573 | p += 2; | |||
| 2574 | } | |||
| 2575 | } else { | |||
| 2576 | for (i=0; i < pixel_count; ++i) { | |||
| 2577 | if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) | |||
| 2578 | p[3] = 0; | |||
| 2579 | p += 4; | |||
| 2580 | } | |||
| 2581 | } | |||
| 2582 | return 1; | |||
| 2583 | } | |||
| 2584 | ||||
| 2585 | static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n) | |||
| 2586 | { | |||
| 2587 | uint32 i, pixel_count = a->s->img_x * a->s->img_y; | |||
| 2588 | uint8 *p, *temp_out, *orig = a->out; | |||
| 2589 | ||||
| 2590 | p = (uint8 *) malloc(pixel_count * pal_img_n); | |||
| 2591 | if (p == NULL((void*)0)) return e("outofmem", "Out of memory")e("outofmem"); | |||
| 2592 | ||||
| 2593 | // between here and free(out) below, exitting would leak | |||
| 2594 | temp_out = p; | |||
| 2595 | ||||
| 2596 | if (pal_img_n == 3) { | |||
| 2597 | for (i=0; i < pixel_count; ++i) { | |||
| 2598 | int n = orig[i]*4; | |||
| 2599 | p[0] = palette[n ]; | |||
| 2600 | p[1] = palette[n+1]; | |||
| 2601 | p[2] = palette[n+2]; | |||
| 2602 | p += 3; | |||
| 2603 | } | |||
| 2604 | } else { | |||
| 2605 | for (i=0; i < pixel_count; ++i) { | |||
| 2606 | int n = orig[i]*4; | |||
| 2607 | p[0] = palette[n ]; | |||
| 2608 | p[1] = palette[n+1]; | |||
| 2609 | p[2] = palette[n+2]; | |||
| 2610 | p[3] = palette[n+3]; | |||
| 2611 | p += 4; | |||
| 2612 | } | |||
| 2613 | } | |||
| 2614 | free(a->out); | |||
| 2615 | a->out = temp_out; | |||
| 2616 | ||||
| 2617 | STBI_NOTUSED(len)(void)sizeof(len); | |||
| 2618 | ||||
| 2619 | return 1; | |||
| 2620 | } | |||
| 2621 | ||||
| 2622 | static int stbi_unpremultiply_on_load = 0; | |||
| 2623 | static int stbi_de_iphone_flag = 0; | |||
| 2624 | ||||
| 2625 | void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) | |||
| 2626 | { | |||
| 2627 | stbi_unpremultiply_on_load = flag_true_if_should_unpremultiply; | |||
| 2628 | } | |||
| 2629 | void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) | |||
| 2630 | { | |||
| 2631 | stbi_de_iphone_flag = flag_true_if_should_convert; | |||
| 2632 | } | |||
| 2633 | ||||
| 2634 | static void stbi_de_iphone(png *z) | |||
| 2635 | { | |||
| 2636 | stbi *s = z->s; | |||
| 2637 | uint32 i, pixel_count = s->img_x * s->img_y; | |||
| 2638 | uint8 *p = z->out; | |||
| 2639 | ||||
| 2640 | if (s->img_out_n == 3) { // convert bgr to rgb | |||
| 2641 | for (i=0; i < pixel_count; ++i) { | |||
| 2642 | uint8 t = p[0]; | |||
| 2643 | p[0] = p[2]; | |||
| 2644 | p[2] = t; | |||
| 2645 | p += 3; | |||
| 2646 | } | |||
| 2647 | } else { | |||
| 2648 | assert(s->img_out_n == 4)((s->img_out_n == 4) ? (void)0 : _assert("s->img_out_n == 4" , "src/siege/internal/stb/stb_image.c", 2648)); | |||
| 2649 | if (stbi_unpremultiply_on_load) { | |||
| 2650 | // convert bgr to rgb and unpremultiply | |||
| 2651 | for (i=0; i < pixel_count; ++i) { | |||
| 2652 | uint8 a = p[3]; | |||
| 2653 | uint8 t = p[0]; | |||
| 2654 | if (a) { | |||
| 2655 | p[0] = p[2] * 255 / a; | |||
| 2656 | p[1] = p[1] * 255 / a; | |||
| 2657 | p[2] = t * 255 / a; | |||
| 2658 | } else { | |||
| 2659 | p[0] = p[2]; | |||
| 2660 | p[2] = t; | |||
| 2661 | } | |||
| 2662 | p += 4; | |||
| 2663 | } | |||
| 2664 | } else { | |||
| 2665 | // convert bgr to rgb | |||
| 2666 | for (i=0; i < pixel_count; ++i) { | |||
| 2667 | uint8 t = p[0]; | |||
| 2668 | p[0] = p[2]; | |||
| 2669 | p[2] = t; | |||
| 2670 | p += 4; | |||
| 2671 | } | |||
| 2672 | } | |||
| 2673 | } | |||
| 2674 | } | |||
| 2675 | ||||
| 2676 | static int parse_png_file(png *z, int scan, int req_comp) | |||
| 2677 | { | |||
| 2678 | uint8 palette[1024], pal_img_n=0; | |||
| 2679 | uint8 has_trans=0, tc[3]; | |||
| 2680 | uint32 ioff=0, idata_limit=0, i, pal_len=0; | |||
| 2681 | int first=1,k,interlace=0, iphone=0; | |||
| 2682 | stbi *s = z->s; | |||
| 2683 | ||||
| 2684 | z->expanded = NULL((void*)0); | |||
| 2685 | z->idata = NULL((void*)0); | |||
| 2686 | z->out = NULL((void*)0); | |||
| 2687 | ||||
| 2688 | if (!check_png_header(s)) return 0; | |||
| 2689 | ||||
| 2690 | if (scan == SCAN_type) return 1; | |||
| 2691 | ||||
| 2692 | for (;;) { | |||
| 2693 | chunk c = get_chunk_header(s); | |||
| 2694 | switch (c.type) { | |||
| 2695 | case PNG_TYPE('C','g','B','I')((('C') << 24) + (('g') << 16) + (('B') << 8 ) + ('I')): | |||
| 2696 | iphone = stbi_de_iphone_flag; | |||
| 2697 | skip(s, c.length); | |||
| 2698 | break; | |||
| 2699 | case PNG_TYPE('I','H','D','R')((('I') << 24) + (('H') << 16) + (('D') << 8 ) + ('R')): { | |||
| 2700 | int depth,color,comp,filter; | |||
| 2701 | if (!first) return e("multiple IHDR","Corrupt PNG")e("multiple IHDR"); | |||
| 2702 | first = 0; | |||
| 2703 | if (c.length != 13) return e("bad IHDR len","Corrupt PNG")e("bad IHDR len"); | |||
| 2704 | s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)")e("too large"); | |||
| 2705 | s->img_y = get32(s); if (s->img_y > (1 << 24)) return e("too large","Very large image (corrupt?)")e("too large"); | |||
| 2706 | depth = get8(s); if (depth != 8) return e("8bit only","PNG not supported: 8-bit only")e("8bit only"); | |||
| 2707 | color = get8(s); if (color > 6) return e("bad ctype","Corrupt PNG")e("bad ctype"); | |||
| 2708 | if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG")e("bad ctype"); | |||
| 2709 | comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG")e("bad comp method"); | |||
| 2710 | filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG")e("bad filter method"); | |||
| 2711 | interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG")e("bad interlace method"); | |||
| 2712 | if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG")e("0-pixel image"); | |||
| 2713 | if (!pal_img_n) { | |||
| 2714 | s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); | |||
| 2715 | if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode")e("too large"); | |||
| 2716 | if (scan == SCAN_header) return 1; | |||
| 2717 | } else { | |||
| 2718 | // if paletted, then pal_n is our final components, and | |||
| 2719 | // img_n is # components to decompress/filter. | |||
| 2720 | s->img_n = 1; | |||
| 2721 | if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large","Corrupt PNG")e("too large"); | |||
| 2722 | // if SCAN_header, have to scan to see if we have a tRNS | |||
| 2723 | } | |||
| 2724 | break; | |||
| 2725 | } | |||
| 2726 | ||||
| 2727 | case PNG_TYPE('P','L','T','E')((('P') << 24) + (('L') << 16) + (('T') << 8 ) + ('E')): { | |||
| 2728 | if (first) return e("first not IHDR", "Corrupt PNG")e("first not IHDR"); | |||
| 2729 | if (c.length > 256*3) return e("invalid PLTE","Corrupt PNG")e("invalid PLTE"); | |||
| 2730 | pal_len = c.length / 3; | |||
| 2731 | if (pal_len * 3 != c.length) return e("invalid PLTE","Corrupt PNG")e("invalid PLTE"); | |||
| 2732 | for (i=0; i < pal_len; ++i) { | |||
| 2733 | palette[i*4+0] = get8u(s); | |||
| 2734 | palette[i*4+1] = get8u(s); | |||
| 2735 | palette[i*4+2] = get8u(s); | |||
| 2736 | palette[i*4+3] = 255; | |||
| 2737 | } | |||
| 2738 | break; | |||
| 2739 | } | |||
| 2740 | ||||
| 2741 | case PNG_TYPE('t','R','N','S')((('t') << 24) + (('R') << 16) + (('N') << 8 ) + ('S')): { | |||
| 2742 | if (first) return e("first not IHDR", "Corrupt PNG")e("first not IHDR"); | |||
| 2743 | if (z->idata) return e("tRNS after IDAT","Corrupt PNG")e("tRNS after IDAT"); | |||
| 2744 | if (pal_img_n) { | |||
| 2745 | if (scan == SCAN_header) { s->img_n = 4; return 1; } | |||
| 2746 | if (pal_len == 0) return e("tRNS before PLTE","Corrupt PNG")e("tRNS before PLTE"); | |||
| 2747 | if (c.length > pal_len) return e("bad tRNS len","Corrupt PNG")e("bad tRNS len"); | |||
| 2748 | pal_img_n = 4; | |||
| 2749 | for (i=0; i < c.length; ++i) | |||
| 2750 | palette[i*4+3] = get8u(s); | |||
| 2751 | } else { | |||
| 2752 | if (!(s->img_n & 1)) return e("tRNS with alpha","Corrupt PNG")e("tRNS with alpha"); | |||
| 2753 | if (c.length != (uint32) s->img_n*2) return e("bad tRNS len","Corrupt PNG")e("bad tRNS len"); | |||
| 2754 | has_trans = 1; | |||
| 2755 | for (k=0; k < s->img_n; ++k) | |||
| 2756 | tc[k] = (uint8) get16(s); // non 8-bit images will be larger | |||
| 2757 | } | |||
| 2758 | break; | |||
| 2759 | } | |||
| 2760 | ||||
| 2761 | case PNG_TYPE('I','D','A','T')((('I') << 24) + (('D') << 16) + (('A') << 8 ) + ('T')): { | |||
| 2762 | if (first) return e("first not IHDR", "Corrupt PNG")e("first not IHDR"); | |||
| 2763 | if (pal_img_n && !pal_len) return e("no PLTE","Corrupt PNG")e("no PLTE"); | |||
| 2764 | if (scan == SCAN_header) { s->img_n = pal_img_n; return 1; } | |||
| 2765 | if (ioff + c.length > idata_limit) { | |||
| 2766 | uint8 *p; | |||
| 2767 | if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; | |||
| 2768 | while (ioff + c.length > idata_limit) | |||
| 2769 | idata_limit *= 2; | |||
| 2770 | p = (uint8 *) realloc(z->idata, idata_limit); if (p == NULL((void*)0)) return e("outofmem", "Out of memory")e("outofmem"); | |||
| 2771 | z->idata = p; | |||
| 2772 | } | |||
| 2773 | if (!getn(s, z->idata+ioff,c.length)) return e("outofdata","Corrupt PNG")e("outofdata"); | |||
| 2774 | ioff += c.length; | |||
| 2775 | break; | |||
| 2776 | } | |||
| 2777 | ||||
| 2778 | case PNG_TYPE('I','E','N','D')((('I') << 24) + (('E') << 16) + (('N') << 8 ) + ('D')): { | |||
| 2779 | uint32 raw_len; | |||
| 2780 | if (first) return e("first not IHDR", "Corrupt PNG")e("first not IHDR"); | |||
| 2781 | if (scan != SCAN_load) return 1; | |||
| 2782 | if (z->idata == NULL((void*)0)) return e("no IDAT","Corrupt PNG")e("no IDAT"); | |||
| 2783 | z->expanded = (uint8 *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, 16384, (int *) &raw_len, !iphone); | |||
| 2784 | if (z->expanded == NULL((void*)0)) return 0; // zlib should set error | |||
| 2785 | free(z->idata); z->idata = NULL((void*)0); | |||
| 2786 | if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) | |||
| 2787 | s->img_out_n = s->img_n+1; | |||
| 2788 | else | |||
| 2789 | s->img_out_n = s->img_n; | |||
| 2790 | if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; | |||
| 2791 | if (has_trans) | |||
| 2792 | if (!compute_transparency(z, tc, s->img_out_n)) return 0; | |||
| 2793 | if (iphone && s->img_out_n > 2) | |||
| 2794 | stbi_de_iphone(z); | |||
| 2795 | if (pal_img_n) { | |||
| 2796 | // pal_img_n == 3 or 4 | |||
| 2797 | s->img_n = pal_img_n; // record the actual colors we had | |||
| 2798 | s->img_out_n = pal_img_n; | |||
| 2799 | if (req_comp >= 3) s->img_out_n = req_comp; | |||
| 2800 | if (!expand_palette(z, palette, pal_len, s->img_out_n)) | |||
| 2801 | return 0; | |||
| 2802 | } | |||
| 2803 | free(z->expanded); z->expanded = NULL((void*)0); | |||
| 2804 | return 1; | |||
| 2805 | } | |||
| 2806 | ||||
| 2807 | default: | |||
| 2808 | // if critical, fail | |||
| 2809 | if (first) return e("first not IHDR", "Corrupt PNG")e("first not IHDR"); | |||
| 2810 | if ((c.type & (1 << 29)) == 0) { | |||
| 2811 | #ifndef STBI_NO_FAILURE_STRINGS | |||
| 2812 | // not threadsafe | |||
| 2813 | static char invalid_chunk[] = "XXXX chunk not known"; | |||
| 2814 | invalid_chunk[0] = (uint8) (c.type >> 24); | |||
| 2815 | invalid_chunk[1] = (uint8) (c.type >> 16); | |||
| 2816 | invalid_chunk[2] = (uint8) (c.type >> 8); | |||
| 2817 | invalid_chunk[3] = (uint8) (c.type >> 0); | |||
| 2818 | #endif | |||
| 2819 | return e(invalid_chunk, "PNG not supported: unknown chunk type")e(invalid_chunk); | |||
| 2820 | } | |||
| 2821 | skip(s, c.length); | |||
| 2822 | break; | |||
| 2823 | } | |||
| 2824 | // end of chunk, read and skip CRC | |||
| 2825 | get32(s); | |||
| 2826 | } | |||
| 2827 | } | |||
| 2828 | ||||
| 2829 | static unsigned char *do_png(png *p, int *x, int *y, int *n, int req_comp) | |||
| 2830 | { | |||
| 2831 | unsigned char *result=NULL((void*)0); | |||
| 2832 | if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error")((unsigned char *) (e("bad req_comp")?((void*)0):((void*)0))); | |||
| 2833 | if (parse_png_file(p, SCAN_load, req_comp)) { | |||
| 2834 | result = p->out; | |||
| 2835 | p->out = NULL((void*)0); | |||
| 2836 | if (req_comp && req_comp != p->s->img_out_n) { | |||
| 2837 | result = convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); | |||
| 2838 | p->s->img_out_n = req_comp; | |||
| 2839 | if (result == NULL((void*)0)) return result; | |||
| 2840 | } | |||
| 2841 | *x = p->s->img_x; | |||
| 2842 | *y = p->s->img_y; | |||
| 2843 | if (n) *n = p->s->img_n; | |||
| 2844 | } | |||
| 2845 | free(p->out); p->out = NULL((void*)0); | |||
| 2846 | free(p->expanded); p->expanded = NULL((void*)0); | |||
| 2847 | free(p->idata); p->idata = NULL((void*)0); | |||
| 2848 | ||||
| 2849 | return result; | |||
| 2850 | } | |||
| 2851 | ||||
| 2852 | static unsigned char *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 2853 | { | |||
| 2854 | png p; | |||
| 2855 | p.s = s; | |||
| 2856 | return do_png(&p, x,y,comp,req_comp); | |||
| 2857 | } | |||
| 2858 | ||||
| 2859 | static int stbi_png_test(stbi *s) | |||
| 2860 | { | |||
| 2861 | int r; | |||
| 2862 | r = check_png_header(s); | |||
| 2863 | stbi_rewind(s); | |||
| 2864 | return r; | |||
| 2865 | } | |||
| 2866 | ||||
| 2867 | static int stbi_png_info_raw(png *p, int *x, int *y, int *comp) | |||
| 2868 | { | |||
| 2869 | if (!parse_png_file(p, SCAN_header, 0)) { | |||
| 2870 | stbi_rewind( p->s ); | |||
| 2871 | return 0; | |||
| 2872 | } | |||
| 2873 | if (x) *x = p->s->img_x; | |||
| 2874 | if (y) *y = p->s->img_y; | |||
| 2875 | if (comp) *comp = p->s->img_n; | |||
| 2876 | return 1; | |||
| 2877 | } | |||
| 2878 | ||||
| 2879 | static int stbi_png_info(stbi *s, int *x, int *y, int *comp) | |||
| 2880 | { | |||
| 2881 | png p; | |||
| 2882 | p.s = s; | |||
| 2883 | return stbi_png_info_raw(&p, x, y, comp); | |||
| 2884 | } | |||
| 2885 | ||||
| 2886 | // Microsoft/Windows BMP image | |||
| 2887 | ||||
| 2888 | static int bmp_test(stbi *s) | |||
| 2889 | { | |||
| 2890 | int sz; | |||
| 2891 | if (get8(s) != 'B') return 0; | |||
| 2892 | if (get8(s) != 'M') return 0; | |||
| 2893 | get32le(s); // discard filesize | |||
| 2894 | get16le(s); // discard reserved | |||
| 2895 | get16le(s); // discard reserved | |||
| 2896 | get32le(s); // discard data offset | |||
| 2897 | sz = get32le(s); | |||
| 2898 | if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1; | |||
| 2899 | return 0; | |||
| 2900 | } | |||
| 2901 | ||||
| 2902 | static int stbi_bmp_test(stbi *s) | |||
| 2903 | { | |||
| 2904 | int r = bmp_test(s); | |||
| 2905 | stbi_rewind(s); | |||
| 2906 | return r; | |||
| 2907 | } | |||
| 2908 | ||||
| 2909 | ||||
| 2910 | // returns 0..31 for the highest set bit | |||
| 2911 | static int high_bit(unsigned int z) | |||
| 2912 | { | |||
| 2913 | int n=0; | |||
| 2914 | if (z == 0) return -1; | |||
| 2915 | if (z >= 0x10000) n += 16, z >>= 16; | |||
| 2916 | if (z >= 0x00100) n += 8, z >>= 8; | |||
| 2917 | if (z >= 0x00010) n += 4, z >>= 4; | |||
| 2918 | if (z >= 0x00004) n += 2, z >>= 2; | |||
| 2919 | if (z >= 0x00002) n += 1, z >>= 1; | |||
| 2920 | return n; | |||
| 2921 | } | |||
| 2922 | ||||
| 2923 | static int bitcount(unsigned int a) | |||
| 2924 | { | |||
| 2925 | a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 | |||
| 2926 | a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 | |||
| 2927 | a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits | |||
| 2928 | a = (a + (a >> 8)); // max 16 per 8 bits | |||
| 2929 | a = (a + (a >> 16)); // max 32 per 8 bits | |||
| 2930 | return a & 0xff; | |||
| 2931 | } | |||
| 2932 | ||||
| 2933 | static int shiftsigned(int v, int shift, int bits) | |||
| 2934 | { | |||
| 2935 | int result; | |||
| 2936 | int z=0; | |||
| 2937 | ||||
| 2938 | if (shift < 0) v <<= -shift; | |||
| 2939 | else v >>= shift; | |||
| 2940 | result = v; | |||
| 2941 | ||||
| 2942 | z = bits; | |||
| 2943 | while (z < 8) { | |||
| 2944 | result += v >> z; | |||
| 2945 | z += bits; | |||
| 2946 | } | |||
| 2947 | return result; | |||
| 2948 | } | |||
| 2949 | ||||
| 2950 | static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 2951 | { | |||
| 2952 | uint8 *out; | |||
| 2953 | unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0; | |||
| 2954 | (void)fake_a; | |||
| 2955 | stbi_uc pal[256][4]; | |||
| 2956 | int psize=0,i,j,compress=0,width; | |||
| 2957 | int bpp, flip_vertically, pad, target, offset, hsz; | |||
| 2958 | if (get8(s) != 'B' || get8(s) != 'M') return epuc("not BMP", "Corrupt BMP")((unsigned char *) (e("not BMP")?((void*)0):((void*)0))); | |||
| 2959 | get32le(s); // discard filesize | |||
| 2960 | get16le(s); // discard reserved | |||
| 2961 | get16le(s); // discard reserved | |||
| 2962 | offset = get32le(s); | |||
| 2963 | hsz = get32le(s); | |||
| 2964 | if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return epuc("unknown BMP", "BMP type not supported: unknown")((unsigned char *) (e("unknown BMP")?((void*)0):((void*)0))); | |||
| 2965 | if (hsz == 12) { | |||
| 2966 | s->img_x = get16le(s); | |||
| 2967 | s->img_y = get16le(s); | |||
| 2968 | } else { | |||
| 2969 | s->img_x = get32le(s); | |||
| 2970 | s->img_y = get32le(s); | |||
| 2971 | } | |||
| 2972 | if (get16le(s) != 1) return epuc("bad BMP", "bad BMP")((unsigned char *) (e("bad BMP")?((void*)0):((void*)0))); | |||
| 2973 | bpp = get16le(s); | |||
| 2974 | if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit")((unsigned char *) (e("monochrome")?((void*)0):((void*)0))); | |||
| 2975 | flip_vertically = ((int) s->img_y) > 0; | |||
| 2976 | s->img_y = abs((int) s->img_y); | |||
| 2977 | if (hsz == 12) { | |||
| 2978 | if (bpp < 24) | |||
| 2979 | psize = (offset - 14 - 24) / 3; | |||
| 2980 | } else { | |||
| 2981 | compress = get32le(s); | |||
| 2982 | if (compress == 1 || compress == 2) return epuc("BMP RLE", "BMP type not supported: RLE")((unsigned char *) (e("BMP RLE")?((void*)0):((void*)0))); | |||
| 2983 | get32le(s); // discard sizeof | |||
| 2984 | get32le(s); // discard hres | |||
| 2985 | get32le(s); // discard vres | |||
| 2986 | get32le(s); // discard colorsused | |||
| 2987 | get32le(s); // discard max important | |||
| 2988 | if (hsz == 40 || hsz == 56) { | |||
| 2989 | if (hsz == 56) { | |||
| 2990 | get32le(s); | |||
| 2991 | get32le(s); | |||
| 2992 | get32le(s); | |||
| 2993 | get32le(s); | |||
| 2994 | } | |||
| 2995 | if (bpp == 16 || bpp == 32) { | |||
| 2996 | mr = mg = mb = 0; | |||
| 2997 | if (compress == 0) { | |||
| 2998 | if (bpp == 32) { | |||
| 2999 | mr = 0xffu << 16; | |||
| 3000 | mg = 0xffu << 8; | |||
| 3001 | mb = 0xffu << 0; | |||
| 3002 | ma = 0xffu << 24; | |||
| 3003 | fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 | |||
| 3004 | } else { | |||
| 3005 | mr = 31u << 10; | |||
| 3006 | mg = 31u << 5; | |||
| 3007 | mb = 31u << 0; | |||
| 3008 | } | |||
| 3009 | } else if (compress == 3) { | |||
| 3010 | mr = get32le(s); | |||
| 3011 | mg = get32le(s); | |||
| 3012 | mb = get32le(s); | |||
| 3013 | // not documented, but generated by photoshop and handled by mspaint | |||
| 3014 | if (mr == mg && mg == mb) { | |||
| 3015 | // ?!?!? | |||
| 3016 | return epuc("bad BMP", "bad BMP")((unsigned char *) (e("bad BMP")?((void*)0):((void*)0))); | |||
| 3017 | } | |||
| 3018 | } else | |||
| 3019 | return epuc("bad BMP", "bad BMP")((unsigned char *) (e("bad BMP")?((void*)0):((void*)0))); | |||
| 3020 | } | |||
| 3021 | } else { | |||
| 3022 | assert(hsz == 108)((hsz == 108) ? (void)0 : _assert("hsz == 108", "src/siege/internal/stb/stb_image.c" , 3022)); | |||
| 3023 | mr = get32le(s); | |||
| 3024 | mg = get32le(s); | |||
| 3025 | mb = get32le(s); | |||
| 3026 | ma = get32le(s); | |||
| 3027 | get32le(s); // discard color space | |||
| 3028 | for (i=0; i < 12; ++i) | |||
| 3029 | get32le(s); // discard color space parameters | |||
| 3030 | } | |||
| 3031 | if (bpp < 16) | |||
| 3032 | psize = (offset - 14 - hsz) >> 2; | |||
| 3033 | } | |||
| 3034 | s->img_n = ma ? 4 : 3; | |||
| 3035 | if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 | |||
| 3036 | target = req_comp; | |||
| 3037 | else | |||
| 3038 | target = s->img_n; // if they want monochrome, we'll post-convert | |||
| 3039 | out = (stbi_uc *) malloc(target * s->img_x * s->img_y); | |||
| 3040 | if (!out) return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); | |||
| 3041 | if (bpp < 16) { | |||
| 3042 | int z=0; | |||
| 3043 | if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP")((unsigned char *) (e("invalid")?((void*)0):((void*)0))); } | |||
| 3044 | for (i=0; i < psize; ++i) { | |||
| 3045 | pal[i][2] = get8u(s); | |||
| 3046 | pal[i][1] = get8u(s); | |||
| 3047 | pal[i][0] = get8u(s); | |||
| 3048 | if (hsz != 12) get8(s); | |||
| 3049 | pal[i][3] = 255; | |||
| 3050 | } | |||
| 3051 | skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); | |||
| 3052 | if (bpp == 4) width = (s->img_x + 1) >> 1; | |||
| 3053 | else if (bpp == 8) width = s->img_x; | |||
| 3054 | else { free(out); return epuc("bad bpp", "Corrupt BMP")((unsigned char *) (e("bad bpp")?((void*)0):((void*)0))); } | |||
| 3055 | pad = (-width)&3; | |||
| 3056 | for (j=0; j < (int) s->img_y; ++j) { | |||
| 3057 | for (i=0; i < (int) s->img_x; i += 2) { | |||
| 3058 | int v=get8(s),v2=0; | |||
| 3059 | if (bpp == 4) { | |||
| 3060 | v2 = v & 15; | |||
| 3061 | v >>= 4; | |||
| 3062 | } | |||
| 3063 | out[z++] = pal[v][0]; | |||
| 3064 | out[z++] = pal[v][1]; | |||
| 3065 | out[z++] = pal[v][2]; | |||
| 3066 | if (target == 4) out[z++] = 255; | |||
| 3067 | if (i+1 == (int) s->img_x) break; | |||
| 3068 | v = (bpp == 8) ? get8(s) : v2; | |||
| 3069 | out[z++] = pal[v][0]; | |||
| 3070 | out[z++] = pal[v][1]; | |||
| 3071 | out[z++] = pal[v][2]; | |||
| 3072 | if (target == 4) out[z++] = 255; | |||
| 3073 | } | |||
| 3074 | skip(s, pad); | |||
| 3075 | } | |||
| 3076 | } else { | |||
| 3077 | int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; | |||
| 3078 | int z = 0; | |||
| 3079 | int easy=0; | |||
| 3080 | skip(s, offset - 14 - hsz); | |||
| 3081 | if (bpp == 24) width = 3 * s->img_x; | |||
| 3082 | else if (bpp == 16) width = 2*s->img_x; | |||
| 3083 | else /* bpp = 32 and pad = 0 */ width=0; | |||
| 3084 | pad = (-width) & 3; | |||
| 3085 | if (bpp == 24) { | |||
| 3086 | easy = 1; | |||
| 3087 | } else if (bpp == 32) { | |||
| 3088 | if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) | |||
| 3089 | easy = 2; | |||
| 3090 | } | |||
| 3091 | if (!easy) { | |||
| 3092 | if (!mr || !mg || !mb) { free(out); return epuc("bad masks", "Corrupt BMP")((unsigned char *) (e("bad masks")?((void*)0):((void*)0))); } | |||
| 3093 | // right shift amt to put high bit in position #7 | |||
| 3094 | rshift = high_bit(mr)-7; rcount = bitcount(mr); | |||
| 3095 | gshift = high_bit(mg)-7; gcount = bitcount(mr); | |||
| 3096 | bshift = high_bit(mb)-7; bcount = bitcount(mr); | |||
| 3097 | ashift = high_bit(ma)-7; acount = bitcount(mr); | |||
| 3098 | } | |||
| 3099 | for (j=0; j < (int) s->img_y; ++j) { | |||
| 3100 | if (easy) { | |||
| 3101 | for (i=0; i < (int) s->img_x; ++i) { | |||
| 3102 | int a; | |||
| 3103 | out[z+2] = get8u(s); | |||
| 3104 | out[z+1] = get8u(s); | |||
| 3105 | out[z+0] = get8u(s); | |||
| 3106 | z += 3; | |||
| 3107 | a = (easy == 2 ? get8(s) : 255); | |||
| 3108 | if (target == 4) out[z++] = (uint8) a; | |||
| 3109 | } | |||
| 3110 | } else { | |||
| 3111 | for (i=0; i < (int) s->img_x; ++i) { | |||
| 3112 | uint32 v = (bpp == 16 ? get16le(s) : get32le(s)); | |||
| 3113 | int a; | |||
| 3114 | out[z++] = (uint8) shiftsigned(v & mr, rshift, rcount); | |||
| 3115 | out[z++] = (uint8) shiftsigned(v & mg, gshift, gcount); | |||
| 3116 | out[z++] = (uint8) shiftsigned(v & mb, bshift, bcount); | |||
| 3117 | a = (ma ? shiftsigned(v & ma, ashift, acount) : 255); | |||
| 3118 | if (target == 4) out[z++] = (uint8) a; | |||
| 3119 | } | |||
| 3120 | } | |||
| 3121 | skip(s, pad); | |||
| 3122 | } | |||
| 3123 | } | |||
| 3124 | if (flip_vertically) { | |||
| 3125 | stbi_uc t; | |||
| 3126 | for (j=0; j < (int) s->img_y>>1; ++j) { | |||
| 3127 | stbi_uc *p1 = out + j *s->img_x*target; | |||
| 3128 | stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; | |||
| 3129 | for (i=0; i < (int) s->img_x*target; ++i) { | |||
| 3130 | t = p1[i], p1[i] = p2[i], p2[i] = t; | |||
| 3131 | } | |||
| 3132 | } | |||
| 3133 | } | |||
| 3134 | ||||
| 3135 | if (req_comp && req_comp != target) { | |||
| 3136 | out = convert_format(out, target, req_comp, s->img_x, s->img_y); | |||
| 3137 | if (out == NULL((void*)0)) return out; // convert_format frees input on failure | |||
| 3138 | } | |||
| 3139 | ||||
| 3140 | *x = s->img_x; | |||
| 3141 | *y = s->img_y; | |||
| 3142 | if (comp) *comp = s->img_n; | |||
| 3143 | return out; | |||
| 3144 | } | |||
| 3145 | ||||
| 3146 | static stbi_uc *stbi_bmp_load(stbi *s,int *x, int *y, int *comp, int req_comp) | |||
| 3147 | { | |||
| 3148 | return bmp_load(s, x,y,comp,req_comp); | |||
| 3149 | } | |||
| 3150 | ||||
| 3151 | ||||
| 3152 | // Targa Truevision - TGA | |||
| 3153 | // by Jonathan Dummer | |||
| 3154 | ||||
| 3155 | static int tga_info(stbi *s, int *x, int *y, int *comp) | |||
| 3156 | { | |||
| 3157 | int tga_w, tga_h, tga_comp; | |||
| 3158 | int sz; | |||
| 3159 | get8u(s); // discard Offset | |||
| 3160 | sz = get8u(s); // color type | |||
| 3161 | if( sz > 1 ) { | |||
| 3162 | stbi_rewind(s); | |||
| 3163 | return 0; // only RGB or indexed allowed | |||
| 3164 | } | |||
| 3165 | sz = get8u(s); // image type | |||
| 3166 | // only RGB or grey allowed, +/- RLE | |||
| 3167 | if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; | |||
| 3168 | skip(s,9); | |||
| 3169 | tga_w = get16le(s); | |||
| 3170 | if( tga_w < 1 ) { | |||
| 3171 | stbi_rewind(s); | |||
| 3172 | return 0; // test width | |||
| 3173 | } | |||
| 3174 | tga_h = get16le(s); | |||
| 3175 | if( tga_h < 1 ) { | |||
| 3176 | stbi_rewind(s); | |||
| 3177 | return 0; // test height | |||
| 3178 | } | |||
| 3179 | sz = get8(s); // bits per pixel | |||
| 3180 | // only RGB or RGBA or grey allowed | |||
| 3181 | if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) { | |||
| 3182 | stbi_rewind(s); | |||
| 3183 | return 0; | |||
| 3184 | } | |||
| 3185 | tga_comp = sz; | |||
| 3186 | if (x) *x = tga_w; | |||
| 3187 | if (y) *y = tga_h; | |||
| 3188 | if (comp) *comp = tga_comp / 8; | |||
| 3189 | return 1; // seems to have passed everything | |||
| 3190 | } | |||
| 3191 | ||||
| 3192 | int stbi_tga_info(stbi *s, int *x, int *y, int *comp) | |||
| 3193 | { | |||
| 3194 | return tga_info(s, x, y, comp); | |||
| 3195 | } | |||
| 3196 | ||||
| 3197 | static int tga_test(stbi *s) | |||
| 3198 | { | |||
| 3199 | int sz; | |||
| 3200 | get8u(s); // discard Offset | |||
| 3201 | sz = get8u(s); // color type | |||
| 3202 | if ( sz > 1 ) return 0; // only RGB or indexed allowed | |||
| 3203 | sz = get8u(s); // image type | |||
| 3204 | if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE | |||
| 3205 | get16(s); // discard palette start | |||
| 3206 | get16(s); // discard palette length | |||
| 3207 | get8(s); // discard bits per palette color entry | |||
| 3208 | get16(s); // discard x origin | |||
| 3209 | get16(s); // discard y origin | |||
| 3210 | if ( get16(s) < 1 ) return 0; // test width | |||
| 3211 | if ( get16(s) < 1 ) return 0; // test height | |||
| 3212 | sz = get8(s); // bits per pixel | |||
| 3213 | if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) return 0; // only RGB or RGBA or grey allowed | |||
| 3214 | return 1; // seems to have passed everything | |||
| 3215 | } | |||
| 3216 | ||||
| 3217 | static int stbi_tga_test(stbi *s) | |||
| 3218 | { | |||
| 3219 | int res = tga_test(s); | |||
| 3220 | stbi_rewind(s); | |||
| 3221 | return res; | |||
| 3222 | } | |||
| 3223 | ||||
| 3224 | static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 3225 | { | |||
| 3226 | // read in the TGA header stuff | |||
| 3227 | int tga_offset = get8u(s); | |||
| 3228 | int tga_indexed = get8u(s); | |||
| 3229 | int tga_image_type = get8u(s); | |||
| 3230 | int tga_is_RLE = 0; | |||
| 3231 | int tga_palette_start = get16le(s); | |||
| 3232 | int tga_palette_len = get16le(s); | |||
| 3233 | int tga_palette_bits = get8u(s); | |||
| 3234 | int tga_x_origin = get16le(s); | |||
| 3235 | int tga_y_origin = get16le(s); | |||
| 3236 | int tga_width = get16le(s); | |||
| 3237 | int tga_height = get16le(s); | |||
| 3238 | int tga_bits_per_pixel = get8u(s); | |||
| 3239 | int tga_inverted = get8u(s); | |||
| 3240 | // image data | |||
| 3241 | unsigned char *tga_data; | |||
| 3242 | unsigned char *tga_palette = NULL((void*)0); | |||
| 3243 | int i, j; | |||
| 3244 | unsigned char raw_data[4]; | |||
| 3245 | unsigned char trans_data[4]; | |||
| 3246 | int RLE_count = 0; | |||
| 3247 | int RLE_repeating = 0; | |||
| 3248 | int read_next_pixel = 1; | |||
| 3249 | ||||
| 3250 | // do a tiny bit of precessing | |||
| 3251 | if ( tga_image_type >= 8 ) | |||
| 3252 | { | |||
| 3253 | tga_image_type -= 8; | |||
| 3254 | tga_is_RLE = 1; | |||
| 3255 | } | |||
| 3256 | /* int tga_alpha_bits = tga_inverted & 15; */ | |||
| 3257 | tga_inverted = 1 - ((tga_inverted >> 5) & 1); | |||
| 3258 | ||||
| 3259 | // error check | |||
| 3260 | if ( //(tga_indexed) || | |||
| 3261 | (tga_width < 1) || (tga_height < 1) || | |||
| 3262 | (tga_image_type < 1) || (tga_image_type > 3) || | |||
| 3263 | ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && | |||
| 3264 | (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) | |||
| 3265 | ) | |||
| 3266 | { | |||
| 3267 | return NULL((void*)0); // we don't report this as a bad TGA because we don't even know if it's TGA | |||
| 3268 | } | |||
| 3269 | ||||
| 3270 | // If I'm paletted, then I'll use the number of bits from the palette | |||
| 3271 | if ( tga_indexed ) | |||
| 3272 | { | |||
| 3273 | tga_bits_per_pixel = tga_palette_bits; | |||
| 3274 | } | |||
| 3275 | ||||
| 3276 | // tga info | |||
| 3277 | *x = tga_width; | |||
| 3278 | *y = tga_height; | |||
| 3279 | if ( (req_comp < 1) || (req_comp > 4) ) | |||
| 3280 | { | |||
| 3281 | // just use whatever the file was | |||
| 3282 | req_comp = tga_bits_per_pixel / 8; | |||
| 3283 | *comp = req_comp; | |||
| 3284 | } else | |||
| 3285 | { | |||
| 3286 | // force a new number of components | |||
| 3287 | *comp = tga_bits_per_pixel/8; | |||
| 3288 | } | |||
| 3289 | tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp ); | |||
| 3290 | if (!tga_data) return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); | |||
| 3291 | ||||
| 3292 | // skip to the data's starting position (offset usually = 0) | |||
| 3293 | skip(s, tga_offset ); | |||
| 3294 | // do I need to load a palette? | |||
| 3295 | if ( tga_indexed ) | |||
| 3296 | { | |||
| 3297 | // any data to skip? (offset usually = 0) | |||
| 3298 | skip(s, tga_palette_start ); | |||
| 3299 | // load the palette | |||
| 3300 | tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 ); | |||
| 3301 | if (!tga_palette) return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); | |||
| 3302 | if (!getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) { | |||
| 3303 | free(tga_data); | |||
| 3304 | free(tga_palette); | |||
| 3305 | return epuc("bad palette", "Corrupt TGA")((unsigned char *) (e("bad palette")?((void*)0):((void*)0))); | |||
| 3306 | } | |||
| 3307 | } | |||
| 3308 | // load the data | |||
| 3309 | trans_data[0] = trans_data[1] = trans_data[2] = trans_data[3] = 0; | |||
| 3310 | for (i=0; i < tga_width * tga_height; ++i) | |||
| 3311 | { | |||
| 3312 | // if I'm in RLE mode, do I need to get a RLE chunk? | |||
| 3313 | if ( tga_is_RLE ) | |||
| 3314 | { | |||
| 3315 | if ( RLE_count == 0 ) | |||
| 3316 | { | |||
| 3317 | // yep, get the next byte as a RLE command | |||
| 3318 | int RLE_cmd = get8u(s); | |||
| 3319 | RLE_count = 1 + (RLE_cmd & 127); | |||
| 3320 | RLE_repeating = RLE_cmd >> 7; | |||
| 3321 | read_next_pixel = 1; | |||
| 3322 | } else if ( !RLE_repeating ) | |||
| 3323 | { | |||
| 3324 | read_next_pixel = 1; | |||
| 3325 | } | |||
| 3326 | } else | |||
| 3327 | { | |||
| 3328 | read_next_pixel = 1; | |||
| 3329 | } | |||
| 3330 | // OK, if I need to read a pixel, do it now | |||
| 3331 | if ( read_next_pixel ) | |||
| 3332 | { | |||
| 3333 | // load however much data we did have | |||
| 3334 | if ( tga_indexed ) | |||
| 3335 | { | |||
| 3336 | // read in 1 byte, then perform the lookup | |||
| 3337 | int pal_idx = get8u(s); | |||
| 3338 | if ( pal_idx >= tga_palette_len ) | |||
| 3339 | { | |||
| 3340 | // invalid index | |||
| 3341 | pal_idx = 0; | |||
| 3342 | } | |||
| 3343 | pal_idx *= tga_bits_per_pixel / 8; | |||
| 3344 | for (j = 0; j*8 < tga_bits_per_pixel; ++j) | |||
| 3345 | { | |||
| 3346 | raw_data[j] = tga_palette[pal_idx+j]; | |||
| 3347 | } | |||
| 3348 | } else | |||
| 3349 | { | |||
| 3350 | // read in the data raw | |||
| 3351 | for (j = 0; j*8 < tga_bits_per_pixel; ++j) | |||
| 3352 | { | |||
| 3353 | raw_data[j] = get8u(s); | |||
| 3354 | } | |||
| 3355 | } | |||
| 3356 | // convert raw to the intermediate format | |||
| 3357 | switch (tga_bits_per_pixel) | |||
| 3358 | { | |||
| 3359 | case 8: | |||
| 3360 | // Luminous => RGBA | |||
| 3361 | trans_data[0] = raw_data[0]; | |||
| 3362 | trans_data[1] = raw_data[0]; | |||
| 3363 | trans_data[2] = raw_data[0]; | |||
| 3364 | trans_data[3] = 255; | |||
| 3365 | break; | |||
| 3366 | case 16: | |||
| 3367 | // Luminous,Alpha => RGBA | |||
| 3368 | trans_data[0] = raw_data[0]; | |||
| 3369 | trans_data[1] = raw_data[0]; | |||
| 3370 | trans_data[2] = raw_data[0]; | |||
| 3371 | trans_data[3] = raw_data[1]; | |||
| 3372 | break; | |||
| 3373 | case 24: | |||
| 3374 | // BGR => RGBA | |||
| 3375 | trans_data[0] = raw_data[2]; | |||
| 3376 | trans_data[1] = raw_data[1]; | |||
| 3377 | trans_data[2] = raw_data[0]; | |||
| 3378 | trans_data[3] = 255; | |||
| 3379 | break; | |||
| 3380 | case 32: | |||
| 3381 | // BGRA => RGBA | |||
| 3382 | trans_data[0] = raw_data[2]; | |||
| 3383 | trans_data[1] = raw_data[1]; | |||
| 3384 | trans_data[2] = raw_data[0]; | |||
| 3385 | trans_data[3] = raw_data[3]; | |||
| 3386 | break; | |||
| 3387 | } | |||
| 3388 | // clear the reading flag for the next pixel | |||
| 3389 | read_next_pixel = 0; | |||
| 3390 | } // end of reading a pixel | |||
| 3391 | // convert to final format | |||
| 3392 | switch (req_comp) | |||
| 3393 | { | |||
| 3394 | case 1: | |||
| 3395 | // RGBA => Luminance | |||
| 3396 | tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); | |||
| 3397 | break; | |||
| 3398 | case 2: | |||
| 3399 | // RGBA => Luminance,Alpha | |||
| 3400 | tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); | |||
| 3401 | tga_data[i*req_comp+1] = trans_data[3]; | |||
| 3402 | break; | |||
| 3403 | case 3: | |||
| 3404 | // RGBA => RGB | |||
| 3405 | tga_data[i*req_comp+0] = trans_data[0]; | |||
| 3406 | tga_data[i*req_comp+1] = trans_data[1]; | |||
| 3407 | tga_data[i*req_comp+2] = trans_data[2]; | |||
| 3408 | break; | |||
| 3409 | case 4: | |||
| 3410 | // RGBA => RGBA | |||
| 3411 | tga_data[i*req_comp+0] = trans_data[0]; | |||
| 3412 | tga_data[i*req_comp+1] = trans_data[1]; | |||
| 3413 | tga_data[i*req_comp+2] = trans_data[2]; | |||
| 3414 | tga_data[i*req_comp+3] = trans_data[3]; | |||
| 3415 | break; | |||
| 3416 | } | |||
| 3417 | // in case we're in RLE mode, keep counting down | |||
| 3418 | --RLE_count; | |||
| 3419 | } | |||
| 3420 | // do I need to invert the image? | |||
| 3421 | if ( tga_inverted ) | |||
| 3422 | { | |||
| 3423 | for (j = 0; j*2 < tga_height; ++j) | |||
| 3424 | { | |||
| 3425 | int index1 = j * tga_width * req_comp; | |||
| 3426 | int index2 = (tga_height - 1 - j) * tga_width * req_comp; | |||
| 3427 | for (i = tga_width * req_comp; i > 0; --i) | |||
| 3428 | { | |||
| 3429 | unsigned char temp = tga_data[index1]; | |||
| 3430 | tga_data[index1] = tga_data[index2]; | |||
| 3431 | tga_data[index2] = temp; | |||
| 3432 | ++index1; | |||
| 3433 | ++index2; | |||
| 3434 | } | |||
| 3435 | } | |||
| 3436 | } | |||
| 3437 | // clear my palette, if I had one | |||
| 3438 | if ( tga_palette != NULL((void*)0) ) | |||
| 3439 | { | |||
| 3440 | free( tga_palette ); | |||
| 3441 | } | |||
| 3442 | // the things I do to get rid of an error message, and yet keep | |||
| 3443 | // Microsoft's C compilers happy... [8^( | |||
| 3444 | tga_palette_start = tga_palette_len = tga_palette_bits = | |||
| 3445 | tga_x_origin = tga_y_origin = 0; | |||
| 3446 | // OK, done | |||
| 3447 | return tga_data; | |||
| 3448 | } | |||
| 3449 | ||||
| 3450 | static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 3451 | { | |||
| 3452 | return tga_load(s,x,y,comp,req_comp); | |||
| 3453 | } | |||
| 3454 | ||||
| 3455 | ||||
| 3456 | // ************************************************************************************************* | |||
| 3457 | // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB | |||
| 3458 | ||||
| 3459 | static int psd_test(stbi *s) | |||
| 3460 | { | |||
| 3461 | if (get32(s) != 0x38425053) return 0; // "8BPS" | |||
| 3462 | else return 1; | |||
| 3463 | } | |||
| 3464 | ||||
| 3465 | static int stbi_psd_test(stbi *s) | |||
| 3466 | { | |||
| 3467 | int r = psd_test(s); | |||
| 3468 | stbi_rewind(s); | |||
| 3469 | return r; | |||
| 3470 | } | |||
| 3471 | ||||
| 3472 | static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 3473 | { | |||
| 3474 | int pixelCount; | |||
| 3475 | int channelCount, compression; | |||
| 3476 | int channel, i, count, len; | |||
| 3477 | int w,h; | |||
| 3478 | uint8 *out; | |||
| 3479 | ||||
| 3480 | // Check identifier | |||
| 3481 | if (get32(s) != 0x38425053) // "8BPS" | |||
| 3482 | return epuc("not PSD", "Corrupt PSD image")((unsigned char *) (e("not PSD")?((void*)0):((void*)0))); | |||
| 3483 | ||||
| 3484 | // Check file type version. | |||
| 3485 | if (get16(s) != 1) | |||
| 3486 | return epuc("wrong version", "Unsupported version of PSD image")((unsigned char *) (e("wrong version")?((void*)0):((void*)0)) ); | |||
| 3487 | ||||
| 3488 | // Skip 6 reserved bytes. | |||
| 3489 | skip(s, 6 ); | |||
| 3490 | ||||
| 3491 | // Read the number of channels (R, G, B, A, etc). | |||
| 3492 | channelCount = get16(s); | |||
| 3493 | if (channelCount < 0 || channelCount > 16) | |||
| 3494 | return epuc("wrong channel count", "Unsupported number of channels in PSD image")((unsigned char *) (e("wrong channel count")?((void*)0):((void *)0))); | |||
| 3495 | ||||
| 3496 | // Read the rows and columns of the image. | |||
| 3497 | h = get32(s); | |||
| 3498 | w = get32(s); | |||
| 3499 | ||||
| 3500 | // Make sure the depth is 8 bits. | |||
| 3501 | if (get16(s) != 8) | |||
| 3502 | return epuc("unsupported bit depth", "PSD bit depth is not 8 bit")((unsigned char *) (e("unsupported bit depth")?((void*)0):((void *)0))); | |||
| 3503 | ||||
| 3504 | // Make sure the color mode is RGB. | |||
| 3505 | // Valid options are: | |||
| 3506 | // 0: Bitmap | |||
| 3507 | // 1: Grayscale | |||
| 3508 | // 2: Indexed color | |||
| 3509 | // 3: RGB color | |||
| 3510 | // 4: CMYK color | |||
| 3511 | // 7: Multichannel | |||
| 3512 | // 8: Duotone | |||
| 3513 | // 9: Lab color | |||
| 3514 | if (get16(s) != 3) | |||
| 3515 | return epuc("wrong color format", "PSD is not in RGB color format")((unsigned char *) (e("wrong color format")?((void*)0):((void *)0))); | |||
| 3516 | ||||
| 3517 | // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) | |||
| 3518 | skip(s,get32(s) ); | |||
| 3519 | ||||
| 3520 | // Skip the image resources. (resolution, pen tool paths, etc) | |||
| 3521 | skip(s, get32(s) ); | |||
| 3522 | ||||
| 3523 | // Skip the reserved data. | |||
| 3524 | skip(s, get32(s) ); | |||
| 3525 | ||||
| 3526 | // Find out if the data is compressed. | |||
| 3527 | // Known values: | |||
| 3528 | // 0: no compression | |||
| 3529 | // 1: RLE compressed | |||
| 3530 | compression = get16(s); | |||
| 3531 | if (compression > 1) | |||
| 3532 | return epuc("bad compression", "PSD has an unknown compression format")((unsigned char *) (e("bad compression")?((void*)0):((void*)0 ))); | |||
| 3533 | ||||
| 3534 | // Create the destination image. | |||
| 3535 | out = (stbi_uc *) malloc(4 * w*h); | |||
| 3536 | if (!out) return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); | |||
| 3537 | pixelCount = w*h; | |||
| 3538 | ||||
| 3539 | // Initialize the data to zero. | |||
| 3540 | //memset( out, 0, pixelCount * 4 ); | |||
| 3541 | ||||
| 3542 | // Finally, the image data. | |||
| 3543 | if (compression) { | |||
| 3544 | // RLE as used by .PSD and .TIFF | |||
| 3545 | // Loop until you get the number of unpacked bytes you are expecting: | |||
| 3546 | // Read the next source byte into n. | |||
| 3547 | // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. | |||
| 3548 | // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. | |||
| 3549 | // Else if n is 128, noop. | |||
| 3550 | // Endloop | |||
| 3551 | ||||
| 3552 | // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, | |||
| 3553 | // which we're going to just skip. | |||
| 3554 | skip(s, h * channelCount * 2 ); | |||
| 3555 | ||||
| 3556 | // Read the RLE data by channel. | |||
| 3557 | for (channel = 0; channel < 4; channel++) { | |||
| 3558 | uint8 *p; | |||
| 3559 | ||||
| 3560 | p = out+channel; | |||
| 3561 | if (channel >= channelCount) { | |||
| 3562 | // Fill this channel with default data. | |||
| 3563 | for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; | |||
| 3564 | } else { | |||
| 3565 | // Read the RLE data. | |||
| 3566 | count = 0; | |||
| 3567 | while (count < pixelCount) { | |||
| 3568 | len = get8(s); | |||
| 3569 | if (len == 128) { | |||
| 3570 | // No-op. | |||
| 3571 | } else if (len < 128) { | |||
| 3572 | // Copy next len+1 bytes literally. | |||
| 3573 | len++; | |||
| 3574 | count += len; | |||
| 3575 | while (len) { | |||
| 3576 | *p = get8u(s); | |||
| 3577 | p += 4; | |||
| 3578 | len--; | |||
| 3579 | } | |||
| 3580 | } else if (len > 128) { | |||
| 3581 | uint8 val; | |||
| 3582 | // Next -len+1 bytes in the dest are replicated from next source byte. | |||
| 3583 | // (Interpret len as a negative 8-bit int.) | |||
| 3584 | len ^= 0x0FF; | |||
| 3585 | len += 2; | |||
| 3586 | val = get8u(s); | |||
| 3587 | count += len; | |||
| 3588 | while (len) { | |||
| 3589 | *p = val; | |||
| 3590 | p += 4; | |||
| 3591 | len--; | |||
| 3592 | } | |||
| 3593 | } | |||
| 3594 | } | |||
| 3595 | } | |||
| 3596 | } | |||
| 3597 | ||||
| 3598 | } else { | |||
| 3599 | // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) | |||
| 3600 | // where each channel consists of an 8-bit value for each pixel in the image. | |||
| 3601 | ||||
| 3602 | // Read the data by channel. | |||
| 3603 | for (channel = 0; channel < 4; channel++) { | |||
| 3604 | uint8 *p; | |||
| 3605 | ||||
| 3606 | p = out + channel; | |||
| 3607 | if (channel > channelCount) { | |||
| 3608 | // Fill this channel with default data. | |||
| 3609 | for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; | |||
| 3610 | } else { | |||
| 3611 | // Read the data. | |||
| 3612 | for (i = 0; i < pixelCount; i++) | |||
| 3613 | *p = get8u(s), p += 4; | |||
| 3614 | } | |||
| 3615 | } | |||
| 3616 | } | |||
| 3617 | ||||
| 3618 | if (req_comp && req_comp != 4) { | |||
| 3619 | out = convert_format(out, 4, req_comp, w, h); | |||
| 3620 | if (out == NULL((void*)0)) return out; // convert_format frees input on failure | |||
| 3621 | } | |||
| 3622 | ||||
| 3623 | if (comp) *comp = channelCount; | |||
| 3624 | *y = h; | |||
| 3625 | *x = w; | |||
| 3626 | ||||
| 3627 | return out; | |||
| 3628 | } | |||
| 3629 | ||||
| 3630 | static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 3631 | { | |||
| 3632 | return psd_load(s,x,y,comp,req_comp); | |||
| 3633 | } | |||
| 3634 | ||||
| 3635 | // ************************************************************************************************* | |||
| 3636 | // Softimage PIC loader | |||
| 3637 | // by Tom Seddon | |||
| 3638 | // | |||
| 3639 | // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format | |||
| 3640 | // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ | |||
| 3641 | ||||
| 3642 | static int pic_is4(stbi *s,const char *str) | |||
| 3643 | { | |||
| 3644 | int i; | |||
| 3645 | for (i=0; i<4; ++i) | |||
| 3646 | if (get8(s) != (stbi_uc)str[i]) | |||
| 3647 | return 0; | |||
| 3648 | ||||
| 3649 | return 1; | |||
| 3650 | } | |||
| 3651 | ||||
| 3652 | static int pic_test(stbi *s) | |||
| 3653 | { | |||
| 3654 | int i; | |||
| 3655 | ||||
| 3656 | if (!pic_is4(s,"\x53\x80\xF6\x34")) | |||
| 3657 | return 0; | |||
| 3658 | ||||
| 3659 | for(i=0;i<84;++i) | |||
| 3660 | get8(s); | |||
| 3661 | ||||
| 3662 | if (!pic_is4(s,"PICT")) | |||
| 3663 | return 0; | |||
| 3664 | ||||
| 3665 | return 1; | |||
| 3666 | } | |||
| 3667 | ||||
| 3668 | typedef struct | |||
| 3669 | { | |||
| 3670 | stbi_uc size,type,channel; | |||
| 3671 | } pic_packet_t; | |||
| 3672 | ||||
| 3673 | static stbi_uc *pic_readval(stbi *s, int channel, stbi_uc *dest) | |||
| 3674 | { | |||
| 3675 | int mask=0x80, i; | |||
| 3676 | ||||
| 3677 | for (i=0; i<4; ++i, mask>>=1) { | |||
| 3678 | if (channel & mask) { | |||
| 3679 | if (at_eof(s)) return epuc("bad file","PIC file too short")((unsigned char *) (e("bad file")?((void*)0):((void*)0))); | |||
| 3680 | dest[i]=get8u(s); | |||
| 3681 | } | |||
| 3682 | } | |||
| 3683 | ||||
| 3684 | return dest; | |||
| 3685 | } | |||
| 3686 | ||||
| 3687 | static void pic_copyval(int channel,stbi_uc *dest,const stbi_uc *src) | |||
| 3688 | { | |||
| 3689 | int mask=0x80,i; | |||
| 3690 | ||||
| 3691 | for (i=0;i<4; ++i, mask>>=1) | |||
| 3692 | if (channel&mask) | |||
| 3693 | dest[i]=src[i]; | |||
| 3694 | } | |||
| 3695 | ||||
| 3696 | static stbi_uc *pic_load2(stbi *s,int width,int height,int *comp, stbi_uc *result) | |||
| 3697 | { | |||
| 3698 | int act_comp=0,num_packets=0,y,chained; | |||
| 3699 | pic_packet_t packets[10]; | |||
| 3700 | ||||
| 3701 | // this will (should...) cater for even some bizarre stuff like having data | |||
| 3702 | // for the same channel in multiple packets. | |||
| 3703 | do { | |||
| 3704 | pic_packet_t *packet; | |||
| 3705 | ||||
| 3706 | if (num_packets==sizeof(packets)/sizeof(packets[0])) | |||
| 3707 | return epuc("bad format","too many packets")((unsigned char *) (e("bad format")?((void*)0):((void*)0))); | |||
| 3708 | ||||
| 3709 | packet = &packets[num_packets++]; | |||
| 3710 | ||||
| 3711 | chained = get8(s); | |||
| 3712 | packet->size = get8u(s); | |||
| 3713 | packet->type = get8u(s); | |||
| 3714 | packet->channel = get8u(s); | |||
| 3715 | ||||
| 3716 | act_comp |= packet->channel; | |||
| 3717 | ||||
| 3718 | if (at_eof(s)) return epuc("bad file","file too short (reading packets)")((unsigned char *) (e("bad file")?((void*)0):((void*)0))); | |||
| 3719 | if (packet->size != 8) return epuc("bad format","packet isn't 8bpp")((unsigned char *) (e("bad format")?((void*)0):((void*)0))); | |||
| 3720 | } while (chained); | |||
| 3721 | ||||
| 3722 | *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? | |||
| 3723 | ||||
| 3724 | for(y=0; y<height; ++y) { | |||
| 3725 | int packet_idx; | |||
| 3726 | ||||
| 3727 | for(packet_idx=0; packet_idx < num_packets; ++packet_idx) { | |||
| 3728 | pic_packet_t *packet = &packets[packet_idx]; | |||
| 3729 | stbi_uc *dest = result+y*width*4; | |||
| 3730 | ||||
| 3731 | switch (packet->type) { | |||
| 3732 | default: | |||
| 3733 | return epuc("bad format","packet has bad compression type")((unsigned char *) (e("bad format")?((void*)0):((void*)0))); | |||
| 3734 | ||||
| 3735 | case 0: {//uncompressed | |||
| 3736 | int x; | |||
| 3737 | ||||
| 3738 | for(x=0;x<width;++x, dest+=4) | |||
| 3739 | if (!pic_readval(s,packet->channel,dest)) | |||
| 3740 | return 0; | |||
| 3741 | break; | |||
| 3742 | } | |||
| 3743 | ||||
| 3744 | case 1://Pure RLE | |||
| 3745 | { | |||
| 3746 | int left=width, i; | |||
| 3747 | ||||
| 3748 | while (left>0) { | |||
| 3749 | stbi_uc count,value[4]; | |||
| 3750 | ||||
| 3751 | count=get8u(s); | |||
| 3752 | if (at_eof(s)) return epuc("bad file","file too short (pure read count)")((unsigned char *) (e("bad file")?((void*)0):((void*)0))); | |||
| 3753 | ||||
| 3754 | if (count > left) | |||
| 3755 | count = (uint8) left; | |||
| 3756 | ||||
| 3757 | if (!pic_readval(s,packet->channel,value)) return 0; | |||
| 3758 | ||||
| 3759 | for(i=0; i<count; ++i,dest+=4) | |||
| 3760 | pic_copyval(packet->channel,dest,value); | |||
| 3761 | left -= count; | |||
| 3762 | } | |||
| 3763 | } | |||
| 3764 | break; | |||
| 3765 | ||||
| 3766 | case 2: {//Mixed RLE | |||
| 3767 | int left=width; | |||
| 3768 | while (left>0) { | |||
| 3769 | int count = get8(s), i; | |||
| 3770 | if (at_eof(s)) return epuc("bad file","file too short (mixed read count)")((unsigned char *) (e("bad file")?((void*)0):((void*)0))); | |||
| 3771 | ||||
| 3772 | if (count >= 128) { // Repeated | |||
| 3773 | stbi_uc value[4]; | |||
| 3774 | int i; | |||
| 3775 | ||||
| 3776 | if (count==128) | |||
| 3777 | count = get16(s); | |||
| 3778 | else | |||
| 3779 | count -= 127; | |||
| 3780 | if (count > left) | |||
| 3781 | return epuc("bad file","scanline overrun")((unsigned char *) (e("bad file")?((void*)0):((void*)0))); | |||
| 3782 | ||||
| 3783 | if (!pic_readval(s,packet->channel,value)) | |||
| 3784 | return 0; | |||
| 3785 | ||||
| 3786 | for(i=0;i<count;++i, dest += 4) | |||
| 3787 | pic_copyval(packet->channel,dest,value); | |||
| 3788 | } else { // Raw | |||
| 3789 | ++count; | |||
| 3790 | if (count>left) return epuc("bad file","scanline overrun")((unsigned char *) (e("bad file")?((void*)0):((void*)0))); | |||
| 3791 | ||||
| 3792 | for(i=0;i<count;++i, dest+=4) | |||
| 3793 | if (!pic_readval(s,packet->channel,dest)) | |||
| 3794 | return 0; | |||
| 3795 | } | |||
| 3796 | left-=count; | |||
| 3797 | } | |||
| 3798 | break; | |||
| 3799 | } | |||
| 3800 | } | |||
| 3801 | } | |||
| 3802 | } | |||
| 3803 | ||||
| 3804 | return result; | |||
| 3805 | } | |||
| 3806 | ||||
| 3807 | static stbi_uc *pic_load(stbi *s,int *px,int *py,int *comp,int req_comp) | |||
| 3808 | { | |||
| 3809 | stbi_uc *result; | |||
| 3810 | int i, x,y; | |||
| 3811 | ||||
| 3812 | for (i=0; i<92; ++i) | |||
| 3813 | get8(s); | |||
| 3814 | ||||
| 3815 | x = get16(s); | |||
| 3816 | y = get16(s); | |||
| 3817 | if (at_eof(s)) return epuc("bad file","file too short (pic header)")((unsigned char *) (e("bad file")?((void*)0):((void*)0))); | |||
| 3818 | if ((1 << 28) / x < y) return epuc("too large", "Image too large to decode")((unsigned char *) (e("too large")?((void*)0):((void*)0))); | |||
| 3819 | ||||
| 3820 | get32(s); //skip `ratio' | |||
| 3821 | get16(s); //skip `fields' | |||
| 3822 | get16(s); //skip `pad' | |||
| 3823 | ||||
| 3824 | // intermediate buffer is RGBA | |||
| 3825 | result = (stbi_uc *) malloc(x*y*4); | |||
| 3826 | memset(result, 0xff, x*y*4); | |||
| 3827 | ||||
| 3828 | if (!pic_load2(s,x,y,comp, result)) { | |||
| 3829 | free(result); | |||
| 3830 | result=0; | |||
| 3831 | } | |||
| 3832 | *px = x; | |||
| 3833 | *py = y; | |||
| 3834 | if (req_comp == 0) req_comp = *comp; | |||
| 3835 | result=convert_format(result,4,req_comp,x,y); | |||
| 3836 | ||||
| 3837 | return result; | |||
| 3838 | } | |||
| 3839 | ||||
| 3840 | static int stbi_pic_test(stbi *s) | |||
| 3841 | { | |||
| 3842 | int r = pic_test(s); | |||
| 3843 | stbi_rewind(s); | |||
| 3844 | return r; | |||
| 3845 | } | |||
| 3846 | ||||
| 3847 | static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 3848 | { | |||
| 3849 | return pic_load(s,x,y,comp,req_comp); | |||
| 3850 | } | |||
| 3851 | ||||
| 3852 | // ************************************************************************************************* | |||
| 3853 | // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb | |||
| 3854 | typedef struct stbi_gif_lzw_struct { | |||
| 3855 | int16 prefix; | |||
| 3856 | uint8 first; | |||
| 3857 | uint8 suffix; | |||
| 3858 | } stbi_gif_lzw; | |||
| 3859 | ||||
| 3860 | typedef struct stbi_gif_struct | |||
| 3861 | { | |||
| 3862 | int w,h; | |||
| 3863 | stbi_uc *out; // output buffer (always 4 components) | |||
| 3864 | int flags, bgindex, ratio, transparent, eflags; | |||
| 3865 | uint8 pal[256][4]; | |||
| 3866 | uint8 lpal[256][4]; | |||
| 3867 | stbi_gif_lzw codes[4096]; | |||
| 3868 | uint8 *color_table; | |||
| 3869 | int parse, step; | |||
| 3870 | int lflags; | |||
| 3871 | int start_x, start_y; | |||
| 3872 | int max_x, max_y; | |||
| 3873 | int cur_x, cur_y; | |||
| 3874 | int line_size; | |||
| 3875 | } stbi_gif; | |||
| 3876 | ||||
| 3877 | static int gif_test(stbi *s) | |||
| 3878 | { | |||
| 3879 | int sz; | |||
| 3880 | if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') return 0; | |||
| 3881 | sz = get8(s); | |||
| 3882 | if (sz != '9' && sz != '7') return 0; | |||
| 3883 | if (get8(s) != 'a') return 0; | |||
| 3884 | return 1; | |||
| 3885 | } | |||
| 3886 | ||||
| 3887 | static int stbi_gif_test(stbi *s) | |||
| 3888 | { | |||
| 3889 | int r = gif_test(s); | |||
| 3890 | stbi_rewind(s); | |||
| 3891 | return r; | |||
| 3892 | } | |||
| 3893 | ||||
| 3894 | static void stbi_gif_parse_colortable(stbi *s, uint8 pal[256][4], int num_entries, int transp) | |||
| 3895 | { | |||
| 3896 | int i; | |||
| 3897 | for (i=0; i < num_entries; ++i) { | |||
| 3898 | pal[i][2] = get8u(s); | |||
| 3899 | pal[i][1] = get8u(s); | |||
| 3900 | pal[i][0] = get8u(s); | |||
| 3901 | pal[i][3] = transp ? 0 : 255; | |||
| 3902 | } | |||
| 3903 | } | |||
| 3904 | ||||
| 3905 | static int stbi_gif_header(stbi *s, stbi_gif *g, int *comp, int is_info) | |||
| 3906 | { | |||
| 3907 | uint8 version; | |||
| 3908 | if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') | |||
| 3909 | return e("not GIF", "Corrupt GIF")e("not GIF"); | |||
| 3910 | ||||
| 3911 | version = get8u(s); | |||
| 3912 | if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF")e("not GIF"); | |||
| 3913 | if (get8(s) != 'a') return e("not GIF", "Corrupt GIF")e("not GIF"); | |||
| 3914 | ||||
| 3915 | failure_reason = ""; | |||
| 3916 | g->w = get16le(s); | |||
| 3917 | g->h = get16le(s); | |||
| 3918 | g->flags = get8(s); | |||
| 3919 | g->bgindex = get8(s); | |||
| 3920 | g->ratio = get8(s); | |||
| 3921 | g->transparent = -1; | |||
| 3922 | ||||
| 3923 | if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments | |||
| 3924 | ||||
| 3925 | if (is_info) return 1; | |||
| 3926 | ||||
| 3927 | if (g->flags & 0x80) | |||
| 3928 | stbi_gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); | |||
| 3929 | ||||
| 3930 | return 1; | |||
| 3931 | } | |||
| 3932 | ||||
| 3933 | static int stbi_gif_info_raw(stbi *s, int *x, int *y, int *comp) | |||
| 3934 | { | |||
| 3935 | stbi_gif g; | |||
| 3936 | if (!stbi_gif_header(s, &g, comp, 1)) { | |||
| 3937 | stbi_rewind( s ); | |||
| 3938 | return 0; | |||
| 3939 | } | |||
| 3940 | if (x) *x = g.w; | |||
| 3941 | if (y) *y = g.h; | |||
| 3942 | return 1; | |||
| 3943 | } | |||
| 3944 | ||||
| 3945 | static void stbi_out_gif_code(stbi_gif *g, uint16 code) | |||
| 3946 | { | |||
| 3947 | uint8 *p, *c; | |||
| 3948 | ||||
| 3949 | // recurse to decode the prefixes, since the linked-list is backwards, | |||
| 3950 | // and working backwards through an interleaved image would be nasty | |||
| 3951 | if (g->codes[code].prefix >= 0) | |||
| 3952 | stbi_out_gif_code(g, g->codes[code].prefix); | |||
| 3953 | ||||
| 3954 | if (g->cur_y >= g->max_y) return; | |||
| 3955 | ||||
| 3956 | p = &g->out[g->cur_x + g->cur_y]; | |||
| 3957 | c = &g->color_table[g->codes[code].suffix * 4]; | |||
| 3958 | ||||
| 3959 | if (c[3] >= 128) { | |||
| 3960 | p[0] = c[2]; | |||
| 3961 | p[1] = c[1]; | |||
| 3962 | p[2] = c[0]; | |||
| 3963 | p[3] = c[3]; | |||
| 3964 | } | |||
| 3965 | g->cur_x += 4; | |||
| 3966 | ||||
| 3967 | if (g->cur_x >= g->max_x) { | |||
| 3968 | g->cur_x = g->start_x; | |||
| 3969 | g->cur_y += g->step; | |||
| 3970 | ||||
| 3971 | while (g->cur_y >= g->max_y && g->parse > 0) { | |||
| 3972 | g->step = (1 << g->parse) * g->line_size; | |||
| 3973 | g->cur_y = g->start_y + (g->step >> 1); | |||
| 3974 | --g->parse; | |||
| 3975 | } | |||
| 3976 | } | |||
| 3977 | } | |||
| 3978 | ||||
| 3979 | static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g) | |||
| 3980 | { | |||
| 3981 | uint8 lzw_cs; | |||
| 3982 | int32 len, code; | |||
| 3983 | uint32 first; | |||
| 3984 | int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; | |||
| 3985 | stbi_gif_lzw *p; | |||
| 3986 | ||||
| 3987 | lzw_cs = get8u(s); | |||
| 3988 | clear = 1 << lzw_cs; | |||
| 3989 | first = 1; | |||
| 3990 | codesize = lzw_cs + 1; | |||
| 3991 | codemask = (1 << codesize) - 1; | |||
| 3992 | bits = 0; | |||
| 3993 | valid_bits = 0; | |||
| 3994 | for (code = 0; code < clear; code++) { | |||
| 3995 | g->codes[code].prefix = -1; | |||
| 3996 | g->codes[code].first = (uint8) code; | |||
| 3997 | g->codes[code].suffix = (uint8) code; | |||
| 3998 | } | |||
| 3999 | ||||
| 4000 | // support no starting clear code | |||
| 4001 | avail = clear+2; | |||
| 4002 | oldcode = -1; | |||
| 4003 | ||||
| 4004 | len = 0; | |||
| 4005 | for(;;) { | |||
| 4006 | if (valid_bits < codesize) { | |||
| 4007 | if (len == 0) { | |||
| 4008 | len = get8(s); // start new block | |||
| 4009 | if (len == 0) | |||
| 4010 | return g->out; | |||
| 4011 | } | |||
| 4012 | --len; | |||
| 4013 | bits |= (int32) get8(s) << valid_bits; | |||
| 4014 | valid_bits += 8; | |||
| 4015 | } else { | |||
| 4016 | int32 code = bits & codemask; | |||
| 4017 | bits >>= codesize; | |||
| 4018 | valid_bits -= codesize; | |||
| 4019 | // @OPTIMIZE: is there some way we can accelerate the non-clear path? | |||
| 4020 | if (code == clear) { // clear code | |||
| 4021 | codesize = lzw_cs + 1; | |||
| 4022 | codemask = (1 << codesize) - 1; | |||
| 4023 | avail = clear + 2; | |||
| 4024 | oldcode = -1; | |||
| 4025 | first = 0; | |||
| 4026 | } else if (code == clear + 1) { // end of stream code | |||
| 4027 | skip(s, len); | |||
| 4028 | while ((len = get8(s)) > 0) | |||
| 4029 | skip(s,len); | |||
| 4030 | return g->out; | |||
| 4031 | } else if (code <= avail) { | |||
| 4032 | if (first) return epuc("no clear code", "Corrupt GIF")((unsigned char *) (e("no clear code")?((void*)0):((void*)0)) ); | |||
| 4033 | ||||
| 4034 | if (oldcode >= 0) { | |||
| 4035 | p = &g->codes[avail++]; | |||
| 4036 | if (avail > 4096) return epuc("too many codes", "Corrupt GIF")((unsigned char *) (e("too many codes")?((void*)0):((void*)0) )); | |||
| 4037 | p->prefix = (int16) oldcode; | |||
| 4038 | p->first = g->codes[oldcode].first; | |||
| 4039 | p->suffix = (code == avail) ? p->first : g->codes[code].first; | |||
| 4040 | } else if (code == avail) | |||
| 4041 | return epuc("illegal code in raster", "Corrupt GIF")((unsigned char *) (e("illegal code in raster")?((void*)0):(( void*)0))); | |||
| 4042 | ||||
| 4043 | stbi_out_gif_code(g, (uint16) code); | |||
| 4044 | ||||
| 4045 | if ((avail & codemask) == 0 && avail <= 0x0FFF) { | |||
| 4046 | codesize++; | |||
| 4047 | codemask = (1 << codesize) - 1; | |||
| 4048 | } | |||
| 4049 | ||||
| 4050 | oldcode = code; | |||
| 4051 | } else { | |||
| 4052 | return epuc("illegal code in raster", "Corrupt GIF")((unsigned char *) (e("illegal code in raster")?((void*)0):(( void*)0))); | |||
| 4053 | } | |||
| 4054 | } | |||
| 4055 | } | |||
| 4056 | } | |||
| 4057 | ||||
| 4058 | static void stbi_fill_gif_background(stbi_gif *g) | |||
| 4059 | { | |||
| 4060 | int i; | |||
| 4061 | uint8 *c = g->pal[g->bgindex]; | |||
| 4062 | // @OPTIMIZE: write a dword at a time | |||
| 4063 | for (i = 0; i < g->w * g->h * 4; i += 4) { | |||
| 4064 | uint8 *p = &g->out[i]; | |||
| 4065 | p[0] = c[2]; | |||
| 4066 | p[1] = c[1]; | |||
| 4067 | p[2] = c[0]; | |||
| 4068 | p[3] = c[3]; | |||
| 4069 | } | |||
| 4070 | } | |||
| 4071 | ||||
| 4072 | // this function is designed to support animated gifs, although stb_image doesn't support it | |||
| 4073 | static uint8 *stbi_gif_load_next(stbi *s, stbi_gif *g, int *comp, int req_comp) | |||
| 4074 | { | |||
| 4075 | int i; | |||
| 4076 | uint8 *old_out = 0; | |||
| 4077 | ||||
| 4078 | if (g->out == 0) { | |||
| 4079 | if (!stbi_gif_header(s, g, comp,0)) return 0; // failure_reason set by stbi_gif_header | |||
| 4080 | g->out = (uint8 *) malloc(4 * g->w * g->h); | |||
| 4081 | if (g->out == 0) return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); | |||
| 4082 | stbi_fill_gif_background(g); | |||
| 4083 | } else { | |||
| 4084 | // animated-gif-only path | |||
| 4085 | if (((g->eflags & 0x1C) >> 2) == 3) { | |||
| 4086 | old_out = g->out; | |||
| 4087 | g->out = (uint8 *) malloc(4 * g->w * g->h); | |||
| 4088 | if (g->out == 0) return epuc("outofmem", "Out of memory")((unsigned char *) (e("outofmem")?((void*)0):((void*)0))); | |||
| 4089 | memcpy(g->out, old_out, g->w*g->h*4); | |||
| 4090 | } | |||
| 4091 | } | |||
| 4092 | ||||
| 4093 | for (;;) { | |||
| 4094 | switch (get8(s)) { | |||
| 4095 | case 0x2C: /* Image Descriptor */ | |||
| 4096 | { | |||
| 4097 | int32 x, y, w, h; | |||
| 4098 | uint8 *o; | |||
| 4099 | ||||
| 4100 | x = get16le(s); | |||
| 4101 | y = get16le(s); | |||
| 4102 | w = get16le(s); | |||
| 4103 | h = get16le(s); | |||
| 4104 | if (((x + w) > (g->w)) || ((y + h) > (g->h))) | |||
| 4105 | return epuc("bad Image Descriptor", "Corrupt GIF")((unsigned char *) (e("bad Image Descriptor")?((void*)0):((void *)0))); | |||
| 4106 | ||||
| 4107 | g->line_size = g->w * 4; | |||
| 4108 | g->start_x = x * 4; | |||
| 4109 | g->start_y = y * g->line_size; | |||
| 4110 | g->max_x = g->start_x + w * 4; | |||
| 4111 | g->max_y = g->start_y + h * g->line_size; | |||
| 4112 | g->cur_x = g->start_x; | |||
| 4113 | g->cur_y = g->start_y; | |||
| 4114 | ||||
| 4115 | g->lflags = get8(s); | |||
| 4116 | ||||
| 4117 | if (g->lflags & 0x40) { | |||
| 4118 | g->step = 8 * g->line_size; // first interlaced spacing | |||
| 4119 | g->parse = 3; | |||
| 4120 | } else { | |||
| 4121 | g->step = g->line_size; | |||
| 4122 | g->parse = 0; | |||
| 4123 | } | |||
| 4124 | ||||
| 4125 | if (g->lflags & 0x80) { | |||
| 4126 | stbi_gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); | |||
| 4127 | g->color_table = (uint8 *) g->lpal; | |||
| 4128 | } else if (g->flags & 0x80) { | |||
| 4129 | for (i=0; i < 256; ++i) // @OPTIMIZE: reset only the previous transparent | |||
| 4130 | g->pal[i][3] = 255; | |||
| 4131 | if (g->transparent >= 0 && (g->eflags & 0x01)) | |||
| 4132 | g->pal[g->transparent][3] = 0; | |||
| 4133 | g->color_table = (uint8 *) g->pal; | |||
| 4134 | } else | |||
| 4135 | return epuc("missing color table", "Corrupt GIF")((unsigned char *) (e("missing color table")?((void*)0):((void *)0))); | |||
| 4136 | ||||
| 4137 | o = stbi_process_gif_raster(s, g); | |||
| 4138 | if (o == NULL((void*)0)) return NULL((void*)0); | |||
| 4139 | ||||
| 4140 | if (req_comp && req_comp != 4) | |||
| 4141 | o = convert_format(o, 4, req_comp, g->w, g->h); | |||
| 4142 | return o; | |||
| 4143 | } | |||
| 4144 | ||||
| 4145 | case 0x21: // Comment Extension. | |||
| 4146 | { | |||
| 4147 | int len; | |||
| 4148 | if (get8(s) == 0xF9) { // Graphic Control Extension. | |||
| 4149 | len = get8(s); | |||
| 4150 | if (len == 4) { | |||
| 4151 | g->eflags = get8(s); | |||
| 4152 | get16le(s); // delay | |||
| 4153 | g->transparent = get8(s); | |||
| 4154 | } else { | |||
| 4155 | skip(s, len); | |||
| 4156 | break; | |||
| 4157 | } | |||
| 4158 | } | |||
| 4159 | while ((len = get8(s)) != 0) | |||
| 4160 | skip(s, len); | |||
| 4161 | break; | |||
| 4162 | } | |||
| 4163 | ||||
| 4164 | case 0x3B: // gif stream termination code | |||
| 4165 | return (uint8 *) 1; | |||
| 4166 | ||||
| 4167 | default: | |||
| 4168 | return epuc("unknown code", "Corrupt GIF")((unsigned char *) (e("unknown code")?((void*)0):((void*)0))); | |||
| 4169 | } | |||
| 4170 | } | |||
| 4171 | } | |||
| 4172 | ||||
| 4173 | static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 4174 | { | |||
| 4175 | uint8 *u = 0; | |||
| 4176 | stbi_gif g={0}; | |||
| 4177 | ||||
| 4178 | u = stbi_gif_load_next(s, &g, comp, req_comp); | |||
| 4179 | if (u == (void *) 1) u = 0; // end of animated gif marker | |||
| 4180 | if (u) { | |||
| 4181 | *x = g.w; | |||
| 4182 | *y = g.h; | |||
| 4183 | } | |||
| 4184 | ||||
| 4185 | return u; | |||
| 4186 | } | |||
| 4187 | ||||
| 4188 | static int stbi_gif_info(stbi *s, int *x, int *y, int *comp) | |||
| 4189 | { | |||
| 4190 | return stbi_gif_info_raw(s,x,y,comp); | |||
| 4191 | } | |||
| 4192 | ||||
| 4193 | ||||
| 4194 | // ************************************************************************************************* | |||
| 4195 | // Radiance RGBE HDR loader | |||
| 4196 | // originally by Nicolas Schulz | |||
| 4197 | #ifndef STBI_NO_HDR | |||
| 4198 | static int hdr_test(stbi *s) | |||
| 4199 | { | |||
| 4200 | const char *signature = "#?RADIANCE\n"; | |||
| 4201 | int i; | |||
| 4202 | for (i=0; signature[i]; ++i) | |||
| 4203 | if (get8(s) != signature[i]) | |||
| 4204 | return 0; | |||
| 4205 | return 1; | |||
| 4206 | } | |||
| 4207 | ||||
| 4208 | static int stbi_hdr_test(stbi* s) | |||
| 4209 | { | |||
| 4210 | int r = hdr_test(s); | |||
| 4211 | stbi_rewind(s); | |||
| 4212 | return r; | |||
| 4213 | } | |||
| 4214 | ||||
| 4215 | #define HDR_BUFLEN1024 1024 | |||
| 4216 | static char *hdr_gettoken(stbi *z, char *buffer) | |||
| 4217 | { | |||
| 4218 | int len=0; | |||
| 4219 | char c = '\0'; | |||
| 4220 | ||||
| 4221 | c = (char) get8(z); | |||
| 4222 | ||||
| 4223 | while (!at_eof(z) && c != '\n') { | |||
| 4224 | buffer[len++] = c; | |||
| 4225 | if (len == HDR_BUFLEN1024-1) { | |||
| 4226 | // flush to end of line | |||
| 4227 | while (!at_eof(z) && get8(z) != '\n') | |||
| 4228 | ; | |||
| 4229 | break; | |||
| 4230 | } | |||
| 4231 | c = (char) get8(z); | |||
| 4232 | } | |||
| 4233 | ||||
| 4234 | buffer[len] = 0; | |||
| 4235 | return buffer; | |||
| 4236 | } | |||
| 4237 | ||||
| 4238 | static void hdr_convert(float *output, stbi_uc *input, int req_comp) | |||
| 4239 | { | |||
| 4240 | if ( input[3] != 0 ) { | |||
| 4241 | float f1; | |||
| 4242 | // Exponent | |||
| 4243 | f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); | |||
| 4244 | if (req_comp <= 2) | |||
| 4245 | output[0] = (input[0] + input[1] + input[2]) * f1 / 3; | |||
| 4246 | else { | |||
| 4247 | output[0] = input[0] * f1; | |||
| 4248 | output[1] = input[1] * f1; | |||
| 4249 | output[2] = input[2] * f1; | |||
| 4250 | } | |||
| 4251 | if (req_comp == 2) output[1] = 1; | |||
| 4252 | if (req_comp == 4) output[3] = 1; | |||
| 4253 | } else { | |||
| 4254 | switch (req_comp) { | |||
| 4255 | case 4: output[3] = 1; /* fallthrough */ | |||
| 4256 | case 3: output[0] = output[1] = output[2] = 0; | |||
| 4257 | break; | |||
| 4258 | case 2: output[1] = 1; /* fallthrough */ | |||
| 4259 | case 1: output[0] = 0; | |||
| 4260 | break; | |||
| 4261 | } | |||
| 4262 | } | |||
| 4263 | } | |||
| 4264 | ||||
| 4265 | static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 4266 | { | |||
| 4267 | char buffer[HDR_BUFLEN1024]; | |||
| 4268 | char *token; | |||
| 4269 | int valid = 0; | |||
| 4270 | int width, height; | |||
| 4271 | stbi_uc *scanline; | |||
| 4272 | float *hdr_data; | |||
| 4273 | int len; | |||
| 4274 | unsigned char count, value; | |||
| 4275 | int i, j, k, c1,c2, z; | |||
| 4276 | ||||
| 4277 | ||||
| 4278 | // Check identifier | |||
| 4279 | if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) | |||
| 4280 | return epf("not HDR", "Corrupt HDR image")((float *) (e("not HDR")?((void*)0):((void*)0))); | |||
| 4281 | ||||
| 4282 | // Parse header | |||
| 4283 | for(;;) { | |||
| 4284 | token = hdr_gettoken(s,buffer); | |||
| 4285 | if (token[0] == 0) break; | |||
| 4286 | if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; | |||
| 4287 | } | |||
| 4288 | ||||
| 4289 | if (!valid) return epf("unsupported format", "Unsupported HDR format")((float *) (e("unsupported format")?((void*)0):((void*)0))); | |||
| 4290 | ||||
| 4291 | // Parse width and height | |||
| 4292 | // can't use sscanf() if we're not using stdio! | |||
| 4293 | token = hdr_gettoken(s,buffer); | |||
| 4294 | if (strncmp(token, "-Y ", 3)) return epf("unsupported data layout", "Unsupported HDR format")((float *) (e("unsupported data layout")?((void*)0):((void*)0 ))); | |||
| 4295 | token += 3; | |||
| 4296 | height = strtol(token, &token, 10); | |||
| 4297 | while (*token == ' ') ++token; | |||
| 4298 | if (strncmp(token, "+X ", 3)) return epf("unsupported data layout", "Unsupported HDR format")((float *) (e("unsupported data layout")?((void*)0):((void*)0 ))); | |||
| 4299 | token += 3; | |||
| 4300 | width = strtol(token, NULL((void*)0), 10); | |||
| 4301 | ||||
| 4302 | *x = width; | |||
| 4303 | *y = height; | |||
| 4304 | ||||
| 4305 | *comp = 3; | |||
| 4306 | if (req_comp == 0) req_comp = 3; | |||
| 4307 | ||||
| 4308 | // Read data | |||
| 4309 | hdr_data = (float *) malloc(height * width * req_comp * sizeof(float)); | |||
| 4310 | ||||
| 4311 | // Load image data | |||
| 4312 | // image data is stored as some number of sca | |||
| 4313 | if ( width < 8 || width >= 32768) { | |||
| 4314 | // Read flat data | |||
| 4315 | for (j=0; j < height; ++j) { | |||
| 4316 | for (i=0; i < width; ++i) { | |||
| 4317 | stbi_uc rgbe[4]; | |||
| 4318 | main_decode_loop: | |||
| 4319 | getn(s, rgbe, 4); | |||
| 4320 | hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); | |||
| 4321 | } | |||
| 4322 | } | |||
| 4323 | } else { | |||
| 4324 | // Read RLE-encoded data | |||
| 4325 | scanline = NULL((void*)0); | |||
| 4326 | ||||
| 4327 | for (j = 0; j < height; ++j) { | |||
| 4328 | c1 = get8(s); | |||
| 4329 | c2 = get8(s); | |||
| 4330 | len = get8(s); | |||
| 4331 | if (c1 != 2 || c2 != 2 || (len & 0x80)) { | |||
| 4332 | // not run-length encoded, so we have to actually use THIS data as a decoded | |||
| 4333 | // pixel (note this can't be a valid pixel--one of RGB must be >= 128) | |||
| 4334 | uint8 rgbe[4]; | |||
| 4335 | rgbe[0] = (uint8) c1; | |||
| 4336 | rgbe[1] = (uint8) c2; | |||
| 4337 | rgbe[2] = (uint8) len; | |||
| 4338 | rgbe[3] = (uint8) get8u(s); | |||
| 4339 | hdr_convert(hdr_data, rgbe, req_comp); | |||
| 4340 | i = 1; | |||
| 4341 | j = 0; | |||
| 4342 | free(scanline); | |||
| 4343 | goto main_decode_loop; // yes, this makes no sense | |||
| 4344 | } | |||
| 4345 | len <<= 8; | |||
| 4346 | len |= get8(s); | |||
| 4347 | if (len != width) { free(hdr_data); free(scanline); return epf("invalid decoded scanline length", "corrupt HDR")((float *) (e("invalid decoded scanline length")?((void*)0):( (void*)0))); } | |||
| 4348 | if (scanline == NULL((void*)0)) scanline = (stbi_uc *) malloc(width * 4); | |||
| 4349 | ||||
| 4350 | for (k = 0; k < 4; ++k) { | |||
| 4351 | i = 0; | |||
| 4352 | while (i < width) { | |||
| 4353 | count = get8u(s); | |||
| 4354 | if (count > 128) { | |||
| 4355 | // Run | |||
| 4356 | value = get8u(s); | |||
| 4357 | count -= 128; | |||
| 4358 | for (z = 0; z < count; ++z) | |||
| 4359 | scanline[i++ * 4 + k] = value; | |||
| 4360 | } else { | |||
| 4361 | // Dump | |||
| 4362 | for (z = 0; z < count; ++z) | |||
| 4363 | scanline[i++ * 4 + k] = get8u(s); | |||
| 4364 | } | |||
| 4365 | } | |||
| 4366 | } | |||
| 4367 | for (i=0; i < width; ++i) | |||
| 4368 | hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); | |||
| 4369 | } | |||
| 4370 | free(scanline); | |||
| 4371 | } | |||
| 4372 | ||||
| 4373 | return hdr_data; | |||
| 4374 | } | |||
| 4375 | ||||
| 4376 | static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) | |||
| 4377 | { | |||
| 4378 | return hdr_load(s,x,y,comp,req_comp); | |||
| 4379 | } | |||
| 4380 | ||||
| 4381 | static int stbi_hdr_info(stbi *s, int *x, int *y, int *comp) | |||
| 4382 | { | |||
| 4383 | char buffer[HDR_BUFLEN1024]; | |||
| 4384 | char *token; | |||
| 4385 | int valid = 0; | |||
| 4386 | ||||
| 4387 | if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) { | |||
| 4388 | stbi_rewind( s ); | |||
| 4389 | return 0; | |||
| 4390 | } | |||
| 4391 | ||||
| 4392 | for(;;) { | |||
| 4393 | token = hdr_gettoken(s,buffer); | |||
| 4394 | if (token[0] == 0) break; | |||
| 4395 | if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; | |||
| 4396 | } | |||
| 4397 | ||||
| 4398 | if (!valid) { | |||
| 4399 | stbi_rewind( s ); | |||
| 4400 | return 0; | |||
| 4401 | } | |||
| 4402 | token = hdr_gettoken(s,buffer); | |||
| 4403 | if (strncmp(token, "-Y ", 3)) { | |||
| 4404 | stbi_rewind( s ); | |||
| 4405 | return 0; | |||
| 4406 | } | |||
| 4407 | token += 3; | |||
| 4408 | *y = strtol(token, &token, 10); | |||
| 4409 | while (*token == ' ') ++token; | |||
| 4410 | if (strncmp(token, "+X ", 3)) { | |||
| 4411 | stbi_rewind( s ); | |||
| 4412 | return 0; | |||
| 4413 | } | |||
| 4414 | token += 3; | |||
| 4415 | *x = strtol(token, NULL((void*)0), 10); | |||
| 4416 | *comp = 3; | |||
| 4417 | return 1; | |||
| 4418 | } | |||
| 4419 | #endif // STBI_NO_HDR | |||
| 4420 | ||||
| 4421 | static int stbi_bmp_info(stbi *s, int *x, int *y, int *comp) | |||
| 4422 | { | |||
| 4423 | int hsz; | |||
| 4424 | if (get8(s) != 'B' || get8(s) != 'M') { | |||
| 4425 | stbi_rewind( s ); | |||
| 4426 | return 0; | |||
| 4427 | } | |||
| 4428 | skip(s,12); | |||
| 4429 | hsz = get32le(s); | |||
| 4430 | if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) { | |||
| 4431 | stbi_rewind( s ); | |||
| 4432 | return 0; | |||
| 4433 | } | |||
| 4434 | if (hsz == 12) { | |||
| 4435 | *x = get16le(s); | |||
| 4436 | *y = get16le(s); | |||
| 4437 | } else { | |||
| 4438 | *x = get32le(s); | |||
| 4439 | *y = get32le(s); | |||
| 4440 | } | |||
| 4441 | if (get16le(s) != 1) { | |||
| 4442 | stbi_rewind( s ); | |||
| 4443 | return 0; | |||
| 4444 | } | |||
| 4445 | *comp = get16le(s) / 8; | |||
| 4446 | return 1; | |||
| 4447 | } | |||
| 4448 | ||||
| 4449 | static int stbi_psd_info(stbi *s, int *x, int *y, int *comp) | |||
| 4450 | { | |||
| 4451 | int channelCount; | |||
| 4452 | if (get32(s) != 0x38425053) { | |||
| 4453 | stbi_rewind( s ); | |||
| 4454 | return 0; | |||
| 4455 | } | |||
| 4456 | if (get16(s) != 1) { | |||
| 4457 | stbi_rewind( s ); | |||
| 4458 | return 0; | |||
| 4459 | } | |||
| 4460 | skip(s, 6); | |||
| 4461 | channelCount = get16(s); | |||
| 4462 | if (channelCount < 0 || channelCount > 16) { | |||
| 4463 | stbi_rewind( s ); | |||
| 4464 | return 0; | |||
| 4465 | } | |||
| 4466 | *y = get32(s); | |||
| 4467 | *x = get32(s); | |||
| 4468 | if (get16(s) != 8) { | |||
| 4469 | stbi_rewind( s ); | |||
| 4470 | return 0; | |||
| 4471 | } | |||
| 4472 | if (get16(s) != 3) { | |||
| 4473 | stbi_rewind( s ); | |||
| 4474 | return 0; | |||
| 4475 | } | |||
| 4476 | *comp = 4; | |||
| 4477 | return 1; | |||
| 4478 | } | |||
| 4479 | ||||
| 4480 | static int stbi_pic_info(stbi *s, int *x, int *y, int *comp) | |||
| 4481 | { | |||
| 4482 | int act_comp=0,num_packets=0,chained; | |||
| 4483 | pic_packet_t packets[10]; | |||
| 4484 | ||||
| 4485 | skip(s, 92); | |||
| 4486 | ||||
| 4487 | *x = get16(s); | |||
| 4488 | *y = get16(s); | |||
| 4489 | if (at_eof(s)) return 0; | |||
| 4490 | if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { | |||
| 4491 | stbi_rewind( s ); | |||
| 4492 | return 0; | |||
| 4493 | } | |||
| 4494 | ||||
| 4495 | skip(s, 8); | |||
| 4496 | ||||
| 4497 | do { | |||
| 4498 | pic_packet_t *packet; | |||
| 4499 | ||||
| 4500 | if (num_packets==sizeof(packets)/sizeof(packets[0])) | |||
| 4501 | return 0; | |||
| 4502 | ||||
| 4503 | packet = &packets[num_packets++]; | |||
| 4504 | chained = get8(s); | |||
| 4505 | packet->size = get8u(s); | |||
| 4506 | packet->type = get8u(s); | |||
| 4507 | packet->channel = get8u(s); | |||
| 4508 | act_comp |= packet->channel; | |||
| 4509 | ||||
| 4510 | if (at_eof(s)) { | |||
| 4511 | stbi_rewind( s ); | |||
| 4512 | return 0; | |||
| 4513 | } | |||
| 4514 | if (packet->size != 8) { | |||
| 4515 | stbi_rewind( s ); | |||
| 4516 | return 0; | |||
| 4517 | } | |||
| 4518 | } while (chained); | |||
| 4519 | ||||
| 4520 | *comp = (act_comp & 0x10 ? 4 : 3); | |||
| 4521 | ||||
| 4522 | return 1; | |||
| 4523 | } | |||
| 4524 | ||||
| 4525 | static int stbi_info_main(stbi *s, int *x, int *y, int *comp) | |||
| 4526 | { | |||
| 4527 | if (stbi_jpeg_info(s, x, y, comp)) | |||
| 4528 | return 1; | |||
| 4529 | if (stbi_png_info(s, x, y, comp)) | |||
| 4530 | return 1; | |||
| 4531 | if (stbi_gif_info(s, x, y, comp)) | |||
| 4532 | return 1; | |||
| 4533 | if (stbi_bmp_info(s, x, y, comp)) | |||
| 4534 | return 1; | |||
| 4535 | if (stbi_psd_info(s, x, y, comp)) | |||
| 4536 | return 1; | |||
| 4537 | if (stbi_pic_info(s, x, y, comp)) | |||
| 4538 | return 1; | |||
| 4539 | #ifndef STBI_NO_HDR | |||
| 4540 | if (stbi_hdr_info(s, x, y, comp)) | |||
| 4541 | return 1; | |||
| 4542 | #endif | |||
| 4543 | // test tga last because it's a crappy test! | |||
| 4544 | if (stbi_tga_info(s, x, y, comp)) | |||
| 4545 | return 1; | |||
| 4546 | return e("unknown image type", "Image not of any known type, or corrupt")e("unknown image type"); | |||
| 4547 | } | |||
| 4548 | ||||
| 4549 | #ifndef STBI_NO_STDIO | |||
| 4550 | int stbi_info(char const *filename, int *x, int *y, int *comp) | |||
| 4551 | { | |||
| 4552 | FILE *f = fopen(filename, "rb"); | |||
| 4553 | int result; | |||
| 4554 | if (!f) return e("can't fopen", "Unable to open file")e("can't fopen"); | |||
| 4555 | result = stbi_info_from_file(f, x, y, comp); | |||
| 4556 | fclose(f); | |||
| 4557 | return result; | |||
| 4558 | } | |||
| 4559 | ||||
| 4560 | int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) | |||
| 4561 | { | |||
| 4562 | int r; | |||
| 4563 | stbi s; | |||
| 4564 | long pos = ftell(f); | |||
| 4565 | start_file(&s, f); | |||
| 4566 | r = stbi_info_main(&s,x,y,comp); | |||
| 4567 | fseek(f,pos,SEEK_SET0); | |||
| 4568 | return r; | |||
| 4569 | } | |||
| 4570 | #endif // !STBI_NO_STDIO | |||
| 4571 | ||||
| 4572 | int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) | |||
| 4573 | { | |||
| 4574 | stbi s; | |||
| 4575 | start_mem(&s,buffer,len); | |||
| 4576 | return stbi_info_main(&s,x,y,comp); | |||
| 4577 | } | |||
| 4578 | ||||
| 4579 | int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) | |||
| 4580 | { | |||
| 4581 | stbi s; | |||
| 4582 | start_callbacks(&s, (stbi_io_callbacks *) c, user); | |||
| 4583 | return stbi_info_main(&s,x,y,comp); | |||
| 4584 | } | |||
| 4585 | ||||
| 4586 | #endif // STBI_HEADER_FILE_ONLY | |||
| 4587 | ||||
| 4588 | /* | |||
| 4589 | revision history: | |||
| 4590 | 1.33 (2011-07-14) | |||
| 4591 | make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements | |||
| 4592 | 1.32 (2011-07-13) | |||
| 4593 | support for "info" function for all supported filetypes (SpartanJ) | |||
| 4594 | 1.31 (2011-06-20) | |||
| 4595 | a few more leak fixes, bug in PNG handling (SpartanJ) | |||
| 4596 | 1.30 (2011-06-11) | |||
| 4597 | added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) | |||
| 4598 | removed deprecated format-specific test/load functions | |||
| 4599 | removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway | |||
| 4600 | error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) | |||
| 4601 | fix inefficiency in decoding 32-bit BMP (David Woo) | |||
| 4602 | 1.29 (2010-08-16) | |||
| 4603 | various warning fixes from Aurelien Pocheville | |||
| 4604 | 1.28 (2010-08-01) | |||
| 4605 | fix bug in GIF palette transparency (SpartanJ) | |||
| 4606 | 1.27 (2010-08-01) | |||
| 4607 | cast-to-uint8 to fix warnings | |||
| 4608 | 1.26 (2010-07-24) | |||
| 4609 | fix bug in file buffering for PNG reported by SpartanJ | |||
| 4610 | 1.25 (2010-07-17) | |||
| 4611 | refix trans_data warning (Won Chun) | |||
| 4612 | 1.24 (2010-07-12) | |||
| 4613 | perf improvements reading from files on platforms with lock-heavy fgetc() | |||
| 4614 | minor perf improvements for jpeg | |||
| 4615 | deprecated type-specific functions so we'll get feedback if they're needed | |||
| 4616 | attempt to fix trans_data warning (Won Chun) | |||
| 4617 | 1.23 fixed bug in iPhone support | |||
| 4618 | 1.22 (2010-07-10) | |||
| 4619 | removed image *writing* support | |||
| 4620 | stbi_info support from Jetro Lauha | |||
| 4621 | GIF support from Jean-Marc Lienher | |||
| 4622 | iPhone PNG-extensions from James Brown | |||
| 4623 | warning-fixes from Nicolas Schulz and Janez Zemva (i.e. Janez (U+017D)emva) | |||
| 4624 | 1.21 fix use of 'uint8' in header (reported by jon blow) | |||
| 4625 | 1.20 added support for Softimage PIC, by Tom Seddon | |||
| 4626 | 1.19 bug in interlaced PNG corruption check (found by ryg) | |||
| 4627 | 1.18 2008-08-02 | |||
| 4628 | fix a threading bug (local mutable static) | |||
| 4629 | 1.17 support interlaced PNG | |||
| 4630 | 1.16 major bugfix - convert_format converted one too many pixels | |||
| 4631 | 1.15 initialize some fields for thread safety | |||
| 4632 | 1.14 fix threadsafe conversion bug | |||
| 4633 | header-file-only version (#define STBI_HEADER_FILE_ONLY before including) | |||
| 4634 | 1.13 threadsafe | |||
| 4635 | 1.12 const qualifiers in the API | |||
| 4636 | 1.11 Support installable IDCT, colorspace conversion routines | |||
| 4637 | 1.10 Fixes for 64-bit (don't use "unsigned long") | |||
| 4638 | optimized upsampling by Fabian "ryg" Giesen | |||
| 4639 | 1.09 Fix format-conversion for PSD code (bad global variables!) | |||
| 4640 | 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz | |||
| 4641 | 1.07 attempt to fix C++ warning/errors again | |||
| 4642 | 1.06 attempt to fix C++ warning/errors again | |||
| 4643 | 1.05 fix TGA loading to return correct *comp and use good luminance calc | |||
| 4644 | 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free | |||
| 4645 | 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR | |||
| 4646 | 1.02 support for (subset of) HDR files, float interface for preferred access to them | |||
| 4647 | 1.01 fix bug: possible bug in handling right-side up bmps... not sure | |||
| 4648 | fix bug: the stbi_bmp_load() and stbi_tga_load() functions didn't work at all | |||
| 4649 | 1.00 interface to zlib that skips zlib header | |||
| 4650 | 0.99 correct handling of alpha in palette | |||
| 4651 | 0.98 TGA loader by lonesock; dynamically add loaders (untested) | |||
| 4652 | 0.97 jpeg errors on too large a file; also catch another malloc failure | |||
| 4653 | 0.96 fix detection of invalid v value - particleman@mollyrocket forum | |||
| 4654 | 0.95 during header scan, seek to markers in case of padding | |||
| 4655 | 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same | |||
| 4656 | 0.93 handle jpegtran output; verbose errors | |||
| 4657 | 0.92 read 4,8,16,24,32-bit BMP files of several formats | |||
| 4658 | 0.91 output 24-bit Windows 3.0 BMP files | |||
| 4659 | 0.90 fix a few more warnings; bump version number to approach 1.0 | |||
| 4660 | 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd | |||
| 4661 | 0.60 fix compiling as c++ | |||
| 4662 | 0.59 fix warnings: merge Dave Moore's -Wall fixes | |||
| 4663 | 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian | |||
| 4664 | 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available | |||
| 4665 | 0.56 fix bug: zlib uncompressed mode len vs. nlen | |||
| 4666 | 0.55 fix bug: restart_interval not initialized to 0 | |||
| 4667 | 0.54 allow NULL for 'int *comp' | |||
| 4668 | 0.53 fix bug in png 3->4; speedup png decoding | |||
| 4669 | 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments | |||
| 4670 | 0.51 obey req_comp requests, 1-component jpegs return as 1-component, | |||
| 4671 | on 'test' only check type, not whether we support this variant | |||
| 4672 | 0.50 first released version | |||
| 4673 | */ |