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