xref: /OK3568_Linux_fs/external/rknpu2/examples/3rdparty/stb/stb_image.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* stb_image - v2.23 - public domain image loader - http://nothings.org/stb
2*4882a593Smuzhiyun                                   no warranty implied; use at your own risk
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun    Do this:
5*4882a593Smuzhiyun       #define STB_IMAGE_IMPLEMENTATION
6*4882a593Smuzhiyun    before you include this file in *one* C or C++ file to create the implementation.
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun    // i.e. it should look like this:
9*4882a593Smuzhiyun    #include ...
10*4882a593Smuzhiyun    #include ...
11*4882a593Smuzhiyun    #include ...
12*4882a593Smuzhiyun    #define STB_IMAGE_IMPLEMENTATION
13*4882a593Smuzhiyun    #include "stb_image.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun    You can #define STBI_ASSERT(x) before the #include to avoid using assert.h.
16*4882a593Smuzhiyun    And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun    QUICK NOTES:
20*4882a593Smuzhiyun       Primarily of interest to game developers and other people who can
21*4882a593Smuzhiyun           avoid problematic images and only need the trivial interface
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun       JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
24*4882a593Smuzhiyun       PNG 1/2/4/8/16-bit-per-channel
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun       TGA (not sure what subset, if a subset)
27*4882a593Smuzhiyun       BMP non-1bpp, non-RLE
28*4882a593Smuzhiyun       PSD (composited view only, no extra channels, 8/16 bit-per-channel)
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun       GIF (*comp always reports as 4-channel)
31*4882a593Smuzhiyun       HDR (radiance rgbE format)
32*4882a593Smuzhiyun       PIC (Softimage PIC)
33*4882a593Smuzhiyun       PNM (PPM and PGM binary only)
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun       Animated GIF still needs a proper API, but here's one way to do it:
36*4882a593Smuzhiyun           http://gist.github.com/urraka/685d9a6340b26b830d49
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun       - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
39*4882a593Smuzhiyun       - decode from arbitrary I/O callbacks
40*4882a593Smuzhiyun       - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun    Full documentation under "DOCUMENTATION" below.
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun LICENSE
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun   See end of file for license information.
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun RECENT REVISION HISTORY:
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun       2.23  (2019-08-11) fix clang static analysis warning
52*4882a593Smuzhiyun       2.22  (2019-03-04) gif fixes, fix warnings
53*4882a593Smuzhiyun       2.21  (2019-02-25) fix typo in comment
54*4882a593Smuzhiyun       2.20  (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
55*4882a593Smuzhiyun       2.19  (2018-02-11) fix warning
56*4882a593Smuzhiyun       2.18  (2018-01-30) fix warnings
57*4882a593Smuzhiyun       2.17  (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
58*4882a593Smuzhiyun       2.16  (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
59*4882a593Smuzhiyun       2.15  (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
60*4882a593Smuzhiyun       2.14  (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
61*4882a593Smuzhiyun       2.13  (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
62*4882a593Smuzhiyun       2.12  (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
63*4882a593Smuzhiyun       2.11  (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
64*4882a593Smuzhiyun                          RGB-format JPEG; remove white matting in PSD;
65*4882a593Smuzhiyun                          allocate large structures on the stack;
66*4882a593Smuzhiyun                          correct channel count for PNG & BMP
67*4882a593Smuzhiyun       2.10  (2016-01-22) avoid warning introduced in 2.09
68*4882a593Smuzhiyun       2.09  (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun    See end of file for full revision history.
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun  ============================    Contributors    =========================
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun  Image formats                          Extensions, features
76*4882a593Smuzhiyun     Sean Barrett (jpeg, png, bmp)          Jetro Lauha (stbi_info)
77*4882a593Smuzhiyun     Nicolas Schulz (hdr, psd)              Martin "SpartanJ" Golini (stbi_info)
78*4882a593Smuzhiyun     Jonathan Dummer (tga)                  James "moose2000" Brown (iPhone PNG)
79*4882a593Smuzhiyun     Jean-Marc Lienher (gif)                Ben "Disch" Wenger (io callbacks)
80*4882a593Smuzhiyun     Tom Seddon (pic)                       Omar Cornut (1/2/4-bit PNG)
81*4882a593Smuzhiyun     Thatcher Ulrich (psd)                  Nicolas Guillemot (vertical flip)
82*4882a593Smuzhiyun     Ken Miller (pgm, ppm)                  Richard Mitton (16-bit PSD)
83*4882a593Smuzhiyun     github:urraka (animated gif)           Junggon Kim (PNM comments)
84*4882a593Smuzhiyun     Christopher Forseth (animated gif)     Daniel Gibson (16-bit TGA)
85*4882a593Smuzhiyun                                            socks-the-fox (16-bit PNG)
86*4882a593Smuzhiyun                                            Jeremy Sawicki (handle all ImageNet JPGs)
87*4882a593Smuzhiyun  Optimizations & bugfixes                  Mikhail Morozov (1-bit BMP)
88*4882a593Smuzhiyun     Fabian "ryg" Giesen                    Anael Seghezzi (is-16-bit query)
89*4882a593Smuzhiyun     Arseny Kapoulkine
90*4882a593Smuzhiyun     John-Mark Allen
91*4882a593Smuzhiyun     Carmelo J Fdez-Aguera
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun  Bug & warning fixes
94*4882a593Smuzhiyun     Marc LeBlanc            David Woo          Guillaume George   Martins Mozeiko
95*4882a593Smuzhiyun     Christpher Lloyd        Jerry Jansson      Joseph Thomson     Phil Jordan
96*4882a593Smuzhiyun     Dave Moore              Roy Eltham         Hayaki Saito       Nathan Reed
97*4882a593Smuzhiyun     Won Chun                Luke Graham        Johan Duparc       Nick Verigakis
98*4882a593Smuzhiyun     the Horde3D community   Thomas Ruf         Ronny Chevalier    github:rlyeh
99*4882a593Smuzhiyun     Janez Zemva             John Bartholomew   Michal Cichon      github:romigrou
100*4882a593Smuzhiyun     Jonathan Blow           Ken Hamada         Tero Hanninen      github:svdijk
101*4882a593Smuzhiyun     Laurent Gomila          Cort Stratton      Sergio Gonzalez    github:snagar
102*4882a593Smuzhiyun     Aruelien Pocheville     Thibault Reuille   Cass Everitt       github:Zelex
103*4882a593Smuzhiyun     Ryamond Barbiero        Paul Du Bois       Engin Manap        github:grim210
104*4882a593Smuzhiyun     Aldo Culquicondor       Philipp Wiesemann  Dale Weiler        github:sammyhw
105*4882a593Smuzhiyun     Oriol Ferrer Mesia      Josh Tobin         Matthew Gregan     github:phprus
106*4882a593Smuzhiyun     Julian Raschke          Gregory Mullen     Baldur Karlsson    github:poppolopoppo
107*4882a593Smuzhiyun     Christian Floisand      Kevin Schmidt      JR Smith           github:darealshinji
108*4882a593Smuzhiyun     Blazej Dariusz Roszkowski                                     github:Michaelangel007
109*4882a593Smuzhiyun */
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun #ifndef STBI_INCLUDE_STB_IMAGE_H
112*4882a593Smuzhiyun #define STBI_INCLUDE_STB_IMAGE_H
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun // DOCUMENTATION
115*4882a593Smuzhiyun //
116*4882a593Smuzhiyun // Limitations:
117*4882a593Smuzhiyun //    - no 12-bit-per-channel JPEG
118*4882a593Smuzhiyun //    - no JPEGs with arithmetic coding
119*4882a593Smuzhiyun //    - GIF always returns *comp=4
120*4882a593Smuzhiyun //
121*4882a593Smuzhiyun // Basic usage (see HDR discussion below for HDR usage):
122*4882a593Smuzhiyun //    int x,y,n;
123*4882a593Smuzhiyun //    unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
124*4882a593Smuzhiyun //    // ... process data if not NULL ...
125*4882a593Smuzhiyun //    // ... x = width, y = height, n = # 8-bit components per pixel ...
126*4882a593Smuzhiyun //    // ... replace '0' with '1'..'4' to force that many components per pixel
127*4882a593Smuzhiyun //    // ... but 'n' will always be the number that it would have been if you said 0
128*4882a593Smuzhiyun //    stbi_image_free(data)
129*4882a593Smuzhiyun //
130*4882a593Smuzhiyun // Standard parameters:
131*4882a593Smuzhiyun //    int *x                 -- outputs image width in pixels
132*4882a593Smuzhiyun //    int *y                 -- outputs image height in pixels
133*4882a593Smuzhiyun //    int *channels_in_file  -- outputs # of image components in image file
134*4882a593Smuzhiyun //    int desired_channels   -- if non-zero, # of image components requested in result
135*4882a593Smuzhiyun //
136*4882a593Smuzhiyun // The return value from an image loader is an 'unsigned char *' which points
137*4882a593Smuzhiyun // to the pixel data, or NULL on an allocation failure or if the image is
138*4882a593Smuzhiyun // corrupt or invalid. The pixel data consists of *y scanlines of *x pixels,
139*4882a593Smuzhiyun // with each pixel consisting of N interleaved 8-bit components; the first
140*4882a593Smuzhiyun // pixel pointed to is top-left-most in the image. There is no padding between
141*4882a593Smuzhiyun // image scanlines or between pixels, regardless of format. The number of
142*4882a593Smuzhiyun // components N is 'desired_channels' if desired_channels is non-zero, or
143*4882a593Smuzhiyun // *channels_in_file otherwise. If desired_channels is non-zero,
144*4882a593Smuzhiyun // *channels_in_file has the number of components that _would_ have been
145*4882a593Smuzhiyun // output otherwise. E.g. if you set desired_channels to 4, you will always
146*4882a593Smuzhiyun // get RGBA output, but you can check *channels_in_file to see if it's trivially
147*4882a593Smuzhiyun // opaque because e.g. there were only 3 channels in the source image.
148*4882a593Smuzhiyun //
149*4882a593Smuzhiyun // An output image with N components has the following components interleaved
150*4882a593Smuzhiyun // in this order in each pixel:
151*4882a593Smuzhiyun //
152*4882a593Smuzhiyun //     N=#comp     components
153*4882a593Smuzhiyun //       1           grey
154*4882a593Smuzhiyun //       2           grey, alpha
155*4882a593Smuzhiyun //       3           red, green, blue
156*4882a593Smuzhiyun //       4           red, green, blue, alpha
157*4882a593Smuzhiyun //
158*4882a593Smuzhiyun // If image loading fails for any reason, the return value will be NULL,
159*4882a593Smuzhiyun // and *x, *y, *channels_in_file will be unchanged. The function
160*4882a593Smuzhiyun // stbi_failure_reason() can be queried for an extremely brief, end-user
161*4882a593Smuzhiyun // unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS
162*4882a593Smuzhiyun // to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
163*4882a593Smuzhiyun // more user-friendly ones.
164*4882a593Smuzhiyun //
165*4882a593Smuzhiyun // Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
166*4882a593Smuzhiyun //
167*4882a593Smuzhiyun // ===========================================================================
168*4882a593Smuzhiyun //
169*4882a593Smuzhiyun // UNICODE:
170*4882a593Smuzhiyun //
171*4882a593Smuzhiyun //   If compiling for Windows and you wish to use Unicode filenames, compile
172*4882a593Smuzhiyun //   with
173*4882a593Smuzhiyun //       #define STBI_WINDOWS_UTF8
174*4882a593Smuzhiyun //   and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert
175*4882a593Smuzhiyun //   Windows wchar_t filenames to utf8.
176*4882a593Smuzhiyun //
177*4882a593Smuzhiyun // ===========================================================================
178*4882a593Smuzhiyun //
179*4882a593Smuzhiyun // Philosophy
180*4882a593Smuzhiyun //
181*4882a593Smuzhiyun // stb libraries are designed with the following priorities:
182*4882a593Smuzhiyun //
183*4882a593Smuzhiyun //    1. easy to use
184*4882a593Smuzhiyun //    2. easy to maintain
185*4882a593Smuzhiyun //    3. good performance
186*4882a593Smuzhiyun //
187*4882a593Smuzhiyun // Sometimes I let "good performance" creep up in priority over "easy to maintain",
188*4882a593Smuzhiyun // and for best performance I may provide less-easy-to-use APIs that give higher
189*4882a593Smuzhiyun // performance, in addition to the easy-to-use ones. Nevertheless, it's important
190*4882a593Smuzhiyun // to keep in mind that from the standpoint of you, a client of this library,
191*4882a593Smuzhiyun // all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
192*4882a593Smuzhiyun //
193*4882a593Smuzhiyun // Some secondary priorities arise directly from the first two, some of which
194*4882a593Smuzhiyun // provide more explicit reasons why performance can't be emphasized.
195*4882a593Smuzhiyun //
196*4882a593Smuzhiyun //    - Portable ("ease of use")
197*4882a593Smuzhiyun //    - Small source code footprint ("easy to maintain")
198*4882a593Smuzhiyun //    - No dependencies ("ease of use")
199*4882a593Smuzhiyun //
200*4882a593Smuzhiyun // ===========================================================================
201*4882a593Smuzhiyun //
202*4882a593Smuzhiyun // I/O callbacks
203*4882a593Smuzhiyun //
204*4882a593Smuzhiyun // I/O callbacks allow you to read from arbitrary sources, like packaged
205*4882a593Smuzhiyun // files or some other source. Data read from callbacks are processed
206*4882a593Smuzhiyun // through a small internal buffer (currently 128 bytes) to try to reduce
207*4882a593Smuzhiyun // overhead.
208*4882a593Smuzhiyun //
209*4882a593Smuzhiyun // The three functions you must define are "read" (reads some bytes of data),
210*4882a593Smuzhiyun // "skip" (skips some bytes of data), "eof" (reports if the stream is at the end).
211*4882a593Smuzhiyun //
212*4882a593Smuzhiyun // ===========================================================================
213*4882a593Smuzhiyun //
214*4882a593Smuzhiyun // SIMD support
215*4882a593Smuzhiyun //
216*4882a593Smuzhiyun // The JPEG decoder will try to automatically use SIMD kernels on x86 when
217*4882a593Smuzhiyun // supported by the compiler. For ARM Neon support, you must explicitly
218*4882a593Smuzhiyun // request it.
219*4882a593Smuzhiyun //
220*4882a593Smuzhiyun // (The old do-it-yourself SIMD API is no longer supported in the current
221*4882a593Smuzhiyun // code.)
222*4882a593Smuzhiyun //
223*4882a593Smuzhiyun // On x86, SSE2 will automatically be used when available based on a run-time
224*4882a593Smuzhiyun // test; if not, the generic C versions are used as a fall-back. On ARM targets,
225*4882a593Smuzhiyun // the typical path is to have separate builds for NEON and non-NEON devices
226*4882a593Smuzhiyun // (at least this is true for iOS and Android). Therefore, the NEON support is
227*4882a593Smuzhiyun // toggled by a build flag: define STBI_NEON to get NEON loops.
228*4882a593Smuzhiyun //
229*4882a593Smuzhiyun // If for some reason you do not want to use any of SIMD code, or if
230*4882a593Smuzhiyun // you have issues compiling it, you can disable it entirely by
231*4882a593Smuzhiyun // defining STBI_NO_SIMD.
232*4882a593Smuzhiyun //
233*4882a593Smuzhiyun // ===========================================================================
234*4882a593Smuzhiyun //
235*4882a593Smuzhiyun // HDR image support   (disable by defining STBI_NO_HDR)
236*4882a593Smuzhiyun //
237*4882a593Smuzhiyun // stb_image supports loading HDR images in general, and currently the Radiance
238*4882a593Smuzhiyun // .HDR file format specifically. You can still load any file through the existing
239*4882a593Smuzhiyun // interface; if you attempt to load an HDR file, it will be automatically remapped
240*4882a593Smuzhiyun // to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
241*4882a593Smuzhiyun // both of these constants can be reconfigured through this interface:
242*4882a593Smuzhiyun //
243*4882a593Smuzhiyun //     stbi_hdr_to_ldr_gamma(2.2f);
244*4882a593Smuzhiyun //     stbi_hdr_to_ldr_scale(1.0f);
245*4882a593Smuzhiyun //
246*4882a593Smuzhiyun // (note, do not use _inverse_ constants; stbi_image will invert them
247*4882a593Smuzhiyun // appropriately).
248*4882a593Smuzhiyun //
249*4882a593Smuzhiyun // Additionally, there is a new, parallel interface for loading files as
250*4882a593Smuzhiyun // (linear) floats to preserve the full dynamic range:
251*4882a593Smuzhiyun //
252*4882a593Smuzhiyun //    float *data = stbi_loadf(filename, &x, &y, &n, 0);
253*4882a593Smuzhiyun //
254*4882a593Smuzhiyun // If you load LDR images through this interface, those images will
255*4882a593Smuzhiyun // be promoted to floating point values, run through the inverse of
256*4882a593Smuzhiyun // constants corresponding to the above:
257*4882a593Smuzhiyun //
258*4882a593Smuzhiyun //     stbi_ldr_to_hdr_scale(1.0f);
259*4882a593Smuzhiyun //     stbi_ldr_to_hdr_gamma(2.2f);
260*4882a593Smuzhiyun //
261*4882a593Smuzhiyun // Finally, given a filename (or an open file or memory block--see header
262*4882a593Smuzhiyun // file for details) containing image data, you can query for the "most
263*4882a593Smuzhiyun // appropriate" interface to use (that is, whether the image is HDR or
264*4882a593Smuzhiyun // not), using:
265*4882a593Smuzhiyun //
266*4882a593Smuzhiyun //     stbi_is_hdr(char *filename);
267*4882a593Smuzhiyun //
268*4882a593Smuzhiyun // ===========================================================================
269*4882a593Smuzhiyun //
270*4882a593Smuzhiyun // iPhone PNG support:
271*4882a593Smuzhiyun //
272*4882a593Smuzhiyun // By default we convert iphone-formatted PNGs back to RGB, even though
273*4882a593Smuzhiyun // they are internally encoded differently. You can disable this conversion
274*4882a593Smuzhiyun // by calling stbi_convert_iphone_png_to_rgb(0), in which case
275*4882a593Smuzhiyun // you will always just get the native iphone "format" through (which
276*4882a593Smuzhiyun // is BGR stored in RGB).
277*4882a593Smuzhiyun //
278*4882a593Smuzhiyun // Call stbi_set_unpremultiply_on_load(1) as well to force a divide per
279*4882a593Smuzhiyun // pixel to remove any premultiplied alpha *only* if the image file explicitly
280*4882a593Smuzhiyun // says there's premultiplied data (currently only happens in iPhone images,
281*4882a593Smuzhiyun // and only if iPhone convert-to-rgb processing is on).
282*4882a593Smuzhiyun //
283*4882a593Smuzhiyun // ===========================================================================
284*4882a593Smuzhiyun //
285*4882a593Smuzhiyun // ADDITIONAL CONFIGURATION
286*4882a593Smuzhiyun //
287*4882a593Smuzhiyun //  - You can suppress implementation of any of the decoders to reduce
288*4882a593Smuzhiyun //    your code footprint by #defining one or more of the following
289*4882a593Smuzhiyun //    symbols before creating the implementation.
290*4882a593Smuzhiyun //
291*4882a593Smuzhiyun //        STBI_NO_JPEG
292*4882a593Smuzhiyun //        STBI_NO_PNG
293*4882a593Smuzhiyun //        STBI_NO_BMP
294*4882a593Smuzhiyun //        STBI_NO_PSD
295*4882a593Smuzhiyun //        STBI_NO_TGA
296*4882a593Smuzhiyun //        STBI_NO_GIF
297*4882a593Smuzhiyun //        STBI_NO_HDR
298*4882a593Smuzhiyun //        STBI_NO_PIC
299*4882a593Smuzhiyun //        STBI_NO_PNM   (.ppm and .pgm)
300*4882a593Smuzhiyun //
301*4882a593Smuzhiyun //  - You can request *only* certain decoders and suppress all other ones
302*4882a593Smuzhiyun //    (this will be more forward-compatible, as addition of new decoders
303*4882a593Smuzhiyun //    doesn't require you to disable them explicitly):
304*4882a593Smuzhiyun //
305*4882a593Smuzhiyun //        STBI_ONLY_JPEG
306*4882a593Smuzhiyun //        STBI_ONLY_PNG
307*4882a593Smuzhiyun //        STBI_ONLY_BMP
308*4882a593Smuzhiyun //        STBI_ONLY_PSD
309*4882a593Smuzhiyun //        STBI_ONLY_TGA
310*4882a593Smuzhiyun //        STBI_ONLY_GIF
311*4882a593Smuzhiyun //        STBI_ONLY_HDR
312*4882a593Smuzhiyun //        STBI_ONLY_PIC
313*4882a593Smuzhiyun //        STBI_ONLY_PNM   (.ppm and .pgm)
314*4882a593Smuzhiyun //
315*4882a593Smuzhiyun //   - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
316*4882a593Smuzhiyun //     want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
317*4882a593Smuzhiyun //
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
321*4882a593Smuzhiyun #include <stdio.h>
322*4882a593Smuzhiyun #endif // STBI_NO_STDIO
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun #define STBI_VERSION 1
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun enum
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun    STBI_default = 0, // only used for desired_channels
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun    STBI_grey       = 1,
331*4882a593Smuzhiyun    STBI_grey_alpha = 2,
332*4882a593Smuzhiyun    STBI_rgb        = 3,
333*4882a593Smuzhiyun    STBI_rgb_alpha  = 4
334*4882a593Smuzhiyun };
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun #include <stdlib.h>
337*4882a593Smuzhiyun typedef unsigned char stbi_uc;
338*4882a593Smuzhiyun typedef unsigned short stbi_us;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun #ifdef __cplusplus
341*4882a593Smuzhiyun extern "C" {
342*4882a593Smuzhiyun #endif
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun #ifndef STBIDEF
345*4882a593Smuzhiyun #ifdef STB_IMAGE_STATIC
346*4882a593Smuzhiyun #define STBIDEF static
347*4882a593Smuzhiyun #else
348*4882a593Smuzhiyun #define STBIDEF extern
349*4882a593Smuzhiyun #endif
350*4882a593Smuzhiyun #endif
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun //////////////////////////////////////////////////////////////////////////////
353*4882a593Smuzhiyun //
354*4882a593Smuzhiyun // PRIMARY API - works on images of any type
355*4882a593Smuzhiyun //
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun //
358*4882a593Smuzhiyun // load image by filename, open file, or memory buffer
359*4882a593Smuzhiyun //
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun typedef struct
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun    int      (*read)  (void *user,char *data,int size);   // fill 'data' with 'size' bytes.  return number of bytes actually read
364*4882a593Smuzhiyun    void     (*skip)  (void *user,int n);                 // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
365*4882a593Smuzhiyun    int      (*eof)   (void *user);                       // returns nonzero if we are at end of file/data
366*4882a593Smuzhiyun } stbi_io_callbacks;
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun ////////////////////////////////////
369*4882a593Smuzhiyun //
370*4882a593Smuzhiyun // 8-bits-per-channel interface
371*4882a593Smuzhiyun //
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load_from_memory   (stbi_uc           const *buffer, int len   , int *x, int *y, int *channels_in_file, int desired_channels);
374*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk  , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
377*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load            (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
378*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load_from_file  (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
379*4882a593Smuzhiyun // for stbi_load_from_file, file pointer is left pointing immediately after image
380*4882a593Smuzhiyun #endif
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun #ifndef STBI_NO_GIF
383*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
384*4882a593Smuzhiyun #endif
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun #ifdef STBI_WINDOWS_UTF8
387*4882a593Smuzhiyun STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
388*4882a593Smuzhiyun #endif
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun ////////////////////////////////////
391*4882a593Smuzhiyun //
392*4882a593Smuzhiyun // 16-bits-per-channel interface
393*4882a593Smuzhiyun //
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun STBIDEF stbi_us *stbi_load_16_from_memory   (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
396*4882a593Smuzhiyun STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
399*4882a593Smuzhiyun STBIDEF stbi_us *stbi_load_16          (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
400*4882a593Smuzhiyun STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
401*4882a593Smuzhiyun #endif
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun ////////////////////////////////////
404*4882a593Smuzhiyun //
405*4882a593Smuzhiyun // float-per-channel interface
406*4882a593Smuzhiyun //
407*4882a593Smuzhiyun #ifndef STBI_NO_LINEAR
408*4882a593Smuzhiyun    STBIDEF float *stbi_loadf_from_memory     (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
409*4882a593Smuzhiyun    STBIDEF float *stbi_loadf_from_callbacks  (stbi_io_callbacks const *clbk, void *user, int *x, int *y,  int *channels_in_file, int desired_channels);
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun    #ifndef STBI_NO_STDIO
412*4882a593Smuzhiyun    STBIDEF float *stbi_loadf            (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
413*4882a593Smuzhiyun    STBIDEF float *stbi_loadf_from_file  (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
414*4882a593Smuzhiyun    #endif
415*4882a593Smuzhiyun #endif
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun #ifndef STBI_NO_HDR
418*4882a593Smuzhiyun    STBIDEF void   stbi_hdr_to_ldr_gamma(float gamma);
419*4882a593Smuzhiyun    STBIDEF void   stbi_hdr_to_ldr_scale(float scale);
420*4882a593Smuzhiyun #endif // STBI_NO_HDR
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun #ifndef STBI_NO_LINEAR
423*4882a593Smuzhiyun    STBIDEF void   stbi_ldr_to_hdr_gamma(float gamma);
424*4882a593Smuzhiyun    STBIDEF void   stbi_ldr_to_hdr_scale(float scale);
425*4882a593Smuzhiyun #endif // STBI_NO_LINEAR
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun // stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
428*4882a593Smuzhiyun STBIDEF int    stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
429*4882a593Smuzhiyun STBIDEF int    stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
430*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
431*4882a593Smuzhiyun STBIDEF int      stbi_is_hdr          (char const *filename);
432*4882a593Smuzhiyun STBIDEF int      stbi_is_hdr_from_file(FILE *f);
433*4882a593Smuzhiyun #endif // STBI_NO_STDIO
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun // get a VERY brief reason for failure
437*4882a593Smuzhiyun // NOT THREADSAFE
438*4882a593Smuzhiyun STBIDEF const char *stbi_failure_reason  (void);
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun // free the loaded image -- this is just free()
441*4882a593Smuzhiyun STBIDEF void     stbi_image_free      (void *retval_from_stbi_load);
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun // get image dimensions & components without fully decoding
444*4882a593Smuzhiyun STBIDEF int      stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
445*4882a593Smuzhiyun STBIDEF int      stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
446*4882a593Smuzhiyun STBIDEF int      stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len);
447*4882a593Smuzhiyun STBIDEF int      stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user);
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
450*4882a593Smuzhiyun STBIDEF int      stbi_info               (char const *filename,     int *x, int *y, int *comp);
451*4882a593Smuzhiyun STBIDEF int      stbi_info_from_file     (FILE *f,                  int *x, int *y, int *comp);
452*4882a593Smuzhiyun STBIDEF int      stbi_is_16_bit          (char const *filename);
453*4882a593Smuzhiyun STBIDEF int      stbi_is_16_bit_from_file(FILE *f);
454*4882a593Smuzhiyun #endif
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun // for image formats that explicitly notate that they have premultiplied alpha,
459*4882a593Smuzhiyun // we just return the colors as stored in the file. set this flag to force
460*4882a593Smuzhiyun // unpremultiplication. results are undefined if the unpremultiply overflow.
461*4882a593Smuzhiyun STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply);
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun // indicate whether we should process iphone images back to canonical format,
464*4882a593Smuzhiyun // or just pass them through "as-is"
465*4882a593Smuzhiyun STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun // flip the image vertically, so the first pixel in the output array is the bottom left
468*4882a593Smuzhiyun STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun // ZLIB client - used by PNG, available for other purposes
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
473*4882a593Smuzhiyun STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header);
474*4882a593Smuzhiyun STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
475*4882a593Smuzhiyun STBIDEF int   stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
478*4882a593Smuzhiyun STBIDEF int   stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun #ifdef __cplusplus
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun #endif
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun //
486*4882a593Smuzhiyun //
487*4882a593Smuzhiyun ////   end header file   /////////////////////////////////////////////////////
488*4882a593Smuzhiyun #endif // STBI_INCLUDE_STB_IMAGE_H
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun #ifdef STB_IMAGE_IMPLEMENTATION
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun #if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \
493*4882a593Smuzhiyun   || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \
494*4882a593Smuzhiyun   || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \
495*4882a593Smuzhiyun   || defined(STBI_ONLY_ZLIB)
496*4882a593Smuzhiyun    #ifndef STBI_ONLY_JPEG
497*4882a593Smuzhiyun    #define STBI_NO_JPEG
498*4882a593Smuzhiyun    #endif
499*4882a593Smuzhiyun    #ifndef STBI_ONLY_PNG
500*4882a593Smuzhiyun    #define STBI_NO_PNG
501*4882a593Smuzhiyun    #endif
502*4882a593Smuzhiyun    #ifndef STBI_ONLY_BMP
503*4882a593Smuzhiyun    #define STBI_NO_BMP
504*4882a593Smuzhiyun    #endif
505*4882a593Smuzhiyun    #ifndef STBI_ONLY_PSD
506*4882a593Smuzhiyun    #define STBI_NO_PSD
507*4882a593Smuzhiyun    #endif
508*4882a593Smuzhiyun    #ifndef STBI_ONLY_TGA
509*4882a593Smuzhiyun    #define STBI_NO_TGA
510*4882a593Smuzhiyun    #endif
511*4882a593Smuzhiyun    #ifndef STBI_ONLY_GIF
512*4882a593Smuzhiyun    #define STBI_NO_GIF
513*4882a593Smuzhiyun    #endif
514*4882a593Smuzhiyun    #ifndef STBI_ONLY_HDR
515*4882a593Smuzhiyun    #define STBI_NO_HDR
516*4882a593Smuzhiyun    #endif
517*4882a593Smuzhiyun    #ifndef STBI_ONLY_PIC
518*4882a593Smuzhiyun    #define STBI_NO_PIC
519*4882a593Smuzhiyun    #endif
520*4882a593Smuzhiyun    #ifndef STBI_ONLY_PNM
521*4882a593Smuzhiyun    #define STBI_NO_PNM
522*4882a593Smuzhiyun    #endif
523*4882a593Smuzhiyun #endif
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun #if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB)
526*4882a593Smuzhiyun #define STBI_NO_ZLIB
527*4882a593Smuzhiyun #endif
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun #include <stdarg.h>
531*4882a593Smuzhiyun #include <stddef.h> // ptrdiff_t on osx
532*4882a593Smuzhiyun #include <stdlib.h>
533*4882a593Smuzhiyun #include <string.h>
534*4882a593Smuzhiyun #include <limits.h>
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
537*4882a593Smuzhiyun #include <math.h>  // ldexp, pow
538*4882a593Smuzhiyun #endif
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
541*4882a593Smuzhiyun #include <stdio.h>
542*4882a593Smuzhiyun #endif
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun #ifndef STBI_ASSERT
545*4882a593Smuzhiyun #include <assert.h>
546*4882a593Smuzhiyun #define STBI_ASSERT(x) assert(x)
547*4882a593Smuzhiyun #endif
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun #ifdef __cplusplus
550*4882a593Smuzhiyun #define STBI_EXTERN extern "C"
551*4882a593Smuzhiyun #else
552*4882a593Smuzhiyun #define STBI_EXTERN extern
553*4882a593Smuzhiyun #endif
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun #ifndef _MSC_VER
557*4882a593Smuzhiyun    #ifdef __cplusplus
558*4882a593Smuzhiyun    #define stbi_inline inline
559*4882a593Smuzhiyun    #else
560*4882a593Smuzhiyun    #define stbi_inline
561*4882a593Smuzhiyun    #endif
562*4882a593Smuzhiyun #else
563*4882a593Smuzhiyun    #define stbi_inline __forceinline
564*4882a593Smuzhiyun #endif
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun #ifdef _MSC_VER
568*4882a593Smuzhiyun typedef unsigned short stbi__uint16;
569*4882a593Smuzhiyun typedef   signed short stbi__int16;
570*4882a593Smuzhiyun typedef unsigned int   stbi__uint32;
571*4882a593Smuzhiyun typedef   signed int   stbi__int32;
572*4882a593Smuzhiyun #else
573*4882a593Smuzhiyun #include <stdint.h>
574*4882a593Smuzhiyun typedef uint16_t stbi__uint16;
575*4882a593Smuzhiyun typedef int16_t  stbi__int16;
576*4882a593Smuzhiyun typedef uint32_t stbi__uint32;
577*4882a593Smuzhiyun typedef int32_t  stbi__int32;
578*4882a593Smuzhiyun #endif
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun // should produce compiler error if size is wrong
581*4882a593Smuzhiyun typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun #ifdef _MSC_VER
584*4882a593Smuzhiyun #define STBI_NOTUSED(v)  (void)(v)
585*4882a593Smuzhiyun #else
586*4882a593Smuzhiyun #define STBI_NOTUSED(v)  (void)sizeof(v)
587*4882a593Smuzhiyun #endif
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun #ifdef _MSC_VER
590*4882a593Smuzhiyun #define STBI_HAS_LROTL
591*4882a593Smuzhiyun #endif
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun #ifdef STBI_HAS_LROTL
594*4882a593Smuzhiyun    #define stbi_lrot(x,y)  _lrotl(x,y)
595*4882a593Smuzhiyun #else
596*4882a593Smuzhiyun    #define stbi_lrot(x,y)  (((x) << (y)) | ((x) >> (32 - (y))))
597*4882a593Smuzhiyun #endif
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
600*4882a593Smuzhiyun // ok
601*4882a593Smuzhiyun #elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED)
602*4882a593Smuzhiyun // ok
603*4882a593Smuzhiyun #else
604*4882a593Smuzhiyun #error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)."
605*4882a593Smuzhiyun #endif
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun #ifndef STBI_MALLOC
608*4882a593Smuzhiyun #define STBI_MALLOC(sz)           malloc(sz)
609*4882a593Smuzhiyun #define STBI_REALLOC(p,newsz)     realloc(p,newsz)
610*4882a593Smuzhiyun #define STBI_FREE(p)              free(p)
611*4882a593Smuzhiyun #endif
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun #ifndef STBI_REALLOC_SIZED
614*4882a593Smuzhiyun #define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
615*4882a593Smuzhiyun #endif
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun // x86/x64 detection
618*4882a593Smuzhiyun #if defined(__x86_64__) || defined(_M_X64)
619*4882a593Smuzhiyun #define STBI__X64_TARGET
620*4882a593Smuzhiyun #elif defined(__i386) || defined(_M_IX86)
621*4882a593Smuzhiyun #define STBI__X86_TARGET
622*4882a593Smuzhiyun #endif
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun #if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
625*4882a593Smuzhiyun // gcc doesn't support sse2 intrinsics unless you compile with -msse2,
626*4882a593Smuzhiyun // which in turn means it gets to use SSE2 everywhere. This is unfortunate,
627*4882a593Smuzhiyun // but previous attempts to provide the SSE2 functions with runtime
628*4882a593Smuzhiyun // detection caused numerous issues. The way architecture extensions are
629*4882a593Smuzhiyun // exposed in GCC/Clang is, sadly, not really suited for one-file libs.
630*4882a593Smuzhiyun // New behavior: if compiled with -msse2, we use SSE2 without any
631*4882a593Smuzhiyun // detection; if not, we don't use it at all.
632*4882a593Smuzhiyun #define STBI_NO_SIMD
633*4882a593Smuzhiyun #endif
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun #if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD)
636*4882a593Smuzhiyun // Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET
637*4882a593Smuzhiyun //
638*4882a593Smuzhiyun // 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the
639*4882a593Smuzhiyun // Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant.
640*4882a593Smuzhiyun // As a result, enabling SSE2 on 32-bit MinGW is dangerous when not
641*4882a593Smuzhiyun // simultaneously enabling "-mstackrealign".
642*4882a593Smuzhiyun //
643*4882a593Smuzhiyun // See https://github.com/nothings/stb/issues/81 for more information.
644*4882a593Smuzhiyun //
645*4882a593Smuzhiyun // So default to no SSE2 on 32-bit MinGW. If you've read this far and added
646*4882a593Smuzhiyun // -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2.
647*4882a593Smuzhiyun #define STBI_NO_SIMD
648*4882a593Smuzhiyun #endif
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun #if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET))
651*4882a593Smuzhiyun #define STBI_SSE2
652*4882a593Smuzhiyun #include <emmintrin.h>
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun #ifdef _MSC_VER
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun #if _MSC_VER >= 1400  // not VC6
657*4882a593Smuzhiyun #include <intrin.h> // __cpuid
stbi__cpuid3(void)658*4882a593Smuzhiyun static int stbi__cpuid3(void)
659*4882a593Smuzhiyun {
660*4882a593Smuzhiyun    int info[4];
661*4882a593Smuzhiyun    __cpuid(info,1);
662*4882a593Smuzhiyun    return info[3];
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun #else
stbi__cpuid3(void)665*4882a593Smuzhiyun static int stbi__cpuid3(void)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun    int res;
668*4882a593Smuzhiyun    __asm {
669*4882a593Smuzhiyun       mov  eax,1
670*4882a593Smuzhiyun       cpuid
671*4882a593Smuzhiyun       mov  res,edx
672*4882a593Smuzhiyun    }
673*4882a593Smuzhiyun    return res;
674*4882a593Smuzhiyun }
675*4882a593Smuzhiyun #endif
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun #define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun #if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
stbi__sse2_available(void)680*4882a593Smuzhiyun static int stbi__sse2_available(void)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun    int info3 = stbi__cpuid3();
683*4882a593Smuzhiyun    return ((info3 >> 26) & 1) != 0;
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun #endif
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun #else // assume GCC-style if not VC++
688*4882a593Smuzhiyun #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun #if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
stbi__sse2_available(void)691*4882a593Smuzhiyun static int stbi__sse2_available(void)
692*4882a593Smuzhiyun {
693*4882a593Smuzhiyun    // If we're even attempting to compile this on GCC/Clang, that means
694*4882a593Smuzhiyun    // -msse2 is on, which means the compiler is allowed to use SSE2
695*4882a593Smuzhiyun    // instructions at will, and so are we.
696*4882a593Smuzhiyun    return 1;
697*4882a593Smuzhiyun }
698*4882a593Smuzhiyun #endif
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun #endif
701*4882a593Smuzhiyun #endif
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun // ARM NEON
704*4882a593Smuzhiyun #if defined(STBI_NO_SIMD) && defined(STBI_NEON)
705*4882a593Smuzhiyun #undef STBI_NEON
706*4882a593Smuzhiyun #endif
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun #ifdef STBI_NEON
709*4882a593Smuzhiyun #include <arm_neon.h>
710*4882a593Smuzhiyun // assume GCC or Clang on ARM targets
711*4882a593Smuzhiyun #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
712*4882a593Smuzhiyun #endif
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun #ifndef STBI_SIMD_ALIGN
715*4882a593Smuzhiyun #define STBI_SIMD_ALIGN(type, name) type name
716*4882a593Smuzhiyun #endif
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun ///////////////////////////////////////////////
719*4882a593Smuzhiyun //
720*4882a593Smuzhiyun //  stbi__context struct and start_xxx functions
721*4882a593Smuzhiyun 
722*4882a593Smuzhiyun // stbi__context structure is our basic context used by all images, so it
723*4882a593Smuzhiyun // contains all the IO context, plus some basic image information
724*4882a593Smuzhiyun typedef struct
725*4882a593Smuzhiyun {
726*4882a593Smuzhiyun    stbi__uint32 img_x, img_y;
727*4882a593Smuzhiyun    int img_n, img_out_n;
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun    stbi_io_callbacks io;
730*4882a593Smuzhiyun    void *io_user_data;
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun    int read_from_callbacks;
733*4882a593Smuzhiyun    int buflen;
734*4882a593Smuzhiyun    stbi_uc buffer_start[128];
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun    stbi_uc *img_buffer, *img_buffer_end;
737*4882a593Smuzhiyun    stbi_uc *img_buffer_original, *img_buffer_original_end;
738*4882a593Smuzhiyun } stbi__context;
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun static void stbi__refill_buffer(stbi__context *s);
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun // initialize a memory-decode context
stbi__start_mem(stbi__context * s,stbi_uc const * buffer,int len)744*4882a593Smuzhiyun static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
745*4882a593Smuzhiyun {
746*4882a593Smuzhiyun    s->io.read = NULL;
747*4882a593Smuzhiyun    s->read_from_callbacks = 0;
748*4882a593Smuzhiyun    s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
749*4882a593Smuzhiyun    s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun // initialize a callback-based context
stbi__start_callbacks(stbi__context * s,stbi_io_callbacks * c,void * user)753*4882a593Smuzhiyun static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user)
754*4882a593Smuzhiyun {
755*4882a593Smuzhiyun    s->io = *c;
756*4882a593Smuzhiyun    s->io_user_data = user;
757*4882a593Smuzhiyun    s->buflen = sizeof(s->buffer_start);
758*4882a593Smuzhiyun    s->read_from_callbacks = 1;
759*4882a593Smuzhiyun    s->img_buffer_original = s->buffer_start;
760*4882a593Smuzhiyun    stbi__refill_buffer(s);
761*4882a593Smuzhiyun    s->img_buffer_original_end = s->img_buffer_end;
762*4882a593Smuzhiyun }
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
765*4882a593Smuzhiyun 
stbi__stdio_read(void * user,char * data,int size)766*4882a593Smuzhiyun static int stbi__stdio_read(void *user, char *data, int size)
767*4882a593Smuzhiyun {
768*4882a593Smuzhiyun    return (int) fread(data,1,size,(FILE*) user);
769*4882a593Smuzhiyun }
770*4882a593Smuzhiyun 
stbi__stdio_skip(void * user,int n)771*4882a593Smuzhiyun static void stbi__stdio_skip(void *user, int n)
772*4882a593Smuzhiyun {
773*4882a593Smuzhiyun    fseek((FILE*) user, n, SEEK_CUR);
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun 
stbi__stdio_eof(void * user)776*4882a593Smuzhiyun static int stbi__stdio_eof(void *user)
777*4882a593Smuzhiyun {
778*4882a593Smuzhiyun    return feof((FILE*) user);
779*4882a593Smuzhiyun }
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun static stbi_io_callbacks stbi__stdio_callbacks =
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun    stbi__stdio_read,
784*4882a593Smuzhiyun    stbi__stdio_skip,
785*4882a593Smuzhiyun    stbi__stdio_eof,
786*4882a593Smuzhiyun };
787*4882a593Smuzhiyun 
stbi__start_file(stbi__context * s,FILE * f)788*4882a593Smuzhiyun static void stbi__start_file(stbi__context *s, FILE *f)
789*4882a593Smuzhiyun {
790*4882a593Smuzhiyun    stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f);
791*4882a593Smuzhiyun }
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun //static void stop_file(stbi__context *s) { }
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun #endif // !STBI_NO_STDIO
796*4882a593Smuzhiyun 
stbi__rewind(stbi__context * s)797*4882a593Smuzhiyun static void stbi__rewind(stbi__context *s)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun    // conceptually rewind SHOULD rewind to the beginning of the stream,
800*4882a593Smuzhiyun    // but we just rewind to the beginning of the initial buffer, because
801*4882a593Smuzhiyun    // we only use it after doing 'test', which only ever looks at at most 92 bytes
802*4882a593Smuzhiyun    s->img_buffer = s->img_buffer_original;
803*4882a593Smuzhiyun    s->img_buffer_end = s->img_buffer_original_end;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun enum
807*4882a593Smuzhiyun {
808*4882a593Smuzhiyun    STBI_ORDER_RGB,
809*4882a593Smuzhiyun    STBI_ORDER_BGR
810*4882a593Smuzhiyun };
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun typedef struct
813*4882a593Smuzhiyun {
814*4882a593Smuzhiyun    int bits_per_channel;
815*4882a593Smuzhiyun    int num_channels;
816*4882a593Smuzhiyun    int channel_order;
817*4882a593Smuzhiyun } stbi__result_info;
818*4882a593Smuzhiyun 
819*4882a593Smuzhiyun #ifndef STBI_NO_JPEG
820*4882a593Smuzhiyun static int      stbi__jpeg_test(stbi__context *s);
821*4882a593Smuzhiyun static void    *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
822*4882a593Smuzhiyun static int      stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp);
823*4882a593Smuzhiyun #endif
824*4882a593Smuzhiyun 
825*4882a593Smuzhiyun #ifndef STBI_NO_PNG
826*4882a593Smuzhiyun static int      stbi__png_test(stbi__context *s);
827*4882a593Smuzhiyun static void    *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
828*4882a593Smuzhiyun static int      stbi__png_info(stbi__context *s, int *x, int *y, int *comp);
829*4882a593Smuzhiyun static int      stbi__png_is16(stbi__context *s);
830*4882a593Smuzhiyun #endif
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun #ifndef STBI_NO_BMP
833*4882a593Smuzhiyun static int      stbi__bmp_test(stbi__context *s);
834*4882a593Smuzhiyun static void    *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
835*4882a593Smuzhiyun static int      stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp);
836*4882a593Smuzhiyun #endif
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun #ifndef STBI_NO_TGA
839*4882a593Smuzhiyun static int      stbi__tga_test(stbi__context *s);
840*4882a593Smuzhiyun static void    *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
841*4882a593Smuzhiyun static int      stbi__tga_info(stbi__context *s, int *x, int *y, int *comp);
842*4882a593Smuzhiyun #endif
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun #ifndef STBI_NO_PSD
845*4882a593Smuzhiyun static int      stbi__psd_test(stbi__context *s);
846*4882a593Smuzhiyun static void    *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc);
847*4882a593Smuzhiyun static int      stbi__psd_info(stbi__context *s, int *x, int *y, int *comp);
848*4882a593Smuzhiyun static int      stbi__psd_is16(stbi__context *s);
849*4882a593Smuzhiyun #endif
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun #ifndef STBI_NO_HDR
852*4882a593Smuzhiyun static int      stbi__hdr_test(stbi__context *s);
853*4882a593Smuzhiyun static float   *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
854*4882a593Smuzhiyun static int      stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp);
855*4882a593Smuzhiyun #endif
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun #ifndef STBI_NO_PIC
858*4882a593Smuzhiyun static int      stbi__pic_test(stbi__context *s);
859*4882a593Smuzhiyun static void    *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
860*4882a593Smuzhiyun static int      stbi__pic_info(stbi__context *s, int *x, int *y, int *comp);
861*4882a593Smuzhiyun #endif
862*4882a593Smuzhiyun 
863*4882a593Smuzhiyun #ifndef STBI_NO_GIF
864*4882a593Smuzhiyun static int      stbi__gif_test(stbi__context *s);
865*4882a593Smuzhiyun static void    *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
866*4882a593Smuzhiyun static void    *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
867*4882a593Smuzhiyun static int      stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
868*4882a593Smuzhiyun #endif
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun #ifndef STBI_NO_PNM
871*4882a593Smuzhiyun static int      stbi__pnm_test(stbi__context *s);
872*4882a593Smuzhiyun static void    *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
873*4882a593Smuzhiyun static int      stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
874*4882a593Smuzhiyun #endif
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun // this is not threadsafe
877*4882a593Smuzhiyun static const char *stbi__g_failure_reason;
878*4882a593Smuzhiyun 
stbi_failure_reason(void)879*4882a593Smuzhiyun STBIDEF const char *stbi_failure_reason(void)
880*4882a593Smuzhiyun {
881*4882a593Smuzhiyun    return stbi__g_failure_reason;
882*4882a593Smuzhiyun }
883*4882a593Smuzhiyun 
stbi__err(const char * str)884*4882a593Smuzhiyun static int stbi__err(const char *str)
885*4882a593Smuzhiyun {
886*4882a593Smuzhiyun    stbi__g_failure_reason = str;
887*4882a593Smuzhiyun    return 0;
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun 
stbi__malloc(size_t size)890*4882a593Smuzhiyun static void *stbi__malloc(size_t size)
891*4882a593Smuzhiyun {
892*4882a593Smuzhiyun     return STBI_MALLOC(size);
893*4882a593Smuzhiyun }
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun // stb_image uses ints pervasively, including for offset calculations.
896*4882a593Smuzhiyun // therefore the largest decoded image size we can support with the
897*4882a593Smuzhiyun // current code, even on 64-bit targets, is INT_MAX. this is not a
898*4882a593Smuzhiyun // significant limitation for the intended use case.
899*4882a593Smuzhiyun //
900*4882a593Smuzhiyun // we do, however, need to make sure our size calculations don't
901*4882a593Smuzhiyun // overflow. hence a few helper functions for size calculations that
902*4882a593Smuzhiyun // multiply integers together, making sure that they're non-negative
903*4882a593Smuzhiyun // and no overflow occurs.
904*4882a593Smuzhiyun 
905*4882a593Smuzhiyun // return 1 if the sum is valid, 0 on overflow.
906*4882a593Smuzhiyun // negative terms are considered invalid.
stbi__addsizes_valid(int a,int b)907*4882a593Smuzhiyun static int stbi__addsizes_valid(int a, int b)
908*4882a593Smuzhiyun {
909*4882a593Smuzhiyun    if (b < 0) return 0;
910*4882a593Smuzhiyun    // now 0 <= b <= INT_MAX, hence also
911*4882a593Smuzhiyun    // 0 <= INT_MAX - b <= INTMAX.
912*4882a593Smuzhiyun    // And "a + b <= INT_MAX" (which might overflow) is the
913*4882a593Smuzhiyun    // same as a <= INT_MAX - b (no overflow)
914*4882a593Smuzhiyun    return a <= INT_MAX - b;
915*4882a593Smuzhiyun }
916*4882a593Smuzhiyun 
917*4882a593Smuzhiyun // returns 1 if the product is valid, 0 on overflow.
918*4882a593Smuzhiyun // negative factors are considered invalid.
stbi__mul2sizes_valid(int a,int b)919*4882a593Smuzhiyun static int stbi__mul2sizes_valid(int a, int b)
920*4882a593Smuzhiyun {
921*4882a593Smuzhiyun    if (a < 0 || b < 0) return 0;
922*4882a593Smuzhiyun    if (b == 0) return 1; // mul-by-0 is always safe
923*4882a593Smuzhiyun    // portable way to check for no overflows in a*b
924*4882a593Smuzhiyun    return a <= INT_MAX/b;
925*4882a593Smuzhiyun }
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun // returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow
stbi__mad2sizes_valid(int a,int b,int add)928*4882a593Smuzhiyun static int stbi__mad2sizes_valid(int a, int b, int add)
929*4882a593Smuzhiyun {
930*4882a593Smuzhiyun    return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add);
931*4882a593Smuzhiyun }
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun // returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow
stbi__mad3sizes_valid(int a,int b,int c,int add)934*4882a593Smuzhiyun static int stbi__mad3sizes_valid(int a, int b, int c, int add)
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun    return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
937*4882a593Smuzhiyun       stbi__addsizes_valid(a*b*c, add);
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun 
940*4882a593Smuzhiyun // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
941*4882a593Smuzhiyun #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
stbi__mad4sizes_valid(int a,int b,int c,int d,int add)942*4882a593Smuzhiyun static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
943*4882a593Smuzhiyun {
944*4882a593Smuzhiyun    return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
945*4882a593Smuzhiyun       stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add);
946*4882a593Smuzhiyun }
947*4882a593Smuzhiyun #endif
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun // mallocs with size overflow checking
stbi__malloc_mad2(int a,int b,int add)950*4882a593Smuzhiyun static void *stbi__malloc_mad2(int a, int b, int add)
951*4882a593Smuzhiyun {
952*4882a593Smuzhiyun    if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
953*4882a593Smuzhiyun    return stbi__malloc(a*b + add);
954*4882a593Smuzhiyun }
955*4882a593Smuzhiyun 
stbi__malloc_mad3(int a,int b,int c,int add)956*4882a593Smuzhiyun static void *stbi__malloc_mad3(int a, int b, int c, int add)
957*4882a593Smuzhiyun {
958*4882a593Smuzhiyun    if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL;
959*4882a593Smuzhiyun    return stbi__malloc(a*b*c + add);
960*4882a593Smuzhiyun }
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
stbi__malloc_mad4(int a,int b,int c,int d,int add)963*4882a593Smuzhiyun static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
964*4882a593Smuzhiyun {
965*4882a593Smuzhiyun    if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL;
966*4882a593Smuzhiyun    return stbi__malloc(a*b*c*d + add);
967*4882a593Smuzhiyun }
968*4882a593Smuzhiyun #endif
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun // stbi__err - error
971*4882a593Smuzhiyun // stbi__errpf - error returning pointer to float
972*4882a593Smuzhiyun // stbi__errpuc - error returning pointer to unsigned char
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun #ifdef STBI_NO_FAILURE_STRINGS
975*4882a593Smuzhiyun    #define stbi__err(x,y)  0
976*4882a593Smuzhiyun #elif defined(STBI_FAILURE_USERMSG)
977*4882a593Smuzhiyun    #define stbi__err(x,y)  stbi__err(y)
978*4882a593Smuzhiyun #else
979*4882a593Smuzhiyun    #define stbi__err(x,y)  stbi__err(x)
980*4882a593Smuzhiyun #endif
981*4882a593Smuzhiyun 
982*4882a593Smuzhiyun #define stbi__errpf(x,y)   ((float *)(size_t) (stbi__err(x,y)?NULL:NULL))
983*4882a593Smuzhiyun #define stbi__errpuc(x,y)  ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL))
984*4882a593Smuzhiyun 
stbi_image_free(void * retval_from_stbi_load)985*4882a593Smuzhiyun STBIDEF void stbi_image_free(void *retval_from_stbi_load)
986*4882a593Smuzhiyun {
987*4882a593Smuzhiyun    STBI_FREE(retval_from_stbi_load);
988*4882a593Smuzhiyun }
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun #ifndef STBI_NO_LINEAR
991*4882a593Smuzhiyun static float   *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
992*4882a593Smuzhiyun #endif
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun #ifndef STBI_NO_HDR
995*4882a593Smuzhiyun static stbi_uc *stbi__hdr_to_ldr(float   *data, int x, int y, int comp);
996*4882a593Smuzhiyun #endif
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun static int stbi__vertically_flip_on_load = 0;
999*4882a593Smuzhiyun 
stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)1000*4882a593Smuzhiyun STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
1001*4882a593Smuzhiyun {
1002*4882a593Smuzhiyun     stbi__vertically_flip_on_load = flag_true_if_should_flip;
1003*4882a593Smuzhiyun }
1004*4882a593Smuzhiyun 
stbi__load_main(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri,int bpc)1005*4882a593Smuzhiyun static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
1006*4882a593Smuzhiyun {
1007*4882a593Smuzhiyun    memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
1008*4882a593Smuzhiyun    ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed
1009*4882a593Smuzhiyun    ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
1010*4882a593Smuzhiyun    ri->num_channels = 0;
1011*4882a593Smuzhiyun 
1012*4882a593Smuzhiyun    #ifndef STBI_NO_JPEG
1013*4882a593Smuzhiyun    if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
1014*4882a593Smuzhiyun    #endif
1015*4882a593Smuzhiyun    #ifndef STBI_NO_PNG
1016*4882a593Smuzhiyun    if (stbi__png_test(s))  return stbi__png_load(s,x,y,comp,req_comp, ri);
1017*4882a593Smuzhiyun    #endif
1018*4882a593Smuzhiyun    #ifndef STBI_NO_BMP
1019*4882a593Smuzhiyun    if (stbi__bmp_test(s))  return stbi__bmp_load(s,x,y,comp,req_comp, ri);
1020*4882a593Smuzhiyun    #endif
1021*4882a593Smuzhiyun    #ifndef STBI_NO_GIF
1022*4882a593Smuzhiyun    if (stbi__gif_test(s))  return stbi__gif_load(s,x,y,comp,req_comp, ri);
1023*4882a593Smuzhiyun    #endif
1024*4882a593Smuzhiyun    #ifndef STBI_NO_PSD
1025*4882a593Smuzhiyun    if (stbi__psd_test(s))  return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
1026*4882a593Smuzhiyun    #endif
1027*4882a593Smuzhiyun    #ifndef STBI_NO_PIC
1028*4882a593Smuzhiyun    if (stbi__pic_test(s))  return stbi__pic_load(s,x,y,comp,req_comp, ri);
1029*4882a593Smuzhiyun    #endif
1030*4882a593Smuzhiyun    #ifndef STBI_NO_PNM
1031*4882a593Smuzhiyun    if (stbi__pnm_test(s))  return stbi__pnm_load(s,x,y,comp,req_comp, ri);
1032*4882a593Smuzhiyun    #endif
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun    #ifndef STBI_NO_HDR
1035*4882a593Smuzhiyun    if (stbi__hdr_test(s)) {
1036*4882a593Smuzhiyun       float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri);
1037*4882a593Smuzhiyun       return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
1038*4882a593Smuzhiyun    }
1039*4882a593Smuzhiyun    #endif
1040*4882a593Smuzhiyun 
1041*4882a593Smuzhiyun    #ifndef STBI_NO_TGA
1042*4882a593Smuzhiyun    // test tga last because it's a crappy test!
1043*4882a593Smuzhiyun    if (stbi__tga_test(s))
1044*4882a593Smuzhiyun       return stbi__tga_load(s,x,y,comp,req_comp, ri);
1045*4882a593Smuzhiyun    #endif
1046*4882a593Smuzhiyun 
1047*4882a593Smuzhiyun    return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
1048*4882a593Smuzhiyun }
1049*4882a593Smuzhiyun 
stbi__convert_16_to_8(stbi__uint16 * orig,int w,int h,int channels)1050*4882a593Smuzhiyun static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels)
1051*4882a593Smuzhiyun {
1052*4882a593Smuzhiyun    int i;
1053*4882a593Smuzhiyun    int img_len = w * h * channels;
1054*4882a593Smuzhiyun    stbi_uc *reduced;
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun    reduced = (stbi_uc *) stbi__malloc(img_len);
1057*4882a593Smuzhiyun    if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory");
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun    for (i = 0; i < img_len; ++i)
1060*4882a593Smuzhiyun       reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling
1061*4882a593Smuzhiyun 
1062*4882a593Smuzhiyun    STBI_FREE(orig);
1063*4882a593Smuzhiyun    return reduced;
1064*4882a593Smuzhiyun }
1065*4882a593Smuzhiyun 
stbi__convert_8_to_16(stbi_uc * orig,int w,int h,int channels)1066*4882a593Smuzhiyun static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels)
1067*4882a593Smuzhiyun {
1068*4882a593Smuzhiyun    int i;
1069*4882a593Smuzhiyun    int img_len = w * h * channels;
1070*4882a593Smuzhiyun    stbi__uint16 *enlarged;
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun    enlarged = (stbi__uint16 *) stbi__malloc(img_len*2);
1073*4882a593Smuzhiyun    if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
1074*4882a593Smuzhiyun 
1075*4882a593Smuzhiyun    for (i = 0; i < img_len; ++i)
1076*4882a593Smuzhiyun       enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
1077*4882a593Smuzhiyun 
1078*4882a593Smuzhiyun    STBI_FREE(orig);
1079*4882a593Smuzhiyun    return enlarged;
1080*4882a593Smuzhiyun }
1081*4882a593Smuzhiyun 
stbi__vertical_flip(void * image,int w,int h,int bytes_per_pixel)1082*4882a593Smuzhiyun static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
1083*4882a593Smuzhiyun {
1084*4882a593Smuzhiyun    int row;
1085*4882a593Smuzhiyun    size_t bytes_per_row = (size_t)w * bytes_per_pixel;
1086*4882a593Smuzhiyun    stbi_uc temp[2048];
1087*4882a593Smuzhiyun    stbi_uc *bytes = (stbi_uc *)image;
1088*4882a593Smuzhiyun 
1089*4882a593Smuzhiyun    for (row = 0; row < (h>>1); row++) {
1090*4882a593Smuzhiyun       stbi_uc *row0 = bytes + row*bytes_per_row;
1091*4882a593Smuzhiyun       stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row;
1092*4882a593Smuzhiyun       // swap row0 with row1
1093*4882a593Smuzhiyun       size_t bytes_left = bytes_per_row;
1094*4882a593Smuzhiyun       while (bytes_left) {
1095*4882a593Smuzhiyun          size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
1096*4882a593Smuzhiyun          memcpy(temp, row0, bytes_copy);
1097*4882a593Smuzhiyun          memcpy(row0, row1, bytes_copy);
1098*4882a593Smuzhiyun          memcpy(row1, temp, bytes_copy);
1099*4882a593Smuzhiyun          row0 += bytes_copy;
1100*4882a593Smuzhiyun          row1 += bytes_copy;
1101*4882a593Smuzhiyun          bytes_left -= bytes_copy;
1102*4882a593Smuzhiyun       }
1103*4882a593Smuzhiyun    }
1104*4882a593Smuzhiyun }
1105*4882a593Smuzhiyun 
1106*4882a593Smuzhiyun #ifndef STBI_NO_GIF
stbi__vertical_flip_slices(void * image,int w,int h,int z,int bytes_per_pixel)1107*4882a593Smuzhiyun static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
1108*4882a593Smuzhiyun {
1109*4882a593Smuzhiyun    int slice;
1110*4882a593Smuzhiyun    int slice_size = w * h * bytes_per_pixel;
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun    stbi_uc *bytes = (stbi_uc *)image;
1113*4882a593Smuzhiyun    for (slice = 0; slice < z; ++slice) {
1114*4882a593Smuzhiyun       stbi__vertical_flip(bytes, w, h, bytes_per_pixel);
1115*4882a593Smuzhiyun       bytes += slice_size;
1116*4882a593Smuzhiyun    }
1117*4882a593Smuzhiyun }
1118*4882a593Smuzhiyun #endif
1119*4882a593Smuzhiyun 
stbi__load_and_postprocess_8bit(stbi__context * s,int * x,int * y,int * comp,int req_comp)1120*4882a593Smuzhiyun static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
1121*4882a593Smuzhiyun {
1122*4882a593Smuzhiyun    stbi__result_info ri;
1123*4882a593Smuzhiyun    void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8);
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun    if (result == NULL)
1126*4882a593Smuzhiyun       return NULL;
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun    if (ri.bits_per_channel != 8) {
1129*4882a593Smuzhiyun       STBI_ASSERT(ri.bits_per_channel == 16);
1130*4882a593Smuzhiyun       result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
1131*4882a593Smuzhiyun       ri.bits_per_channel = 8;
1132*4882a593Smuzhiyun    }
1133*4882a593Smuzhiyun 
1134*4882a593Smuzhiyun    // @TODO: move stbi__convert_format to here
1135*4882a593Smuzhiyun 
1136*4882a593Smuzhiyun    if (stbi__vertically_flip_on_load) {
1137*4882a593Smuzhiyun       int channels = req_comp ? req_comp : *comp;
1138*4882a593Smuzhiyun       stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
1139*4882a593Smuzhiyun    }
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun    return (unsigned char *) result;
1142*4882a593Smuzhiyun }
1143*4882a593Smuzhiyun 
stbi__load_and_postprocess_16bit(stbi__context * s,int * x,int * y,int * comp,int req_comp)1144*4882a593Smuzhiyun static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
1145*4882a593Smuzhiyun {
1146*4882a593Smuzhiyun    stbi__result_info ri;
1147*4882a593Smuzhiyun    void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16);
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun    if (result == NULL)
1150*4882a593Smuzhiyun       return NULL;
1151*4882a593Smuzhiyun 
1152*4882a593Smuzhiyun    if (ri.bits_per_channel != 16) {
1153*4882a593Smuzhiyun       STBI_ASSERT(ri.bits_per_channel == 8);
1154*4882a593Smuzhiyun       result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
1155*4882a593Smuzhiyun       ri.bits_per_channel = 16;
1156*4882a593Smuzhiyun    }
1157*4882a593Smuzhiyun 
1158*4882a593Smuzhiyun    // @TODO: move stbi__convert_format16 to here
1159*4882a593Smuzhiyun    // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision
1160*4882a593Smuzhiyun 
1161*4882a593Smuzhiyun    if (stbi__vertically_flip_on_load) {
1162*4882a593Smuzhiyun       int channels = req_comp ? req_comp : *comp;
1163*4882a593Smuzhiyun       stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16));
1164*4882a593Smuzhiyun    }
1165*4882a593Smuzhiyun 
1166*4882a593Smuzhiyun    return (stbi__uint16 *) result;
1167*4882a593Smuzhiyun }
1168*4882a593Smuzhiyun 
1169*4882a593Smuzhiyun #if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR)
stbi__float_postprocess(float * result,int * x,int * y,int * comp,int req_comp)1170*4882a593Smuzhiyun static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
1171*4882a593Smuzhiyun {
1172*4882a593Smuzhiyun    if (stbi__vertically_flip_on_load && result != NULL) {
1173*4882a593Smuzhiyun       int channels = req_comp ? req_comp : *comp;
1174*4882a593Smuzhiyun       stbi__vertical_flip(result, *x, *y, channels * sizeof(float));
1175*4882a593Smuzhiyun    }
1176*4882a593Smuzhiyun }
1177*4882a593Smuzhiyun #endif
1178*4882a593Smuzhiyun 
1179*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
1180*4882a593Smuzhiyun 
1181*4882a593Smuzhiyun #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
1182*4882a593Smuzhiyun STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
1183*4882a593Smuzhiyun STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
1184*4882a593Smuzhiyun #endif
1185*4882a593Smuzhiyun 
1186*4882a593Smuzhiyun #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
stbi_convert_wchar_to_utf8(char * buffer,size_t bufferlen,const wchar_t * input)1187*4882a593Smuzhiyun STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
1188*4882a593Smuzhiyun {
1189*4882a593Smuzhiyun 	return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
1190*4882a593Smuzhiyun }
1191*4882a593Smuzhiyun #endif
1192*4882a593Smuzhiyun 
stbi__fopen(char const * filename,char const * mode)1193*4882a593Smuzhiyun static FILE *stbi__fopen(char const *filename, char const *mode)
1194*4882a593Smuzhiyun {
1195*4882a593Smuzhiyun    FILE *f;
1196*4882a593Smuzhiyun #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
1197*4882a593Smuzhiyun    wchar_t wMode[64];
1198*4882a593Smuzhiyun    wchar_t wFilename[1024];
1199*4882a593Smuzhiyun 	if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
1200*4882a593Smuzhiyun       return 0;
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun 	if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
1203*4882a593Smuzhiyun       return 0;
1204*4882a593Smuzhiyun 
1205*4882a593Smuzhiyun #if _MSC_VER >= 1400
1206*4882a593Smuzhiyun 	if (0 != _wfopen_s(&f, wFilename, wMode))
1207*4882a593Smuzhiyun 		f = 0;
1208*4882a593Smuzhiyun #else
1209*4882a593Smuzhiyun    f = _wfopen(wFilename, wMode);
1210*4882a593Smuzhiyun #endif
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun #elif defined(_MSC_VER) && _MSC_VER >= 1400
1213*4882a593Smuzhiyun    if (0 != fopen_s(&f, filename, mode))
1214*4882a593Smuzhiyun       f=0;
1215*4882a593Smuzhiyun #else
1216*4882a593Smuzhiyun    f = fopen(filename, mode);
1217*4882a593Smuzhiyun #endif
1218*4882a593Smuzhiyun    return f;
1219*4882a593Smuzhiyun }
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 
stbi_load(char const * filename,int * x,int * y,int * comp,int req_comp)1222*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
1223*4882a593Smuzhiyun {
1224*4882a593Smuzhiyun    FILE *f = stbi__fopen(filename, "rb");
1225*4882a593Smuzhiyun    unsigned char *result;
1226*4882a593Smuzhiyun    if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
1227*4882a593Smuzhiyun    result = stbi_load_from_file(f,x,y,comp,req_comp);
1228*4882a593Smuzhiyun    fclose(f);
1229*4882a593Smuzhiyun    return result;
1230*4882a593Smuzhiyun }
1231*4882a593Smuzhiyun 
stbi_load_from_file(FILE * f,int * x,int * y,int * comp,int req_comp)1232*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
1233*4882a593Smuzhiyun {
1234*4882a593Smuzhiyun    unsigned char *result;
1235*4882a593Smuzhiyun    stbi__context s;
1236*4882a593Smuzhiyun    stbi__start_file(&s,f);
1237*4882a593Smuzhiyun    result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
1238*4882a593Smuzhiyun    if (result) {
1239*4882a593Smuzhiyun       // need to 'unget' all the characters in the IO buffer
1240*4882a593Smuzhiyun       fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
1241*4882a593Smuzhiyun    }
1242*4882a593Smuzhiyun    return result;
1243*4882a593Smuzhiyun }
1244*4882a593Smuzhiyun 
stbi_load_from_file_16(FILE * f,int * x,int * y,int * comp,int req_comp)1245*4882a593Smuzhiyun STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp)
1246*4882a593Smuzhiyun {
1247*4882a593Smuzhiyun    stbi__uint16 *result;
1248*4882a593Smuzhiyun    stbi__context s;
1249*4882a593Smuzhiyun    stbi__start_file(&s,f);
1250*4882a593Smuzhiyun    result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
1251*4882a593Smuzhiyun    if (result) {
1252*4882a593Smuzhiyun       // need to 'unget' all the characters in the IO buffer
1253*4882a593Smuzhiyun       fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
1254*4882a593Smuzhiyun    }
1255*4882a593Smuzhiyun    return result;
1256*4882a593Smuzhiyun }
1257*4882a593Smuzhiyun 
stbi_load_16(char const * filename,int * x,int * y,int * comp,int req_comp)1258*4882a593Smuzhiyun STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp)
1259*4882a593Smuzhiyun {
1260*4882a593Smuzhiyun    FILE *f = stbi__fopen(filename, "rb");
1261*4882a593Smuzhiyun    stbi__uint16 *result;
1262*4882a593Smuzhiyun    if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file");
1263*4882a593Smuzhiyun    result = stbi_load_from_file_16(f,x,y,comp,req_comp);
1264*4882a593Smuzhiyun    fclose(f);
1265*4882a593Smuzhiyun    return result;
1266*4882a593Smuzhiyun }
1267*4882a593Smuzhiyun 
1268*4882a593Smuzhiyun 
1269*4882a593Smuzhiyun #endif //!STBI_NO_STDIO
1270*4882a593Smuzhiyun 
stbi_load_16_from_memory(stbi_uc const * buffer,int len,int * x,int * y,int * channels_in_file,int desired_channels)1271*4882a593Smuzhiyun STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels)
1272*4882a593Smuzhiyun {
1273*4882a593Smuzhiyun    stbi__context s;
1274*4882a593Smuzhiyun    stbi__start_mem(&s,buffer,len);
1275*4882a593Smuzhiyun    return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
1276*4882a593Smuzhiyun }
1277*4882a593Smuzhiyun 
stbi_load_16_from_callbacks(stbi_io_callbacks const * clbk,void * user,int * x,int * y,int * channels_in_file,int desired_channels)1278*4882a593Smuzhiyun STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels)
1279*4882a593Smuzhiyun {
1280*4882a593Smuzhiyun    stbi__context s;
1281*4882a593Smuzhiyun    stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
1282*4882a593Smuzhiyun    return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
1283*4882a593Smuzhiyun }
1284*4882a593Smuzhiyun 
stbi_load_from_memory(stbi_uc const * buffer,int len,int * x,int * y,int * comp,int req_comp)1285*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
1286*4882a593Smuzhiyun {
1287*4882a593Smuzhiyun    stbi__context s;
1288*4882a593Smuzhiyun    stbi__start_mem(&s,buffer,len);
1289*4882a593Smuzhiyun    return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
1290*4882a593Smuzhiyun }
1291*4882a593Smuzhiyun 
stbi_load_from_callbacks(stbi_io_callbacks const * clbk,void * user,int * x,int * y,int * comp,int req_comp)1292*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
1293*4882a593Smuzhiyun {
1294*4882a593Smuzhiyun    stbi__context s;
1295*4882a593Smuzhiyun    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
1296*4882a593Smuzhiyun    return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
1297*4882a593Smuzhiyun }
1298*4882a593Smuzhiyun 
1299*4882a593Smuzhiyun #ifndef STBI_NO_GIF
stbi_load_gif_from_memory(stbi_uc const * buffer,int len,int ** delays,int * x,int * y,int * z,int * comp,int req_comp)1300*4882a593Smuzhiyun STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
1301*4882a593Smuzhiyun {
1302*4882a593Smuzhiyun    unsigned char *result;
1303*4882a593Smuzhiyun    stbi__context s;
1304*4882a593Smuzhiyun    stbi__start_mem(&s,buffer,len);
1305*4882a593Smuzhiyun 
1306*4882a593Smuzhiyun    result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
1307*4882a593Smuzhiyun    if (stbi__vertically_flip_on_load) {
1308*4882a593Smuzhiyun       stbi__vertical_flip_slices( result, *x, *y, *z, *comp );
1309*4882a593Smuzhiyun    }
1310*4882a593Smuzhiyun 
1311*4882a593Smuzhiyun    return result;
1312*4882a593Smuzhiyun }
1313*4882a593Smuzhiyun #endif
1314*4882a593Smuzhiyun 
1315*4882a593Smuzhiyun #ifndef STBI_NO_LINEAR
stbi__loadf_main(stbi__context * s,int * x,int * y,int * comp,int req_comp)1316*4882a593Smuzhiyun static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
1317*4882a593Smuzhiyun {
1318*4882a593Smuzhiyun    unsigned char *data;
1319*4882a593Smuzhiyun    #ifndef STBI_NO_HDR
1320*4882a593Smuzhiyun    if (stbi__hdr_test(s)) {
1321*4882a593Smuzhiyun       stbi__result_info ri;
1322*4882a593Smuzhiyun       float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri);
1323*4882a593Smuzhiyun       if (hdr_data)
1324*4882a593Smuzhiyun          stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
1325*4882a593Smuzhiyun       return hdr_data;
1326*4882a593Smuzhiyun    }
1327*4882a593Smuzhiyun    #endif
1328*4882a593Smuzhiyun    data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp);
1329*4882a593Smuzhiyun    if (data)
1330*4882a593Smuzhiyun       return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
1331*4882a593Smuzhiyun    return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
1332*4882a593Smuzhiyun }
1333*4882a593Smuzhiyun 
stbi_loadf_from_memory(stbi_uc const * buffer,int len,int * x,int * y,int * comp,int req_comp)1334*4882a593Smuzhiyun STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
1335*4882a593Smuzhiyun {
1336*4882a593Smuzhiyun    stbi__context s;
1337*4882a593Smuzhiyun    stbi__start_mem(&s,buffer,len);
1338*4882a593Smuzhiyun    return stbi__loadf_main(&s,x,y,comp,req_comp);
1339*4882a593Smuzhiyun }
1340*4882a593Smuzhiyun 
stbi_loadf_from_callbacks(stbi_io_callbacks const * clbk,void * user,int * x,int * y,int * comp,int req_comp)1341*4882a593Smuzhiyun STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
1342*4882a593Smuzhiyun {
1343*4882a593Smuzhiyun    stbi__context s;
1344*4882a593Smuzhiyun    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
1345*4882a593Smuzhiyun    return stbi__loadf_main(&s,x,y,comp,req_comp);
1346*4882a593Smuzhiyun }
1347*4882a593Smuzhiyun 
1348*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
stbi_loadf(char const * filename,int * x,int * y,int * comp,int req_comp)1349*4882a593Smuzhiyun STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp)
1350*4882a593Smuzhiyun {
1351*4882a593Smuzhiyun    float *result;
1352*4882a593Smuzhiyun    FILE *f = stbi__fopen(filename, "rb");
1353*4882a593Smuzhiyun    if (!f) return stbi__errpf("can't fopen", "Unable to open file");
1354*4882a593Smuzhiyun    result = stbi_loadf_from_file(f,x,y,comp,req_comp);
1355*4882a593Smuzhiyun    fclose(f);
1356*4882a593Smuzhiyun    return result;
1357*4882a593Smuzhiyun }
1358*4882a593Smuzhiyun 
stbi_loadf_from_file(FILE * f,int * x,int * y,int * comp,int req_comp)1359*4882a593Smuzhiyun STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
1360*4882a593Smuzhiyun {
1361*4882a593Smuzhiyun    stbi__context s;
1362*4882a593Smuzhiyun    stbi__start_file(&s,f);
1363*4882a593Smuzhiyun    return stbi__loadf_main(&s,x,y,comp,req_comp);
1364*4882a593Smuzhiyun }
1365*4882a593Smuzhiyun #endif // !STBI_NO_STDIO
1366*4882a593Smuzhiyun 
1367*4882a593Smuzhiyun #endif // !STBI_NO_LINEAR
1368*4882a593Smuzhiyun 
1369*4882a593Smuzhiyun // these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is
1370*4882a593Smuzhiyun // defined, for API simplicity; if STBI_NO_LINEAR is defined, it always
1371*4882a593Smuzhiyun // reports false!
1372*4882a593Smuzhiyun 
stbi_is_hdr_from_memory(stbi_uc const * buffer,int len)1373*4882a593Smuzhiyun STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
1374*4882a593Smuzhiyun {
1375*4882a593Smuzhiyun    #ifndef STBI_NO_HDR
1376*4882a593Smuzhiyun    stbi__context s;
1377*4882a593Smuzhiyun    stbi__start_mem(&s,buffer,len);
1378*4882a593Smuzhiyun    return stbi__hdr_test(&s);
1379*4882a593Smuzhiyun    #else
1380*4882a593Smuzhiyun    STBI_NOTUSED(buffer);
1381*4882a593Smuzhiyun    STBI_NOTUSED(len);
1382*4882a593Smuzhiyun    return 0;
1383*4882a593Smuzhiyun    #endif
1384*4882a593Smuzhiyun }
1385*4882a593Smuzhiyun 
1386*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
stbi_is_hdr(char const * filename)1387*4882a593Smuzhiyun STBIDEF int      stbi_is_hdr          (char const *filename)
1388*4882a593Smuzhiyun {
1389*4882a593Smuzhiyun    FILE *f = stbi__fopen(filename, "rb");
1390*4882a593Smuzhiyun    int result=0;
1391*4882a593Smuzhiyun    if (f) {
1392*4882a593Smuzhiyun       result = stbi_is_hdr_from_file(f);
1393*4882a593Smuzhiyun       fclose(f);
1394*4882a593Smuzhiyun    }
1395*4882a593Smuzhiyun    return result;
1396*4882a593Smuzhiyun }
1397*4882a593Smuzhiyun 
stbi_is_hdr_from_file(FILE * f)1398*4882a593Smuzhiyun STBIDEF int stbi_is_hdr_from_file(FILE *f)
1399*4882a593Smuzhiyun {
1400*4882a593Smuzhiyun    #ifndef STBI_NO_HDR
1401*4882a593Smuzhiyun    long pos = ftell(f);
1402*4882a593Smuzhiyun    int res;
1403*4882a593Smuzhiyun    stbi__context s;
1404*4882a593Smuzhiyun    stbi__start_file(&s,f);
1405*4882a593Smuzhiyun    res = stbi__hdr_test(&s);
1406*4882a593Smuzhiyun    fseek(f, pos, SEEK_SET);
1407*4882a593Smuzhiyun    return res;
1408*4882a593Smuzhiyun    #else
1409*4882a593Smuzhiyun    STBI_NOTUSED(f);
1410*4882a593Smuzhiyun    return 0;
1411*4882a593Smuzhiyun    #endif
1412*4882a593Smuzhiyun }
1413*4882a593Smuzhiyun #endif // !STBI_NO_STDIO
1414*4882a593Smuzhiyun 
stbi_is_hdr_from_callbacks(stbi_io_callbacks const * clbk,void * user)1415*4882a593Smuzhiyun STBIDEF int      stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user)
1416*4882a593Smuzhiyun {
1417*4882a593Smuzhiyun    #ifndef STBI_NO_HDR
1418*4882a593Smuzhiyun    stbi__context s;
1419*4882a593Smuzhiyun    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
1420*4882a593Smuzhiyun    return stbi__hdr_test(&s);
1421*4882a593Smuzhiyun    #else
1422*4882a593Smuzhiyun    STBI_NOTUSED(clbk);
1423*4882a593Smuzhiyun    STBI_NOTUSED(user);
1424*4882a593Smuzhiyun    return 0;
1425*4882a593Smuzhiyun    #endif
1426*4882a593Smuzhiyun }
1427*4882a593Smuzhiyun 
1428*4882a593Smuzhiyun #ifndef STBI_NO_LINEAR
1429*4882a593Smuzhiyun static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f;
1430*4882a593Smuzhiyun 
stbi_ldr_to_hdr_gamma(float gamma)1431*4882a593Smuzhiyun STBIDEF void   stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
stbi_ldr_to_hdr_scale(float scale)1432*4882a593Smuzhiyun STBIDEF void   stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
1433*4882a593Smuzhiyun #endif
1434*4882a593Smuzhiyun 
1435*4882a593Smuzhiyun static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
1436*4882a593Smuzhiyun 
stbi_hdr_to_ldr_gamma(float gamma)1437*4882a593Smuzhiyun STBIDEF void   stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
stbi_hdr_to_ldr_scale(float scale)1438*4882a593Smuzhiyun STBIDEF void   stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
1439*4882a593Smuzhiyun 
1440*4882a593Smuzhiyun 
1441*4882a593Smuzhiyun //////////////////////////////////////////////////////////////////////////////
1442*4882a593Smuzhiyun //
1443*4882a593Smuzhiyun // Common code used by all image loaders
1444*4882a593Smuzhiyun //
1445*4882a593Smuzhiyun 
1446*4882a593Smuzhiyun enum
1447*4882a593Smuzhiyun {
1448*4882a593Smuzhiyun    STBI__SCAN_load=0,
1449*4882a593Smuzhiyun    STBI__SCAN_type,
1450*4882a593Smuzhiyun    STBI__SCAN_header
1451*4882a593Smuzhiyun };
1452*4882a593Smuzhiyun 
stbi__refill_buffer(stbi__context * s)1453*4882a593Smuzhiyun static void stbi__refill_buffer(stbi__context *s)
1454*4882a593Smuzhiyun {
1455*4882a593Smuzhiyun    int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
1456*4882a593Smuzhiyun    if (n == 0) {
1457*4882a593Smuzhiyun       // at end of file, treat same as if from memory, but need to handle case
1458*4882a593Smuzhiyun       // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
1459*4882a593Smuzhiyun       s->read_from_callbacks = 0;
1460*4882a593Smuzhiyun       s->img_buffer = s->buffer_start;
1461*4882a593Smuzhiyun       s->img_buffer_end = s->buffer_start+1;
1462*4882a593Smuzhiyun       *s->img_buffer = 0;
1463*4882a593Smuzhiyun    } else {
1464*4882a593Smuzhiyun       s->img_buffer = s->buffer_start;
1465*4882a593Smuzhiyun       s->img_buffer_end = s->buffer_start + n;
1466*4882a593Smuzhiyun    }
1467*4882a593Smuzhiyun }
1468*4882a593Smuzhiyun 
stbi__get8(stbi__context * s)1469*4882a593Smuzhiyun stbi_inline static stbi_uc stbi__get8(stbi__context *s)
1470*4882a593Smuzhiyun {
1471*4882a593Smuzhiyun    if (s->img_buffer < s->img_buffer_end)
1472*4882a593Smuzhiyun       return *s->img_buffer++;
1473*4882a593Smuzhiyun    if (s->read_from_callbacks) {
1474*4882a593Smuzhiyun       stbi__refill_buffer(s);
1475*4882a593Smuzhiyun       return *s->img_buffer++;
1476*4882a593Smuzhiyun    }
1477*4882a593Smuzhiyun    return 0;
1478*4882a593Smuzhiyun }
1479*4882a593Smuzhiyun 
stbi__at_eof(stbi__context * s)1480*4882a593Smuzhiyun stbi_inline static int stbi__at_eof(stbi__context *s)
1481*4882a593Smuzhiyun {
1482*4882a593Smuzhiyun    if (s->io.read) {
1483*4882a593Smuzhiyun       if (!(s->io.eof)(s->io_user_data)) return 0;
1484*4882a593Smuzhiyun       // if feof() is true, check if buffer = end
1485*4882a593Smuzhiyun       // special case: we've only got the special 0 character at the end
1486*4882a593Smuzhiyun       if (s->read_from_callbacks == 0) return 1;
1487*4882a593Smuzhiyun    }
1488*4882a593Smuzhiyun 
1489*4882a593Smuzhiyun    return s->img_buffer >= s->img_buffer_end;
1490*4882a593Smuzhiyun }
1491*4882a593Smuzhiyun 
stbi__skip(stbi__context * s,int n)1492*4882a593Smuzhiyun static void stbi__skip(stbi__context *s, int n)
1493*4882a593Smuzhiyun {
1494*4882a593Smuzhiyun    if (n < 0) {
1495*4882a593Smuzhiyun       s->img_buffer = s->img_buffer_end;
1496*4882a593Smuzhiyun       return;
1497*4882a593Smuzhiyun    }
1498*4882a593Smuzhiyun    if (s->io.read) {
1499*4882a593Smuzhiyun       int blen = (int) (s->img_buffer_end - s->img_buffer);
1500*4882a593Smuzhiyun       if (blen < n) {
1501*4882a593Smuzhiyun          s->img_buffer = s->img_buffer_end;
1502*4882a593Smuzhiyun          (s->io.skip)(s->io_user_data, n - blen);
1503*4882a593Smuzhiyun          return;
1504*4882a593Smuzhiyun       }
1505*4882a593Smuzhiyun    }
1506*4882a593Smuzhiyun    s->img_buffer += n;
1507*4882a593Smuzhiyun }
1508*4882a593Smuzhiyun 
stbi__getn(stbi__context * s,stbi_uc * buffer,int n)1509*4882a593Smuzhiyun static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
1510*4882a593Smuzhiyun {
1511*4882a593Smuzhiyun    if (s->io.read) {
1512*4882a593Smuzhiyun       int blen = (int) (s->img_buffer_end - s->img_buffer);
1513*4882a593Smuzhiyun       if (blen < n) {
1514*4882a593Smuzhiyun          int res, count;
1515*4882a593Smuzhiyun 
1516*4882a593Smuzhiyun          memcpy(buffer, s->img_buffer, blen);
1517*4882a593Smuzhiyun 
1518*4882a593Smuzhiyun          count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen);
1519*4882a593Smuzhiyun          res = (count == (n-blen));
1520*4882a593Smuzhiyun          s->img_buffer = s->img_buffer_end;
1521*4882a593Smuzhiyun          return res;
1522*4882a593Smuzhiyun       }
1523*4882a593Smuzhiyun    }
1524*4882a593Smuzhiyun 
1525*4882a593Smuzhiyun    if (s->img_buffer+n <= s->img_buffer_end) {
1526*4882a593Smuzhiyun       memcpy(buffer, s->img_buffer, n);
1527*4882a593Smuzhiyun       s->img_buffer += n;
1528*4882a593Smuzhiyun       return 1;
1529*4882a593Smuzhiyun    } else
1530*4882a593Smuzhiyun       return 0;
1531*4882a593Smuzhiyun }
1532*4882a593Smuzhiyun 
stbi__get16be(stbi__context * s)1533*4882a593Smuzhiyun static int stbi__get16be(stbi__context *s)
1534*4882a593Smuzhiyun {
1535*4882a593Smuzhiyun    int z = stbi__get8(s);
1536*4882a593Smuzhiyun    return (z << 8) + stbi__get8(s);
1537*4882a593Smuzhiyun }
1538*4882a593Smuzhiyun 
stbi__get32be(stbi__context * s)1539*4882a593Smuzhiyun static stbi__uint32 stbi__get32be(stbi__context *s)
1540*4882a593Smuzhiyun {
1541*4882a593Smuzhiyun    stbi__uint32 z = stbi__get16be(s);
1542*4882a593Smuzhiyun    return (z << 16) + stbi__get16be(s);
1543*4882a593Smuzhiyun }
1544*4882a593Smuzhiyun 
1545*4882a593Smuzhiyun #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
1546*4882a593Smuzhiyun // nothing
1547*4882a593Smuzhiyun #else
stbi__get16le(stbi__context * s)1548*4882a593Smuzhiyun static int stbi__get16le(stbi__context *s)
1549*4882a593Smuzhiyun {
1550*4882a593Smuzhiyun    int z = stbi__get8(s);
1551*4882a593Smuzhiyun    return z + (stbi__get8(s) << 8);
1552*4882a593Smuzhiyun }
1553*4882a593Smuzhiyun #endif
1554*4882a593Smuzhiyun 
1555*4882a593Smuzhiyun #ifndef STBI_NO_BMP
stbi__get32le(stbi__context * s)1556*4882a593Smuzhiyun static stbi__uint32 stbi__get32le(stbi__context *s)
1557*4882a593Smuzhiyun {
1558*4882a593Smuzhiyun    stbi__uint32 z = stbi__get16le(s);
1559*4882a593Smuzhiyun    return z + (stbi__get16le(s) << 16);
1560*4882a593Smuzhiyun }
1561*4882a593Smuzhiyun #endif
1562*4882a593Smuzhiyun 
1563*4882a593Smuzhiyun #define STBI__BYTECAST(x)  ((stbi_uc) ((x) & 255))  // truncate int to byte without warnings
1564*4882a593Smuzhiyun 
1565*4882a593Smuzhiyun 
1566*4882a593Smuzhiyun //////////////////////////////////////////////////////////////////////////////
1567*4882a593Smuzhiyun //
1568*4882a593Smuzhiyun //  generic converter from built-in img_n to req_comp
1569*4882a593Smuzhiyun //    individual types do this automatically as much as possible (e.g. jpeg
1570*4882a593Smuzhiyun //    does all cases internally since it needs to colorspace convert anyway,
1571*4882a593Smuzhiyun //    and it never has alpha, so very few cases ). png can automatically
1572*4882a593Smuzhiyun //    interleave an alpha=255 channel, but falls back to this for other cases
1573*4882a593Smuzhiyun //
1574*4882a593Smuzhiyun //  assume data buffer is malloced, so malloc a new one and free that one
1575*4882a593Smuzhiyun //  only failure mode is malloc failing
1576*4882a593Smuzhiyun 
stbi__compute_y(int r,int g,int b)1577*4882a593Smuzhiyun static stbi_uc stbi__compute_y(int r, int g, int b)
1578*4882a593Smuzhiyun {
1579*4882a593Smuzhiyun    return (stbi_uc) (((r*77) + (g*150) +  (29*b)) >> 8);
1580*4882a593Smuzhiyun }
1581*4882a593Smuzhiyun 
stbi__convert_format(unsigned char * data,int img_n,int req_comp,unsigned int x,unsigned int y)1582*4882a593Smuzhiyun static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y)
1583*4882a593Smuzhiyun {
1584*4882a593Smuzhiyun    int i,j;
1585*4882a593Smuzhiyun    unsigned char *good;
1586*4882a593Smuzhiyun 
1587*4882a593Smuzhiyun    if (req_comp == img_n) return data;
1588*4882a593Smuzhiyun    STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
1589*4882a593Smuzhiyun 
1590*4882a593Smuzhiyun    good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0);
1591*4882a593Smuzhiyun    if (good == NULL) {
1592*4882a593Smuzhiyun       STBI_FREE(data);
1593*4882a593Smuzhiyun       return stbi__errpuc("outofmem", "Out of memory");
1594*4882a593Smuzhiyun    }
1595*4882a593Smuzhiyun 
1596*4882a593Smuzhiyun    for (j=0; j < (int) y; ++j) {
1597*4882a593Smuzhiyun       unsigned char *src  = data + j * x * img_n   ;
1598*4882a593Smuzhiyun       unsigned char *dest = good + j * x * req_comp;
1599*4882a593Smuzhiyun 
1600*4882a593Smuzhiyun       #define STBI__COMBO(a,b)  ((a)*8+(b))
1601*4882a593Smuzhiyun       #define STBI__CASE(a,b)   case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
1602*4882a593Smuzhiyun       // convert source image with img_n components to one with req_comp components;
1603*4882a593Smuzhiyun       // avoid switch per pixel, so use switch per scanline and massive macros
1604*4882a593Smuzhiyun       switch (STBI__COMBO(img_n, req_comp)) {
1605*4882a593Smuzhiyun          STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255;                                     } break;
1606*4882a593Smuzhiyun          STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0];                                  } break;
1607*4882a593Smuzhiyun          STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255;                     } break;
1608*4882a593Smuzhiyun          STBI__CASE(2,1) { dest[0]=src[0];                                                  } break;
1609*4882a593Smuzhiyun          STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0];                                  } break;
1610*4882a593Smuzhiyun          STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1];                  } break;
1611*4882a593Smuzhiyun          STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255;        } break;
1612*4882a593Smuzhiyun          STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]);                   } break;
1613*4882a593Smuzhiyun          STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255;    } break;
1614*4882a593Smuzhiyun          STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]);                   } break;
1615*4882a593Smuzhiyun          STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
1616*4882a593Smuzhiyun          STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];                    } break;
1617*4882a593Smuzhiyun          default: STBI_ASSERT(0);
1618*4882a593Smuzhiyun       }
1619*4882a593Smuzhiyun       #undef STBI__CASE
1620*4882a593Smuzhiyun    }
1621*4882a593Smuzhiyun 
1622*4882a593Smuzhiyun    STBI_FREE(data);
1623*4882a593Smuzhiyun    return good;
1624*4882a593Smuzhiyun }
1625*4882a593Smuzhiyun 
stbi__compute_y_16(int r,int g,int b)1626*4882a593Smuzhiyun static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
1627*4882a593Smuzhiyun {
1628*4882a593Smuzhiyun    return (stbi__uint16) (((r*77) + (g*150) +  (29*b)) >> 8);
1629*4882a593Smuzhiyun }
1630*4882a593Smuzhiyun 
stbi__convert_format16(stbi__uint16 * data,int img_n,int req_comp,unsigned int x,unsigned int y)1631*4882a593Smuzhiyun static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
1632*4882a593Smuzhiyun {
1633*4882a593Smuzhiyun    int i,j;
1634*4882a593Smuzhiyun    stbi__uint16 *good;
1635*4882a593Smuzhiyun 
1636*4882a593Smuzhiyun    if (req_comp == img_n) return data;
1637*4882a593Smuzhiyun    STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
1638*4882a593Smuzhiyun 
1639*4882a593Smuzhiyun    good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2);
1640*4882a593Smuzhiyun    if (good == NULL) {
1641*4882a593Smuzhiyun       STBI_FREE(data);
1642*4882a593Smuzhiyun       return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
1643*4882a593Smuzhiyun    }
1644*4882a593Smuzhiyun 
1645*4882a593Smuzhiyun    for (j=0; j < (int) y; ++j) {
1646*4882a593Smuzhiyun       stbi__uint16 *src  = data + j * x * img_n   ;
1647*4882a593Smuzhiyun       stbi__uint16 *dest = good + j * x * req_comp;
1648*4882a593Smuzhiyun 
1649*4882a593Smuzhiyun       #define STBI__COMBO(a,b)  ((a)*8+(b))
1650*4882a593Smuzhiyun       #define STBI__CASE(a,b)   case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
1651*4882a593Smuzhiyun       // convert source image with img_n components to one with req_comp components;
1652*4882a593Smuzhiyun       // avoid switch per pixel, so use switch per scanline and massive macros
1653*4882a593Smuzhiyun       switch (STBI__COMBO(img_n, req_comp)) {
1654*4882a593Smuzhiyun          STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff;                                     } break;
1655*4882a593Smuzhiyun          STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0];                                     } break;
1656*4882a593Smuzhiyun          STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff;                     } break;
1657*4882a593Smuzhiyun          STBI__CASE(2,1) { dest[0]=src[0];                                                     } break;
1658*4882a593Smuzhiyun          STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0];                                     } break;
1659*4882a593Smuzhiyun          STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1];                     } break;
1660*4882a593Smuzhiyun          STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff;        } break;
1661*4882a593Smuzhiyun          STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]);                   } break;
1662*4882a593Smuzhiyun          STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break;
1663*4882a593Smuzhiyun          STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]);                   } break;
1664*4882a593Smuzhiyun          STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
1665*4882a593Smuzhiyun          STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];                       } break;
1666*4882a593Smuzhiyun          default: STBI_ASSERT(0);
1667*4882a593Smuzhiyun       }
1668*4882a593Smuzhiyun       #undef STBI__CASE
1669*4882a593Smuzhiyun    }
1670*4882a593Smuzhiyun 
1671*4882a593Smuzhiyun    STBI_FREE(data);
1672*4882a593Smuzhiyun    return good;
1673*4882a593Smuzhiyun }
1674*4882a593Smuzhiyun 
1675*4882a593Smuzhiyun #ifndef STBI_NO_LINEAR
stbi__ldr_to_hdr(stbi_uc * data,int x,int y,int comp)1676*4882a593Smuzhiyun static float   *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
1677*4882a593Smuzhiyun {
1678*4882a593Smuzhiyun    int i,k,n;
1679*4882a593Smuzhiyun    float *output;
1680*4882a593Smuzhiyun    if (!data) return NULL;
1681*4882a593Smuzhiyun    output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0);
1682*4882a593Smuzhiyun    if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); }
1683*4882a593Smuzhiyun    // compute number of non-alpha components
1684*4882a593Smuzhiyun    if (comp & 1) n = comp; else n = comp-1;
1685*4882a593Smuzhiyun    for (i=0; i < x*y; ++i) {
1686*4882a593Smuzhiyun       for (k=0; k < n; ++k) {
1687*4882a593Smuzhiyun          output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
1688*4882a593Smuzhiyun       }
1689*4882a593Smuzhiyun    }
1690*4882a593Smuzhiyun    if (n < comp) {
1691*4882a593Smuzhiyun       for (i=0; i < x*y; ++i) {
1692*4882a593Smuzhiyun          output[i*comp + n] = data[i*comp + n]/255.0f;
1693*4882a593Smuzhiyun       }
1694*4882a593Smuzhiyun    }
1695*4882a593Smuzhiyun    STBI_FREE(data);
1696*4882a593Smuzhiyun    return output;
1697*4882a593Smuzhiyun }
1698*4882a593Smuzhiyun #endif
1699*4882a593Smuzhiyun 
1700*4882a593Smuzhiyun #ifndef STBI_NO_HDR
1701*4882a593Smuzhiyun #define stbi__float2int(x)   ((int) (x))
stbi__hdr_to_ldr(float * data,int x,int y,int comp)1702*4882a593Smuzhiyun static stbi_uc *stbi__hdr_to_ldr(float   *data, int x, int y, int comp)
1703*4882a593Smuzhiyun {
1704*4882a593Smuzhiyun    int i,k,n;
1705*4882a593Smuzhiyun    stbi_uc *output;
1706*4882a593Smuzhiyun    if (!data) return NULL;
1707*4882a593Smuzhiyun    output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0);
1708*4882a593Smuzhiyun    if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); }
1709*4882a593Smuzhiyun    // compute number of non-alpha components
1710*4882a593Smuzhiyun    if (comp & 1) n = comp; else n = comp-1;
1711*4882a593Smuzhiyun    for (i=0; i < x*y; ++i) {
1712*4882a593Smuzhiyun       for (k=0; k < n; ++k) {
1713*4882a593Smuzhiyun          float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f;
1714*4882a593Smuzhiyun          if (z < 0) z = 0;
1715*4882a593Smuzhiyun          if (z > 255) z = 255;
1716*4882a593Smuzhiyun          output[i*comp + k] = (stbi_uc) stbi__float2int(z);
1717*4882a593Smuzhiyun       }
1718*4882a593Smuzhiyun       if (k < comp) {
1719*4882a593Smuzhiyun          float z = data[i*comp+k] * 255 + 0.5f;
1720*4882a593Smuzhiyun          if (z < 0) z = 0;
1721*4882a593Smuzhiyun          if (z > 255) z = 255;
1722*4882a593Smuzhiyun          output[i*comp + k] = (stbi_uc) stbi__float2int(z);
1723*4882a593Smuzhiyun       }
1724*4882a593Smuzhiyun    }
1725*4882a593Smuzhiyun    STBI_FREE(data);
1726*4882a593Smuzhiyun    return output;
1727*4882a593Smuzhiyun }
1728*4882a593Smuzhiyun #endif
1729*4882a593Smuzhiyun 
1730*4882a593Smuzhiyun //////////////////////////////////////////////////////////////////////////////
1731*4882a593Smuzhiyun //
1732*4882a593Smuzhiyun //  "baseline" JPEG/JFIF decoder
1733*4882a593Smuzhiyun //
1734*4882a593Smuzhiyun //    simple implementation
1735*4882a593Smuzhiyun //      - doesn't support delayed output of y-dimension
1736*4882a593Smuzhiyun //      - simple interface (only one output format: 8-bit interleaved RGB)
1737*4882a593Smuzhiyun //      - doesn't try to recover corrupt jpegs
1738*4882a593Smuzhiyun //      - doesn't allow partial loading, loading multiple at once
1739*4882a593Smuzhiyun //      - still fast on x86 (copying globals into locals doesn't help x86)
1740*4882a593Smuzhiyun //      - allocates lots of intermediate memory (full size of all components)
1741*4882a593Smuzhiyun //        - non-interleaved case requires this anyway
1742*4882a593Smuzhiyun //        - allows good upsampling (see next)
1743*4882a593Smuzhiyun //    high-quality
1744*4882a593Smuzhiyun //      - upsampled channels are bilinearly interpolated, even across blocks
1745*4882a593Smuzhiyun //      - quality integer IDCT derived from IJG's 'slow'
1746*4882a593Smuzhiyun //    performance
1747*4882a593Smuzhiyun //      - fast huffman; reasonable integer IDCT
1748*4882a593Smuzhiyun //      - some SIMD kernels for common paths on targets with SSE2/NEON
1749*4882a593Smuzhiyun //      - uses a lot of intermediate memory, could cache poorly
1750*4882a593Smuzhiyun 
1751*4882a593Smuzhiyun #ifndef STBI_NO_JPEG
1752*4882a593Smuzhiyun 
1753*4882a593Smuzhiyun // huffman decoding acceleration
1754*4882a593Smuzhiyun #define FAST_BITS   9  // larger handles more cases; smaller stomps less cache
1755*4882a593Smuzhiyun 
1756*4882a593Smuzhiyun typedef struct
1757*4882a593Smuzhiyun {
1758*4882a593Smuzhiyun    stbi_uc  fast[1 << FAST_BITS];
1759*4882a593Smuzhiyun    // weirdly, repacking this into AoS is a 10% speed loss, instead of a win
1760*4882a593Smuzhiyun    stbi__uint16 code[256];
1761*4882a593Smuzhiyun    stbi_uc  values[256];
1762*4882a593Smuzhiyun    stbi_uc  size[257];
1763*4882a593Smuzhiyun    unsigned int maxcode[18];
1764*4882a593Smuzhiyun    int    delta[17];   // old 'firstsymbol' - old 'firstcode'
1765*4882a593Smuzhiyun } stbi__huffman;
1766*4882a593Smuzhiyun 
1767*4882a593Smuzhiyun typedef struct
1768*4882a593Smuzhiyun {
1769*4882a593Smuzhiyun    stbi__context *s;
1770*4882a593Smuzhiyun    stbi__huffman huff_dc[4];
1771*4882a593Smuzhiyun    stbi__huffman huff_ac[4];
1772*4882a593Smuzhiyun    stbi__uint16 dequant[4][64];
1773*4882a593Smuzhiyun    stbi__int16 fast_ac[4][1 << FAST_BITS];
1774*4882a593Smuzhiyun 
1775*4882a593Smuzhiyun // sizes for components, interleaved MCUs
1776*4882a593Smuzhiyun    int img_h_max, img_v_max;
1777*4882a593Smuzhiyun    int img_mcu_x, img_mcu_y;
1778*4882a593Smuzhiyun    int img_mcu_w, img_mcu_h;
1779*4882a593Smuzhiyun 
1780*4882a593Smuzhiyun // definition of jpeg image component
1781*4882a593Smuzhiyun    struct
1782*4882a593Smuzhiyun    {
1783*4882a593Smuzhiyun       int id;
1784*4882a593Smuzhiyun       int h,v;
1785*4882a593Smuzhiyun       int tq;
1786*4882a593Smuzhiyun       int hd,ha;
1787*4882a593Smuzhiyun       int dc_pred;
1788*4882a593Smuzhiyun 
1789*4882a593Smuzhiyun       int x,y,w2,h2;
1790*4882a593Smuzhiyun       stbi_uc *data;
1791*4882a593Smuzhiyun       void *raw_data, *raw_coeff;
1792*4882a593Smuzhiyun       stbi_uc *linebuf;
1793*4882a593Smuzhiyun       short   *coeff;   // progressive only
1794*4882a593Smuzhiyun       int      coeff_w, coeff_h; // number of 8x8 coefficient blocks
1795*4882a593Smuzhiyun    } img_comp[4];
1796*4882a593Smuzhiyun 
1797*4882a593Smuzhiyun    stbi__uint32   code_buffer; // jpeg entropy-coded buffer
1798*4882a593Smuzhiyun    int            code_bits;   // number of valid bits
1799*4882a593Smuzhiyun    unsigned char  marker;      // marker seen while filling entropy buffer
1800*4882a593Smuzhiyun    int            nomore;      // flag if we saw a marker so must stop
1801*4882a593Smuzhiyun 
1802*4882a593Smuzhiyun    int            progressive;
1803*4882a593Smuzhiyun    int            spec_start;
1804*4882a593Smuzhiyun    int            spec_end;
1805*4882a593Smuzhiyun    int            succ_high;
1806*4882a593Smuzhiyun    int            succ_low;
1807*4882a593Smuzhiyun    int            eob_run;
1808*4882a593Smuzhiyun    int            jfif;
1809*4882a593Smuzhiyun    int            app14_color_transform; // Adobe APP14 tag
1810*4882a593Smuzhiyun    int            rgb;
1811*4882a593Smuzhiyun 
1812*4882a593Smuzhiyun    int scan_n, order[4];
1813*4882a593Smuzhiyun    int restart_interval, todo;
1814*4882a593Smuzhiyun 
1815*4882a593Smuzhiyun // kernels
1816*4882a593Smuzhiyun    void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]);
1817*4882a593Smuzhiyun    void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step);
1818*4882a593Smuzhiyun    stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs);
1819*4882a593Smuzhiyun } stbi__jpeg;
1820*4882a593Smuzhiyun 
stbi__build_huffman(stbi__huffman * h,int * count)1821*4882a593Smuzhiyun static int stbi__build_huffman(stbi__huffman *h, int *count)
1822*4882a593Smuzhiyun {
1823*4882a593Smuzhiyun    int i,j,k=0;
1824*4882a593Smuzhiyun    unsigned int code;
1825*4882a593Smuzhiyun    // build size list for each symbol (from JPEG spec)
1826*4882a593Smuzhiyun    for (i=0; i < 16; ++i)
1827*4882a593Smuzhiyun       for (j=0; j < count[i]; ++j)
1828*4882a593Smuzhiyun          h->size[k++] = (stbi_uc) (i+1);
1829*4882a593Smuzhiyun    h->size[k] = 0;
1830*4882a593Smuzhiyun 
1831*4882a593Smuzhiyun    // compute actual symbols (from jpeg spec)
1832*4882a593Smuzhiyun    code = 0;
1833*4882a593Smuzhiyun    k = 0;
1834*4882a593Smuzhiyun    for(j=1; j <= 16; ++j) {
1835*4882a593Smuzhiyun       // compute delta to add to code to compute symbol id
1836*4882a593Smuzhiyun       h->delta[j] = k - code;
1837*4882a593Smuzhiyun       if (h->size[k] == j) {
1838*4882a593Smuzhiyun          while (h->size[k] == j)
1839*4882a593Smuzhiyun             h->code[k++] = (stbi__uint16) (code++);
1840*4882a593Smuzhiyun          if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG");
1841*4882a593Smuzhiyun       }
1842*4882a593Smuzhiyun       // compute largest code + 1 for this size, preshifted as needed later
1843*4882a593Smuzhiyun       h->maxcode[j] = code << (16-j);
1844*4882a593Smuzhiyun       code <<= 1;
1845*4882a593Smuzhiyun    }
1846*4882a593Smuzhiyun    h->maxcode[j] = 0xffffffff;
1847*4882a593Smuzhiyun 
1848*4882a593Smuzhiyun    // build non-spec acceleration table; 255 is flag for not-accelerated
1849*4882a593Smuzhiyun    memset(h->fast, 255, 1 << FAST_BITS);
1850*4882a593Smuzhiyun    for (i=0; i < k; ++i) {
1851*4882a593Smuzhiyun       int s = h->size[i];
1852*4882a593Smuzhiyun       if (s <= FAST_BITS) {
1853*4882a593Smuzhiyun          int c = h->code[i] << (FAST_BITS-s);
1854*4882a593Smuzhiyun          int m = 1 << (FAST_BITS-s);
1855*4882a593Smuzhiyun          for (j=0; j < m; ++j) {
1856*4882a593Smuzhiyun             h->fast[c+j] = (stbi_uc) i;
1857*4882a593Smuzhiyun          }
1858*4882a593Smuzhiyun       }
1859*4882a593Smuzhiyun    }
1860*4882a593Smuzhiyun    return 1;
1861*4882a593Smuzhiyun }
1862*4882a593Smuzhiyun 
1863*4882a593Smuzhiyun // build a table that decodes both magnitude and value of small ACs in
1864*4882a593Smuzhiyun // one go.
stbi__build_fast_ac(stbi__int16 * fast_ac,stbi__huffman * h)1865*4882a593Smuzhiyun static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
1866*4882a593Smuzhiyun {
1867*4882a593Smuzhiyun    int i;
1868*4882a593Smuzhiyun    for (i=0; i < (1 << FAST_BITS); ++i) {
1869*4882a593Smuzhiyun       stbi_uc fast = h->fast[i];
1870*4882a593Smuzhiyun       fast_ac[i] = 0;
1871*4882a593Smuzhiyun       if (fast < 255) {
1872*4882a593Smuzhiyun          int rs = h->values[fast];
1873*4882a593Smuzhiyun          int run = (rs >> 4) & 15;
1874*4882a593Smuzhiyun          int magbits = rs & 15;
1875*4882a593Smuzhiyun          int len = h->size[fast];
1876*4882a593Smuzhiyun 
1877*4882a593Smuzhiyun          if (magbits && len + magbits <= FAST_BITS) {
1878*4882a593Smuzhiyun             // magnitude code followed by receive_extend code
1879*4882a593Smuzhiyun             int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
1880*4882a593Smuzhiyun             int m = 1 << (magbits - 1);
1881*4882a593Smuzhiyun             if (k < m) k += (~0U << magbits) + 1;
1882*4882a593Smuzhiyun             // if the result is small enough, we can fit it in fast_ac table
1883*4882a593Smuzhiyun             if (k >= -128 && k <= 127)
1884*4882a593Smuzhiyun                fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits));
1885*4882a593Smuzhiyun          }
1886*4882a593Smuzhiyun       }
1887*4882a593Smuzhiyun    }
1888*4882a593Smuzhiyun }
1889*4882a593Smuzhiyun 
stbi__grow_buffer_unsafe(stbi__jpeg * j)1890*4882a593Smuzhiyun static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
1891*4882a593Smuzhiyun {
1892*4882a593Smuzhiyun    do {
1893*4882a593Smuzhiyun       unsigned int b = j->nomore ? 0 : stbi__get8(j->s);
1894*4882a593Smuzhiyun       if (b == 0xff) {
1895*4882a593Smuzhiyun          int c = stbi__get8(j->s);
1896*4882a593Smuzhiyun          while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes
1897*4882a593Smuzhiyun          if (c != 0) {
1898*4882a593Smuzhiyun             j->marker = (unsigned char) c;
1899*4882a593Smuzhiyun             j->nomore = 1;
1900*4882a593Smuzhiyun             return;
1901*4882a593Smuzhiyun          }
1902*4882a593Smuzhiyun       }
1903*4882a593Smuzhiyun       j->code_buffer |= b << (24 - j->code_bits);
1904*4882a593Smuzhiyun       j->code_bits += 8;
1905*4882a593Smuzhiyun    } while (j->code_bits <= 24);
1906*4882a593Smuzhiyun }
1907*4882a593Smuzhiyun 
1908*4882a593Smuzhiyun // (1 << n) - 1
1909*4882a593Smuzhiyun static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
1910*4882a593Smuzhiyun 
1911*4882a593Smuzhiyun // decode a jpeg huffman value from the bitstream
stbi__jpeg_huff_decode(stbi__jpeg * j,stbi__huffman * h)1912*4882a593Smuzhiyun stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
1913*4882a593Smuzhiyun {
1914*4882a593Smuzhiyun    unsigned int temp;
1915*4882a593Smuzhiyun    int c,k;
1916*4882a593Smuzhiyun 
1917*4882a593Smuzhiyun    if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
1918*4882a593Smuzhiyun 
1919*4882a593Smuzhiyun    // look at the top FAST_BITS and determine what symbol ID it is,
1920*4882a593Smuzhiyun    // if the code is <= FAST_BITS
1921*4882a593Smuzhiyun    c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
1922*4882a593Smuzhiyun    k = h->fast[c];
1923*4882a593Smuzhiyun    if (k < 255) {
1924*4882a593Smuzhiyun       int s = h->size[k];
1925*4882a593Smuzhiyun       if (s > j->code_bits)
1926*4882a593Smuzhiyun          return -1;
1927*4882a593Smuzhiyun       j->code_buffer <<= s;
1928*4882a593Smuzhiyun       j->code_bits -= s;
1929*4882a593Smuzhiyun       return h->values[k];
1930*4882a593Smuzhiyun    }
1931*4882a593Smuzhiyun 
1932*4882a593Smuzhiyun    // naive test is to shift the code_buffer down so k bits are
1933*4882a593Smuzhiyun    // valid, then test against maxcode. To speed this up, we've
1934*4882a593Smuzhiyun    // preshifted maxcode left so that it has (16-k) 0s at the
1935*4882a593Smuzhiyun    // end; in other words, regardless of the number of bits, it
1936*4882a593Smuzhiyun    // wants to be compared against something shifted to have 16;
1937*4882a593Smuzhiyun    // that way we don't need to shift inside the loop.
1938*4882a593Smuzhiyun    temp = j->code_buffer >> 16;
1939*4882a593Smuzhiyun    for (k=FAST_BITS+1 ; ; ++k)
1940*4882a593Smuzhiyun       if (temp < h->maxcode[k])
1941*4882a593Smuzhiyun          break;
1942*4882a593Smuzhiyun    if (k == 17) {
1943*4882a593Smuzhiyun       // error! code not found
1944*4882a593Smuzhiyun       j->code_bits -= 16;
1945*4882a593Smuzhiyun       return -1;
1946*4882a593Smuzhiyun    }
1947*4882a593Smuzhiyun 
1948*4882a593Smuzhiyun    if (k > j->code_bits)
1949*4882a593Smuzhiyun       return -1;
1950*4882a593Smuzhiyun 
1951*4882a593Smuzhiyun    // convert the huffman code to the symbol id
1952*4882a593Smuzhiyun    c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
1953*4882a593Smuzhiyun    STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
1954*4882a593Smuzhiyun 
1955*4882a593Smuzhiyun    // convert the id to a symbol
1956*4882a593Smuzhiyun    j->code_bits -= k;
1957*4882a593Smuzhiyun    j->code_buffer <<= k;
1958*4882a593Smuzhiyun    return h->values[c];
1959*4882a593Smuzhiyun }
1960*4882a593Smuzhiyun 
1961*4882a593Smuzhiyun // bias[n] = (-1<<n) + 1
1962*4882a593Smuzhiyun static const int stbi__jbias[16] = {0,-1,-3,-7,-15,-31,-63,-127,-255,-511,-1023,-2047,-4095,-8191,-16383,-32767};
1963*4882a593Smuzhiyun 
1964*4882a593Smuzhiyun // combined JPEG 'receive' and JPEG 'extend', since baseline
1965*4882a593Smuzhiyun // always extends everything it receives.
stbi__extend_receive(stbi__jpeg * j,int n)1966*4882a593Smuzhiyun stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
1967*4882a593Smuzhiyun {
1968*4882a593Smuzhiyun    unsigned int k;
1969*4882a593Smuzhiyun    int sgn;
1970*4882a593Smuzhiyun    if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
1971*4882a593Smuzhiyun 
1972*4882a593Smuzhiyun    sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
1973*4882a593Smuzhiyun    k = stbi_lrot(j->code_buffer, n);
1974*4882a593Smuzhiyun    STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
1975*4882a593Smuzhiyun    j->code_buffer = k & ~stbi__bmask[n];
1976*4882a593Smuzhiyun    k &= stbi__bmask[n];
1977*4882a593Smuzhiyun    j->code_bits -= n;
1978*4882a593Smuzhiyun    return k + (stbi__jbias[n] & ~sgn);
1979*4882a593Smuzhiyun }
1980*4882a593Smuzhiyun 
1981*4882a593Smuzhiyun // get some unsigned bits
stbi__jpeg_get_bits(stbi__jpeg * j,int n)1982*4882a593Smuzhiyun stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n)
1983*4882a593Smuzhiyun {
1984*4882a593Smuzhiyun    unsigned int k;
1985*4882a593Smuzhiyun    if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
1986*4882a593Smuzhiyun    k = stbi_lrot(j->code_buffer, n);
1987*4882a593Smuzhiyun    j->code_buffer = k & ~stbi__bmask[n];
1988*4882a593Smuzhiyun    k &= stbi__bmask[n];
1989*4882a593Smuzhiyun    j->code_bits -= n;
1990*4882a593Smuzhiyun    return k;
1991*4882a593Smuzhiyun }
1992*4882a593Smuzhiyun 
stbi__jpeg_get_bit(stbi__jpeg * j)1993*4882a593Smuzhiyun stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
1994*4882a593Smuzhiyun {
1995*4882a593Smuzhiyun    unsigned int k;
1996*4882a593Smuzhiyun    if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
1997*4882a593Smuzhiyun    k = j->code_buffer;
1998*4882a593Smuzhiyun    j->code_buffer <<= 1;
1999*4882a593Smuzhiyun    --j->code_bits;
2000*4882a593Smuzhiyun    return k & 0x80000000;
2001*4882a593Smuzhiyun }
2002*4882a593Smuzhiyun 
2003*4882a593Smuzhiyun // given a value that's at position X in the zigzag stream,
2004*4882a593Smuzhiyun // where does it appear in the 8x8 matrix coded as row-major?
2005*4882a593Smuzhiyun static const stbi_uc stbi__jpeg_dezigzag[64+15] =
2006*4882a593Smuzhiyun {
2007*4882a593Smuzhiyun     0,  1,  8, 16,  9,  2,  3, 10,
2008*4882a593Smuzhiyun    17, 24, 32, 25, 18, 11,  4,  5,
2009*4882a593Smuzhiyun    12, 19, 26, 33, 40, 48, 41, 34,
2010*4882a593Smuzhiyun    27, 20, 13,  6,  7, 14, 21, 28,
2011*4882a593Smuzhiyun    35, 42, 49, 56, 57, 50, 43, 36,
2012*4882a593Smuzhiyun    29, 22, 15, 23, 30, 37, 44, 51,
2013*4882a593Smuzhiyun    58, 59, 52, 45, 38, 31, 39, 46,
2014*4882a593Smuzhiyun    53, 60, 61, 54, 47, 55, 62, 63,
2015*4882a593Smuzhiyun    // let corrupt input sample past end
2016*4882a593Smuzhiyun    63, 63, 63, 63, 63, 63, 63, 63,
2017*4882a593Smuzhiyun    63, 63, 63, 63, 63, 63, 63
2018*4882a593Smuzhiyun };
2019*4882a593Smuzhiyun 
2020*4882a593Smuzhiyun // decode one 64-entry block--
stbi__jpeg_decode_block(stbi__jpeg * j,short data[64],stbi__huffman * hdc,stbi__huffman * hac,stbi__int16 * fac,int b,stbi__uint16 * dequant)2021*4882a593Smuzhiyun static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant)
2022*4882a593Smuzhiyun {
2023*4882a593Smuzhiyun    int diff,dc,k;
2024*4882a593Smuzhiyun    int t;
2025*4882a593Smuzhiyun 
2026*4882a593Smuzhiyun    if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
2027*4882a593Smuzhiyun    t = stbi__jpeg_huff_decode(j, hdc);
2028*4882a593Smuzhiyun    if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG");
2029*4882a593Smuzhiyun 
2030*4882a593Smuzhiyun    // 0 all the ac values now so we can do it 32-bits at a time
2031*4882a593Smuzhiyun    memset(data,0,64*sizeof(data[0]));
2032*4882a593Smuzhiyun 
2033*4882a593Smuzhiyun    diff = t ? stbi__extend_receive(j, t) : 0;
2034*4882a593Smuzhiyun    dc = j->img_comp[b].dc_pred + diff;
2035*4882a593Smuzhiyun    j->img_comp[b].dc_pred = dc;
2036*4882a593Smuzhiyun    data[0] = (short) (dc * dequant[0]);
2037*4882a593Smuzhiyun 
2038*4882a593Smuzhiyun    // decode AC components, see JPEG spec
2039*4882a593Smuzhiyun    k = 1;
2040*4882a593Smuzhiyun    do {
2041*4882a593Smuzhiyun       unsigned int zig;
2042*4882a593Smuzhiyun       int c,r,s;
2043*4882a593Smuzhiyun       if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
2044*4882a593Smuzhiyun       c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
2045*4882a593Smuzhiyun       r = fac[c];
2046*4882a593Smuzhiyun       if (r) { // fast-AC path
2047*4882a593Smuzhiyun          k += (r >> 4) & 15; // run
2048*4882a593Smuzhiyun          s = r & 15; // combined length
2049*4882a593Smuzhiyun          j->code_buffer <<= s;
2050*4882a593Smuzhiyun          j->code_bits -= s;
2051*4882a593Smuzhiyun          // decode into unzigzag'd location
2052*4882a593Smuzhiyun          zig = stbi__jpeg_dezigzag[k++];
2053*4882a593Smuzhiyun          data[zig] = (short) ((r >> 8) * dequant[zig]);
2054*4882a593Smuzhiyun       } else {
2055*4882a593Smuzhiyun          int rs = stbi__jpeg_huff_decode(j, hac);
2056*4882a593Smuzhiyun          if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
2057*4882a593Smuzhiyun          s = rs & 15;
2058*4882a593Smuzhiyun          r = rs >> 4;
2059*4882a593Smuzhiyun          if (s == 0) {
2060*4882a593Smuzhiyun             if (rs != 0xf0) break; // end block
2061*4882a593Smuzhiyun             k += 16;
2062*4882a593Smuzhiyun          } else {
2063*4882a593Smuzhiyun             k += r;
2064*4882a593Smuzhiyun             // decode into unzigzag'd location
2065*4882a593Smuzhiyun             zig = stbi__jpeg_dezigzag[k++];
2066*4882a593Smuzhiyun             data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]);
2067*4882a593Smuzhiyun          }
2068*4882a593Smuzhiyun       }
2069*4882a593Smuzhiyun    } while (k < 64);
2070*4882a593Smuzhiyun    return 1;
2071*4882a593Smuzhiyun }
2072*4882a593Smuzhiyun 
stbi__jpeg_decode_block_prog_dc(stbi__jpeg * j,short data[64],stbi__huffman * hdc,int b)2073*4882a593Smuzhiyun static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b)
2074*4882a593Smuzhiyun {
2075*4882a593Smuzhiyun    int diff,dc;
2076*4882a593Smuzhiyun    int t;
2077*4882a593Smuzhiyun    if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
2078*4882a593Smuzhiyun 
2079*4882a593Smuzhiyun    if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
2080*4882a593Smuzhiyun 
2081*4882a593Smuzhiyun    if (j->succ_high == 0) {
2082*4882a593Smuzhiyun       // first scan for DC coefficient, must be first
2083*4882a593Smuzhiyun       memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
2084*4882a593Smuzhiyun       t = stbi__jpeg_huff_decode(j, hdc);
2085*4882a593Smuzhiyun       diff = t ? stbi__extend_receive(j, t) : 0;
2086*4882a593Smuzhiyun 
2087*4882a593Smuzhiyun       dc = j->img_comp[b].dc_pred + diff;
2088*4882a593Smuzhiyun       j->img_comp[b].dc_pred = dc;
2089*4882a593Smuzhiyun       data[0] = (short) (dc << j->succ_low);
2090*4882a593Smuzhiyun    } else {
2091*4882a593Smuzhiyun       // refinement scan for DC coefficient
2092*4882a593Smuzhiyun       if (stbi__jpeg_get_bit(j))
2093*4882a593Smuzhiyun          data[0] += (short) (1 << j->succ_low);
2094*4882a593Smuzhiyun    }
2095*4882a593Smuzhiyun    return 1;
2096*4882a593Smuzhiyun }
2097*4882a593Smuzhiyun 
2098*4882a593Smuzhiyun // @OPTIMIZE: store non-zigzagged during the decode passes,
2099*4882a593Smuzhiyun // and only de-zigzag when dequantizing
stbi__jpeg_decode_block_prog_ac(stbi__jpeg * j,short data[64],stbi__huffman * hac,stbi__int16 * fac)2100*4882a593Smuzhiyun static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac)
2101*4882a593Smuzhiyun {
2102*4882a593Smuzhiyun    int k;
2103*4882a593Smuzhiyun    if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
2104*4882a593Smuzhiyun 
2105*4882a593Smuzhiyun    if (j->succ_high == 0) {
2106*4882a593Smuzhiyun       int shift = j->succ_low;
2107*4882a593Smuzhiyun 
2108*4882a593Smuzhiyun       if (j->eob_run) {
2109*4882a593Smuzhiyun          --j->eob_run;
2110*4882a593Smuzhiyun          return 1;
2111*4882a593Smuzhiyun       }
2112*4882a593Smuzhiyun 
2113*4882a593Smuzhiyun       k = j->spec_start;
2114*4882a593Smuzhiyun       do {
2115*4882a593Smuzhiyun          unsigned int zig;
2116*4882a593Smuzhiyun          int c,r,s;
2117*4882a593Smuzhiyun          if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
2118*4882a593Smuzhiyun          c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
2119*4882a593Smuzhiyun          r = fac[c];
2120*4882a593Smuzhiyun          if (r) { // fast-AC path
2121*4882a593Smuzhiyun             k += (r >> 4) & 15; // run
2122*4882a593Smuzhiyun             s = r & 15; // combined length
2123*4882a593Smuzhiyun             j->code_buffer <<= s;
2124*4882a593Smuzhiyun             j->code_bits -= s;
2125*4882a593Smuzhiyun             zig = stbi__jpeg_dezigzag[k++];
2126*4882a593Smuzhiyun             data[zig] = (short) ((r >> 8) << shift);
2127*4882a593Smuzhiyun          } else {
2128*4882a593Smuzhiyun             int rs = stbi__jpeg_huff_decode(j, hac);
2129*4882a593Smuzhiyun             if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
2130*4882a593Smuzhiyun             s = rs & 15;
2131*4882a593Smuzhiyun             r = rs >> 4;
2132*4882a593Smuzhiyun             if (s == 0) {
2133*4882a593Smuzhiyun                if (r < 15) {
2134*4882a593Smuzhiyun                   j->eob_run = (1 << r);
2135*4882a593Smuzhiyun                   if (r)
2136*4882a593Smuzhiyun                      j->eob_run += stbi__jpeg_get_bits(j, r);
2137*4882a593Smuzhiyun                   --j->eob_run;
2138*4882a593Smuzhiyun                   break;
2139*4882a593Smuzhiyun                }
2140*4882a593Smuzhiyun                k += 16;
2141*4882a593Smuzhiyun             } else {
2142*4882a593Smuzhiyun                k += r;
2143*4882a593Smuzhiyun                zig = stbi__jpeg_dezigzag[k++];
2144*4882a593Smuzhiyun                data[zig] = (short) (stbi__extend_receive(j,s) << shift);
2145*4882a593Smuzhiyun             }
2146*4882a593Smuzhiyun          }
2147*4882a593Smuzhiyun       } while (k <= j->spec_end);
2148*4882a593Smuzhiyun    } else {
2149*4882a593Smuzhiyun       // refinement scan for these AC coefficients
2150*4882a593Smuzhiyun 
2151*4882a593Smuzhiyun       short bit = (short) (1 << j->succ_low);
2152*4882a593Smuzhiyun 
2153*4882a593Smuzhiyun       if (j->eob_run) {
2154*4882a593Smuzhiyun          --j->eob_run;
2155*4882a593Smuzhiyun          for (k = j->spec_start; k <= j->spec_end; ++k) {
2156*4882a593Smuzhiyun             short *p = &data[stbi__jpeg_dezigzag[k]];
2157*4882a593Smuzhiyun             if (*p != 0)
2158*4882a593Smuzhiyun                if (stbi__jpeg_get_bit(j))
2159*4882a593Smuzhiyun                   if ((*p & bit)==0) {
2160*4882a593Smuzhiyun                      if (*p > 0)
2161*4882a593Smuzhiyun                         *p += bit;
2162*4882a593Smuzhiyun                      else
2163*4882a593Smuzhiyun                         *p -= bit;
2164*4882a593Smuzhiyun                   }
2165*4882a593Smuzhiyun          }
2166*4882a593Smuzhiyun       } else {
2167*4882a593Smuzhiyun          k = j->spec_start;
2168*4882a593Smuzhiyun          do {
2169*4882a593Smuzhiyun             int r,s;
2170*4882a593Smuzhiyun             int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh
2171*4882a593Smuzhiyun             if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
2172*4882a593Smuzhiyun             s = rs & 15;
2173*4882a593Smuzhiyun             r = rs >> 4;
2174*4882a593Smuzhiyun             if (s == 0) {
2175*4882a593Smuzhiyun                if (r < 15) {
2176*4882a593Smuzhiyun                   j->eob_run = (1 << r) - 1;
2177*4882a593Smuzhiyun                   if (r)
2178*4882a593Smuzhiyun                      j->eob_run += stbi__jpeg_get_bits(j, r);
2179*4882a593Smuzhiyun                   r = 64; // force end of block
2180*4882a593Smuzhiyun                } else {
2181*4882a593Smuzhiyun                   // r=15 s=0 should write 16 0s, so we just do
2182*4882a593Smuzhiyun                   // a run of 15 0s and then write s (which is 0),
2183*4882a593Smuzhiyun                   // so we don't have to do anything special here
2184*4882a593Smuzhiyun                }
2185*4882a593Smuzhiyun             } else {
2186*4882a593Smuzhiyun                if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG");
2187*4882a593Smuzhiyun                // sign bit
2188*4882a593Smuzhiyun                if (stbi__jpeg_get_bit(j))
2189*4882a593Smuzhiyun                   s = bit;
2190*4882a593Smuzhiyun                else
2191*4882a593Smuzhiyun                   s = -bit;
2192*4882a593Smuzhiyun             }
2193*4882a593Smuzhiyun 
2194*4882a593Smuzhiyun             // advance by r
2195*4882a593Smuzhiyun             while (k <= j->spec_end) {
2196*4882a593Smuzhiyun                short *p = &data[stbi__jpeg_dezigzag[k++]];
2197*4882a593Smuzhiyun                if (*p != 0) {
2198*4882a593Smuzhiyun                   if (stbi__jpeg_get_bit(j))
2199*4882a593Smuzhiyun                      if ((*p & bit)==0) {
2200*4882a593Smuzhiyun                         if (*p > 0)
2201*4882a593Smuzhiyun                            *p += bit;
2202*4882a593Smuzhiyun                         else
2203*4882a593Smuzhiyun                            *p -= bit;
2204*4882a593Smuzhiyun                      }
2205*4882a593Smuzhiyun                } else {
2206*4882a593Smuzhiyun                   if (r == 0) {
2207*4882a593Smuzhiyun                      *p = (short) s;
2208*4882a593Smuzhiyun                      break;
2209*4882a593Smuzhiyun                   }
2210*4882a593Smuzhiyun                   --r;
2211*4882a593Smuzhiyun                }
2212*4882a593Smuzhiyun             }
2213*4882a593Smuzhiyun          } while (k <= j->spec_end);
2214*4882a593Smuzhiyun       }
2215*4882a593Smuzhiyun    }
2216*4882a593Smuzhiyun    return 1;
2217*4882a593Smuzhiyun }
2218*4882a593Smuzhiyun 
2219*4882a593Smuzhiyun // take a -128..127 value and stbi__clamp it and convert to 0..255
stbi__clamp(int x)2220*4882a593Smuzhiyun stbi_inline static stbi_uc stbi__clamp(int x)
2221*4882a593Smuzhiyun {
2222*4882a593Smuzhiyun    // trick to use a single test to catch both cases
2223*4882a593Smuzhiyun    if ((unsigned int) x > 255) {
2224*4882a593Smuzhiyun       if (x < 0) return 0;
2225*4882a593Smuzhiyun       if (x > 255) return 255;
2226*4882a593Smuzhiyun    }
2227*4882a593Smuzhiyun    return (stbi_uc) x;
2228*4882a593Smuzhiyun }
2229*4882a593Smuzhiyun 
2230*4882a593Smuzhiyun #define stbi__f2f(x)  ((int) (((x) * 4096 + 0.5)))
2231*4882a593Smuzhiyun #define stbi__fsh(x)  ((x) * 4096)
2232*4882a593Smuzhiyun 
2233*4882a593Smuzhiyun // derived from jidctint -- DCT_ISLOW
2234*4882a593Smuzhiyun #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \
2235*4882a593Smuzhiyun    int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \
2236*4882a593Smuzhiyun    p2 = s2;                                    \
2237*4882a593Smuzhiyun    p3 = s6;                                    \
2238*4882a593Smuzhiyun    p1 = (p2+p3) * stbi__f2f(0.5411961f);       \
2239*4882a593Smuzhiyun    t2 = p1 + p3*stbi__f2f(-1.847759065f);      \
2240*4882a593Smuzhiyun    t3 = p1 + p2*stbi__f2f( 0.765366865f);      \
2241*4882a593Smuzhiyun    p2 = s0;                                    \
2242*4882a593Smuzhiyun    p3 = s4;                                    \
2243*4882a593Smuzhiyun    t0 = stbi__fsh(p2+p3);                      \
2244*4882a593Smuzhiyun    t1 = stbi__fsh(p2-p3);                      \
2245*4882a593Smuzhiyun    x0 = t0+t3;                                 \
2246*4882a593Smuzhiyun    x3 = t0-t3;                                 \
2247*4882a593Smuzhiyun    x1 = t1+t2;                                 \
2248*4882a593Smuzhiyun    x2 = t1-t2;                                 \
2249*4882a593Smuzhiyun    t0 = s7;                                    \
2250*4882a593Smuzhiyun    t1 = s5;                                    \
2251*4882a593Smuzhiyun    t2 = s3;                                    \
2252*4882a593Smuzhiyun    t3 = s1;                                    \
2253*4882a593Smuzhiyun    p3 = t0+t2;                                 \
2254*4882a593Smuzhiyun    p4 = t1+t3;                                 \
2255*4882a593Smuzhiyun    p1 = t0+t3;                                 \
2256*4882a593Smuzhiyun    p2 = t1+t2;                                 \
2257*4882a593Smuzhiyun    p5 = (p3+p4)*stbi__f2f( 1.175875602f);      \
2258*4882a593Smuzhiyun    t0 = t0*stbi__f2f( 0.298631336f);           \
2259*4882a593Smuzhiyun    t1 = t1*stbi__f2f( 2.053119869f);           \
2260*4882a593Smuzhiyun    t2 = t2*stbi__f2f( 3.072711026f);           \
2261*4882a593Smuzhiyun    t3 = t3*stbi__f2f( 1.501321110f);           \
2262*4882a593Smuzhiyun    p1 = p5 + p1*stbi__f2f(-0.899976223f);      \
2263*4882a593Smuzhiyun    p2 = p5 + p2*stbi__f2f(-2.562915447f);      \
2264*4882a593Smuzhiyun    p3 = p3*stbi__f2f(-1.961570560f);           \
2265*4882a593Smuzhiyun    p4 = p4*stbi__f2f(-0.390180644f);           \
2266*4882a593Smuzhiyun    t3 += p1+p4;                                \
2267*4882a593Smuzhiyun    t2 += p2+p3;                                \
2268*4882a593Smuzhiyun    t1 += p2+p4;                                \
2269*4882a593Smuzhiyun    t0 += p1+p3;
2270*4882a593Smuzhiyun 
stbi__idct_block(stbi_uc * out,int out_stride,short data[64])2271*4882a593Smuzhiyun static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64])
2272*4882a593Smuzhiyun {
2273*4882a593Smuzhiyun    int i,val[64],*v=val;
2274*4882a593Smuzhiyun    stbi_uc *o;
2275*4882a593Smuzhiyun    short *d = data;
2276*4882a593Smuzhiyun 
2277*4882a593Smuzhiyun    // columns
2278*4882a593Smuzhiyun    for (i=0; i < 8; ++i,++d, ++v) {
2279*4882a593Smuzhiyun       // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing
2280*4882a593Smuzhiyun       if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0
2281*4882a593Smuzhiyun            && d[40]==0 && d[48]==0 && d[56]==0) {
2282*4882a593Smuzhiyun          //    no shortcut                 0     seconds
2283*4882a593Smuzhiyun          //    (1|2|3|4|5|6|7)==0          0     seconds
2284*4882a593Smuzhiyun          //    all separate               -0.047 seconds
2285*4882a593Smuzhiyun          //    1 && 2|3 && 4|5 && 6|7:    -0.047 seconds
2286*4882a593Smuzhiyun          int dcterm = d[0]*4;
2287*4882a593Smuzhiyun          v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm;
2288*4882a593Smuzhiyun       } else {
2289*4882a593Smuzhiyun          STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56])
2290*4882a593Smuzhiyun          // constants scaled things up by 1<<12; let's bring them back
2291*4882a593Smuzhiyun          // down, but keep 2 extra bits of precision
2292*4882a593Smuzhiyun          x0 += 512; x1 += 512; x2 += 512; x3 += 512;
2293*4882a593Smuzhiyun          v[ 0] = (x0+t3) >> 10;
2294*4882a593Smuzhiyun          v[56] = (x0-t3) >> 10;
2295*4882a593Smuzhiyun          v[ 8] = (x1+t2) >> 10;
2296*4882a593Smuzhiyun          v[48] = (x1-t2) >> 10;
2297*4882a593Smuzhiyun          v[16] = (x2+t1) >> 10;
2298*4882a593Smuzhiyun          v[40] = (x2-t1) >> 10;
2299*4882a593Smuzhiyun          v[24] = (x3+t0) >> 10;
2300*4882a593Smuzhiyun          v[32] = (x3-t0) >> 10;
2301*4882a593Smuzhiyun       }
2302*4882a593Smuzhiyun    }
2303*4882a593Smuzhiyun 
2304*4882a593Smuzhiyun    for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) {
2305*4882a593Smuzhiyun       // no fast case since the first 1D IDCT spread components out
2306*4882a593Smuzhiyun       STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])
2307*4882a593Smuzhiyun       // constants scaled things up by 1<<12, plus we had 1<<2 from first
2308*4882a593Smuzhiyun       // loop, plus horizontal and vertical each scale by sqrt(8) so together
2309*4882a593Smuzhiyun       // we've got an extra 1<<3, so 1<<17 total we need to remove.
2310*4882a593Smuzhiyun       // so we want to round that, which means adding 0.5 * 1<<17,
2311*4882a593Smuzhiyun       // aka 65536. Also, we'll end up with -128 to 127 that we want
2312*4882a593Smuzhiyun       // to encode as 0..255 by adding 128, so we'll add that before the shift
2313*4882a593Smuzhiyun       x0 += 65536 + (128<<17);
2314*4882a593Smuzhiyun       x1 += 65536 + (128<<17);
2315*4882a593Smuzhiyun       x2 += 65536 + (128<<17);
2316*4882a593Smuzhiyun       x3 += 65536 + (128<<17);
2317*4882a593Smuzhiyun       // tried computing the shifts into temps, or'ing the temps to see
2318*4882a593Smuzhiyun       // if any were out of range, but that was slower
2319*4882a593Smuzhiyun       o[0] = stbi__clamp((x0+t3) >> 17);
2320*4882a593Smuzhiyun       o[7] = stbi__clamp((x0-t3) >> 17);
2321*4882a593Smuzhiyun       o[1] = stbi__clamp((x1+t2) >> 17);
2322*4882a593Smuzhiyun       o[6] = stbi__clamp((x1-t2) >> 17);
2323*4882a593Smuzhiyun       o[2] = stbi__clamp((x2+t1) >> 17);
2324*4882a593Smuzhiyun       o[5] = stbi__clamp((x2-t1) >> 17);
2325*4882a593Smuzhiyun       o[3] = stbi__clamp((x3+t0) >> 17);
2326*4882a593Smuzhiyun       o[4] = stbi__clamp((x3-t0) >> 17);
2327*4882a593Smuzhiyun    }
2328*4882a593Smuzhiyun }
2329*4882a593Smuzhiyun 
2330*4882a593Smuzhiyun #ifdef STBI_SSE2
2331*4882a593Smuzhiyun // sse2 integer IDCT. not the fastest possible implementation but it
2332*4882a593Smuzhiyun // produces bit-identical results to the generic C version so it's
2333*4882a593Smuzhiyun // fully "transparent".
stbi__idct_simd(stbi_uc * out,int out_stride,short data[64])2334*4882a593Smuzhiyun static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
2335*4882a593Smuzhiyun {
2336*4882a593Smuzhiyun    // This is constructed to match our regular (generic) integer IDCT exactly.
2337*4882a593Smuzhiyun    __m128i row0, row1, row2, row3, row4, row5, row6, row7;
2338*4882a593Smuzhiyun    __m128i tmp;
2339*4882a593Smuzhiyun 
2340*4882a593Smuzhiyun    // dot product constant: even elems=x, odd elems=y
2341*4882a593Smuzhiyun    #define dct_const(x,y)  _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y))
2342*4882a593Smuzhiyun 
2343*4882a593Smuzhiyun    // out(0) = c0[even]*x + c0[odd]*y   (c0, x, y 16-bit, out 32-bit)
2344*4882a593Smuzhiyun    // out(1) = c1[even]*x + c1[odd]*y
2345*4882a593Smuzhiyun    #define dct_rot(out0,out1, x,y,c0,c1) \
2346*4882a593Smuzhiyun       __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \
2347*4882a593Smuzhiyun       __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \
2348*4882a593Smuzhiyun       __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \
2349*4882a593Smuzhiyun       __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \
2350*4882a593Smuzhiyun       __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \
2351*4882a593Smuzhiyun       __m128i out1##_h = _mm_madd_epi16(c0##hi, c1)
2352*4882a593Smuzhiyun 
2353*4882a593Smuzhiyun    // out = in << 12  (in 16-bit, out 32-bit)
2354*4882a593Smuzhiyun    #define dct_widen(out, in) \
2355*4882a593Smuzhiyun       __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \
2356*4882a593Smuzhiyun       __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4)
2357*4882a593Smuzhiyun 
2358*4882a593Smuzhiyun    // wide add
2359*4882a593Smuzhiyun    #define dct_wadd(out, a, b) \
2360*4882a593Smuzhiyun       __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \
2361*4882a593Smuzhiyun       __m128i out##_h = _mm_add_epi32(a##_h, b##_h)
2362*4882a593Smuzhiyun 
2363*4882a593Smuzhiyun    // wide sub
2364*4882a593Smuzhiyun    #define dct_wsub(out, a, b) \
2365*4882a593Smuzhiyun       __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \
2366*4882a593Smuzhiyun       __m128i out##_h = _mm_sub_epi32(a##_h, b##_h)
2367*4882a593Smuzhiyun 
2368*4882a593Smuzhiyun    // butterfly a/b, add bias, then shift by "s" and pack
2369*4882a593Smuzhiyun    #define dct_bfly32o(out0, out1, a,b,bias,s) \
2370*4882a593Smuzhiyun       { \
2371*4882a593Smuzhiyun          __m128i abiased_l = _mm_add_epi32(a##_l, bias); \
2372*4882a593Smuzhiyun          __m128i abiased_h = _mm_add_epi32(a##_h, bias); \
2373*4882a593Smuzhiyun          dct_wadd(sum, abiased, b); \
2374*4882a593Smuzhiyun          dct_wsub(dif, abiased, b); \
2375*4882a593Smuzhiyun          out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \
2376*4882a593Smuzhiyun          out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \
2377*4882a593Smuzhiyun       }
2378*4882a593Smuzhiyun 
2379*4882a593Smuzhiyun    // 8-bit interleave step (for transposes)
2380*4882a593Smuzhiyun    #define dct_interleave8(a, b) \
2381*4882a593Smuzhiyun       tmp = a; \
2382*4882a593Smuzhiyun       a = _mm_unpacklo_epi8(a, b); \
2383*4882a593Smuzhiyun       b = _mm_unpackhi_epi8(tmp, b)
2384*4882a593Smuzhiyun 
2385*4882a593Smuzhiyun    // 16-bit interleave step (for transposes)
2386*4882a593Smuzhiyun    #define dct_interleave16(a, b) \
2387*4882a593Smuzhiyun       tmp = a; \
2388*4882a593Smuzhiyun       a = _mm_unpacklo_epi16(a, b); \
2389*4882a593Smuzhiyun       b = _mm_unpackhi_epi16(tmp, b)
2390*4882a593Smuzhiyun 
2391*4882a593Smuzhiyun    #define dct_pass(bias,shift) \
2392*4882a593Smuzhiyun       { \
2393*4882a593Smuzhiyun          /* even part */ \
2394*4882a593Smuzhiyun          dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \
2395*4882a593Smuzhiyun          __m128i sum04 = _mm_add_epi16(row0, row4); \
2396*4882a593Smuzhiyun          __m128i dif04 = _mm_sub_epi16(row0, row4); \
2397*4882a593Smuzhiyun          dct_widen(t0e, sum04); \
2398*4882a593Smuzhiyun          dct_widen(t1e, dif04); \
2399*4882a593Smuzhiyun          dct_wadd(x0, t0e, t3e); \
2400*4882a593Smuzhiyun          dct_wsub(x3, t0e, t3e); \
2401*4882a593Smuzhiyun          dct_wadd(x1, t1e, t2e); \
2402*4882a593Smuzhiyun          dct_wsub(x2, t1e, t2e); \
2403*4882a593Smuzhiyun          /* odd part */ \
2404*4882a593Smuzhiyun          dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \
2405*4882a593Smuzhiyun          dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \
2406*4882a593Smuzhiyun          __m128i sum17 = _mm_add_epi16(row1, row7); \
2407*4882a593Smuzhiyun          __m128i sum35 = _mm_add_epi16(row3, row5); \
2408*4882a593Smuzhiyun          dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \
2409*4882a593Smuzhiyun          dct_wadd(x4, y0o, y4o); \
2410*4882a593Smuzhiyun          dct_wadd(x5, y1o, y5o); \
2411*4882a593Smuzhiyun          dct_wadd(x6, y2o, y5o); \
2412*4882a593Smuzhiyun          dct_wadd(x7, y3o, y4o); \
2413*4882a593Smuzhiyun          dct_bfly32o(row0,row7, x0,x7,bias,shift); \
2414*4882a593Smuzhiyun          dct_bfly32o(row1,row6, x1,x6,bias,shift); \
2415*4882a593Smuzhiyun          dct_bfly32o(row2,row5, x2,x5,bias,shift); \
2416*4882a593Smuzhiyun          dct_bfly32o(row3,row4, x3,x4,bias,shift); \
2417*4882a593Smuzhiyun       }
2418*4882a593Smuzhiyun 
2419*4882a593Smuzhiyun    __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f));
2420*4882a593Smuzhiyun    __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f));
2421*4882a593Smuzhiyun    __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f));
2422*4882a593Smuzhiyun    __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f));
2423*4882a593Smuzhiyun    __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f));
2424*4882a593Smuzhiyun    __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f));
2425*4882a593Smuzhiyun    __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f));
2426*4882a593Smuzhiyun    __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f));
2427*4882a593Smuzhiyun 
2428*4882a593Smuzhiyun    // rounding biases in column/row passes, see stbi__idct_block for explanation.
2429*4882a593Smuzhiyun    __m128i bias_0 = _mm_set1_epi32(512);
2430*4882a593Smuzhiyun    __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17));
2431*4882a593Smuzhiyun 
2432*4882a593Smuzhiyun    // load
2433*4882a593Smuzhiyun    row0 = _mm_load_si128((const __m128i *) (data + 0*8));
2434*4882a593Smuzhiyun    row1 = _mm_load_si128((const __m128i *) (data + 1*8));
2435*4882a593Smuzhiyun    row2 = _mm_load_si128((const __m128i *) (data + 2*8));
2436*4882a593Smuzhiyun    row3 = _mm_load_si128((const __m128i *) (data + 3*8));
2437*4882a593Smuzhiyun    row4 = _mm_load_si128((const __m128i *) (data + 4*8));
2438*4882a593Smuzhiyun    row5 = _mm_load_si128((const __m128i *) (data + 5*8));
2439*4882a593Smuzhiyun    row6 = _mm_load_si128((const __m128i *) (data + 6*8));
2440*4882a593Smuzhiyun    row7 = _mm_load_si128((const __m128i *) (data + 7*8));
2441*4882a593Smuzhiyun 
2442*4882a593Smuzhiyun    // column pass
2443*4882a593Smuzhiyun    dct_pass(bias_0, 10);
2444*4882a593Smuzhiyun 
2445*4882a593Smuzhiyun    {
2446*4882a593Smuzhiyun       // 16bit 8x8 transpose pass 1
2447*4882a593Smuzhiyun       dct_interleave16(row0, row4);
2448*4882a593Smuzhiyun       dct_interleave16(row1, row5);
2449*4882a593Smuzhiyun       dct_interleave16(row2, row6);
2450*4882a593Smuzhiyun       dct_interleave16(row3, row7);
2451*4882a593Smuzhiyun 
2452*4882a593Smuzhiyun       // transpose pass 2
2453*4882a593Smuzhiyun       dct_interleave16(row0, row2);
2454*4882a593Smuzhiyun       dct_interleave16(row1, row3);
2455*4882a593Smuzhiyun       dct_interleave16(row4, row6);
2456*4882a593Smuzhiyun       dct_interleave16(row5, row7);
2457*4882a593Smuzhiyun 
2458*4882a593Smuzhiyun       // transpose pass 3
2459*4882a593Smuzhiyun       dct_interleave16(row0, row1);
2460*4882a593Smuzhiyun       dct_interleave16(row2, row3);
2461*4882a593Smuzhiyun       dct_interleave16(row4, row5);
2462*4882a593Smuzhiyun       dct_interleave16(row6, row7);
2463*4882a593Smuzhiyun    }
2464*4882a593Smuzhiyun 
2465*4882a593Smuzhiyun    // row pass
2466*4882a593Smuzhiyun    dct_pass(bias_1, 17);
2467*4882a593Smuzhiyun 
2468*4882a593Smuzhiyun    {
2469*4882a593Smuzhiyun       // pack
2470*4882a593Smuzhiyun       __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7
2471*4882a593Smuzhiyun       __m128i p1 = _mm_packus_epi16(row2, row3);
2472*4882a593Smuzhiyun       __m128i p2 = _mm_packus_epi16(row4, row5);
2473*4882a593Smuzhiyun       __m128i p3 = _mm_packus_epi16(row6, row7);
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun       // 8bit 8x8 transpose pass 1
2476*4882a593Smuzhiyun       dct_interleave8(p0, p2); // a0e0a1e1...
2477*4882a593Smuzhiyun       dct_interleave8(p1, p3); // c0g0c1g1...
2478*4882a593Smuzhiyun 
2479*4882a593Smuzhiyun       // transpose pass 2
2480*4882a593Smuzhiyun       dct_interleave8(p0, p1); // a0c0e0g0...
2481*4882a593Smuzhiyun       dct_interleave8(p2, p3); // b0d0f0h0...
2482*4882a593Smuzhiyun 
2483*4882a593Smuzhiyun       // transpose pass 3
2484*4882a593Smuzhiyun       dct_interleave8(p0, p2); // a0b0c0d0...
2485*4882a593Smuzhiyun       dct_interleave8(p1, p3); // a4b4c4d4...
2486*4882a593Smuzhiyun 
2487*4882a593Smuzhiyun       // store
2488*4882a593Smuzhiyun       _mm_storel_epi64((__m128i *) out, p0); out += out_stride;
2489*4882a593Smuzhiyun       _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride;
2490*4882a593Smuzhiyun       _mm_storel_epi64((__m128i *) out, p2); out += out_stride;
2491*4882a593Smuzhiyun       _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride;
2492*4882a593Smuzhiyun       _mm_storel_epi64((__m128i *) out, p1); out += out_stride;
2493*4882a593Smuzhiyun       _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride;
2494*4882a593Smuzhiyun       _mm_storel_epi64((__m128i *) out, p3); out += out_stride;
2495*4882a593Smuzhiyun       _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e));
2496*4882a593Smuzhiyun    }
2497*4882a593Smuzhiyun 
2498*4882a593Smuzhiyun #undef dct_const
2499*4882a593Smuzhiyun #undef dct_rot
2500*4882a593Smuzhiyun #undef dct_widen
2501*4882a593Smuzhiyun #undef dct_wadd
2502*4882a593Smuzhiyun #undef dct_wsub
2503*4882a593Smuzhiyun #undef dct_bfly32o
2504*4882a593Smuzhiyun #undef dct_interleave8
2505*4882a593Smuzhiyun #undef dct_interleave16
2506*4882a593Smuzhiyun #undef dct_pass
2507*4882a593Smuzhiyun }
2508*4882a593Smuzhiyun 
2509*4882a593Smuzhiyun #endif // STBI_SSE2
2510*4882a593Smuzhiyun 
2511*4882a593Smuzhiyun #ifdef STBI_NEON
2512*4882a593Smuzhiyun 
2513*4882a593Smuzhiyun // NEON integer IDCT. should produce bit-identical
2514*4882a593Smuzhiyun // results to the generic C version.
stbi__idct_simd(stbi_uc * out,int out_stride,short data[64])2515*4882a593Smuzhiyun static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
2516*4882a593Smuzhiyun {
2517*4882a593Smuzhiyun    int16x8_t row0, row1, row2, row3, row4, row5, row6, row7;
2518*4882a593Smuzhiyun 
2519*4882a593Smuzhiyun    int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f));
2520*4882a593Smuzhiyun    int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f));
2521*4882a593Smuzhiyun    int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f));
2522*4882a593Smuzhiyun    int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f));
2523*4882a593Smuzhiyun    int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f));
2524*4882a593Smuzhiyun    int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f));
2525*4882a593Smuzhiyun    int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f));
2526*4882a593Smuzhiyun    int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f));
2527*4882a593Smuzhiyun    int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f));
2528*4882a593Smuzhiyun    int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f));
2529*4882a593Smuzhiyun    int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f));
2530*4882a593Smuzhiyun    int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f));
2531*4882a593Smuzhiyun 
2532*4882a593Smuzhiyun #define dct_long_mul(out, inq, coeff) \
2533*4882a593Smuzhiyun    int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \
2534*4882a593Smuzhiyun    int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff)
2535*4882a593Smuzhiyun 
2536*4882a593Smuzhiyun #define dct_long_mac(out, acc, inq, coeff) \
2537*4882a593Smuzhiyun    int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \
2538*4882a593Smuzhiyun    int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff)
2539*4882a593Smuzhiyun 
2540*4882a593Smuzhiyun #define dct_widen(out, inq) \
2541*4882a593Smuzhiyun    int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \
2542*4882a593Smuzhiyun    int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12)
2543*4882a593Smuzhiyun 
2544*4882a593Smuzhiyun // wide add
2545*4882a593Smuzhiyun #define dct_wadd(out, a, b) \
2546*4882a593Smuzhiyun    int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \
2547*4882a593Smuzhiyun    int32x4_t out##_h = vaddq_s32(a##_h, b##_h)
2548*4882a593Smuzhiyun 
2549*4882a593Smuzhiyun // wide sub
2550*4882a593Smuzhiyun #define dct_wsub(out, a, b) \
2551*4882a593Smuzhiyun    int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \
2552*4882a593Smuzhiyun    int32x4_t out##_h = vsubq_s32(a##_h, b##_h)
2553*4882a593Smuzhiyun 
2554*4882a593Smuzhiyun // butterfly a/b, then shift using "shiftop" by "s" and pack
2555*4882a593Smuzhiyun #define dct_bfly32o(out0,out1, a,b,shiftop,s) \
2556*4882a593Smuzhiyun    { \
2557*4882a593Smuzhiyun       dct_wadd(sum, a, b); \
2558*4882a593Smuzhiyun       dct_wsub(dif, a, b); \
2559*4882a593Smuzhiyun       out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \
2560*4882a593Smuzhiyun       out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \
2561*4882a593Smuzhiyun    }
2562*4882a593Smuzhiyun 
2563*4882a593Smuzhiyun #define dct_pass(shiftop, shift) \
2564*4882a593Smuzhiyun    { \
2565*4882a593Smuzhiyun       /* even part */ \
2566*4882a593Smuzhiyun       int16x8_t sum26 = vaddq_s16(row2, row6); \
2567*4882a593Smuzhiyun       dct_long_mul(p1e, sum26, rot0_0); \
2568*4882a593Smuzhiyun       dct_long_mac(t2e, p1e, row6, rot0_1); \
2569*4882a593Smuzhiyun       dct_long_mac(t3e, p1e, row2, rot0_2); \
2570*4882a593Smuzhiyun       int16x8_t sum04 = vaddq_s16(row0, row4); \
2571*4882a593Smuzhiyun       int16x8_t dif04 = vsubq_s16(row0, row4); \
2572*4882a593Smuzhiyun       dct_widen(t0e, sum04); \
2573*4882a593Smuzhiyun       dct_widen(t1e, dif04); \
2574*4882a593Smuzhiyun       dct_wadd(x0, t0e, t3e); \
2575*4882a593Smuzhiyun       dct_wsub(x3, t0e, t3e); \
2576*4882a593Smuzhiyun       dct_wadd(x1, t1e, t2e); \
2577*4882a593Smuzhiyun       dct_wsub(x2, t1e, t2e); \
2578*4882a593Smuzhiyun       /* odd part */ \
2579*4882a593Smuzhiyun       int16x8_t sum15 = vaddq_s16(row1, row5); \
2580*4882a593Smuzhiyun       int16x8_t sum17 = vaddq_s16(row1, row7); \
2581*4882a593Smuzhiyun       int16x8_t sum35 = vaddq_s16(row3, row5); \
2582*4882a593Smuzhiyun       int16x8_t sum37 = vaddq_s16(row3, row7); \
2583*4882a593Smuzhiyun       int16x8_t sumodd = vaddq_s16(sum17, sum35); \
2584*4882a593Smuzhiyun       dct_long_mul(p5o, sumodd, rot1_0); \
2585*4882a593Smuzhiyun       dct_long_mac(p1o, p5o, sum17, rot1_1); \
2586*4882a593Smuzhiyun       dct_long_mac(p2o, p5o, sum35, rot1_2); \
2587*4882a593Smuzhiyun       dct_long_mul(p3o, sum37, rot2_0); \
2588*4882a593Smuzhiyun       dct_long_mul(p4o, sum15, rot2_1); \
2589*4882a593Smuzhiyun       dct_wadd(sump13o, p1o, p3o); \
2590*4882a593Smuzhiyun       dct_wadd(sump24o, p2o, p4o); \
2591*4882a593Smuzhiyun       dct_wadd(sump23o, p2o, p3o); \
2592*4882a593Smuzhiyun       dct_wadd(sump14o, p1o, p4o); \
2593*4882a593Smuzhiyun       dct_long_mac(x4, sump13o, row7, rot3_0); \
2594*4882a593Smuzhiyun       dct_long_mac(x5, sump24o, row5, rot3_1); \
2595*4882a593Smuzhiyun       dct_long_mac(x6, sump23o, row3, rot3_2); \
2596*4882a593Smuzhiyun       dct_long_mac(x7, sump14o, row1, rot3_3); \
2597*4882a593Smuzhiyun       dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \
2598*4882a593Smuzhiyun       dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \
2599*4882a593Smuzhiyun       dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \
2600*4882a593Smuzhiyun       dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \
2601*4882a593Smuzhiyun    }
2602*4882a593Smuzhiyun 
2603*4882a593Smuzhiyun    // load
2604*4882a593Smuzhiyun    row0 = vld1q_s16(data + 0*8);
2605*4882a593Smuzhiyun    row1 = vld1q_s16(data + 1*8);
2606*4882a593Smuzhiyun    row2 = vld1q_s16(data + 2*8);
2607*4882a593Smuzhiyun    row3 = vld1q_s16(data + 3*8);
2608*4882a593Smuzhiyun    row4 = vld1q_s16(data + 4*8);
2609*4882a593Smuzhiyun    row5 = vld1q_s16(data + 5*8);
2610*4882a593Smuzhiyun    row6 = vld1q_s16(data + 6*8);
2611*4882a593Smuzhiyun    row7 = vld1q_s16(data + 7*8);
2612*4882a593Smuzhiyun 
2613*4882a593Smuzhiyun    // add DC bias
2614*4882a593Smuzhiyun    row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0));
2615*4882a593Smuzhiyun 
2616*4882a593Smuzhiyun    // column pass
2617*4882a593Smuzhiyun    dct_pass(vrshrn_n_s32, 10);
2618*4882a593Smuzhiyun 
2619*4882a593Smuzhiyun    // 16bit 8x8 transpose
2620*4882a593Smuzhiyun    {
2621*4882a593Smuzhiyun // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively.
2622*4882a593Smuzhiyun // whether compilers actually get this is another story, sadly.
2623*4882a593Smuzhiyun #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; }
2624*4882a593Smuzhiyun #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); }
2625*4882a593Smuzhiyun #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); }
2626*4882a593Smuzhiyun 
2627*4882a593Smuzhiyun       // pass 1
2628*4882a593Smuzhiyun       dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6
2629*4882a593Smuzhiyun       dct_trn16(row2, row3);
2630*4882a593Smuzhiyun       dct_trn16(row4, row5);
2631*4882a593Smuzhiyun       dct_trn16(row6, row7);
2632*4882a593Smuzhiyun 
2633*4882a593Smuzhiyun       // pass 2
2634*4882a593Smuzhiyun       dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4
2635*4882a593Smuzhiyun       dct_trn32(row1, row3);
2636*4882a593Smuzhiyun       dct_trn32(row4, row6);
2637*4882a593Smuzhiyun       dct_trn32(row5, row7);
2638*4882a593Smuzhiyun 
2639*4882a593Smuzhiyun       // pass 3
2640*4882a593Smuzhiyun       dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0
2641*4882a593Smuzhiyun       dct_trn64(row1, row5);
2642*4882a593Smuzhiyun       dct_trn64(row2, row6);
2643*4882a593Smuzhiyun       dct_trn64(row3, row7);
2644*4882a593Smuzhiyun 
2645*4882a593Smuzhiyun #undef dct_trn16
2646*4882a593Smuzhiyun #undef dct_trn32
2647*4882a593Smuzhiyun #undef dct_trn64
2648*4882a593Smuzhiyun    }
2649*4882a593Smuzhiyun 
2650*4882a593Smuzhiyun    // row pass
2651*4882a593Smuzhiyun    // vrshrn_n_s32 only supports shifts up to 16, we need
2652*4882a593Smuzhiyun    // 17. so do a non-rounding shift of 16 first then follow
2653*4882a593Smuzhiyun    // up with a rounding shift by 1.
2654*4882a593Smuzhiyun    dct_pass(vshrn_n_s32, 16);
2655*4882a593Smuzhiyun 
2656*4882a593Smuzhiyun    {
2657*4882a593Smuzhiyun       // pack and round
2658*4882a593Smuzhiyun       uint8x8_t p0 = vqrshrun_n_s16(row0, 1);
2659*4882a593Smuzhiyun       uint8x8_t p1 = vqrshrun_n_s16(row1, 1);
2660*4882a593Smuzhiyun       uint8x8_t p2 = vqrshrun_n_s16(row2, 1);
2661*4882a593Smuzhiyun       uint8x8_t p3 = vqrshrun_n_s16(row3, 1);
2662*4882a593Smuzhiyun       uint8x8_t p4 = vqrshrun_n_s16(row4, 1);
2663*4882a593Smuzhiyun       uint8x8_t p5 = vqrshrun_n_s16(row5, 1);
2664*4882a593Smuzhiyun       uint8x8_t p6 = vqrshrun_n_s16(row6, 1);
2665*4882a593Smuzhiyun       uint8x8_t p7 = vqrshrun_n_s16(row7, 1);
2666*4882a593Smuzhiyun 
2667*4882a593Smuzhiyun       // again, these can translate into one instruction, but often don't.
2668*4882a593Smuzhiyun #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; }
2669*4882a593Smuzhiyun #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); }
2670*4882a593Smuzhiyun #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); }
2671*4882a593Smuzhiyun 
2672*4882a593Smuzhiyun       // sadly can't use interleaved stores here since we only write
2673*4882a593Smuzhiyun       // 8 bytes to each scan line!
2674*4882a593Smuzhiyun 
2675*4882a593Smuzhiyun       // 8x8 8-bit transpose pass 1
2676*4882a593Smuzhiyun       dct_trn8_8(p0, p1);
2677*4882a593Smuzhiyun       dct_trn8_8(p2, p3);
2678*4882a593Smuzhiyun       dct_trn8_8(p4, p5);
2679*4882a593Smuzhiyun       dct_trn8_8(p6, p7);
2680*4882a593Smuzhiyun 
2681*4882a593Smuzhiyun       // pass 2
2682*4882a593Smuzhiyun       dct_trn8_16(p0, p2);
2683*4882a593Smuzhiyun       dct_trn8_16(p1, p3);
2684*4882a593Smuzhiyun       dct_trn8_16(p4, p6);
2685*4882a593Smuzhiyun       dct_trn8_16(p5, p7);
2686*4882a593Smuzhiyun 
2687*4882a593Smuzhiyun       // pass 3
2688*4882a593Smuzhiyun       dct_trn8_32(p0, p4);
2689*4882a593Smuzhiyun       dct_trn8_32(p1, p5);
2690*4882a593Smuzhiyun       dct_trn8_32(p2, p6);
2691*4882a593Smuzhiyun       dct_trn8_32(p3, p7);
2692*4882a593Smuzhiyun 
2693*4882a593Smuzhiyun       // store
2694*4882a593Smuzhiyun       vst1_u8(out, p0); out += out_stride;
2695*4882a593Smuzhiyun       vst1_u8(out, p1); out += out_stride;
2696*4882a593Smuzhiyun       vst1_u8(out, p2); out += out_stride;
2697*4882a593Smuzhiyun       vst1_u8(out, p3); out += out_stride;
2698*4882a593Smuzhiyun       vst1_u8(out, p4); out += out_stride;
2699*4882a593Smuzhiyun       vst1_u8(out, p5); out += out_stride;
2700*4882a593Smuzhiyun       vst1_u8(out, p6); out += out_stride;
2701*4882a593Smuzhiyun       vst1_u8(out, p7);
2702*4882a593Smuzhiyun 
2703*4882a593Smuzhiyun #undef dct_trn8_8
2704*4882a593Smuzhiyun #undef dct_trn8_16
2705*4882a593Smuzhiyun #undef dct_trn8_32
2706*4882a593Smuzhiyun    }
2707*4882a593Smuzhiyun 
2708*4882a593Smuzhiyun #undef dct_long_mul
2709*4882a593Smuzhiyun #undef dct_long_mac
2710*4882a593Smuzhiyun #undef dct_widen
2711*4882a593Smuzhiyun #undef dct_wadd
2712*4882a593Smuzhiyun #undef dct_wsub
2713*4882a593Smuzhiyun #undef dct_bfly32o
2714*4882a593Smuzhiyun #undef dct_pass
2715*4882a593Smuzhiyun }
2716*4882a593Smuzhiyun 
2717*4882a593Smuzhiyun #endif // STBI_NEON
2718*4882a593Smuzhiyun 
2719*4882a593Smuzhiyun #define STBI__MARKER_none  0xff
2720*4882a593Smuzhiyun // if there's a pending marker from the entropy stream, return that
2721*4882a593Smuzhiyun // otherwise, fetch from the stream and get a marker. if there's no
2722*4882a593Smuzhiyun // marker, return 0xff, which is never a valid marker value
stbi__get_marker(stbi__jpeg * j)2723*4882a593Smuzhiyun static stbi_uc stbi__get_marker(stbi__jpeg *j)
2724*4882a593Smuzhiyun {
2725*4882a593Smuzhiyun    stbi_uc x;
2726*4882a593Smuzhiyun    if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; }
2727*4882a593Smuzhiyun    x = stbi__get8(j->s);
2728*4882a593Smuzhiyun    if (x != 0xff) return STBI__MARKER_none;
2729*4882a593Smuzhiyun    while (x == 0xff)
2730*4882a593Smuzhiyun       x = stbi__get8(j->s); // consume repeated 0xff fill bytes
2731*4882a593Smuzhiyun    return x;
2732*4882a593Smuzhiyun }
2733*4882a593Smuzhiyun 
2734*4882a593Smuzhiyun // in each scan, we'll have scan_n components, and the order
2735*4882a593Smuzhiyun // of the components is specified by order[]
2736*4882a593Smuzhiyun #define STBI__RESTART(x)     ((x) >= 0xd0 && (x) <= 0xd7)
2737*4882a593Smuzhiyun 
2738*4882a593Smuzhiyun // after a restart interval, stbi__jpeg_reset the entropy decoder and
2739*4882a593Smuzhiyun // the dc prediction
stbi__jpeg_reset(stbi__jpeg * j)2740*4882a593Smuzhiyun static void stbi__jpeg_reset(stbi__jpeg *j)
2741*4882a593Smuzhiyun {
2742*4882a593Smuzhiyun    j->code_bits = 0;
2743*4882a593Smuzhiyun    j->code_buffer = 0;
2744*4882a593Smuzhiyun    j->nomore = 0;
2745*4882a593Smuzhiyun    j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0;
2746*4882a593Smuzhiyun    j->marker = STBI__MARKER_none;
2747*4882a593Smuzhiyun    j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
2748*4882a593Smuzhiyun    j->eob_run = 0;
2749*4882a593Smuzhiyun    // no more than 1<<31 MCUs if no restart_interal? that's plenty safe,
2750*4882a593Smuzhiyun    // since we don't even allow 1<<30 pixels
2751*4882a593Smuzhiyun }
2752*4882a593Smuzhiyun 
stbi__parse_entropy_coded_data(stbi__jpeg * z)2753*4882a593Smuzhiyun static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
2754*4882a593Smuzhiyun {
2755*4882a593Smuzhiyun    stbi__jpeg_reset(z);
2756*4882a593Smuzhiyun    if (!z->progressive) {
2757*4882a593Smuzhiyun       if (z->scan_n == 1) {
2758*4882a593Smuzhiyun          int i,j;
2759*4882a593Smuzhiyun          STBI_SIMD_ALIGN(short, data[64]);
2760*4882a593Smuzhiyun          int n = z->order[0];
2761*4882a593Smuzhiyun          // non-interleaved data, we just need to process one block at a time,
2762*4882a593Smuzhiyun          // in trivial scanline order
2763*4882a593Smuzhiyun          // number of blocks to do just depends on how many actual "pixels" this
2764*4882a593Smuzhiyun          // component has, independent of interleaved MCU blocking and such
2765*4882a593Smuzhiyun          int w = (z->img_comp[n].x+7) >> 3;
2766*4882a593Smuzhiyun          int h = (z->img_comp[n].y+7) >> 3;
2767*4882a593Smuzhiyun          for (j=0; j < h; ++j) {
2768*4882a593Smuzhiyun             for (i=0; i < w; ++i) {
2769*4882a593Smuzhiyun                int ha = z->img_comp[n].ha;
2770*4882a593Smuzhiyun                if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
2771*4882a593Smuzhiyun                z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
2772*4882a593Smuzhiyun                // every data block is an MCU, so countdown the restart interval
2773*4882a593Smuzhiyun                if (--z->todo <= 0) {
2774*4882a593Smuzhiyun                   if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
2775*4882a593Smuzhiyun                   // if it's NOT a restart, then just bail, so we get corrupt data
2776*4882a593Smuzhiyun                   // rather than no data
2777*4882a593Smuzhiyun                   if (!STBI__RESTART(z->marker)) return 1;
2778*4882a593Smuzhiyun                   stbi__jpeg_reset(z);
2779*4882a593Smuzhiyun                }
2780*4882a593Smuzhiyun             }
2781*4882a593Smuzhiyun          }
2782*4882a593Smuzhiyun          return 1;
2783*4882a593Smuzhiyun       } else { // interleaved
2784*4882a593Smuzhiyun          int i,j,k,x,y;
2785*4882a593Smuzhiyun          STBI_SIMD_ALIGN(short, data[64]);
2786*4882a593Smuzhiyun          for (j=0; j < z->img_mcu_y; ++j) {
2787*4882a593Smuzhiyun             for (i=0; i < z->img_mcu_x; ++i) {
2788*4882a593Smuzhiyun                // scan an interleaved mcu... process scan_n components in order
2789*4882a593Smuzhiyun                for (k=0; k < z->scan_n; ++k) {
2790*4882a593Smuzhiyun                   int n = z->order[k];
2791*4882a593Smuzhiyun                   // scan out an mcu's worth of this component; that's just determined
2792*4882a593Smuzhiyun                   // by the basic H and V specified for the component
2793*4882a593Smuzhiyun                   for (y=0; y < z->img_comp[n].v; ++y) {
2794*4882a593Smuzhiyun                      for (x=0; x < z->img_comp[n].h; ++x) {
2795*4882a593Smuzhiyun                         int x2 = (i*z->img_comp[n].h + x)*8;
2796*4882a593Smuzhiyun                         int y2 = (j*z->img_comp[n].v + y)*8;
2797*4882a593Smuzhiyun                         int ha = z->img_comp[n].ha;
2798*4882a593Smuzhiyun                         if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
2799*4882a593Smuzhiyun                         z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data);
2800*4882a593Smuzhiyun                      }
2801*4882a593Smuzhiyun                   }
2802*4882a593Smuzhiyun                }
2803*4882a593Smuzhiyun                // after all interleaved components, that's an interleaved MCU,
2804*4882a593Smuzhiyun                // so now count down the restart interval
2805*4882a593Smuzhiyun                if (--z->todo <= 0) {
2806*4882a593Smuzhiyun                   if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
2807*4882a593Smuzhiyun                   if (!STBI__RESTART(z->marker)) return 1;
2808*4882a593Smuzhiyun                   stbi__jpeg_reset(z);
2809*4882a593Smuzhiyun                }
2810*4882a593Smuzhiyun             }
2811*4882a593Smuzhiyun          }
2812*4882a593Smuzhiyun          return 1;
2813*4882a593Smuzhiyun       }
2814*4882a593Smuzhiyun    } else {
2815*4882a593Smuzhiyun       if (z->scan_n == 1) {
2816*4882a593Smuzhiyun          int i,j;
2817*4882a593Smuzhiyun          int n = z->order[0];
2818*4882a593Smuzhiyun          // non-interleaved data, we just need to process one block at a time,
2819*4882a593Smuzhiyun          // in trivial scanline order
2820*4882a593Smuzhiyun          // number of blocks to do just depends on how many actual "pixels" this
2821*4882a593Smuzhiyun          // component has, independent of interleaved MCU blocking and such
2822*4882a593Smuzhiyun          int w = (z->img_comp[n].x+7) >> 3;
2823*4882a593Smuzhiyun          int h = (z->img_comp[n].y+7) >> 3;
2824*4882a593Smuzhiyun          for (j=0; j < h; ++j) {
2825*4882a593Smuzhiyun             for (i=0; i < w; ++i) {
2826*4882a593Smuzhiyun                short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
2827*4882a593Smuzhiyun                if (z->spec_start == 0) {
2828*4882a593Smuzhiyun                   if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
2829*4882a593Smuzhiyun                      return 0;
2830*4882a593Smuzhiyun                } else {
2831*4882a593Smuzhiyun                   int ha = z->img_comp[n].ha;
2832*4882a593Smuzhiyun                   if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha]))
2833*4882a593Smuzhiyun                      return 0;
2834*4882a593Smuzhiyun                }
2835*4882a593Smuzhiyun                // every data block is an MCU, so countdown the restart interval
2836*4882a593Smuzhiyun                if (--z->todo <= 0) {
2837*4882a593Smuzhiyun                   if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
2838*4882a593Smuzhiyun                   if (!STBI__RESTART(z->marker)) return 1;
2839*4882a593Smuzhiyun                   stbi__jpeg_reset(z);
2840*4882a593Smuzhiyun                }
2841*4882a593Smuzhiyun             }
2842*4882a593Smuzhiyun          }
2843*4882a593Smuzhiyun          return 1;
2844*4882a593Smuzhiyun       } else { // interleaved
2845*4882a593Smuzhiyun          int i,j,k,x,y;
2846*4882a593Smuzhiyun          for (j=0; j < z->img_mcu_y; ++j) {
2847*4882a593Smuzhiyun             for (i=0; i < z->img_mcu_x; ++i) {
2848*4882a593Smuzhiyun                // scan an interleaved mcu... process scan_n components in order
2849*4882a593Smuzhiyun                for (k=0; k < z->scan_n; ++k) {
2850*4882a593Smuzhiyun                   int n = z->order[k];
2851*4882a593Smuzhiyun                   // scan out an mcu's worth of this component; that's just determined
2852*4882a593Smuzhiyun                   // by the basic H and V specified for the component
2853*4882a593Smuzhiyun                   for (y=0; y < z->img_comp[n].v; ++y) {
2854*4882a593Smuzhiyun                      for (x=0; x < z->img_comp[n].h; ++x) {
2855*4882a593Smuzhiyun                         int x2 = (i*z->img_comp[n].h + x);
2856*4882a593Smuzhiyun                         int y2 = (j*z->img_comp[n].v + y);
2857*4882a593Smuzhiyun                         short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w);
2858*4882a593Smuzhiyun                         if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
2859*4882a593Smuzhiyun                            return 0;
2860*4882a593Smuzhiyun                      }
2861*4882a593Smuzhiyun                   }
2862*4882a593Smuzhiyun                }
2863*4882a593Smuzhiyun                // after all interleaved components, that's an interleaved MCU,
2864*4882a593Smuzhiyun                // so now count down the restart interval
2865*4882a593Smuzhiyun                if (--z->todo <= 0) {
2866*4882a593Smuzhiyun                   if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
2867*4882a593Smuzhiyun                   if (!STBI__RESTART(z->marker)) return 1;
2868*4882a593Smuzhiyun                   stbi__jpeg_reset(z);
2869*4882a593Smuzhiyun                }
2870*4882a593Smuzhiyun             }
2871*4882a593Smuzhiyun          }
2872*4882a593Smuzhiyun          return 1;
2873*4882a593Smuzhiyun       }
2874*4882a593Smuzhiyun    }
2875*4882a593Smuzhiyun }
2876*4882a593Smuzhiyun 
stbi__jpeg_dequantize(short * data,stbi__uint16 * dequant)2877*4882a593Smuzhiyun static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant)
2878*4882a593Smuzhiyun {
2879*4882a593Smuzhiyun    int i;
2880*4882a593Smuzhiyun    for (i=0; i < 64; ++i)
2881*4882a593Smuzhiyun       data[i] *= dequant[i];
2882*4882a593Smuzhiyun }
2883*4882a593Smuzhiyun 
stbi__jpeg_finish(stbi__jpeg * z)2884*4882a593Smuzhiyun static void stbi__jpeg_finish(stbi__jpeg *z)
2885*4882a593Smuzhiyun {
2886*4882a593Smuzhiyun    if (z->progressive) {
2887*4882a593Smuzhiyun       // dequantize and idct the data
2888*4882a593Smuzhiyun       int i,j,n;
2889*4882a593Smuzhiyun       for (n=0; n < z->s->img_n; ++n) {
2890*4882a593Smuzhiyun          int w = (z->img_comp[n].x+7) >> 3;
2891*4882a593Smuzhiyun          int h = (z->img_comp[n].y+7) >> 3;
2892*4882a593Smuzhiyun          for (j=0; j < h; ++j) {
2893*4882a593Smuzhiyun             for (i=0; i < w; ++i) {
2894*4882a593Smuzhiyun                short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
2895*4882a593Smuzhiyun                stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]);
2896*4882a593Smuzhiyun                z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
2897*4882a593Smuzhiyun             }
2898*4882a593Smuzhiyun          }
2899*4882a593Smuzhiyun       }
2900*4882a593Smuzhiyun    }
2901*4882a593Smuzhiyun }
2902*4882a593Smuzhiyun 
stbi__process_marker(stbi__jpeg * z,int m)2903*4882a593Smuzhiyun static int stbi__process_marker(stbi__jpeg *z, int m)
2904*4882a593Smuzhiyun {
2905*4882a593Smuzhiyun    int L;
2906*4882a593Smuzhiyun    switch (m) {
2907*4882a593Smuzhiyun       case STBI__MARKER_none: // no marker found
2908*4882a593Smuzhiyun          return stbi__err("expected marker","Corrupt JPEG");
2909*4882a593Smuzhiyun 
2910*4882a593Smuzhiyun       case 0xDD: // DRI - specify restart interval
2911*4882a593Smuzhiyun          if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG");
2912*4882a593Smuzhiyun          z->restart_interval = stbi__get16be(z->s);
2913*4882a593Smuzhiyun          return 1;
2914*4882a593Smuzhiyun 
2915*4882a593Smuzhiyun       case 0xDB: // DQT - define quantization table
2916*4882a593Smuzhiyun          L = stbi__get16be(z->s)-2;
2917*4882a593Smuzhiyun          while (L > 0) {
2918*4882a593Smuzhiyun             int q = stbi__get8(z->s);
2919*4882a593Smuzhiyun             int p = q >> 4, sixteen = (p != 0);
2920*4882a593Smuzhiyun             int t = q & 15,i;
2921*4882a593Smuzhiyun             if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG");
2922*4882a593Smuzhiyun             if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG");
2923*4882a593Smuzhiyun 
2924*4882a593Smuzhiyun             for (i=0; i < 64; ++i)
2925*4882a593Smuzhiyun                z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s));
2926*4882a593Smuzhiyun             L -= (sixteen ? 129 : 65);
2927*4882a593Smuzhiyun          }
2928*4882a593Smuzhiyun          return L==0;
2929*4882a593Smuzhiyun 
2930*4882a593Smuzhiyun       case 0xC4: // DHT - define huffman table
2931*4882a593Smuzhiyun          L = stbi__get16be(z->s)-2;
2932*4882a593Smuzhiyun          while (L > 0) {
2933*4882a593Smuzhiyun             stbi_uc *v;
2934*4882a593Smuzhiyun             int sizes[16],i,n=0;
2935*4882a593Smuzhiyun             int q = stbi__get8(z->s);
2936*4882a593Smuzhiyun             int tc = q >> 4;
2937*4882a593Smuzhiyun             int th = q & 15;
2938*4882a593Smuzhiyun             if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG");
2939*4882a593Smuzhiyun             for (i=0; i < 16; ++i) {
2940*4882a593Smuzhiyun                sizes[i] = stbi__get8(z->s);
2941*4882a593Smuzhiyun                n += sizes[i];
2942*4882a593Smuzhiyun             }
2943*4882a593Smuzhiyun             L -= 17;
2944*4882a593Smuzhiyun             if (tc == 0) {
2945*4882a593Smuzhiyun                if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
2946*4882a593Smuzhiyun                v = z->huff_dc[th].values;
2947*4882a593Smuzhiyun             } else {
2948*4882a593Smuzhiyun                if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0;
2949*4882a593Smuzhiyun                v = z->huff_ac[th].values;
2950*4882a593Smuzhiyun             }
2951*4882a593Smuzhiyun             for (i=0; i < n; ++i)
2952*4882a593Smuzhiyun                v[i] = stbi__get8(z->s);
2953*4882a593Smuzhiyun             if (tc != 0)
2954*4882a593Smuzhiyun                stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th);
2955*4882a593Smuzhiyun             L -= n;
2956*4882a593Smuzhiyun          }
2957*4882a593Smuzhiyun          return L==0;
2958*4882a593Smuzhiyun    }
2959*4882a593Smuzhiyun 
2960*4882a593Smuzhiyun    // check for comment block or APP blocks
2961*4882a593Smuzhiyun    if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
2962*4882a593Smuzhiyun       L = stbi__get16be(z->s);
2963*4882a593Smuzhiyun       if (L < 2) {
2964*4882a593Smuzhiyun          if (m == 0xFE)
2965*4882a593Smuzhiyun             return stbi__err("bad COM len","Corrupt JPEG");
2966*4882a593Smuzhiyun          else
2967*4882a593Smuzhiyun             return stbi__err("bad APP len","Corrupt JPEG");
2968*4882a593Smuzhiyun       }
2969*4882a593Smuzhiyun       L -= 2;
2970*4882a593Smuzhiyun 
2971*4882a593Smuzhiyun       if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
2972*4882a593Smuzhiyun          static const unsigned char tag[5] = {'J','F','I','F','\0'};
2973*4882a593Smuzhiyun          int ok = 1;
2974*4882a593Smuzhiyun          int i;
2975*4882a593Smuzhiyun          for (i=0; i < 5; ++i)
2976*4882a593Smuzhiyun             if (stbi__get8(z->s) != tag[i])
2977*4882a593Smuzhiyun                ok = 0;
2978*4882a593Smuzhiyun          L -= 5;
2979*4882a593Smuzhiyun          if (ok)
2980*4882a593Smuzhiyun             z->jfif = 1;
2981*4882a593Smuzhiyun       } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
2982*4882a593Smuzhiyun          static const unsigned char tag[6] = {'A','d','o','b','e','\0'};
2983*4882a593Smuzhiyun          int ok = 1;
2984*4882a593Smuzhiyun          int i;
2985*4882a593Smuzhiyun          for (i=0; i < 6; ++i)
2986*4882a593Smuzhiyun             if (stbi__get8(z->s) != tag[i])
2987*4882a593Smuzhiyun                ok = 0;
2988*4882a593Smuzhiyun          L -= 6;
2989*4882a593Smuzhiyun          if (ok) {
2990*4882a593Smuzhiyun             stbi__get8(z->s); // version
2991*4882a593Smuzhiyun             stbi__get16be(z->s); // flags0
2992*4882a593Smuzhiyun             stbi__get16be(z->s); // flags1
2993*4882a593Smuzhiyun             z->app14_color_transform = stbi__get8(z->s); // color transform
2994*4882a593Smuzhiyun             L -= 6;
2995*4882a593Smuzhiyun          }
2996*4882a593Smuzhiyun       }
2997*4882a593Smuzhiyun 
2998*4882a593Smuzhiyun       stbi__skip(z->s, L);
2999*4882a593Smuzhiyun       return 1;
3000*4882a593Smuzhiyun    }
3001*4882a593Smuzhiyun 
3002*4882a593Smuzhiyun    return stbi__err("unknown marker","Corrupt JPEG");
3003*4882a593Smuzhiyun }
3004*4882a593Smuzhiyun 
3005*4882a593Smuzhiyun // after we see SOS
stbi__process_scan_header(stbi__jpeg * z)3006*4882a593Smuzhiyun static int stbi__process_scan_header(stbi__jpeg *z)
3007*4882a593Smuzhiyun {
3008*4882a593Smuzhiyun    int i;
3009*4882a593Smuzhiyun    int Ls = stbi__get16be(z->s);
3010*4882a593Smuzhiyun    z->scan_n = stbi__get8(z->s);
3011*4882a593Smuzhiyun    if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG");
3012*4882a593Smuzhiyun    if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG");
3013*4882a593Smuzhiyun    for (i=0; i < z->scan_n; ++i) {
3014*4882a593Smuzhiyun       int id = stbi__get8(z->s), which;
3015*4882a593Smuzhiyun       int q = stbi__get8(z->s);
3016*4882a593Smuzhiyun       for (which = 0; which < z->s->img_n; ++which)
3017*4882a593Smuzhiyun          if (z->img_comp[which].id == id)
3018*4882a593Smuzhiyun             break;
3019*4882a593Smuzhiyun       if (which == z->s->img_n) return 0; // no match
3020*4882a593Smuzhiyun       z->img_comp[which].hd = q >> 4;   if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG");
3021*4882a593Smuzhiyun       z->img_comp[which].ha = q & 15;   if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG");
3022*4882a593Smuzhiyun       z->order[i] = which;
3023*4882a593Smuzhiyun    }
3024*4882a593Smuzhiyun 
3025*4882a593Smuzhiyun    {
3026*4882a593Smuzhiyun       int aa;
3027*4882a593Smuzhiyun       z->spec_start = stbi__get8(z->s);
3028*4882a593Smuzhiyun       z->spec_end   = stbi__get8(z->s); // should be 63, but might be 0
3029*4882a593Smuzhiyun       aa = stbi__get8(z->s);
3030*4882a593Smuzhiyun       z->succ_high = (aa >> 4);
3031*4882a593Smuzhiyun       z->succ_low  = (aa & 15);
3032*4882a593Smuzhiyun       if (z->progressive) {
3033*4882a593Smuzhiyun          if (z->spec_start > 63 || z->spec_end > 63  || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13)
3034*4882a593Smuzhiyun             return stbi__err("bad SOS", "Corrupt JPEG");
3035*4882a593Smuzhiyun       } else {
3036*4882a593Smuzhiyun          if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG");
3037*4882a593Smuzhiyun          if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG");
3038*4882a593Smuzhiyun          z->spec_end = 63;
3039*4882a593Smuzhiyun       }
3040*4882a593Smuzhiyun    }
3041*4882a593Smuzhiyun 
3042*4882a593Smuzhiyun    return 1;
3043*4882a593Smuzhiyun }
3044*4882a593Smuzhiyun 
stbi__free_jpeg_components(stbi__jpeg * z,int ncomp,int why)3045*4882a593Smuzhiyun static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why)
3046*4882a593Smuzhiyun {
3047*4882a593Smuzhiyun    int i;
3048*4882a593Smuzhiyun    for (i=0; i < ncomp; ++i) {
3049*4882a593Smuzhiyun       if (z->img_comp[i].raw_data) {
3050*4882a593Smuzhiyun          STBI_FREE(z->img_comp[i].raw_data);
3051*4882a593Smuzhiyun          z->img_comp[i].raw_data = NULL;
3052*4882a593Smuzhiyun          z->img_comp[i].data = NULL;
3053*4882a593Smuzhiyun       }
3054*4882a593Smuzhiyun       if (z->img_comp[i].raw_coeff) {
3055*4882a593Smuzhiyun          STBI_FREE(z->img_comp[i].raw_coeff);
3056*4882a593Smuzhiyun          z->img_comp[i].raw_coeff = 0;
3057*4882a593Smuzhiyun          z->img_comp[i].coeff = 0;
3058*4882a593Smuzhiyun       }
3059*4882a593Smuzhiyun       if (z->img_comp[i].linebuf) {
3060*4882a593Smuzhiyun          STBI_FREE(z->img_comp[i].linebuf);
3061*4882a593Smuzhiyun          z->img_comp[i].linebuf = NULL;
3062*4882a593Smuzhiyun       }
3063*4882a593Smuzhiyun    }
3064*4882a593Smuzhiyun    return why;
3065*4882a593Smuzhiyun }
3066*4882a593Smuzhiyun 
stbi__process_frame_header(stbi__jpeg * z,int scan)3067*4882a593Smuzhiyun static int stbi__process_frame_header(stbi__jpeg *z, int scan)
3068*4882a593Smuzhiyun {
3069*4882a593Smuzhiyun    stbi__context *s = z->s;
3070*4882a593Smuzhiyun    int Lf,p,i,q, h_max=1,v_max=1,c;
3071*4882a593Smuzhiyun    Lf = stbi__get16be(s);         if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG
3072*4882a593Smuzhiyun    p  = stbi__get8(s);            if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
3073*4882a593Smuzhiyun    s->img_y = stbi__get16be(s);   if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
3074*4882a593Smuzhiyun    s->img_x = stbi__get16be(s);   if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
3075*4882a593Smuzhiyun    c = stbi__get8(s);
3076*4882a593Smuzhiyun    if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
3077*4882a593Smuzhiyun    s->img_n = c;
3078*4882a593Smuzhiyun    for (i=0; i < c; ++i) {
3079*4882a593Smuzhiyun       z->img_comp[i].data = NULL;
3080*4882a593Smuzhiyun       z->img_comp[i].linebuf = NULL;
3081*4882a593Smuzhiyun    }
3082*4882a593Smuzhiyun 
3083*4882a593Smuzhiyun    if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG");
3084*4882a593Smuzhiyun 
3085*4882a593Smuzhiyun    z->rgb = 0;
3086*4882a593Smuzhiyun    for (i=0; i < s->img_n; ++i) {
3087*4882a593Smuzhiyun       static const unsigned char rgb[3] = { 'R', 'G', 'B' };
3088*4882a593Smuzhiyun       z->img_comp[i].id = stbi__get8(s);
3089*4882a593Smuzhiyun       if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
3090*4882a593Smuzhiyun          ++z->rgb;
3091*4882a593Smuzhiyun       q = stbi__get8(s);
3092*4882a593Smuzhiyun       z->img_comp[i].h = (q >> 4);  if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
3093*4882a593Smuzhiyun       z->img_comp[i].v = q & 15;    if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
3094*4882a593Smuzhiyun       z->img_comp[i].tq = stbi__get8(s);  if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG");
3095*4882a593Smuzhiyun    }
3096*4882a593Smuzhiyun 
3097*4882a593Smuzhiyun    if (scan != STBI__SCAN_load) return 1;
3098*4882a593Smuzhiyun 
3099*4882a593Smuzhiyun    if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode");
3100*4882a593Smuzhiyun 
3101*4882a593Smuzhiyun    for (i=0; i < s->img_n; ++i) {
3102*4882a593Smuzhiyun       if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h;
3103*4882a593Smuzhiyun       if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v;
3104*4882a593Smuzhiyun    }
3105*4882a593Smuzhiyun 
3106*4882a593Smuzhiyun    // compute interleaved mcu info
3107*4882a593Smuzhiyun    z->img_h_max = h_max;
3108*4882a593Smuzhiyun    z->img_v_max = v_max;
3109*4882a593Smuzhiyun    z->img_mcu_w = h_max * 8;
3110*4882a593Smuzhiyun    z->img_mcu_h = v_max * 8;
3111*4882a593Smuzhiyun    // these sizes can't be more than 17 bits
3112*4882a593Smuzhiyun    z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w;
3113*4882a593Smuzhiyun    z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h;
3114*4882a593Smuzhiyun 
3115*4882a593Smuzhiyun    for (i=0; i < s->img_n; ++i) {
3116*4882a593Smuzhiyun       // number of effective pixels (e.g. for non-interleaved MCU)
3117*4882a593Smuzhiyun       z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max;
3118*4882a593Smuzhiyun       z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max;
3119*4882a593Smuzhiyun       // to simplify generation, we'll allocate enough memory to decode
3120*4882a593Smuzhiyun       // the bogus oversized data from using interleaved MCUs and their
3121*4882a593Smuzhiyun       // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
3122*4882a593Smuzhiyun       // discard the extra data until colorspace conversion
3123*4882a593Smuzhiyun       //
3124*4882a593Smuzhiyun       // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier)
3125*4882a593Smuzhiyun       // so these muls can't overflow with 32-bit ints (which we require)
3126*4882a593Smuzhiyun       z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8;
3127*4882a593Smuzhiyun       z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8;
3128*4882a593Smuzhiyun       z->img_comp[i].coeff = 0;
3129*4882a593Smuzhiyun       z->img_comp[i].raw_coeff = 0;
3130*4882a593Smuzhiyun       z->img_comp[i].linebuf = NULL;
3131*4882a593Smuzhiyun       z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15);
3132*4882a593Smuzhiyun       if (z->img_comp[i].raw_data == NULL)
3133*4882a593Smuzhiyun          return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
3134*4882a593Smuzhiyun       // align blocks for idct using mmx/sse
3135*4882a593Smuzhiyun       z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15);
3136*4882a593Smuzhiyun       if (z->progressive) {
3137*4882a593Smuzhiyun          // w2, h2 are multiples of 8 (see above)
3138*4882a593Smuzhiyun          z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8;
3139*4882a593Smuzhiyun          z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8;
3140*4882a593Smuzhiyun          z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15);
3141*4882a593Smuzhiyun          if (z->img_comp[i].raw_coeff == NULL)
3142*4882a593Smuzhiyun             return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
3143*4882a593Smuzhiyun          z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15);
3144*4882a593Smuzhiyun       }
3145*4882a593Smuzhiyun    }
3146*4882a593Smuzhiyun 
3147*4882a593Smuzhiyun    return 1;
3148*4882a593Smuzhiyun }
3149*4882a593Smuzhiyun 
3150*4882a593Smuzhiyun // use comparisons since in some cases we handle more than one case (e.g. SOF)
3151*4882a593Smuzhiyun #define stbi__DNL(x)         ((x) == 0xdc)
3152*4882a593Smuzhiyun #define stbi__SOI(x)         ((x) == 0xd8)
3153*4882a593Smuzhiyun #define stbi__EOI(x)         ((x) == 0xd9)
3154*4882a593Smuzhiyun #define stbi__SOF(x)         ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2)
3155*4882a593Smuzhiyun #define stbi__SOS(x)         ((x) == 0xda)
3156*4882a593Smuzhiyun 
3157*4882a593Smuzhiyun #define stbi__SOF_progressive(x)   ((x) == 0xc2)
3158*4882a593Smuzhiyun 
stbi__decode_jpeg_header(stbi__jpeg * z,int scan)3159*4882a593Smuzhiyun static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
3160*4882a593Smuzhiyun {
3161*4882a593Smuzhiyun    int m;
3162*4882a593Smuzhiyun    z->jfif = 0;
3163*4882a593Smuzhiyun    z->app14_color_transform = -1; // valid values are 0,1,2
3164*4882a593Smuzhiyun    z->marker = STBI__MARKER_none; // initialize cached marker to empty
3165*4882a593Smuzhiyun    m = stbi__get_marker(z);
3166*4882a593Smuzhiyun    if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
3167*4882a593Smuzhiyun    if (scan == STBI__SCAN_type) return 1;
3168*4882a593Smuzhiyun    m = stbi__get_marker(z);
3169*4882a593Smuzhiyun    while (!stbi__SOF(m)) {
3170*4882a593Smuzhiyun       if (!stbi__process_marker(z,m)) return 0;
3171*4882a593Smuzhiyun       m = stbi__get_marker(z);
3172*4882a593Smuzhiyun       while (m == STBI__MARKER_none) {
3173*4882a593Smuzhiyun          // some files have extra padding after their blocks, so ok, we'll scan
3174*4882a593Smuzhiyun          if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG");
3175*4882a593Smuzhiyun          m = stbi__get_marker(z);
3176*4882a593Smuzhiyun       }
3177*4882a593Smuzhiyun    }
3178*4882a593Smuzhiyun    z->progressive = stbi__SOF_progressive(m);
3179*4882a593Smuzhiyun    if (!stbi__process_frame_header(z, scan)) return 0;
3180*4882a593Smuzhiyun    return 1;
3181*4882a593Smuzhiyun }
3182*4882a593Smuzhiyun 
3183*4882a593Smuzhiyun // decode image to YCbCr format
stbi__decode_jpeg_image(stbi__jpeg * j)3184*4882a593Smuzhiyun static int stbi__decode_jpeg_image(stbi__jpeg *j)
3185*4882a593Smuzhiyun {
3186*4882a593Smuzhiyun    int m;
3187*4882a593Smuzhiyun    for (m = 0; m < 4; m++) {
3188*4882a593Smuzhiyun       j->img_comp[m].raw_data = NULL;
3189*4882a593Smuzhiyun       j->img_comp[m].raw_coeff = NULL;
3190*4882a593Smuzhiyun    }
3191*4882a593Smuzhiyun    j->restart_interval = 0;
3192*4882a593Smuzhiyun    if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0;
3193*4882a593Smuzhiyun    m = stbi__get_marker(j);
3194*4882a593Smuzhiyun    while (!stbi__EOI(m)) {
3195*4882a593Smuzhiyun       if (stbi__SOS(m)) {
3196*4882a593Smuzhiyun          if (!stbi__process_scan_header(j)) return 0;
3197*4882a593Smuzhiyun          if (!stbi__parse_entropy_coded_data(j)) return 0;
3198*4882a593Smuzhiyun          if (j->marker == STBI__MARKER_none ) {
3199*4882a593Smuzhiyun             // handle 0s at the end of image data from IP Kamera 9060
3200*4882a593Smuzhiyun             while (!stbi__at_eof(j->s)) {
3201*4882a593Smuzhiyun                int x = stbi__get8(j->s);
3202*4882a593Smuzhiyun                if (x == 255) {
3203*4882a593Smuzhiyun                   j->marker = stbi__get8(j->s);
3204*4882a593Smuzhiyun                   break;
3205*4882a593Smuzhiyun                }
3206*4882a593Smuzhiyun             }
3207*4882a593Smuzhiyun             // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
3208*4882a593Smuzhiyun          }
3209*4882a593Smuzhiyun       } else if (stbi__DNL(m)) {
3210*4882a593Smuzhiyun          int Ld = stbi__get16be(j->s);
3211*4882a593Smuzhiyun          stbi__uint32 NL = stbi__get16be(j->s);
3212*4882a593Smuzhiyun          if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
3213*4882a593Smuzhiyun          if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
3214*4882a593Smuzhiyun       } else {
3215*4882a593Smuzhiyun          if (!stbi__process_marker(j, m)) return 0;
3216*4882a593Smuzhiyun       }
3217*4882a593Smuzhiyun       m = stbi__get_marker(j);
3218*4882a593Smuzhiyun    }
3219*4882a593Smuzhiyun    if (j->progressive)
3220*4882a593Smuzhiyun       stbi__jpeg_finish(j);
3221*4882a593Smuzhiyun    return 1;
3222*4882a593Smuzhiyun }
3223*4882a593Smuzhiyun 
3224*4882a593Smuzhiyun // static jfif-centered resampling (across block boundaries)
3225*4882a593Smuzhiyun 
3226*4882a593Smuzhiyun typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1,
3227*4882a593Smuzhiyun                                     int w, int hs);
3228*4882a593Smuzhiyun 
3229*4882a593Smuzhiyun #define stbi__div4(x) ((stbi_uc) ((x) >> 2))
3230*4882a593Smuzhiyun 
resample_row_1(stbi_uc * out,stbi_uc * in_near,stbi_uc * in_far,int w,int hs)3231*4882a593Smuzhiyun static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
3232*4882a593Smuzhiyun {
3233*4882a593Smuzhiyun    STBI_NOTUSED(out);
3234*4882a593Smuzhiyun    STBI_NOTUSED(in_far);
3235*4882a593Smuzhiyun    STBI_NOTUSED(w);
3236*4882a593Smuzhiyun    STBI_NOTUSED(hs);
3237*4882a593Smuzhiyun    return in_near;
3238*4882a593Smuzhiyun }
3239*4882a593Smuzhiyun 
stbi__resample_row_v_2(stbi_uc * out,stbi_uc * in_near,stbi_uc * in_far,int w,int hs)3240*4882a593Smuzhiyun static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
3241*4882a593Smuzhiyun {
3242*4882a593Smuzhiyun    // need to generate two samples vertically for every one in input
3243*4882a593Smuzhiyun    int i;
3244*4882a593Smuzhiyun    STBI_NOTUSED(hs);
3245*4882a593Smuzhiyun    for (i=0; i < w; ++i)
3246*4882a593Smuzhiyun       out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2);
3247*4882a593Smuzhiyun    return out;
3248*4882a593Smuzhiyun }
3249*4882a593Smuzhiyun 
stbi__resample_row_h_2(stbi_uc * out,stbi_uc * in_near,stbi_uc * in_far,int w,int hs)3250*4882a593Smuzhiyun static stbi_uc*  stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
3251*4882a593Smuzhiyun {
3252*4882a593Smuzhiyun    // need to generate two samples horizontally for every one in input
3253*4882a593Smuzhiyun    int i;
3254*4882a593Smuzhiyun    stbi_uc *input = in_near;
3255*4882a593Smuzhiyun 
3256*4882a593Smuzhiyun    if (w == 1) {
3257*4882a593Smuzhiyun       // if only one sample, can't do any interpolation
3258*4882a593Smuzhiyun       out[0] = out[1] = input[0];
3259*4882a593Smuzhiyun       return out;
3260*4882a593Smuzhiyun    }
3261*4882a593Smuzhiyun 
3262*4882a593Smuzhiyun    out[0] = input[0];
3263*4882a593Smuzhiyun    out[1] = stbi__div4(input[0]*3 + input[1] + 2);
3264*4882a593Smuzhiyun    for (i=1; i < w-1; ++i) {
3265*4882a593Smuzhiyun       int n = 3*input[i]+2;
3266*4882a593Smuzhiyun       out[i*2+0] = stbi__div4(n+input[i-1]);
3267*4882a593Smuzhiyun       out[i*2+1] = stbi__div4(n+input[i+1]);
3268*4882a593Smuzhiyun    }
3269*4882a593Smuzhiyun    out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2);
3270*4882a593Smuzhiyun    out[i*2+1] = input[w-1];
3271*4882a593Smuzhiyun 
3272*4882a593Smuzhiyun    STBI_NOTUSED(in_far);
3273*4882a593Smuzhiyun    STBI_NOTUSED(hs);
3274*4882a593Smuzhiyun 
3275*4882a593Smuzhiyun    return out;
3276*4882a593Smuzhiyun }
3277*4882a593Smuzhiyun 
3278*4882a593Smuzhiyun #define stbi__div16(x) ((stbi_uc) ((x) >> 4))
3279*4882a593Smuzhiyun 
stbi__resample_row_hv_2(stbi_uc * out,stbi_uc * in_near,stbi_uc * in_far,int w,int hs)3280*4882a593Smuzhiyun static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
3281*4882a593Smuzhiyun {
3282*4882a593Smuzhiyun    // need to generate 2x2 samples for every one in input
3283*4882a593Smuzhiyun    int i,t0,t1;
3284*4882a593Smuzhiyun    if (w == 1) {
3285*4882a593Smuzhiyun       out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2);
3286*4882a593Smuzhiyun       return out;
3287*4882a593Smuzhiyun    }
3288*4882a593Smuzhiyun 
3289*4882a593Smuzhiyun    t1 = 3*in_near[0] + in_far[0];
3290*4882a593Smuzhiyun    out[0] = stbi__div4(t1+2);
3291*4882a593Smuzhiyun    for (i=1; i < w; ++i) {
3292*4882a593Smuzhiyun       t0 = t1;
3293*4882a593Smuzhiyun       t1 = 3*in_near[i]+in_far[i];
3294*4882a593Smuzhiyun       out[i*2-1] = stbi__div16(3*t0 + t1 + 8);
3295*4882a593Smuzhiyun       out[i*2  ] = stbi__div16(3*t1 + t0 + 8);
3296*4882a593Smuzhiyun    }
3297*4882a593Smuzhiyun    out[w*2-1] = stbi__div4(t1+2);
3298*4882a593Smuzhiyun 
3299*4882a593Smuzhiyun    STBI_NOTUSED(hs);
3300*4882a593Smuzhiyun 
3301*4882a593Smuzhiyun    return out;
3302*4882a593Smuzhiyun }
3303*4882a593Smuzhiyun 
3304*4882a593Smuzhiyun #if defined(STBI_SSE2) || defined(STBI_NEON)
stbi__resample_row_hv_2_simd(stbi_uc * out,stbi_uc * in_near,stbi_uc * in_far,int w,int hs)3305*4882a593Smuzhiyun static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
3306*4882a593Smuzhiyun {
3307*4882a593Smuzhiyun    // need to generate 2x2 samples for every one in input
3308*4882a593Smuzhiyun    int i=0,t0,t1;
3309*4882a593Smuzhiyun 
3310*4882a593Smuzhiyun    if (w == 1) {
3311*4882a593Smuzhiyun       out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2);
3312*4882a593Smuzhiyun       return out;
3313*4882a593Smuzhiyun    }
3314*4882a593Smuzhiyun 
3315*4882a593Smuzhiyun    t1 = 3*in_near[0] + in_far[0];
3316*4882a593Smuzhiyun    // process groups of 8 pixels for as long as we can.
3317*4882a593Smuzhiyun    // note we can't handle the last pixel in a row in this loop
3318*4882a593Smuzhiyun    // because we need to handle the filter boundary conditions.
3319*4882a593Smuzhiyun    for (; i < ((w-1) & ~7); i += 8) {
3320*4882a593Smuzhiyun #if defined(STBI_SSE2)
3321*4882a593Smuzhiyun       // load and perform the vertical filtering pass
3322*4882a593Smuzhiyun       // this uses 3*x + y = 4*x + (y - x)
3323*4882a593Smuzhiyun       __m128i zero  = _mm_setzero_si128();
3324*4882a593Smuzhiyun       __m128i farb  = _mm_loadl_epi64((__m128i *) (in_far + i));
3325*4882a593Smuzhiyun       __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i));
3326*4882a593Smuzhiyun       __m128i farw  = _mm_unpacklo_epi8(farb, zero);
3327*4882a593Smuzhiyun       __m128i nearw = _mm_unpacklo_epi8(nearb, zero);
3328*4882a593Smuzhiyun       __m128i diff  = _mm_sub_epi16(farw, nearw);
3329*4882a593Smuzhiyun       __m128i nears = _mm_slli_epi16(nearw, 2);
3330*4882a593Smuzhiyun       __m128i curr  = _mm_add_epi16(nears, diff); // current row
3331*4882a593Smuzhiyun 
3332*4882a593Smuzhiyun       // horizontal filter works the same based on shifted vers of current
3333*4882a593Smuzhiyun       // row. "prev" is current row shifted right by 1 pixel; we need to
3334*4882a593Smuzhiyun       // insert the previous pixel value (from t1).
3335*4882a593Smuzhiyun       // "next" is current row shifted left by 1 pixel, with first pixel
3336*4882a593Smuzhiyun       // of next block of 8 pixels added in.
3337*4882a593Smuzhiyun       __m128i prv0 = _mm_slli_si128(curr, 2);
3338*4882a593Smuzhiyun       __m128i nxt0 = _mm_srli_si128(curr, 2);
3339*4882a593Smuzhiyun       __m128i prev = _mm_insert_epi16(prv0, t1, 0);
3340*4882a593Smuzhiyun       __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7);
3341*4882a593Smuzhiyun 
3342*4882a593Smuzhiyun       // horizontal filter, polyphase implementation since it's convenient:
3343*4882a593Smuzhiyun       // even pixels = 3*cur + prev = cur*4 + (prev - cur)
3344*4882a593Smuzhiyun       // odd  pixels = 3*cur + next = cur*4 + (next - cur)
3345*4882a593Smuzhiyun       // note the shared term.
3346*4882a593Smuzhiyun       __m128i bias  = _mm_set1_epi16(8);
3347*4882a593Smuzhiyun       __m128i curs = _mm_slli_epi16(curr, 2);
3348*4882a593Smuzhiyun       __m128i prvd = _mm_sub_epi16(prev, curr);
3349*4882a593Smuzhiyun       __m128i nxtd = _mm_sub_epi16(next, curr);
3350*4882a593Smuzhiyun       __m128i curb = _mm_add_epi16(curs, bias);
3351*4882a593Smuzhiyun       __m128i even = _mm_add_epi16(prvd, curb);
3352*4882a593Smuzhiyun       __m128i odd  = _mm_add_epi16(nxtd, curb);
3353*4882a593Smuzhiyun 
3354*4882a593Smuzhiyun       // interleave even and odd pixels, then undo scaling.
3355*4882a593Smuzhiyun       __m128i int0 = _mm_unpacklo_epi16(even, odd);
3356*4882a593Smuzhiyun       __m128i int1 = _mm_unpackhi_epi16(even, odd);
3357*4882a593Smuzhiyun       __m128i de0  = _mm_srli_epi16(int0, 4);
3358*4882a593Smuzhiyun       __m128i de1  = _mm_srli_epi16(int1, 4);
3359*4882a593Smuzhiyun 
3360*4882a593Smuzhiyun       // pack and write output
3361*4882a593Smuzhiyun       __m128i outv = _mm_packus_epi16(de0, de1);
3362*4882a593Smuzhiyun       _mm_storeu_si128((__m128i *) (out + i*2), outv);
3363*4882a593Smuzhiyun #elif defined(STBI_NEON)
3364*4882a593Smuzhiyun       // load and perform the vertical filtering pass
3365*4882a593Smuzhiyun       // this uses 3*x + y = 4*x + (y - x)
3366*4882a593Smuzhiyun       uint8x8_t farb  = vld1_u8(in_far + i);
3367*4882a593Smuzhiyun       uint8x8_t nearb = vld1_u8(in_near + i);
3368*4882a593Smuzhiyun       int16x8_t diff  = vreinterpretq_s16_u16(vsubl_u8(farb, nearb));
3369*4882a593Smuzhiyun       int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2));
3370*4882a593Smuzhiyun       int16x8_t curr  = vaddq_s16(nears, diff); // current row
3371*4882a593Smuzhiyun 
3372*4882a593Smuzhiyun       // horizontal filter works the same based on shifted vers of current
3373*4882a593Smuzhiyun       // row. "prev" is current row shifted right by 1 pixel; we need to
3374*4882a593Smuzhiyun       // insert the previous pixel value (from t1).
3375*4882a593Smuzhiyun       // "next" is current row shifted left by 1 pixel, with first pixel
3376*4882a593Smuzhiyun       // of next block of 8 pixels added in.
3377*4882a593Smuzhiyun       int16x8_t prv0 = vextq_s16(curr, curr, 7);
3378*4882a593Smuzhiyun       int16x8_t nxt0 = vextq_s16(curr, curr, 1);
3379*4882a593Smuzhiyun       int16x8_t prev = vsetq_lane_s16(t1, prv0, 0);
3380*4882a593Smuzhiyun       int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7);
3381*4882a593Smuzhiyun 
3382*4882a593Smuzhiyun       // horizontal filter, polyphase implementation since it's convenient:
3383*4882a593Smuzhiyun       // even pixels = 3*cur + prev = cur*4 + (prev - cur)
3384*4882a593Smuzhiyun       // odd  pixels = 3*cur + next = cur*4 + (next - cur)
3385*4882a593Smuzhiyun       // note the shared term.
3386*4882a593Smuzhiyun       int16x8_t curs = vshlq_n_s16(curr, 2);
3387*4882a593Smuzhiyun       int16x8_t prvd = vsubq_s16(prev, curr);
3388*4882a593Smuzhiyun       int16x8_t nxtd = vsubq_s16(next, curr);
3389*4882a593Smuzhiyun       int16x8_t even = vaddq_s16(curs, prvd);
3390*4882a593Smuzhiyun       int16x8_t odd  = vaddq_s16(curs, nxtd);
3391*4882a593Smuzhiyun 
3392*4882a593Smuzhiyun       // undo scaling and round, then store with even/odd phases interleaved
3393*4882a593Smuzhiyun       uint8x8x2_t o;
3394*4882a593Smuzhiyun       o.val[0] = vqrshrun_n_s16(even, 4);
3395*4882a593Smuzhiyun       o.val[1] = vqrshrun_n_s16(odd,  4);
3396*4882a593Smuzhiyun       vst2_u8(out + i*2, o);
3397*4882a593Smuzhiyun #endif
3398*4882a593Smuzhiyun 
3399*4882a593Smuzhiyun       // "previous" value for next iter
3400*4882a593Smuzhiyun       t1 = 3*in_near[i+7] + in_far[i+7];
3401*4882a593Smuzhiyun    }
3402*4882a593Smuzhiyun 
3403*4882a593Smuzhiyun    t0 = t1;
3404*4882a593Smuzhiyun    t1 = 3*in_near[i] + in_far[i];
3405*4882a593Smuzhiyun    out[i*2] = stbi__div16(3*t1 + t0 + 8);
3406*4882a593Smuzhiyun 
3407*4882a593Smuzhiyun    for (++i; i < w; ++i) {
3408*4882a593Smuzhiyun       t0 = t1;
3409*4882a593Smuzhiyun       t1 = 3*in_near[i]+in_far[i];
3410*4882a593Smuzhiyun       out[i*2-1] = stbi__div16(3*t0 + t1 + 8);
3411*4882a593Smuzhiyun       out[i*2  ] = stbi__div16(3*t1 + t0 + 8);
3412*4882a593Smuzhiyun    }
3413*4882a593Smuzhiyun    out[w*2-1] = stbi__div4(t1+2);
3414*4882a593Smuzhiyun 
3415*4882a593Smuzhiyun    STBI_NOTUSED(hs);
3416*4882a593Smuzhiyun 
3417*4882a593Smuzhiyun    return out;
3418*4882a593Smuzhiyun }
3419*4882a593Smuzhiyun #endif
3420*4882a593Smuzhiyun 
stbi__resample_row_generic(stbi_uc * out,stbi_uc * in_near,stbi_uc * in_far,int w,int hs)3421*4882a593Smuzhiyun static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
3422*4882a593Smuzhiyun {
3423*4882a593Smuzhiyun    // resample with nearest-neighbor
3424*4882a593Smuzhiyun    int i,j;
3425*4882a593Smuzhiyun    STBI_NOTUSED(in_far);
3426*4882a593Smuzhiyun    for (i=0; i < w; ++i)
3427*4882a593Smuzhiyun       for (j=0; j < hs; ++j)
3428*4882a593Smuzhiyun          out[i*hs+j] = in_near[i];
3429*4882a593Smuzhiyun    return out;
3430*4882a593Smuzhiyun }
3431*4882a593Smuzhiyun 
3432*4882a593Smuzhiyun // this is a reduced-precision calculation of YCbCr-to-RGB introduced
3433*4882a593Smuzhiyun // to make sure the code produces the same results in both SIMD and scalar
3434*4882a593Smuzhiyun #define stbi__float2fixed(x)  (((int) ((x) * 4096.0f + 0.5f)) << 8)
stbi__YCbCr_to_RGB_row(stbi_uc * out,const stbi_uc * y,const stbi_uc * pcb,const stbi_uc * pcr,int count,int step)3435*4882a593Smuzhiyun static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
3436*4882a593Smuzhiyun {
3437*4882a593Smuzhiyun    int i;
3438*4882a593Smuzhiyun    for (i=0; i < count; ++i) {
3439*4882a593Smuzhiyun       int y_fixed = (y[i] << 20) + (1<<19); // rounding
3440*4882a593Smuzhiyun       int r,g,b;
3441*4882a593Smuzhiyun       int cr = pcr[i] - 128;
3442*4882a593Smuzhiyun       int cb = pcb[i] - 128;
3443*4882a593Smuzhiyun       r = y_fixed +  cr* stbi__float2fixed(1.40200f);
3444*4882a593Smuzhiyun       g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
3445*4882a593Smuzhiyun       b = y_fixed                                     +   cb* stbi__float2fixed(1.77200f);
3446*4882a593Smuzhiyun       r >>= 20;
3447*4882a593Smuzhiyun       g >>= 20;
3448*4882a593Smuzhiyun       b >>= 20;
3449*4882a593Smuzhiyun       if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
3450*4882a593Smuzhiyun       if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
3451*4882a593Smuzhiyun       if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
3452*4882a593Smuzhiyun       out[0] = (stbi_uc)r;
3453*4882a593Smuzhiyun       out[1] = (stbi_uc)g;
3454*4882a593Smuzhiyun       out[2] = (stbi_uc)b;
3455*4882a593Smuzhiyun       out[3] = 255;
3456*4882a593Smuzhiyun       out += step;
3457*4882a593Smuzhiyun    }
3458*4882a593Smuzhiyun }
3459*4882a593Smuzhiyun 
3460*4882a593Smuzhiyun #if defined(STBI_SSE2) || defined(STBI_NEON)
stbi__YCbCr_to_RGB_simd(stbi_uc * out,stbi_uc const * y,stbi_uc const * pcb,stbi_uc const * pcr,int count,int step)3461*4882a593Smuzhiyun static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step)
3462*4882a593Smuzhiyun {
3463*4882a593Smuzhiyun    int i = 0;
3464*4882a593Smuzhiyun 
3465*4882a593Smuzhiyun #ifdef STBI_SSE2
3466*4882a593Smuzhiyun    // step == 3 is pretty ugly on the final interleave, and i'm not convinced
3467*4882a593Smuzhiyun    // it's useful in practice (you wouldn't use it for textures, for example).
3468*4882a593Smuzhiyun    // so just accelerate step == 4 case.
3469*4882a593Smuzhiyun    if (step == 4) {
3470*4882a593Smuzhiyun       // this is a fairly straightforward implementation and not super-optimized.
3471*4882a593Smuzhiyun       __m128i signflip  = _mm_set1_epi8(-0x80);
3472*4882a593Smuzhiyun       __m128i cr_const0 = _mm_set1_epi16(   (short) ( 1.40200f*4096.0f+0.5f));
3473*4882a593Smuzhiyun       __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f));
3474*4882a593Smuzhiyun       __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f));
3475*4882a593Smuzhiyun       __m128i cb_const1 = _mm_set1_epi16(   (short) ( 1.77200f*4096.0f+0.5f));
3476*4882a593Smuzhiyun       __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128);
3477*4882a593Smuzhiyun       __m128i xw = _mm_set1_epi16(255); // alpha channel
3478*4882a593Smuzhiyun 
3479*4882a593Smuzhiyun       for (; i+7 < count; i += 8) {
3480*4882a593Smuzhiyun          // load
3481*4882a593Smuzhiyun          __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i));
3482*4882a593Smuzhiyun          __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i));
3483*4882a593Smuzhiyun          __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i));
3484*4882a593Smuzhiyun          __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128
3485*4882a593Smuzhiyun          __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128
3486*4882a593Smuzhiyun 
3487*4882a593Smuzhiyun          // unpack to short (and left-shift cr, cb by 8)
3488*4882a593Smuzhiyun          __m128i yw  = _mm_unpacklo_epi8(y_bias, y_bytes);
3489*4882a593Smuzhiyun          __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased);
3490*4882a593Smuzhiyun          __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased);
3491*4882a593Smuzhiyun 
3492*4882a593Smuzhiyun          // color transform
3493*4882a593Smuzhiyun          __m128i yws = _mm_srli_epi16(yw, 4);
3494*4882a593Smuzhiyun          __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw);
3495*4882a593Smuzhiyun          __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw);
3496*4882a593Smuzhiyun          __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1);
3497*4882a593Smuzhiyun          __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1);
3498*4882a593Smuzhiyun          __m128i rws = _mm_add_epi16(cr0, yws);
3499*4882a593Smuzhiyun          __m128i gwt = _mm_add_epi16(cb0, yws);
3500*4882a593Smuzhiyun          __m128i bws = _mm_add_epi16(yws, cb1);
3501*4882a593Smuzhiyun          __m128i gws = _mm_add_epi16(gwt, cr1);
3502*4882a593Smuzhiyun 
3503*4882a593Smuzhiyun          // descale
3504*4882a593Smuzhiyun          __m128i rw = _mm_srai_epi16(rws, 4);
3505*4882a593Smuzhiyun          __m128i bw = _mm_srai_epi16(bws, 4);
3506*4882a593Smuzhiyun          __m128i gw = _mm_srai_epi16(gws, 4);
3507*4882a593Smuzhiyun 
3508*4882a593Smuzhiyun          // back to byte, set up for transpose
3509*4882a593Smuzhiyun          __m128i brb = _mm_packus_epi16(rw, bw);
3510*4882a593Smuzhiyun          __m128i gxb = _mm_packus_epi16(gw, xw);
3511*4882a593Smuzhiyun 
3512*4882a593Smuzhiyun          // transpose to interleave channels
3513*4882a593Smuzhiyun          __m128i t0 = _mm_unpacklo_epi8(brb, gxb);
3514*4882a593Smuzhiyun          __m128i t1 = _mm_unpackhi_epi8(brb, gxb);
3515*4882a593Smuzhiyun          __m128i o0 = _mm_unpacklo_epi16(t0, t1);
3516*4882a593Smuzhiyun          __m128i o1 = _mm_unpackhi_epi16(t0, t1);
3517*4882a593Smuzhiyun 
3518*4882a593Smuzhiyun          // store
3519*4882a593Smuzhiyun          _mm_storeu_si128((__m128i *) (out + 0), o0);
3520*4882a593Smuzhiyun          _mm_storeu_si128((__m128i *) (out + 16), o1);
3521*4882a593Smuzhiyun          out += 32;
3522*4882a593Smuzhiyun       }
3523*4882a593Smuzhiyun    }
3524*4882a593Smuzhiyun #endif
3525*4882a593Smuzhiyun 
3526*4882a593Smuzhiyun #ifdef STBI_NEON
3527*4882a593Smuzhiyun    // in this version, step=3 support would be easy to add. but is there demand?
3528*4882a593Smuzhiyun    if (step == 4) {
3529*4882a593Smuzhiyun       // this is a fairly straightforward implementation and not super-optimized.
3530*4882a593Smuzhiyun       uint8x8_t signflip = vdup_n_u8(0x80);
3531*4882a593Smuzhiyun       int16x8_t cr_const0 = vdupq_n_s16(   (short) ( 1.40200f*4096.0f+0.5f));
3532*4882a593Smuzhiyun       int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f));
3533*4882a593Smuzhiyun       int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f));
3534*4882a593Smuzhiyun       int16x8_t cb_const1 = vdupq_n_s16(   (short) ( 1.77200f*4096.0f+0.5f));
3535*4882a593Smuzhiyun 
3536*4882a593Smuzhiyun       for (; i+7 < count; i += 8) {
3537*4882a593Smuzhiyun          // load
3538*4882a593Smuzhiyun          uint8x8_t y_bytes  = vld1_u8(y + i);
3539*4882a593Smuzhiyun          uint8x8_t cr_bytes = vld1_u8(pcr + i);
3540*4882a593Smuzhiyun          uint8x8_t cb_bytes = vld1_u8(pcb + i);
3541*4882a593Smuzhiyun          int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip));
3542*4882a593Smuzhiyun          int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip));
3543*4882a593Smuzhiyun 
3544*4882a593Smuzhiyun          // expand to s16
3545*4882a593Smuzhiyun          int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4));
3546*4882a593Smuzhiyun          int16x8_t crw = vshll_n_s8(cr_biased, 7);
3547*4882a593Smuzhiyun          int16x8_t cbw = vshll_n_s8(cb_biased, 7);
3548*4882a593Smuzhiyun 
3549*4882a593Smuzhiyun          // color transform
3550*4882a593Smuzhiyun          int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0);
3551*4882a593Smuzhiyun          int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0);
3552*4882a593Smuzhiyun          int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1);
3553*4882a593Smuzhiyun          int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1);
3554*4882a593Smuzhiyun          int16x8_t rws = vaddq_s16(yws, cr0);
3555*4882a593Smuzhiyun          int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1);
3556*4882a593Smuzhiyun          int16x8_t bws = vaddq_s16(yws, cb1);
3557*4882a593Smuzhiyun 
3558*4882a593Smuzhiyun          // undo scaling, round, convert to byte
3559*4882a593Smuzhiyun          uint8x8x4_t o;
3560*4882a593Smuzhiyun          o.val[0] = vqrshrun_n_s16(rws, 4);
3561*4882a593Smuzhiyun          o.val[1] = vqrshrun_n_s16(gws, 4);
3562*4882a593Smuzhiyun          o.val[2] = vqrshrun_n_s16(bws, 4);
3563*4882a593Smuzhiyun          o.val[3] = vdup_n_u8(255);
3564*4882a593Smuzhiyun 
3565*4882a593Smuzhiyun          // store, interleaving r/g/b/a
3566*4882a593Smuzhiyun          vst4_u8(out, o);
3567*4882a593Smuzhiyun          out += 8*4;
3568*4882a593Smuzhiyun       }
3569*4882a593Smuzhiyun    }
3570*4882a593Smuzhiyun #endif
3571*4882a593Smuzhiyun 
3572*4882a593Smuzhiyun    for (; i < count; ++i) {
3573*4882a593Smuzhiyun       int y_fixed = (y[i] << 20) + (1<<19); // rounding
3574*4882a593Smuzhiyun       int r,g,b;
3575*4882a593Smuzhiyun       int cr = pcr[i] - 128;
3576*4882a593Smuzhiyun       int cb = pcb[i] - 128;
3577*4882a593Smuzhiyun       r = y_fixed + cr* stbi__float2fixed(1.40200f);
3578*4882a593Smuzhiyun       g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
3579*4882a593Smuzhiyun       b = y_fixed                                   +   cb* stbi__float2fixed(1.77200f);
3580*4882a593Smuzhiyun       r >>= 20;
3581*4882a593Smuzhiyun       g >>= 20;
3582*4882a593Smuzhiyun       b >>= 20;
3583*4882a593Smuzhiyun       if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
3584*4882a593Smuzhiyun       if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
3585*4882a593Smuzhiyun       if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
3586*4882a593Smuzhiyun       out[0] = (stbi_uc)r;
3587*4882a593Smuzhiyun       out[1] = (stbi_uc)g;
3588*4882a593Smuzhiyun       out[2] = (stbi_uc)b;
3589*4882a593Smuzhiyun       out[3] = 255;
3590*4882a593Smuzhiyun       out += step;
3591*4882a593Smuzhiyun    }
3592*4882a593Smuzhiyun }
3593*4882a593Smuzhiyun #endif
3594*4882a593Smuzhiyun 
3595*4882a593Smuzhiyun // set up the kernels
stbi__setup_jpeg(stbi__jpeg * j)3596*4882a593Smuzhiyun static void stbi__setup_jpeg(stbi__jpeg *j)
3597*4882a593Smuzhiyun {
3598*4882a593Smuzhiyun    j->idct_block_kernel = stbi__idct_block;
3599*4882a593Smuzhiyun    j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row;
3600*4882a593Smuzhiyun    j->resample_row_hv_2_kernel = stbi__resample_row_hv_2;
3601*4882a593Smuzhiyun 
3602*4882a593Smuzhiyun #ifdef STBI_SSE2
3603*4882a593Smuzhiyun    if (stbi__sse2_available()) {
3604*4882a593Smuzhiyun       j->idct_block_kernel = stbi__idct_simd;
3605*4882a593Smuzhiyun       j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
3606*4882a593Smuzhiyun       j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
3607*4882a593Smuzhiyun    }
3608*4882a593Smuzhiyun #endif
3609*4882a593Smuzhiyun 
3610*4882a593Smuzhiyun #ifdef STBI_NEON
3611*4882a593Smuzhiyun    j->idct_block_kernel = stbi__idct_simd;
3612*4882a593Smuzhiyun    j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
3613*4882a593Smuzhiyun    j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
3614*4882a593Smuzhiyun #endif
3615*4882a593Smuzhiyun }
3616*4882a593Smuzhiyun 
3617*4882a593Smuzhiyun // clean up the temporary component buffers
stbi__cleanup_jpeg(stbi__jpeg * j)3618*4882a593Smuzhiyun static void stbi__cleanup_jpeg(stbi__jpeg *j)
3619*4882a593Smuzhiyun {
3620*4882a593Smuzhiyun    stbi__free_jpeg_components(j, j->s->img_n, 0);
3621*4882a593Smuzhiyun }
3622*4882a593Smuzhiyun 
3623*4882a593Smuzhiyun typedef struct
3624*4882a593Smuzhiyun {
3625*4882a593Smuzhiyun    resample_row_func resample;
3626*4882a593Smuzhiyun    stbi_uc *line0,*line1;
3627*4882a593Smuzhiyun    int hs,vs;   // expansion factor in each axis
3628*4882a593Smuzhiyun    int w_lores; // horizontal pixels pre-expansion
3629*4882a593Smuzhiyun    int ystep;   // how far through vertical expansion we are
3630*4882a593Smuzhiyun    int ypos;    // which pre-expansion row we're on
3631*4882a593Smuzhiyun } stbi__resample;
3632*4882a593Smuzhiyun 
3633*4882a593Smuzhiyun // fast 0..255 * 0..255 => 0..255 rounded multiplication
stbi__blinn_8x8(stbi_uc x,stbi_uc y)3634*4882a593Smuzhiyun static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y)
3635*4882a593Smuzhiyun {
3636*4882a593Smuzhiyun    unsigned int t = x*y + 128;
3637*4882a593Smuzhiyun    return (stbi_uc) ((t + (t >>8)) >> 8);
3638*4882a593Smuzhiyun }
3639*4882a593Smuzhiyun 
load_jpeg_image(stbi__jpeg * z,int * out_x,int * out_y,int * comp,int req_comp)3640*4882a593Smuzhiyun static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
3641*4882a593Smuzhiyun {
3642*4882a593Smuzhiyun    int n, decode_n, is_rgb;
3643*4882a593Smuzhiyun    z->s->img_n = 0; // make stbi__cleanup_jpeg safe
3644*4882a593Smuzhiyun 
3645*4882a593Smuzhiyun    // validate req_comp
3646*4882a593Smuzhiyun    if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
3647*4882a593Smuzhiyun 
3648*4882a593Smuzhiyun    // load a jpeg image from whichever source, but leave in YCbCr format
3649*4882a593Smuzhiyun    if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
3650*4882a593Smuzhiyun 
3651*4882a593Smuzhiyun    // determine actual number of components to generate
3652*4882a593Smuzhiyun    n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
3653*4882a593Smuzhiyun 
3654*4882a593Smuzhiyun    is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
3655*4882a593Smuzhiyun 
3656*4882a593Smuzhiyun    if (z->s->img_n == 3 && n < 3 && !is_rgb)
3657*4882a593Smuzhiyun       decode_n = 1;
3658*4882a593Smuzhiyun    else
3659*4882a593Smuzhiyun       decode_n = z->s->img_n;
3660*4882a593Smuzhiyun 
3661*4882a593Smuzhiyun    // resample and color-convert
3662*4882a593Smuzhiyun    {
3663*4882a593Smuzhiyun       int k;
3664*4882a593Smuzhiyun       unsigned int i,j;
3665*4882a593Smuzhiyun       stbi_uc *output;
3666*4882a593Smuzhiyun       stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL };
3667*4882a593Smuzhiyun 
3668*4882a593Smuzhiyun       stbi__resample res_comp[4];
3669*4882a593Smuzhiyun 
3670*4882a593Smuzhiyun       for (k=0; k < decode_n; ++k) {
3671*4882a593Smuzhiyun          stbi__resample *r = &res_comp[k];
3672*4882a593Smuzhiyun 
3673*4882a593Smuzhiyun          // allocate line buffer big enough for upsampling off the edges
3674*4882a593Smuzhiyun          // with upsample factor of 4
3675*4882a593Smuzhiyun          z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3);
3676*4882a593Smuzhiyun          if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
3677*4882a593Smuzhiyun 
3678*4882a593Smuzhiyun          r->hs      = z->img_h_max / z->img_comp[k].h;
3679*4882a593Smuzhiyun          r->vs      = z->img_v_max / z->img_comp[k].v;
3680*4882a593Smuzhiyun          r->ystep   = r->vs >> 1;
3681*4882a593Smuzhiyun          r->w_lores = (z->s->img_x + r->hs-1) / r->hs;
3682*4882a593Smuzhiyun          r->ypos    = 0;
3683*4882a593Smuzhiyun          r->line0   = r->line1 = z->img_comp[k].data;
3684*4882a593Smuzhiyun 
3685*4882a593Smuzhiyun          if      (r->hs == 1 && r->vs == 1) r->resample = resample_row_1;
3686*4882a593Smuzhiyun          else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2;
3687*4882a593Smuzhiyun          else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2;
3688*4882a593Smuzhiyun          else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel;
3689*4882a593Smuzhiyun          else                               r->resample = stbi__resample_row_generic;
3690*4882a593Smuzhiyun       }
3691*4882a593Smuzhiyun 
3692*4882a593Smuzhiyun       // can't error after this so, this is safe
3693*4882a593Smuzhiyun       output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1);
3694*4882a593Smuzhiyun       if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
3695*4882a593Smuzhiyun 
3696*4882a593Smuzhiyun       // now go ahead and resample
3697*4882a593Smuzhiyun       for (j=0; j < z->s->img_y; ++j) {
3698*4882a593Smuzhiyun          stbi_uc *out = output + n * z->s->img_x * j;
3699*4882a593Smuzhiyun          for (k=0; k < decode_n; ++k) {
3700*4882a593Smuzhiyun             stbi__resample *r = &res_comp[k];
3701*4882a593Smuzhiyun             int y_bot = r->ystep >= (r->vs >> 1);
3702*4882a593Smuzhiyun             coutput[k] = r->resample(z->img_comp[k].linebuf,
3703*4882a593Smuzhiyun                                      y_bot ? r->line1 : r->line0,
3704*4882a593Smuzhiyun                                      y_bot ? r->line0 : r->line1,
3705*4882a593Smuzhiyun                                      r->w_lores, r->hs);
3706*4882a593Smuzhiyun             if (++r->ystep >= r->vs) {
3707*4882a593Smuzhiyun                r->ystep = 0;
3708*4882a593Smuzhiyun                r->line0 = r->line1;
3709*4882a593Smuzhiyun                if (++r->ypos < z->img_comp[k].y)
3710*4882a593Smuzhiyun                   r->line1 += z->img_comp[k].w2;
3711*4882a593Smuzhiyun             }
3712*4882a593Smuzhiyun          }
3713*4882a593Smuzhiyun          if (n >= 3) {
3714*4882a593Smuzhiyun             stbi_uc *y = coutput[0];
3715*4882a593Smuzhiyun             if (z->s->img_n == 3) {
3716*4882a593Smuzhiyun                if (is_rgb) {
3717*4882a593Smuzhiyun                   for (i=0; i < z->s->img_x; ++i) {
3718*4882a593Smuzhiyun                      out[0] = y[i];
3719*4882a593Smuzhiyun                      out[1] = coutput[1][i];
3720*4882a593Smuzhiyun                      out[2] = coutput[2][i];
3721*4882a593Smuzhiyun                      out[3] = 255;
3722*4882a593Smuzhiyun                      out += n;
3723*4882a593Smuzhiyun                   }
3724*4882a593Smuzhiyun                } else {
3725*4882a593Smuzhiyun                   z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
3726*4882a593Smuzhiyun                }
3727*4882a593Smuzhiyun             } else if (z->s->img_n == 4) {
3728*4882a593Smuzhiyun                if (z->app14_color_transform == 0) { // CMYK
3729*4882a593Smuzhiyun                   for (i=0; i < z->s->img_x; ++i) {
3730*4882a593Smuzhiyun                      stbi_uc m = coutput[3][i];
3731*4882a593Smuzhiyun                      out[0] = stbi__blinn_8x8(coutput[0][i], m);
3732*4882a593Smuzhiyun                      out[1] = stbi__blinn_8x8(coutput[1][i], m);
3733*4882a593Smuzhiyun                      out[2] = stbi__blinn_8x8(coutput[2][i], m);
3734*4882a593Smuzhiyun                      out[3] = 255;
3735*4882a593Smuzhiyun                      out += n;
3736*4882a593Smuzhiyun                   }
3737*4882a593Smuzhiyun                } else if (z->app14_color_transform == 2) { // YCCK
3738*4882a593Smuzhiyun                   z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
3739*4882a593Smuzhiyun                   for (i=0; i < z->s->img_x; ++i) {
3740*4882a593Smuzhiyun                      stbi_uc m = coutput[3][i];
3741*4882a593Smuzhiyun                      out[0] = stbi__blinn_8x8(255 - out[0], m);
3742*4882a593Smuzhiyun                      out[1] = stbi__blinn_8x8(255 - out[1], m);
3743*4882a593Smuzhiyun                      out[2] = stbi__blinn_8x8(255 - out[2], m);
3744*4882a593Smuzhiyun                      out += n;
3745*4882a593Smuzhiyun                   }
3746*4882a593Smuzhiyun                } else { // YCbCr + alpha?  Ignore the fourth channel for now
3747*4882a593Smuzhiyun                   z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
3748*4882a593Smuzhiyun                }
3749*4882a593Smuzhiyun             } else
3750*4882a593Smuzhiyun                for (i=0; i < z->s->img_x; ++i) {
3751*4882a593Smuzhiyun                   out[0] = out[1] = out[2] = y[i];
3752*4882a593Smuzhiyun                   out[3] = 255; // not used if n==3
3753*4882a593Smuzhiyun                   out += n;
3754*4882a593Smuzhiyun                }
3755*4882a593Smuzhiyun          } else {
3756*4882a593Smuzhiyun             if (is_rgb) {
3757*4882a593Smuzhiyun                if (n == 1)
3758*4882a593Smuzhiyun                   for (i=0; i < z->s->img_x; ++i)
3759*4882a593Smuzhiyun                      *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
3760*4882a593Smuzhiyun                else {
3761*4882a593Smuzhiyun                   for (i=0; i < z->s->img_x; ++i, out += 2) {
3762*4882a593Smuzhiyun                      out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
3763*4882a593Smuzhiyun                      out[1] = 255;
3764*4882a593Smuzhiyun                   }
3765*4882a593Smuzhiyun                }
3766*4882a593Smuzhiyun             } else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
3767*4882a593Smuzhiyun                for (i=0; i < z->s->img_x; ++i) {
3768*4882a593Smuzhiyun                   stbi_uc m = coutput[3][i];
3769*4882a593Smuzhiyun                   stbi_uc r = stbi__blinn_8x8(coutput[0][i], m);
3770*4882a593Smuzhiyun                   stbi_uc g = stbi__blinn_8x8(coutput[1][i], m);
3771*4882a593Smuzhiyun                   stbi_uc b = stbi__blinn_8x8(coutput[2][i], m);
3772*4882a593Smuzhiyun                   out[0] = stbi__compute_y(r, g, b);
3773*4882a593Smuzhiyun                   out[1] = 255;
3774*4882a593Smuzhiyun                   out += n;
3775*4882a593Smuzhiyun                }
3776*4882a593Smuzhiyun             } else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
3777*4882a593Smuzhiyun                for (i=0; i < z->s->img_x; ++i) {
3778*4882a593Smuzhiyun                   out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
3779*4882a593Smuzhiyun                   out[1] = 255;
3780*4882a593Smuzhiyun                   out += n;
3781*4882a593Smuzhiyun                }
3782*4882a593Smuzhiyun             } else {
3783*4882a593Smuzhiyun                stbi_uc *y = coutput[0];
3784*4882a593Smuzhiyun                if (n == 1)
3785*4882a593Smuzhiyun                   for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
3786*4882a593Smuzhiyun                else
3787*4882a593Smuzhiyun                   for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; }
3788*4882a593Smuzhiyun             }
3789*4882a593Smuzhiyun          }
3790*4882a593Smuzhiyun       }
3791*4882a593Smuzhiyun       stbi__cleanup_jpeg(z);
3792*4882a593Smuzhiyun       *out_x = z->s->img_x;
3793*4882a593Smuzhiyun       *out_y = z->s->img_y;
3794*4882a593Smuzhiyun       if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
3795*4882a593Smuzhiyun       return output;
3796*4882a593Smuzhiyun    }
3797*4882a593Smuzhiyun }
3798*4882a593Smuzhiyun 
stbi__jpeg_load(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri)3799*4882a593Smuzhiyun static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
3800*4882a593Smuzhiyun {
3801*4882a593Smuzhiyun    unsigned char* result;
3802*4882a593Smuzhiyun    stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
3803*4882a593Smuzhiyun    STBI_NOTUSED(ri);
3804*4882a593Smuzhiyun    j->s = s;
3805*4882a593Smuzhiyun    stbi__setup_jpeg(j);
3806*4882a593Smuzhiyun    result = load_jpeg_image(j, x,y,comp,req_comp);
3807*4882a593Smuzhiyun    STBI_FREE(j);
3808*4882a593Smuzhiyun    return result;
3809*4882a593Smuzhiyun }
3810*4882a593Smuzhiyun 
stbi__jpeg_test(stbi__context * s)3811*4882a593Smuzhiyun static int stbi__jpeg_test(stbi__context *s)
3812*4882a593Smuzhiyun {
3813*4882a593Smuzhiyun    int r;
3814*4882a593Smuzhiyun    stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
3815*4882a593Smuzhiyun    j->s = s;
3816*4882a593Smuzhiyun    stbi__setup_jpeg(j);
3817*4882a593Smuzhiyun    r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
3818*4882a593Smuzhiyun    stbi__rewind(s);
3819*4882a593Smuzhiyun    STBI_FREE(j);
3820*4882a593Smuzhiyun    return r;
3821*4882a593Smuzhiyun }
3822*4882a593Smuzhiyun 
stbi__jpeg_info_raw(stbi__jpeg * j,int * x,int * y,int * comp)3823*4882a593Smuzhiyun static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
3824*4882a593Smuzhiyun {
3825*4882a593Smuzhiyun    if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) {
3826*4882a593Smuzhiyun       stbi__rewind( j->s );
3827*4882a593Smuzhiyun       return 0;
3828*4882a593Smuzhiyun    }
3829*4882a593Smuzhiyun    if (x) *x = j->s->img_x;
3830*4882a593Smuzhiyun    if (y) *y = j->s->img_y;
3831*4882a593Smuzhiyun    if (comp) *comp = j->s->img_n >= 3 ? 3 : 1;
3832*4882a593Smuzhiyun    return 1;
3833*4882a593Smuzhiyun }
3834*4882a593Smuzhiyun 
stbi__jpeg_info(stbi__context * s,int * x,int * y,int * comp)3835*4882a593Smuzhiyun static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
3836*4882a593Smuzhiyun {
3837*4882a593Smuzhiyun    int result;
3838*4882a593Smuzhiyun    stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
3839*4882a593Smuzhiyun    j->s = s;
3840*4882a593Smuzhiyun    result = stbi__jpeg_info_raw(j, x, y, comp);
3841*4882a593Smuzhiyun    STBI_FREE(j);
3842*4882a593Smuzhiyun    return result;
3843*4882a593Smuzhiyun }
3844*4882a593Smuzhiyun #endif
3845*4882a593Smuzhiyun 
3846*4882a593Smuzhiyun // public domain zlib decode    v0.2  Sean Barrett 2006-11-18
3847*4882a593Smuzhiyun //    simple implementation
3848*4882a593Smuzhiyun //      - all input must be provided in an upfront buffer
3849*4882a593Smuzhiyun //      - all output is written to a single output buffer (can malloc/realloc)
3850*4882a593Smuzhiyun //    performance
3851*4882a593Smuzhiyun //      - fast huffman
3852*4882a593Smuzhiyun 
3853*4882a593Smuzhiyun #ifndef STBI_NO_ZLIB
3854*4882a593Smuzhiyun 
3855*4882a593Smuzhiyun // fast-way is faster to check than jpeg huffman, but slow way is slower
3856*4882a593Smuzhiyun #define STBI__ZFAST_BITS  9 // accelerate all cases in default tables
3857*4882a593Smuzhiyun #define STBI__ZFAST_MASK  ((1 << STBI__ZFAST_BITS) - 1)
3858*4882a593Smuzhiyun 
3859*4882a593Smuzhiyun // zlib-style huffman encoding
3860*4882a593Smuzhiyun // (jpegs packs from left, zlib from right, so can't share code)
3861*4882a593Smuzhiyun typedef struct
3862*4882a593Smuzhiyun {
3863*4882a593Smuzhiyun    stbi__uint16 fast[1 << STBI__ZFAST_BITS];
3864*4882a593Smuzhiyun    stbi__uint16 firstcode[16];
3865*4882a593Smuzhiyun    int maxcode[17];
3866*4882a593Smuzhiyun    stbi__uint16 firstsymbol[16];
3867*4882a593Smuzhiyun    stbi_uc  size[288];
3868*4882a593Smuzhiyun    stbi__uint16 value[288];
3869*4882a593Smuzhiyun } stbi__zhuffman;
3870*4882a593Smuzhiyun 
stbi__bitreverse16(int n)3871*4882a593Smuzhiyun stbi_inline static int stbi__bitreverse16(int n)
3872*4882a593Smuzhiyun {
3873*4882a593Smuzhiyun   n = ((n & 0xAAAA) >>  1) | ((n & 0x5555) << 1);
3874*4882a593Smuzhiyun   n = ((n & 0xCCCC) >>  2) | ((n & 0x3333) << 2);
3875*4882a593Smuzhiyun   n = ((n & 0xF0F0) >>  4) | ((n & 0x0F0F) << 4);
3876*4882a593Smuzhiyun   n = ((n & 0xFF00) >>  8) | ((n & 0x00FF) << 8);
3877*4882a593Smuzhiyun   return n;
3878*4882a593Smuzhiyun }
3879*4882a593Smuzhiyun 
stbi__bit_reverse(int v,int bits)3880*4882a593Smuzhiyun stbi_inline static int stbi__bit_reverse(int v, int bits)
3881*4882a593Smuzhiyun {
3882*4882a593Smuzhiyun    STBI_ASSERT(bits <= 16);
3883*4882a593Smuzhiyun    // to bit reverse n bits, reverse 16 and shift
3884*4882a593Smuzhiyun    // e.g. 11 bits, bit reverse and shift away 5
3885*4882a593Smuzhiyun    return stbi__bitreverse16(v) >> (16-bits);
3886*4882a593Smuzhiyun }
3887*4882a593Smuzhiyun 
stbi__zbuild_huffman(stbi__zhuffman * z,const stbi_uc * sizelist,int num)3888*4882a593Smuzhiyun static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num)
3889*4882a593Smuzhiyun {
3890*4882a593Smuzhiyun    int i,k=0;
3891*4882a593Smuzhiyun    int code, next_code[16], sizes[17];
3892*4882a593Smuzhiyun 
3893*4882a593Smuzhiyun    // DEFLATE spec for generating codes
3894*4882a593Smuzhiyun    memset(sizes, 0, sizeof(sizes));
3895*4882a593Smuzhiyun    memset(z->fast, 0, sizeof(z->fast));
3896*4882a593Smuzhiyun    for (i=0; i < num; ++i)
3897*4882a593Smuzhiyun       ++sizes[sizelist[i]];
3898*4882a593Smuzhiyun    sizes[0] = 0;
3899*4882a593Smuzhiyun    for (i=1; i < 16; ++i)
3900*4882a593Smuzhiyun       if (sizes[i] > (1 << i))
3901*4882a593Smuzhiyun          return stbi__err("bad sizes", "Corrupt PNG");
3902*4882a593Smuzhiyun    code = 0;
3903*4882a593Smuzhiyun    for (i=1; i < 16; ++i) {
3904*4882a593Smuzhiyun       next_code[i] = code;
3905*4882a593Smuzhiyun       z->firstcode[i] = (stbi__uint16) code;
3906*4882a593Smuzhiyun       z->firstsymbol[i] = (stbi__uint16) k;
3907*4882a593Smuzhiyun       code = (code + sizes[i]);
3908*4882a593Smuzhiyun       if (sizes[i])
3909*4882a593Smuzhiyun          if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG");
3910*4882a593Smuzhiyun       z->maxcode[i] = code << (16-i); // preshift for inner loop
3911*4882a593Smuzhiyun       code <<= 1;
3912*4882a593Smuzhiyun       k += sizes[i];
3913*4882a593Smuzhiyun    }
3914*4882a593Smuzhiyun    z->maxcode[16] = 0x10000; // sentinel
3915*4882a593Smuzhiyun    for (i=0; i < num; ++i) {
3916*4882a593Smuzhiyun       int s = sizelist[i];
3917*4882a593Smuzhiyun       if (s) {
3918*4882a593Smuzhiyun          int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s];
3919*4882a593Smuzhiyun          stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i);
3920*4882a593Smuzhiyun          z->size [c] = (stbi_uc     ) s;
3921*4882a593Smuzhiyun          z->value[c] = (stbi__uint16) i;
3922*4882a593Smuzhiyun          if (s <= STBI__ZFAST_BITS) {
3923*4882a593Smuzhiyun             int j = stbi__bit_reverse(next_code[s],s);
3924*4882a593Smuzhiyun             while (j < (1 << STBI__ZFAST_BITS)) {
3925*4882a593Smuzhiyun                z->fast[j] = fastv;
3926*4882a593Smuzhiyun                j += (1 << s);
3927*4882a593Smuzhiyun             }
3928*4882a593Smuzhiyun          }
3929*4882a593Smuzhiyun          ++next_code[s];
3930*4882a593Smuzhiyun       }
3931*4882a593Smuzhiyun    }
3932*4882a593Smuzhiyun    return 1;
3933*4882a593Smuzhiyun }
3934*4882a593Smuzhiyun 
3935*4882a593Smuzhiyun // zlib-from-memory implementation for PNG reading
3936*4882a593Smuzhiyun //    because PNG allows splitting the zlib stream arbitrarily,
3937*4882a593Smuzhiyun //    and it's annoying structurally to have PNG call ZLIB call PNG,
3938*4882a593Smuzhiyun //    we require PNG read all the IDATs and combine them into a single
3939*4882a593Smuzhiyun //    memory buffer
3940*4882a593Smuzhiyun 
3941*4882a593Smuzhiyun typedef struct
3942*4882a593Smuzhiyun {
3943*4882a593Smuzhiyun    stbi_uc *zbuffer, *zbuffer_end;
3944*4882a593Smuzhiyun    int num_bits;
3945*4882a593Smuzhiyun    stbi__uint32 code_buffer;
3946*4882a593Smuzhiyun 
3947*4882a593Smuzhiyun    char *zout;
3948*4882a593Smuzhiyun    char *zout_start;
3949*4882a593Smuzhiyun    char *zout_end;
3950*4882a593Smuzhiyun    int   z_expandable;
3951*4882a593Smuzhiyun 
3952*4882a593Smuzhiyun    stbi__zhuffman z_length, z_distance;
3953*4882a593Smuzhiyun } stbi__zbuf;
3954*4882a593Smuzhiyun 
stbi__zget8(stbi__zbuf * z)3955*4882a593Smuzhiyun stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
3956*4882a593Smuzhiyun {
3957*4882a593Smuzhiyun    if (z->zbuffer >= z->zbuffer_end) return 0;
3958*4882a593Smuzhiyun    return *z->zbuffer++;
3959*4882a593Smuzhiyun }
3960*4882a593Smuzhiyun 
stbi__fill_bits(stbi__zbuf * z)3961*4882a593Smuzhiyun static void stbi__fill_bits(stbi__zbuf *z)
3962*4882a593Smuzhiyun {
3963*4882a593Smuzhiyun    do {
3964*4882a593Smuzhiyun       STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
3965*4882a593Smuzhiyun       z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
3966*4882a593Smuzhiyun       z->num_bits += 8;
3967*4882a593Smuzhiyun    } while (z->num_bits <= 24);
3968*4882a593Smuzhiyun }
3969*4882a593Smuzhiyun 
stbi__zreceive(stbi__zbuf * z,int n)3970*4882a593Smuzhiyun stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n)
3971*4882a593Smuzhiyun {
3972*4882a593Smuzhiyun    unsigned int k;
3973*4882a593Smuzhiyun    if (z->num_bits < n) stbi__fill_bits(z);
3974*4882a593Smuzhiyun    k = z->code_buffer & ((1 << n) - 1);
3975*4882a593Smuzhiyun    z->code_buffer >>= n;
3976*4882a593Smuzhiyun    z->num_bits -= n;
3977*4882a593Smuzhiyun    return k;
3978*4882a593Smuzhiyun }
3979*4882a593Smuzhiyun 
stbi__zhuffman_decode_slowpath(stbi__zbuf * a,stbi__zhuffman * z)3980*4882a593Smuzhiyun static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
3981*4882a593Smuzhiyun {
3982*4882a593Smuzhiyun    int b,s,k;
3983*4882a593Smuzhiyun    // not resolved by fast table, so compute it the slow way
3984*4882a593Smuzhiyun    // use jpeg approach, which requires MSbits at top
3985*4882a593Smuzhiyun    k = stbi__bit_reverse(a->code_buffer, 16);
3986*4882a593Smuzhiyun    for (s=STBI__ZFAST_BITS+1; ; ++s)
3987*4882a593Smuzhiyun       if (k < z->maxcode[s])
3988*4882a593Smuzhiyun          break;
3989*4882a593Smuzhiyun    if (s == 16) return -1; // invalid code!
3990*4882a593Smuzhiyun    // code size is s, so:
3991*4882a593Smuzhiyun    b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
3992*4882a593Smuzhiyun    STBI_ASSERT(z->size[b] == s);
3993*4882a593Smuzhiyun    a->code_buffer >>= s;
3994*4882a593Smuzhiyun    a->num_bits -= s;
3995*4882a593Smuzhiyun    return z->value[b];
3996*4882a593Smuzhiyun }
3997*4882a593Smuzhiyun 
stbi__zhuffman_decode(stbi__zbuf * a,stbi__zhuffman * z)3998*4882a593Smuzhiyun stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
3999*4882a593Smuzhiyun {
4000*4882a593Smuzhiyun    int b,s;
4001*4882a593Smuzhiyun    if (a->num_bits < 16) stbi__fill_bits(a);
4002*4882a593Smuzhiyun    b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
4003*4882a593Smuzhiyun    if (b) {
4004*4882a593Smuzhiyun       s = b >> 9;
4005*4882a593Smuzhiyun       a->code_buffer >>= s;
4006*4882a593Smuzhiyun       a->num_bits -= s;
4007*4882a593Smuzhiyun       return b & 511;
4008*4882a593Smuzhiyun    }
4009*4882a593Smuzhiyun    return stbi__zhuffman_decode_slowpath(a, z);
4010*4882a593Smuzhiyun }
4011*4882a593Smuzhiyun 
stbi__zexpand(stbi__zbuf * z,char * zout,int n)4012*4882a593Smuzhiyun static int stbi__zexpand(stbi__zbuf *z, char *zout, int n)  // need to make room for n bytes
4013*4882a593Smuzhiyun {
4014*4882a593Smuzhiyun    char *q;
4015*4882a593Smuzhiyun    int cur, limit, old_limit;
4016*4882a593Smuzhiyun    z->zout = zout;
4017*4882a593Smuzhiyun    if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
4018*4882a593Smuzhiyun    cur   = (int) (z->zout     - z->zout_start);
4019*4882a593Smuzhiyun    limit = old_limit = (int) (z->zout_end - z->zout_start);
4020*4882a593Smuzhiyun    while (cur + n > limit)
4021*4882a593Smuzhiyun       limit *= 2;
4022*4882a593Smuzhiyun    q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
4023*4882a593Smuzhiyun    STBI_NOTUSED(old_limit);
4024*4882a593Smuzhiyun    if (q == NULL) return stbi__err("outofmem", "Out of memory");
4025*4882a593Smuzhiyun    z->zout_start = q;
4026*4882a593Smuzhiyun    z->zout       = q + cur;
4027*4882a593Smuzhiyun    z->zout_end   = q + limit;
4028*4882a593Smuzhiyun    return 1;
4029*4882a593Smuzhiyun }
4030*4882a593Smuzhiyun 
4031*4882a593Smuzhiyun static const int stbi__zlength_base[31] = {
4032*4882a593Smuzhiyun    3,4,5,6,7,8,9,10,11,13,
4033*4882a593Smuzhiyun    15,17,19,23,27,31,35,43,51,59,
4034*4882a593Smuzhiyun    67,83,99,115,131,163,195,227,258,0,0 };
4035*4882a593Smuzhiyun 
4036*4882a593Smuzhiyun static const int stbi__zlength_extra[31]=
4037*4882a593Smuzhiyun { 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 };
4038*4882a593Smuzhiyun 
4039*4882a593Smuzhiyun static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
4040*4882a593Smuzhiyun 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
4041*4882a593Smuzhiyun 
4042*4882a593Smuzhiyun static const int stbi__zdist_extra[32] =
4043*4882a593Smuzhiyun { 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};
4044*4882a593Smuzhiyun 
stbi__parse_huffman_block(stbi__zbuf * a)4045*4882a593Smuzhiyun static int stbi__parse_huffman_block(stbi__zbuf *a)
4046*4882a593Smuzhiyun {
4047*4882a593Smuzhiyun    char *zout = a->zout;
4048*4882a593Smuzhiyun    for(;;) {
4049*4882a593Smuzhiyun       int z = stbi__zhuffman_decode(a, &a->z_length);
4050*4882a593Smuzhiyun       if (z < 256) {
4051*4882a593Smuzhiyun          if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes
4052*4882a593Smuzhiyun          if (zout >= a->zout_end) {
4053*4882a593Smuzhiyun             if (!stbi__zexpand(a, zout, 1)) return 0;
4054*4882a593Smuzhiyun             zout = a->zout;
4055*4882a593Smuzhiyun          }
4056*4882a593Smuzhiyun          *zout++ = (char) z;
4057*4882a593Smuzhiyun       } else {
4058*4882a593Smuzhiyun          stbi_uc *p;
4059*4882a593Smuzhiyun          int len,dist;
4060*4882a593Smuzhiyun          if (z == 256) {
4061*4882a593Smuzhiyun             a->zout = zout;
4062*4882a593Smuzhiyun             return 1;
4063*4882a593Smuzhiyun          }
4064*4882a593Smuzhiyun          z -= 257;
4065*4882a593Smuzhiyun          len = stbi__zlength_base[z];
4066*4882a593Smuzhiyun          if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]);
4067*4882a593Smuzhiyun          z = stbi__zhuffman_decode(a, &a->z_distance);
4068*4882a593Smuzhiyun          if (z < 0) return stbi__err("bad huffman code","Corrupt PNG");
4069*4882a593Smuzhiyun          dist = stbi__zdist_base[z];
4070*4882a593Smuzhiyun          if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
4071*4882a593Smuzhiyun          if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
4072*4882a593Smuzhiyun          if (zout + len > a->zout_end) {
4073*4882a593Smuzhiyun             if (!stbi__zexpand(a, zout, len)) return 0;
4074*4882a593Smuzhiyun             zout = a->zout;
4075*4882a593Smuzhiyun          }
4076*4882a593Smuzhiyun          p = (stbi_uc *) (zout - dist);
4077*4882a593Smuzhiyun          if (dist == 1) { // run of one byte; common in images.
4078*4882a593Smuzhiyun             stbi_uc v = *p;
4079*4882a593Smuzhiyun             if (len) { do *zout++ = v; while (--len); }
4080*4882a593Smuzhiyun          } else {
4081*4882a593Smuzhiyun             if (len) { do *zout++ = *p++; while (--len); }
4082*4882a593Smuzhiyun          }
4083*4882a593Smuzhiyun       }
4084*4882a593Smuzhiyun    }
4085*4882a593Smuzhiyun }
4086*4882a593Smuzhiyun 
stbi__compute_huffman_codes(stbi__zbuf * a)4087*4882a593Smuzhiyun static int stbi__compute_huffman_codes(stbi__zbuf *a)
4088*4882a593Smuzhiyun {
4089*4882a593Smuzhiyun    static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
4090*4882a593Smuzhiyun    stbi__zhuffman z_codelength;
4091*4882a593Smuzhiyun    stbi_uc lencodes[286+32+137];//padding for maximum single op
4092*4882a593Smuzhiyun    stbi_uc codelength_sizes[19];
4093*4882a593Smuzhiyun    int i,n;
4094*4882a593Smuzhiyun 
4095*4882a593Smuzhiyun    int hlit  = stbi__zreceive(a,5) + 257;
4096*4882a593Smuzhiyun    int hdist = stbi__zreceive(a,5) + 1;
4097*4882a593Smuzhiyun    int hclen = stbi__zreceive(a,4) + 4;
4098*4882a593Smuzhiyun    int ntot  = hlit + hdist;
4099*4882a593Smuzhiyun 
4100*4882a593Smuzhiyun    memset(codelength_sizes, 0, sizeof(codelength_sizes));
4101*4882a593Smuzhiyun    for (i=0; i < hclen; ++i) {
4102*4882a593Smuzhiyun       int s = stbi__zreceive(a,3);
4103*4882a593Smuzhiyun       codelength_sizes[length_dezigzag[i]] = (stbi_uc) s;
4104*4882a593Smuzhiyun    }
4105*4882a593Smuzhiyun    if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0;
4106*4882a593Smuzhiyun 
4107*4882a593Smuzhiyun    n = 0;
4108*4882a593Smuzhiyun    while (n < ntot) {
4109*4882a593Smuzhiyun       int c = stbi__zhuffman_decode(a, &z_codelength);
4110*4882a593Smuzhiyun       if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG");
4111*4882a593Smuzhiyun       if (c < 16)
4112*4882a593Smuzhiyun          lencodes[n++] = (stbi_uc) c;
4113*4882a593Smuzhiyun       else {
4114*4882a593Smuzhiyun          stbi_uc fill = 0;
4115*4882a593Smuzhiyun          if (c == 16) {
4116*4882a593Smuzhiyun             c = stbi__zreceive(a,2)+3;
4117*4882a593Smuzhiyun             if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
4118*4882a593Smuzhiyun             fill = lencodes[n-1];
4119*4882a593Smuzhiyun          } else if (c == 17)
4120*4882a593Smuzhiyun             c = stbi__zreceive(a,3)+3;
4121*4882a593Smuzhiyun          else {
4122*4882a593Smuzhiyun             STBI_ASSERT(c == 18);
4123*4882a593Smuzhiyun             c = stbi__zreceive(a,7)+11;
4124*4882a593Smuzhiyun          }
4125*4882a593Smuzhiyun          if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
4126*4882a593Smuzhiyun          memset(lencodes+n, fill, c);
4127*4882a593Smuzhiyun          n += c;
4128*4882a593Smuzhiyun       }
4129*4882a593Smuzhiyun    }
4130*4882a593Smuzhiyun    if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG");
4131*4882a593Smuzhiyun    if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0;
4132*4882a593Smuzhiyun    if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0;
4133*4882a593Smuzhiyun    return 1;
4134*4882a593Smuzhiyun }
4135*4882a593Smuzhiyun 
stbi__parse_uncompressed_block(stbi__zbuf * a)4136*4882a593Smuzhiyun static int stbi__parse_uncompressed_block(stbi__zbuf *a)
4137*4882a593Smuzhiyun {
4138*4882a593Smuzhiyun    stbi_uc header[4];
4139*4882a593Smuzhiyun    int len,nlen,k;
4140*4882a593Smuzhiyun    if (a->num_bits & 7)
4141*4882a593Smuzhiyun       stbi__zreceive(a, a->num_bits & 7); // discard
4142*4882a593Smuzhiyun    // drain the bit-packed data into header
4143*4882a593Smuzhiyun    k = 0;
4144*4882a593Smuzhiyun    while (a->num_bits > 0) {
4145*4882a593Smuzhiyun       header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check
4146*4882a593Smuzhiyun       a->code_buffer >>= 8;
4147*4882a593Smuzhiyun       a->num_bits -= 8;
4148*4882a593Smuzhiyun    }
4149*4882a593Smuzhiyun    STBI_ASSERT(a->num_bits == 0);
4150*4882a593Smuzhiyun    // now fill header the normal way
4151*4882a593Smuzhiyun    while (k < 4)
4152*4882a593Smuzhiyun       header[k++] = stbi__zget8(a);
4153*4882a593Smuzhiyun    len  = header[1] * 256 + header[0];
4154*4882a593Smuzhiyun    nlen = header[3] * 256 + header[2];
4155*4882a593Smuzhiyun    if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG");
4156*4882a593Smuzhiyun    if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG");
4157*4882a593Smuzhiyun    if (a->zout + len > a->zout_end)
4158*4882a593Smuzhiyun       if (!stbi__zexpand(a, a->zout, len)) return 0;
4159*4882a593Smuzhiyun    memcpy(a->zout, a->zbuffer, len);
4160*4882a593Smuzhiyun    a->zbuffer += len;
4161*4882a593Smuzhiyun    a->zout += len;
4162*4882a593Smuzhiyun    return 1;
4163*4882a593Smuzhiyun }
4164*4882a593Smuzhiyun 
stbi__parse_zlib_header(stbi__zbuf * a)4165*4882a593Smuzhiyun static int stbi__parse_zlib_header(stbi__zbuf *a)
4166*4882a593Smuzhiyun {
4167*4882a593Smuzhiyun    int cmf   = stbi__zget8(a);
4168*4882a593Smuzhiyun    int cm    = cmf & 15;
4169*4882a593Smuzhiyun    /* int cinfo = cmf >> 4; */
4170*4882a593Smuzhiyun    int flg   = stbi__zget8(a);
4171*4882a593Smuzhiyun    if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
4172*4882a593Smuzhiyun    if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
4173*4882a593Smuzhiyun    if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
4174*4882a593Smuzhiyun    // window = 1 << (8 + cinfo)... but who cares, we fully buffer output
4175*4882a593Smuzhiyun    return 1;
4176*4882a593Smuzhiyun }
4177*4882a593Smuzhiyun 
4178*4882a593Smuzhiyun static const stbi_uc stbi__zdefault_length[288] =
4179*4882a593Smuzhiyun {
4180*4882a593Smuzhiyun    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
4181*4882a593Smuzhiyun    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
4182*4882a593Smuzhiyun    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
4183*4882a593Smuzhiyun    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
4184*4882a593Smuzhiyun    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
4185*4882a593Smuzhiyun    9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
4186*4882a593Smuzhiyun    9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
4187*4882a593Smuzhiyun    9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
4188*4882a593Smuzhiyun    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8
4189*4882a593Smuzhiyun };
4190*4882a593Smuzhiyun static const stbi_uc stbi__zdefault_distance[32] =
4191*4882a593Smuzhiyun {
4192*4882a593Smuzhiyun    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
4193*4882a593Smuzhiyun };
4194*4882a593Smuzhiyun /*
4195*4882a593Smuzhiyun Init algorithm:
4196*4882a593Smuzhiyun {
4197*4882a593Smuzhiyun    int i;   // use <= to match clearly with spec
4198*4882a593Smuzhiyun    for (i=0; i <= 143; ++i)     stbi__zdefault_length[i]   = 8;
4199*4882a593Smuzhiyun    for (   ; i <= 255; ++i)     stbi__zdefault_length[i]   = 9;
4200*4882a593Smuzhiyun    for (   ; i <= 279; ++i)     stbi__zdefault_length[i]   = 7;
4201*4882a593Smuzhiyun    for (   ; i <= 287; ++i)     stbi__zdefault_length[i]   = 8;
4202*4882a593Smuzhiyun 
4203*4882a593Smuzhiyun    for (i=0; i <=  31; ++i)     stbi__zdefault_distance[i] = 5;
4204*4882a593Smuzhiyun }
4205*4882a593Smuzhiyun */
4206*4882a593Smuzhiyun 
stbi__parse_zlib(stbi__zbuf * a,int parse_header)4207*4882a593Smuzhiyun static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
4208*4882a593Smuzhiyun {
4209*4882a593Smuzhiyun    int final, type;
4210*4882a593Smuzhiyun    if (parse_header)
4211*4882a593Smuzhiyun       if (!stbi__parse_zlib_header(a)) return 0;
4212*4882a593Smuzhiyun    a->num_bits = 0;
4213*4882a593Smuzhiyun    a->code_buffer = 0;
4214*4882a593Smuzhiyun    do {
4215*4882a593Smuzhiyun       final = stbi__zreceive(a,1);
4216*4882a593Smuzhiyun       type = stbi__zreceive(a,2);
4217*4882a593Smuzhiyun       if (type == 0) {
4218*4882a593Smuzhiyun          if (!stbi__parse_uncompressed_block(a)) return 0;
4219*4882a593Smuzhiyun       } else if (type == 3) {
4220*4882a593Smuzhiyun          return 0;
4221*4882a593Smuzhiyun       } else {
4222*4882a593Smuzhiyun          if (type == 1) {
4223*4882a593Smuzhiyun             // use fixed code lengths
4224*4882a593Smuzhiyun             if (!stbi__zbuild_huffman(&a->z_length  , stbi__zdefault_length  , 288)) return 0;
4225*4882a593Smuzhiyun             if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance,  32)) return 0;
4226*4882a593Smuzhiyun          } else {
4227*4882a593Smuzhiyun             if (!stbi__compute_huffman_codes(a)) return 0;
4228*4882a593Smuzhiyun          }
4229*4882a593Smuzhiyun          if (!stbi__parse_huffman_block(a)) return 0;
4230*4882a593Smuzhiyun       }
4231*4882a593Smuzhiyun    } while (!final);
4232*4882a593Smuzhiyun    return 1;
4233*4882a593Smuzhiyun }
4234*4882a593Smuzhiyun 
stbi__do_zlib(stbi__zbuf * a,char * obuf,int olen,int exp,int parse_header)4235*4882a593Smuzhiyun static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header)
4236*4882a593Smuzhiyun {
4237*4882a593Smuzhiyun    a->zout_start = obuf;
4238*4882a593Smuzhiyun    a->zout       = obuf;
4239*4882a593Smuzhiyun    a->zout_end   = obuf + olen;
4240*4882a593Smuzhiyun    a->z_expandable = exp;
4241*4882a593Smuzhiyun 
4242*4882a593Smuzhiyun    return stbi__parse_zlib(a, parse_header);
4243*4882a593Smuzhiyun }
4244*4882a593Smuzhiyun 
stbi_zlib_decode_malloc_guesssize(const char * buffer,int len,int initial_size,int * outlen)4245*4882a593Smuzhiyun STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen)
4246*4882a593Smuzhiyun {
4247*4882a593Smuzhiyun    stbi__zbuf a;
4248*4882a593Smuzhiyun    char *p = (char *) stbi__malloc(initial_size);
4249*4882a593Smuzhiyun    if (p == NULL) return NULL;
4250*4882a593Smuzhiyun    a.zbuffer = (stbi_uc *) buffer;
4251*4882a593Smuzhiyun    a.zbuffer_end = (stbi_uc *) buffer + len;
4252*4882a593Smuzhiyun    if (stbi__do_zlib(&a, p, initial_size, 1, 1)) {
4253*4882a593Smuzhiyun       if (outlen) *outlen = (int) (a.zout - a.zout_start);
4254*4882a593Smuzhiyun       return a.zout_start;
4255*4882a593Smuzhiyun    } else {
4256*4882a593Smuzhiyun       STBI_FREE(a.zout_start);
4257*4882a593Smuzhiyun       return NULL;
4258*4882a593Smuzhiyun    }
4259*4882a593Smuzhiyun }
4260*4882a593Smuzhiyun 
stbi_zlib_decode_malloc(char const * buffer,int len,int * outlen)4261*4882a593Smuzhiyun STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen)
4262*4882a593Smuzhiyun {
4263*4882a593Smuzhiyun    return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen);
4264*4882a593Smuzhiyun }
4265*4882a593Smuzhiyun 
stbi_zlib_decode_malloc_guesssize_headerflag(const char * buffer,int len,int initial_size,int * outlen,int parse_header)4266*4882a593Smuzhiyun STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header)
4267*4882a593Smuzhiyun {
4268*4882a593Smuzhiyun    stbi__zbuf a;
4269*4882a593Smuzhiyun    char *p = (char *) stbi__malloc(initial_size);
4270*4882a593Smuzhiyun    if (p == NULL) return NULL;
4271*4882a593Smuzhiyun    a.zbuffer = (stbi_uc *) buffer;
4272*4882a593Smuzhiyun    a.zbuffer_end = (stbi_uc *) buffer + len;
4273*4882a593Smuzhiyun    if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) {
4274*4882a593Smuzhiyun       if (outlen) *outlen = (int) (a.zout - a.zout_start);
4275*4882a593Smuzhiyun       return a.zout_start;
4276*4882a593Smuzhiyun    } else {
4277*4882a593Smuzhiyun       STBI_FREE(a.zout_start);
4278*4882a593Smuzhiyun       return NULL;
4279*4882a593Smuzhiyun    }
4280*4882a593Smuzhiyun }
4281*4882a593Smuzhiyun 
stbi_zlib_decode_buffer(char * obuffer,int olen,char const * ibuffer,int ilen)4282*4882a593Smuzhiyun STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen)
4283*4882a593Smuzhiyun {
4284*4882a593Smuzhiyun    stbi__zbuf a;
4285*4882a593Smuzhiyun    a.zbuffer = (stbi_uc *) ibuffer;
4286*4882a593Smuzhiyun    a.zbuffer_end = (stbi_uc *) ibuffer + ilen;
4287*4882a593Smuzhiyun    if (stbi__do_zlib(&a, obuffer, olen, 0, 1))
4288*4882a593Smuzhiyun       return (int) (a.zout - a.zout_start);
4289*4882a593Smuzhiyun    else
4290*4882a593Smuzhiyun       return -1;
4291*4882a593Smuzhiyun }
4292*4882a593Smuzhiyun 
stbi_zlib_decode_noheader_malloc(char const * buffer,int len,int * outlen)4293*4882a593Smuzhiyun STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen)
4294*4882a593Smuzhiyun {
4295*4882a593Smuzhiyun    stbi__zbuf a;
4296*4882a593Smuzhiyun    char *p = (char *) stbi__malloc(16384);
4297*4882a593Smuzhiyun    if (p == NULL) return NULL;
4298*4882a593Smuzhiyun    a.zbuffer = (stbi_uc *) buffer;
4299*4882a593Smuzhiyun    a.zbuffer_end = (stbi_uc *) buffer+len;
4300*4882a593Smuzhiyun    if (stbi__do_zlib(&a, p, 16384, 1, 0)) {
4301*4882a593Smuzhiyun       if (outlen) *outlen = (int) (a.zout - a.zout_start);
4302*4882a593Smuzhiyun       return a.zout_start;
4303*4882a593Smuzhiyun    } else {
4304*4882a593Smuzhiyun       STBI_FREE(a.zout_start);
4305*4882a593Smuzhiyun       return NULL;
4306*4882a593Smuzhiyun    }
4307*4882a593Smuzhiyun }
4308*4882a593Smuzhiyun 
stbi_zlib_decode_noheader_buffer(char * obuffer,int olen,const char * ibuffer,int ilen)4309*4882a593Smuzhiyun STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen)
4310*4882a593Smuzhiyun {
4311*4882a593Smuzhiyun    stbi__zbuf a;
4312*4882a593Smuzhiyun    a.zbuffer = (stbi_uc *) ibuffer;
4313*4882a593Smuzhiyun    a.zbuffer_end = (stbi_uc *) ibuffer + ilen;
4314*4882a593Smuzhiyun    if (stbi__do_zlib(&a, obuffer, olen, 0, 0))
4315*4882a593Smuzhiyun       return (int) (a.zout - a.zout_start);
4316*4882a593Smuzhiyun    else
4317*4882a593Smuzhiyun       return -1;
4318*4882a593Smuzhiyun }
4319*4882a593Smuzhiyun #endif
4320*4882a593Smuzhiyun 
4321*4882a593Smuzhiyun // public domain "baseline" PNG decoder   v0.10  Sean Barrett 2006-11-18
4322*4882a593Smuzhiyun //    simple implementation
4323*4882a593Smuzhiyun //      - only 8-bit samples
4324*4882a593Smuzhiyun //      - no CRC checking
4325*4882a593Smuzhiyun //      - allocates lots of intermediate memory
4326*4882a593Smuzhiyun //        - avoids problem of streaming data between subsystems
4327*4882a593Smuzhiyun //        - avoids explicit window management
4328*4882a593Smuzhiyun //    performance
4329*4882a593Smuzhiyun //      - uses stb_zlib, a PD zlib implementation with fast huffman decoding
4330*4882a593Smuzhiyun 
4331*4882a593Smuzhiyun #ifndef STBI_NO_PNG
4332*4882a593Smuzhiyun typedef struct
4333*4882a593Smuzhiyun {
4334*4882a593Smuzhiyun    stbi__uint32 length;
4335*4882a593Smuzhiyun    stbi__uint32 type;
4336*4882a593Smuzhiyun } stbi__pngchunk;
4337*4882a593Smuzhiyun 
stbi__get_chunk_header(stbi__context * s)4338*4882a593Smuzhiyun static stbi__pngchunk stbi__get_chunk_header(stbi__context *s)
4339*4882a593Smuzhiyun {
4340*4882a593Smuzhiyun    stbi__pngchunk c;
4341*4882a593Smuzhiyun    c.length = stbi__get32be(s);
4342*4882a593Smuzhiyun    c.type   = stbi__get32be(s);
4343*4882a593Smuzhiyun    return c;
4344*4882a593Smuzhiyun }
4345*4882a593Smuzhiyun 
stbi__check_png_header(stbi__context * s)4346*4882a593Smuzhiyun static int stbi__check_png_header(stbi__context *s)
4347*4882a593Smuzhiyun {
4348*4882a593Smuzhiyun    static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 };
4349*4882a593Smuzhiyun    int i;
4350*4882a593Smuzhiyun    for (i=0; i < 8; ++i)
4351*4882a593Smuzhiyun       if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG");
4352*4882a593Smuzhiyun    return 1;
4353*4882a593Smuzhiyun }
4354*4882a593Smuzhiyun 
4355*4882a593Smuzhiyun typedef struct
4356*4882a593Smuzhiyun {
4357*4882a593Smuzhiyun    stbi__context *s;
4358*4882a593Smuzhiyun    stbi_uc *idata, *expanded, *out;
4359*4882a593Smuzhiyun    int depth;
4360*4882a593Smuzhiyun } stbi__png;
4361*4882a593Smuzhiyun 
4362*4882a593Smuzhiyun 
4363*4882a593Smuzhiyun enum {
4364*4882a593Smuzhiyun    STBI__F_none=0,
4365*4882a593Smuzhiyun    STBI__F_sub=1,
4366*4882a593Smuzhiyun    STBI__F_up=2,
4367*4882a593Smuzhiyun    STBI__F_avg=3,
4368*4882a593Smuzhiyun    STBI__F_paeth=4,
4369*4882a593Smuzhiyun    // synthetic filters used for first scanline to avoid needing a dummy row of 0s
4370*4882a593Smuzhiyun    STBI__F_avg_first,
4371*4882a593Smuzhiyun    STBI__F_paeth_first
4372*4882a593Smuzhiyun };
4373*4882a593Smuzhiyun 
4374*4882a593Smuzhiyun static stbi_uc first_row_filter[5] =
4375*4882a593Smuzhiyun {
4376*4882a593Smuzhiyun    STBI__F_none,
4377*4882a593Smuzhiyun    STBI__F_sub,
4378*4882a593Smuzhiyun    STBI__F_none,
4379*4882a593Smuzhiyun    STBI__F_avg_first,
4380*4882a593Smuzhiyun    STBI__F_paeth_first
4381*4882a593Smuzhiyun };
4382*4882a593Smuzhiyun 
stbi__paeth(int a,int b,int c)4383*4882a593Smuzhiyun static int stbi__paeth(int a, int b, int c)
4384*4882a593Smuzhiyun {
4385*4882a593Smuzhiyun    int p = a + b - c;
4386*4882a593Smuzhiyun    int pa = abs(p-a);
4387*4882a593Smuzhiyun    int pb = abs(p-b);
4388*4882a593Smuzhiyun    int pc = abs(p-c);
4389*4882a593Smuzhiyun    if (pa <= pb && pa <= pc) return a;
4390*4882a593Smuzhiyun    if (pb <= pc) return b;
4391*4882a593Smuzhiyun    return c;
4392*4882a593Smuzhiyun }
4393*4882a593Smuzhiyun 
4394*4882a593Smuzhiyun static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
4395*4882a593Smuzhiyun 
4396*4882a593Smuzhiyun // create the png data from post-deflated data
stbi__create_png_image_raw(stbi__png * a,stbi_uc * raw,stbi__uint32 raw_len,int out_n,stbi__uint32 x,stbi__uint32 y,int depth,int color)4397*4882a593Smuzhiyun static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
4398*4882a593Smuzhiyun {
4399*4882a593Smuzhiyun    int bytes = (depth == 16? 2 : 1);
4400*4882a593Smuzhiyun    stbi__context *s = a->s;
4401*4882a593Smuzhiyun    stbi__uint32 i,j,stride = x*out_n*bytes;
4402*4882a593Smuzhiyun    stbi__uint32 img_len, img_width_bytes;
4403*4882a593Smuzhiyun    int k;
4404*4882a593Smuzhiyun    int img_n = s->img_n; // copy it into a local for later
4405*4882a593Smuzhiyun 
4406*4882a593Smuzhiyun    int output_bytes = out_n*bytes;
4407*4882a593Smuzhiyun    int filter_bytes = img_n*bytes;
4408*4882a593Smuzhiyun    int width = x;
4409*4882a593Smuzhiyun 
4410*4882a593Smuzhiyun    STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
4411*4882a593Smuzhiyun    a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
4412*4882a593Smuzhiyun    if (!a->out) return stbi__err("outofmem", "Out of memory");
4413*4882a593Smuzhiyun 
4414*4882a593Smuzhiyun    if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
4415*4882a593Smuzhiyun    img_width_bytes = (((img_n * x * depth) + 7) >> 3);
4416*4882a593Smuzhiyun    img_len = (img_width_bytes + 1) * y;
4417*4882a593Smuzhiyun 
4418*4882a593Smuzhiyun    // we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
4419*4882a593Smuzhiyun    // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros),
4420*4882a593Smuzhiyun    // so just check for raw_len < img_len always.
4421*4882a593Smuzhiyun    if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
4422*4882a593Smuzhiyun 
4423*4882a593Smuzhiyun    for (j=0; j < y; ++j) {
4424*4882a593Smuzhiyun       stbi_uc *cur = a->out + stride*j;
4425*4882a593Smuzhiyun       stbi_uc *prior;
4426*4882a593Smuzhiyun       int filter = *raw++;
4427*4882a593Smuzhiyun 
4428*4882a593Smuzhiyun       if (filter > 4)
4429*4882a593Smuzhiyun          return stbi__err("invalid filter","Corrupt PNG");
4430*4882a593Smuzhiyun 
4431*4882a593Smuzhiyun       if (depth < 8) {
4432*4882a593Smuzhiyun          STBI_ASSERT(img_width_bytes <= x);
4433*4882a593Smuzhiyun          cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
4434*4882a593Smuzhiyun          filter_bytes = 1;
4435*4882a593Smuzhiyun          width = img_width_bytes;
4436*4882a593Smuzhiyun       }
4437*4882a593Smuzhiyun       prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
4438*4882a593Smuzhiyun 
4439*4882a593Smuzhiyun       // if first row, use special filter that doesn't sample previous row
4440*4882a593Smuzhiyun       if (j == 0) filter = first_row_filter[filter];
4441*4882a593Smuzhiyun 
4442*4882a593Smuzhiyun       // handle first byte explicitly
4443*4882a593Smuzhiyun       for (k=0; k < filter_bytes; ++k) {
4444*4882a593Smuzhiyun          switch (filter) {
4445*4882a593Smuzhiyun             case STBI__F_none       : cur[k] = raw[k]; break;
4446*4882a593Smuzhiyun             case STBI__F_sub        : cur[k] = raw[k]; break;
4447*4882a593Smuzhiyun             case STBI__F_up         : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
4448*4882a593Smuzhiyun             case STBI__F_avg        : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break;
4449*4882a593Smuzhiyun             case STBI__F_paeth      : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break;
4450*4882a593Smuzhiyun             case STBI__F_avg_first  : cur[k] = raw[k]; break;
4451*4882a593Smuzhiyun             case STBI__F_paeth_first: cur[k] = raw[k]; break;
4452*4882a593Smuzhiyun          }
4453*4882a593Smuzhiyun       }
4454*4882a593Smuzhiyun 
4455*4882a593Smuzhiyun       if (depth == 8) {
4456*4882a593Smuzhiyun          if (img_n != out_n)
4457*4882a593Smuzhiyun             cur[img_n] = 255; // first pixel
4458*4882a593Smuzhiyun          raw += img_n;
4459*4882a593Smuzhiyun          cur += out_n;
4460*4882a593Smuzhiyun          prior += out_n;
4461*4882a593Smuzhiyun       } else if (depth == 16) {
4462*4882a593Smuzhiyun          if (img_n != out_n) {
4463*4882a593Smuzhiyun             cur[filter_bytes]   = 255; // first pixel top byte
4464*4882a593Smuzhiyun             cur[filter_bytes+1] = 255; // first pixel bottom byte
4465*4882a593Smuzhiyun          }
4466*4882a593Smuzhiyun          raw += filter_bytes;
4467*4882a593Smuzhiyun          cur += output_bytes;
4468*4882a593Smuzhiyun          prior += output_bytes;
4469*4882a593Smuzhiyun       } else {
4470*4882a593Smuzhiyun          raw += 1;
4471*4882a593Smuzhiyun          cur += 1;
4472*4882a593Smuzhiyun          prior += 1;
4473*4882a593Smuzhiyun       }
4474*4882a593Smuzhiyun 
4475*4882a593Smuzhiyun       // this is a little gross, so that we don't switch per-pixel or per-component
4476*4882a593Smuzhiyun       if (depth < 8 || img_n == out_n) {
4477*4882a593Smuzhiyun          int nk = (width - 1)*filter_bytes;
4478*4882a593Smuzhiyun          #define STBI__CASE(f) \
4479*4882a593Smuzhiyun              case f:     \
4480*4882a593Smuzhiyun                 for (k=0; k < nk; ++k)
4481*4882a593Smuzhiyun          switch (filter) {
4482*4882a593Smuzhiyun             // "none" filter turns into a memcpy here; make that explicit.
4483*4882a593Smuzhiyun             case STBI__F_none:         memcpy(cur, raw, nk); break;
4484*4882a593Smuzhiyun             STBI__CASE(STBI__F_sub)          { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
4485*4882a593Smuzhiyun             STBI__CASE(STBI__F_up)           { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
4486*4882a593Smuzhiyun             STBI__CASE(STBI__F_avg)          { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
4487*4882a593Smuzhiyun             STBI__CASE(STBI__F_paeth)        { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
4488*4882a593Smuzhiyun             STBI__CASE(STBI__F_avg_first)    { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
4489*4882a593Smuzhiyun             STBI__CASE(STBI__F_paeth_first)  { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
4490*4882a593Smuzhiyun          }
4491*4882a593Smuzhiyun          #undef STBI__CASE
4492*4882a593Smuzhiyun          raw += nk;
4493*4882a593Smuzhiyun       } else {
4494*4882a593Smuzhiyun          STBI_ASSERT(img_n+1 == out_n);
4495*4882a593Smuzhiyun          #define STBI__CASE(f) \
4496*4882a593Smuzhiyun              case f:     \
4497*4882a593Smuzhiyun                 for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
4498*4882a593Smuzhiyun                    for (k=0; k < filter_bytes; ++k)
4499*4882a593Smuzhiyun          switch (filter) {
4500*4882a593Smuzhiyun             STBI__CASE(STBI__F_none)         { cur[k] = raw[k]; } break;
4501*4882a593Smuzhiyun             STBI__CASE(STBI__F_sub)          { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
4502*4882a593Smuzhiyun             STBI__CASE(STBI__F_up)           { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
4503*4882a593Smuzhiyun             STBI__CASE(STBI__F_avg)          { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
4504*4882a593Smuzhiyun             STBI__CASE(STBI__F_paeth)        { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
4505*4882a593Smuzhiyun             STBI__CASE(STBI__F_avg_first)    { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
4506*4882a593Smuzhiyun             STBI__CASE(STBI__F_paeth_first)  { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
4507*4882a593Smuzhiyun          }
4508*4882a593Smuzhiyun          #undef STBI__CASE
4509*4882a593Smuzhiyun 
4510*4882a593Smuzhiyun          // the loop above sets the high byte of the pixels' alpha, but for
4511*4882a593Smuzhiyun          // 16 bit png files we also need the low byte set. we'll do that here.
4512*4882a593Smuzhiyun          if (depth == 16) {
4513*4882a593Smuzhiyun             cur = a->out + stride*j; // start at the beginning of the row again
4514*4882a593Smuzhiyun             for (i=0; i < x; ++i,cur+=output_bytes) {
4515*4882a593Smuzhiyun                cur[filter_bytes+1] = 255;
4516*4882a593Smuzhiyun             }
4517*4882a593Smuzhiyun          }
4518*4882a593Smuzhiyun       }
4519*4882a593Smuzhiyun    }
4520*4882a593Smuzhiyun 
4521*4882a593Smuzhiyun    // we make a separate pass to expand bits to pixels; for performance,
4522*4882a593Smuzhiyun    // this could run two scanlines behind the above code, so it won't
4523*4882a593Smuzhiyun    // intefere with filtering but will still be in the cache.
4524*4882a593Smuzhiyun    if (depth < 8) {
4525*4882a593Smuzhiyun       for (j=0; j < y; ++j) {
4526*4882a593Smuzhiyun          stbi_uc *cur = a->out + stride*j;
4527*4882a593Smuzhiyun          stbi_uc *in  = a->out + stride*j + x*out_n - img_width_bytes;
4528*4882a593Smuzhiyun          // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
4529*4882a593Smuzhiyun          // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
4530*4882a593Smuzhiyun          stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
4531*4882a593Smuzhiyun 
4532*4882a593Smuzhiyun          // note that the final byte might overshoot and write more data than desired.
4533*4882a593Smuzhiyun          // we can allocate enough data that this never writes out of memory, but it
4534*4882a593Smuzhiyun          // could also overwrite the next scanline. can it overwrite non-empty data
4535*4882a593Smuzhiyun          // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
4536*4882a593Smuzhiyun          // so we need to explicitly clamp the final ones
4537*4882a593Smuzhiyun 
4538*4882a593Smuzhiyun          if (depth == 4) {
4539*4882a593Smuzhiyun             for (k=x*img_n; k >= 2; k-=2, ++in) {
4540*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 4)       );
4541*4882a593Smuzhiyun                *cur++ = scale * ((*in     ) & 0x0f);
4542*4882a593Smuzhiyun             }
4543*4882a593Smuzhiyun             if (k > 0) *cur++ = scale * ((*in >> 4)       );
4544*4882a593Smuzhiyun          } else if (depth == 2) {
4545*4882a593Smuzhiyun             for (k=x*img_n; k >= 4; k-=4, ++in) {
4546*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 6)       );
4547*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 4) & 0x03);
4548*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 2) & 0x03);
4549*4882a593Smuzhiyun                *cur++ = scale * ((*in     ) & 0x03);
4550*4882a593Smuzhiyun             }
4551*4882a593Smuzhiyun             if (k > 0) *cur++ = scale * ((*in >> 6)       );
4552*4882a593Smuzhiyun             if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03);
4553*4882a593Smuzhiyun             if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03);
4554*4882a593Smuzhiyun          } else if (depth == 1) {
4555*4882a593Smuzhiyun             for (k=x*img_n; k >= 8; k-=8, ++in) {
4556*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 7)       );
4557*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 6) & 0x01);
4558*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 5) & 0x01);
4559*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 4) & 0x01);
4560*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 3) & 0x01);
4561*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 2) & 0x01);
4562*4882a593Smuzhiyun                *cur++ = scale * ((*in >> 1) & 0x01);
4563*4882a593Smuzhiyun                *cur++ = scale * ((*in     ) & 0x01);
4564*4882a593Smuzhiyun             }
4565*4882a593Smuzhiyun             if (k > 0) *cur++ = scale * ((*in >> 7)       );
4566*4882a593Smuzhiyun             if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01);
4567*4882a593Smuzhiyun             if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01);
4568*4882a593Smuzhiyun             if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01);
4569*4882a593Smuzhiyun             if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01);
4570*4882a593Smuzhiyun             if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01);
4571*4882a593Smuzhiyun             if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
4572*4882a593Smuzhiyun          }
4573*4882a593Smuzhiyun          if (img_n != out_n) {
4574*4882a593Smuzhiyun             int q;
4575*4882a593Smuzhiyun             // insert alpha = 255
4576*4882a593Smuzhiyun             cur = a->out + stride*j;
4577*4882a593Smuzhiyun             if (img_n == 1) {
4578*4882a593Smuzhiyun                for (q=x-1; q >= 0; --q) {
4579*4882a593Smuzhiyun                   cur[q*2+1] = 255;
4580*4882a593Smuzhiyun                   cur[q*2+0] = cur[q];
4581*4882a593Smuzhiyun                }
4582*4882a593Smuzhiyun             } else {
4583*4882a593Smuzhiyun                STBI_ASSERT(img_n == 3);
4584*4882a593Smuzhiyun                for (q=x-1; q >= 0; --q) {
4585*4882a593Smuzhiyun                   cur[q*4+3] = 255;
4586*4882a593Smuzhiyun                   cur[q*4+2] = cur[q*3+2];
4587*4882a593Smuzhiyun                   cur[q*4+1] = cur[q*3+1];
4588*4882a593Smuzhiyun                   cur[q*4+0] = cur[q*3+0];
4589*4882a593Smuzhiyun                }
4590*4882a593Smuzhiyun             }
4591*4882a593Smuzhiyun          }
4592*4882a593Smuzhiyun       }
4593*4882a593Smuzhiyun    } else if (depth == 16) {
4594*4882a593Smuzhiyun       // force the image data from big-endian to platform-native.
4595*4882a593Smuzhiyun       // this is done in a separate pass due to the decoding relying
4596*4882a593Smuzhiyun       // on the data being untouched, but could probably be done
4597*4882a593Smuzhiyun       // per-line during decode if care is taken.
4598*4882a593Smuzhiyun       stbi_uc *cur = a->out;
4599*4882a593Smuzhiyun       stbi__uint16 *cur16 = (stbi__uint16*)cur;
4600*4882a593Smuzhiyun 
4601*4882a593Smuzhiyun       for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
4602*4882a593Smuzhiyun          *cur16 = (cur[0] << 8) | cur[1];
4603*4882a593Smuzhiyun       }
4604*4882a593Smuzhiyun    }
4605*4882a593Smuzhiyun 
4606*4882a593Smuzhiyun    return 1;
4607*4882a593Smuzhiyun }
4608*4882a593Smuzhiyun 
stbi__create_png_image(stbi__png * a,stbi_uc * image_data,stbi__uint32 image_data_len,int out_n,int depth,int color,int interlaced)4609*4882a593Smuzhiyun static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced)
4610*4882a593Smuzhiyun {
4611*4882a593Smuzhiyun    int bytes = (depth == 16 ? 2 : 1);
4612*4882a593Smuzhiyun    int out_bytes = out_n * bytes;
4613*4882a593Smuzhiyun    stbi_uc *final;
4614*4882a593Smuzhiyun    int p;
4615*4882a593Smuzhiyun    if (!interlaced)
4616*4882a593Smuzhiyun       return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color);
4617*4882a593Smuzhiyun 
4618*4882a593Smuzhiyun    // de-interlacing
4619*4882a593Smuzhiyun    final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
4620*4882a593Smuzhiyun    for (p=0; p < 7; ++p) {
4621*4882a593Smuzhiyun       int xorig[] = { 0,4,0,2,0,1,0 };
4622*4882a593Smuzhiyun       int yorig[] = { 0,0,4,0,2,0,1 };
4623*4882a593Smuzhiyun       int xspc[]  = { 8,8,4,4,2,2,1 };
4624*4882a593Smuzhiyun       int yspc[]  = { 8,8,8,4,4,2,2 };
4625*4882a593Smuzhiyun       int i,j,x,y;
4626*4882a593Smuzhiyun       // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1
4627*4882a593Smuzhiyun       x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p];
4628*4882a593Smuzhiyun       y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p];
4629*4882a593Smuzhiyun       if (x && y) {
4630*4882a593Smuzhiyun          stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y;
4631*4882a593Smuzhiyun          if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) {
4632*4882a593Smuzhiyun             STBI_FREE(final);
4633*4882a593Smuzhiyun             return 0;
4634*4882a593Smuzhiyun          }
4635*4882a593Smuzhiyun          for (j=0; j < y; ++j) {
4636*4882a593Smuzhiyun             for (i=0; i < x; ++i) {
4637*4882a593Smuzhiyun                int out_y = j*yspc[p]+yorig[p];
4638*4882a593Smuzhiyun                int out_x = i*xspc[p]+xorig[p];
4639*4882a593Smuzhiyun                memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes,
4640*4882a593Smuzhiyun                       a->out + (j*x+i)*out_bytes, out_bytes);
4641*4882a593Smuzhiyun             }
4642*4882a593Smuzhiyun          }
4643*4882a593Smuzhiyun          STBI_FREE(a->out);
4644*4882a593Smuzhiyun          image_data += img_len;
4645*4882a593Smuzhiyun          image_data_len -= img_len;
4646*4882a593Smuzhiyun       }
4647*4882a593Smuzhiyun    }
4648*4882a593Smuzhiyun    a->out = final;
4649*4882a593Smuzhiyun 
4650*4882a593Smuzhiyun    return 1;
4651*4882a593Smuzhiyun }
4652*4882a593Smuzhiyun 
stbi__compute_transparency(stbi__png * z,stbi_uc tc[3],int out_n)4653*4882a593Smuzhiyun static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
4654*4882a593Smuzhiyun {
4655*4882a593Smuzhiyun    stbi__context *s = z->s;
4656*4882a593Smuzhiyun    stbi__uint32 i, pixel_count = s->img_x * s->img_y;
4657*4882a593Smuzhiyun    stbi_uc *p = z->out;
4658*4882a593Smuzhiyun 
4659*4882a593Smuzhiyun    // compute color-based transparency, assuming we've
4660*4882a593Smuzhiyun    // already got 255 as the alpha value in the output
4661*4882a593Smuzhiyun    STBI_ASSERT(out_n == 2 || out_n == 4);
4662*4882a593Smuzhiyun 
4663*4882a593Smuzhiyun    if (out_n == 2) {
4664*4882a593Smuzhiyun       for (i=0; i < pixel_count; ++i) {
4665*4882a593Smuzhiyun          p[1] = (p[0] == tc[0] ? 0 : 255);
4666*4882a593Smuzhiyun          p += 2;
4667*4882a593Smuzhiyun       }
4668*4882a593Smuzhiyun    } else {
4669*4882a593Smuzhiyun       for (i=0; i < pixel_count; ++i) {
4670*4882a593Smuzhiyun          if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
4671*4882a593Smuzhiyun             p[3] = 0;
4672*4882a593Smuzhiyun          p += 4;
4673*4882a593Smuzhiyun       }
4674*4882a593Smuzhiyun    }
4675*4882a593Smuzhiyun    return 1;
4676*4882a593Smuzhiyun }
4677*4882a593Smuzhiyun 
stbi__compute_transparency16(stbi__png * z,stbi__uint16 tc[3],int out_n)4678*4882a593Smuzhiyun static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n)
4679*4882a593Smuzhiyun {
4680*4882a593Smuzhiyun    stbi__context *s = z->s;
4681*4882a593Smuzhiyun    stbi__uint32 i, pixel_count = s->img_x * s->img_y;
4682*4882a593Smuzhiyun    stbi__uint16 *p = (stbi__uint16*) z->out;
4683*4882a593Smuzhiyun 
4684*4882a593Smuzhiyun    // compute color-based transparency, assuming we've
4685*4882a593Smuzhiyun    // already got 65535 as the alpha value in the output
4686*4882a593Smuzhiyun    STBI_ASSERT(out_n == 2 || out_n == 4);
4687*4882a593Smuzhiyun 
4688*4882a593Smuzhiyun    if (out_n == 2) {
4689*4882a593Smuzhiyun       for (i = 0; i < pixel_count; ++i) {
4690*4882a593Smuzhiyun          p[1] = (p[0] == tc[0] ? 0 : 65535);
4691*4882a593Smuzhiyun          p += 2;
4692*4882a593Smuzhiyun       }
4693*4882a593Smuzhiyun    } else {
4694*4882a593Smuzhiyun       for (i = 0; i < pixel_count; ++i) {
4695*4882a593Smuzhiyun          if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
4696*4882a593Smuzhiyun             p[3] = 0;
4697*4882a593Smuzhiyun          p += 4;
4698*4882a593Smuzhiyun       }
4699*4882a593Smuzhiyun    }
4700*4882a593Smuzhiyun    return 1;
4701*4882a593Smuzhiyun }
4702*4882a593Smuzhiyun 
stbi__expand_png_palette(stbi__png * a,stbi_uc * palette,int len,int pal_img_n)4703*4882a593Smuzhiyun static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n)
4704*4882a593Smuzhiyun {
4705*4882a593Smuzhiyun    stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
4706*4882a593Smuzhiyun    stbi_uc *p, *temp_out, *orig = a->out;
4707*4882a593Smuzhiyun 
4708*4882a593Smuzhiyun    p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0);
4709*4882a593Smuzhiyun    if (p == NULL) return stbi__err("outofmem", "Out of memory");
4710*4882a593Smuzhiyun 
4711*4882a593Smuzhiyun    // between here and free(out) below, exitting would leak
4712*4882a593Smuzhiyun    temp_out = p;
4713*4882a593Smuzhiyun 
4714*4882a593Smuzhiyun    if (pal_img_n == 3) {
4715*4882a593Smuzhiyun       for (i=0; i < pixel_count; ++i) {
4716*4882a593Smuzhiyun          int n = orig[i]*4;
4717*4882a593Smuzhiyun          p[0] = palette[n  ];
4718*4882a593Smuzhiyun          p[1] = palette[n+1];
4719*4882a593Smuzhiyun          p[2] = palette[n+2];
4720*4882a593Smuzhiyun          p += 3;
4721*4882a593Smuzhiyun       }
4722*4882a593Smuzhiyun    } else {
4723*4882a593Smuzhiyun       for (i=0; i < pixel_count; ++i) {
4724*4882a593Smuzhiyun          int n = orig[i]*4;
4725*4882a593Smuzhiyun          p[0] = palette[n  ];
4726*4882a593Smuzhiyun          p[1] = palette[n+1];
4727*4882a593Smuzhiyun          p[2] = palette[n+2];
4728*4882a593Smuzhiyun          p[3] = palette[n+3];
4729*4882a593Smuzhiyun          p += 4;
4730*4882a593Smuzhiyun       }
4731*4882a593Smuzhiyun    }
4732*4882a593Smuzhiyun    STBI_FREE(a->out);
4733*4882a593Smuzhiyun    a->out = temp_out;
4734*4882a593Smuzhiyun 
4735*4882a593Smuzhiyun    STBI_NOTUSED(len);
4736*4882a593Smuzhiyun 
4737*4882a593Smuzhiyun    return 1;
4738*4882a593Smuzhiyun }
4739*4882a593Smuzhiyun 
4740*4882a593Smuzhiyun static int stbi__unpremultiply_on_load = 0;
4741*4882a593Smuzhiyun static int stbi__de_iphone_flag = 0;
4742*4882a593Smuzhiyun 
stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)4743*4882a593Smuzhiyun STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
4744*4882a593Smuzhiyun {
4745*4882a593Smuzhiyun    stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply;
4746*4882a593Smuzhiyun }
4747*4882a593Smuzhiyun 
stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)4748*4882a593Smuzhiyun STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
4749*4882a593Smuzhiyun {
4750*4882a593Smuzhiyun    stbi__de_iphone_flag = flag_true_if_should_convert;
4751*4882a593Smuzhiyun }
4752*4882a593Smuzhiyun 
stbi__de_iphone(stbi__png * z)4753*4882a593Smuzhiyun static void stbi__de_iphone(stbi__png *z)
4754*4882a593Smuzhiyun {
4755*4882a593Smuzhiyun    stbi__context *s = z->s;
4756*4882a593Smuzhiyun    stbi__uint32 i, pixel_count = s->img_x * s->img_y;
4757*4882a593Smuzhiyun    stbi_uc *p = z->out;
4758*4882a593Smuzhiyun 
4759*4882a593Smuzhiyun    if (s->img_out_n == 3) {  // convert bgr to rgb
4760*4882a593Smuzhiyun       for (i=0; i < pixel_count; ++i) {
4761*4882a593Smuzhiyun          stbi_uc t = p[0];
4762*4882a593Smuzhiyun          p[0] = p[2];
4763*4882a593Smuzhiyun          p[2] = t;
4764*4882a593Smuzhiyun          p += 3;
4765*4882a593Smuzhiyun       }
4766*4882a593Smuzhiyun    } else {
4767*4882a593Smuzhiyun       STBI_ASSERT(s->img_out_n == 4);
4768*4882a593Smuzhiyun       if (stbi__unpremultiply_on_load) {
4769*4882a593Smuzhiyun          // convert bgr to rgb and unpremultiply
4770*4882a593Smuzhiyun          for (i=0; i < pixel_count; ++i) {
4771*4882a593Smuzhiyun             stbi_uc a = p[3];
4772*4882a593Smuzhiyun             stbi_uc t = p[0];
4773*4882a593Smuzhiyun             if (a) {
4774*4882a593Smuzhiyun                stbi_uc half = a / 2;
4775*4882a593Smuzhiyun                p[0] = (p[2] * 255 + half) / a;
4776*4882a593Smuzhiyun                p[1] = (p[1] * 255 + half) / a;
4777*4882a593Smuzhiyun                p[2] = ( t   * 255 + half) / a;
4778*4882a593Smuzhiyun             } else {
4779*4882a593Smuzhiyun                p[0] = p[2];
4780*4882a593Smuzhiyun                p[2] = t;
4781*4882a593Smuzhiyun             }
4782*4882a593Smuzhiyun             p += 4;
4783*4882a593Smuzhiyun          }
4784*4882a593Smuzhiyun       } else {
4785*4882a593Smuzhiyun          // convert bgr to rgb
4786*4882a593Smuzhiyun          for (i=0; i < pixel_count; ++i) {
4787*4882a593Smuzhiyun             stbi_uc t = p[0];
4788*4882a593Smuzhiyun             p[0] = p[2];
4789*4882a593Smuzhiyun             p[2] = t;
4790*4882a593Smuzhiyun             p += 4;
4791*4882a593Smuzhiyun          }
4792*4882a593Smuzhiyun       }
4793*4882a593Smuzhiyun    }
4794*4882a593Smuzhiyun }
4795*4882a593Smuzhiyun 
4796*4882a593Smuzhiyun #define STBI__PNG_TYPE(a,b,c,d)  (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d))
4797*4882a593Smuzhiyun 
stbi__parse_png_file(stbi__png * z,int scan,int req_comp)4798*4882a593Smuzhiyun static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
4799*4882a593Smuzhiyun {
4800*4882a593Smuzhiyun    stbi_uc palette[1024], pal_img_n=0;
4801*4882a593Smuzhiyun    stbi_uc has_trans=0, tc[3]={0};
4802*4882a593Smuzhiyun    stbi__uint16 tc16[3];
4803*4882a593Smuzhiyun    stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
4804*4882a593Smuzhiyun    int first=1,k,interlace=0, color=0, is_iphone=0;
4805*4882a593Smuzhiyun    stbi__context *s = z->s;
4806*4882a593Smuzhiyun 
4807*4882a593Smuzhiyun    z->expanded = NULL;
4808*4882a593Smuzhiyun    z->idata = NULL;
4809*4882a593Smuzhiyun    z->out = NULL;
4810*4882a593Smuzhiyun 
4811*4882a593Smuzhiyun    if (!stbi__check_png_header(s)) return 0;
4812*4882a593Smuzhiyun 
4813*4882a593Smuzhiyun    if (scan == STBI__SCAN_type) return 1;
4814*4882a593Smuzhiyun 
4815*4882a593Smuzhiyun    for (;;) {
4816*4882a593Smuzhiyun       stbi__pngchunk c = stbi__get_chunk_header(s);
4817*4882a593Smuzhiyun       switch (c.type) {
4818*4882a593Smuzhiyun          case STBI__PNG_TYPE('C','g','B','I'):
4819*4882a593Smuzhiyun             is_iphone = 1;
4820*4882a593Smuzhiyun             stbi__skip(s, c.length);
4821*4882a593Smuzhiyun             break;
4822*4882a593Smuzhiyun          case STBI__PNG_TYPE('I','H','D','R'): {
4823*4882a593Smuzhiyun             int comp,filter;
4824*4882a593Smuzhiyun             if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
4825*4882a593Smuzhiyun             first = 0;
4826*4882a593Smuzhiyun             if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
4827*4882a593Smuzhiyun             s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
4828*4882a593Smuzhiyun             s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
4829*4882a593Smuzhiyun             z->depth = stbi__get8(s);  if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16)  return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
4830*4882a593Smuzhiyun             color = stbi__get8(s);  if (color > 6)         return stbi__err("bad ctype","Corrupt PNG");
4831*4882a593Smuzhiyun             if (color == 3 && z->depth == 16)                  return stbi__err("bad ctype","Corrupt PNG");
4832*4882a593Smuzhiyun             if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
4833*4882a593Smuzhiyun             comp  = stbi__get8(s);  if (comp) return stbi__err("bad comp method","Corrupt PNG");
4834*4882a593Smuzhiyun             filter= stbi__get8(s);  if (filter) return stbi__err("bad filter method","Corrupt PNG");
4835*4882a593Smuzhiyun             interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG");
4836*4882a593Smuzhiyun             if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG");
4837*4882a593Smuzhiyun             if (!pal_img_n) {
4838*4882a593Smuzhiyun                s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
4839*4882a593Smuzhiyun                if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode");
4840*4882a593Smuzhiyun                if (scan == STBI__SCAN_header) return 1;
4841*4882a593Smuzhiyun             } else {
4842*4882a593Smuzhiyun                // if paletted, then pal_n is our final components, and
4843*4882a593Smuzhiyun                // img_n is # components to decompress/filter.
4844*4882a593Smuzhiyun                s->img_n = 1;
4845*4882a593Smuzhiyun                if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG");
4846*4882a593Smuzhiyun                // if SCAN_header, have to scan to see if we have a tRNS
4847*4882a593Smuzhiyun             }
4848*4882a593Smuzhiyun             break;
4849*4882a593Smuzhiyun          }
4850*4882a593Smuzhiyun 
4851*4882a593Smuzhiyun          case STBI__PNG_TYPE('P','L','T','E'):  {
4852*4882a593Smuzhiyun             if (first) return stbi__err("first not IHDR", "Corrupt PNG");
4853*4882a593Smuzhiyun             if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG");
4854*4882a593Smuzhiyun             pal_len = c.length / 3;
4855*4882a593Smuzhiyun             if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG");
4856*4882a593Smuzhiyun             for (i=0; i < pal_len; ++i) {
4857*4882a593Smuzhiyun                palette[i*4+0] = stbi__get8(s);
4858*4882a593Smuzhiyun                palette[i*4+1] = stbi__get8(s);
4859*4882a593Smuzhiyun                palette[i*4+2] = stbi__get8(s);
4860*4882a593Smuzhiyun                palette[i*4+3] = 255;
4861*4882a593Smuzhiyun             }
4862*4882a593Smuzhiyun             break;
4863*4882a593Smuzhiyun          }
4864*4882a593Smuzhiyun 
4865*4882a593Smuzhiyun          case STBI__PNG_TYPE('t','R','N','S'): {
4866*4882a593Smuzhiyun             if (first) return stbi__err("first not IHDR", "Corrupt PNG");
4867*4882a593Smuzhiyun             if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG");
4868*4882a593Smuzhiyun             if (pal_img_n) {
4869*4882a593Smuzhiyun                if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; }
4870*4882a593Smuzhiyun                if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG");
4871*4882a593Smuzhiyun                if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG");
4872*4882a593Smuzhiyun                pal_img_n = 4;
4873*4882a593Smuzhiyun                for (i=0; i < c.length; ++i)
4874*4882a593Smuzhiyun                   palette[i*4+3] = stbi__get8(s);
4875*4882a593Smuzhiyun             } else {
4876*4882a593Smuzhiyun                if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
4877*4882a593Smuzhiyun                if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
4878*4882a593Smuzhiyun                has_trans = 1;
4879*4882a593Smuzhiyun                if (z->depth == 16) {
4880*4882a593Smuzhiyun                   for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
4881*4882a593Smuzhiyun                } else {
4882*4882a593Smuzhiyun                   for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
4883*4882a593Smuzhiyun                }
4884*4882a593Smuzhiyun             }
4885*4882a593Smuzhiyun             break;
4886*4882a593Smuzhiyun          }
4887*4882a593Smuzhiyun 
4888*4882a593Smuzhiyun          case STBI__PNG_TYPE('I','D','A','T'): {
4889*4882a593Smuzhiyun             if (first) return stbi__err("first not IHDR", "Corrupt PNG");
4890*4882a593Smuzhiyun             if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
4891*4882a593Smuzhiyun             if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
4892*4882a593Smuzhiyun             if ((int)(ioff + c.length) < (int)ioff) return 0;
4893*4882a593Smuzhiyun             if (ioff + c.length > idata_limit) {
4894*4882a593Smuzhiyun                stbi__uint32 idata_limit_old = idata_limit;
4895*4882a593Smuzhiyun                stbi_uc *p;
4896*4882a593Smuzhiyun                if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
4897*4882a593Smuzhiyun                while (ioff + c.length > idata_limit)
4898*4882a593Smuzhiyun                   idata_limit *= 2;
4899*4882a593Smuzhiyun                STBI_NOTUSED(idata_limit_old);
4900*4882a593Smuzhiyun                p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
4901*4882a593Smuzhiyun                z->idata = p;
4902*4882a593Smuzhiyun             }
4903*4882a593Smuzhiyun             if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG");
4904*4882a593Smuzhiyun             ioff += c.length;
4905*4882a593Smuzhiyun             break;
4906*4882a593Smuzhiyun          }
4907*4882a593Smuzhiyun 
4908*4882a593Smuzhiyun          case STBI__PNG_TYPE('I','E','N','D'): {
4909*4882a593Smuzhiyun             stbi__uint32 raw_len, bpl;
4910*4882a593Smuzhiyun             if (first) return stbi__err("first not IHDR", "Corrupt PNG");
4911*4882a593Smuzhiyun             if (scan != STBI__SCAN_load) return 1;
4912*4882a593Smuzhiyun             if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
4913*4882a593Smuzhiyun             // initial guess for decoded data size to avoid unnecessary reallocs
4914*4882a593Smuzhiyun             bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
4915*4882a593Smuzhiyun             raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
4916*4882a593Smuzhiyun             z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
4917*4882a593Smuzhiyun             if (z->expanded == NULL) return 0; // zlib should set error
4918*4882a593Smuzhiyun             STBI_FREE(z->idata); z->idata = NULL;
4919*4882a593Smuzhiyun             if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans)
4920*4882a593Smuzhiyun                s->img_out_n = s->img_n+1;
4921*4882a593Smuzhiyun             else
4922*4882a593Smuzhiyun                s->img_out_n = s->img_n;
4923*4882a593Smuzhiyun             if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
4924*4882a593Smuzhiyun             if (has_trans) {
4925*4882a593Smuzhiyun                if (z->depth == 16) {
4926*4882a593Smuzhiyun                   if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0;
4927*4882a593Smuzhiyun                } else {
4928*4882a593Smuzhiyun                   if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
4929*4882a593Smuzhiyun                }
4930*4882a593Smuzhiyun             }
4931*4882a593Smuzhiyun             if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
4932*4882a593Smuzhiyun                stbi__de_iphone(z);
4933*4882a593Smuzhiyun             if (pal_img_n) {
4934*4882a593Smuzhiyun                // pal_img_n == 3 or 4
4935*4882a593Smuzhiyun                s->img_n = pal_img_n; // record the actual colors we had
4936*4882a593Smuzhiyun                s->img_out_n = pal_img_n;
4937*4882a593Smuzhiyun                if (req_comp >= 3) s->img_out_n = req_comp;
4938*4882a593Smuzhiyun                if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n))
4939*4882a593Smuzhiyun                   return 0;
4940*4882a593Smuzhiyun             } else if (has_trans) {
4941*4882a593Smuzhiyun                // non-paletted image with tRNS -> source image has (constant) alpha
4942*4882a593Smuzhiyun                ++s->img_n;
4943*4882a593Smuzhiyun             }
4944*4882a593Smuzhiyun             STBI_FREE(z->expanded); z->expanded = NULL;
4945*4882a593Smuzhiyun             return 1;
4946*4882a593Smuzhiyun          }
4947*4882a593Smuzhiyun 
4948*4882a593Smuzhiyun          default:
4949*4882a593Smuzhiyun             // if critical, fail
4950*4882a593Smuzhiyun             if (first) return stbi__err("first not IHDR", "Corrupt PNG");
4951*4882a593Smuzhiyun             if ((c.type & (1 << 29)) == 0) {
4952*4882a593Smuzhiyun                #ifndef STBI_NO_FAILURE_STRINGS
4953*4882a593Smuzhiyun                // not threadsafe
4954*4882a593Smuzhiyun                static char invalid_chunk[] = "XXXX PNG chunk not known";
4955*4882a593Smuzhiyun                invalid_chunk[0] = STBI__BYTECAST(c.type >> 24);
4956*4882a593Smuzhiyun                invalid_chunk[1] = STBI__BYTECAST(c.type >> 16);
4957*4882a593Smuzhiyun                invalid_chunk[2] = STBI__BYTECAST(c.type >>  8);
4958*4882a593Smuzhiyun                invalid_chunk[3] = STBI__BYTECAST(c.type >>  0);
4959*4882a593Smuzhiyun                #endif
4960*4882a593Smuzhiyun                return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type");
4961*4882a593Smuzhiyun             }
4962*4882a593Smuzhiyun             stbi__skip(s, c.length);
4963*4882a593Smuzhiyun             break;
4964*4882a593Smuzhiyun       }
4965*4882a593Smuzhiyun       // end of PNG chunk, read and skip CRC
4966*4882a593Smuzhiyun       stbi__get32be(s);
4967*4882a593Smuzhiyun    }
4968*4882a593Smuzhiyun }
4969*4882a593Smuzhiyun 
stbi__do_png(stbi__png * p,int * x,int * y,int * n,int req_comp,stbi__result_info * ri)4970*4882a593Smuzhiyun static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri)
4971*4882a593Smuzhiyun {
4972*4882a593Smuzhiyun    void *result=NULL;
4973*4882a593Smuzhiyun    if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
4974*4882a593Smuzhiyun    if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
4975*4882a593Smuzhiyun       if (p->depth < 8)
4976*4882a593Smuzhiyun          ri->bits_per_channel = 8;
4977*4882a593Smuzhiyun       else
4978*4882a593Smuzhiyun          ri->bits_per_channel = p->depth;
4979*4882a593Smuzhiyun       result = p->out;
4980*4882a593Smuzhiyun       p->out = NULL;
4981*4882a593Smuzhiyun       if (req_comp && req_comp != p->s->img_out_n) {
4982*4882a593Smuzhiyun          if (ri->bits_per_channel == 8)
4983*4882a593Smuzhiyun             result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
4984*4882a593Smuzhiyun          else
4985*4882a593Smuzhiyun             result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
4986*4882a593Smuzhiyun          p->s->img_out_n = req_comp;
4987*4882a593Smuzhiyun          if (result == NULL) return result;
4988*4882a593Smuzhiyun       }
4989*4882a593Smuzhiyun       *x = p->s->img_x;
4990*4882a593Smuzhiyun       *y = p->s->img_y;
4991*4882a593Smuzhiyun       if (n) *n = p->s->img_n;
4992*4882a593Smuzhiyun    }
4993*4882a593Smuzhiyun    STBI_FREE(p->out);      p->out      = NULL;
4994*4882a593Smuzhiyun    STBI_FREE(p->expanded); p->expanded = NULL;
4995*4882a593Smuzhiyun    STBI_FREE(p->idata);    p->idata    = NULL;
4996*4882a593Smuzhiyun 
4997*4882a593Smuzhiyun    return result;
4998*4882a593Smuzhiyun }
4999*4882a593Smuzhiyun 
stbi__png_load(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri)5000*4882a593Smuzhiyun static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
5001*4882a593Smuzhiyun {
5002*4882a593Smuzhiyun    stbi__png p;
5003*4882a593Smuzhiyun    p.s = s;
5004*4882a593Smuzhiyun    return stbi__do_png(&p, x,y,comp,req_comp, ri);
5005*4882a593Smuzhiyun }
5006*4882a593Smuzhiyun 
stbi__png_test(stbi__context * s)5007*4882a593Smuzhiyun static int stbi__png_test(stbi__context *s)
5008*4882a593Smuzhiyun {
5009*4882a593Smuzhiyun    int r;
5010*4882a593Smuzhiyun    r = stbi__check_png_header(s);
5011*4882a593Smuzhiyun    stbi__rewind(s);
5012*4882a593Smuzhiyun    return r;
5013*4882a593Smuzhiyun }
5014*4882a593Smuzhiyun 
stbi__png_info_raw(stbi__png * p,int * x,int * y,int * comp)5015*4882a593Smuzhiyun static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp)
5016*4882a593Smuzhiyun {
5017*4882a593Smuzhiyun    if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) {
5018*4882a593Smuzhiyun       stbi__rewind( p->s );
5019*4882a593Smuzhiyun       return 0;
5020*4882a593Smuzhiyun    }
5021*4882a593Smuzhiyun    if (x) *x = p->s->img_x;
5022*4882a593Smuzhiyun    if (y) *y = p->s->img_y;
5023*4882a593Smuzhiyun    if (comp) *comp = p->s->img_n;
5024*4882a593Smuzhiyun    return 1;
5025*4882a593Smuzhiyun }
5026*4882a593Smuzhiyun 
stbi__png_info(stbi__context * s,int * x,int * y,int * comp)5027*4882a593Smuzhiyun static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp)
5028*4882a593Smuzhiyun {
5029*4882a593Smuzhiyun    stbi__png p;
5030*4882a593Smuzhiyun    p.s = s;
5031*4882a593Smuzhiyun    return stbi__png_info_raw(&p, x, y, comp);
5032*4882a593Smuzhiyun }
5033*4882a593Smuzhiyun 
stbi__png_is16(stbi__context * s)5034*4882a593Smuzhiyun static int stbi__png_is16(stbi__context *s)
5035*4882a593Smuzhiyun {
5036*4882a593Smuzhiyun    stbi__png p;
5037*4882a593Smuzhiyun    p.s = s;
5038*4882a593Smuzhiyun    if (!stbi__png_info_raw(&p, NULL, NULL, NULL))
5039*4882a593Smuzhiyun 	   return 0;
5040*4882a593Smuzhiyun    if (p.depth != 16) {
5041*4882a593Smuzhiyun       stbi__rewind(p.s);
5042*4882a593Smuzhiyun       return 0;
5043*4882a593Smuzhiyun    }
5044*4882a593Smuzhiyun    return 1;
5045*4882a593Smuzhiyun }
5046*4882a593Smuzhiyun #endif
5047*4882a593Smuzhiyun 
5048*4882a593Smuzhiyun // Microsoft/Windows BMP image
5049*4882a593Smuzhiyun 
5050*4882a593Smuzhiyun #ifndef STBI_NO_BMP
stbi__bmp_test_raw(stbi__context * s)5051*4882a593Smuzhiyun static int stbi__bmp_test_raw(stbi__context *s)
5052*4882a593Smuzhiyun {
5053*4882a593Smuzhiyun    int r;
5054*4882a593Smuzhiyun    int sz;
5055*4882a593Smuzhiyun    if (stbi__get8(s) != 'B') return 0;
5056*4882a593Smuzhiyun    if (stbi__get8(s) != 'M') return 0;
5057*4882a593Smuzhiyun    stbi__get32le(s); // discard filesize
5058*4882a593Smuzhiyun    stbi__get16le(s); // discard reserved
5059*4882a593Smuzhiyun    stbi__get16le(s); // discard reserved
5060*4882a593Smuzhiyun    stbi__get32le(s); // discard data offset
5061*4882a593Smuzhiyun    sz = stbi__get32le(s);
5062*4882a593Smuzhiyun    r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124);
5063*4882a593Smuzhiyun    return r;
5064*4882a593Smuzhiyun }
5065*4882a593Smuzhiyun 
stbi__bmp_test(stbi__context * s)5066*4882a593Smuzhiyun static int stbi__bmp_test(stbi__context *s)
5067*4882a593Smuzhiyun {
5068*4882a593Smuzhiyun    int r = stbi__bmp_test_raw(s);
5069*4882a593Smuzhiyun    stbi__rewind(s);
5070*4882a593Smuzhiyun    return r;
5071*4882a593Smuzhiyun }
5072*4882a593Smuzhiyun 
5073*4882a593Smuzhiyun 
5074*4882a593Smuzhiyun // returns 0..31 for the highest set bit
stbi__high_bit(unsigned int z)5075*4882a593Smuzhiyun static int stbi__high_bit(unsigned int z)
5076*4882a593Smuzhiyun {
5077*4882a593Smuzhiyun    int n=0;
5078*4882a593Smuzhiyun    if (z == 0) return -1;
5079*4882a593Smuzhiyun    if (z >= 0x10000) { n += 16; z >>= 16; }
5080*4882a593Smuzhiyun    if (z >= 0x00100) { n +=  8; z >>=  8; }
5081*4882a593Smuzhiyun    if (z >= 0x00010) { n +=  4; z >>=  4; }
5082*4882a593Smuzhiyun    if (z >= 0x00004) { n +=  2; z >>=  2; }
5083*4882a593Smuzhiyun    if (z >= 0x00002) { n +=  1;/* >>=  1;*/ }
5084*4882a593Smuzhiyun    return n;
5085*4882a593Smuzhiyun }
5086*4882a593Smuzhiyun 
stbi__bitcount(unsigned int a)5087*4882a593Smuzhiyun static int stbi__bitcount(unsigned int a)
5088*4882a593Smuzhiyun {
5089*4882a593Smuzhiyun    a = (a & 0x55555555) + ((a >>  1) & 0x55555555); // max 2
5090*4882a593Smuzhiyun    a = (a & 0x33333333) + ((a >>  2) & 0x33333333); // max 4
5091*4882a593Smuzhiyun    a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits
5092*4882a593Smuzhiyun    a = (a + (a >> 8)); // max 16 per 8 bits
5093*4882a593Smuzhiyun    a = (a + (a >> 16)); // max 32 per 8 bits
5094*4882a593Smuzhiyun    return a & 0xff;
5095*4882a593Smuzhiyun }
5096*4882a593Smuzhiyun 
5097*4882a593Smuzhiyun // extract an arbitrarily-aligned N-bit value (N=bits)
5098*4882a593Smuzhiyun // from v, and then make it 8-bits long and fractionally
5099*4882a593Smuzhiyun // extend it to full full range.
stbi__shiftsigned(unsigned int v,int shift,int bits)5100*4882a593Smuzhiyun static int stbi__shiftsigned(unsigned int v, int shift, int bits)
5101*4882a593Smuzhiyun {
5102*4882a593Smuzhiyun    static unsigned int mul_table[9] = {
5103*4882a593Smuzhiyun       0,
5104*4882a593Smuzhiyun       0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/,
5105*4882a593Smuzhiyun       0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/,
5106*4882a593Smuzhiyun    };
5107*4882a593Smuzhiyun    static unsigned int shift_table[9] = {
5108*4882a593Smuzhiyun       0, 0,0,1,0,2,4,6,0,
5109*4882a593Smuzhiyun    };
5110*4882a593Smuzhiyun    if (shift < 0)
5111*4882a593Smuzhiyun       v <<= -shift;
5112*4882a593Smuzhiyun    else
5113*4882a593Smuzhiyun       v >>= shift;
5114*4882a593Smuzhiyun    STBI_ASSERT(v >= 0 && v < 256);
5115*4882a593Smuzhiyun    v >>= (8-bits);
5116*4882a593Smuzhiyun    STBI_ASSERT(bits >= 0 && bits <= 8);
5117*4882a593Smuzhiyun    return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
5118*4882a593Smuzhiyun }
5119*4882a593Smuzhiyun 
5120*4882a593Smuzhiyun typedef struct
5121*4882a593Smuzhiyun {
5122*4882a593Smuzhiyun    int bpp, offset, hsz;
5123*4882a593Smuzhiyun    unsigned int mr,mg,mb,ma, all_a;
5124*4882a593Smuzhiyun } stbi__bmp_data;
5125*4882a593Smuzhiyun 
stbi__bmp_parse_header(stbi__context * s,stbi__bmp_data * info)5126*4882a593Smuzhiyun static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
5127*4882a593Smuzhiyun {
5128*4882a593Smuzhiyun    int hsz;
5129*4882a593Smuzhiyun    if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP");
5130*4882a593Smuzhiyun    stbi__get32le(s); // discard filesize
5131*4882a593Smuzhiyun    stbi__get16le(s); // discard reserved
5132*4882a593Smuzhiyun    stbi__get16le(s); // discard reserved
5133*4882a593Smuzhiyun    info->offset = stbi__get32le(s);
5134*4882a593Smuzhiyun    info->hsz = hsz = stbi__get32le(s);
5135*4882a593Smuzhiyun    info->mr = info->mg = info->mb = info->ma = 0;
5136*4882a593Smuzhiyun 
5137*4882a593Smuzhiyun    if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
5138*4882a593Smuzhiyun    if (hsz == 12) {
5139*4882a593Smuzhiyun       s->img_x = stbi__get16le(s);
5140*4882a593Smuzhiyun       s->img_y = stbi__get16le(s);
5141*4882a593Smuzhiyun    } else {
5142*4882a593Smuzhiyun       s->img_x = stbi__get32le(s);
5143*4882a593Smuzhiyun       s->img_y = stbi__get32le(s);
5144*4882a593Smuzhiyun    }
5145*4882a593Smuzhiyun    if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP");
5146*4882a593Smuzhiyun    info->bpp = stbi__get16le(s);
5147*4882a593Smuzhiyun    if (hsz != 12) {
5148*4882a593Smuzhiyun       int compress = stbi__get32le(s);
5149*4882a593Smuzhiyun       if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
5150*4882a593Smuzhiyun       stbi__get32le(s); // discard sizeof
5151*4882a593Smuzhiyun       stbi__get32le(s); // discard hres
5152*4882a593Smuzhiyun       stbi__get32le(s); // discard vres
5153*4882a593Smuzhiyun       stbi__get32le(s); // discard colorsused
5154*4882a593Smuzhiyun       stbi__get32le(s); // discard max important
5155*4882a593Smuzhiyun       if (hsz == 40 || hsz == 56) {
5156*4882a593Smuzhiyun          if (hsz == 56) {
5157*4882a593Smuzhiyun             stbi__get32le(s);
5158*4882a593Smuzhiyun             stbi__get32le(s);
5159*4882a593Smuzhiyun             stbi__get32le(s);
5160*4882a593Smuzhiyun             stbi__get32le(s);
5161*4882a593Smuzhiyun          }
5162*4882a593Smuzhiyun          if (info->bpp == 16 || info->bpp == 32) {
5163*4882a593Smuzhiyun             if (compress == 0) {
5164*4882a593Smuzhiyun                if (info->bpp == 32) {
5165*4882a593Smuzhiyun                   info->mr = 0xffu << 16;
5166*4882a593Smuzhiyun                   info->mg = 0xffu <<  8;
5167*4882a593Smuzhiyun                   info->mb = 0xffu <<  0;
5168*4882a593Smuzhiyun                   info->ma = 0xffu << 24;
5169*4882a593Smuzhiyun                   info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
5170*4882a593Smuzhiyun                } else {
5171*4882a593Smuzhiyun                   info->mr = 31u << 10;
5172*4882a593Smuzhiyun                   info->mg = 31u <<  5;
5173*4882a593Smuzhiyun                   info->mb = 31u <<  0;
5174*4882a593Smuzhiyun                }
5175*4882a593Smuzhiyun             } else if (compress == 3) {
5176*4882a593Smuzhiyun                info->mr = stbi__get32le(s);
5177*4882a593Smuzhiyun                info->mg = stbi__get32le(s);
5178*4882a593Smuzhiyun                info->mb = stbi__get32le(s);
5179*4882a593Smuzhiyun                // not documented, but generated by photoshop and handled by mspaint
5180*4882a593Smuzhiyun                if (info->mr == info->mg && info->mg == info->mb) {
5181*4882a593Smuzhiyun                   // ?!?!?
5182*4882a593Smuzhiyun                   return stbi__errpuc("bad BMP", "bad BMP");
5183*4882a593Smuzhiyun                }
5184*4882a593Smuzhiyun             } else
5185*4882a593Smuzhiyun                return stbi__errpuc("bad BMP", "bad BMP");
5186*4882a593Smuzhiyun          }
5187*4882a593Smuzhiyun       } else {
5188*4882a593Smuzhiyun          int i;
5189*4882a593Smuzhiyun          if (hsz != 108 && hsz != 124)
5190*4882a593Smuzhiyun             return stbi__errpuc("bad BMP", "bad BMP");
5191*4882a593Smuzhiyun          info->mr = stbi__get32le(s);
5192*4882a593Smuzhiyun          info->mg = stbi__get32le(s);
5193*4882a593Smuzhiyun          info->mb = stbi__get32le(s);
5194*4882a593Smuzhiyun          info->ma = stbi__get32le(s);
5195*4882a593Smuzhiyun          stbi__get32le(s); // discard color space
5196*4882a593Smuzhiyun          for (i=0; i < 12; ++i)
5197*4882a593Smuzhiyun             stbi__get32le(s); // discard color space parameters
5198*4882a593Smuzhiyun          if (hsz == 124) {
5199*4882a593Smuzhiyun             stbi__get32le(s); // discard rendering intent
5200*4882a593Smuzhiyun             stbi__get32le(s); // discard offset of profile data
5201*4882a593Smuzhiyun             stbi__get32le(s); // discard size of profile data
5202*4882a593Smuzhiyun             stbi__get32le(s); // discard reserved
5203*4882a593Smuzhiyun          }
5204*4882a593Smuzhiyun       }
5205*4882a593Smuzhiyun    }
5206*4882a593Smuzhiyun    return (void *) 1;
5207*4882a593Smuzhiyun }
5208*4882a593Smuzhiyun 
5209*4882a593Smuzhiyun 
stbi__bmp_load(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri)5210*4882a593Smuzhiyun static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
5211*4882a593Smuzhiyun {
5212*4882a593Smuzhiyun    stbi_uc *out;
5213*4882a593Smuzhiyun    unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
5214*4882a593Smuzhiyun    stbi_uc pal[256][4];
5215*4882a593Smuzhiyun    int psize=0,i,j,width;
5216*4882a593Smuzhiyun    int flip_vertically, pad, target;
5217*4882a593Smuzhiyun    stbi__bmp_data info;
5218*4882a593Smuzhiyun    STBI_NOTUSED(ri);
5219*4882a593Smuzhiyun 
5220*4882a593Smuzhiyun    info.all_a = 255;
5221*4882a593Smuzhiyun    if (stbi__bmp_parse_header(s, &info) == NULL)
5222*4882a593Smuzhiyun       return NULL; // error code already set
5223*4882a593Smuzhiyun 
5224*4882a593Smuzhiyun    flip_vertically = ((int) s->img_y) > 0;
5225*4882a593Smuzhiyun    s->img_y = abs((int) s->img_y);
5226*4882a593Smuzhiyun 
5227*4882a593Smuzhiyun    mr = info.mr;
5228*4882a593Smuzhiyun    mg = info.mg;
5229*4882a593Smuzhiyun    mb = info.mb;
5230*4882a593Smuzhiyun    ma = info.ma;
5231*4882a593Smuzhiyun    all_a = info.all_a;
5232*4882a593Smuzhiyun 
5233*4882a593Smuzhiyun    if (info.hsz == 12) {
5234*4882a593Smuzhiyun       if (info.bpp < 24)
5235*4882a593Smuzhiyun          psize = (info.offset - 14 - 24) / 3;
5236*4882a593Smuzhiyun    } else {
5237*4882a593Smuzhiyun       if (info.bpp < 16)
5238*4882a593Smuzhiyun          psize = (info.offset - 14 - info.hsz) >> 2;
5239*4882a593Smuzhiyun    }
5240*4882a593Smuzhiyun 
5241*4882a593Smuzhiyun    if (info.bpp == 24 && ma == 0xff000000)
5242*4882a593Smuzhiyun       s->img_n = 3;
5243*4882a593Smuzhiyun    else
5244*4882a593Smuzhiyun       s->img_n = ma ? 4 : 3;
5245*4882a593Smuzhiyun    if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
5246*4882a593Smuzhiyun       target = req_comp;
5247*4882a593Smuzhiyun    else
5248*4882a593Smuzhiyun       target = s->img_n; // if they want monochrome, we'll post-convert
5249*4882a593Smuzhiyun 
5250*4882a593Smuzhiyun    // sanity-check size
5251*4882a593Smuzhiyun    if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0))
5252*4882a593Smuzhiyun       return stbi__errpuc("too large", "Corrupt BMP");
5253*4882a593Smuzhiyun 
5254*4882a593Smuzhiyun    out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0);
5255*4882a593Smuzhiyun    if (!out) return stbi__errpuc("outofmem", "Out of memory");
5256*4882a593Smuzhiyun    if (info.bpp < 16) {
5257*4882a593Smuzhiyun       int z=0;
5258*4882a593Smuzhiyun       if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); }
5259*4882a593Smuzhiyun       for (i=0; i < psize; ++i) {
5260*4882a593Smuzhiyun          pal[i][2] = stbi__get8(s);
5261*4882a593Smuzhiyun          pal[i][1] = stbi__get8(s);
5262*4882a593Smuzhiyun          pal[i][0] = stbi__get8(s);
5263*4882a593Smuzhiyun          if (info.hsz != 12) stbi__get8(s);
5264*4882a593Smuzhiyun          pal[i][3] = 255;
5265*4882a593Smuzhiyun       }
5266*4882a593Smuzhiyun       stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
5267*4882a593Smuzhiyun       if (info.bpp == 1) width = (s->img_x + 7) >> 3;
5268*4882a593Smuzhiyun       else if (info.bpp == 4) width = (s->img_x + 1) >> 1;
5269*4882a593Smuzhiyun       else if (info.bpp == 8) width = s->img_x;
5270*4882a593Smuzhiyun       else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); }
5271*4882a593Smuzhiyun       pad = (-width)&3;
5272*4882a593Smuzhiyun       if (info.bpp == 1) {
5273*4882a593Smuzhiyun          for (j=0; j < (int) s->img_y; ++j) {
5274*4882a593Smuzhiyun             int bit_offset = 7, v = stbi__get8(s);
5275*4882a593Smuzhiyun             for (i=0; i < (int) s->img_x; ++i) {
5276*4882a593Smuzhiyun                int color = (v>>bit_offset)&0x1;
5277*4882a593Smuzhiyun                out[z++] = pal[color][0];
5278*4882a593Smuzhiyun                out[z++] = pal[color][1];
5279*4882a593Smuzhiyun                out[z++] = pal[color][2];
5280*4882a593Smuzhiyun                if (target == 4) out[z++] = 255;
5281*4882a593Smuzhiyun                if (i+1 == (int) s->img_x) break;
5282*4882a593Smuzhiyun                if((--bit_offset) < 0) {
5283*4882a593Smuzhiyun                   bit_offset = 7;
5284*4882a593Smuzhiyun                   v = stbi__get8(s);
5285*4882a593Smuzhiyun                }
5286*4882a593Smuzhiyun             }
5287*4882a593Smuzhiyun             stbi__skip(s, pad);
5288*4882a593Smuzhiyun          }
5289*4882a593Smuzhiyun       } else {
5290*4882a593Smuzhiyun          for (j=0; j < (int) s->img_y; ++j) {
5291*4882a593Smuzhiyun             for (i=0; i < (int) s->img_x; i += 2) {
5292*4882a593Smuzhiyun                int v=stbi__get8(s),v2=0;
5293*4882a593Smuzhiyun                if (info.bpp == 4) {
5294*4882a593Smuzhiyun                   v2 = v & 15;
5295*4882a593Smuzhiyun                   v >>= 4;
5296*4882a593Smuzhiyun                }
5297*4882a593Smuzhiyun                out[z++] = pal[v][0];
5298*4882a593Smuzhiyun                out[z++] = pal[v][1];
5299*4882a593Smuzhiyun                out[z++] = pal[v][2];
5300*4882a593Smuzhiyun                if (target == 4) out[z++] = 255;
5301*4882a593Smuzhiyun                if (i+1 == (int) s->img_x) break;
5302*4882a593Smuzhiyun                v = (info.bpp == 8) ? stbi__get8(s) : v2;
5303*4882a593Smuzhiyun                out[z++] = pal[v][0];
5304*4882a593Smuzhiyun                out[z++] = pal[v][1];
5305*4882a593Smuzhiyun                out[z++] = pal[v][2];
5306*4882a593Smuzhiyun                if (target == 4) out[z++] = 255;
5307*4882a593Smuzhiyun             }
5308*4882a593Smuzhiyun             stbi__skip(s, pad);
5309*4882a593Smuzhiyun          }
5310*4882a593Smuzhiyun       }
5311*4882a593Smuzhiyun    } else {
5312*4882a593Smuzhiyun       int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
5313*4882a593Smuzhiyun       int z = 0;
5314*4882a593Smuzhiyun       int easy=0;
5315*4882a593Smuzhiyun       stbi__skip(s, info.offset - 14 - info.hsz);
5316*4882a593Smuzhiyun       if (info.bpp == 24) width = 3 * s->img_x;
5317*4882a593Smuzhiyun       else if (info.bpp == 16) width = 2*s->img_x;
5318*4882a593Smuzhiyun       else /* bpp = 32 and pad = 0 */ width=0;
5319*4882a593Smuzhiyun       pad = (-width) & 3;
5320*4882a593Smuzhiyun       if (info.bpp == 24) {
5321*4882a593Smuzhiyun          easy = 1;
5322*4882a593Smuzhiyun       } else if (info.bpp == 32) {
5323*4882a593Smuzhiyun          if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
5324*4882a593Smuzhiyun             easy = 2;
5325*4882a593Smuzhiyun       }
5326*4882a593Smuzhiyun       if (!easy) {
5327*4882a593Smuzhiyun          if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
5328*4882a593Smuzhiyun          // right shift amt to put high bit in position #7
5329*4882a593Smuzhiyun          rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr);
5330*4882a593Smuzhiyun          gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
5331*4882a593Smuzhiyun          bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
5332*4882a593Smuzhiyun          ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
5333*4882a593Smuzhiyun       }
5334*4882a593Smuzhiyun       for (j=0; j < (int) s->img_y; ++j) {
5335*4882a593Smuzhiyun          if (easy) {
5336*4882a593Smuzhiyun             for (i=0; i < (int) s->img_x; ++i) {
5337*4882a593Smuzhiyun                unsigned char a;
5338*4882a593Smuzhiyun                out[z+2] = stbi__get8(s);
5339*4882a593Smuzhiyun                out[z+1] = stbi__get8(s);
5340*4882a593Smuzhiyun                out[z+0] = stbi__get8(s);
5341*4882a593Smuzhiyun                z += 3;
5342*4882a593Smuzhiyun                a = (easy == 2 ? stbi__get8(s) : 255);
5343*4882a593Smuzhiyun                all_a |= a;
5344*4882a593Smuzhiyun                if (target == 4) out[z++] = a;
5345*4882a593Smuzhiyun             }
5346*4882a593Smuzhiyun          } else {
5347*4882a593Smuzhiyun             int bpp = info.bpp;
5348*4882a593Smuzhiyun             for (i=0; i < (int) s->img_x; ++i) {
5349*4882a593Smuzhiyun                stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
5350*4882a593Smuzhiyun                unsigned int a;
5351*4882a593Smuzhiyun                out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
5352*4882a593Smuzhiyun                out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
5353*4882a593Smuzhiyun                out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount));
5354*4882a593Smuzhiyun                a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255);
5355*4882a593Smuzhiyun                all_a |= a;
5356*4882a593Smuzhiyun                if (target == 4) out[z++] = STBI__BYTECAST(a);
5357*4882a593Smuzhiyun             }
5358*4882a593Smuzhiyun          }
5359*4882a593Smuzhiyun          stbi__skip(s, pad);
5360*4882a593Smuzhiyun       }
5361*4882a593Smuzhiyun    }
5362*4882a593Smuzhiyun 
5363*4882a593Smuzhiyun    // if alpha channel is all 0s, replace with all 255s
5364*4882a593Smuzhiyun    if (target == 4 && all_a == 0)
5365*4882a593Smuzhiyun       for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
5366*4882a593Smuzhiyun          out[i] = 255;
5367*4882a593Smuzhiyun 
5368*4882a593Smuzhiyun    if (flip_vertically) {
5369*4882a593Smuzhiyun       stbi_uc t;
5370*4882a593Smuzhiyun       for (j=0; j < (int) s->img_y>>1; ++j) {
5371*4882a593Smuzhiyun          stbi_uc *p1 = out +      j     *s->img_x*target;
5372*4882a593Smuzhiyun          stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
5373*4882a593Smuzhiyun          for (i=0; i < (int) s->img_x*target; ++i) {
5374*4882a593Smuzhiyun             t = p1[i]; p1[i] = p2[i]; p2[i] = t;
5375*4882a593Smuzhiyun          }
5376*4882a593Smuzhiyun       }
5377*4882a593Smuzhiyun    }
5378*4882a593Smuzhiyun 
5379*4882a593Smuzhiyun    if (req_comp && req_comp != target) {
5380*4882a593Smuzhiyun       out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y);
5381*4882a593Smuzhiyun       if (out == NULL) return out; // stbi__convert_format frees input on failure
5382*4882a593Smuzhiyun    }
5383*4882a593Smuzhiyun 
5384*4882a593Smuzhiyun    *x = s->img_x;
5385*4882a593Smuzhiyun    *y = s->img_y;
5386*4882a593Smuzhiyun    if (comp) *comp = s->img_n;
5387*4882a593Smuzhiyun    return out;
5388*4882a593Smuzhiyun }
5389*4882a593Smuzhiyun #endif
5390*4882a593Smuzhiyun 
5391*4882a593Smuzhiyun // Targa Truevision - TGA
5392*4882a593Smuzhiyun // by Jonathan Dummer
5393*4882a593Smuzhiyun #ifndef STBI_NO_TGA
5394*4882a593Smuzhiyun // returns STBI_rgb or whatever, 0 on error
stbi__tga_get_comp(int bits_per_pixel,int is_grey,int * is_rgb16)5395*4882a593Smuzhiyun static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
5396*4882a593Smuzhiyun {
5397*4882a593Smuzhiyun    // only RGB or RGBA (incl. 16bit) or grey allowed
5398*4882a593Smuzhiyun    if (is_rgb16) *is_rgb16 = 0;
5399*4882a593Smuzhiyun    switch(bits_per_pixel) {
5400*4882a593Smuzhiyun       case 8:  return STBI_grey;
5401*4882a593Smuzhiyun       case 16: if(is_grey) return STBI_grey_alpha;
5402*4882a593Smuzhiyun                // fallthrough
5403*4882a593Smuzhiyun       case 15: if(is_rgb16) *is_rgb16 = 1;
5404*4882a593Smuzhiyun                return STBI_rgb;
5405*4882a593Smuzhiyun       case 24: // fallthrough
5406*4882a593Smuzhiyun       case 32: return bits_per_pixel/8;
5407*4882a593Smuzhiyun       default: return 0;
5408*4882a593Smuzhiyun    }
5409*4882a593Smuzhiyun }
5410*4882a593Smuzhiyun 
stbi__tga_info(stbi__context * s,int * x,int * y,int * comp)5411*4882a593Smuzhiyun static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
5412*4882a593Smuzhiyun {
5413*4882a593Smuzhiyun     int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
5414*4882a593Smuzhiyun     int sz, tga_colormap_type;
5415*4882a593Smuzhiyun     stbi__get8(s);                   // discard Offset
5416*4882a593Smuzhiyun     tga_colormap_type = stbi__get8(s); // colormap type
5417*4882a593Smuzhiyun     if( tga_colormap_type > 1 ) {
5418*4882a593Smuzhiyun         stbi__rewind(s);
5419*4882a593Smuzhiyun         return 0;      // only RGB or indexed allowed
5420*4882a593Smuzhiyun     }
5421*4882a593Smuzhiyun     tga_image_type = stbi__get8(s); // image type
5422*4882a593Smuzhiyun     if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
5423*4882a593Smuzhiyun         if (tga_image_type != 1 && tga_image_type != 9) {
5424*4882a593Smuzhiyun             stbi__rewind(s);
5425*4882a593Smuzhiyun             return 0;
5426*4882a593Smuzhiyun         }
5427*4882a593Smuzhiyun         stbi__skip(s,4);       // skip index of first colormap entry and number of entries
5428*4882a593Smuzhiyun         sz = stbi__get8(s);    //   check bits per palette color entry
5429*4882a593Smuzhiyun         if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) {
5430*4882a593Smuzhiyun             stbi__rewind(s);
5431*4882a593Smuzhiyun             return 0;
5432*4882a593Smuzhiyun         }
5433*4882a593Smuzhiyun         stbi__skip(s,4);       // skip image x and y origin
5434*4882a593Smuzhiyun         tga_colormap_bpp = sz;
5435*4882a593Smuzhiyun     } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
5436*4882a593Smuzhiyun         if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) {
5437*4882a593Smuzhiyun             stbi__rewind(s);
5438*4882a593Smuzhiyun             return 0; // only RGB or grey allowed, +/- RLE
5439*4882a593Smuzhiyun         }
5440*4882a593Smuzhiyun         stbi__skip(s,9); // skip colormap specification and image x/y origin
5441*4882a593Smuzhiyun         tga_colormap_bpp = 0;
5442*4882a593Smuzhiyun     }
5443*4882a593Smuzhiyun     tga_w = stbi__get16le(s);
5444*4882a593Smuzhiyun     if( tga_w < 1 ) {
5445*4882a593Smuzhiyun         stbi__rewind(s);
5446*4882a593Smuzhiyun         return 0;   // test width
5447*4882a593Smuzhiyun     }
5448*4882a593Smuzhiyun     tga_h = stbi__get16le(s);
5449*4882a593Smuzhiyun     if( tga_h < 1 ) {
5450*4882a593Smuzhiyun         stbi__rewind(s);
5451*4882a593Smuzhiyun         return 0;   // test height
5452*4882a593Smuzhiyun     }
5453*4882a593Smuzhiyun     tga_bits_per_pixel = stbi__get8(s); // bits per pixel
5454*4882a593Smuzhiyun     stbi__get8(s); // ignore alpha bits
5455*4882a593Smuzhiyun     if (tga_colormap_bpp != 0) {
5456*4882a593Smuzhiyun         if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
5457*4882a593Smuzhiyun             // when using a colormap, tga_bits_per_pixel is the size of the indexes
5458*4882a593Smuzhiyun             // I don't think anything but 8 or 16bit indexes makes sense
5459*4882a593Smuzhiyun             stbi__rewind(s);
5460*4882a593Smuzhiyun             return 0;
5461*4882a593Smuzhiyun         }
5462*4882a593Smuzhiyun         tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
5463*4882a593Smuzhiyun     } else {
5464*4882a593Smuzhiyun         tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
5465*4882a593Smuzhiyun     }
5466*4882a593Smuzhiyun     if(!tga_comp) {
5467*4882a593Smuzhiyun       stbi__rewind(s);
5468*4882a593Smuzhiyun       return 0;
5469*4882a593Smuzhiyun     }
5470*4882a593Smuzhiyun     if (x) *x = tga_w;
5471*4882a593Smuzhiyun     if (y) *y = tga_h;
5472*4882a593Smuzhiyun     if (comp) *comp = tga_comp;
5473*4882a593Smuzhiyun     return 1;                   // seems to have passed everything
5474*4882a593Smuzhiyun }
5475*4882a593Smuzhiyun 
stbi__tga_test(stbi__context * s)5476*4882a593Smuzhiyun static int stbi__tga_test(stbi__context *s)
5477*4882a593Smuzhiyun {
5478*4882a593Smuzhiyun    int res = 0;
5479*4882a593Smuzhiyun    int sz, tga_color_type;
5480*4882a593Smuzhiyun    stbi__get8(s);      //   discard Offset
5481*4882a593Smuzhiyun    tga_color_type = stbi__get8(s);   //   color type
5482*4882a593Smuzhiyun    if ( tga_color_type > 1 ) goto errorEnd;   //   only RGB or indexed allowed
5483*4882a593Smuzhiyun    sz = stbi__get8(s);   //   image type
5484*4882a593Smuzhiyun    if ( tga_color_type == 1 ) { // colormapped (paletted) image
5485*4882a593Smuzhiyun       if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
5486*4882a593Smuzhiyun       stbi__skip(s,4);       // skip index of first colormap entry and number of entries
5487*4882a593Smuzhiyun       sz = stbi__get8(s);    //   check bits per palette color entry
5488*4882a593Smuzhiyun       if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
5489*4882a593Smuzhiyun       stbi__skip(s,4);       // skip image x and y origin
5490*4882a593Smuzhiyun    } else { // "normal" image w/o colormap
5491*4882a593Smuzhiyun       if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE
5492*4882a593Smuzhiyun       stbi__skip(s,9); // skip colormap specification and image x/y origin
5493*4882a593Smuzhiyun    }
5494*4882a593Smuzhiyun    if ( stbi__get16le(s) < 1 ) goto errorEnd;      //   test width
5495*4882a593Smuzhiyun    if ( stbi__get16le(s) < 1 ) goto errorEnd;      //   test height
5496*4882a593Smuzhiyun    sz = stbi__get8(s);   //   bits per pixel
5497*4882a593Smuzhiyun    if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
5498*4882a593Smuzhiyun    if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
5499*4882a593Smuzhiyun 
5500*4882a593Smuzhiyun    res = 1; // if we got this far, everything's good and we can return 1 instead of 0
5501*4882a593Smuzhiyun 
5502*4882a593Smuzhiyun errorEnd:
5503*4882a593Smuzhiyun    stbi__rewind(s);
5504*4882a593Smuzhiyun    return res;
5505*4882a593Smuzhiyun }
5506*4882a593Smuzhiyun 
5507*4882a593Smuzhiyun // read 16bit value and convert to 24bit RGB
stbi__tga_read_rgb16(stbi__context * s,stbi_uc * out)5508*4882a593Smuzhiyun static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
5509*4882a593Smuzhiyun {
5510*4882a593Smuzhiyun    stbi__uint16 px = (stbi__uint16)stbi__get16le(s);
5511*4882a593Smuzhiyun    stbi__uint16 fiveBitMask = 31;
5512*4882a593Smuzhiyun    // we have 3 channels with 5bits each
5513*4882a593Smuzhiyun    int r = (px >> 10) & fiveBitMask;
5514*4882a593Smuzhiyun    int g = (px >> 5) & fiveBitMask;
5515*4882a593Smuzhiyun    int b = px & fiveBitMask;
5516*4882a593Smuzhiyun    // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
5517*4882a593Smuzhiyun    out[0] = (stbi_uc)((r * 255)/31);
5518*4882a593Smuzhiyun    out[1] = (stbi_uc)((g * 255)/31);
5519*4882a593Smuzhiyun    out[2] = (stbi_uc)((b * 255)/31);
5520*4882a593Smuzhiyun 
5521*4882a593Smuzhiyun    // some people claim that the most significant bit might be used for alpha
5522*4882a593Smuzhiyun    // (possibly if an alpha-bit is set in the "image descriptor byte")
5523*4882a593Smuzhiyun    // but that only made 16bit test images completely translucent..
5524*4882a593Smuzhiyun    // so let's treat all 15 and 16bit TGAs as RGB with no alpha.
5525*4882a593Smuzhiyun }
5526*4882a593Smuzhiyun 
stbi__tga_load(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri)5527*4882a593Smuzhiyun static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
5528*4882a593Smuzhiyun {
5529*4882a593Smuzhiyun    //   read in the TGA header stuff
5530*4882a593Smuzhiyun    int tga_offset = stbi__get8(s);
5531*4882a593Smuzhiyun    int tga_indexed = stbi__get8(s);
5532*4882a593Smuzhiyun    int tga_image_type = stbi__get8(s);
5533*4882a593Smuzhiyun    int tga_is_RLE = 0;
5534*4882a593Smuzhiyun    int tga_palette_start = stbi__get16le(s);
5535*4882a593Smuzhiyun    int tga_palette_len = stbi__get16le(s);
5536*4882a593Smuzhiyun    int tga_palette_bits = stbi__get8(s);
5537*4882a593Smuzhiyun    int tga_x_origin = stbi__get16le(s);
5538*4882a593Smuzhiyun    int tga_y_origin = stbi__get16le(s);
5539*4882a593Smuzhiyun    int tga_width = stbi__get16le(s);
5540*4882a593Smuzhiyun    int tga_height = stbi__get16le(s);
5541*4882a593Smuzhiyun    int tga_bits_per_pixel = stbi__get8(s);
5542*4882a593Smuzhiyun    int tga_comp, tga_rgb16=0;
5543*4882a593Smuzhiyun    int tga_inverted = stbi__get8(s);
5544*4882a593Smuzhiyun    // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
5545*4882a593Smuzhiyun    //   image data
5546*4882a593Smuzhiyun    unsigned char *tga_data;
5547*4882a593Smuzhiyun    unsigned char *tga_palette = NULL;
5548*4882a593Smuzhiyun    int i, j;
5549*4882a593Smuzhiyun    unsigned char raw_data[4] = {0};
5550*4882a593Smuzhiyun    int RLE_count = 0;
5551*4882a593Smuzhiyun    int RLE_repeating = 0;
5552*4882a593Smuzhiyun    int read_next_pixel = 1;
5553*4882a593Smuzhiyun    STBI_NOTUSED(ri);
5554*4882a593Smuzhiyun    STBI_NOTUSED(tga_x_origin); // @TODO
5555*4882a593Smuzhiyun    STBI_NOTUSED(tga_y_origin); // @TODO
5556*4882a593Smuzhiyun 
5557*4882a593Smuzhiyun    //   do a tiny bit of precessing
5558*4882a593Smuzhiyun    if ( tga_image_type >= 8 )
5559*4882a593Smuzhiyun    {
5560*4882a593Smuzhiyun       tga_image_type -= 8;
5561*4882a593Smuzhiyun       tga_is_RLE = 1;
5562*4882a593Smuzhiyun    }
5563*4882a593Smuzhiyun    tga_inverted = 1 - ((tga_inverted >> 5) & 1);
5564*4882a593Smuzhiyun 
5565*4882a593Smuzhiyun    //   If I'm paletted, then I'll use the number of bits from the palette
5566*4882a593Smuzhiyun    if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
5567*4882a593Smuzhiyun    else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
5568*4882a593Smuzhiyun 
5569*4882a593Smuzhiyun    if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
5570*4882a593Smuzhiyun       return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
5571*4882a593Smuzhiyun 
5572*4882a593Smuzhiyun    //   tga info
5573*4882a593Smuzhiyun    *x = tga_width;
5574*4882a593Smuzhiyun    *y = tga_height;
5575*4882a593Smuzhiyun    if (comp) *comp = tga_comp;
5576*4882a593Smuzhiyun 
5577*4882a593Smuzhiyun    if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0))
5578*4882a593Smuzhiyun       return stbi__errpuc("too large", "Corrupt TGA");
5579*4882a593Smuzhiyun 
5580*4882a593Smuzhiyun    tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
5581*4882a593Smuzhiyun    if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
5582*4882a593Smuzhiyun 
5583*4882a593Smuzhiyun    // skip to the data's starting position (offset usually = 0)
5584*4882a593Smuzhiyun    stbi__skip(s, tga_offset );
5585*4882a593Smuzhiyun 
5586*4882a593Smuzhiyun    if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) {
5587*4882a593Smuzhiyun       for (i=0; i < tga_height; ++i) {
5588*4882a593Smuzhiyun          int row = tga_inverted ? tga_height -i - 1 : i;
5589*4882a593Smuzhiyun          stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
5590*4882a593Smuzhiyun          stbi__getn(s, tga_row, tga_width * tga_comp);
5591*4882a593Smuzhiyun       }
5592*4882a593Smuzhiyun    } else  {
5593*4882a593Smuzhiyun       //   do I need to load a palette?
5594*4882a593Smuzhiyun       if ( tga_indexed)
5595*4882a593Smuzhiyun       {
5596*4882a593Smuzhiyun          //   any data to skip? (offset usually = 0)
5597*4882a593Smuzhiyun          stbi__skip(s, tga_palette_start );
5598*4882a593Smuzhiyun          //   load the palette
5599*4882a593Smuzhiyun          tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);
5600*4882a593Smuzhiyun          if (!tga_palette) {
5601*4882a593Smuzhiyun             STBI_FREE(tga_data);
5602*4882a593Smuzhiyun             return stbi__errpuc("outofmem", "Out of memory");
5603*4882a593Smuzhiyun          }
5604*4882a593Smuzhiyun          if (tga_rgb16) {
5605*4882a593Smuzhiyun             stbi_uc *pal_entry = tga_palette;
5606*4882a593Smuzhiyun             STBI_ASSERT(tga_comp == STBI_rgb);
5607*4882a593Smuzhiyun             for (i=0; i < tga_palette_len; ++i) {
5608*4882a593Smuzhiyun                stbi__tga_read_rgb16(s, pal_entry);
5609*4882a593Smuzhiyun                pal_entry += tga_comp;
5610*4882a593Smuzhiyun             }
5611*4882a593Smuzhiyun          } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
5612*4882a593Smuzhiyun                STBI_FREE(tga_data);
5613*4882a593Smuzhiyun                STBI_FREE(tga_palette);
5614*4882a593Smuzhiyun                return stbi__errpuc("bad palette", "Corrupt TGA");
5615*4882a593Smuzhiyun          }
5616*4882a593Smuzhiyun       }
5617*4882a593Smuzhiyun       //   load the data
5618*4882a593Smuzhiyun       for (i=0; i < tga_width * tga_height; ++i)
5619*4882a593Smuzhiyun       {
5620*4882a593Smuzhiyun          //   if I'm in RLE mode, do I need to get a RLE stbi__pngchunk?
5621*4882a593Smuzhiyun          if ( tga_is_RLE )
5622*4882a593Smuzhiyun          {
5623*4882a593Smuzhiyun             if ( RLE_count == 0 )
5624*4882a593Smuzhiyun             {
5625*4882a593Smuzhiyun                //   yep, get the next byte as a RLE command
5626*4882a593Smuzhiyun                int RLE_cmd = stbi__get8(s);
5627*4882a593Smuzhiyun                RLE_count = 1 + (RLE_cmd & 127);
5628*4882a593Smuzhiyun                RLE_repeating = RLE_cmd >> 7;
5629*4882a593Smuzhiyun                read_next_pixel = 1;
5630*4882a593Smuzhiyun             } else if ( !RLE_repeating )
5631*4882a593Smuzhiyun             {
5632*4882a593Smuzhiyun                read_next_pixel = 1;
5633*4882a593Smuzhiyun             }
5634*4882a593Smuzhiyun          } else
5635*4882a593Smuzhiyun          {
5636*4882a593Smuzhiyun             read_next_pixel = 1;
5637*4882a593Smuzhiyun          }
5638*4882a593Smuzhiyun          //   OK, if I need to read a pixel, do it now
5639*4882a593Smuzhiyun          if ( read_next_pixel )
5640*4882a593Smuzhiyun          {
5641*4882a593Smuzhiyun             //   load however much data we did have
5642*4882a593Smuzhiyun             if ( tga_indexed )
5643*4882a593Smuzhiyun             {
5644*4882a593Smuzhiyun                // read in index, then perform the lookup
5645*4882a593Smuzhiyun                int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
5646*4882a593Smuzhiyun                if ( pal_idx >= tga_palette_len ) {
5647*4882a593Smuzhiyun                   // invalid index
5648*4882a593Smuzhiyun                   pal_idx = 0;
5649*4882a593Smuzhiyun                }
5650*4882a593Smuzhiyun                pal_idx *= tga_comp;
5651*4882a593Smuzhiyun                for (j = 0; j < tga_comp; ++j) {
5652*4882a593Smuzhiyun                   raw_data[j] = tga_palette[pal_idx+j];
5653*4882a593Smuzhiyun                }
5654*4882a593Smuzhiyun             } else if(tga_rgb16) {
5655*4882a593Smuzhiyun                STBI_ASSERT(tga_comp == STBI_rgb);
5656*4882a593Smuzhiyun                stbi__tga_read_rgb16(s, raw_data);
5657*4882a593Smuzhiyun             } else {
5658*4882a593Smuzhiyun                //   read in the data raw
5659*4882a593Smuzhiyun                for (j = 0; j < tga_comp; ++j) {
5660*4882a593Smuzhiyun                   raw_data[j] = stbi__get8(s);
5661*4882a593Smuzhiyun                }
5662*4882a593Smuzhiyun             }
5663*4882a593Smuzhiyun             //   clear the reading flag for the next pixel
5664*4882a593Smuzhiyun             read_next_pixel = 0;
5665*4882a593Smuzhiyun          } // end of reading a pixel
5666*4882a593Smuzhiyun 
5667*4882a593Smuzhiyun          // copy data
5668*4882a593Smuzhiyun          for (j = 0; j < tga_comp; ++j)
5669*4882a593Smuzhiyun            tga_data[i*tga_comp+j] = raw_data[j];
5670*4882a593Smuzhiyun 
5671*4882a593Smuzhiyun          //   in case we're in RLE mode, keep counting down
5672*4882a593Smuzhiyun          --RLE_count;
5673*4882a593Smuzhiyun       }
5674*4882a593Smuzhiyun       //   do I need to invert the image?
5675*4882a593Smuzhiyun       if ( tga_inverted )
5676*4882a593Smuzhiyun       {
5677*4882a593Smuzhiyun          for (j = 0; j*2 < tga_height; ++j)
5678*4882a593Smuzhiyun          {
5679*4882a593Smuzhiyun             int index1 = j * tga_width * tga_comp;
5680*4882a593Smuzhiyun             int index2 = (tga_height - 1 - j) * tga_width * tga_comp;
5681*4882a593Smuzhiyun             for (i = tga_width * tga_comp; i > 0; --i)
5682*4882a593Smuzhiyun             {
5683*4882a593Smuzhiyun                unsigned char temp = tga_data[index1];
5684*4882a593Smuzhiyun                tga_data[index1] = tga_data[index2];
5685*4882a593Smuzhiyun                tga_data[index2] = temp;
5686*4882a593Smuzhiyun                ++index1;
5687*4882a593Smuzhiyun                ++index2;
5688*4882a593Smuzhiyun             }
5689*4882a593Smuzhiyun          }
5690*4882a593Smuzhiyun       }
5691*4882a593Smuzhiyun       //   clear my palette, if I had one
5692*4882a593Smuzhiyun       if ( tga_palette != NULL )
5693*4882a593Smuzhiyun       {
5694*4882a593Smuzhiyun          STBI_FREE( tga_palette );
5695*4882a593Smuzhiyun       }
5696*4882a593Smuzhiyun    }
5697*4882a593Smuzhiyun 
5698*4882a593Smuzhiyun    // swap RGB - if the source data was RGB16, it already is in the right order
5699*4882a593Smuzhiyun    if (tga_comp >= 3 && !tga_rgb16)
5700*4882a593Smuzhiyun    {
5701*4882a593Smuzhiyun       unsigned char* tga_pixel = tga_data;
5702*4882a593Smuzhiyun       for (i=0; i < tga_width * tga_height; ++i)
5703*4882a593Smuzhiyun       {
5704*4882a593Smuzhiyun          unsigned char temp = tga_pixel[0];
5705*4882a593Smuzhiyun          tga_pixel[0] = tga_pixel[2];
5706*4882a593Smuzhiyun          tga_pixel[2] = temp;
5707*4882a593Smuzhiyun          tga_pixel += tga_comp;
5708*4882a593Smuzhiyun       }
5709*4882a593Smuzhiyun    }
5710*4882a593Smuzhiyun 
5711*4882a593Smuzhiyun    // convert to target component count
5712*4882a593Smuzhiyun    if (req_comp && req_comp != tga_comp)
5713*4882a593Smuzhiyun       tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height);
5714*4882a593Smuzhiyun 
5715*4882a593Smuzhiyun    //   the things I do to get rid of an error message, and yet keep
5716*4882a593Smuzhiyun    //   Microsoft's C compilers happy... [8^(
5717*4882a593Smuzhiyun    tga_palette_start = tga_palette_len = tga_palette_bits =
5718*4882a593Smuzhiyun          tga_x_origin = tga_y_origin = 0;
5719*4882a593Smuzhiyun    STBI_NOTUSED(tga_palette_start);
5720*4882a593Smuzhiyun    //   OK, done
5721*4882a593Smuzhiyun    return tga_data;
5722*4882a593Smuzhiyun }
5723*4882a593Smuzhiyun #endif
5724*4882a593Smuzhiyun 
5725*4882a593Smuzhiyun // *************************************************************************************************
5726*4882a593Smuzhiyun // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB
5727*4882a593Smuzhiyun 
5728*4882a593Smuzhiyun #ifndef STBI_NO_PSD
stbi__psd_test(stbi__context * s)5729*4882a593Smuzhiyun static int stbi__psd_test(stbi__context *s)
5730*4882a593Smuzhiyun {
5731*4882a593Smuzhiyun    int r = (stbi__get32be(s) == 0x38425053);
5732*4882a593Smuzhiyun    stbi__rewind(s);
5733*4882a593Smuzhiyun    return r;
5734*4882a593Smuzhiyun }
5735*4882a593Smuzhiyun 
stbi__psd_decode_rle(stbi__context * s,stbi_uc * p,int pixelCount)5736*4882a593Smuzhiyun static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount)
5737*4882a593Smuzhiyun {
5738*4882a593Smuzhiyun    int count, nleft, len;
5739*4882a593Smuzhiyun 
5740*4882a593Smuzhiyun    count = 0;
5741*4882a593Smuzhiyun    while ((nleft = pixelCount - count) > 0) {
5742*4882a593Smuzhiyun       len = stbi__get8(s);
5743*4882a593Smuzhiyun       if (len == 128) {
5744*4882a593Smuzhiyun          // No-op.
5745*4882a593Smuzhiyun       } else if (len < 128) {
5746*4882a593Smuzhiyun          // Copy next len+1 bytes literally.
5747*4882a593Smuzhiyun          len++;
5748*4882a593Smuzhiyun          if (len > nleft) return 0; // corrupt data
5749*4882a593Smuzhiyun          count += len;
5750*4882a593Smuzhiyun          while (len) {
5751*4882a593Smuzhiyun             *p = stbi__get8(s);
5752*4882a593Smuzhiyun             p += 4;
5753*4882a593Smuzhiyun             len--;
5754*4882a593Smuzhiyun          }
5755*4882a593Smuzhiyun       } else if (len > 128) {
5756*4882a593Smuzhiyun          stbi_uc   val;
5757*4882a593Smuzhiyun          // Next -len+1 bytes in the dest are replicated from next source byte.
5758*4882a593Smuzhiyun          // (Interpret len as a negative 8-bit int.)
5759*4882a593Smuzhiyun          len = 257 - len;
5760*4882a593Smuzhiyun          if (len > nleft) return 0; // corrupt data
5761*4882a593Smuzhiyun          val = stbi__get8(s);
5762*4882a593Smuzhiyun          count += len;
5763*4882a593Smuzhiyun          while (len) {
5764*4882a593Smuzhiyun             *p = val;
5765*4882a593Smuzhiyun             p += 4;
5766*4882a593Smuzhiyun             len--;
5767*4882a593Smuzhiyun          }
5768*4882a593Smuzhiyun       }
5769*4882a593Smuzhiyun    }
5770*4882a593Smuzhiyun 
5771*4882a593Smuzhiyun    return 1;
5772*4882a593Smuzhiyun }
5773*4882a593Smuzhiyun 
stbi__psd_load(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri,int bpc)5774*4882a593Smuzhiyun static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
5775*4882a593Smuzhiyun {
5776*4882a593Smuzhiyun    int pixelCount;
5777*4882a593Smuzhiyun    int channelCount, compression;
5778*4882a593Smuzhiyun    int channel, i;
5779*4882a593Smuzhiyun    int bitdepth;
5780*4882a593Smuzhiyun    int w,h;
5781*4882a593Smuzhiyun    stbi_uc *out;
5782*4882a593Smuzhiyun    STBI_NOTUSED(ri);
5783*4882a593Smuzhiyun 
5784*4882a593Smuzhiyun    // Check identifier
5785*4882a593Smuzhiyun    if (stbi__get32be(s) != 0x38425053)   // "8BPS"
5786*4882a593Smuzhiyun       return stbi__errpuc("not PSD", "Corrupt PSD image");
5787*4882a593Smuzhiyun 
5788*4882a593Smuzhiyun    // Check file type version.
5789*4882a593Smuzhiyun    if (stbi__get16be(s) != 1)
5790*4882a593Smuzhiyun       return stbi__errpuc("wrong version", "Unsupported version of PSD image");
5791*4882a593Smuzhiyun 
5792*4882a593Smuzhiyun    // Skip 6 reserved bytes.
5793*4882a593Smuzhiyun    stbi__skip(s, 6 );
5794*4882a593Smuzhiyun 
5795*4882a593Smuzhiyun    // Read the number of channels (R, G, B, A, etc).
5796*4882a593Smuzhiyun    channelCount = stbi__get16be(s);
5797*4882a593Smuzhiyun    if (channelCount < 0 || channelCount > 16)
5798*4882a593Smuzhiyun       return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image");
5799*4882a593Smuzhiyun 
5800*4882a593Smuzhiyun    // Read the rows and columns of the image.
5801*4882a593Smuzhiyun    h = stbi__get32be(s);
5802*4882a593Smuzhiyun    w = stbi__get32be(s);
5803*4882a593Smuzhiyun 
5804*4882a593Smuzhiyun    // Make sure the depth is 8 bits.
5805*4882a593Smuzhiyun    bitdepth = stbi__get16be(s);
5806*4882a593Smuzhiyun    if (bitdepth != 8 && bitdepth != 16)
5807*4882a593Smuzhiyun       return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit");
5808*4882a593Smuzhiyun 
5809*4882a593Smuzhiyun    // Make sure the color mode is RGB.
5810*4882a593Smuzhiyun    // Valid options are:
5811*4882a593Smuzhiyun    //   0: Bitmap
5812*4882a593Smuzhiyun    //   1: Grayscale
5813*4882a593Smuzhiyun    //   2: Indexed color
5814*4882a593Smuzhiyun    //   3: RGB color
5815*4882a593Smuzhiyun    //   4: CMYK color
5816*4882a593Smuzhiyun    //   7: Multichannel
5817*4882a593Smuzhiyun    //   8: Duotone
5818*4882a593Smuzhiyun    //   9: Lab color
5819*4882a593Smuzhiyun    if (stbi__get16be(s) != 3)
5820*4882a593Smuzhiyun       return stbi__errpuc("wrong color format", "PSD is not in RGB color format");
5821*4882a593Smuzhiyun 
5822*4882a593Smuzhiyun    // Skip the Mode Data.  (It's the palette for indexed color; other info for other modes.)
5823*4882a593Smuzhiyun    stbi__skip(s,stbi__get32be(s) );
5824*4882a593Smuzhiyun 
5825*4882a593Smuzhiyun    // Skip the image resources.  (resolution, pen tool paths, etc)
5826*4882a593Smuzhiyun    stbi__skip(s, stbi__get32be(s) );
5827*4882a593Smuzhiyun 
5828*4882a593Smuzhiyun    // Skip the reserved data.
5829*4882a593Smuzhiyun    stbi__skip(s, stbi__get32be(s) );
5830*4882a593Smuzhiyun 
5831*4882a593Smuzhiyun    // Find out if the data is compressed.
5832*4882a593Smuzhiyun    // Known values:
5833*4882a593Smuzhiyun    //   0: no compression
5834*4882a593Smuzhiyun    //   1: RLE compressed
5835*4882a593Smuzhiyun    compression = stbi__get16be(s);
5836*4882a593Smuzhiyun    if (compression > 1)
5837*4882a593Smuzhiyun       return stbi__errpuc("bad compression", "PSD has an unknown compression format");
5838*4882a593Smuzhiyun 
5839*4882a593Smuzhiyun    // Check size
5840*4882a593Smuzhiyun    if (!stbi__mad3sizes_valid(4, w, h, 0))
5841*4882a593Smuzhiyun       return stbi__errpuc("too large", "Corrupt PSD");
5842*4882a593Smuzhiyun 
5843*4882a593Smuzhiyun    // Create the destination image.
5844*4882a593Smuzhiyun 
5845*4882a593Smuzhiyun    if (!compression && bitdepth == 16 && bpc == 16) {
5846*4882a593Smuzhiyun       out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0);
5847*4882a593Smuzhiyun       ri->bits_per_channel = 16;
5848*4882a593Smuzhiyun    } else
5849*4882a593Smuzhiyun       out = (stbi_uc *) stbi__malloc(4 * w*h);
5850*4882a593Smuzhiyun 
5851*4882a593Smuzhiyun    if (!out) return stbi__errpuc("outofmem", "Out of memory");
5852*4882a593Smuzhiyun    pixelCount = w*h;
5853*4882a593Smuzhiyun 
5854*4882a593Smuzhiyun    // Initialize the data to zero.
5855*4882a593Smuzhiyun    //memset( out, 0, pixelCount * 4 );
5856*4882a593Smuzhiyun 
5857*4882a593Smuzhiyun    // Finally, the image data.
5858*4882a593Smuzhiyun    if (compression) {
5859*4882a593Smuzhiyun       // RLE as used by .PSD and .TIFF
5860*4882a593Smuzhiyun       // Loop until you get the number of unpacked bytes you are expecting:
5861*4882a593Smuzhiyun       //     Read the next source byte into n.
5862*4882a593Smuzhiyun       //     If n is between 0 and 127 inclusive, copy the next n+1 bytes literally.
5863*4882a593Smuzhiyun       //     Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times.
5864*4882a593Smuzhiyun       //     Else if n is 128, noop.
5865*4882a593Smuzhiyun       // Endloop
5866*4882a593Smuzhiyun 
5867*4882a593Smuzhiyun       // The RLE-compressed data is preceded by a 2-byte data count for each row in the data,
5868*4882a593Smuzhiyun       // which we're going to just skip.
5869*4882a593Smuzhiyun       stbi__skip(s, h * channelCount * 2 );
5870*4882a593Smuzhiyun 
5871*4882a593Smuzhiyun       // Read the RLE data by channel.
5872*4882a593Smuzhiyun       for (channel = 0; channel < 4; channel++) {
5873*4882a593Smuzhiyun          stbi_uc *p;
5874*4882a593Smuzhiyun 
5875*4882a593Smuzhiyun          p = out+channel;
5876*4882a593Smuzhiyun          if (channel >= channelCount) {
5877*4882a593Smuzhiyun             // Fill this channel with default data.
5878*4882a593Smuzhiyun             for (i = 0; i < pixelCount; i++, p += 4)
5879*4882a593Smuzhiyun                *p = (channel == 3 ? 255 : 0);
5880*4882a593Smuzhiyun          } else {
5881*4882a593Smuzhiyun             // Read the RLE data.
5882*4882a593Smuzhiyun             if (!stbi__psd_decode_rle(s, p, pixelCount)) {
5883*4882a593Smuzhiyun                STBI_FREE(out);
5884*4882a593Smuzhiyun                return stbi__errpuc("corrupt", "bad RLE data");
5885*4882a593Smuzhiyun             }
5886*4882a593Smuzhiyun          }
5887*4882a593Smuzhiyun       }
5888*4882a593Smuzhiyun 
5889*4882a593Smuzhiyun    } else {
5890*4882a593Smuzhiyun       // We're at the raw image data.  It's each channel in order (Red, Green, Blue, Alpha, ...)
5891*4882a593Smuzhiyun       // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image.
5892*4882a593Smuzhiyun 
5893*4882a593Smuzhiyun       // Read the data by channel.
5894*4882a593Smuzhiyun       for (channel = 0; channel < 4; channel++) {
5895*4882a593Smuzhiyun          if (channel >= channelCount) {
5896*4882a593Smuzhiyun             // Fill this channel with default data.
5897*4882a593Smuzhiyun             if (bitdepth == 16 && bpc == 16) {
5898*4882a593Smuzhiyun                stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
5899*4882a593Smuzhiyun                stbi__uint16 val = channel == 3 ? 65535 : 0;
5900*4882a593Smuzhiyun                for (i = 0; i < pixelCount; i++, q += 4)
5901*4882a593Smuzhiyun                   *q = val;
5902*4882a593Smuzhiyun             } else {
5903*4882a593Smuzhiyun                stbi_uc *p = out+channel;
5904*4882a593Smuzhiyun                stbi_uc val = channel == 3 ? 255 : 0;
5905*4882a593Smuzhiyun                for (i = 0; i < pixelCount; i++, p += 4)
5906*4882a593Smuzhiyun                   *p = val;
5907*4882a593Smuzhiyun             }
5908*4882a593Smuzhiyun          } else {
5909*4882a593Smuzhiyun             if (ri->bits_per_channel == 16) {    // output bpc
5910*4882a593Smuzhiyun                stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
5911*4882a593Smuzhiyun                for (i = 0; i < pixelCount; i++, q += 4)
5912*4882a593Smuzhiyun                   *q = (stbi__uint16) stbi__get16be(s);
5913*4882a593Smuzhiyun             } else {
5914*4882a593Smuzhiyun                stbi_uc *p = out+channel;
5915*4882a593Smuzhiyun                if (bitdepth == 16) {  // input bpc
5916*4882a593Smuzhiyun                   for (i = 0; i < pixelCount; i++, p += 4)
5917*4882a593Smuzhiyun                      *p = (stbi_uc) (stbi__get16be(s) >> 8);
5918*4882a593Smuzhiyun                } else {
5919*4882a593Smuzhiyun                   for (i = 0; i < pixelCount; i++, p += 4)
5920*4882a593Smuzhiyun                      *p = stbi__get8(s);
5921*4882a593Smuzhiyun                }
5922*4882a593Smuzhiyun             }
5923*4882a593Smuzhiyun          }
5924*4882a593Smuzhiyun       }
5925*4882a593Smuzhiyun    }
5926*4882a593Smuzhiyun 
5927*4882a593Smuzhiyun    // remove weird white matte from PSD
5928*4882a593Smuzhiyun    if (channelCount >= 4) {
5929*4882a593Smuzhiyun       if (ri->bits_per_channel == 16) {
5930*4882a593Smuzhiyun          for (i=0; i < w*h; ++i) {
5931*4882a593Smuzhiyun             stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i;
5932*4882a593Smuzhiyun             if (pixel[3] != 0 && pixel[3] != 65535) {
5933*4882a593Smuzhiyun                float a = pixel[3] / 65535.0f;
5934*4882a593Smuzhiyun                float ra = 1.0f / a;
5935*4882a593Smuzhiyun                float inv_a = 65535.0f * (1 - ra);
5936*4882a593Smuzhiyun                pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a);
5937*4882a593Smuzhiyun                pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a);
5938*4882a593Smuzhiyun                pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a);
5939*4882a593Smuzhiyun             }
5940*4882a593Smuzhiyun          }
5941*4882a593Smuzhiyun       } else {
5942*4882a593Smuzhiyun          for (i=0; i < w*h; ++i) {
5943*4882a593Smuzhiyun             unsigned char *pixel = out + 4*i;
5944*4882a593Smuzhiyun             if (pixel[3] != 0 && pixel[3] != 255) {
5945*4882a593Smuzhiyun                float a = pixel[3] / 255.0f;
5946*4882a593Smuzhiyun                float ra = 1.0f / a;
5947*4882a593Smuzhiyun                float inv_a = 255.0f * (1 - ra);
5948*4882a593Smuzhiyun                pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
5949*4882a593Smuzhiyun                pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
5950*4882a593Smuzhiyun                pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
5951*4882a593Smuzhiyun             }
5952*4882a593Smuzhiyun          }
5953*4882a593Smuzhiyun       }
5954*4882a593Smuzhiyun    }
5955*4882a593Smuzhiyun 
5956*4882a593Smuzhiyun    // convert to desired output format
5957*4882a593Smuzhiyun    if (req_comp && req_comp != 4) {
5958*4882a593Smuzhiyun       if (ri->bits_per_channel == 16)
5959*4882a593Smuzhiyun          out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h);
5960*4882a593Smuzhiyun       else
5961*4882a593Smuzhiyun          out = stbi__convert_format(out, 4, req_comp, w, h);
5962*4882a593Smuzhiyun       if (out == NULL) return out; // stbi__convert_format frees input on failure
5963*4882a593Smuzhiyun    }
5964*4882a593Smuzhiyun 
5965*4882a593Smuzhiyun    if (comp) *comp = 4;
5966*4882a593Smuzhiyun    *y = h;
5967*4882a593Smuzhiyun    *x = w;
5968*4882a593Smuzhiyun 
5969*4882a593Smuzhiyun    return out;
5970*4882a593Smuzhiyun }
5971*4882a593Smuzhiyun #endif
5972*4882a593Smuzhiyun 
5973*4882a593Smuzhiyun // *************************************************************************************************
5974*4882a593Smuzhiyun // Softimage PIC loader
5975*4882a593Smuzhiyun // by Tom Seddon
5976*4882a593Smuzhiyun //
5977*4882a593Smuzhiyun // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format
5978*4882a593Smuzhiyun // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/
5979*4882a593Smuzhiyun 
5980*4882a593Smuzhiyun #ifndef STBI_NO_PIC
stbi__pic_is4(stbi__context * s,const char * str)5981*4882a593Smuzhiyun static int stbi__pic_is4(stbi__context *s,const char *str)
5982*4882a593Smuzhiyun {
5983*4882a593Smuzhiyun    int i;
5984*4882a593Smuzhiyun    for (i=0; i<4; ++i)
5985*4882a593Smuzhiyun       if (stbi__get8(s) != (stbi_uc)str[i])
5986*4882a593Smuzhiyun          return 0;
5987*4882a593Smuzhiyun 
5988*4882a593Smuzhiyun    return 1;
5989*4882a593Smuzhiyun }
5990*4882a593Smuzhiyun 
stbi__pic_test_core(stbi__context * s)5991*4882a593Smuzhiyun static int stbi__pic_test_core(stbi__context *s)
5992*4882a593Smuzhiyun {
5993*4882a593Smuzhiyun    int i;
5994*4882a593Smuzhiyun 
5995*4882a593Smuzhiyun    if (!stbi__pic_is4(s,"\x53\x80\xF6\x34"))
5996*4882a593Smuzhiyun       return 0;
5997*4882a593Smuzhiyun 
5998*4882a593Smuzhiyun    for(i=0;i<84;++i)
5999*4882a593Smuzhiyun       stbi__get8(s);
6000*4882a593Smuzhiyun 
6001*4882a593Smuzhiyun    if (!stbi__pic_is4(s,"PICT"))
6002*4882a593Smuzhiyun       return 0;
6003*4882a593Smuzhiyun 
6004*4882a593Smuzhiyun    return 1;
6005*4882a593Smuzhiyun }
6006*4882a593Smuzhiyun 
6007*4882a593Smuzhiyun typedef struct
6008*4882a593Smuzhiyun {
6009*4882a593Smuzhiyun    stbi_uc size,type,channel;
6010*4882a593Smuzhiyun } stbi__pic_packet;
6011*4882a593Smuzhiyun 
stbi__readval(stbi__context * s,int channel,stbi_uc * dest)6012*4882a593Smuzhiyun static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest)
6013*4882a593Smuzhiyun {
6014*4882a593Smuzhiyun    int mask=0x80, i;
6015*4882a593Smuzhiyun 
6016*4882a593Smuzhiyun    for (i=0; i<4; ++i, mask>>=1) {
6017*4882a593Smuzhiyun       if (channel & mask) {
6018*4882a593Smuzhiyun          if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short");
6019*4882a593Smuzhiyun          dest[i]=stbi__get8(s);
6020*4882a593Smuzhiyun       }
6021*4882a593Smuzhiyun    }
6022*4882a593Smuzhiyun 
6023*4882a593Smuzhiyun    return dest;
6024*4882a593Smuzhiyun }
6025*4882a593Smuzhiyun 
stbi__copyval(int channel,stbi_uc * dest,const stbi_uc * src)6026*4882a593Smuzhiyun static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src)
6027*4882a593Smuzhiyun {
6028*4882a593Smuzhiyun    int mask=0x80,i;
6029*4882a593Smuzhiyun 
6030*4882a593Smuzhiyun    for (i=0;i<4; ++i, mask>>=1)
6031*4882a593Smuzhiyun       if (channel&mask)
6032*4882a593Smuzhiyun          dest[i]=src[i];
6033*4882a593Smuzhiyun }
6034*4882a593Smuzhiyun 
stbi__pic_load_core(stbi__context * s,int width,int height,int * comp,stbi_uc * result)6035*4882a593Smuzhiyun static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result)
6036*4882a593Smuzhiyun {
6037*4882a593Smuzhiyun    int act_comp=0,num_packets=0,y,chained;
6038*4882a593Smuzhiyun    stbi__pic_packet packets[10];
6039*4882a593Smuzhiyun 
6040*4882a593Smuzhiyun    // this will (should...) cater for even some bizarre stuff like having data
6041*4882a593Smuzhiyun     // for the same channel in multiple packets.
6042*4882a593Smuzhiyun    do {
6043*4882a593Smuzhiyun       stbi__pic_packet *packet;
6044*4882a593Smuzhiyun 
6045*4882a593Smuzhiyun       if (num_packets==sizeof(packets)/sizeof(packets[0]))
6046*4882a593Smuzhiyun          return stbi__errpuc("bad format","too many packets");
6047*4882a593Smuzhiyun 
6048*4882a593Smuzhiyun       packet = &packets[num_packets++];
6049*4882a593Smuzhiyun 
6050*4882a593Smuzhiyun       chained = stbi__get8(s);
6051*4882a593Smuzhiyun       packet->size    = stbi__get8(s);
6052*4882a593Smuzhiyun       packet->type    = stbi__get8(s);
6053*4882a593Smuzhiyun       packet->channel = stbi__get8(s);
6054*4882a593Smuzhiyun 
6055*4882a593Smuzhiyun       act_comp |= packet->channel;
6056*4882a593Smuzhiyun 
6057*4882a593Smuzhiyun       if (stbi__at_eof(s))          return stbi__errpuc("bad file","file too short (reading packets)");
6058*4882a593Smuzhiyun       if (packet->size != 8)  return stbi__errpuc("bad format","packet isn't 8bpp");
6059*4882a593Smuzhiyun    } while (chained);
6060*4882a593Smuzhiyun 
6061*4882a593Smuzhiyun    *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel?
6062*4882a593Smuzhiyun 
6063*4882a593Smuzhiyun    for(y=0; y<height; ++y) {
6064*4882a593Smuzhiyun       int packet_idx;
6065*4882a593Smuzhiyun 
6066*4882a593Smuzhiyun       for(packet_idx=0; packet_idx < num_packets; ++packet_idx) {
6067*4882a593Smuzhiyun          stbi__pic_packet *packet = &packets[packet_idx];
6068*4882a593Smuzhiyun          stbi_uc *dest = result+y*width*4;
6069*4882a593Smuzhiyun 
6070*4882a593Smuzhiyun          switch (packet->type) {
6071*4882a593Smuzhiyun             default:
6072*4882a593Smuzhiyun                return stbi__errpuc("bad format","packet has bad compression type");
6073*4882a593Smuzhiyun 
6074*4882a593Smuzhiyun             case 0: {//uncompressed
6075*4882a593Smuzhiyun                int x;
6076*4882a593Smuzhiyun 
6077*4882a593Smuzhiyun                for(x=0;x<width;++x, dest+=4)
6078*4882a593Smuzhiyun                   if (!stbi__readval(s,packet->channel,dest))
6079*4882a593Smuzhiyun                      return 0;
6080*4882a593Smuzhiyun                break;
6081*4882a593Smuzhiyun             }
6082*4882a593Smuzhiyun 
6083*4882a593Smuzhiyun             case 1://Pure RLE
6084*4882a593Smuzhiyun                {
6085*4882a593Smuzhiyun                   int left=width, i;
6086*4882a593Smuzhiyun 
6087*4882a593Smuzhiyun                   while (left>0) {
6088*4882a593Smuzhiyun                      stbi_uc count,value[4];
6089*4882a593Smuzhiyun 
6090*4882a593Smuzhiyun                      count=stbi__get8(s);
6091*4882a593Smuzhiyun                      if (stbi__at_eof(s))   return stbi__errpuc("bad file","file too short (pure read count)");
6092*4882a593Smuzhiyun 
6093*4882a593Smuzhiyun                      if (count > left)
6094*4882a593Smuzhiyun                         count = (stbi_uc) left;
6095*4882a593Smuzhiyun 
6096*4882a593Smuzhiyun                      if (!stbi__readval(s,packet->channel,value))  return 0;
6097*4882a593Smuzhiyun 
6098*4882a593Smuzhiyun                      for(i=0; i<count; ++i,dest+=4)
6099*4882a593Smuzhiyun                         stbi__copyval(packet->channel,dest,value);
6100*4882a593Smuzhiyun                      left -= count;
6101*4882a593Smuzhiyun                   }
6102*4882a593Smuzhiyun                }
6103*4882a593Smuzhiyun                break;
6104*4882a593Smuzhiyun 
6105*4882a593Smuzhiyun             case 2: {//Mixed RLE
6106*4882a593Smuzhiyun                int left=width;
6107*4882a593Smuzhiyun                while (left>0) {
6108*4882a593Smuzhiyun                   int count = stbi__get8(s), i;
6109*4882a593Smuzhiyun                   if (stbi__at_eof(s))  return stbi__errpuc("bad file","file too short (mixed read count)");
6110*4882a593Smuzhiyun 
6111*4882a593Smuzhiyun                   if (count >= 128) { // Repeated
6112*4882a593Smuzhiyun                      stbi_uc value[4];
6113*4882a593Smuzhiyun 
6114*4882a593Smuzhiyun                      if (count==128)
6115*4882a593Smuzhiyun                         count = stbi__get16be(s);
6116*4882a593Smuzhiyun                      else
6117*4882a593Smuzhiyun                         count -= 127;
6118*4882a593Smuzhiyun                      if (count > left)
6119*4882a593Smuzhiyun                         return stbi__errpuc("bad file","scanline overrun");
6120*4882a593Smuzhiyun 
6121*4882a593Smuzhiyun                      if (!stbi__readval(s,packet->channel,value))
6122*4882a593Smuzhiyun                         return 0;
6123*4882a593Smuzhiyun 
6124*4882a593Smuzhiyun                      for(i=0;i<count;++i, dest += 4)
6125*4882a593Smuzhiyun                         stbi__copyval(packet->channel,dest,value);
6126*4882a593Smuzhiyun                   } else { // Raw
6127*4882a593Smuzhiyun                      ++count;
6128*4882a593Smuzhiyun                      if (count>left) return stbi__errpuc("bad file","scanline overrun");
6129*4882a593Smuzhiyun 
6130*4882a593Smuzhiyun                      for(i=0;i<count;++i, dest+=4)
6131*4882a593Smuzhiyun                         if (!stbi__readval(s,packet->channel,dest))
6132*4882a593Smuzhiyun                            return 0;
6133*4882a593Smuzhiyun                   }
6134*4882a593Smuzhiyun                   left-=count;
6135*4882a593Smuzhiyun                }
6136*4882a593Smuzhiyun                break;
6137*4882a593Smuzhiyun             }
6138*4882a593Smuzhiyun          }
6139*4882a593Smuzhiyun       }
6140*4882a593Smuzhiyun    }
6141*4882a593Smuzhiyun 
6142*4882a593Smuzhiyun    return result;
6143*4882a593Smuzhiyun }
6144*4882a593Smuzhiyun 
stbi__pic_load(stbi__context * s,int * px,int * py,int * comp,int req_comp,stbi__result_info * ri)6145*4882a593Smuzhiyun static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri)
6146*4882a593Smuzhiyun {
6147*4882a593Smuzhiyun    stbi_uc *result;
6148*4882a593Smuzhiyun    int i, x,y, internal_comp;
6149*4882a593Smuzhiyun    STBI_NOTUSED(ri);
6150*4882a593Smuzhiyun 
6151*4882a593Smuzhiyun    if (!comp) comp = &internal_comp;
6152*4882a593Smuzhiyun 
6153*4882a593Smuzhiyun    for (i=0; i<92; ++i)
6154*4882a593Smuzhiyun       stbi__get8(s);
6155*4882a593Smuzhiyun 
6156*4882a593Smuzhiyun    x = stbi__get16be(s);
6157*4882a593Smuzhiyun    y = stbi__get16be(s);
6158*4882a593Smuzhiyun    if (stbi__at_eof(s))  return stbi__errpuc("bad file","file too short (pic header)");
6159*4882a593Smuzhiyun    if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
6160*4882a593Smuzhiyun 
6161*4882a593Smuzhiyun    stbi__get32be(s); //skip `ratio'
6162*4882a593Smuzhiyun    stbi__get16be(s); //skip `fields'
6163*4882a593Smuzhiyun    stbi__get16be(s); //skip `pad'
6164*4882a593Smuzhiyun 
6165*4882a593Smuzhiyun    // intermediate buffer is RGBA
6166*4882a593Smuzhiyun    result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0);
6167*4882a593Smuzhiyun    memset(result, 0xff, x*y*4);
6168*4882a593Smuzhiyun 
6169*4882a593Smuzhiyun    if (!stbi__pic_load_core(s,x,y,comp, result)) {
6170*4882a593Smuzhiyun       STBI_FREE(result);
6171*4882a593Smuzhiyun       result=0;
6172*4882a593Smuzhiyun    }
6173*4882a593Smuzhiyun    *px = x;
6174*4882a593Smuzhiyun    *py = y;
6175*4882a593Smuzhiyun    if (req_comp == 0) req_comp = *comp;
6176*4882a593Smuzhiyun    result=stbi__convert_format(result,4,req_comp,x,y);
6177*4882a593Smuzhiyun 
6178*4882a593Smuzhiyun    return result;
6179*4882a593Smuzhiyun }
6180*4882a593Smuzhiyun 
stbi__pic_test(stbi__context * s)6181*4882a593Smuzhiyun static int stbi__pic_test(stbi__context *s)
6182*4882a593Smuzhiyun {
6183*4882a593Smuzhiyun    int r = stbi__pic_test_core(s);
6184*4882a593Smuzhiyun    stbi__rewind(s);
6185*4882a593Smuzhiyun    return r;
6186*4882a593Smuzhiyun }
6187*4882a593Smuzhiyun #endif
6188*4882a593Smuzhiyun 
6189*4882a593Smuzhiyun // *************************************************************************************************
6190*4882a593Smuzhiyun // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
6191*4882a593Smuzhiyun 
6192*4882a593Smuzhiyun #ifndef STBI_NO_GIF
6193*4882a593Smuzhiyun typedef struct
6194*4882a593Smuzhiyun {
6195*4882a593Smuzhiyun    stbi__int16 prefix;
6196*4882a593Smuzhiyun    stbi_uc first;
6197*4882a593Smuzhiyun    stbi_uc suffix;
6198*4882a593Smuzhiyun } stbi__gif_lzw;
6199*4882a593Smuzhiyun 
6200*4882a593Smuzhiyun typedef struct
6201*4882a593Smuzhiyun {
6202*4882a593Smuzhiyun    int w,h;
6203*4882a593Smuzhiyun    stbi_uc *out;                 // output buffer (always 4 components)
6204*4882a593Smuzhiyun    stbi_uc *background;          // The current "background" as far as a gif is concerned
6205*4882a593Smuzhiyun    stbi_uc *history;
6206*4882a593Smuzhiyun    int flags, bgindex, ratio, transparent, eflags;
6207*4882a593Smuzhiyun    stbi_uc  pal[256][4];
6208*4882a593Smuzhiyun    stbi_uc lpal[256][4];
6209*4882a593Smuzhiyun    stbi__gif_lzw codes[8192];
6210*4882a593Smuzhiyun    stbi_uc *color_table;
6211*4882a593Smuzhiyun    int parse, step;
6212*4882a593Smuzhiyun    int lflags;
6213*4882a593Smuzhiyun    int start_x, start_y;
6214*4882a593Smuzhiyun    int max_x, max_y;
6215*4882a593Smuzhiyun    int cur_x, cur_y;
6216*4882a593Smuzhiyun    int line_size;
6217*4882a593Smuzhiyun    int delay;
6218*4882a593Smuzhiyun } stbi__gif;
6219*4882a593Smuzhiyun 
stbi__gif_test_raw(stbi__context * s)6220*4882a593Smuzhiyun static int stbi__gif_test_raw(stbi__context *s)
6221*4882a593Smuzhiyun {
6222*4882a593Smuzhiyun    int sz;
6223*4882a593Smuzhiyun    if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0;
6224*4882a593Smuzhiyun    sz = stbi__get8(s);
6225*4882a593Smuzhiyun    if (sz != '9' && sz != '7') return 0;
6226*4882a593Smuzhiyun    if (stbi__get8(s) != 'a') return 0;
6227*4882a593Smuzhiyun    return 1;
6228*4882a593Smuzhiyun }
6229*4882a593Smuzhiyun 
stbi__gif_test(stbi__context * s)6230*4882a593Smuzhiyun static int stbi__gif_test(stbi__context *s)
6231*4882a593Smuzhiyun {
6232*4882a593Smuzhiyun    int r = stbi__gif_test_raw(s);
6233*4882a593Smuzhiyun    stbi__rewind(s);
6234*4882a593Smuzhiyun    return r;
6235*4882a593Smuzhiyun }
6236*4882a593Smuzhiyun 
stbi__gif_parse_colortable(stbi__context * s,stbi_uc pal[256][4],int num_entries,int transp)6237*4882a593Smuzhiyun static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp)
6238*4882a593Smuzhiyun {
6239*4882a593Smuzhiyun    int i;
6240*4882a593Smuzhiyun    for (i=0; i < num_entries; ++i) {
6241*4882a593Smuzhiyun       pal[i][2] = stbi__get8(s);
6242*4882a593Smuzhiyun       pal[i][1] = stbi__get8(s);
6243*4882a593Smuzhiyun       pal[i][0] = stbi__get8(s);
6244*4882a593Smuzhiyun       pal[i][3] = transp == i ? 0 : 255;
6245*4882a593Smuzhiyun    }
6246*4882a593Smuzhiyun }
6247*4882a593Smuzhiyun 
stbi__gif_header(stbi__context * s,stbi__gif * g,int * comp,int is_info)6248*4882a593Smuzhiyun static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info)
6249*4882a593Smuzhiyun {
6250*4882a593Smuzhiyun    stbi_uc version;
6251*4882a593Smuzhiyun    if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8')
6252*4882a593Smuzhiyun       return stbi__err("not GIF", "Corrupt GIF");
6253*4882a593Smuzhiyun 
6254*4882a593Smuzhiyun    version = stbi__get8(s);
6255*4882a593Smuzhiyun    if (version != '7' && version != '9')    return stbi__err("not GIF", "Corrupt GIF");
6256*4882a593Smuzhiyun    if (stbi__get8(s) != 'a')                return stbi__err("not GIF", "Corrupt GIF");
6257*4882a593Smuzhiyun 
6258*4882a593Smuzhiyun    stbi__g_failure_reason = "";
6259*4882a593Smuzhiyun    g->w = stbi__get16le(s);
6260*4882a593Smuzhiyun    g->h = stbi__get16le(s);
6261*4882a593Smuzhiyun    g->flags = stbi__get8(s);
6262*4882a593Smuzhiyun    g->bgindex = stbi__get8(s);
6263*4882a593Smuzhiyun    g->ratio = stbi__get8(s);
6264*4882a593Smuzhiyun    g->transparent = -1;
6265*4882a593Smuzhiyun 
6266*4882a593Smuzhiyun    if (comp != 0) *comp = 4;  // can't actually tell whether it's 3 or 4 until we parse the comments
6267*4882a593Smuzhiyun 
6268*4882a593Smuzhiyun    if (is_info) return 1;
6269*4882a593Smuzhiyun 
6270*4882a593Smuzhiyun    if (g->flags & 0x80)
6271*4882a593Smuzhiyun       stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1);
6272*4882a593Smuzhiyun 
6273*4882a593Smuzhiyun    return 1;
6274*4882a593Smuzhiyun }
6275*4882a593Smuzhiyun 
stbi__gif_info_raw(stbi__context * s,int * x,int * y,int * comp)6276*4882a593Smuzhiyun static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
6277*4882a593Smuzhiyun {
6278*4882a593Smuzhiyun    stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
6279*4882a593Smuzhiyun    if (!stbi__gif_header(s, g, comp, 1)) {
6280*4882a593Smuzhiyun       STBI_FREE(g);
6281*4882a593Smuzhiyun       stbi__rewind( s );
6282*4882a593Smuzhiyun       return 0;
6283*4882a593Smuzhiyun    }
6284*4882a593Smuzhiyun    if (x) *x = g->w;
6285*4882a593Smuzhiyun    if (y) *y = g->h;
6286*4882a593Smuzhiyun    STBI_FREE(g);
6287*4882a593Smuzhiyun    return 1;
6288*4882a593Smuzhiyun }
6289*4882a593Smuzhiyun 
stbi__out_gif_code(stbi__gif * g,stbi__uint16 code)6290*4882a593Smuzhiyun static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
6291*4882a593Smuzhiyun {
6292*4882a593Smuzhiyun    stbi_uc *p, *c;
6293*4882a593Smuzhiyun    int idx;
6294*4882a593Smuzhiyun 
6295*4882a593Smuzhiyun    // recurse to decode the prefixes, since the linked-list is backwards,
6296*4882a593Smuzhiyun    // and working backwards through an interleaved image would be nasty
6297*4882a593Smuzhiyun    if (g->codes[code].prefix >= 0)
6298*4882a593Smuzhiyun       stbi__out_gif_code(g, g->codes[code].prefix);
6299*4882a593Smuzhiyun 
6300*4882a593Smuzhiyun    if (g->cur_y >= g->max_y) return;
6301*4882a593Smuzhiyun 
6302*4882a593Smuzhiyun    idx = g->cur_x + g->cur_y;
6303*4882a593Smuzhiyun    p = &g->out[idx];
6304*4882a593Smuzhiyun    g->history[idx / 4] = 1;
6305*4882a593Smuzhiyun 
6306*4882a593Smuzhiyun    c = &g->color_table[g->codes[code].suffix * 4];
6307*4882a593Smuzhiyun    if (c[3] > 128) { // don't render transparent pixels;
6308*4882a593Smuzhiyun       p[0] = c[2];
6309*4882a593Smuzhiyun       p[1] = c[1];
6310*4882a593Smuzhiyun       p[2] = c[0];
6311*4882a593Smuzhiyun       p[3] = c[3];
6312*4882a593Smuzhiyun    }
6313*4882a593Smuzhiyun    g->cur_x += 4;
6314*4882a593Smuzhiyun 
6315*4882a593Smuzhiyun    if (g->cur_x >= g->max_x) {
6316*4882a593Smuzhiyun       g->cur_x = g->start_x;
6317*4882a593Smuzhiyun       g->cur_y += g->step;
6318*4882a593Smuzhiyun 
6319*4882a593Smuzhiyun       while (g->cur_y >= g->max_y && g->parse > 0) {
6320*4882a593Smuzhiyun          g->step = (1 << g->parse) * g->line_size;
6321*4882a593Smuzhiyun          g->cur_y = g->start_y + (g->step >> 1);
6322*4882a593Smuzhiyun          --g->parse;
6323*4882a593Smuzhiyun       }
6324*4882a593Smuzhiyun    }
6325*4882a593Smuzhiyun }
6326*4882a593Smuzhiyun 
stbi__process_gif_raster(stbi__context * s,stbi__gif * g)6327*4882a593Smuzhiyun static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
6328*4882a593Smuzhiyun {
6329*4882a593Smuzhiyun    stbi_uc lzw_cs;
6330*4882a593Smuzhiyun    stbi__int32 len, init_code;
6331*4882a593Smuzhiyun    stbi__uint32 first;
6332*4882a593Smuzhiyun    stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear;
6333*4882a593Smuzhiyun    stbi__gif_lzw *p;
6334*4882a593Smuzhiyun 
6335*4882a593Smuzhiyun    lzw_cs = stbi__get8(s);
6336*4882a593Smuzhiyun    if (lzw_cs > 12) return NULL;
6337*4882a593Smuzhiyun    clear = 1 << lzw_cs;
6338*4882a593Smuzhiyun    first = 1;
6339*4882a593Smuzhiyun    codesize = lzw_cs + 1;
6340*4882a593Smuzhiyun    codemask = (1 << codesize) - 1;
6341*4882a593Smuzhiyun    bits = 0;
6342*4882a593Smuzhiyun    valid_bits = 0;
6343*4882a593Smuzhiyun    for (init_code = 0; init_code < clear; init_code++) {
6344*4882a593Smuzhiyun       g->codes[init_code].prefix = -1;
6345*4882a593Smuzhiyun       g->codes[init_code].first = (stbi_uc) init_code;
6346*4882a593Smuzhiyun       g->codes[init_code].suffix = (stbi_uc) init_code;
6347*4882a593Smuzhiyun    }
6348*4882a593Smuzhiyun 
6349*4882a593Smuzhiyun    // support no starting clear code
6350*4882a593Smuzhiyun    avail = clear+2;
6351*4882a593Smuzhiyun    oldcode = -1;
6352*4882a593Smuzhiyun 
6353*4882a593Smuzhiyun    len = 0;
6354*4882a593Smuzhiyun    for(;;) {
6355*4882a593Smuzhiyun       if (valid_bits < codesize) {
6356*4882a593Smuzhiyun          if (len == 0) {
6357*4882a593Smuzhiyun             len = stbi__get8(s); // start new block
6358*4882a593Smuzhiyun             if (len == 0)
6359*4882a593Smuzhiyun                return g->out;
6360*4882a593Smuzhiyun          }
6361*4882a593Smuzhiyun          --len;
6362*4882a593Smuzhiyun          bits |= (stbi__int32) stbi__get8(s) << valid_bits;
6363*4882a593Smuzhiyun          valid_bits += 8;
6364*4882a593Smuzhiyun       } else {
6365*4882a593Smuzhiyun          stbi__int32 code = bits & codemask;
6366*4882a593Smuzhiyun          bits >>= codesize;
6367*4882a593Smuzhiyun          valid_bits -= codesize;
6368*4882a593Smuzhiyun          // @OPTIMIZE: is there some way we can accelerate the non-clear path?
6369*4882a593Smuzhiyun          if (code == clear) {  // clear code
6370*4882a593Smuzhiyun             codesize = lzw_cs + 1;
6371*4882a593Smuzhiyun             codemask = (1 << codesize) - 1;
6372*4882a593Smuzhiyun             avail = clear + 2;
6373*4882a593Smuzhiyun             oldcode = -1;
6374*4882a593Smuzhiyun             first = 0;
6375*4882a593Smuzhiyun          } else if (code == clear + 1) { // end of stream code
6376*4882a593Smuzhiyun             stbi__skip(s, len);
6377*4882a593Smuzhiyun             while ((len = stbi__get8(s)) > 0)
6378*4882a593Smuzhiyun                stbi__skip(s,len);
6379*4882a593Smuzhiyun             return g->out;
6380*4882a593Smuzhiyun          } else if (code <= avail) {
6381*4882a593Smuzhiyun             if (first) {
6382*4882a593Smuzhiyun                return stbi__errpuc("no clear code", "Corrupt GIF");
6383*4882a593Smuzhiyun             }
6384*4882a593Smuzhiyun 
6385*4882a593Smuzhiyun             if (oldcode >= 0) {
6386*4882a593Smuzhiyun                p = &g->codes[avail++];
6387*4882a593Smuzhiyun                if (avail > 8192) {
6388*4882a593Smuzhiyun                   return stbi__errpuc("too many codes", "Corrupt GIF");
6389*4882a593Smuzhiyun                }
6390*4882a593Smuzhiyun 
6391*4882a593Smuzhiyun                p->prefix = (stbi__int16) oldcode;
6392*4882a593Smuzhiyun                p->first = g->codes[oldcode].first;
6393*4882a593Smuzhiyun                p->suffix = (code == avail) ? p->first : g->codes[code].first;
6394*4882a593Smuzhiyun             } else if (code == avail)
6395*4882a593Smuzhiyun                return stbi__errpuc("illegal code in raster", "Corrupt GIF");
6396*4882a593Smuzhiyun 
6397*4882a593Smuzhiyun             stbi__out_gif_code(g, (stbi__uint16) code);
6398*4882a593Smuzhiyun 
6399*4882a593Smuzhiyun             if ((avail & codemask) == 0 && avail <= 0x0FFF) {
6400*4882a593Smuzhiyun                codesize++;
6401*4882a593Smuzhiyun                codemask = (1 << codesize) - 1;
6402*4882a593Smuzhiyun             }
6403*4882a593Smuzhiyun 
6404*4882a593Smuzhiyun             oldcode = code;
6405*4882a593Smuzhiyun          } else {
6406*4882a593Smuzhiyun             return stbi__errpuc("illegal code in raster", "Corrupt GIF");
6407*4882a593Smuzhiyun          }
6408*4882a593Smuzhiyun       }
6409*4882a593Smuzhiyun    }
6410*4882a593Smuzhiyun }
6411*4882a593Smuzhiyun 
6412*4882a593Smuzhiyun // this function is designed to support animated gifs, although stb_image doesn't support it
6413*4882a593Smuzhiyun // two back is the image from two frames ago, used for a very specific disposal format
stbi__gif_load_next(stbi__context * s,stbi__gif * g,int * comp,int req_comp,stbi_uc * two_back)6414*4882a593Smuzhiyun static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back)
6415*4882a593Smuzhiyun {
6416*4882a593Smuzhiyun    int dispose;
6417*4882a593Smuzhiyun    int first_frame;
6418*4882a593Smuzhiyun    int pi;
6419*4882a593Smuzhiyun    int pcount;
6420*4882a593Smuzhiyun    STBI_NOTUSED(req_comp);
6421*4882a593Smuzhiyun 
6422*4882a593Smuzhiyun    // on first frame, any non-written pixels get the background colour (non-transparent)
6423*4882a593Smuzhiyun    first_frame = 0;
6424*4882a593Smuzhiyun    if (g->out == 0) {
6425*4882a593Smuzhiyun       if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
6426*4882a593Smuzhiyun       if (!stbi__mad3sizes_valid(4, g->w, g->h, 0))
6427*4882a593Smuzhiyun          return stbi__errpuc("too large", "GIF image is too large");
6428*4882a593Smuzhiyun       pcount = g->w * g->h;
6429*4882a593Smuzhiyun       g->out = (stbi_uc *) stbi__malloc(4 * pcount);
6430*4882a593Smuzhiyun       g->background = (stbi_uc *) stbi__malloc(4 * pcount);
6431*4882a593Smuzhiyun       g->history = (stbi_uc *) stbi__malloc(pcount);
6432*4882a593Smuzhiyun       if (!g->out || !g->background || !g->history)
6433*4882a593Smuzhiyun          return stbi__errpuc("outofmem", "Out of memory");
6434*4882a593Smuzhiyun 
6435*4882a593Smuzhiyun       // image is treated as "transparent" at the start - ie, nothing overwrites the current background;
6436*4882a593Smuzhiyun       // background colour is only used for pixels that are not rendered first frame, after that "background"
6437*4882a593Smuzhiyun       // color refers to the color that was there the previous frame.
6438*4882a593Smuzhiyun       memset(g->out, 0x00, 4 * pcount);
6439*4882a593Smuzhiyun       memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent)
6440*4882a593Smuzhiyun       memset(g->history, 0x00, pcount);        // pixels that were affected previous frame
6441*4882a593Smuzhiyun       first_frame = 1;
6442*4882a593Smuzhiyun    } else {
6443*4882a593Smuzhiyun       // second frame - how do we dispoase of the previous one?
6444*4882a593Smuzhiyun       dispose = (g->eflags & 0x1C) >> 2;
6445*4882a593Smuzhiyun       pcount = g->w * g->h;
6446*4882a593Smuzhiyun 
6447*4882a593Smuzhiyun       if ((dispose == 3) && (two_back == 0)) {
6448*4882a593Smuzhiyun          dispose = 2; // if I don't have an image to revert back to, default to the old background
6449*4882a593Smuzhiyun       }
6450*4882a593Smuzhiyun 
6451*4882a593Smuzhiyun       if (dispose == 3) { // use previous graphic
6452*4882a593Smuzhiyun          for (pi = 0; pi < pcount; ++pi) {
6453*4882a593Smuzhiyun             if (g->history[pi]) {
6454*4882a593Smuzhiyun                memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 );
6455*4882a593Smuzhiyun             }
6456*4882a593Smuzhiyun          }
6457*4882a593Smuzhiyun       } else if (dispose == 2) {
6458*4882a593Smuzhiyun          // restore what was changed last frame to background before that frame;
6459*4882a593Smuzhiyun          for (pi = 0; pi < pcount; ++pi) {
6460*4882a593Smuzhiyun             if (g->history[pi]) {
6461*4882a593Smuzhiyun                memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 );
6462*4882a593Smuzhiyun             }
6463*4882a593Smuzhiyun          }
6464*4882a593Smuzhiyun       } else {
6465*4882a593Smuzhiyun          // This is a non-disposal case eithe way, so just
6466*4882a593Smuzhiyun          // leave the pixels as is, and they will become the new background
6467*4882a593Smuzhiyun          // 1: do not dispose
6468*4882a593Smuzhiyun          // 0:  not specified.
6469*4882a593Smuzhiyun       }
6470*4882a593Smuzhiyun 
6471*4882a593Smuzhiyun       // background is what out is after the undoing of the previou frame;
6472*4882a593Smuzhiyun       memcpy( g->background, g->out, 4 * g->w * g->h );
6473*4882a593Smuzhiyun    }
6474*4882a593Smuzhiyun 
6475*4882a593Smuzhiyun    // clear my history;
6476*4882a593Smuzhiyun    memset( g->history, 0x00, g->w * g->h );        // pixels that were affected previous frame
6477*4882a593Smuzhiyun 
6478*4882a593Smuzhiyun    for (;;) {
6479*4882a593Smuzhiyun       int tag = stbi__get8(s);
6480*4882a593Smuzhiyun       switch (tag) {
6481*4882a593Smuzhiyun          case 0x2C: /* Image Descriptor */
6482*4882a593Smuzhiyun          {
6483*4882a593Smuzhiyun             stbi__int32 x, y, w, h;
6484*4882a593Smuzhiyun             stbi_uc *o;
6485*4882a593Smuzhiyun 
6486*4882a593Smuzhiyun             x = stbi__get16le(s);
6487*4882a593Smuzhiyun             y = stbi__get16le(s);
6488*4882a593Smuzhiyun             w = stbi__get16le(s);
6489*4882a593Smuzhiyun             h = stbi__get16le(s);
6490*4882a593Smuzhiyun             if (((x + w) > (g->w)) || ((y + h) > (g->h)))
6491*4882a593Smuzhiyun                return stbi__errpuc("bad Image Descriptor", "Corrupt GIF");
6492*4882a593Smuzhiyun 
6493*4882a593Smuzhiyun             g->line_size = g->w * 4;
6494*4882a593Smuzhiyun             g->start_x = x * 4;
6495*4882a593Smuzhiyun             g->start_y = y * g->line_size;
6496*4882a593Smuzhiyun             g->max_x   = g->start_x + w * 4;
6497*4882a593Smuzhiyun             g->max_y   = g->start_y + h * g->line_size;
6498*4882a593Smuzhiyun             g->cur_x   = g->start_x;
6499*4882a593Smuzhiyun             g->cur_y   = g->start_y;
6500*4882a593Smuzhiyun 
6501*4882a593Smuzhiyun             // if the width of the specified rectangle is 0, that means
6502*4882a593Smuzhiyun             // we may not see *any* pixels or the image is malformed;
6503*4882a593Smuzhiyun             // to make sure this is caught, move the current y down to
6504*4882a593Smuzhiyun             // max_y (which is what out_gif_code checks).
6505*4882a593Smuzhiyun             if (w == 0)
6506*4882a593Smuzhiyun                g->cur_y = g->max_y;
6507*4882a593Smuzhiyun 
6508*4882a593Smuzhiyun             g->lflags = stbi__get8(s);
6509*4882a593Smuzhiyun 
6510*4882a593Smuzhiyun             if (g->lflags & 0x40) {
6511*4882a593Smuzhiyun                g->step = 8 * g->line_size; // first interlaced spacing
6512*4882a593Smuzhiyun                g->parse = 3;
6513*4882a593Smuzhiyun             } else {
6514*4882a593Smuzhiyun                g->step = g->line_size;
6515*4882a593Smuzhiyun                g->parse = 0;
6516*4882a593Smuzhiyun             }
6517*4882a593Smuzhiyun 
6518*4882a593Smuzhiyun             if (g->lflags & 0x80) {
6519*4882a593Smuzhiyun                stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1);
6520*4882a593Smuzhiyun                g->color_table = (stbi_uc *) g->lpal;
6521*4882a593Smuzhiyun             } else if (g->flags & 0x80) {
6522*4882a593Smuzhiyun                g->color_table = (stbi_uc *) g->pal;
6523*4882a593Smuzhiyun             } else
6524*4882a593Smuzhiyun                return stbi__errpuc("missing color table", "Corrupt GIF");
6525*4882a593Smuzhiyun 
6526*4882a593Smuzhiyun             o = stbi__process_gif_raster(s, g);
6527*4882a593Smuzhiyun             if (!o) return NULL;
6528*4882a593Smuzhiyun 
6529*4882a593Smuzhiyun             // if this was the first frame,
6530*4882a593Smuzhiyun             pcount = g->w * g->h;
6531*4882a593Smuzhiyun             if (first_frame && (g->bgindex > 0)) {
6532*4882a593Smuzhiyun                // if first frame, any pixel not drawn to gets the background color
6533*4882a593Smuzhiyun                for (pi = 0; pi < pcount; ++pi) {
6534*4882a593Smuzhiyun                   if (g->history[pi] == 0) {
6535*4882a593Smuzhiyun                      g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be;
6536*4882a593Smuzhiyun                      memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 );
6537*4882a593Smuzhiyun                   }
6538*4882a593Smuzhiyun                }
6539*4882a593Smuzhiyun             }
6540*4882a593Smuzhiyun 
6541*4882a593Smuzhiyun             return o;
6542*4882a593Smuzhiyun          }
6543*4882a593Smuzhiyun 
6544*4882a593Smuzhiyun          case 0x21: // Comment Extension.
6545*4882a593Smuzhiyun          {
6546*4882a593Smuzhiyun             int len;
6547*4882a593Smuzhiyun             int ext = stbi__get8(s);
6548*4882a593Smuzhiyun             if (ext == 0xF9) { // Graphic Control Extension.
6549*4882a593Smuzhiyun                len = stbi__get8(s);
6550*4882a593Smuzhiyun                if (len == 4) {
6551*4882a593Smuzhiyun                   g->eflags = stbi__get8(s);
6552*4882a593Smuzhiyun                   g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths.
6553*4882a593Smuzhiyun 
6554*4882a593Smuzhiyun                   // unset old transparent
6555*4882a593Smuzhiyun                   if (g->transparent >= 0) {
6556*4882a593Smuzhiyun                      g->pal[g->transparent][3] = 255;
6557*4882a593Smuzhiyun                   }
6558*4882a593Smuzhiyun                   if (g->eflags & 0x01) {
6559*4882a593Smuzhiyun                      g->transparent = stbi__get8(s);
6560*4882a593Smuzhiyun                      if (g->transparent >= 0) {
6561*4882a593Smuzhiyun                         g->pal[g->transparent][3] = 0;
6562*4882a593Smuzhiyun                      }
6563*4882a593Smuzhiyun                   } else {
6564*4882a593Smuzhiyun                      // don't need transparent
6565*4882a593Smuzhiyun                      stbi__skip(s, 1);
6566*4882a593Smuzhiyun                      g->transparent = -1;
6567*4882a593Smuzhiyun                   }
6568*4882a593Smuzhiyun                } else {
6569*4882a593Smuzhiyun                   stbi__skip(s, len);
6570*4882a593Smuzhiyun                   break;
6571*4882a593Smuzhiyun                }
6572*4882a593Smuzhiyun             }
6573*4882a593Smuzhiyun             while ((len = stbi__get8(s)) != 0) {
6574*4882a593Smuzhiyun                stbi__skip(s, len);
6575*4882a593Smuzhiyun             }
6576*4882a593Smuzhiyun             break;
6577*4882a593Smuzhiyun          }
6578*4882a593Smuzhiyun 
6579*4882a593Smuzhiyun          case 0x3B: // gif stream termination code
6580*4882a593Smuzhiyun             return (stbi_uc *) s; // using '1' causes warning on some compilers
6581*4882a593Smuzhiyun 
6582*4882a593Smuzhiyun          default:
6583*4882a593Smuzhiyun             return stbi__errpuc("unknown code", "Corrupt GIF");
6584*4882a593Smuzhiyun       }
6585*4882a593Smuzhiyun    }
6586*4882a593Smuzhiyun }
6587*4882a593Smuzhiyun 
stbi__load_gif_main(stbi__context * s,int ** delays,int * x,int * y,int * z,int * comp,int req_comp)6588*4882a593Smuzhiyun static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
6589*4882a593Smuzhiyun {
6590*4882a593Smuzhiyun    if (stbi__gif_test(s)) {
6591*4882a593Smuzhiyun       int layers = 0;
6592*4882a593Smuzhiyun       stbi_uc *u = 0;
6593*4882a593Smuzhiyun       stbi_uc *out = 0;
6594*4882a593Smuzhiyun       stbi_uc *two_back = 0;
6595*4882a593Smuzhiyun       stbi__gif g;
6596*4882a593Smuzhiyun       int stride;
6597*4882a593Smuzhiyun       memset(&g, 0, sizeof(g));
6598*4882a593Smuzhiyun       if (delays) {
6599*4882a593Smuzhiyun          *delays = 0;
6600*4882a593Smuzhiyun       }
6601*4882a593Smuzhiyun 
6602*4882a593Smuzhiyun       do {
6603*4882a593Smuzhiyun          u = stbi__gif_load_next(s, &g, comp, req_comp, two_back);
6604*4882a593Smuzhiyun          if (u == (stbi_uc *) s) u = 0;  // end of animated gif marker
6605*4882a593Smuzhiyun 
6606*4882a593Smuzhiyun          if (u) {
6607*4882a593Smuzhiyun             *x = g.w;
6608*4882a593Smuzhiyun             *y = g.h;
6609*4882a593Smuzhiyun             ++layers;
6610*4882a593Smuzhiyun             stride = g.w * g.h * 4;
6611*4882a593Smuzhiyun 
6612*4882a593Smuzhiyun             if (out) {
6613*4882a593Smuzhiyun                out = (stbi_uc*) STBI_REALLOC( out, layers * stride );
6614*4882a593Smuzhiyun                if (delays) {
6615*4882a593Smuzhiyun                   *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
6616*4882a593Smuzhiyun                }
6617*4882a593Smuzhiyun             } else {
6618*4882a593Smuzhiyun                out = (stbi_uc*)stbi__malloc( layers * stride );
6619*4882a593Smuzhiyun                if (delays) {
6620*4882a593Smuzhiyun                   *delays = (int*) stbi__malloc( layers * sizeof(int) );
6621*4882a593Smuzhiyun                }
6622*4882a593Smuzhiyun             }
6623*4882a593Smuzhiyun             memcpy( out + ((layers - 1) * stride), u, stride );
6624*4882a593Smuzhiyun             if (layers >= 2) {
6625*4882a593Smuzhiyun                two_back = out - 2 * stride;
6626*4882a593Smuzhiyun             }
6627*4882a593Smuzhiyun 
6628*4882a593Smuzhiyun             if (delays) {
6629*4882a593Smuzhiyun                (*delays)[layers - 1U] = g.delay;
6630*4882a593Smuzhiyun             }
6631*4882a593Smuzhiyun          }
6632*4882a593Smuzhiyun       } while (u != 0);
6633*4882a593Smuzhiyun 
6634*4882a593Smuzhiyun       // free temp buffer;
6635*4882a593Smuzhiyun       STBI_FREE(g.out);
6636*4882a593Smuzhiyun       STBI_FREE(g.history);
6637*4882a593Smuzhiyun       STBI_FREE(g.background);
6638*4882a593Smuzhiyun 
6639*4882a593Smuzhiyun       // do the final conversion after loading everything;
6640*4882a593Smuzhiyun       if (req_comp && req_comp != 4)
6641*4882a593Smuzhiyun          out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h);
6642*4882a593Smuzhiyun 
6643*4882a593Smuzhiyun       *z = layers;
6644*4882a593Smuzhiyun       return out;
6645*4882a593Smuzhiyun    } else {
6646*4882a593Smuzhiyun       return stbi__errpuc("not GIF", "Image was not as a gif type.");
6647*4882a593Smuzhiyun    }
6648*4882a593Smuzhiyun }
6649*4882a593Smuzhiyun 
stbi__gif_load(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri)6650*4882a593Smuzhiyun static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
6651*4882a593Smuzhiyun {
6652*4882a593Smuzhiyun    stbi_uc *u = 0;
6653*4882a593Smuzhiyun    stbi__gif g;
6654*4882a593Smuzhiyun    memset(&g, 0, sizeof(g));
6655*4882a593Smuzhiyun    STBI_NOTUSED(ri);
6656*4882a593Smuzhiyun 
6657*4882a593Smuzhiyun    u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
6658*4882a593Smuzhiyun    if (u == (stbi_uc *) s) u = 0;  // end of animated gif marker
6659*4882a593Smuzhiyun    if (u) {
6660*4882a593Smuzhiyun       *x = g.w;
6661*4882a593Smuzhiyun       *y = g.h;
6662*4882a593Smuzhiyun 
6663*4882a593Smuzhiyun       // moved conversion to after successful load so that the same
6664*4882a593Smuzhiyun       // can be done for multiple frames.
6665*4882a593Smuzhiyun       if (req_comp && req_comp != 4)
6666*4882a593Smuzhiyun          u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
6667*4882a593Smuzhiyun    } else if (g.out) {
6668*4882a593Smuzhiyun       // if there was an error and we allocated an image buffer, free it!
6669*4882a593Smuzhiyun       STBI_FREE(g.out);
6670*4882a593Smuzhiyun    }
6671*4882a593Smuzhiyun 
6672*4882a593Smuzhiyun    // free buffers needed for multiple frame loading;
6673*4882a593Smuzhiyun    STBI_FREE(g.history);
6674*4882a593Smuzhiyun    STBI_FREE(g.background);
6675*4882a593Smuzhiyun 
6676*4882a593Smuzhiyun    return u;
6677*4882a593Smuzhiyun }
6678*4882a593Smuzhiyun 
stbi__gif_info(stbi__context * s,int * x,int * y,int * comp)6679*4882a593Smuzhiyun static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp)
6680*4882a593Smuzhiyun {
6681*4882a593Smuzhiyun    return stbi__gif_info_raw(s,x,y,comp);
6682*4882a593Smuzhiyun }
6683*4882a593Smuzhiyun #endif
6684*4882a593Smuzhiyun 
6685*4882a593Smuzhiyun // *************************************************************************************************
6686*4882a593Smuzhiyun // Radiance RGBE HDR loader
6687*4882a593Smuzhiyun // originally by Nicolas Schulz
6688*4882a593Smuzhiyun #ifndef STBI_NO_HDR
stbi__hdr_test_core(stbi__context * s,const char * signature)6689*4882a593Smuzhiyun static int stbi__hdr_test_core(stbi__context *s, const char *signature)
6690*4882a593Smuzhiyun {
6691*4882a593Smuzhiyun    int i;
6692*4882a593Smuzhiyun    for (i=0; signature[i]; ++i)
6693*4882a593Smuzhiyun       if (stbi__get8(s) != signature[i])
6694*4882a593Smuzhiyun           return 0;
6695*4882a593Smuzhiyun    stbi__rewind(s);
6696*4882a593Smuzhiyun    return 1;
6697*4882a593Smuzhiyun }
6698*4882a593Smuzhiyun 
stbi__hdr_test(stbi__context * s)6699*4882a593Smuzhiyun static int stbi__hdr_test(stbi__context* s)
6700*4882a593Smuzhiyun {
6701*4882a593Smuzhiyun    int r = stbi__hdr_test_core(s, "#?RADIANCE\n");
6702*4882a593Smuzhiyun    stbi__rewind(s);
6703*4882a593Smuzhiyun    if(!r) {
6704*4882a593Smuzhiyun        r = stbi__hdr_test_core(s, "#?RGBE\n");
6705*4882a593Smuzhiyun        stbi__rewind(s);
6706*4882a593Smuzhiyun    }
6707*4882a593Smuzhiyun    return r;
6708*4882a593Smuzhiyun }
6709*4882a593Smuzhiyun 
6710*4882a593Smuzhiyun #define STBI__HDR_BUFLEN  1024
stbi__hdr_gettoken(stbi__context * z,char * buffer)6711*4882a593Smuzhiyun static char *stbi__hdr_gettoken(stbi__context *z, char *buffer)
6712*4882a593Smuzhiyun {
6713*4882a593Smuzhiyun    int len=0;
6714*4882a593Smuzhiyun    char c = '\0';
6715*4882a593Smuzhiyun 
6716*4882a593Smuzhiyun    c = (char) stbi__get8(z);
6717*4882a593Smuzhiyun 
6718*4882a593Smuzhiyun    while (!stbi__at_eof(z) && c != '\n') {
6719*4882a593Smuzhiyun       buffer[len++] = c;
6720*4882a593Smuzhiyun       if (len == STBI__HDR_BUFLEN-1) {
6721*4882a593Smuzhiyun          // flush to end of line
6722*4882a593Smuzhiyun          while (!stbi__at_eof(z) && stbi__get8(z) != '\n')
6723*4882a593Smuzhiyun             ;
6724*4882a593Smuzhiyun          break;
6725*4882a593Smuzhiyun       }
6726*4882a593Smuzhiyun       c = (char) stbi__get8(z);
6727*4882a593Smuzhiyun    }
6728*4882a593Smuzhiyun 
6729*4882a593Smuzhiyun    buffer[len] = 0;
6730*4882a593Smuzhiyun    return buffer;
6731*4882a593Smuzhiyun }
6732*4882a593Smuzhiyun 
stbi__hdr_convert(float * output,stbi_uc * input,int req_comp)6733*4882a593Smuzhiyun static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp)
6734*4882a593Smuzhiyun {
6735*4882a593Smuzhiyun    if ( input[3] != 0 ) {
6736*4882a593Smuzhiyun       float f1;
6737*4882a593Smuzhiyun       // Exponent
6738*4882a593Smuzhiyun       f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8));
6739*4882a593Smuzhiyun       if (req_comp <= 2)
6740*4882a593Smuzhiyun          output[0] = (input[0] + input[1] + input[2]) * f1 / 3;
6741*4882a593Smuzhiyun       else {
6742*4882a593Smuzhiyun          output[0] = input[0] * f1;
6743*4882a593Smuzhiyun          output[1] = input[1] * f1;
6744*4882a593Smuzhiyun          output[2] = input[2] * f1;
6745*4882a593Smuzhiyun       }
6746*4882a593Smuzhiyun       if (req_comp == 2) output[1] = 1;
6747*4882a593Smuzhiyun       if (req_comp == 4) output[3] = 1;
6748*4882a593Smuzhiyun    } else {
6749*4882a593Smuzhiyun       switch (req_comp) {
6750*4882a593Smuzhiyun          case 4: output[3] = 1; /* fallthrough */
6751*4882a593Smuzhiyun          case 3: output[0] = output[1] = output[2] = 0;
6752*4882a593Smuzhiyun                  break;
6753*4882a593Smuzhiyun          case 2: output[1] = 1; /* fallthrough */
6754*4882a593Smuzhiyun          case 1: output[0] = 0;
6755*4882a593Smuzhiyun                  break;
6756*4882a593Smuzhiyun       }
6757*4882a593Smuzhiyun    }
6758*4882a593Smuzhiyun }
6759*4882a593Smuzhiyun 
stbi__hdr_load(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri)6760*4882a593Smuzhiyun static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
6761*4882a593Smuzhiyun {
6762*4882a593Smuzhiyun    char buffer[STBI__HDR_BUFLEN];
6763*4882a593Smuzhiyun    char *token;
6764*4882a593Smuzhiyun    int valid = 0;
6765*4882a593Smuzhiyun    int width, height;
6766*4882a593Smuzhiyun    stbi_uc *scanline;
6767*4882a593Smuzhiyun    float *hdr_data;
6768*4882a593Smuzhiyun    int len;
6769*4882a593Smuzhiyun    unsigned char count, value;
6770*4882a593Smuzhiyun    int i, j, k, c1,c2, z;
6771*4882a593Smuzhiyun    const char *headerToken;
6772*4882a593Smuzhiyun    STBI_NOTUSED(ri);
6773*4882a593Smuzhiyun 
6774*4882a593Smuzhiyun    // Check identifier
6775*4882a593Smuzhiyun    headerToken = stbi__hdr_gettoken(s,buffer);
6776*4882a593Smuzhiyun    if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0)
6777*4882a593Smuzhiyun       return stbi__errpf("not HDR", "Corrupt HDR image");
6778*4882a593Smuzhiyun 
6779*4882a593Smuzhiyun    // Parse header
6780*4882a593Smuzhiyun    for(;;) {
6781*4882a593Smuzhiyun       token = stbi__hdr_gettoken(s,buffer);
6782*4882a593Smuzhiyun       if (token[0] == 0) break;
6783*4882a593Smuzhiyun       if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
6784*4882a593Smuzhiyun    }
6785*4882a593Smuzhiyun 
6786*4882a593Smuzhiyun    if (!valid)    return stbi__errpf("unsupported format", "Unsupported HDR format");
6787*4882a593Smuzhiyun 
6788*4882a593Smuzhiyun    // Parse width and height
6789*4882a593Smuzhiyun    // can't use sscanf() if we're not using stdio!
6790*4882a593Smuzhiyun    token = stbi__hdr_gettoken(s,buffer);
6791*4882a593Smuzhiyun    if (strncmp(token, "-Y ", 3))  return stbi__errpf("unsupported data layout", "Unsupported HDR format");
6792*4882a593Smuzhiyun    token += 3;
6793*4882a593Smuzhiyun    height = (int) strtol(token, &token, 10);
6794*4882a593Smuzhiyun    while (*token == ' ') ++token;
6795*4882a593Smuzhiyun    if (strncmp(token, "+X ", 3))  return stbi__errpf("unsupported data layout", "Unsupported HDR format");
6796*4882a593Smuzhiyun    token += 3;
6797*4882a593Smuzhiyun    width = (int) strtol(token, NULL, 10);
6798*4882a593Smuzhiyun 
6799*4882a593Smuzhiyun    *x = width;
6800*4882a593Smuzhiyun    *y = height;
6801*4882a593Smuzhiyun 
6802*4882a593Smuzhiyun    if (comp) *comp = 3;
6803*4882a593Smuzhiyun    if (req_comp == 0) req_comp = 3;
6804*4882a593Smuzhiyun 
6805*4882a593Smuzhiyun    if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0))
6806*4882a593Smuzhiyun       return stbi__errpf("too large", "HDR image is too large");
6807*4882a593Smuzhiyun 
6808*4882a593Smuzhiyun    // Read data
6809*4882a593Smuzhiyun    hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0);
6810*4882a593Smuzhiyun    if (!hdr_data)
6811*4882a593Smuzhiyun       return stbi__errpf("outofmem", "Out of memory");
6812*4882a593Smuzhiyun 
6813*4882a593Smuzhiyun    // Load image data
6814*4882a593Smuzhiyun    // image data is stored as some number of sca
6815*4882a593Smuzhiyun    if ( width < 8 || width >= 32768) {
6816*4882a593Smuzhiyun       // Read flat data
6817*4882a593Smuzhiyun       for (j=0; j < height; ++j) {
6818*4882a593Smuzhiyun          for (i=0; i < width; ++i) {
6819*4882a593Smuzhiyun             stbi_uc rgbe[4];
6820*4882a593Smuzhiyun            main_decode_loop:
6821*4882a593Smuzhiyun             stbi__getn(s, rgbe, 4);
6822*4882a593Smuzhiyun             stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
6823*4882a593Smuzhiyun          }
6824*4882a593Smuzhiyun       }
6825*4882a593Smuzhiyun    } else {
6826*4882a593Smuzhiyun       // Read RLE-encoded data
6827*4882a593Smuzhiyun       scanline = NULL;
6828*4882a593Smuzhiyun 
6829*4882a593Smuzhiyun       for (j = 0; j < height; ++j) {
6830*4882a593Smuzhiyun          c1 = stbi__get8(s);
6831*4882a593Smuzhiyun          c2 = stbi__get8(s);
6832*4882a593Smuzhiyun          len = stbi__get8(s);
6833*4882a593Smuzhiyun          if (c1 != 2 || c2 != 2 || (len & 0x80)) {
6834*4882a593Smuzhiyun             // not run-length encoded, so we have to actually use THIS data as a decoded
6835*4882a593Smuzhiyun             // pixel (note this can't be a valid pixel--one of RGB must be >= 128)
6836*4882a593Smuzhiyun             stbi_uc rgbe[4];
6837*4882a593Smuzhiyun             rgbe[0] = (stbi_uc) c1;
6838*4882a593Smuzhiyun             rgbe[1] = (stbi_uc) c2;
6839*4882a593Smuzhiyun             rgbe[2] = (stbi_uc) len;
6840*4882a593Smuzhiyun             rgbe[3] = (stbi_uc) stbi__get8(s);
6841*4882a593Smuzhiyun             stbi__hdr_convert(hdr_data, rgbe, req_comp);
6842*4882a593Smuzhiyun             i = 1;
6843*4882a593Smuzhiyun             j = 0;
6844*4882a593Smuzhiyun             STBI_FREE(scanline);
6845*4882a593Smuzhiyun             goto main_decode_loop; // yes, this makes no sense
6846*4882a593Smuzhiyun          }
6847*4882a593Smuzhiyun          len <<= 8;
6848*4882a593Smuzhiyun          len |= stbi__get8(s);
6849*4882a593Smuzhiyun          if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
6850*4882a593Smuzhiyun          if (scanline == NULL) {
6851*4882a593Smuzhiyun             scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0);
6852*4882a593Smuzhiyun             if (!scanline) {
6853*4882a593Smuzhiyun                STBI_FREE(hdr_data);
6854*4882a593Smuzhiyun                return stbi__errpf("outofmem", "Out of memory");
6855*4882a593Smuzhiyun             }
6856*4882a593Smuzhiyun          }
6857*4882a593Smuzhiyun 
6858*4882a593Smuzhiyun          for (k = 0; k < 4; ++k) {
6859*4882a593Smuzhiyun             int nleft;
6860*4882a593Smuzhiyun             i = 0;
6861*4882a593Smuzhiyun             while ((nleft = width - i) > 0) {
6862*4882a593Smuzhiyun                count = stbi__get8(s);
6863*4882a593Smuzhiyun                if (count > 128) {
6864*4882a593Smuzhiyun                   // Run
6865*4882a593Smuzhiyun                   value = stbi__get8(s);
6866*4882a593Smuzhiyun                   count -= 128;
6867*4882a593Smuzhiyun                   if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
6868*4882a593Smuzhiyun                   for (z = 0; z < count; ++z)
6869*4882a593Smuzhiyun                      scanline[i++ * 4 + k] = value;
6870*4882a593Smuzhiyun                } else {
6871*4882a593Smuzhiyun                   // Dump
6872*4882a593Smuzhiyun                   if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
6873*4882a593Smuzhiyun                   for (z = 0; z < count; ++z)
6874*4882a593Smuzhiyun                      scanline[i++ * 4 + k] = stbi__get8(s);
6875*4882a593Smuzhiyun                }
6876*4882a593Smuzhiyun             }
6877*4882a593Smuzhiyun          }
6878*4882a593Smuzhiyun          for (i=0; i < width; ++i)
6879*4882a593Smuzhiyun             stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
6880*4882a593Smuzhiyun       }
6881*4882a593Smuzhiyun       if (scanline)
6882*4882a593Smuzhiyun          STBI_FREE(scanline);
6883*4882a593Smuzhiyun    }
6884*4882a593Smuzhiyun 
6885*4882a593Smuzhiyun    return hdr_data;
6886*4882a593Smuzhiyun }
6887*4882a593Smuzhiyun 
stbi__hdr_info(stbi__context * s,int * x,int * y,int * comp)6888*4882a593Smuzhiyun static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
6889*4882a593Smuzhiyun {
6890*4882a593Smuzhiyun    char buffer[STBI__HDR_BUFLEN];
6891*4882a593Smuzhiyun    char *token;
6892*4882a593Smuzhiyun    int valid = 0;
6893*4882a593Smuzhiyun    int dummy;
6894*4882a593Smuzhiyun 
6895*4882a593Smuzhiyun    if (!x) x = &dummy;
6896*4882a593Smuzhiyun    if (!y) y = &dummy;
6897*4882a593Smuzhiyun    if (!comp) comp = &dummy;
6898*4882a593Smuzhiyun 
6899*4882a593Smuzhiyun    if (stbi__hdr_test(s) == 0) {
6900*4882a593Smuzhiyun        stbi__rewind( s );
6901*4882a593Smuzhiyun        return 0;
6902*4882a593Smuzhiyun    }
6903*4882a593Smuzhiyun 
6904*4882a593Smuzhiyun    for(;;) {
6905*4882a593Smuzhiyun       token = stbi__hdr_gettoken(s,buffer);
6906*4882a593Smuzhiyun       if (token[0] == 0) break;
6907*4882a593Smuzhiyun       if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
6908*4882a593Smuzhiyun    }
6909*4882a593Smuzhiyun 
6910*4882a593Smuzhiyun    if (!valid) {
6911*4882a593Smuzhiyun        stbi__rewind( s );
6912*4882a593Smuzhiyun        return 0;
6913*4882a593Smuzhiyun    }
6914*4882a593Smuzhiyun    token = stbi__hdr_gettoken(s,buffer);
6915*4882a593Smuzhiyun    if (strncmp(token, "-Y ", 3)) {
6916*4882a593Smuzhiyun        stbi__rewind( s );
6917*4882a593Smuzhiyun        return 0;
6918*4882a593Smuzhiyun    }
6919*4882a593Smuzhiyun    token += 3;
6920*4882a593Smuzhiyun    *y = (int) strtol(token, &token, 10);
6921*4882a593Smuzhiyun    while (*token == ' ') ++token;
6922*4882a593Smuzhiyun    if (strncmp(token, "+X ", 3)) {
6923*4882a593Smuzhiyun        stbi__rewind( s );
6924*4882a593Smuzhiyun        return 0;
6925*4882a593Smuzhiyun    }
6926*4882a593Smuzhiyun    token += 3;
6927*4882a593Smuzhiyun    *x = (int) strtol(token, NULL, 10);
6928*4882a593Smuzhiyun    *comp = 3;
6929*4882a593Smuzhiyun    return 1;
6930*4882a593Smuzhiyun }
6931*4882a593Smuzhiyun #endif // STBI_NO_HDR
6932*4882a593Smuzhiyun 
6933*4882a593Smuzhiyun #ifndef STBI_NO_BMP
stbi__bmp_info(stbi__context * s,int * x,int * y,int * comp)6934*4882a593Smuzhiyun static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
6935*4882a593Smuzhiyun {
6936*4882a593Smuzhiyun    void *p;
6937*4882a593Smuzhiyun    stbi__bmp_data info;
6938*4882a593Smuzhiyun 
6939*4882a593Smuzhiyun    info.all_a = 255;
6940*4882a593Smuzhiyun    p = stbi__bmp_parse_header(s, &info);
6941*4882a593Smuzhiyun    stbi__rewind( s );
6942*4882a593Smuzhiyun    if (p == NULL)
6943*4882a593Smuzhiyun       return 0;
6944*4882a593Smuzhiyun    if (x) *x = s->img_x;
6945*4882a593Smuzhiyun    if (y) *y = s->img_y;
6946*4882a593Smuzhiyun    if (comp) {
6947*4882a593Smuzhiyun       if (info.bpp == 24 && info.ma == 0xff000000)
6948*4882a593Smuzhiyun          *comp = 3;
6949*4882a593Smuzhiyun       else
6950*4882a593Smuzhiyun          *comp = info.ma ? 4 : 3;
6951*4882a593Smuzhiyun    }
6952*4882a593Smuzhiyun    return 1;
6953*4882a593Smuzhiyun }
6954*4882a593Smuzhiyun #endif
6955*4882a593Smuzhiyun 
6956*4882a593Smuzhiyun #ifndef STBI_NO_PSD
stbi__psd_info(stbi__context * s,int * x,int * y,int * comp)6957*4882a593Smuzhiyun static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
6958*4882a593Smuzhiyun {
6959*4882a593Smuzhiyun    int channelCount, dummy, depth;
6960*4882a593Smuzhiyun    if (!x) x = &dummy;
6961*4882a593Smuzhiyun    if (!y) y = &dummy;
6962*4882a593Smuzhiyun    if (!comp) comp = &dummy;
6963*4882a593Smuzhiyun    if (stbi__get32be(s) != 0x38425053) {
6964*4882a593Smuzhiyun        stbi__rewind( s );
6965*4882a593Smuzhiyun        return 0;
6966*4882a593Smuzhiyun    }
6967*4882a593Smuzhiyun    if (stbi__get16be(s) != 1) {
6968*4882a593Smuzhiyun        stbi__rewind( s );
6969*4882a593Smuzhiyun        return 0;
6970*4882a593Smuzhiyun    }
6971*4882a593Smuzhiyun    stbi__skip(s, 6);
6972*4882a593Smuzhiyun    channelCount = stbi__get16be(s);
6973*4882a593Smuzhiyun    if (channelCount < 0 || channelCount > 16) {
6974*4882a593Smuzhiyun        stbi__rewind( s );
6975*4882a593Smuzhiyun        return 0;
6976*4882a593Smuzhiyun    }
6977*4882a593Smuzhiyun    *y = stbi__get32be(s);
6978*4882a593Smuzhiyun    *x = stbi__get32be(s);
6979*4882a593Smuzhiyun    depth = stbi__get16be(s);
6980*4882a593Smuzhiyun    if (depth != 8 && depth != 16) {
6981*4882a593Smuzhiyun        stbi__rewind( s );
6982*4882a593Smuzhiyun        return 0;
6983*4882a593Smuzhiyun    }
6984*4882a593Smuzhiyun    if (stbi__get16be(s) != 3) {
6985*4882a593Smuzhiyun        stbi__rewind( s );
6986*4882a593Smuzhiyun        return 0;
6987*4882a593Smuzhiyun    }
6988*4882a593Smuzhiyun    *comp = 4;
6989*4882a593Smuzhiyun    return 1;
6990*4882a593Smuzhiyun }
6991*4882a593Smuzhiyun 
stbi__psd_is16(stbi__context * s)6992*4882a593Smuzhiyun static int stbi__psd_is16(stbi__context *s)
6993*4882a593Smuzhiyun {
6994*4882a593Smuzhiyun    int channelCount, depth;
6995*4882a593Smuzhiyun    if (stbi__get32be(s) != 0x38425053) {
6996*4882a593Smuzhiyun        stbi__rewind( s );
6997*4882a593Smuzhiyun        return 0;
6998*4882a593Smuzhiyun    }
6999*4882a593Smuzhiyun    if (stbi__get16be(s) != 1) {
7000*4882a593Smuzhiyun        stbi__rewind( s );
7001*4882a593Smuzhiyun        return 0;
7002*4882a593Smuzhiyun    }
7003*4882a593Smuzhiyun    stbi__skip(s, 6);
7004*4882a593Smuzhiyun    channelCount = stbi__get16be(s);
7005*4882a593Smuzhiyun    if (channelCount < 0 || channelCount > 16) {
7006*4882a593Smuzhiyun        stbi__rewind( s );
7007*4882a593Smuzhiyun        return 0;
7008*4882a593Smuzhiyun    }
7009*4882a593Smuzhiyun    (void) stbi__get32be(s);
7010*4882a593Smuzhiyun    (void) stbi__get32be(s);
7011*4882a593Smuzhiyun    depth = stbi__get16be(s);
7012*4882a593Smuzhiyun    if (depth != 16) {
7013*4882a593Smuzhiyun        stbi__rewind( s );
7014*4882a593Smuzhiyun        return 0;
7015*4882a593Smuzhiyun    }
7016*4882a593Smuzhiyun    return 1;
7017*4882a593Smuzhiyun }
7018*4882a593Smuzhiyun #endif
7019*4882a593Smuzhiyun 
7020*4882a593Smuzhiyun #ifndef STBI_NO_PIC
stbi__pic_info(stbi__context * s,int * x,int * y,int * comp)7021*4882a593Smuzhiyun static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
7022*4882a593Smuzhiyun {
7023*4882a593Smuzhiyun    int act_comp=0,num_packets=0,chained,dummy;
7024*4882a593Smuzhiyun    stbi__pic_packet packets[10];
7025*4882a593Smuzhiyun 
7026*4882a593Smuzhiyun    if (!x) x = &dummy;
7027*4882a593Smuzhiyun    if (!y) y = &dummy;
7028*4882a593Smuzhiyun    if (!comp) comp = &dummy;
7029*4882a593Smuzhiyun 
7030*4882a593Smuzhiyun    if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
7031*4882a593Smuzhiyun       stbi__rewind(s);
7032*4882a593Smuzhiyun       return 0;
7033*4882a593Smuzhiyun    }
7034*4882a593Smuzhiyun 
7035*4882a593Smuzhiyun    stbi__skip(s, 88);
7036*4882a593Smuzhiyun 
7037*4882a593Smuzhiyun    *x = stbi__get16be(s);
7038*4882a593Smuzhiyun    *y = stbi__get16be(s);
7039*4882a593Smuzhiyun    if (stbi__at_eof(s)) {
7040*4882a593Smuzhiyun       stbi__rewind( s);
7041*4882a593Smuzhiyun       return 0;
7042*4882a593Smuzhiyun    }
7043*4882a593Smuzhiyun    if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) {
7044*4882a593Smuzhiyun       stbi__rewind( s );
7045*4882a593Smuzhiyun       return 0;
7046*4882a593Smuzhiyun    }
7047*4882a593Smuzhiyun 
7048*4882a593Smuzhiyun    stbi__skip(s, 8);
7049*4882a593Smuzhiyun 
7050*4882a593Smuzhiyun    do {
7051*4882a593Smuzhiyun       stbi__pic_packet *packet;
7052*4882a593Smuzhiyun 
7053*4882a593Smuzhiyun       if (num_packets==sizeof(packets)/sizeof(packets[0]))
7054*4882a593Smuzhiyun          return 0;
7055*4882a593Smuzhiyun 
7056*4882a593Smuzhiyun       packet = &packets[num_packets++];
7057*4882a593Smuzhiyun       chained = stbi__get8(s);
7058*4882a593Smuzhiyun       packet->size    = stbi__get8(s);
7059*4882a593Smuzhiyun       packet->type    = stbi__get8(s);
7060*4882a593Smuzhiyun       packet->channel = stbi__get8(s);
7061*4882a593Smuzhiyun       act_comp |= packet->channel;
7062*4882a593Smuzhiyun 
7063*4882a593Smuzhiyun       if (stbi__at_eof(s)) {
7064*4882a593Smuzhiyun           stbi__rewind( s );
7065*4882a593Smuzhiyun           return 0;
7066*4882a593Smuzhiyun       }
7067*4882a593Smuzhiyun       if (packet->size != 8) {
7068*4882a593Smuzhiyun           stbi__rewind( s );
7069*4882a593Smuzhiyun           return 0;
7070*4882a593Smuzhiyun       }
7071*4882a593Smuzhiyun    } while (chained);
7072*4882a593Smuzhiyun 
7073*4882a593Smuzhiyun    *comp = (act_comp & 0x10 ? 4 : 3);
7074*4882a593Smuzhiyun 
7075*4882a593Smuzhiyun    return 1;
7076*4882a593Smuzhiyun }
7077*4882a593Smuzhiyun #endif
7078*4882a593Smuzhiyun 
7079*4882a593Smuzhiyun // *************************************************************************************************
7080*4882a593Smuzhiyun // Portable Gray Map and Portable Pixel Map loader
7081*4882a593Smuzhiyun // by Ken Miller
7082*4882a593Smuzhiyun //
7083*4882a593Smuzhiyun // PGM: http://netpbm.sourceforge.net/doc/pgm.html
7084*4882a593Smuzhiyun // PPM: http://netpbm.sourceforge.net/doc/ppm.html
7085*4882a593Smuzhiyun //
7086*4882a593Smuzhiyun // Known limitations:
7087*4882a593Smuzhiyun //    Does not support comments in the header section
7088*4882a593Smuzhiyun //    Does not support ASCII image data (formats P2 and P3)
7089*4882a593Smuzhiyun //    Does not support 16-bit-per-channel
7090*4882a593Smuzhiyun 
7091*4882a593Smuzhiyun #ifndef STBI_NO_PNM
7092*4882a593Smuzhiyun 
stbi__pnm_test(stbi__context * s)7093*4882a593Smuzhiyun static int      stbi__pnm_test(stbi__context *s)
7094*4882a593Smuzhiyun {
7095*4882a593Smuzhiyun    char p, t;
7096*4882a593Smuzhiyun    p = (char) stbi__get8(s);
7097*4882a593Smuzhiyun    t = (char) stbi__get8(s);
7098*4882a593Smuzhiyun    if (p != 'P' || (t != '5' && t != '6')) {
7099*4882a593Smuzhiyun        stbi__rewind( s );
7100*4882a593Smuzhiyun        return 0;
7101*4882a593Smuzhiyun    }
7102*4882a593Smuzhiyun    return 1;
7103*4882a593Smuzhiyun }
7104*4882a593Smuzhiyun 
stbi__pnm_load(stbi__context * s,int * x,int * y,int * comp,int req_comp,stbi__result_info * ri)7105*4882a593Smuzhiyun static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
7106*4882a593Smuzhiyun {
7107*4882a593Smuzhiyun    stbi_uc *out;
7108*4882a593Smuzhiyun    STBI_NOTUSED(ri);
7109*4882a593Smuzhiyun 
7110*4882a593Smuzhiyun    if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
7111*4882a593Smuzhiyun       return 0;
7112*4882a593Smuzhiyun 
7113*4882a593Smuzhiyun    *x = s->img_x;
7114*4882a593Smuzhiyun    *y = s->img_y;
7115*4882a593Smuzhiyun    if (comp) *comp = s->img_n;
7116*4882a593Smuzhiyun 
7117*4882a593Smuzhiyun    if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
7118*4882a593Smuzhiyun       return stbi__errpuc("too large", "PNM too large");
7119*4882a593Smuzhiyun 
7120*4882a593Smuzhiyun    out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0);
7121*4882a593Smuzhiyun    if (!out) return stbi__errpuc("outofmem", "Out of memory");
7122*4882a593Smuzhiyun    stbi__getn(s, out, s->img_n * s->img_x * s->img_y);
7123*4882a593Smuzhiyun 
7124*4882a593Smuzhiyun    if (req_comp && req_comp != s->img_n) {
7125*4882a593Smuzhiyun       out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
7126*4882a593Smuzhiyun       if (out == NULL) return out; // stbi__convert_format frees input on failure
7127*4882a593Smuzhiyun    }
7128*4882a593Smuzhiyun    return out;
7129*4882a593Smuzhiyun }
7130*4882a593Smuzhiyun 
stbi__pnm_isspace(char c)7131*4882a593Smuzhiyun static int      stbi__pnm_isspace(char c)
7132*4882a593Smuzhiyun {
7133*4882a593Smuzhiyun    return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
7134*4882a593Smuzhiyun }
7135*4882a593Smuzhiyun 
stbi__pnm_skip_whitespace(stbi__context * s,char * c)7136*4882a593Smuzhiyun static void     stbi__pnm_skip_whitespace(stbi__context *s, char *c)
7137*4882a593Smuzhiyun {
7138*4882a593Smuzhiyun    for (;;) {
7139*4882a593Smuzhiyun       while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
7140*4882a593Smuzhiyun          *c = (char) stbi__get8(s);
7141*4882a593Smuzhiyun 
7142*4882a593Smuzhiyun       if (stbi__at_eof(s) || *c != '#')
7143*4882a593Smuzhiyun          break;
7144*4882a593Smuzhiyun 
7145*4882a593Smuzhiyun       while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' )
7146*4882a593Smuzhiyun          *c = (char) stbi__get8(s);
7147*4882a593Smuzhiyun    }
7148*4882a593Smuzhiyun }
7149*4882a593Smuzhiyun 
stbi__pnm_isdigit(char c)7150*4882a593Smuzhiyun static int      stbi__pnm_isdigit(char c)
7151*4882a593Smuzhiyun {
7152*4882a593Smuzhiyun    return c >= '0' && c <= '9';
7153*4882a593Smuzhiyun }
7154*4882a593Smuzhiyun 
stbi__pnm_getinteger(stbi__context * s,char * c)7155*4882a593Smuzhiyun static int      stbi__pnm_getinteger(stbi__context *s, char *c)
7156*4882a593Smuzhiyun {
7157*4882a593Smuzhiyun    int value = 0;
7158*4882a593Smuzhiyun 
7159*4882a593Smuzhiyun    while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
7160*4882a593Smuzhiyun       value = value*10 + (*c - '0');
7161*4882a593Smuzhiyun       *c = (char) stbi__get8(s);
7162*4882a593Smuzhiyun    }
7163*4882a593Smuzhiyun 
7164*4882a593Smuzhiyun    return value;
7165*4882a593Smuzhiyun }
7166*4882a593Smuzhiyun 
stbi__pnm_info(stbi__context * s,int * x,int * y,int * comp)7167*4882a593Smuzhiyun static int      stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
7168*4882a593Smuzhiyun {
7169*4882a593Smuzhiyun    int maxv, dummy;
7170*4882a593Smuzhiyun    char c, p, t;
7171*4882a593Smuzhiyun 
7172*4882a593Smuzhiyun    if (!x) x = &dummy;
7173*4882a593Smuzhiyun    if (!y) y = &dummy;
7174*4882a593Smuzhiyun    if (!comp) comp = &dummy;
7175*4882a593Smuzhiyun 
7176*4882a593Smuzhiyun    stbi__rewind(s);
7177*4882a593Smuzhiyun 
7178*4882a593Smuzhiyun    // Get identifier
7179*4882a593Smuzhiyun    p = (char) stbi__get8(s);
7180*4882a593Smuzhiyun    t = (char) stbi__get8(s);
7181*4882a593Smuzhiyun    if (p != 'P' || (t != '5' && t != '6')) {
7182*4882a593Smuzhiyun        stbi__rewind(s);
7183*4882a593Smuzhiyun        return 0;
7184*4882a593Smuzhiyun    }
7185*4882a593Smuzhiyun 
7186*4882a593Smuzhiyun    *comp = (t == '6') ? 3 : 1;  // '5' is 1-component .pgm; '6' is 3-component .ppm
7187*4882a593Smuzhiyun 
7188*4882a593Smuzhiyun    c = (char) stbi__get8(s);
7189*4882a593Smuzhiyun    stbi__pnm_skip_whitespace(s, &c);
7190*4882a593Smuzhiyun 
7191*4882a593Smuzhiyun    *x = stbi__pnm_getinteger(s, &c); // read width
7192*4882a593Smuzhiyun    stbi__pnm_skip_whitespace(s, &c);
7193*4882a593Smuzhiyun 
7194*4882a593Smuzhiyun    *y = stbi__pnm_getinteger(s, &c); // read height
7195*4882a593Smuzhiyun    stbi__pnm_skip_whitespace(s, &c);
7196*4882a593Smuzhiyun 
7197*4882a593Smuzhiyun    maxv = stbi__pnm_getinteger(s, &c);  // read max value
7198*4882a593Smuzhiyun 
7199*4882a593Smuzhiyun    if (maxv > 255)
7200*4882a593Smuzhiyun       return stbi__err("max value > 255", "PPM image not 8-bit");
7201*4882a593Smuzhiyun    else
7202*4882a593Smuzhiyun       return 1;
7203*4882a593Smuzhiyun }
7204*4882a593Smuzhiyun #endif
7205*4882a593Smuzhiyun 
stbi__info_main(stbi__context * s,int * x,int * y,int * comp)7206*4882a593Smuzhiyun static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
7207*4882a593Smuzhiyun {
7208*4882a593Smuzhiyun    #ifndef STBI_NO_JPEG
7209*4882a593Smuzhiyun    if (stbi__jpeg_info(s, x, y, comp)) return 1;
7210*4882a593Smuzhiyun    #endif
7211*4882a593Smuzhiyun 
7212*4882a593Smuzhiyun    #ifndef STBI_NO_PNG
7213*4882a593Smuzhiyun    if (stbi__png_info(s, x, y, comp))  return 1;
7214*4882a593Smuzhiyun    #endif
7215*4882a593Smuzhiyun 
7216*4882a593Smuzhiyun    #ifndef STBI_NO_GIF
7217*4882a593Smuzhiyun    if (stbi__gif_info(s, x, y, comp))  return 1;
7218*4882a593Smuzhiyun    #endif
7219*4882a593Smuzhiyun 
7220*4882a593Smuzhiyun    #ifndef STBI_NO_BMP
7221*4882a593Smuzhiyun    if (stbi__bmp_info(s, x, y, comp))  return 1;
7222*4882a593Smuzhiyun    #endif
7223*4882a593Smuzhiyun 
7224*4882a593Smuzhiyun    #ifndef STBI_NO_PSD
7225*4882a593Smuzhiyun    if (stbi__psd_info(s, x, y, comp))  return 1;
7226*4882a593Smuzhiyun    #endif
7227*4882a593Smuzhiyun 
7228*4882a593Smuzhiyun    #ifndef STBI_NO_PIC
7229*4882a593Smuzhiyun    if (stbi__pic_info(s, x, y, comp))  return 1;
7230*4882a593Smuzhiyun    #endif
7231*4882a593Smuzhiyun 
7232*4882a593Smuzhiyun    #ifndef STBI_NO_PNM
7233*4882a593Smuzhiyun    if (stbi__pnm_info(s, x, y, comp))  return 1;
7234*4882a593Smuzhiyun    #endif
7235*4882a593Smuzhiyun 
7236*4882a593Smuzhiyun    #ifndef STBI_NO_HDR
7237*4882a593Smuzhiyun    if (stbi__hdr_info(s, x, y, comp))  return 1;
7238*4882a593Smuzhiyun    #endif
7239*4882a593Smuzhiyun 
7240*4882a593Smuzhiyun    // test tga last because it's a crappy test!
7241*4882a593Smuzhiyun    #ifndef STBI_NO_TGA
7242*4882a593Smuzhiyun    if (stbi__tga_info(s, x, y, comp))
7243*4882a593Smuzhiyun        return 1;
7244*4882a593Smuzhiyun    #endif
7245*4882a593Smuzhiyun    return stbi__err("unknown image type", "Image not of any known type, or corrupt");
7246*4882a593Smuzhiyun }
7247*4882a593Smuzhiyun 
stbi__is_16_main(stbi__context * s)7248*4882a593Smuzhiyun static int stbi__is_16_main(stbi__context *s)
7249*4882a593Smuzhiyun {
7250*4882a593Smuzhiyun    #ifndef STBI_NO_PNG
7251*4882a593Smuzhiyun    if (stbi__png_is16(s))  return 1;
7252*4882a593Smuzhiyun    #endif
7253*4882a593Smuzhiyun 
7254*4882a593Smuzhiyun    #ifndef STBI_NO_PSD
7255*4882a593Smuzhiyun    if (stbi__psd_is16(s))  return 1;
7256*4882a593Smuzhiyun    #endif
7257*4882a593Smuzhiyun 
7258*4882a593Smuzhiyun    return 0;
7259*4882a593Smuzhiyun }
7260*4882a593Smuzhiyun 
7261*4882a593Smuzhiyun #ifndef STBI_NO_STDIO
stbi_info(char const * filename,int * x,int * y,int * comp)7262*4882a593Smuzhiyun STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp)
7263*4882a593Smuzhiyun {
7264*4882a593Smuzhiyun     FILE *f = stbi__fopen(filename, "rb");
7265*4882a593Smuzhiyun     int result;
7266*4882a593Smuzhiyun     if (!f) return stbi__err("can't fopen", "Unable to open file");
7267*4882a593Smuzhiyun     result = stbi_info_from_file(f, x, y, comp);
7268*4882a593Smuzhiyun     fclose(f);
7269*4882a593Smuzhiyun     return result;
7270*4882a593Smuzhiyun }
7271*4882a593Smuzhiyun 
stbi_info_from_file(FILE * f,int * x,int * y,int * comp)7272*4882a593Smuzhiyun STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
7273*4882a593Smuzhiyun {
7274*4882a593Smuzhiyun    int r;
7275*4882a593Smuzhiyun    stbi__context s;
7276*4882a593Smuzhiyun    long pos = ftell(f);
7277*4882a593Smuzhiyun    stbi__start_file(&s, f);
7278*4882a593Smuzhiyun    r = stbi__info_main(&s,x,y,comp);
7279*4882a593Smuzhiyun    fseek(f,pos,SEEK_SET);
7280*4882a593Smuzhiyun    return r;
7281*4882a593Smuzhiyun }
7282*4882a593Smuzhiyun 
stbi_is_16_bit(char const * filename)7283*4882a593Smuzhiyun STBIDEF int stbi_is_16_bit(char const *filename)
7284*4882a593Smuzhiyun {
7285*4882a593Smuzhiyun     FILE *f = stbi__fopen(filename, "rb");
7286*4882a593Smuzhiyun     int result;
7287*4882a593Smuzhiyun     if (!f) return stbi__err("can't fopen", "Unable to open file");
7288*4882a593Smuzhiyun     result = stbi_is_16_bit_from_file(f);
7289*4882a593Smuzhiyun     fclose(f);
7290*4882a593Smuzhiyun     return result;
7291*4882a593Smuzhiyun }
7292*4882a593Smuzhiyun 
stbi_is_16_bit_from_file(FILE * f)7293*4882a593Smuzhiyun STBIDEF int stbi_is_16_bit_from_file(FILE *f)
7294*4882a593Smuzhiyun {
7295*4882a593Smuzhiyun    int r;
7296*4882a593Smuzhiyun    stbi__context s;
7297*4882a593Smuzhiyun    long pos = ftell(f);
7298*4882a593Smuzhiyun    stbi__start_file(&s, f);
7299*4882a593Smuzhiyun    r = stbi__is_16_main(&s);
7300*4882a593Smuzhiyun    fseek(f,pos,SEEK_SET);
7301*4882a593Smuzhiyun    return r;
7302*4882a593Smuzhiyun }
7303*4882a593Smuzhiyun #endif // !STBI_NO_STDIO
7304*4882a593Smuzhiyun 
stbi_info_from_memory(stbi_uc const * buffer,int len,int * x,int * y,int * comp)7305*4882a593Smuzhiyun STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp)
7306*4882a593Smuzhiyun {
7307*4882a593Smuzhiyun    stbi__context s;
7308*4882a593Smuzhiyun    stbi__start_mem(&s,buffer,len);
7309*4882a593Smuzhiyun    return stbi__info_main(&s,x,y,comp);
7310*4882a593Smuzhiyun }
7311*4882a593Smuzhiyun 
stbi_info_from_callbacks(stbi_io_callbacks const * c,void * user,int * x,int * y,int * comp)7312*4882a593Smuzhiyun STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp)
7313*4882a593Smuzhiyun {
7314*4882a593Smuzhiyun    stbi__context s;
7315*4882a593Smuzhiyun    stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
7316*4882a593Smuzhiyun    return stbi__info_main(&s,x,y,comp);
7317*4882a593Smuzhiyun }
7318*4882a593Smuzhiyun 
stbi_is_16_bit_from_memory(stbi_uc const * buffer,int len)7319*4882a593Smuzhiyun STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len)
7320*4882a593Smuzhiyun {
7321*4882a593Smuzhiyun    stbi__context s;
7322*4882a593Smuzhiyun    stbi__start_mem(&s,buffer,len);
7323*4882a593Smuzhiyun    return stbi__is_16_main(&s);
7324*4882a593Smuzhiyun }
7325*4882a593Smuzhiyun 
stbi_is_16_bit_from_callbacks(stbi_io_callbacks const * c,void * user)7326*4882a593Smuzhiyun STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user)
7327*4882a593Smuzhiyun {
7328*4882a593Smuzhiyun    stbi__context s;
7329*4882a593Smuzhiyun    stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
7330*4882a593Smuzhiyun    return stbi__is_16_main(&s);
7331*4882a593Smuzhiyun }
7332*4882a593Smuzhiyun 
7333*4882a593Smuzhiyun #endif // STB_IMAGE_IMPLEMENTATION
7334*4882a593Smuzhiyun 
7335*4882a593Smuzhiyun /*
7336*4882a593Smuzhiyun    revision history:
7337*4882a593Smuzhiyun       2.20  (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
7338*4882a593Smuzhiyun       2.19  (2018-02-11) fix warning
7339*4882a593Smuzhiyun       2.18  (2018-01-30) fix warnings
7340*4882a593Smuzhiyun       2.17  (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
7341*4882a593Smuzhiyun                          1-bit BMP
7342*4882a593Smuzhiyun                          *_is_16_bit api
7343*4882a593Smuzhiyun                          avoid warnings
7344*4882a593Smuzhiyun       2.16  (2017-07-23) all functions have 16-bit variants;
7345*4882a593Smuzhiyun                          STBI_NO_STDIO works again;
7346*4882a593Smuzhiyun                          compilation fixes;
7347*4882a593Smuzhiyun                          fix rounding in unpremultiply;
7348*4882a593Smuzhiyun                          optimize vertical flip;
7349*4882a593Smuzhiyun                          disable raw_len validation;
7350*4882a593Smuzhiyun                          documentation fixes
7351*4882a593Smuzhiyun       2.15  (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
7352*4882a593Smuzhiyun                          warning fixes; disable run-time SSE detection on gcc;
7353*4882a593Smuzhiyun                          uniform handling of optional "return" values;
7354*4882a593Smuzhiyun                          thread-safe initialization of zlib tables
7355*4882a593Smuzhiyun       2.14  (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
7356*4882a593Smuzhiyun       2.13  (2016-11-29) add 16-bit API, only supported for PNG right now
7357*4882a593Smuzhiyun       2.12  (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
7358*4882a593Smuzhiyun       2.11  (2016-04-02) allocate large structures on the stack
7359*4882a593Smuzhiyun                          remove white matting for transparent PSD
7360*4882a593Smuzhiyun                          fix reported channel count for PNG & BMP
7361*4882a593Smuzhiyun                          re-enable SSE2 in non-gcc 64-bit
7362*4882a593Smuzhiyun                          support RGB-formatted JPEG
7363*4882a593Smuzhiyun                          read 16-bit PNGs (only as 8-bit)
7364*4882a593Smuzhiyun       2.10  (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
7365*4882a593Smuzhiyun       2.09  (2016-01-16) allow comments in PNM files
7366*4882a593Smuzhiyun                          16-bit-per-pixel TGA (not bit-per-component)
7367*4882a593Smuzhiyun                          info() for TGA could break due to .hdr handling
7368*4882a593Smuzhiyun                          info() for BMP to shares code instead of sloppy parse
7369*4882a593Smuzhiyun                          can use STBI_REALLOC_SIZED if allocator doesn't support realloc
7370*4882a593Smuzhiyun                          code cleanup
7371*4882a593Smuzhiyun       2.08  (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
7372*4882a593Smuzhiyun       2.07  (2015-09-13) fix compiler warnings
7373*4882a593Smuzhiyun                          partial animated GIF support
7374*4882a593Smuzhiyun                          limited 16-bpc PSD support
7375*4882a593Smuzhiyun                          #ifdef unused functions
7376*4882a593Smuzhiyun                          bug with < 92 byte PIC,PNM,HDR,TGA
7377*4882a593Smuzhiyun       2.06  (2015-04-19) fix bug where PSD returns wrong '*comp' value
7378*4882a593Smuzhiyun       2.05  (2015-04-19) fix bug in progressive JPEG handling, fix warning
7379*4882a593Smuzhiyun       2.04  (2015-04-15) try to re-enable SIMD on MinGW 64-bit
7380*4882a593Smuzhiyun       2.03  (2015-04-12) extra corruption checking (mmozeiko)
7381*4882a593Smuzhiyun                          stbi_set_flip_vertically_on_load (nguillemot)
7382*4882a593Smuzhiyun                          fix NEON support; fix mingw support
7383*4882a593Smuzhiyun       2.02  (2015-01-19) fix incorrect assert, fix warning
7384*4882a593Smuzhiyun       2.01  (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2
7385*4882a593Smuzhiyun       2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
7386*4882a593Smuzhiyun       2.00  (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg)
7387*4882a593Smuzhiyun                          progressive JPEG (stb)
7388*4882a593Smuzhiyun                          PGM/PPM support (Ken Miller)
7389*4882a593Smuzhiyun                          STBI_MALLOC,STBI_REALLOC,STBI_FREE
7390*4882a593Smuzhiyun                          GIF bugfix -- seemingly never worked
7391*4882a593Smuzhiyun                          STBI_NO_*, STBI_ONLY_*
7392*4882a593Smuzhiyun       1.48  (2014-12-14) fix incorrectly-named assert()
7393*4882a593Smuzhiyun       1.47  (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb)
7394*4882a593Smuzhiyun                          optimize PNG (ryg)
7395*4882a593Smuzhiyun                          fix bug in interlaced PNG with user-specified channel count (stb)
7396*4882a593Smuzhiyun       1.46  (2014-08-26)
7397*4882a593Smuzhiyun               fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG
7398*4882a593Smuzhiyun       1.45  (2014-08-16)
7399*4882a593Smuzhiyun               fix MSVC-ARM internal compiler error by wrapping malloc
7400*4882a593Smuzhiyun       1.44  (2014-08-07)
7401*4882a593Smuzhiyun               various warning fixes from Ronny Chevalier
7402*4882a593Smuzhiyun       1.43  (2014-07-15)
7403*4882a593Smuzhiyun               fix MSVC-only compiler problem in code changed in 1.42
7404*4882a593Smuzhiyun       1.42  (2014-07-09)
7405*4882a593Smuzhiyun               don't define _CRT_SECURE_NO_WARNINGS (affects user code)
7406*4882a593Smuzhiyun               fixes to stbi__cleanup_jpeg path
7407*4882a593Smuzhiyun               added STBI_ASSERT to avoid requiring assert.h
7408*4882a593Smuzhiyun       1.41  (2014-06-25)
7409*4882a593Smuzhiyun               fix search&replace from 1.36 that messed up comments/error messages
7410*4882a593Smuzhiyun       1.40  (2014-06-22)
7411*4882a593Smuzhiyun               fix gcc struct-initialization warning
7412*4882a593Smuzhiyun       1.39  (2014-06-15)
7413*4882a593Smuzhiyun               fix to TGA optimization when req_comp != number of components in TGA;
7414*4882a593Smuzhiyun               fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite)
7415*4882a593Smuzhiyun               add support for BMP version 5 (more ignored fields)
7416*4882a593Smuzhiyun       1.38  (2014-06-06)
7417*4882a593Smuzhiyun               suppress MSVC warnings on integer casts truncating values
7418*4882a593Smuzhiyun               fix accidental rename of 'skip' field of I/O
7419*4882a593Smuzhiyun       1.37  (2014-06-04)
7420*4882a593Smuzhiyun               remove duplicate typedef
7421*4882a593Smuzhiyun       1.36  (2014-06-03)
7422*4882a593Smuzhiyun               convert to header file single-file library
7423*4882a593Smuzhiyun               if de-iphone isn't set, load iphone images color-swapped instead of returning NULL
7424*4882a593Smuzhiyun       1.35  (2014-05-27)
7425*4882a593Smuzhiyun               various warnings
7426*4882a593Smuzhiyun               fix broken STBI_SIMD path
7427*4882a593Smuzhiyun               fix bug where stbi_load_from_file no longer left file pointer in correct place
7428*4882a593Smuzhiyun               fix broken non-easy path for 32-bit BMP (possibly never used)
7429*4882a593Smuzhiyun               TGA optimization by Arseny Kapoulkine
7430*4882a593Smuzhiyun       1.34  (unknown)
7431*4882a593Smuzhiyun               use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case
7432*4882a593Smuzhiyun       1.33  (2011-07-14)
7433*4882a593Smuzhiyun               make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements
7434*4882a593Smuzhiyun       1.32  (2011-07-13)
7435*4882a593Smuzhiyun               support for "info" function for all supported filetypes (SpartanJ)
7436*4882a593Smuzhiyun       1.31  (2011-06-20)
7437*4882a593Smuzhiyun               a few more leak fixes, bug in PNG handling (SpartanJ)
7438*4882a593Smuzhiyun       1.30  (2011-06-11)
7439*4882a593Smuzhiyun               added ability to load files via callbacks to accomidate custom input streams (Ben Wenger)
7440*4882a593Smuzhiyun               removed deprecated format-specific test/load functions
7441*4882a593Smuzhiyun               removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway
7442*4882a593Smuzhiyun               error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha)
7443*4882a593Smuzhiyun               fix inefficiency in decoding 32-bit BMP (David Woo)
7444*4882a593Smuzhiyun       1.29  (2010-08-16)
7445*4882a593Smuzhiyun               various warning fixes from Aurelien Pocheville
7446*4882a593Smuzhiyun       1.28  (2010-08-01)
7447*4882a593Smuzhiyun               fix bug in GIF palette transparency (SpartanJ)
7448*4882a593Smuzhiyun       1.27  (2010-08-01)
7449*4882a593Smuzhiyun               cast-to-stbi_uc to fix warnings
7450*4882a593Smuzhiyun       1.26  (2010-07-24)
7451*4882a593Smuzhiyun               fix bug in file buffering for PNG reported by SpartanJ
7452*4882a593Smuzhiyun       1.25  (2010-07-17)
7453*4882a593Smuzhiyun               refix trans_data warning (Won Chun)
7454*4882a593Smuzhiyun       1.24  (2010-07-12)
7455*4882a593Smuzhiyun               perf improvements reading from files on platforms with lock-heavy fgetc()
7456*4882a593Smuzhiyun               minor perf improvements for jpeg
7457*4882a593Smuzhiyun               deprecated type-specific functions so we'll get feedback if they're needed
7458*4882a593Smuzhiyun               attempt to fix trans_data warning (Won Chun)
7459*4882a593Smuzhiyun       1.23    fixed bug in iPhone support
7460*4882a593Smuzhiyun       1.22  (2010-07-10)
7461*4882a593Smuzhiyun               removed image *writing* support
7462*4882a593Smuzhiyun               stbi_info support from Jetro Lauha
7463*4882a593Smuzhiyun               GIF support from Jean-Marc Lienher
7464*4882a593Smuzhiyun               iPhone PNG-extensions from James Brown
7465*4882a593Smuzhiyun               warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva)
7466*4882a593Smuzhiyun       1.21    fix use of 'stbi_uc' in header (reported by jon blow)
7467*4882a593Smuzhiyun       1.20    added support for Softimage PIC, by Tom Seddon
7468*4882a593Smuzhiyun       1.19    bug in interlaced PNG corruption check (found by ryg)
7469*4882a593Smuzhiyun       1.18  (2008-08-02)
7470*4882a593Smuzhiyun               fix a threading bug (local mutable static)
7471*4882a593Smuzhiyun       1.17    support interlaced PNG
7472*4882a593Smuzhiyun       1.16    major bugfix - stbi__convert_format converted one too many pixels
7473*4882a593Smuzhiyun       1.15    initialize some fields for thread safety
7474*4882a593Smuzhiyun       1.14    fix threadsafe conversion bug
7475*4882a593Smuzhiyun               header-file-only version (#define STBI_HEADER_FILE_ONLY before including)
7476*4882a593Smuzhiyun       1.13    threadsafe
7477*4882a593Smuzhiyun       1.12    const qualifiers in the API
7478*4882a593Smuzhiyun       1.11    Support installable IDCT, colorspace conversion routines
7479*4882a593Smuzhiyun       1.10    Fixes for 64-bit (don't use "unsigned long")
7480*4882a593Smuzhiyun               optimized upsampling by Fabian "ryg" Giesen
7481*4882a593Smuzhiyun       1.09    Fix format-conversion for PSD code (bad global variables!)
7482*4882a593Smuzhiyun       1.08    Thatcher Ulrich's PSD code integrated by Nicolas Schulz
7483*4882a593Smuzhiyun       1.07    attempt to fix C++ warning/errors again
7484*4882a593Smuzhiyun       1.06    attempt to fix C++ warning/errors again
7485*4882a593Smuzhiyun       1.05    fix TGA loading to return correct *comp and use good luminance calc
7486*4882a593Smuzhiyun       1.04    default float alpha is 1, not 255; use 'void *' for stbi_image_free
7487*4882a593Smuzhiyun       1.03    bugfixes to STBI_NO_STDIO, STBI_NO_HDR
7488*4882a593Smuzhiyun       1.02    support for (subset of) HDR files, float interface for preferred access to them
7489*4882a593Smuzhiyun       1.01    fix bug: possible bug in handling right-side up bmps... not sure
7490*4882a593Smuzhiyun               fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all
7491*4882a593Smuzhiyun       1.00    interface to zlib that skips zlib header
7492*4882a593Smuzhiyun       0.99    correct handling of alpha in palette
7493*4882a593Smuzhiyun       0.98    TGA loader by lonesock; dynamically add loaders (untested)
7494*4882a593Smuzhiyun       0.97    jpeg errors on too large a file; also catch another malloc failure
7495*4882a593Smuzhiyun       0.96    fix detection of invalid v value - particleman@mollyrocket forum
7496*4882a593Smuzhiyun       0.95    during header scan, seek to markers in case of padding
7497*4882a593Smuzhiyun       0.94    STBI_NO_STDIO to disable stdio usage; rename all #defines the same
7498*4882a593Smuzhiyun       0.93    handle jpegtran output; verbose errors
7499*4882a593Smuzhiyun       0.92    read 4,8,16,24,32-bit BMP files of several formats
7500*4882a593Smuzhiyun       0.91    output 24-bit Windows 3.0 BMP files
7501*4882a593Smuzhiyun       0.90    fix a few more warnings; bump version number to approach 1.0
7502*4882a593Smuzhiyun       0.61    bugfixes due to Marc LeBlanc, Christopher Lloyd
7503*4882a593Smuzhiyun       0.60    fix compiling as c++
7504*4882a593Smuzhiyun       0.59    fix warnings: merge Dave Moore's -Wall fixes
7505*4882a593Smuzhiyun       0.58    fix bug: zlib uncompressed mode len/nlen was wrong endian
7506*4882a593Smuzhiyun       0.57    fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available
7507*4882a593Smuzhiyun       0.56    fix bug: zlib uncompressed mode len vs. nlen
7508*4882a593Smuzhiyun       0.55    fix bug: restart_interval not initialized to 0
7509*4882a593Smuzhiyun       0.54    allow NULL for 'int *comp'
7510*4882a593Smuzhiyun       0.53    fix bug in png 3->4; speedup png decoding
7511*4882a593Smuzhiyun       0.52    png handles req_comp=3,4 directly; minor cleanup; jpeg comments
7512*4882a593Smuzhiyun       0.51    obey req_comp requests, 1-component jpegs return as 1-component,
7513*4882a593Smuzhiyun               on 'test' only check type, not whether we support this variant
7514*4882a593Smuzhiyun       0.50  (2006-11-19)
7515*4882a593Smuzhiyun               first released version
7516*4882a593Smuzhiyun */
7517*4882a593Smuzhiyun 
7518*4882a593Smuzhiyun 
7519*4882a593Smuzhiyun /*
7520*4882a593Smuzhiyun ------------------------------------------------------------------------------
7521*4882a593Smuzhiyun This software is available under 2 licenses -- choose whichever you prefer.
7522*4882a593Smuzhiyun ------------------------------------------------------------------------------
7523*4882a593Smuzhiyun ALTERNATIVE A - MIT License
7524*4882a593Smuzhiyun Copyright (c) 2017 Sean Barrett
7525*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a copy of
7526*4882a593Smuzhiyun this software and associated documentation files (the "Software"), to deal in
7527*4882a593Smuzhiyun the Software without restriction, including without limitation the rights to
7528*4882a593Smuzhiyun use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7529*4882a593Smuzhiyun of the Software, and to permit persons to whom the Software is furnished to do
7530*4882a593Smuzhiyun so, subject to the following conditions:
7531*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in all
7532*4882a593Smuzhiyun copies or substantial portions of the Software.
7533*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7534*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7535*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7536*4882a593Smuzhiyun AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7537*4882a593Smuzhiyun LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7538*4882a593Smuzhiyun OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
7539*4882a593Smuzhiyun SOFTWARE.
7540*4882a593Smuzhiyun ------------------------------------------------------------------------------
7541*4882a593Smuzhiyun ALTERNATIVE B - Public Domain (www.unlicense.org)
7542*4882a593Smuzhiyun This is free and unencumbered software released into the public domain.
7543*4882a593Smuzhiyun Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
7544*4882a593Smuzhiyun software, either in source code form or as a compiled binary, for any purpose,
7545*4882a593Smuzhiyun commercial or non-commercial, and by any means.
7546*4882a593Smuzhiyun In jurisdictions that recognize copyright laws, the author or authors of this
7547*4882a593Smuzhiyun software dedicate any and all copyright interest in the software to the public
7548*4882a593Smuzhiyun domain. We make this dedication for the benefit of the public at large and to
7549*4882a593Smuzhiyun the detriment of our heirs and successors. We intend this dedication to be an
7550*4882a593Smuzhiyun overt act of relinquishment in perpetuity of all present and future rights to
7551*4882a593Smuzhiyun this software under copyright law.
7552*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7553*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7554*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7555*4882a593Smuzhiyun AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
7556*4882a593Smuzhiyun ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
7557*4882a593Smuzhiyun WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7558*4882a593Smuzhiyun ------------------------------------------------------------------------------
7559*4882a593Smuzhiyun */
7560