├── .gitignore ├── tests ├── blob.stl ├── mask.png ├── scene.png ├── scene.stl ├── puzzle.stl ├── blob-stl.png ├── puzzlemask.png ├── scene-stl.png ├── scene-thick.stl └── scene-thick-print.jpg ├── stb_image.h ├── Makefile ├── heightmap.h ├── test ├── all.tcl └── static.test.tcl ├── LICENSE ├── heightmap.c ├── README.md ├── hmstl.c └── stb_image.c /.gitignore: -------------------------------------------------------------------------------- 1 | hmstl 2 | *.o 3 | -------------------------------------------------------------------------------- /tests/blob.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/blob.stl -------------------------------------------------------------------------------- /tests/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/mask.png -------------------------------------------------------------------------------- /tests/scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/scene.png -------------------------------------------------------------------------------- /tests/scene.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/scene.stl -------------------------------------------------------------------------------- /tests/puzzle.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/puzzle.stl -------------------------------------------------------------------------------- /tests/blob-stl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/blob-stl.png -------------------------------------------------------------------------------- /tests/puzzlemask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/puzzlemask.png -------------------------------------------------------------------------------- /tests/scene-stl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/scene-stl.png -------------------------------------------------------------------------------- /tests/scene-thick.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/scene-thick.stl -------------------------------------------------------------------------------- /tests/scene-thick-print.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anoved/hmstl/HEAD/tests/scene-thick-print.jpg -------------------------------------------------------------------------------- /stb_image.h: -------------------------------------------------------------------------------- 1 | #define STBI_HEADER_FILE_ONLY 2 | #define STBI_FAILURE_USERMSG 3 | #include "stb_image.c" 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test clean 2 | 3 | hmstl: hmstl.c heightmap.c heightmap.h stb_image.o 4 | gcc hmstl.c heightmap.c stb_image.o -o hmstl -ltrix -lm -L/usr/local/lib -Wl,-R/usr/local/lib 5 | 6 | stb_image.o: stb_image.c stb_image.h 7 | gcc -c stb_image.c -o stb_image.o 8 | 9 | test: hmstl 10 | tclsh test/all.tcl -constraint static 11 | 12 | clean: 13 | rm -f hmstl stb_image.o 14 | -------------------------------------------------------------------------------- /heightmap.h: -------------------------------------------------------------------------------- 1 | #ifndef _HEIGHTMAP_H 2 | #define _HEIGHTMAP_H 3 | 4 | typedef struct { 5 | 6 | // xy dimensions (size = width * height) 7 | unsigned int width, height; 8 | unsigned long size; 9 | 10 | // z dimensions (range = max - min = relief) 11 | unsigned char min, max, range; 12 | 13 | // raster with size pixels ranging in value from min to max 14 | unsigned char *data; 15 | 16 | } Heightmap; 17 | 18 | Heightmap *ReadHeightmap(const char *path); 19 | void FreeHeightmap(Heightmap **hm); 20 | void DumpHeightmap(const Heightmap *hm); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /test/all.tcl: -------------------------------------------------------------------------------- 1 | package require Tcl 8.5 2 | package require tcltest 2 3 | 4 | # Use the tests directory as the working directory for all tests. 5 | ::tcltest::workingDirectory [file dirname [info script]] 6 | 7 | # Stow any temporary test files in the tmp subdirectory. 8 | # runAllTests should only look here, in the test directory, for tests. 9 | # It should not bother looking for tests in the tmp subdirectory. 10 | # Files that end in .test.tcl (excepting any lock files) contain tests. 11 | ::tcltest::configure \ 12 | -tmpdir tmp \ 13 | -testdir [::tcltest::workingDirectory] \ 14 | -asidefromdir {tmp sample} \ 15 | -file {*.test.tcl} \ 16 | -notfile {l.*.test.tcl} \ 17 | -verbose {body pass skip error} 18 | 19 | # Apply any additional configuration arguments. 20 | eval ::tcltest::configure $argv 21 | 22 | # Perform the tests. 23 | ::tcltest::runAllTests 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Jim DeVona 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /heightmap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "stb_image.h" 6 | #include "heightmap.h" 7 | 8 | 9 | void ScanHeightmap(Heightmap *hm) { 10 | 11 | unsigned long i; 12 | unsigned char min, max; 13 | 14 | if (hm == NULL || hm->data == NULL) { 15 | return; 16 | } 17 | 18 | min = 255; 19 | max = 0; 20 | 21 | for (i = 0; i < hm->size; i++) { 22 | if (hm->data[i] < min) { 23 | min = hm->data[i]; 24 | } 25 | if (hm->data[i] > max) { 26 | max = hm->data[i]; 27 | } 28 | } 29 | 30 | hm->min = min; 31 | hm->max = max; 32 | hm->range = max - min; 33 | } 34 | 35 | // Returns pointer to Heightmap 36 | // Returns NULL on error 37 | Heightmap *ReadHeightmap(const char *path) { 38 | 39 | int width, height, depth; 40 | unsigned char *data; 41 | Heightmap *hm; 42 | 43 | if (path == NULL) { 44 | data = stbi_load_from_file(stdin, &width, &height, &depth, 1); 45 | } 46 | else { 47 | data = stbi_load(path, &width, &height, &depth, 1); 48 | } 49 | 50 | if (data == NULL) { 51 | fprintf(stderr, "%s\n", stbi_failure_reason()); 52 | return NULL; 53 | } 54 | 55 | if ((hm = (Heightmap *)malloc(sizeof(Heightmap))) == NULL) { 56 | fprintf(stderr, "Cannot allocate memory for heightmap structure\n"); 57 | free(data); 58 | return NULL; 59 | } 60 | 61 | hm->width = (unsigned int)width; 62 | hm->height = (unsigned int)height; 63 | hm->size = (unsigned long)width * (unsigned long)height; 64 | hm->data = data; 65 | 66 | ScanHeightmap(hm); 67 | 68 | return hm; 69 | } 70 | 71 | void FreeHeightmap(Heightmap **hm) { 72 | 73 | if (hm == NULL || *hm == NULL) { 74 | return; 75 | } 76 | 77 | if ((*hm)->data != NULL) { 78 | stbi_image_free((*hm)->data); 79 | } 80 | 81 | free(*hm); 82 | *hm = NULL; 83 | } 84 | 85 | void DumpHeightmap(const Heightmap *hm) { 86 | fprintf(stderr, "Width: %u\n", hm->width); 87 | fprintf(stderr, "Height: %u\n", hm->height); 88 | fprintf(stderr, "Size: %lu\n", hm->size); 89 | fprintf(stderr, "Min: %d\n", hm->min); 90 | fprintf(stderr, "Max: %d\n", hm->max); 91 | fprintf(stderr, "Range: %d\n", hm->range); 92 | } 93 | 94 | 95 | -------------------------------------------------------------------------------- /test/static.test.tcl: -------------------------------------------------------------------------------- 1 | package require Tcl 8.5 2 | package require tcltest 2 3 | namespace import ::tcltest::test ::tcltest::makeFile ::tcltest::removeFile 4 | 5 | # Use the test directory as the working directory for all tests. 6 | ::tcltest::workingDirectory [file dirname [info script]] 7 | 8 | # Stow any temporary test files in a tmp subdirectory. 9 | ::tcltest::configure -tmpdir tmp 10 | 11 | # Apply any additional configuration arguments. 12 | eval ::tcltest::configure $argv 13 | 14 | # Because these tests are more time consuming than others, they are skipped 15 | # by default. To run them, run `tclsh test/static.test.tcl -constraints static` 16 | 17 | ::tcltest::testConstraint has_splint [expr {![catch {exec which splint}]}] 18 | ::tcltest::testConstraint has_cppcheck [expr {![catch {exec which cppcheck}]}] 19 | ::tcltest::testConstraint has_clang [expr {![catch {exec which clang}]}] 20 | 21 | test static-splint-1 { 22 | # Check that Splint reports no issues (-weak mode). 23 | } -constraints { 24 | static 25 | has_splint 26 | } -body { 27 | # +quiet suppresses "herald" line and error count (simplifies success case) 28 | exec splint -weak +quiet -unrecog ../hmstl.c -I/usr/local/include 29 | } -result {} 30 | 31 | test static-splint-2 { 32 | # splint heightmap 33 | } -constraints { 34 | static 35 | has_splint 36 | } -body { 37 | exec splint -weak +quiet ../heightmap.c 38 | } -result {} 39 | 40 | test static-cppcheck-1 { 41 | # Check that CPPCheck reports no issues. 42 | } -constraints { 43 | static 44 | has_cppcheck 45 | } -body { 46 | exec cppcheck --enable=all --quiet ../hmstl.c 47 | } -result {} 48 | 49 | test static-cppcheck-2 { 50 | # cppcheck heightmap 51 | } -constraints { 52 | static 53 | has_cppcheck 54 | } -body { 55 | exec cppcheck --enable=all --quiet ../heightmap.c 56 | } -result {} 57 | 58 | test static-clang-1 { 59 | # Check that Clang's analyzer reports no issues. 60 | } -constraints { 61 | static 62 | has_clang 63 | } -body { 64 | exec clang --analyze ../hmstl.c 65 | } -cleanup { 66 | # Remove diagnostics file generated by clang 67 | file delete hmstl.plist 68 | } -result {} 69 | 70 | test static-clang-2 { 71 | # clang analyze heightmap 72 | } -constraints { 73 | static 74 | has_clang 75 | } -body { 76 | exec clang --analyze ../heightmap.c 77 | } -cleanup { 78 | file delete heightmap.plist 79 | } -result {} 80 | 81 | ::tcltest::cleanupTests 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Heightmap to STL 2 | 3 | `hmstl` is a simple program to convert heightmap images to 3D models. The output format is [STL](http://www.ennex.com/~fabbers/StL.asp). 4 | 5 | ## Prerequisites 6 | 7 | `hmstl` requires [libtrix](https://github.com/anoved/libtrix/), my rudimentary C library for generating STL files from triangle lists. 8 | 9 | ## Build 10 | 11 | Compile `hmstl` with: 12 | 13 | make hmstl 14 | 15 | ## Usage 16 | 17 | By default, `hmstl` can be used as a filter to convert heightmap images on standard input to STL models on standard output. The following options are also supported: 18 | 19 | - `-i INPUT` read heightmap image from the specified `INPUT` file. Otherwise, read heightmap image from standard input. 20 | - `-o OUTPUT` write STL data to the specified `OUTPUT` file. Otherwise, write STL data to standard output. 21 | - `-z SCALE` multiple heightmap values by `SCALE`. Default: `1` 22 | - `-b HEIGHT` set base thickness to `HEIGHT`. Default and minimum: `1` 23 | - `-s` terrain surface only; omits base walls and bottom 24 | - `-a` output ASCII STL instead of default binary STL 25 | 26 | The following options apply a mask to the heightmap. Only the portion of the heightmap visible through the mask is output. This can be used to generate models of areas with non-rectangular boundaries. 27 | 28 | - `-m MASK` load mask image from the specified `MASK` file. Dimensions must match heightmap dimensions. 29 | - `-t THRESHOLD` consider mask values equal to or less than `THRESHOLD` to be opaque. Default: `127` (in range 0..255) 30 | - `-h` as an alternative to `-m`, use the heightmap as its own mask; elevations below `THRESHOLD` are considered masked. 31 | - `-r` reverse mask interpretation (swap transparent and opaque areas) 32 | 33 | Supported input image formats include JPG (excluding progressive JPG), PNG, GIF, and BMP. Color images are interpreted as grayscale based on pixel luminance (0.3 R, 0.59 G, 0.11 B). 34 | 35 | ## Example 36 | 37 | [![Test scene heightmap](tests/scene.png)](tests/scene.png) 38 | 39 | Create an STL model of `tests/scene.pgm`, the heightmap image above, with the following command. The `-z` option is used to scale height values; an appropriate value depends on dataset resolution and desired exaggeration. 40 | 41 | hmstl -z 0.25 < tests/scene.png > tests/scene.stl 42 | 43 | Here is the output displayed in [Meshlab](http://meshlab.sourceforge.net/): 44 | 45 | [![Test scene STL file](tests/scene-stl.png)](tests/scene.stl) 46 | 47 | Here is a contrived masking example using the same heightmap and a compound oval mask: 48 | 49 | hmstl -z 0.25 -i tests/scene.png -m tests/mask.png -o tests/blob.stl 50 | 51 | [![Masked model](tests/blob-stl.png)](tests/blob.stl) 52 | 53 | Here is a photo of a Makerbot printing of the [scene-thick](tests/scene-thick.stl) sample model: 54 | 55 | [![Printed model of sample scene](tests/scene-thick-print.jpg)](tests/scene-thick-print.jpg) 56 | 57 | ## Scale and Orientation 58 | 59 | Each pixel in the input heightmap is output as a unit quad (1 unit extent in xy plane) comprised of two triangles. By default, Z values are assumed to use the same units; use the `-z` option to set the correct scale. 60 | 61 | The upper left pixel of the input heightmap is output centered at x/y 0/h, where h is the y extent of the heightmap, with the bottom of the model at z 0. Because the output pixel quads are 1 unit square centered over the pixel coordinates, the actual upper left extent of the output model is at -0.5, h + 0.5. 62 | 63 | ## Post-Processing 64 | 65 | Meshlab's *Quadric Edge Collapse Decimation* filter is suitable for simplifying `hmstl` output to reduce the number of faces without losing important features. Use various constraints such as *Preserve Boundary* or *Planar Simplification* to ensure original edges are preserved. 66 | 67 | ## License 68 | 69 | Freely distributed under an [MIT License](LICENSE). See the `LICENSE` files for details. 70 | 71 | ## Acknowledgements 72 | 73 | Heightmap images are loaded using [Sean Barrett](http://nothings.org/)'s public domain [stb_image.c](http://nothings.org/stb_image.c) library. 74 | -------------------------------------------------------------------------------- /hmstl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef S_SPLINT_S 5 | #include 6 | #endif 7 | 8 | #include 9 | #include "heightmap.h" 10 | 11 | typedef struct { 12 | int base; // boolean; output walls and bottom as well as terrain surface if true 13 | int ascii; // boolean; output ASCII STL instead of binary STL if true 14 | char *input; // path to input file; use stdin if NULL 15 | char *output; // path to output file; use stdout if NULL 16 | char *mask; // path to mask file; no mask if NULL 17 | int threshold; // 0-255; maximum value considered masked 18 | int reversed; // boolean; reverse results of mask tests if true 19 | int heightmask; // boolean; use heightmap as it's own mask if true 20 | float zscale; // scaling factor applied to raw Z values 21 | float baseheight; // height in STL units of base below lowest terrain (technically, offset added to scaled Z values) 22 | } Settings; 23 | 24 | Settings CONFIG = { 25 | 1, // generate base (walls and bottom) 26 | 0, // binary output 27 | NULL, // read from stdin 28 | NULL, // write to stdout 29 | NULL, // no mask 30 | 127, // middle of 8 bit range 31 | 0, // normal un-reversed mask 32 | 0, // no heightmasking 33 | 1.0, // no z scaling (use raw heightmap values) 34 | 1.0 // minimum base thickness of one unit 35 | }; 36 | 37 | Heightmap *mask = NULL; 38 | 39 | // If a mask is defined, only portions of the heightmap that are visible through the mask are output. 40 | // Bright areas of the mask image are considered transparent and dark areas are considered opaque. 41 | int Masked(unsigned int x, unsigned int y) { 42 | unsigned long index; 43 | int result = 0; 44 | 45 | // is masking mode even on? 46 | // (not if no heightmask or mask file.) 47 | if (mask == NULL) { 48 | return 0; 49 | } 50 | 51 | index = (y * mask->width) + x; 52 | if (mask->data[index] <= (unsigned char)CONFIG.threshold) { 53 | result = 1; 54 | } 55 | 56 | if (CONFIG.reversed) { 57 | result = !result; 58 | } 59 | 60 | return result; 61 | } 62 | 63 | static trix_result Wall(trix_mesh *mesh, const trix_vertex *a, const trix_vertex *b) { 64 | trix_vertex a0 = *a; 65 | trix_vertex b0 = *b; 66 | trix_triangle t1; 67 | trix_triangle t2; 68 | trix_result r; 69 | a0.z = 0; 70 | b0.z = 0; 71 | t1.a = *a; 72 | t1.b = *b; 73 | t1.c = b0; 74 | t2.a = b0; 75 | t2.b = a0; 76 | t2.c = *a; 77 | if ((r = trixAddTriangle(mesh, &t1)) != TRIX_OK) { 78 | return r; 79 | } 80 | if ((r = trixAddTriangle(mesh, &t2)) != TRIX_OK) { 81 | return r; 82 | } 83 | return TRIX_OK; 84 | } 85 | 86 | // returns average of all non-negative arguments. 87 | // If any argument is negative, it is not included in the average. 88 | // argument zp will always be nonnegative. 89 | static float avgnonneg(float zp, float z1, float z2, float z3) { 90 | float sum = zp; 91 | float z[3] = {z1, z2, z3}; 92 | int i, n = 1; 93 | 94 | for (i = 0; i < 3; i++) { 95 | if (z[i] >= 0) { 96 | sum += z[i]; 97 | n++; 98 | } 99 | } 100 | 101 | return sum / (float)n; 102 | } 103 | 104 | static float hmzat(const Heightmap *hm, unsigned int x, unsigned int y) { 105 | return CONFIG.baseheight + (CONFIG.zscale * hm->data[(hm->width * y) + x]);; 106 | } 107 | 108 | // given four vertices and a mesh, add two triangles representing the quad with given corners 109 | trix_result Surface(trix_mesh *mesh, const trix_vertex *v1, const trix_vertex *v2, const trix_vertex *v3, const trix_vertex *v4) { 110 | trix_triangle i, j; 111 | trix_result r; 112 | 113 | i.a = *v4; 114 | i.b = *v2; 115 | i.c = *v1; 116 | 117 | j.a = *v4; 118 | j.b = *v3; 119 | j.c = *v2; 120 | 121 | if ((r = trixAddTriangle(mesh, &i)) != TRIX_OK) { 122 | return r; 123 | } 124 | 125 | if ((r = trixAddTriangle(mesh, &j)) != TRIX_OK) { 126 | return r; 127 | } 128 | 129 | return TRIX_OK; 130 | } 131 | 132 | trix_result Mesh(const Heightmap *hm, trix_mesh *mesh) { 133 | unsigned int x, y; 134 | float az, bz, cz, dz, ez, fz, gz, hz; 135 | trix_vertex vp, v1, v2, v3, v4; 136 | trix_result r; 137 | 138 | for (y = 0; y < hm->height; y++) { 139 | for (x = 0; x < hm->width; x++) { 140 | 141 | if (Masked(x, y)) { 142 | continue; 143 | } 144 | 145 | /* 146 | 147 | +---+---+---+ 148 | | | | | 149 | | A | B | C | 150 | | | | | 151 | +---1---2---+ 152 | | |I /| | 153 | | H | P | D | 154 | | |/ J| | 155 | +---4---3---+ 156 | | | | | 157 | | G | F | E | 158 | | | | | 159 | +---+---+---+ 160 | 161 | Current pixel position is marked at center as P. 162 | This pixel is output as two triangles, I and J. 163 | Points 1, 2, 3, and 4 are offset half a unit from P. 164 | Neighboring pixels are A, B, C, D, E, F, G, and H. 165 | 166 | Vertex 1 z is average of ABPH z 167 | Vertex 2 z is average of BCDP z 168 | Vertex 3 z is average of PDEF z 169 | Vertex 4 z is average of HPFG z 170 | 171 | Averages do not include neighbors that would lie 172 | outside the image, but do included masked values. 173 | 174 | */ 175 | 176 | // determine elevation of neighboring pixels in order to 177 | // to interpolate height of corners 1, 2, 3, and 4. 178 | // -1 is used to flag edge pixels to disregard. 179 | // (Masked neighbors are still considered.) 180 | 181 | if (x == 0 || y == 0) { 182 | az = -1; 183 | } else { 184 | az = hmzat(hm, x - 1, y - 1); 185 | } 186 | 187 | if (y == 0) { 188 | bz = -1; 189 | } else { 190 | bz = hmzat(hm, x, y - 1); 191 | } 192 | 193 | if (y == 0 || x + 1 == hm->width) { 194 | cz = -1; 195 | } else { 196 | cz = hmzat(hm, x + 1, y - 1); 197 | } 198 | 199 | if (x + 1 == hm->width) { 200 | dz = -1; 201 | } else { 202 | dz = hmzat(hm, x + 1, y); 203 | } 204 | 205 | if (x + 1 == hm->width || y + 1 == hm->height) { 206 | ez = -1; 207 | } else { 208 | ez = hmzat(hm, x + 1, y + 1); 209 | } 210 | 211 | if (y + 1 == hm->height) { 212 | fz = -1; 213 | } else { 214 | fz = hmzat(hm, x, y + 1); 215 | } 216 | 217 | if (y + 1 == hm->height || x == 0) { 218 | gz = -1; 219 | } else { 220 | gz = hmzat(hm, x - 1, y + 1); 221 | } 222 | 223 | if (x == 0) { 224 | hz = -1; 225 | } else { 226 | hz = hmzat(hm, x - 1, y); 227 | } 228 | 229 | // pixel vertex 230 | vp.x = (float)x; 231 | vp.y = (float)(hm->height - y); 232 | vp.z = hmzat(hm, x, y); 233 | 234 | // Vertex 1 235 | v1.x = (float)x - 0.5; 236 | v1.y = ((float)hm->height - ((float)y - 0.5)); 237 | v1.z = avgnonneg(vp.z, az, bz, hz); 238 | 239 | // Vertex 2 240 | v2.x = (float)x + 0.5; 241 | v2.y = v1.y; 242 | v2.z = avgnonneg(vp.z, bz, cz, dz); 243 | 244 | // Vertex 3 245 | v3.x = v2.x; 246 | v3.y = ((float)hm->height - ((float)y + 0.5)); 247 | v3.z = avgnonneg(vp.z, dz, ez, fz); 248 | 249 | // Vertex 4 250 | v4.x = v1.x; 251 | v4.y = v3.y; 252 | v4.z = avgnonneg(vp.z, hz, fz, gz); 253 | 254 | // Upper surface 255 | if ((r = Surface(mesh, &v1, &v2, &v3, &v4)) != TRIX_OK) { 256 | return r; 257 | } 258 | 259 | // nothing left to do for this pixel unless we need to make walls 260 | if (!CONFIG.base) { 261 | continue; 262 | } 263 | 264 | // north wall (vertex 1 to 2) 265 | if (y == 0 || Masked(x, y - 1)) { 266 | if ((r = Wall(mesh, &v1, &v2)) != TRIX_OK) { 267 | return r; 268 | } 269 | } 270 | 271 | // east wall (vertex 2 to 3) 272 | if (x + 1 == hm->width || Masked(x + 1, y)) { 273 | if ((r = Wall(mesh, &v2, &v3)) != TRIX_OK) { 274 | return r; 275 | } 276 | } 277 | 278 | // south wall (vertex 3 to 4) 279 | if (y + 1 == hm->height || Masked(x, y + 1)) { 280 | if ((r = Wall(mesh, &v3, &v4)) != TRIX_OK) { 281 | return r; 282 | } 283 | } 284 | 285 | // west wall (vertex 4 to 1) 286 | if (x == 0 || Masked(x - 1, y)) { 287 | if ((r = Wall(mesh, &v4, &v1)) != TRIX_OK) { 288 | return r; 289 | } 290 | } 291 | 292 | // bottom surface - same as top, except with z = 0 and reverse winding 293 | v1.z = 0; v2.z = 0; v3.z = 0; v4.z = 0; 294 | if ((r = Surface(mesh, &v4, &v3, &v2, &v1)) != TRIX_OK) { 295 | return r; 296 | } 297 | } 298 | } 299 | 300 | return TRIX_OK; 301 | } 302 | 303 | // returns 0 on success, nonzero otherwise 304 | int HeightmapToSTL(Heightmap *hm) { 305 | trix_result r; 306 | trix_mesh *mesh; 307 | 308 | if ((r = trixCreate(&mesh, "hmstl")) != TRIX_OK) { 309 | return (int)r; 310 | } 311 | 312 | if ((r = Mesh(hm, mesh)) != TRIX_OK) { 313 | return (int)r; 314 | } 315 | 316 | // writes to stdout if CONFIG.output is null, otherwise writes to path it names 317 | if ((r = trixWrite(mesh, CONFIG.output, (CONFIG.ascii ? TRIX_STL_ASCII : TRIX_STL_BINARY))) != TRIX_OK) { 318 | return (int)r; 319 | } 320 | 321 | (void)trixRelease(&mesh); 322 | 323 | return 0; 324 | } 325 | 326 | // https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html 327 | // returns 0 if options are parsed successfully; nonzero otherwise 328 | int parseopts(int argc, char **argv) { 329 | 330 | int c; 331 | 332 | // suppress automatic error messages generated by getopt 333 | opterr = 0; 334 | 335 | while ((c = getopt(argc, argv, "az:b:o:i:m:t:rhs")) != -1) { 336 | switch (c) { 337 | case 'a': 338 | // ASCII mode output 339 | CONFIG.ascii = 1; 340 | break; 341 | case 'z': 342 | // Z scale (heightmap value units relative to XY) 343 | if (sscanf(optarg, "%20f", &CONFIG.zscale) != 1 || CONFIG.zscale <= 0) { 344 | fprintf(stderr, "Z scale must be a number greater than 0.\n"); 345 | return 1; 346 | } 347 | break; 348 | case 'b': 349 | // Base height (default 1.0 units) 350 | if (sscanf(optarg, "%20f", &CONFIG.baseheight) != 1 || CONFIG.baseheight < 1) { 351 | fprintf(stderr, "BASEHEIGHT must be a number greater than or equal to 1.\n"); 352 | return 1; 353 | } 354 | break; 355 | case 'o': 356 | // Output file (default stdout) 357 | CONFIG.output = optarg; 358 | break; 359 | case 'i': 360 | // Input file (default stdin) 361 | CONFIG.input = optarg; 362 | break; 363 | case 'm': 364 | // Mask file (default none) 365 | CONFIG.mask = optarg; 366 | break; 367 | case 't': 368 | // Mask threshold 369 | if (sscanf(optarg, "%5d", &CONFIG.threshold) != 1 || CONFIG.threshold < 0 || CONFIG.threshold > 255) { 370 | fprintf(stderr, "THRESHOLD must be a number between 0 to 255 inclusive\n"); 371 | return 1; 372 | } 373 | break; 374 | case 'r': 375 | // Reverse mask 376 | CONFIG.reversed = 1; 377 | break; 378 | case 'h': 379 | // Heightmask mode 380 | CONFIG.heightmask = 1; 381 | break; 382 | case 's': 383 | // surface only mode - omit base (walls and bottom) 384 | CONFIG.base = 0; 385 | break; 386 | case '?': 387 | // unrecognized option OR missing option argument 388 | switch (optopt) { 389 | case 'z': 390 | case 'b': 391 | case 'i': 392 | case 'o': 393 | case 'm': 394 | case 't': 395 | fprintf(stderr, "Option -%c requires an argument.\n", optopt); 396 | break; 397 | default: 398 | if (isprint(optopt)) { 399 | fprintf(stderr, "Unknown option -%c\n", optopt); 400 | } 401 | else { 402 | fprintf(stderr, "Unknown option character \\x%x\n", optopt); 403 | } 404 | break; 405 | } 406 | return 1; 407 | break; 408 | default: 409 | // My understand is getopt will return ? for all unrecognized options, 410 | // so I'm not sure what other cases will be caught here. Perhaps just 411 | // options specified in optstring that I forget to handle above... 412 | fprintf(stderr, "Unexpected getopt result: %c\n", optopt); 413 | return 1; 414 | break; 415 | } 416 | } 417 | 418 | // should be no parameters left 419 | if (optind < argc) { 420 | fprintf(stderr, "Extraneous arguments\n"); 421 | return 1; 422 | } 423 | 424 | return 0; 425 | } 426 | 427 | int main(int argc, char **argv) { 428 | Heightmap *hm = NULL; 429 | trix_result r; 430 | 431 | if (parseopts(argc, argv)) { 432 | fprintf(stderr, "option parsing failed\n"); 433 | return 1; 434 | } 435 | 436 | if ((hm = ReadHeightmap(CONFIG.input)) == NULL) { 437 | return 1; 438 | } 439 | 440 | if (CONFIG.heightmask) { 441 | // point the mask at the heightmap 442 | // instead of reading a separate image 443 | mask = hm; 444 | } else { 445 | mask = NULL; 446 | } 447 | 448 | // mask file loaded only if heightmask isn't already assigned 449 | if (CONFIG.mask != NULL && mask == NULL) { 450 | 451 | if ((mask = ReadHeightmap(CONFIG.mask)) == NULL) { 452 | return 1; 453 | } 454 | 455 | if ((mask->width != hm->width) || (mask->height != hm->height)) { 456 | fprintf(stderr, "Mask dimensions do not match heightmap dimensions.\n"); 457 | fprintf(stderr, "Heightmap width: %u, height: %u\n", hm->width, hm->height); 458 | return 1; 459 | } 460 | } 461 | 462 | if ((r = HeightmapToSTL(hm)) != TRIX_OK) { 463 | fprintf(stderr, "Heightmap conversion failed (%d)\n", (int)r); 464 | return 1; 465 | } 466 | 467 | FreeHeightmap(&hm); 468 | 469 | // free mask iff it is its own image 470 | if (mask != NULL && !CONFIG.heightmask) { 471 | FreeHeightmap(&mask); 472 | } 473 | 474 | return 0; 475 | } 476 | -------------------------------------------------------------------------------- /stb_image.c: -------------------------------------------------------------------------------- 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-per-channel 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 194 | #endif 195 | 196 | #define STBI_VERSION 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 // ldexp 338 | #include // strcmp, strtok 339 | #endif 340 | 341 | #ifndef STBI_NO_STDIO 342 | #include 343 | #endif 344 | #include 345 | #include 346 | #include 347 | #include 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) 376 | 377 | #ifdef _MSC_VER 378 | #define STBI_HAS_LROTL 379 | #endif 380 | 381 | #ifdef STBI_HAS_LROTL 382 | #define stbi_lrot(x,y) _lrotl(x,y) 383 | #else 384 | #define stbi_lrot(x,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; 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_CUR); 442 | } 443 | 444 | static int stdio_eof(void *user) 445 | { 446 | return feof((FILE*) user); 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) 0 515 | #elif defined(STBI_FAILURE_USERMSG) 516 | #define e(x,y) e(y) 517 | #else 518 | #define e(x,y) e(x) 519 | #endif 520 | 521 | #define epf(x,y) ((float *) (e(x,y)?NULL:NULL)) 522 | #define epuc(x,y) ((unsigned char *) (e(x,y)?NULL:NULL)) 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"); 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"); 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"); 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"); 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); 651 | STBI_NOTUSED(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); 841 | 842 | good = (unsigned char *) malloc(req_comp * x * y); 843 | if (good == NULL) { 844 | free(data); 845 | return epuc("outofmem", "Out of memory"); 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)) 853 | #define CASE(a,b) case COMBO(a,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)) { 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); 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) { free(data); return epf("outofmem", "Out of memory"); } 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)) 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) { free(data); return epuc("outofmem", "Out of memory"); } 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); 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); 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_BITS 9 // larger handles more cases; smaller stomps less cache 952 | 953 | typedef struct 954 | { 955 | uint8 fast[1 << FAST_BITS]; 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"); 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_BITS); 1031 | for (i=0; i < k; ++i) { 1032 | int s = h->size[i]; 1033 | if (s <= FAST_BITS) { 1034 | int c = h->code[i] << (FAST_BITS-s); 1035 | int m = 1 << (FAST_BITS-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_BITS)) & ((1 << FAST_BITS)-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_BITS+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]); 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); 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"); 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"); 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)) 1205 | #define fsh(x) ((x) << 12) 1206 | 1207 | // derived from jidctint -- DCT_ISLOW 1208 | #define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ 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); \ 1213 | t2 = p1 + p3*f2f(-1.847759065f); \ 1214 | t3 = p1 + p2*f2f( 0.765366865f); \ 1215 | p2 = s0; \ 1216 | p3 = s4; \ 1217 | t0 = fsh(p2+p3); \ 1218 | t1 = fsh(p2-p3); \ 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); \ 1232 | t0 = t0*f2f( 0.298631336f); \ 1233 | t1 = t1*f2f( 2.053119869f); \ 1234 | t2 = t2*f2f( 3.072711026f); \ 1235 | t3 = t3*f2f( 1.501321110f); \ 1236 | p1 = p5 + p1*f2f(-0.899976223f); \ 1237 | p2 = p5 + p2*f2f(-2.562915447f); \ 1238 | p3 = p3*f2f(-1.961570560f); \ 1239 | p4 = p4*f2f(-0.390180644f); \ 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], 1272 | d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56]) 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]) 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_none 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_none) { x = j->marker; j->marker = MARKER_none; return x; } 1330 | x = get8u(j->s); 1331 | if (x != 0xff) return MARKER_none; 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) 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_none; 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)) 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)) 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)) 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_none: // no marker found 1432 | return e("expected marker","Corrupt JPEG"); 1433 | 1434 | case 0xC2: // SOF - progressive 1435 | return e("progressive jpeg","JPEG format not supported (progressive)"); 1436 | 1437 | case 0xDD: // DRI - specify restart interval 1438 | if (get16(z->s) != 4) return e("bad DRI len","Corrupt JPEG"); 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"); 1449 | if (t > 3) return e("bad DQT table","Corrupt JPEG"); 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"); 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"); 1502 | if (Ls != 6+2*z->scan_n) return e("bad SOS len","Corrupt JPEG"); 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"); 1511 | z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return e("bad AC huff","Corrupt JPEG"); 1512 | z->order[i] = which; 1513 | } 1514 | if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG"); 1515 | get8(z->s); // should be 63, but might be 0 1516 | if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG"); 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"); // JPEG 1526 | p = get8(s); if (p != 8) return e("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline 1527 | s->img_y = get16(s); if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed 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"); // JPEG requires 1529 | c = get8(s); 1530 | if (c != 3 && c != 1) return e("bad component count","Corrupt JPEG"); // JFIF requires 1531 | s->img_n = c; 1532 | for (i=0; i < c; ++i) { 1533 | z->img_comp[i].data = NULL; 1534 | z->img_comp[i].linebuf = NULL; 1535 | } 1536 | 1537 | if (Lf != 8+3*s->img_n) return e("bad SOF len","Corrupt JPEG"); 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"); 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"); 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"); 1547 | z->img_comp[i].tq = get8(s); if (z->img_comp[i].tq > 3) return e("bad TQ","Corrupt JPEG"); 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"); 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) { 1579 | for(--i; i >= 0; --i) { 1580 | free(z->img_comp[i].raw_data); 1581 | z->img_comp[i].data = NULL; 1582 | } 1583 | return e("outofmem", "Out of memory"); 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; 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) 1595 | #define SOI(x) ((x) == 0xd8) 1596 | #define EOI(x) ((x) == 0xd9) 1597 | #define SOF(x) ((x) == 0xc0 || (x) == 0xc1) 1598 | #define SOS(x) ((x) == 0xda) 1599 | 1600 | static int decode_jpeg_header(jpeg *z, int scan) 1601 | { 1602 | int m; 1603 | z->marker = MARKER_none; // initialize cached marker to empty 1604 | m = get_marker(z); 1605 | if (!SOI(m)) return e("no SOI","Corrupt JPEG"); 1606 | if (scan == SCAN_type) return 1; 1607 | m = get_marker(z); 1608 | while (!SOF(m)) { 1609 | if (!process_marker(z,m)) return 0; 1610 | m = get_marker(z); 1611 | while (m == MARKER_none) { 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"); 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)) { 1628 | if (SOS(m)) { 1629 | if (!process_scan_header(j)) return 0; 1630 | if (!parse_entropy_coded_data(j)) return 0; 1631 | if (j->marker == MARKER_none ) { 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)) 1658 | 1659 | static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) 1660 | { 1661 | STBI_NOTUSED(out); 1662 | STBI_NOTUSED(in_far); 1663 | STBI_NOTUSED(w); 1664 | STBI_NOTUSED(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); 1673 | for (i=0; i < w; ++i) 1674 | out[i] = div4(3*in_near[i] + in_far[i] + 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); 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]); 1695 | out[i*2+1] = div4(n+input[i+1]); 1696 | } 1697 | out[i*2+0] = div4(input[w-2]*3 + input[w-1] + 2); 1698 | out[i*2+1] = input[w-1]; 1699 | 1700 | STBI_NOTUSED(in_far); 1701 | STBI_NOTUSED(hs); 1702 | 1703 | return out; 1704 | } 1705 | 1706 | #define div16(x) ((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); 1714 | return out; 1715 | } 1716 | 1717 | t1 = 3*in_near[0] + in_far[0]; 1718 | out[0] = div4(t1+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); 1723 | out[i*2 ] = div16(3*t1 + t0 + 8); 1724 | } 1725 | out[w*2-1] = div4(t1+2); 1726 | 1727 | STBI_NOTUSED(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 | in_far = in_far; 1737 | for (i=0; i < w; ++i) 1738 | for (j=0; j < hs; ++j) 1739 | out[i*hs+j] = in_near[i]; 1740 | return out; 1741 | } 1742 | 1743 | #define float2fixed(x) ((int) ((x) * 65536 + 0.5)) 1744 | 1745 | // 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro) 1746 | // VC6 without processor=Pro is generating multiple LEAs per multiply! 1747 | static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step) 1748 | { 1749 | int i; 1750 | for (i=0; i < count; ++i) { 1751 | int y_fixed = (y[i] << 16) + 32768; // rounding 1752 | int r,g,b; 1753 | int cr = pcr[i] - 128; 1754 | int cb = pcb[i] - 128; 1755 | r = y_fixed + cr*float2fixed(1.40200f); 1756 | g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); 1757 | b = y_fixed + cb*float2fixed(1.77200f); 1758 | r >>= 16; 1759 | g >>= 16; 1760 | b >>= 16; 1761 | if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } 1762 | if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } 1763 | if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } 1764 | out[0] = (uint8)r; 1765 | out[1] = (uint8)g; 1766 | out[2] = (uint8)b; 1767 | out[3] = 255; 1768 | out += step; 1769 | } 1770 | } 1771 | 1772 | #ifdef STBI_SIMD 1773 | static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row; 1774 | 1775 | void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func) 1776 | { 1777 | stbi_YCbCr_installed = func; 1778 | } 1779 | #endif 1780 | 1781 | 1782 | // clean up the temporary component buffers 1783 | static void cleanup_jpeg(jpeg *j) 1784 | { 1785 | int i; 1786 | for (i=0; i < j->s->img_n; ++i) { 1787 | if (j->img_comp[i].data) { 1788 | free(j->img_comp[i].raw_data); 1789 | j->img_comp[i].data = NULL; 1790 | } 1791 | if (j->img_comp[i].linebuf) { 1792 | free(j->img_comp[i].linebuf); 1793 | j->img_comp[i].linebuf = NULL; 1794 | } 1795 | } 1796 | } 1797 | 1798 | typedef struct 1799 | { 1800 | resample_row_func resample; 1801 | uint8 *line0,*line1; 1802 | int hs,vs; // expansion factor in each axis 1803 | int w_lores; // horizontal pixels pre-expansion 1804 | int ystep; // how far through vertical expansion we are 1805 | int ypos; // which pre-expansion row we're on 1806 | } stbi_resample; 1807 | 1808 | static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) 1809 | { 1810 | int n, decode_n; 1811 | // validate req_comp 1812 | if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); 1813 | z->s->img_n = 0; 1814 | 1815 | // load a jpeg image from whichever source 1816 | if (!decode_jpeg_image(z)) { cleanup_jpeg(z); return NULL; } 1817 | 1818 | // determine actual number of components to generate 1819 | n = req_comp ? req_comp : z->s->img_n; 1820 | 1821 | if (z->s->img_n == 3 && n < 3) 1822 | decode_n = 1; 1823 | else 1824 | decode_n = z->s->img_n; 1825 | 1826 | // resample and color-convert 1827 | { 1828 | int k; 1829 | uint i,j; 1830 | uint8 *output; 1831 | uint8 *coutput[4]; 1832 | 1833 | stbi_resample res_comp[4]; 1834 | 1835 | for (k=0; k < decode_n; ++k) { 1836 | stbi_resample *r = &res_comp[k]; 1837 | 1838 | // allocate line buffer big enough for upsampling off the edges 1839 | // with upsample factor of 4 1840 | z->img_comp[k].linebuf = (uint8 *) malloc(z->s->img_x + 3); 1841 | if (!z->img_comp[k].linebuf) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } 1842 | 1843 | r->hs = z->img_h_max / z->img_comp[k].h; 1844 | r->vs = z->img_v_max / z->img_comp[k].v; 1845 | r->ystep = r->vs >> 1; 1846 | r->w_lores = (z->s->img_x + r->hs-1) / r->hs; 1847 | r->ypos = 0; 1848 | r->line0 = r->line1 = z->img_comp[k].data; 1849 | 1850 | if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; 1851 | else if (r->hs == 1 && r->vs == 2) r->resample = resample_row_v_2; 1852 | else if (r->hs == 2 && r->vs == 1) r->resample = resample_row_h_2; 1853 | else if (r->hs == 2 && r->vs == 2) r->resample = resample_row_hv_2; 1854 | else r->resample = resample_row_generic; 1855 | } 1856 | 1857 | // can't error after this so, this is safe 1858 | output = (uint8 *) malloc(n * z->s->img_x * z->s->img_y + 1); 1859 | if (!output) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } 1860 | 1861 | // now go ahead and resample 1862 | for (j=0; j < z->s->img_y; ++j) { 1863 | uint8 *out = output + n * z->s->img_x * j; 1864 | for (k=0; k < decode_n; ++k) { 1865 | stbi_resample *r = &res_comp[k]; 1866 | int y_bot = r->ystep >= (r->vs >> 1); 1867 | coutput[k] = r->resample(z->img_comp[k].linebuf, 1868 | y_bot ? r->line1 : r->line0, 1869 | y_bot ? r->line0 : r->line1, 1870 | r->w_lores, r->hs); 1871 | if (++r->ystep >= r->vs) { 1872 | r->ystep = 0; 1873 | r->line0 = r->line1; 1874 | if (++r->ypos < z->img_comp[k].y) 1875 | r->line1 += z->img_comp[k].w2; 1876 | } 1877 | } 1878 | if (n >= 3) { 1879 | uint8 *y = coutput[0]; 1880 | if (z->s->img_n == 3) { 1881 | #ifdef STBI_SIMD 1882 | stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n); 1883 | #else 1884 | YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s->img_x, n); 1885 | #endif 1886 | } else 1887 | for (i=0; i < z->s->img_x; ++i) { 1888 | out[0] = out[1] = out[2] = y[i]; 1889 | out[3] = 255; // not used if n==3 1890 | out += n; 1891 | } 1892 | } else { 1893 | uint8 *y = coutput[0]; 1894 | if (n == 1) 1895 | for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; 1896 | else 1897 | for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; 1898 | } 1899 | } 1900 | cleanup_jpeg(z); 1901 | *out_x = z->s->img_x; 1902 | *out_y = z->s->img_y; 1903 | if (comp) *comp = z->s->img_n; // report original components, not output 1904 | return output; 1905 | } 1906 | } 1907 | 1908 | static unsigned char *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp) 1909 | { 1910 | jpeg j; 1911 | j.s = s; 1912 | return load_jpeg_image(&j, x,y,comp,req_comp); 1913 | } 1914 | 1915 | static int stbi_jpeg_test(stbi *s) 1916 | { 1917 | int r; 1918 | jpeg j; 1919 | j.s = s; 1920 | r = decode_jpeg_header(&j, SCAN_type); 1921 | stbi_rewind(s); 1922 | return r; 1923 | } 1924 | 1925 | static int stbi_jpeg_info_raw(jpeg *j, int *x, int *y, int *comp) 1926 | { 1927 | if (!decode_jpeg_header(j, SCAN_header)) { 1928 | stbi_rewind( j->s ); 1929 | return 0; 1930 | } 1931 | if (x) *x = j->s->img_x; 1932 | if (y) *y = j->s->img_y; 1933 | if (comp) *comp = j->s->img_n; 1934 | return 1; 1935 | } 1936 | 1937 | static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp) 1938 | { 1939 | jpeg j; 1940 | j.s = s; 1941 | return stbi_jpeg_info_raw(&j, x, y, comp); 1942 | } 1943 | 1944 | // public domain zlib decode v0.2 Sean Barrett 2006-11-18 1945 | // simple implementation 1946 | // - all input must be provided in an upfront buffer 1947 | // - all output is written to a single output buffer (can malloc/realloc) 1948 | // performance 1949 | // - fast huffman 1950 | 1951 | // fast-way is faster to check than jpeg huffman, but slow way is slower 1952 | #define ZFAST_BITS 9 // accelerate all cases in default tables 1953 | #define ZFAST_MASK ((1 << ZFAST_BITS) - 1) 1954 | 1955 | // zlib-style huffman encoding 1956 | // (jpegs packs from left, zlib from right, so can't share code) 1957 | typedef struct 1958 | { 1959 | uint16 fast[1 << ZFAST_BITS]; 1960 | uint16 firstcode[16]; 1961 | int maxcode[17]; 1962 | uint16 firstsymbol[16]; 1963 | uint8 size[288]; 1964 | uint16 value[288]; 1965 | } zhuffman; 1966 | 1967 | stbi_inline static int bitreverse16(int n) 1968 | { 1969 | n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); 1970 | n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); 1971 | n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); 1972 | n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 1973 | return n; 1974 | } 1975 | 1976 | stbi_inline static int bit_reverse(int v, int bits) 1977 | { 1978 | assert(bits <= 16); 1979 | // to bit reverse n bits, reverse 16 and shift 1980 | // e.g. 11 bits, bit reverse and shift away 5 1981 | return bitreverse16(v) >> (16-bits); 1982 | } 1983 | 1984 | static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num) 1985 | { 1986 | int i,k=0; 1987 | int code, next_code[16], sizes[17]; 1988 | 1989 | // DEFLATE spec for generating codes 1990 | memset(sizes, 0, sizeof(sizes)); 1991 | memset(z->fast, 255, sizeof(z->fast)); 1992 | for (i=0; i < num; ++i) 1993 | ++sizes[sizelist[i]]; 1994 | sizes[0] = 0; 1995 | for (i=1; i < 16; ++i) 1996 | assert(sizes[i] <= (1 << i)); 1997 | code = 0; 1998 | for (i=1; i < 16; ++i) { 1999 | next_code[i] = code; 2000 | z->firstcode[i] = (uint16) code; 2001 | z->firstsymbol[i] = (uint16) k; 2002 | code = (code + sizes[i]); 2003 | if (sizes[i]) 2004 | if (code-1 >= (1 << i)) return e("bad codelengths","Corrupt JPEG"); 2005 | z->maxcode[i] = code << (16-i); // preshift for inner loop 2006 | code <<= 1; 2007 | k += sizes[i]; 2008 | } 2009 | z->maxcode[16] = 0x10000; // sentinel 2010 | for (i=0; i < num; ++i) { 2011 | int s = sizelist[i]; 2012 | if (s) { 2013 | int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; 2014 | z->size[c] = (uint8)s; 2015 | z->value[c] = (uint16)i; 2016 | if (s <= ZFAST_BITS) { 2017 | int k = bit_reverse(next_code[s],s); 2018 | while (k < (1 << ZFAST_BITS)) { 2019 | z->fast[k] = (uint16) c; 2020 | k += (1 << s); 2021 | } 2022 | } 2023 | ++next_code[s]; 2024 | } 2025 | } 2026 | return 1; 2027 | } 2028 | 2029 | // zlib-from-memory implementation for PNG reading 2030 | // because PNG allows splitting the zlib stream arbitrarily, 2031 | // and it's annoying structurally to have PNG call ZLIB call PNG, 2032 | // we require PNG read all the IDATs and combine them into a single 2033 | // memory buffer 2034 | 2035 | typedef struct 2036 | { 2037 | uint8 *zbuffer, *zbuffer_end; 2038 | int num_bits; 2039 | uint32 code_buffer; 2040 | 2041 | char *zout; 2042 | char *zout_start; 2043 | char *zout_end; 2044 | int z_expandable; 2045 | 2046 | zhuffman z_length, z_distance; 2047 | } zbuf; 2048 | 2049 | stbi_inline static int zget8(zbuf *z) 2050 | { 2051 | if (z->zbuffer >= z->zbuffer_end) return 0; 2052 | return *z->zbuffer++; 2053 | } 2054 | 2055 | static void fill_bits(zbuf *z) 2056 | { 2057 | do { 2058 | assert(z->code_buffer < (1U << z->num_bits)); 2059 | z->code_buffer |= zget8(z) << z->num_bits; 2060 | z->num_bits += 8; 2061 | } while (z->num_bits <= 24); 2062 | } 2063 | 2064 | stbi_inline static unsigned int zreceive(zbuf *z, int n) 2065 | { 2066 | unsigned int k; 2067 | if (z->num_bits < n) fill_bits(z); 2068 | k = z->code_buffer & ((1 << n) - 1); 2069 | z->code_buffer >>= n; 2070 | z->num_bits -= n; 2071 | return k; 2072 | } 2073 | 2074 | stbi_inline static int zhuffman_decode(zbuf *a, zhuffman *z) 2075 | { 2076 | int b,s,k; 2077 | if (a->num_bits < 16) fill_bits(a); 2078 | b = z->fast[a->code_buffer & ZFAST_MASK]; 2079 | if (b < 0xffff) { 2080 | s = z->size[b]; 2081 | a->code_buffer >>= s; 2082 | a->num_bits -= s; 2083 | return z->value[b]; 2084 | } 2085 | 2086 | // not resolved by fast table, so compute it the slow way 2087 | // use jpeg approach, which requires MSbits at top 2088 | k = bit_reverse(a->code_buffer, 16); 2089 | for (s=ZFAST_BITS+1; ; ++s) 2090 | if (k < z->maxcode[s]) 2091 | break; 2092 | if (s == 16) return -1; // invalid code! 2093 | // code size is s, so: 2094 | b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; 2095 | assert(z->size[b] == s); 2096 | a->code_buffer >>= s; 2097 | a->num_bits -= s; 2098 | return z->value[b]; 2099 | } 2100 | 2101 | static int expand(zbuf *z, int n) // need to make room for n bytes 2102 | { 2103 | char *q; 2104 | int cur, limit; 2105 | if (!z->z_expandable) return e("output buffer limit","Corrupt PNG"); 2106 | cur = (int) (z->zout - z->zout_start); 2107 | limit = (int) (z->zout_end - z->zout_start); 2108 | while (cur + n > limit) 2109 | limit *= 2; 2110 | q = (char *) realloc(z->zout_start, limit); 2111 | if (q == NULL) return e("outofmem", "Out of memory"); 2112 | z->zout_start = q; 2113 | z->zout = q + cur; 2114 | z->zout_end = q + limit; 2115 | return 1; 2116 | } 2117 | 2118 | static int length_base[31] = { 2119 | 3,4,5,6,7,8,9,10,11,13, 2120 | 15,17,19,23,27,31,35,43,51,59, 2121 | 67,83,99,115,131,163,195,227,258,0,0 }; 2122 | 2123 | static int length_extra[31]= 2124 | { 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 }; 2125 | 2126 | static int dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 2127 | 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; 2128 | 2129 | static int dist_extra[32] = 2130 | { 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}; 2131 | 2132 | static int parse_huffman_block(zbuf *a) 2133 | { 2134 | for(;;) { 2135 | int z = zhuffman_decode(a, &a->z_length); 2136 | if (z < 256) { 2137 | if (z < 0) return e("bad huffman code","Corrupt PNG"); // error in huffman codes 2138 | if (a->zout >= a->zout_end) if (!expand(a, 1)) return 0; 2139 | *a->zout++ = (char) z; 2140 | } else { 2141 | uint8 *p; 2142 | int len,dist; 2143 | if (z == 256) return 1; 2144 | z -= 257; 2145 | len = length_base[z]; 2146 | if (length_extra[z]) len += zreceive(a, length_extra[z]); 2147 | z = zhuffman_decode(a, &a->z_distance); 2148 | if (z < 0) return e("bad huffman code","Corrupt PNG"); 2149 | dist = dist_base[z]; 2150 | if (dist_extra[z]) dist += zreceive(a, dist_extra[z]); 2151 | if (a->zout - a->zout_start < dist) return e("bad dist","Corrupt PNG"); 2152 | if (a->zout + len > a->zout_end) if (!expand(a, len)) return 0; 2153 | p = (uint8 *) (a->zout - dist); 2154 | while (len--) 2155 | *a->zout++ = *p++; 2156 | } 2157 | } 2158 | } 2159 | 2160 | static int compute_huffman_codes(zbuf *a) 2161 | { 2162 | static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; 2163 | zhuffman z_codelength; 2164 | uint8 lencodes[286+32+137];//padding for maximum single op 2165 | uint8 codelength_sizes[19]; 2166 | int i,n; 2167 | 2168 | int hlit = zreceive(a,5) + 257; 2169 | int hdist = zreceive(a,5) + 1; 2170 | int hclen = zreceive(a,4) + 4; 2171 | 2172 | memset(codelength_sizes, 0, sizeof(codelength_sizes)); 2173 | for (i=0; i < hclen; ++i) { 2174 | int s = zreceive(a,3); 2175 | codelength_sizes[length_dezigzag[i]] = (uint8) s; 2176 | } 2177 | if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; 2178 | 2179 | n = 0; 2180 | while (n < hlit + hdist) { 2181 | int c = zhuffman_decode(a, &z_codelength); 2182 | assert(c >= 0 && c < 19); 2183 | if (c < 16) 2184 | lencodes[n++] = (uint8) c; 2185 | else if (c == 16) { 2186 | c = zreceive(a,2)+3; 2187 | memset(lencodes+n, lencodes[n-1], c); 2188 | n += c; 2189 | } else if (c == 17) { 2190 | c = zreceive(a,3)+3; 2191 | memset(lencodes+n, 0, c); 2192 | n += c; 2193 | } else { 2194 | assert(c == 18); 2195 | c = zreceive(a,7)+11; 2196 | memset(lencodes+n, 0, c); 2197 | n += c; 2198 | } 2199 | } 2200 | if (n != hlit+hdist) return e("bad codelengths","Corrupt PNG"); 2201 | if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; 2202 | if (!zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; 2203 | return 1; 2204 | } 2205 | 2206 | static int parse_uncompressed_block(zbuf *a) 2207 | { 2208 | uint8 header[4]; 2209 | int len,nlen,k; 2210 | if (a->num_bits & 7) 2211 | zreceive(a, a->num_bits & 7); // discard 2212 | // drain the bit-packed data into header 2213 | k = 0; 2214 | while (a->num_bits > 0) { 2215 | header[k++] = (uint8) (a->code_buffer & 255); // wtf this warns? 2216 | a->code_buffer >>= 8; 2217 | a->num_bits -= 8; 2218 | } 2219 | assert(a->num_bits == 0); 2220 | // now fill header the normal way 2221 | while (k < 4) 2222 | header[k++] = (uint8) zget8(a); 2223 | len = header[1] * 256 + header[0]; 2224 | nlen = header[3] * 256 + header[2]; 2225 | if (nlen != (len ^ 0xffff)) return e("zlib corrupt","Corrupt PNG"); 2226 | if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer","Corrupt PNG"); 2227 | if (a->zout + len > a->zout_end) 2228 | if (!expand(a, len)) return 0; 2229 | memcpy(a->zout, a->zbuffer, len); 2230 | a->zbuffer += len; 2231 | a->zout += len; 2232 | return 1; 2233 | } 2234 | 2235 | static int parse_zlib_header(zbuf *a) 2236 | { 2237 | int cmf = zget8(a); 2238 | int cm = cmf & 15; 2239 | /* int cinfo = cmf >> 4; */ 2240 | int flg = zget8(a); 2241 | if ((cmf*256+flg) % 31 != 0) return e("bad zlib header","Corrupt PNG"); // zlib spec 2242 | if (flg & 32) return e("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png 2243 | if (cm != 8) return e("bad compression","Corrupt PNG"); // DEFLATE required for png 2244 | // window = 1 << (8 + cinfo)... but who cares, we fully buffer output 2245 | return 1; 2246 | } 2247 | 2248 | // @TODO: should statically initialize these for optimal thread safety 2249 | static uint8 default_length[288], default_distance[32]; 2250 | static void init_defaults(void) 2251 | { 2252 | int i; // use <= to match clearly with spec 2253 | for (i=0; i <= 143; ++i) default_length[i] = 8; 2254 | for ( ; i <= 255; ++i) default_length[i] = 9; 2255 | for ( ; i <= 279; ++i) default_length[i] = 7; 2256 | for ( ; i <= 287; ++i) default_length[i] = 8; 2257 | 2258 | for (i=0; i <= 31; ++i) default_distance[i] = 5; 2259 | } 2260 | 2261 | int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead 2262 | static int parse_zlib(zbuf *a, int parse_header) 2263 | { 2264 | int final, type; 2265 | if (parse_header) 2266 | if (!parse_zlib_header(a)) return 0; 2267 | a->num_bits = 0; 2268 | a->code_buffer = 0; 2269 | do { 2270 | final = zreceive(a,1); 2271 | type = zreceive(a,2); 2272 | if (type == 0) { 2273 | if (!parse_uncompressed_block(a)) return 0; 2274 | } else if (type == 3) { 2275 | return 0; 2276 | } else { 2277 | if (type == 1) { 2278 | // use fixed code lengths 2279 | if (!default_distance[31]) init_defaults(); 2280 | if (!zbuild_huffman(&a->z_length , default_length , 288)) return 0; 2281 | if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0; 2282 | } else { 2283 | if (!compute_huffman_codes(a)) return 0; 2284 | } 2285 | if (!parse_huffman_block(a)) return 0; 2286 | } 2287 | if (stbi_png_partial && a->zout - a->zout_start > 65536) 2288 | break; 2289 | } while (!final); 2290 | return 1; 2291 | } 2292 | 2293 | static int do_zlib(zbuf *a, char *obuf, int olen, int exp, int parse_header) 2294 | { 2295 | a->zout_start = obuf; 2296 | a->zout = obuf; 2297 | a->zout_end = obuf + olen; 2298 | a->z_expandable = exp; 2299 | 2300 | return parse_zlib(a, parse_header); 2301 | } 2302 | 2303 | char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) 2304 | { 2305 | zbuf a; 2306 | char *p = (char *) malloc(initial_size); 2307 | if (p == NULL) return NULL; 2308 | a.zbuffer = (uint8 *) buffer; 2309 | a.zbuffer_end = (uint8 *) buffer + len; 2310 | if (do_zlib(&a, p, initial_size, 1, 1)) { 2311 | if (outlen) *outlen = (int) (a.zout - a.zout_start); 2312 | return a.zout_start; 2313 | } else { 2314 | free(a.zout_start); 2315 | return NULL; 2316 | } 2317 | } 2318 | 2319 | char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) 2320 | { 2321 | return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); 2322 | } 2323 | 2324 | char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) 2325 | { 2326 | zbuf a; 2327 | char *p = (char *) malloc(initial_size); 2328 | if (p == NULL) return NULL; 2329 | a.zbuffer = (uint8 *) buffer; 2330 | a.zbuffer_end = (uint8 *) buffer + len; 2331 | if (do_zlib(&a, p, initial_size, 1, parse_header)) { 2332 | if (outlen) *outlen = (int) (a.zout - a.zout_start); 2333 | return a.zout_start; 2334 | } else { 2335 | free(a.zout_start); 2336 | return NULL; 2337 | } 2338 | } 2339 | 2340 | int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) 2341 | { 2342 | zbuf a; 2343 | a.zbuffer = (uint8 *) ibuffer; 2344 | a.zbuffer_end = (uint8 *) ibuffer + ilen; 2345 | if (do_zlib(&a, obuffer, olen, 0, 1)) 2346 | return (int) (a.zout - a.zout_start); 2347 | else 2348 | return -1; 2349 | } 2350 | 2351 | char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) 2352 | { 2353 | zbuf a; 2354 | char *p = (char *) malloc(16384); 2355 | if (p == NULL) return NULL; 2356 | a.zbuffer = (uint8 *) buffer; 2357 | a.zbuffer_end = (uint8 *) buffer+len; 2358 | if (do_zlib(&a, p, 16384, 1, 0)) { 2359 | if (outlen) *outlen = (int) (a.zout - a.zout_start); 2360 | return a.zout_start; 2361 | } else { 2362 | free(a.zout_start); 2363 | return NULL; 2364 | } 2365 | } 2366 | 2367 | int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) 2368 | { 2369 | zbuf a; 2370 | a.zbuffer = (uint8 *) ibuffer; 2371 | a.zbuffer_end = (uint8 *) ibuffer + ilen; 2372 | if (do_zlib(&a, obuffer, olen, 0, 0)) 2373 | return (int) (a.zout - a.zout_start); 2374 | else 2375 | return -1; 2376 | } 2377 | 2378 | // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 2379 | // simple implementation 2380 | // - only 8-bit samples 2381 | // - no CRC checking 2382 | // - allocates lots of intermediate memory 2383 | // - avoids problem of streaming data between subsystems 2384 | // - avoids explicit window management 2385 | // performance 2386 | // - uses stb_zlib, a PD zlib implementation with fast huffman decoding 2387 | 2388 | 2389 | typedef struct 2390 | { 2391 | uint32 length; 2392 | uint32 type; 2393 | } chunk; 2394 | 2395 | #define PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) 2396 | 2397 | static chunk get_chunk_header(stbi *s) 2398 | { 2399 | chunk c; 2400 | c.length = get32(s); 2401 | c.type = get32(s); 2402 | return c; 2403 | } 2404 | 2405 | static int check_png_header(stbi *s) 2406 | { 2407 | static uint8 png_sig[8] = { 137,80,78,71,13,10,26,10 }; 2408 | int i; 2409 | for (i=0; i < 8; ++i) 2410 | if (get8u(s) != png_sig[i]) return e("bad png sig","Not a PNG"); 2411 | return 1; 2412 | } 2413 | 2414 | typedef struct 2415 | { 2416 | stbi *s; 2417 | uint8 *idata, *expanded, *out; 2418 | } png; 2419 | 2420 | 2421 | enum { 2422 | F_none=0, F_sub=1, F_up=2, F_avg=3, F_paeth=4, 2423 | F_avg_first, F_paeth_first 2424 | }; 2425 | 2426 | static uint8 first_row_filter[5] = 2427 | { 2428 | F_none, F_sub, F_none, F_avg_first, F_paeth_first 2429 | }; 2430 | 2431 | static int paeth(int a, int b, int c) 2432 | { 2433 | int p = a + b - c; 2434 | int pa = abs(p-a); 2435 | int pb = abs(p-b); 2436 | int pc = abs(p-c); 2437 | if (pa <= pb && pa <= pc) return a; 2438 | if (pb <= pc) return b; 2439 | return c; 2440 | } 2441 | 2442 | // create the png data from post-deflated data 2443 | static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y) 2444 | { 2445 | stbi *s = a->s; 2446 | uint32 i,j,stride = x*out_n; 2447 | int k; 2448 | int img_n = s->img_n; // copy it into a local for later 2449 | assert(out_n == s->img_n || out_n == s->img_n+1); 2450 | if (stbi_png_partial) y = 1; 2451 | a->out = (uint8 *) malloc(x * y * out_n); 2452 | if (!a->out) return e("outofmem", "Out of memory"); 2453 | if (!stbi_png_partial) { 2454 | if (s->img_x == x && s->img_y == y) { 2455 | if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); 2456 | } else { // interlaced: 2457 | if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); 2458 | } 2459 | } 2460 | for (j=0; j < y; ++j) { 2461 | uint8 *cur = a->out + stride*j; 2462 | uint8 *prior = cur - stride; 2463 | int filter = *raw++; 2464 | if (filter > 4) return e("invalid filter","Corrupt PNG"); 2465 | // if first row, use special filter that doesn't sample previous row 2466 | if (j == 0) filter = first_row_filter[filter]; 2467 | // handle first pixel explicitly 2468 | for (k=0; k < img_n; ++k) { 2469 | switch (filter) { 2470 | case F_none : cur[k] = raw[k]; break; 2471 | case F_sub : cur[k] = raw[k]; break; 2472 | case F_up : cur[k] = raw[k] + prior[k]; break; 2473 | case F_avg : cur[k] = raw[k] + (prior[k]>>1); break; 2474 | case F_paeth : cur[k] = (uint8) (raw[k] + paeth(0,prior[k],0)); break; 2475 | case F_avg_first : cur[k] = raw[k]; break; 2476 | case F_paeth_first: cur[k] = raw[k]; break; 2477 | } 2478 | } 2479 | if (img_n != out_n) cur[img_n] = 255; 2480 | raw += img_n; 2481 | cur += out_n; 2482 | prior += out_n; 2483 | // this is a little gross, so that we don't switch per-pixel or per-component 2484 | if (img_n == out_n) { 2485 | #define CASE(f) \ 2486 | case f: \ 2487 | for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ 2488 | for (k=0; k < img_n; ++k) 2489 | switch (filter) { 2490 | CASE(F_none) cur[k] = raw[k]; break; 2491 | CASE(F_sub) cur[k] = raw[k] + cur[k-img_n]; break; 2492 | CASE(F_up) cur[k] = raw[k] + prior[k]; break; 2493 | CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-img_n])>>1); break; 2494 | CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],prior[k],prior[k-img_n])); break; 2495 | CASE(F_avg_first) cur[k] = raw[k] + (cur[k-img_n] >> 1); break; 2496 | CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],0,0)); break; 2497 | } 2498 | #undef CASE 2499 | } else { 2500 | assert(img_n+1 == out_n); 2501 | #define CASE(f) \ 2502 | case f: \ 2503 | for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ 2504 | for (k=0; k < img_n; ++k) 2505 | switch (filter) { 2506 | CASE(F_none) cur[k] = raw[k]; break; 2507 | CASE(F_sub) cur[k] = raw[k] + cur[k-out_n]; break; 2508 | CASE(F_up) cur[k] = raw[k] + prior[k]; break; 2509 | CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-out_n])>>1); break; 2510 | CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; 2511 | CASE(F_avg_first) cur[k] = raw[k] + (cur[k-out_n] >> 1); break; 2512 | CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],0,0)); break; 2513 | } 2514 | #undef CASE 2515 | } 2516 | } 2517 | return 1; 2518 | } 2519 | 2520 | static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced) 2521 | { 2522 | uint8 *final; 2523 | int p; 2524 | int save; 2525 | if (!interlaced) 2526 | return create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y); 2527 | save = stbi_png_partial; 2528 | stbi_png_partial = 0; 2529 | 2530 | // de-interlacing 2531 | final = (uint8 *) malloc(a->s->img_x * a->s->img_y * out_n); 2532 | for (p=0; p < 7; ++p) { 2533 | int xorig[] = { 0,4,0,2,0,1,0 }; 2534 | int yorig[] = { 0,0,4,0,2,0,1 }; 2535 | int xspc[] = { 8,8,4,4,2,2,1 }; 2536 | int yspc[] = { 8,8,8,4,4,2,2 }; 2537 | int i,j,x,y; 2538 | // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 2539 | x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; 2540 | y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; 2541 | if (x && y) { 2542 | if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) { 2543 | free(final); 2544 | return 0; 2545 | } 2546 | for (j=0; j < y; ++j) 2547 | for (i=0; i < x; ++i) 2548 | memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n, 2549 | a->out + (j*x+i)*out_n, out_n); 2550 | free(a->out); 2551 | raw += (x*out_n+1)*y; 2552 | raw_len -= (x*out_n+1)*y; 2553 | } 2554 | } 2555 | a->out = final; 2556 | 2557 | stbi_png_partial = save; 2558 | return 1; 2559 | } 2560 | 2561 | static int compute_transparency(png *z, uint8 tc[3], int out_n) 2562 | { 2563 | stbi *s = z->s; 2564 | uint32 i, pixel_count = s->img_x * s->img_y; 2565 | uint8 *p = z->out; 2566 | 2567 | // compute color-based transparency, assuming we've 2568 | // already got 255 as the alpha value in the output 2569 | assert(out_n == 2 || out_n == 4); 2570 | 2571 | if (out_n == 2) { 2572 | for (i=0; i < pixel_count; ++i) { 2573 | p[1] = (p[0] == tc[0] ? 0 : 255); 2574 | p += 2; 2575 | } 2576 | } else { 2577 | for (i=0; i < pixel_count; ++i) { 2578 | if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) 2579 | p[3] = 0; 2580 | p += 4; 2581 | } 2582 | } 2583 | return 1; 2584 | } 2585 | 2586 | static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n) 2587 | { 2588 | uint32 i, pixel_count = a->s->img_x * a->s->img_y; 2589 | uint8 *p, *temp_out, *orig = a->out; 2590 | 2591 | p = (uint8 *) malloc(pixel_count * pal_img_n); 2592 | if (p == NULL) return e("outofmem", "Out of memory"); 2593 | 2594 | // between here and free(out) below, exitting would leak 2595 | temp_out = p; 2596 | 2597 | if (pal_img_n == 3) { 2598 | for (i=0; i < pixel_count; ++i) { 2599 | int n = orig[i]*4; 2600 | p[0] = palette[n ]; 2601 | p[1] = palette[n+1]; 2602 | p[2] = palette[n+2]; 2603 | p += 3; 2604 | } 2605 | } else { 2606 | for (i=0; i < pixel_count; ++i) { 2607 | int n = orig[i]*4; 2608 | p[0] = palette[n ]; 2609 | p[1] = palette[n+1]; 2610 | p[2] = palette[n+2]; 2611 | p[3] = palette[n+3]; 2612 | p += 4; 2613 | } 2614 | } 2615 | free(a->out); 2616 | a->out = temp_out; 2617 | 2618 | STBI_NOTUSED(len); 2619 | 2620 | return 1; 2621 | } 2622 | 2623 | static int stbi_unpremultiply_on_load = 0; 2624 | static int stbi_de_iphone_flag = 0; 2625 | 2626 | void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) 2627 | { 2628 | stbi_unpremultiply_on_load = flag_true_if_should_unpremultiply; 2629 | } 2630 | void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) 2631 | { 2632 | stbi_de_iphone_flag = flag_true_if_should_convert; 2633 | } 2634 | 2635 | static void stbi_de_iphone(png *z) 2636 | { 2637 | stbi *s = z->s; 2638 | uint32 i, pixel_count = s->img_x * s->img_y; 2639 | uint8 *p = z->out; 2640 | 2641 | if (s->img_out_n == 3) { // convert bgr to rgb 2642 | for (i=0; i < pixel_count; ++i) { 2643 | uint8 t = p[0]; 2644 | p[0] = p[2]; 2645 | p[2] = t; 2646 | p += 3; 2647 | } 2648 | } else { 2649 | assert(s->img_out_n == 4); 2650 | if (stbi_unpremultiply_on_load) { 2651 | // convert bgr to rgb and unpremultiply 2652 | for (i=0; i < pixel_count; ++i) { 2653 | uint8 a = p[3]; 2654 | uint8 t = p[0]; 2655 | if (a) { 2656 | p[0] = p[2] * 255 / a; 2657 | p[1] = p[1] * 255 / a; 2658 | p[2] = t * 255 / a; 2659 | } else { 2660 | p[0] = p[2]; 2661 | p[2] = t; 2662 | } 2663 | p += 4; 2664 | } 2665 | } else { 2666 | // convert bgr to rgb 2667 | for (i=0; i < pixel_count; ++i) { 2668 | uint8 t = p[0]; 2669 | p[0] = p[2]; 2670 | p[2] = t; 2671 | p += 4; 2672 | } 2673 | } 2674 | } 2675 | } 2676 | 2677 | static int parse_png_file(png *z, int scan, int req_comp) 2678 | { 2679 | uint8 palette[1024], pal_img_n=0; 2680 | uint8 has_trans=0, tc[3]; 2681 | uint32 ioff=0, idata_limit=0, i, pal_len=0; 2682 | int first=1,k,interlace=0, iphone=0; 2683 | stbi *s = z->s; 2684 | 2685 | z->expanded = NULL; 2686 | z->idata = NULL; 2687 | z->out = NULL; 2688 | 2689 | if (!check_png_header(s)) return 0; 2690 | 2691 | if (scan == SCAN_type) return 1; 2692 | 2693 | for (;;) { 2694 | chunk c = get_chunk_header(s); 2695 | switch (c.type) { 2696 | case PNG_TYPE('C','g','B','I'): 2697 | iphone = stbi_de_iphone_flag; 2698 | skip(s, c.length); 2699 | break; 2700 | case PNG_TYPE('I','H','D','R'): { 2701 | int depth,color,comp,filter; 2702 | if (!first) return e("multiple IHDR","Corrupt PNG"); 2703 | first = 0; 2704 | if (c.length != 13) return e("bad IHDR len","Corrupt PNG"); 2705 | s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)"); 2706 | s->img_y = get32(s); if (s->img_y > (1 << 24)) return e("too large","Very large image (corrupt?)"); 2707 | depth = get8(s); if (depth != 8) return e("8bit only","PNG not supported: 8-bit only"); 2708 | color = get8(s); if (color > 6) return e("bad ctype","Corrupt PNG"); 2709 | if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG"); 2710 | comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG"); 2711 | filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG"); 2712 | interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG"); 2713 | if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG"); 2714 | if (!pal_img_n) { 2715 | s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); 2716 | if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); 2717 | if (scan == SCAN_header) return 1; 2718 | } else { 2719 | // if paletted, then pal_n is our final components, and 2720 | // img_n is # components to decompress/filter. 2721 | s->img_n = 1; 2722 | if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large","Corrupt PNG"); 2723 | // if SCAN_header, have to scan to see if we have a tRNS 2724 | } 2725 | break; 2726 | } 2727 | 2728 | case PNG_TYPE('P','L','T','E'): { 2729 | if (first) return e("first not IHDR", "Corrupt PNG"); 2730 | if (c.length > 256*3) return e("invalid PLTE","Corrupt PNG"); 2731 | pal_len = c.length / 3; 2732 | if (pal_len * 3 != c.length) return e("invalid PLTE","Corrupt PNG"); 2733 | for (i=0; i < pal_len; ++i) { 2734 | palette[i*4+0] = get8u(s); 2735 | palette[i*4+1] = get8u(s); 2736 | palette[i*4+2] = get8u(s); 2737 | palette[i*4+3] = 255; 2738 | } 2739 | break; 2740 | } 2741 | 2742 | case PNG_TYPE('t','R','N','S'): { 2743 | if (first) return e("first not IHDR", "Corrupt PNG"); 2744 | if (z->idata) return e("tRNS after IDAT","Corrupt PNG"); 2745 | if (pal_img_n) { 2746 | if (scan == SCAN_header) { s->img_n = 4; return 1; } 2747 | if (pal_len == 0) return e("tRNS before PLTE","Corrupt PNG"); 2748 | if (c.length > pal_len) return e("bad tRNS len","Corrupt PNG"); 2749 | pal_img_n = 4; 2750 | for (i=0; i < c.length; ++i) 2751 | palette[i*4+3] = get8u(s); 2752 | } else { 2753 | if (!(s->img_n & 1)) return e("tRNS with alpha","Corrupt PNG"); 2754 | if (c.length != (uint32) s->img_n*2) return e("bad tRNS len","Corrupt PNG"); 2755 | has_trans = 1; 2756 | for (k=0; k < s->img_n; ++k) 2757 | tc[k] = (uint8) get16(s); // non 8-bit images will be larger 2758 | } 2759 | break; 2760 | } 2761 | 2762 | case PNG_TYPE('I','D','A','T'): { 2763 | if (first) return e("first not IHDR", "Corrupt PNG"); 2764 | if (pal_img_n && !pal_len) return e("no PLTE","Corrupt PNG"); 2765 | if (scan == SCAN_header) { s->img_n = pal_img_n; return 1; } 2766 | if (ioff + c.length > idata_limit) { 2767 | uint8 *p; 2768 | if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; 2769 | while (ioff + c.length > idata_limit) 2770 | idata_limit *= 2; 2771 | p = (uint8 *) realloc(z->idata, idata_limit); if (p == NULL) return e("outofmem", "Out of memory"); 2772 | z->idata = p; 2773 | } 2774 | if (!getn(s, z->idata+ioff,c.length)) return e("outofdata","Corrupt PNG"); 2775 | ioff += c.length; 2776 | break; 2777 | } 2778 | 2779 | case PNG_TYPE('I','E','N','D'): { 2780 | uint32 raw_len; 2781 | if (first) return e("first not IHDR", "Corrupt PNG"); 2782 | if (scan != SCAN_load) return 1; 2783 | if (z->idata == NULL) return e("no IDAT","Corrupt PNG"); 2784 | z->expanded = (uint8 *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, 16384, (int *) &raw_len, !iphone); 2785 | if (z->expanded == NULL) return 0; // zlib should set error 2786 | free(z->idata); z->idata = NULL; 2787 | if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) 2788 | s->img_out_n = s->img_n+1; 2789 | else 2790 | s->img_out_n = s->img_n; 2791 | if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; 2792 | if (has_trans) 2793 | if (!compute_transparency(z, tc, s->img_out_n)) return 0; 2794 | if (iphone && s->img_out_n > 2) 2795 | stbi_de_iphone(z); 2796 | if (pal_img_n) { 2797 | // pal_img_n == 3 or 4 2798 | s->img_n = pal_img_n; // record the actual colors we had 2799 | s->img_out_n = pal_img_n; 2800 | if (req_comp >= 3) s->img_out_n = req_comp; 2801 | if (!expand_palette(z, palette, pal_len, s->img_out_n)) 2802 | return 0; 2803 | } 2804 | free(z->expanded); z->expanded = NULL; 2805 | return 1; 2806 | } 2807 | 2808 | default: 2809 | // if critical, fail 2810 | if (first) return e("first not IHDR", "Corrupt PNG"); 2811 | if ((c.type & (1 << 29)) == 0) { 2812 | #ifndef STBI_NO_FAILURE_STRINGS 2813 | // not threadsafe 2814 | static char invalid_chunk[] = "XXXX chunk not known"; 2815 | invalid_chunk[0] = (uint8) (c.type >> 24); 2816 | invalid_chunk[1] = (uint8) (c.type >> 16); 2817 | invalid_chunk[2] = (uint8) (c.type >> 8); 2818 | invalid_chunk[3] = (uint8) (c.type >> 0); 2819 | #endif 2820 | return e(invalid_chunk, "PNG not supported: unknown chunk type"); 2821 | } 2822 | skip(s, c.length); 2823 | break; 2824 | } 2825 | // end of chunk, read and skip CRC 2826 | get32(s); 2827 | } 2828 | } 2829 | 2830 | static unsigned char *do_png(png *p, int *x, int *y, int *n, int req_comp) 2831 | { 2832 | unsigned char *result=NULL; 2833 | if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); 2834 | if (parse_png_file(p, SCAN_load, req_comp)) { 2835 | result = p->out; 2836 | p->out = NULL; 2837 | if (req_comp && req_comp != p->s->img_out_n) { 2838 | result = convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); 2839 | p->s->img_out_n = req_comp; 2840 | if (result == NULL) return result; 2841 | } 2842 | *x = p->s->img_x; 2843 | *y = p->s->img_y; 2844 | if (n) *n = p->s->img_n; 2845 | } 2846 | free(p->out); p->out = NULL; 2847 | free(p->expanded); p->expanded = NULL; 2848 | free(p->idata); p->idata = NULL; 2849 | 2850 | return result; 2851 | } 2852 | 2853 | static unsigned char *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp) 2854 | { 2855 | png p; 2856 | p.s = s; 2857 | return do_png(&p, x,y,comp,req_comp); 2858 | } 2859 | 2860 | static int stbi_png_test(stbi *s) 2861 | { 2862 | int r; 2863 | r = check_png_header(s); 2864 | stbi_rewind(s); 2865 | return r; 2866 | } 2867 | 2868 | static int stbi_png_info_raw(png *p, int *x, int *y, int *comp) 2869 | { 2870 | if (!parse_png_file(p, SCAN_header, 0)) { 2871 | stbi_rewind( p->s ); 2872 | return 0; 2873 | } 2874 | if (x) *x = p->s->img_x; 2875 | if (y) *y = p->s->img_y; 2876 | if (comp) *comp = p->s->img_n; 2877 | return 1; 2878 | } 2879 | 2880 | static int stbi_png_info(stbi *s, int *x, int *y, int *comp) 2881 | { 2882 | png p; 2883 | p.s = s; 2884 | return stbi_png_info_raw(&p, x, y, comp); 2885 | } 2886 | 2887 | // Microsoft/Windows BMP image 2888 | 2889 | static int bmp_test(stbi *s) 2890 | { 2891 | int sz; 2892 | if (get8(s) != 'B') return 0; 2893 | if (get8(s) != 'M') return 0; 2894 | get32le(s); // discard filesize 2895 | get16le(s); // discard reserved 2896 | get16le(s); // discard reserved 2897 | get32le(s); // discard data offset 2898 | sz = get32le(s); 2899 | if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1; 2900 | return 0; 2901 | } 2902 | 2903 | static int stbi_bmp_test(stbi *s) 2904 | { 2905 | int r = bmp_test(s); 2906 | stbi_rewind(s); 2907 | return r; 2908 | } 2909 | 2910 | 2911 | // returns 0..31 for the highest set bit 2912 | static int high_bit(unsigned int z) 2913 | { 2914 | int n=0; 2915 | if (z == 0) return -1; 2916 | if (z >= 0x10000) n += 16, z >>= 16; 2917 | if (z >= 0x00100) n += 8, z >>= 8; 2918 | if (z >= 0x00010) n += 4, z >>= 4; 2919 | if (z >= 0x00004) n += 2, z >>= 2; 2920 | if (z >= 0x00002) n += 1, z >>= 1; 2921 | return n; 2922 | } 2923 | 2924 | static int bitcount(unsigned int a) 2925 | { 2926 | a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 2927 | a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 2928 | a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits 2929 | a = (a + (a >> 8)); // max 16 per 8 bits 2930 | a = (a + (a >> 16)); // max 32 per 8 bits 2931 | return a & 0xff; 2932 | } 2933 | 2934 | static int shiftsigned(int v, int shift, int bits) 2935 | { 2936 | int result; 2937 | int z=0; 2938 | 2939 | if (shift < 0) v <<= -shift; 2940 | else v >>= shift; 2941 | result = v; 2942 | 2943 | z = bits; 2944 | while (z < 8) { 2945 | result += v >> z; 2946 | z += bits; 2947 | } 2948 | return result; 2949 | } 2950 | 2951 | static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) 2952 | { 2953 | uint8 *out; 2954 | unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0; 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"); 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"); 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"); 2973 | bpp = get16le(s); 2974 | if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit"); 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"); 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"); 3017 | } 3018 | } else 3019 | return epuc("bad BMP", "bad BMP"); 3020 | } 3021 | } else { 3022 | assert(hsz == 108); 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"); 3041 | if (bpp < 16) { 3042 | int z=0; 3043 | if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP"); } 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"); } 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"); } 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) 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; 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; // 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"); 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"); 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"); 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 ) 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"); 3483 | 3484 | // Check file type version. 3485 | if (get16(s) != 1) 3486 | return epuc("wrong version", "Unsupported version of PSD image"); 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"); 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"); 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"); 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"); 3533 | 3534 | // Create the destination image. 3535 | out = (stbi_uc *) malloc(4 * w*h); 3536 | if (!out) return epuc("outofmem", "Out of memory"); 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) 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"); 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"); 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)"); 3719 | if (packet->size != 8) return epuc("bad format","packet isn't 8bpp"); 3720 | } while (chained); 3721 | 3722 | *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? 3723 | 3724 | for(y=0; ytype) { 3732 | default: 3733 | return epuc("bad format","packet has bad compression type"); 3734 | 3735 | case 0: {//uncompressed 3736 | int x; 3737 | 3738 | for(x=0;xchannel,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)"); 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; ichannel,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)"); 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"); 3782 | 3783 | if (!pic_readval(s,packet->channel,value)) 3784 | return 0; 3785 | 3786 | for(i=0;ichannel,dest,value); 3788 | } else { // Raw 3789 | ++count; 3790 | if (count>left) return epuc("bad file","scanline overrun"); 3791 | 3792 | for(i=0;ichannel,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)"); 3818 | if ((1 << 28) / x < y) return epuc("too large", "Image too large to decode"); 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"); 3910 | 3911 | version = get8u(s); 3912 | if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF"); 3913 | if (get8(s) != 'a') return e("not GIF", "Corrupt 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"); 4033 | 4034 | if (oldcode >= 0) { 4035 | p = &g->codes[avail++]; 4036 | if (avail > 4096) return epuc("too many codes", "Corrupt GIF"); 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"); 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"); 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"); 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"); 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"); 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"); 4136 | 4137 | o = stbi_process_gif_raster(s, g); 4138 | if (o == NULL) return NULL; 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"); 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_BUFLEN 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_BUFLEN-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_BUFLEN]; 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"); 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"); 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"); 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"); 4299 | token += 3; 4300 | width = strtol(token, NULL, 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; 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"); } 4348 | if (scanline == NULL) 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_BUFLEN]; 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, 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"); 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"); 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_SET); 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 | */ 4674 | --------------------------------------------------------------------------------