annotate stb_image.c @ 96:6bf5220fa47e

Urgh .. use memset to silence some bogus GCC warnings about using potentially uninitialized values, while that will not actually be possible. In any case, it is annoying.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 02 Oct 2012 18:52:28 +0300
parents b0f1b8544b62
children 43c985265fd5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1 /* stbi-1.33 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2 when you control the images you're loading
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3 no warranty implied; use at your own risk
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
5 QUICK NOTES:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
6 Primarily of interest to game developers and other people who can
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
7 avoid problematic images and only need the trivial interface
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
8
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
9 JPEG baseline (no JPEG progressive)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
10 PNG 8-bit only
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
11
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
12 TGA (not sure what subset, if a subset)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
13 BMP non-1bpp, non-RLE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
14 PSD (composited view only, no extra channels)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
15
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
16 GIF (*comp always reports as 4-channel)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
17 HDR (radiance rgbE format)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
18 PIC (Softimage PIC)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
19
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
20 - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
21 - decode from arbitrary I/O callbacks
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
22 - overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
23
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
24 Latest revisions:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
25 1.33 (2011-07-14) minor fixes suggested by Dave Moore
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
26 1.32 (2011-07-13) info support for all filetypes (SpartanJ)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
27 1.31 (2011-06-19) a few more leak fixes, bug in PNG handling (SpartanJ)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
28 1.30 (2011-06-11) added ability to load files via io callbacks (Ben Wenger)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
29 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
30 1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
31 1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
32 allow trailing 0s at end of image data (Laurent Gomila)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
33 1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
34
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
35 See end of file for full revision history.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
36
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
37 TODO:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
38 stbi_info support for BMP,PSD,HDR,PIC
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
39
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
40
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
41 ============================ Contributors =========================
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
42
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
43 Image formats Optimizations & bugfixes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
44 Sean Barrett (jpeg, png, bmp) Fabian "ryg" Giesen
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
45 Nicolas Schulz (hdr, psd)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
46 Jonathan Dummer (tga) Bug fixes & warning fixes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
47 Jean-Marc Lienher (gif) Marc LeBlanc
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
48 Tom Seddon (pic) Christpher Lloyd
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
49 Thatcher Ulrich (psd) Dave Moore
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
50 Won Chun
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
51 the Horde3D community
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
52 Extensions, features Janez Zemva
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
53 Jetro Lauha (stbi_info) Jonathan Blow
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
54 James "moose2000" Brown (iPhone PNG) Laurent Gomila
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
55 Ben "Disch" Wenger (io callbacks) Aruelien Pocheville
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
56 Martin "SpartanJ" Golini Ryamond Barbiero
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
57 David Woo
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
58
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
59
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
60 If your name should be here but isn't, let Sean know.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
61
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
62 */
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
63
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
64 #ifndef STBI_INCLUDE_STB_IMAGE_H
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
65 #define STBI_INCLUDE_STB_IMAGE_H
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
66
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
67 // To get a header file for this, either cut and paste the header,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
68 // or create stb_image.h, #define STBI_HEADER_FILE_ONLY, and
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
69 // then include stb_image.c from it.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
70
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
71 //// begin header file ////////////////////////////////////////////////////
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
72 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
73 // Limitations:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
74 // - no jpeg progressive support
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
75 // - non-HDR formats support 8-bit samples only (jpeg, png)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
76 // - no delayed line count (jpeg) -- IJG doesn't support either
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
77 // - no 1-bit BMP
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
78 // - GIF always returns *comp=4
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
79 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
80 // Basic usage (see HDR discussion below):
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
81 // int x,y,n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
82 // unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
83 // // ... process data if not NULL ...
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
84 // // ... x = width, y = height, n = # 8-bit components per pixel ...
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
85 // // ... replace '0' with '1'..'4' to force that many components per pixel
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
86 // // ... but 'n' will always be the number that it would have been if you said 0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
87 // stbi_image_free(data)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
88 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
89 // Standard parameters:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
90 // int *x -- outputs image width in pixels
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
91 // int *y -- outputs image height in pixels
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
92 // int *comp -- outputs # of image components in image file
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
93 // int req_comp -- if non-zero, # of image components requested in result
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
94 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
95 // The return value from an image loader is an 'unsigned char *' which points
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
96 // to the pixel data. The pixel data consists of *y scanlines of *x pixels,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
97 // with each pixel consisting of N interleaved 8-bit components; the first
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
98 // pixel pointed to is top-left-most in the image. There is no padding between
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
99 // image scanlines or between pixels, regardless of format. The number of
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
100 // components N is 'req_comp' if req_comp is non-zero, or *comp otherwise.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
101 // If req_comp is non-zero, *comp has the number of components that _would_
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
102 // have been output otherwise. E.g. if you set req_comp to 4, you will always
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
103 // get RGBA output, but you can check *comp to easily see if it's opaque.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
104 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
105 // An output image with N components has the following components interleaved
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
106 // in this order in each pixel:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
107 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
108 // N=#comp components
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
109 // 1 grey
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
110 // 2 grey, alpha
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
111 // 3 red, green, blue
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
112 // 4 red, green, blue, alpha
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
113 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
114 // If image loading fails for any reason, the return value will be NULL,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
115 // and *x, *y, *comp will be unchanged. The function stbi_failure_reason()
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
116 // can be queried for an extremely brief, end-user unfriendly explanation
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
117 // of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
118 // compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
119 // more user-friendly ones.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
120 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
121 // Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
122 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
123 // ===========================================================================
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
124 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
125 // iPhone PNG support:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
126 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
127 // By default we convert iphone-formatted PNGs back to RGB; nominally they
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
128 // would silently load as BGR, except the existing code should have just
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
129 // failed on such iPhone PNGs. But you can disable this conversion by
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
130 // by calling stbi_convert_iphone_png_to_rgb(0), in which case
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
131 // you will always just get the native iphone "format" through.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
132 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
133 // Call stbi_set_unpremultiply_on_load(1) as well to force a divide per
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
134 // pixel to remove any premultiplied alpha *only* if the image file explicitly
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
135 // says there's premultiplied data (currently only happens in iPhone images,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
136 // and only if iPhone convert-to-rgb processing is on).
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
137 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
138 // ===========================================================================
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
139 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
140 // HDR image support (disable by defining STBI_NO_HDR)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
141 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
142 // stb_image now supports loading HDR images in general, and currently
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
143 // the Radiance .HDR file format, although the support is provided
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
144 // generically. You can still load any file through the existing interface;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
145 // if you attempt to load an HDR file, it will be automatically remapped to
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
146 // LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
147 // both of these constants can be reconfigured through this interface:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
148 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
149 // stbi_hdr_to_ldr_gamma(2.2f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
150 // stbi_hdr_to_ldr_scale(1.0f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
151 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
152 // (note, do not use _inverse_ constants; stbi_image will invert them
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
153 // appropriately).
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
154 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
155 // Additionally, there is a new, parallel interface for loading files as
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
156 // (linear) floats to preserve the full dynamic range:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
157 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
158 // float *data = stbi_loadf(filename, &x, &y, &n, 0);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
159 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
160 // If you load LDR images through this interface, those images will
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
161 // be promoted to floating point values, run through the inverse of
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
162 // constants corresponding to the above:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
163 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
164 // stbi_ldr_to_hdr_scale(1.0f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
165 // stbi_ldr_to_hdr_gamma(2.2f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
166 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
167 // Finally, given a filename (or an open file or memory block--see header
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
168 // file for details) containing image data, you can query for the "most
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
169 // appropriate" interface to use (that is, whether the image is HDR or
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
170 // not), using:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
171 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
172 // stbi_is_hdr(char *filename);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
173 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
174 // ===========================================================================
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
175 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
176 // I/O callbacks
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
177 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
178 // I/O callbacks allow you to read from arbitrary sources, like packaged
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
179 // files or some other source. Data read from callbacks are processed
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
180 // through a small internal buffer (currently 128 bytes) to try to reduce
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
181 // overhead.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
182 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
183 // The three functions you must define are "read" (reads some bytes of data),
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
184 // "skip" (skips some bytes of data), "eof" (reports if the stream is at the end).
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
185
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
186
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
187 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
188
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
189 #if defined(_MSC_VER) && _MSC_VER >= 0x1400
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
190 #define _CRT_SECURE_NO_WARNINGS // suppress bogus warnings about fopen()
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
191 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
192
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
193 #include <stdio.h>
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
194 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
195
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
196 #define STBI_VERSION 1
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
197
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
198 enum
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
199 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
200 STBI_default = 0, // only used for req_comp
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
201
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
202 STBI_grey = 1,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
203 STBI_grey_alpha = 2,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
204 STBI_rgb = 3,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
205 STBI_rgb_alpha = 4
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
206 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
207
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
208 typedef unsigned char stbi_uc;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
209
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
210 #ifdef __cplusplus
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
211 extern "C" {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
212 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
213
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
214 //////////////////////////////////////////////////////////////////////////////
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
215 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
216 // PRIMARY API - works on images of any type
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
217 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
218
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
219 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
220 // load image by filename, open file, or memory buffer
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
221 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
222
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
223 extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
224
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
225 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
226 extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
227 extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
228 // for stbi_load_from_file, file pointer is left pointing immediately after image
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
229 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
230
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
231 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
232 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
233 int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
234 void (*skip) (void *user,unsigned n); // skip the next 'n' bytes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
235 int (*eof) (void *user); // returns nonzero if we are at end of file/data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
236 } stbi_io_callbacks;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
237
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
238 extern stbi_uc *stbi_load_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
239
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
240 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
241 extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
242
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
243 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
244 extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
245 extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
246 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
247
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
248 extern float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
249
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
250 extern void stbi_hdr_to_ldr_gamma(float gamma);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
251 extern void stbi_hdr_to_ldr_scale(float scale);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
252
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
253 extern void stbi_ldr_to_hdr_gamma(float gamma);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
254 extern void stbi_ldr_to_hdr_scale(float scale);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
255 #endif // STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
256
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
257 // stbi_is_hdr is always defined
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
258 extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
259 extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
260 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
261 extern int stbi_is_hdr (char const *filename);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
262 extern int stbi_is_hdr_from_file(FILE *f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
263 #endif // STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
264
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
265
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
266 // get a VERY brief reason for failure
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
267 // NOT THREADSAFE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
268 extern const char *stbi_failure_reason (void);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
269
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
270 // free the loaded image -- this is just free()
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
271 extern void stbi_image_free (void *retval_from_stbi_load);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
272
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
273 // get image dimensions & components without fully decoding
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
274 extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
275 extern int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
276
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
277 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
278 extern int stbi_info (char const *filename, int *x, int *y, int *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
279 extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
280
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
281 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
282
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
283
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
284
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
285 // for image formats that explicitly notate that they have premultiplied alpha,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
286 // we just return the colors as stored in the file. set this flag to force
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
287 // unpremultiplication. results are undefined if the unpremultiply overflow.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
288 extern void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
289
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
290 // indicate whether we should process iphone images back to canonical format,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
291 // or just pass them through "as-is"
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
292 extern void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
293
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
294
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
295 // ZLIB client - used by PNG, available for other purposes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
296
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
297 extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
298 extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
299 extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
300
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
301 extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
302 extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
303
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
304
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
305 // define faster low-level operations (typically SIMD support)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
306 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
307 typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
308 // compute an integer IDCT on "input"
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
309 // input[x] = data[x] * dequantize[x]
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
310 // write results to 'out': 64 samples, each run of 8 spaced by 'out_stride'
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
311 // CLAMP results to 0..255
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
312 typedef void (*stbi_YCbCr_to_RGB_run)(stbi_uc *output, stbi_uc const *y, stbi_uc const *cb, stbi_uc const *cr, int count, int step);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
313 // compute a conversion from YCbCr to RGB
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
314 // 'count' pixels
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
315 // write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
316 // y: Y input channel
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
317 // cb: Cb input channel; scale/biased to be 0..255
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
318 // cr: Cr input channel; scale/biased to be 0..255
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
319
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
320 extern void stbi_install_idct(stbi_idct_8x8 func);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
321 extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
322 #endif // STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
323
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
324
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
325 #ifdef __cplusplus
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
326 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
327 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
328
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
329 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
330 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
331 //// end header file /////////////////////////////////////////////////////
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
332 #endif // STBI_INCLUDE_STB_IMAGE_H
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
333
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
334 #ifndef STBI_HEADER_FILE_ONLY
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
335
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
336 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
337 #include <math.h> // ldexp
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
338 #include <string.h> // strcmp, strtok
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
339 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
340
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
341 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
342 #include <stdio.h>
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
343 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
344 #include <stdlib.h>
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
345 #include <memory.h>
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
346 #include <assert.h>
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
347 #include <stdarg.h>
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
348
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
349 #ifndef _MSC_VER
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
350 #ifdef __cplusplus
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
351 #define stbi_inline inline
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
352 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
353 #define stbi_inline
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
354 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
355 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
356 #define stbi_inline __forceinline
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
357 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
358
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
359
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
360 // implementation:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
361 typedef unsigned char uint8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
362 typedef unsigned short uint16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
363 typedef signed short int16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
364 typedef unsigned int uint32;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
365 typedef signed int int32;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
366 typedef unsigned int uint;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
367
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
368 // should produce compiler error if size is wrong
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
369 typedef unsigned char validate_uint32[sizeof(uint32)==4 ? 1 : -1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
370
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
371 #if defined(STBI_NO_STDIO) && !defined(STBI_NO_WRITE)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
372 #define STBI_NO_WRITE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
373 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
374
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
375 #define STBI_NOTUSED(v) (void)sizeof(v)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
376
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
377 #ifdef _MSC_VER
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
378 #define STBI_HAS_LROTL
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
379 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
380
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
381 #ifdef STBI_HAS_LROTL
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
382 #define stbi_lrot(x,y) _lrotl(x,y)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
383 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
384 #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
385 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
386
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
387 ///////////////////////////////////////////////
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
388 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
389 // stbi struct and start_xxx functions
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
390
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
391 // stbi structure is our basic context used by all images, so it
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
392 // contains all the IO context, plus some basic image information
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
393 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
394 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
395 uint32 img_x, img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
396 int img_n, img_out_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
397
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
398 stbi_io_callbacks io;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
399 void *io_user_data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
400
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
401 int read_from_callbacks;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
402 int buflen;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
403 uint8 buffer_start[128];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
404
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
405 uint8 *img_buffer, *img_buffer_end;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
406 uint8 *img_buffer_original;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
407 } stbi;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
408
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
409
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
410 static void refill_buffer(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
411
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
412 // initialize a memory-decode context
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
413 static void start_mem(stbi *s, uint8 const *buffer, int len)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
414 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
415 s->io.read = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
416 s->read_from_callbacks = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
417 s->img_buffer = s->img_buffer_original = (uint8 *) buffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
418 s->img_buffer_end = (uint8 *) buffer+len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
419 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
420
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
421 // initialize a callback-based context
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
422 static void start_callbacks(stbi *s, stbi_io_callbacks *c, void *user)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
423 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
424 s->io = *c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
425 s->io_user_data = user;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
426 s->buflen = sizeof(s->buffer_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
427 s->read_from_callbacks = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
428 s->img_buffer_original = s->buffer_start;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
429 refill_buffer(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
430 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
431
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
432 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
433
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
434 static int stdio_read(void *user, char *data, int size)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
435 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
436 return (int) fread(data,1,size,(FILE*) user);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
437 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
438
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
439 static void stdio_skip(void *user, unsigned n)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
440 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
441 fseek((FILE*) user, n, SEEK_CUR);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
442 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
443
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
444 static int stdio_eof(void *user)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
445 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
446 return feof((FILE*) user);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
447 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
448
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
449 static stbi_io_callbacks stbi_stdio_callbacks =
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
450 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
451 stdio_read,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
452 stdio_skip,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
453 stdio_eof,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
454 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
455
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
456 static void start_file(stbi *s, FILE *f)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
457 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
458 start_callbacks(s, &stbi_stdio_callbacks, (void *) f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
459 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
460
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
461 //static void stop_file(stbi *s) { }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
462
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
463 #endif // !STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
464
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
465 static void stbi_rewind(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
466 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
467 // conceptually rewind SHOULD rewind to the beginning of the stream,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
468 // but we just rewind to the beginning of the initial buffer, because
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
469 // we only use it after doing 'test', which only ever looks at at most 92 bytes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
470 s->img_buffer = s->img_buffer_original;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
471 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
472
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
473 static int stbi_jpeg_test(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
474 static stbi_uc *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
475 static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
476 static int stbi_png_test(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
477 static stbi_uc *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
478 static int stbi_png_info(stbi *s, int *x, int *y, int *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
479 #ifdef STBI_CRAP_FORMATS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
480 static int stbi_bmp_test(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
481 static stbi_uc *stbi_bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
482 static int stbi_tga_test(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
483 static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
484 static int stbi_tga_info(stbi *s, int *x, int *y, int *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
485 static int stbi_psd_test(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
486 static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
487 static int stbi_pic_test(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
488 static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
489 static int stbi_gif_test(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
490 static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
491 static int stbi_gif_info(stbi *s, int *x, int *y, int *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
492 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
493
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
494 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
495 static int stbi_hdr_test(stbi *s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
496 static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
497 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
498
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
499 // this is not threadsafe
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
500 static const char *failure_reason;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
501
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
502 const char *stbi_failure_reason(void)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
503 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
504 return failure_reason;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
505 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
506
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
507 static int e(const char *str)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
508 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
509 failure_reason = str;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
510 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
511 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
512
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
513 // e - error
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
514 // epf - error returning pointer to float
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
515 // epuc - error returning pointer to unsigned char
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
516
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
517 #ifdef STBI_NO_FAILURE_STRINGS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
518 #define e(x,y) 0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
519 #elif defined(STBI_FAILURE_USERMSG)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
520 #define e(x,y) e(y)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
521 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
522 #define e(x,y) e(x)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
523 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
524
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
525 #define epf(x,y) ((float *) (e(x,y)?NULL:NULL))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
526 #define epuc(x,y) ((unsigned char *) (e(x,y)?NULL:NULL))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
527
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
528 void stbi_image_free(void *retval_from_stbi_load)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
529 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
530 free(retval_from_stbi_load);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
531 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
532
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
533 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
534 static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
535 static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
536 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
537
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
538 static unsigned char *stbi_load_main(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
539 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
540 if (stbi_jpeg_test(s)) return stbi_jpeg_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
541 if (stbi_png_test(s)) return stbi_png_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
542 #ifdef STBI_CRAP_FORMATS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
543 if (stbi_bmp_test(s)) return stbi_bmp_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
544 if (stbi_gif_test(s)) return stbi_gif_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
545 if (stbi_psd_test(s)) return stbi_psd_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
546 if (stbi_pic_test(s)) return stbi_pic_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
547 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
548
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
549 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
550 if (stbi_hdr_test(s)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
551 float *hdr = stbi_hdr_load(s, x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
552 return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
553 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
554 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
555
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
556 #ifdef STBI_CRAP_FORMATS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
557 // test tga last because it's a crappy test!
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
558 if (stbi_tga_test(s))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
559 return stbi_tga_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
560 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
561
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
562 return epuc("unknown image type", "Image not of any known type, or corrupt");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
563 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
564
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
565 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
566 unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
567 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
568 FILE *f = fopen(filename, "rb");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
569 unsigned char *result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
570 if (!f) return epuc("can't fopen", "Unable to open file");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
571 result = stbi_load_from_file(f,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
572 fclose(f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
573 return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
574 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
575
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
576 unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
577 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
578 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
579 start_file(&s,f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
580 return stbi_load_main(&s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
581 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
582 #endif //!STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
583
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
584 unsigned char *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
585 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
586 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
587 start_mem(&s,buffer,len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
588 return stbi_load_main(&s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
589 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
590
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
591 unsigned char *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
592 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
593 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
594 start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
595 return stbi_load_main(&s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
596 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
597
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
598 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
599
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
600 float *stbi_loadf_main(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
601 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
602 unsigned char *data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
603 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
604 if (stbi_hdr_test(s))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
605 return stbi_hdr_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
606 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
607 data = stbi_load_main(s, x, y, comp, req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
608 if (data)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
609 return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
610 return epf("unknown image type", "Image not of any known type, or corrupt");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
611 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
612
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
613 float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
614 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
615 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
616 start_mem(&s,buffer,len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
617 return stbi_loadf_main(&s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
618 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
619
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
620 float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
621 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
622 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
623 start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
624 return stbi_loadf_main(&s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
625 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
626
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
627 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
628 float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
629 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
630 FILE *f = fopen(filename, "rb");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
631 float *result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
632 if (!f) return epf("can't fopen", "Unable to open file");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
633 result = stbi_loadf_from_file(f,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
634 fclose(f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
635 return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
636 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
637
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
638 float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
639 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
640 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
641 start_file(&s,f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
642 return stbi_loadf_main(&s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
643 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
644 #endif // !STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
645
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
646 #endif // !STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
647
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
648 // these is-hdr-or-not is defined independent of whether STBI_NO_HDR is
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
649 // defined, for API simplicity; if STBI_NO_HDR is defined, it always
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
650 // reports false!
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
651
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
652 int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
653 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
654 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
655 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
656 start_mem(&s,buffer,len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
657 return stbi_hdr_test(&s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
658 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
659 STBI_NOTUSED(buffer);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
660 STBI_NOTUSED(len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
661 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
662 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
663 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
664
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
665 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
666 extern int stbi_is_hdr (char const *filename)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
667 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
668 FILE *f = fopen(filename, "rb");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
669 int result=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
670 if (f) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
671 result = stbi_is_hdr_from_file(f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
672 fclose(f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
673 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
674 return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
675 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
676
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
677 extern int stbi_is_hdr_from_file(FILE *f)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
678 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
679 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
680 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
681 start_file(&s,f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
682 return stbi_hdr_test(&s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
683 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
684 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
685 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
686 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
687 #endif // !STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
688
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
689 extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
690 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
691 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
692 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
693 start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
694 return stbi_hdr_test(&s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
695 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
696 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
697 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
698 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
699
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
700 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
701 static float h2l_gamma_i=1.0f/2.2f, h2l_scale_i=1.0f;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
702 static float l2h_gamma=2.2f, l2h_scale=1.0f;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
703
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
704 void stbi_hdr_to_ldr_gamma(float gamma) { h2l_gamma_i = 1/gamma; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
705 void stbi_hdr_to_ldr_scale(float scale) { h2l_scale_i = 1/scale; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
706
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
707 void stbi_ldr_to_hdr_gamma(float gamma) { l2h_gamma = gamma; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
708 void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
709 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
710
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
711
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
712 //////////////////////////////////////////////////////////////////////////////
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
713 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
714 // Common code used by all image loaders
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
715 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
716
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
717 enum
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
718 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
719 SCAN_load=0,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
720 SCAN_type,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
721 SCAN_header
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
722 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
723
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
724 static void refill_buffer(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
725 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
726 int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
727 if (n == 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
728 // at end of file, treat same as if from memory
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
729 s->read_from_callbacks = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
730 s->img_buffer = s->img_buffer_end-1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
731 *s->img_buffer = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
732 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
733 s->img_buffer = s->buffer_start;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
734 s->img_buffer_end = s->buffer_start + n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
735 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
736 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
737
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
738 stbi_inline static int get8(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
739 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
740 if (s->img_buffer < s->img_buffer_end)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
741 return *s->img_buffer++;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
742 if (s->read_from_callbacks) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
743 refill_buffer(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
744 return *s->img_buffer++;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
745 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
746 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
747 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
748
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
749 stbi_inline static int at_eof(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
750 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
751 if (s->io.read) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
752 if (!(s->io.eof)(s->io_user_data)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
753 // if feof() is true, check if buffer = end
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
754 // special case: we've only got the special 0 character at the end
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
755 if (s->read_from_callbacks == 0) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
756 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
757
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
758 return s->img_buffer >= s->img_buffer_end;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
759 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
760
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
761 stbi_inline static uint8 get8u(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
762 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
763 return (uint8) get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
764 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
765
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
766 static void skip(stbi *s, int n)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
767 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
768 if (s->io.read) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
769 int blen = s->img_buffer_end - s->img_buffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
770 if (blen < n) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
771 s->img_buffer = s->img_buffer_end;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
772 (s->io.skip)(s->io_user_data, n - blen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
773 return;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
774 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
775 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
776 s->img_buffer += n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
777 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
778
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
779 static int getn(stbi *s, stbi_uc *buffer, int n)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
780 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
781 if (s->io.read) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
782 int blen = s->img_buffer_end - s->img_buffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
783 if (blen < n) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
784 int res, count;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
785
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
786 memcpy(buffer, s->img_buffer, blen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
787
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
788 count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
789 res = (count == (n-blen));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
790 s->img_buffer = s->img_buffer_end;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
791 return res;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
792 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
793 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
794
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
795 if (s->img_buffer+n <= s->img_buffer_end) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
796 memcpy(buffer, s->img_buffer, n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
797 s->img_buffer += n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
798 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
799 } else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
800 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
801 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
802
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
803 static int get16(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
804 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
805 int z = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
806 return (z << 8) + get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
807 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
808
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
809 static uint32 get32(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
810 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
811 uint32 z = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
812 return (z << 16) + get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
813 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
814
24
b0f1b8544b62 Silence some warnings.
Matti Hamalainen <ccr@tnsp.org>
parents: 0
diff changeset
815 #ifdef STBI_CRAP_FORMATS
0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
816 static int get16le(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
817 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
818 int z = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
819 return z + (get8(s) << 8);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
820 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
821
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
822 static uint32 get32le(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
823 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
824 uint32 z = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
825 return z + (get16le(s) << 16);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
826 }
24
b0f1b8544b62 Silence some warnings.
Matti Hamalainen <ccr@tnsp.org>
parents: 0
diff changeset
827 #endif
0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
828
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
829 //////////////////////////////////////////////////////////////////////////////
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
830 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
831 // generic converter from built-in img_n to req_comp
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
832 // individual types do this automatically as much as possible (e.g. jpeg
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
833 // does all cases internally since it needs to colorspace convert anyway,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
834 // and it never has alpha, so very few cases ). png can automatically
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
835 // interleave an alpha=255 channel, but falls back to this for other cases
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
836 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
837 // assume data buffer is malloced, so malloc a new one and free that one
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
838 // only failure mode is malloc failing
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
839
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
840 static uint8 compute_y(int r, int g, int b)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
841 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
842 return (uint8) (((r*77) + (g*150) + (29*b)) >> 8);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
843 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
844
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
845 static unsigned char *convert_format(unsigned char *data, int img_n, int req_comp, uint x, uint y)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
846 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
847 int i,j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
848 unsigned char *good;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
849
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
850 if (req_comp == img_n) return data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
851 assert(req_comp >= 1 && req_comp <= 4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
852
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
853 good = (unsigned char *) malloc(req_comp * x * y);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
854 if (good == NULL) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
855 free(data);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
856 return epuc("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
857 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
858
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
859 for (j=0; j < (int) y; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
860 unsigned char *src = data + j * x * img_n ;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
861 unsigned char *dest = good + j * x * req_comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
862
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
863 #define COMBO(a,b) ((a)*8+(b))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
864 #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
865 // convert source image with img_n components to one with req_comp components;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
866 // avoid switch per pixel, so use switch per scanline and massive macros
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
867 switch (COMBO(img_n, req_comp)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
868 CASE(1,2) dest[0]=src[0], dest[1]=255; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
869 CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
870 CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
871 CASE(2,1) dest[0]=src[0]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
872 CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
873 CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
874 CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
875 CASE(3,1) dest[0]=compute_y(src[0],src[1],src[2]); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
876 CASE(3,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = 255; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
877 CASE(4,1) dest[0]=compute_y(src[0],src[1],src[2]); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
878 CASE(4,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
879 CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
880 default: assert(0);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
881 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
882 #undef CASE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
883 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
884
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
885 free(data);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
886 return good;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
887 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
888
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
889 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
890 static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
891 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
892 int i,k,n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
893 float *output = (float *) malloc(x * y * comp * sizeof(float));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
894 if (output == NULL) { free(data); return epf("outofmem", "Out of memory"); }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
895 // compute number of non-alpha components
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
896 if (comp & 1) n = comp; else n = comp-1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
897 for (i=0; i < x*y; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
898 for (k=0; k < n; ++k) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
899 output[i*comp + k] = (float) pow(data[i*comp+k]/255.0f, l2h_gamma) * l2h_scale;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
900 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
901 if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
902 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
903 free(data);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
904 return output;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
905 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
906
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
907 #define float2int(x) ((int) (x))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
908 static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
909 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
910 int i,k,n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
911 stbi_uc *output = (stbi_uc *) malloc(x * y * comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
912 if (output == NULL) { free(data); return epuc("outofmem", "Out of memory"); }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
913 // compute number of non-alpha components
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
914 if (comp & 1) n = comp; else n = comp-1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
915 for (i=0; i < x*y; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
916 for (k=0; k < n; ++k) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
917 float z = (float) pow(data[i*comp+k]*h2l_scale_i, h2l_gamma_i) * 255 + 0.5f;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
918 if (z < 0) z = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
919 if (z > 255) z = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
920 output[i*comp + k] = (uint8) float2int(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
921 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
922 if (k < comp) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
923 float z = data[i*comp+k] * 255 + 0.5f;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
924 if (z < 0) z = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
925 if (z > 255) z = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
926 output[i*comp + k] = (uint8) float2int(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
927 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
928 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
929 free(data);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
930 return output;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
931 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
932 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
933
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
934 //////////////////////////////////////////////////////////////////////////////
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
935 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
936 // "baseline" JPEG/JFIF decoder (not actually fully baseline implementation)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
937 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
938 // simple implementation
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
939 // - channel subsampling of at most 2 in each dimension
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
940 // - doesn't support delayed output of y-dimension
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
941 // - simple interface (only one output format: 8-bit interleaved RGB)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
942 // - doesn't try to recover corrupt jpegs
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
943 // - doesn't allow partial loading, loading multiple at once
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
944 // - still fast on x86 (copying globals into locals doesn't help x86)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
945 // - allocates lots of intermediate memory (full size of all components)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
946 // - non-interleaved case requires this anyway
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
947 // - allows good upsampling (see next)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
948 // high-quality
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
949 // - upsampled channels are bilinearly interpolated, even across blocks
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
950 // - quality integer IDCT derived from IJG's 'slow'
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
951 // performance
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
952 // - fast huffman; reasonable integer IDCT
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
953 // - uses a lot of intermediate memory, could cache poorly
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
954 // - load http://nothings.org/remote/anemones.jpg 3 times on 2.8Ghz P4
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
955 // stb_jpeg: 1.34 seconds (MSVC6, default release build)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
956 // stb_jpeg: 1.06 seconds (MSVC6, processor = Pentium Pro)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
957 // IJL11.dll: 1.08 seconds (compiled by intel)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
958 // IJG 1998: 0.98 seconds (MSVC6, makefile provided by IJG)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
959 // IJG 1998: 0.95 seconds (MSVC6, makefile + proc=PPro)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
960
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
961 // huffman decoding acceleration
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
962 #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
963
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
964 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
965 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
966 uint8 fast[1 << FAST_BITS];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
967 // weirdly, repacking this into AoS is a 10% speed loss, instead of a win
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
968 uint16 code[256];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
969 uint8 values[256];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
970 uint8 size[257];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
971 unsigned int maxcode[18];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
972 int delta[17]; // old 'firstsymbol' - old 'firstcode'
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
973 } huffman;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
974
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
975 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
976 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
977 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
978 unsigned short dequant2[4][64];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
979 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
980 stbi *s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
981 huffman huff_dc[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
982 huffman huff_ac[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
983 uint8 dequant[4][64];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
984
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
985 // sizes for components, interleaved MCUs
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
986 int img_h_max, img_v_max;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
987 int img_mcu_x, img_mcu_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
988 int img_mcu_w, img_mcu_h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
989
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
990 // definition of jpeg image component
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
991 struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
992 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
993 int id;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
994 int h,v;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
995 int tq;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
996 int hd,ha;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
997 int dc_pred;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
998
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
999 int x,y,w2,h2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1000 uint8 *data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1001 void *raw_data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1002 uint8 *linebuf;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1003 } img_comp[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1004
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1005 uint32 code_buffer; // jpeg entropy-coded buffer
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1006 int code_bits; // number of valid bits
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1007 unsigned char marker; // marker seen while filling entropy buffer
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1008 int nomore; // flag if we saw a marker so must stop
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1009
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1010 int scan_n, order[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1011 int restart_interval, todo;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1012 } jpeg;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1013
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1014 static int build_huffman(huffman *h, int *count)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1015 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1016 int i,j,k=0,code;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1017 // build size list for each symbol (from JPEG spec)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1018 for (i=0; i < 16; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1019 for (j=0; j < count[i]; ++j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1020 h->size[k++] = (uint8) (i+1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1021 h->size[k] = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1022
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1023 // compute actual symbols (from jpeg spec)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1024 code = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1025 k = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1026 for(j=1; j <= 16; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1027 // compute delta to add to code to compute symbol id
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1028 h->delta[j] = k - code;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1029 if (h->size[k] == j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1030 while (h->size[k] == j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1031 h->code[k++] = (uint16) (code++);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1032 if (code-1 >= (1 << j)) return e("bad code lengths","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1033 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1034 // compute largest code + 1 for this size, preshifted as needed later
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1035 h->maxcode[j] = code << (16-j);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1036 code <<= 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1037 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1038 h->maxcode[j] = 0xffffffff;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1039
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1040 // build non-spec acceleration table; 255 is flag for not-accelerated
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1041 memset(h->fast, 255, 1 << FAST_BITS);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1042 for (i=0; i < k; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1043 int s = h->size[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1044 if (s <= FAST_BITS) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1045 int c = h->code[i] << (FAST_BITS-s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1046 int m = 1 << (FAST_BITS-s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1047 for (j=0; j < m; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1048 h->fast[c+j] = (uint8) i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1049 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1050 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1051 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1052 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1053 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1054
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1055 static void grow_buffer_unsafe(jpeg *j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1056 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1057 do {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1058 int b = j->nomore ? 0 : get8(j->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1059 if (b == 0xff) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1060 int c = get8(j->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1061 if (c != 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1062 j->marker = (unsigned char) c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1063 j->nomore = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1064 return;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1065 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1066 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1067 j->code_buffer |= b << (24 - j->code_bits);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1068 j->code_bits += 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1069 } while (j->code_bits <= 24);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1070 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1071
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1072 // (1 << n) - 1
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1073 static uint32 bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1074
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1075 // decode a jpeg huffman value from the bitstream
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1076 stbi_inline static int decode(jpeg *j, huffman *h)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1077 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1078 unsigned int temp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1079 int c,k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1080
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1081 if (j->code_bits < 16) grow_buffer_unsafe(j);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1082
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1083 // look at the top FAST_BITS and determine what symbol ID it is,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1084 // if the code is <= FAST_BITS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1085 c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1086 k = h->fast[c];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1087 if (k < 255) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1088 int s = h->size[k];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1089 if (s > j->code_bits)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1090 return -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1091 j->code_buffer <<= s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1092 j->code_bits -= s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1093 return h->values[k];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1094 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1095
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1096 // naive test is to shift the code_buffer down so k bits are
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1097 // valid, then test against maxcode. To speed this up, we've
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1098 // preshifted maxcode left so that it has (16-k) 0s at the
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1099 // end; in other words, regardless of the number of bits, it
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1100 // wants to be compared against something shifted to have 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1101 // that way we don't need to shift inside the loop.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1102 temp = j->code_buffer >> 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1103 for (k=FAST_BITS+1 ; ; ++k)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1104 if (temp < h->maxcode[k])
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1105 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1106 if (k == 17) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1107 // error! code not found
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1108 j->code_bits -= 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1109 return -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1110 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1111
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1112 if (k > j->code_bits)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1113 return -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1114
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1115 // convert the huffman code to the symbol id
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1116 c = ((j->code_buffer >> (32 - k)) & bmask[k]) + h->delta[k];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1117 assert((((j->code_buffer) >> (32 - h->size[c])) & bmask[h->size[c]]) == h->code[c]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1118
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1119 // convert the id to a symbol
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1120 j->code_bits -= k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1121 j->code_buffer <<= k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1122 return h->values[c];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1123 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1124
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1125 // combined JPEG 'receive' and JPEG 'extend', since baseline
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1126 // always extends everything it receives.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1127 stbi_inline static int extend_receive(jpeg *j, int n)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1128 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1129 unsigned int m = 1 << (n-1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1130 unsigned int k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1131 if (j->code_bits < n) grow_buffer_unsafe(j);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1132
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1133 #if 1
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1134 k = stbi_lrot(j->code_buffer, n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1135 j->code_buffer = k & ~bmask[n];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1136 k &= bmask[n];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1137 j->code_bits -= n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1138 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1139 k = (j->code_buffer >> (32 - n)) & bmask[n];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1140 j->code_bits -= n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1141 j->code_buffer <<= n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1142 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1143 // the following test is probably a random branch that won't
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1144 // predict well. I tried to table accelerate it but failed.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1145 // maybe it's compiling as a conditional move?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1146 if (k < m)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1147 return (-1 << n) + k + 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1148 else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1149 return k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1150 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1151
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1152 // given a value that's at position X in the zigzag stream,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1153 // where does it appear in the 8x8 matrix coded as row-major?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1154 static uint8 dezigzag[64+15] =
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1155 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1156 0, 1, 8, 16, 9, 2, 3, 10,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1157 17, 24, 32, 25, 18, 11, 4, 5,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1158 12, 19, 26, 33, 40, 48, 41, 34,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1159 27, 20, 13, 6, 7, 14, 21, 28,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1160 35, 42, 49, 56, 57, 50, 43, 36,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1161 29, 22, 15, 23, 30, 37, 44, 51,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1162 58, 59, 52, 45, 38, 31, 39, 46,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1163 53, 60, 61, 54, 47, 55, 62, 63,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1164 // let corrupt input sample past end
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1165 63, 63, 63, 63, 63, 63, 63, 63,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1166 63, 63, 63, 63, 63, 63, 63
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1167 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1168
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1169 // decode one 64-entry block--
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1170 static int decode_block(jpeg *j, short data[64], huffman *hdc, huffman *hac, int b)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1171 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1172 int diff,dc,k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1173 int t = decode(j, hdc);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1174 if (t < 0) return e("bad huffman code","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1175
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1176 // 0 all the ac values now so we can do it 32-bits at a time
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1177 memset(data,0,64*sizeof(data[0]));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1178
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1179 diff = t ? extend_receive(j, t) : 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1180 dc = j->img_comp[b].dc_pred + diff;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1181 j->img_comp[b].dc_pred = dc;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1182 data[0] = (short) dc;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1183
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1184 // decode AC components, see JPEG spec
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1185 k = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1186 do {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1187 int r,s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1188 int rs = decode(j, hac);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1189 if (rs < 0) return e("bad huffman code","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1190 s = rs & 15;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1191 r = rs >> 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1192 if (s == 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1193 if (rs != 0xf0) break; // end block
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1194 k += 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1195 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1196 k += r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1197 // decode into unzigzag'd location
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1198 data[dezigzag[k++]] = (short) extend_receive(j,s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1199 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1200 } while (k < 64);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1201 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1202 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1203
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1204 // take a -128..127 value and clamp it and convert to 0..255
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1205 stbi_inline static uint8 clamp(int x)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1206 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1207 // trick to use a single test to catch both cases
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1208 if ((unsigned int) x > 255) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1209 if (x < 0) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1210 if (x > 255) return 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1211 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1212 return (uint8) x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1213 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1214
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1215 #define f2f(x) (int) (((x) * 4096 + 0.5))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1216 #define fsh(x) ((x) << 12)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1217
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1218 // derived from jidctint -- DCT_ISLOW
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1219 #define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1220 int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1221 p2 = s2; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1222 p3 = s6; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1223 p1 = (p2+p3) * f2f(0.5411961f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1224 t2 = p1 + p3*f2f(-1.847759065f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1225 t3 = p1 + p2*f2f( 0.765366865f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1226 p2 = s0; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1227 p3 = s4; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1228 t0 = fsh(p2+p3); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1229 t1 = fsh(p2-p3); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1230 x0 = t0+t3; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1231 x3 = t0-t3; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1232 x1 = t1+t2; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1233 x2 = t1-t2; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1234 t0 = s7; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1235 t1 = s5; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1236 t2 = s3; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1237 t3 = s1; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1238 p3 = t0+t2; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1239 p4 = t1+t3; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1240 p1 = t0+t3; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1241 p2 = t1+t2; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1242 p5 = (p3+p4)*f2f( 1.175875602f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1243 t0 = t0*f2f( 0.298631336f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1244 t1 = t1*f2f( 2.053119869f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1245 t2 = t2*f2f( 3.072711026f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1246 t3 = t3*f2f( 1.501321110f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1247 p1 = p5 + p1*f2f(-0.899976223f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1248 p2 = p5 + p2*f2f(-2.562915447f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1249 p3 = p3*f2f(-1.961570560f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1250 p4 = p4*f2f(-0.390180644f); \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1251 t3 += p1+p4; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1252 t2 += p2+p3; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1253 t1 += p2+p4; \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1254 t0 += p1+p3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1255
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1256 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1257 typedef unsigned short stbi_dequantize_t;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1258 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1259 typedef uint8 stbi_dequantize_t;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1260 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1261
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1262 // .344 seconds on 3*anemones.jpg
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1263 static void idct_block(uint8 *out, int out_stride, short data[64], stbi_dequantize_t *dequantize)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1264 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1265 int i,val[64],*v=val;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1266 stbi_dequantize_t *dq = dequantize;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1267 uint8 *o;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1268 short *d = data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1269
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1270 // columns
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1271 for (i=0; i < 8; ++i,++d,++dq, ++v) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1272 // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1273 if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1274 && d[40]==0 && d[48]==0 && d[56]==0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1275 // no shortcut 0 seconds
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1276 // (1|2|3|4|5|6|7)==0 0 seconds
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1277 // all separate -0.047 seconds
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1278 // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1279 int dcterm = d[0] * dq[0] << 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1280 v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1281 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1282 IDCT_1D(d[ 0]*dq[ 0],d[ 8]*dq[ 8],d[16]*dq[16],d[24]*dq[24],
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1283 d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56])
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1284 // constants scaled things up by 1<<12; let's bring them back
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1285 // down, but keep 2 extra bits of precision
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1286 x0 += 512; x1 += 512; x2 += 512; x3 += 512;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1287 v[ 0] = (x0+t3) >> 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1288 v[56] = (x0-t3) >> 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1289 v[ 8] = (x1+t2) >> 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1290 v[48] = (x1-t2) >> 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1291 v[16] = (x2+t1) >> 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1292 v[40] = (x2-t1) >> 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1293 v[24] = (x3+t0) >> 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1294 v[32] = (x3-t0) >> 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1295 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1296 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1297
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1298 for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1299 // no fast case since the first 1D IDCT spread components out
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1300 IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1301 // constants scaled things up by 1<<12, plus we had 1<<2 from first
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1302 // loop, plus horizontal and vertical each scale by sqrt(8) so together
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1303 // we've got an extra 1<<3, so 1<<17 total we need to remove.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1304 // so we want to round that, which means adding 0.5 * 1<<17,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1305 // aka 65536. Also, we'll end up with -128 to 127 that we want
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1306 // to encode as 0..255 by adding 128, so we'll add that before the shift
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1307 x0 += 65536 + (128<<17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1308 x1 += 65536 + (128<<17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1309 x2 += 65536 + (128<<17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1310 x3 += 65536 + (128<<17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1311 // tried computing the shifts into temps, or'ing the temps to see
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1312 // if any were out of range, but that was slower
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1313 o[0] = clamp((x0+t3) >> 17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1314 o[7] = clamp((x0-t3) >> 17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1315 o[1] = clamp((x1+t2) >> 17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1316 o[6] = clamp((x1-t2) >> 17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1317 o[2] = clamp((x2+t1) >> 17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1318 o[5] = clamp((x2-t1) >> 17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1319 o[3] = clamp((x3+t0) >> 17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1320 o[4] = clamp((x3-t0) >> 17);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1321 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1322 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1323
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1324 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1325 static stbi_idct_8x8 stbi_idct_installed = idct_block;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1326
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1327 void stbi_install_idct(stbi_idct_8x8 func)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1328 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1329 stbi_idct_installed = func;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1330 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1331 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1332
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1333 #define MARKER_none 0xff
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1334 // if there's a pending marker from the entropy stream, return that
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1335 // otherwise, fetch from the stream and get a marker. if there's no
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1336 // marker, return 0xff, which is never a valid marker value
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1337 static uint8 get_marker(jpeg *j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1338 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1339 uint8 x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1340 if (j->marker != MARKER_none) { x = j->marker; j->marker = MARKER_none; return x; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1341 x = get8u(j->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1342 if (x != 0xff) return MARKER_none;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1343 while (x == 0xff)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1344 x = get8u(j->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1345 return x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1346 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1347
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1348 // in each scan, we'll have scan_n components, and the order
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1349 // of the components is specified by order[]
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1350 #define RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1351
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1352 // after a restart interval, reset the entropy decoder and
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1353 // the dc prediction
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1354 static void reset(jpeg *j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1355 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1356 j->code_bits = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1357 j->code_buffer = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1358 j->nomore = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1359 j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1360 j->marker = MARKER_none;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1361 j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1362 // no more than 1<<31 MCUs if no restart_interal? that's plenty safe,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1363 // since we don't even allow 1<<30 pixels
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1364 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1365
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1366 static int parse_entropy_coded_data(jpeg *z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1367 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1368 reset(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1369 if (z->scan_n == 1) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1370 int i,j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1371 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1372 __declspec(align(16))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1373 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1374 short data[64];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1375 int n = z->order[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1376 // non-interleaved data, we just need to process one block at a time,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1377 // in trivial scanline order
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1378 // number of blocks to do just depends on how many actual "pixels" this
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1379 // component has, independent of interleaved MCU blocking and such
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1380 int w = (z->img_comp[n].x+7) >> 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1381 int h = (z->img_comp[n].y+7) >> 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1382 for (j=0; j < h; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1383 for (i=0; i < w; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1384 if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1385 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1386 stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1387 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1388 idct_block(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1389 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1390 // every data block is an MCU, so countdown the restart interval
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1391 if (--z->todo <= 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1392 if (z->code_bits < 24) grow_buffer_unsafe(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1393 // if it's NOT a restart, then just bail, so we get corrupt data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1394 // rather than no data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1395 if (!RESTART(z->marker)) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1396 reset(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1397 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1398 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1399 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1400 } else { // interleaved!
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1401 int i,j,k,x,y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1402 short data[64];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1403 for (j=0; j < z->img_mcu_y; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1404 for (i=0; i < z->img_mcu_x; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1405 // scan an interleaved mcu... process scan_n components in order
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1406 for (k=0; k < z->scan_n; ++k) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1407 int n = z->order[k];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1408 // scan out an mcu's worth of this component; that's just determined
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1409 // by the basic H and V specified for the component
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1410 for (y=0; y < z->img_comp[n].v; ++y) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1411 for (x=0; x < z->img_comp[n].h; ++x) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1412 int x2 = (i*z->img_comp[n].h + x)*8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1413 int y2 = (j*z->img_comp[n].v + y)*8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1414 if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1415 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1416 stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1417 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1418 idct_block(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1419 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1420 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1421 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1422 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1423 // after all interleaved components, that's an interleaved MCU,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1424 // so now count down the restart interval
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1425 if (--z->todo <= 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1426 if (z->code_bits < 24) grow_buffer_unsafe(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1427 // if it's NOT a restart, then just bail, so we get corrupt data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1428 // rather than no data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1429 if (!RESTART(z->marker)) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1430 reset(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1431 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1432 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1433 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1434 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1435 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1436 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1437
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1438 static int process_marker(jpeg *z, int m)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1439 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1440 int L;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1441 switch (m) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1442 case MARKER_none: // no marker found
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1443 return e("expected marker","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1444
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1445 case 0xC2: // SOF - progressive
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1446 return e("progressive jpeg","JPEG format not supported (progressive)");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1447
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1448 case 0xDD: // DRI - specify restart interval
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1449 if (get16(z->s) != 4) return e("bad DRI len","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1450 z->restart_interval = get16(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1451 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1452
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1453 case 0xDB: // DQT - define quantization table
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1454 L = get16(z->s)-2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1455 while (L > 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1456 int q = get8(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1457 int p = q >> 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1458 int t = q & 15,i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1459 if (p != 0) return e("bad DQT type","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1460 if (t > 3) return e("bad DQT table","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1461 for (i=0; i < 64; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1462 z->dequant[t][dezigzag[i]] = get8u(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1463 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1464 for (i=0; i < 64; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1465 z->dequant2[t][i] = z->dequant[t][i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1466 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1467 L -= 65;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1468 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1469 return L==0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1470
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1471 case 0xC4: // DHT - define huffman table
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1472 L = get16(z->s)-2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1473 while (L > 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1474 uint8 *v;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1475 int sizes[16],i,m=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1476 int q = get8(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1477 int tc = q >> 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1478 int th = q & 15;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1479 if (tc > 1 || th > 3) return e("bad DHT header","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1480 for (i=0; i < 16; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1481 sizes[i] = get8(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1482 m += sizes[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1483 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1484 L -= 17;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1485 if (tc == 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1486 if (!build_huffman(z->huff_dc+th, sizes)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1487 v = z->huff_dc[th].values;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1488 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1489 if (!build_huffman(z->huff_ac+th, sizes)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1490 v = z->huff_ac[th].values;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1491 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1492 for (i=0; i < m; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1493 v[i] = get8u(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1494 L -= m;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1495 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1496 return L==0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1497 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1498 // check for comment block or APP blocks
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1499 if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1500 skip(z->s, get16(z->s)-2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1501 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1502 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1503 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1504 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1505
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1506 // after we see SOS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1507 static int process_scan_header(jpeg *z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1508 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1509 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1510 int Ls = get16(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1511 z->scan_n = get8(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1512 if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return e("bad SOS component count","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1513 if (Ls != 6+2*z->scan_n) return e("bad SOS len","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1514 for (i=0; i < z->scan_n; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1515 int id = get8(z->s), which;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1516 int q = get8(z->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1517 for (which = 0; which < z->s->img_n; ++which)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1518 if (z->img_comp[which].id == id)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1519 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1520 if (which == z->s->img_n) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1521 z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return e("bad DC huff","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1522 z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return e("bad AC huff","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1523 z->order[i] = which;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1524 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1525 if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1526 get8(z->s); // should be 63, but might be 0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1527 if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1528
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1529 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1530 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1531
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1532 static int process_frame_header(jpeg *z, int scan)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1533 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1534 stbi *s = z->s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1535 int Lf,p,i,q, h_max=1,v_max=1,c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1536 Lf = get16(s); if (Lf < 11) return e("bad SOF len","Corrupt JPEG"); // JPEG
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1537 p = get8(s); if (p != 8) return e("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1538 s->img_y = get16(s); if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1539 s->img_x = get16(s); if (s->img_x == 0) return e("0 width","Corrupt JPEG"); // JPEG requires
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1540 c = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1541 if (c != 3 && c != 1) return e("bad component count","Corrupt JPEG"); // JFIF requires
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1542 s->img_n = c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1543 for (i=0; i < c; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1544 z->img_comp[i].data = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1545 z->img_comp[i].linebuf = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1546 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1547
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1548 if (Lf != 8+3*s->img_n) return e("bad SOF len","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1549
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1550 for (i=0; i < s->img_n; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1551 z->img_comp[i].id = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1552 if (z->img_comp[i].id != i+1) // JFIF requires
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1553 if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files!
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1554 return e("bad component ID","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1555 q = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1556 z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return e("bad H","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1557 z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return e("bad V","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1558 z->img_comp[i].tq = get8(s); if (z->img_comp[i].tq > 3) return e("bad TQ","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1559 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1560
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1561 if (scan != SCAN_load) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1562
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1563 if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1564
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1565 for (i=0; i < s->img_n; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1566 if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1567 if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1568 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1569
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1570 // compute interleaved mcu info
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1571 z->img_h_max = h_max;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1572 z->img_v_max = v_max;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1573 z->img_mcu_w = h_max * 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1574 z->img_mcu_h = v_max * 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1575 z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1576 z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1577
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1578 for (i=0; i < s->img_n; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1579 // number of effective pixels (e.g. for non-interleaved MCU)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1580 z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1581 z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1582 // to simplify generation, we'll allocate enough memory to decode
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1583 // the bogus oversized data from using interleaved MCUs and their
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1584 // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1585 // discard the extra data until colorspace conversion
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1586 z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1587 z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1588 z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1589 if (z->img_comp[i].raw_data == NULL) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1590 for(--i; i >= 0; --i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1591 free(z->img_comp[i].raw_data);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1592 z->img_comp[i].data = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1593 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1594 return e("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1595 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1596 // align blocks for installable-idct using mmx/sse
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1597 z->img_comp[i].data = (uint8*) (((size_t) z->img_comp[i].raw_data + 15) & ~15);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1598 z->img_comp[i].linebuf = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1599 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1600
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1601 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1602 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1603
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1604 // use comparisons since in some cases we handle more than one case (e.g. SOF)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1605 #define DNL(x) ((x) == 0xdc)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1606 #define SOI(x) ((x) == 0xd8)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1607 #define EOI(x) ((x) == 0xd9)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1608 #define SOF(x) ((x) == 0xc0 || (x) == 0xc1)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1609 #define SOS(x) ((x) == 0xda)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1610
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1611 static int decode_jpeg_header(jpeg *z, int scan)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1612 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1613 int m;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1614 z->marker = MARKER_none; // initialize cached marker to empty
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1615 m = get_marker(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1616 if (!SOI(m)) return e("no SOI","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1617 if (scan == SCAN_type) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1618 m = get_marker(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1619 while (!SOF(m)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1620 if (!process_marker(z,m)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1621 m = get_marker(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1622 while (m == MARKER_none) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1623 // some files have extra padding after their blocks, so ok, we'll scan
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1624 if (at_eof(z->s)) return e("no SOF", "Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1625 m = get_marker(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1626 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1627 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1628 if (!process_frame_header(z, scan)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1629 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1630 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1631
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1632 static int decode_jpeg_image(jpeg *j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1633 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1634 int m;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1635 j->restart_interval = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1636 if (!decode_jpeg_header(j, SCAN_load)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1637 m = get_marker(j);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1638 while (!EOI(m)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1639 if (SOS(m)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1640 if (!process_scan_header(j)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1641 if (!parse_entropy_coded_data(j)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1642 if (j->marker == MARKER_none ) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1643 // handle 0s at the end of image data from IP Kamera 9060
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1644 while (!at_eof(j->s)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1645 int x = get8(j->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1646 if (x == 255) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1647 j->marker = get8u(j->s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1648 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1649 } else if (x != 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1650 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1651 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1652 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1653 // if we reach eof without hitting a marker, get_marker() below will fail and we'll eventually return 0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1654 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1655 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1656 if (!process_marker(j, m)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1657 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1658 m = get_marker(j);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1659 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1660 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1661 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1662
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1663 // static jfif-centered resampling (across block boundaries)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1664
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1665 typedef uint8 *(*resample_row_func)(uint8 *out, uint8 *in0, uint8 *in1,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1666 int w, int hs);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1667
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1668 #define div4(x) ((uint8) ((x) >> 2))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1669
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1670 static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1671 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1672 STBI_NOTUSED(out);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1673 STBI_NOTUSED(in_far);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1674 STBI_NOTUSED(w);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1675 STBI_NOTUSED(hs);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1676 return in_near;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1677 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1678
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1679 static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1680 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1681 // need to generate two samples vertically for every one in input
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1682 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1683 STBI_NOTUSED(hs);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1684 for (i=0; i < w; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1685 out[i] = div4(3*in_near[i] + in_far[i] + 2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1686 return out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1687 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1688
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1689 static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1690 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1691 // need to generate two samples horizontally for every one in input
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1692 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1693 uint8 *input = in_near;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1694
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1695 if (w == 1) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1696 // if only one sample, can't do any interpolation
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1697 out[0] = out[1] = input[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1698 return out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1699 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1700
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1701 out[0] = input[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1702 out[1] = div4(input[0]*3 + input[1] + 2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1703 for (i=1; i < w-1; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1704 int n = 3*input[i]+2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1705 out[i*2+0] = div4(n+input[i-1]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1706 out[i*2+1] = div4(n+input[i+1]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1707 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1708 out[i*2+0] = div4(input[w-2]*3 + input[w-1] + 2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1709 out[i*2+1] = input[w-1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1710
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1711 STBI_NOTUSED(in_far);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1712 STBI_NOTUSED(hs);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1713
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1714 return out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1715 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1716
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1717 #define div16(x) ((uint8) ((x) >> 4))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1718
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1719 static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1720 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1721 // need to generate 2x2 samples for every one in input
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1722 int i,t0,t1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1723 if (w == 1) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1724 out[0] = out[1] = div4(3*in_near[0] + in_far[0] + 2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1725 return out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1726 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1727
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1728 t1 = 3*in_near[0] + in_far[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1729 out[0] = div4(t1+2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1730 for (i=1; i < w; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1731 t0 = t1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1732 t1 = 3*in_near[i]+in_far[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1733 out[i*2-1] = div16(3*t0 + t1 + 8);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1734 out[i*2 ] = div16(3*t1 + t0 + 8);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1735 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1736 out[w*2-1] = div4(t1+2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1737
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1738 STBI_NOTUSED(hs);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1739
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1740 return out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1741 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1742
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1743 static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1744 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1745 // resample with nearest-neighbor
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1746 int i,j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1747 in_far = in_far;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1748 for (i=0; i < w; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1749 for (j=0; j < hs; ++j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1750 out[i*hs+j] = in_near[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1751 return out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1752 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1753
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1754 #define float2fixed(x) ((int) ((x) * 65536 + 0.5))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1755
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1756 // 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1757 // VC6 without processor=Pro is generating multiple LEAs per multiply!
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1758 static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1759 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1760 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1761 for (i=0; i < count; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1762 int y_fixed = (y[i] << 16) + 32768; // rounding
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1763 int r,g,b;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1764 int cr = pcr[i] - 128;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1765 int cb = pcb[i] - 128;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1766 r = y_fixed + cr*float2fixed(1.40200f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1767 g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1768 b = y_fixed + cb*float2fixed(1.77200f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1769 r >>= 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1770 g >>= 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1771 b >>= 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1772 if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1773 if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1774 if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1775 out[0] = (uint8)r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1776 out[1] = (uint8)g;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1777 out[2] = (uint8)b;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1778 out[3] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1779 out += step;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1780 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1781 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1782
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1783 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1784 static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1785
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1786 void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1787 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1788 stbi_YCbCr_installed = func;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1789 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1790 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1791
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1792
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1793 // clean up the temporary component buffers
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1794 static void cleanup_jpeg(jpeg *j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1795 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1796 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1797 for (i=0; i < j->s->img_n; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1798 if (j->img_comp[i].data) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1799 free(j->img_comp[i].raw_data);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1800 j->img_comp[i].data = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1801 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1802 if (j->img_comp[i].linebuf) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1803 free(j->img_comp[i].linebuf);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1804 j->img_comp[i].linebuf = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1805 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1806 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1807 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1808
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1809 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1810 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1811 resample_row_func resample;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1812 uint8 *line0,*line1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1813 int hs,vs; // expansion factor in each axis
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1814 int w_lores; // horizontal pixels pre-expansion
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1815 int ystep; // how far through vertical expansion we are
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1816 int ypos; // which pre-expansion row we're on
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1817 } stbi_resample;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1818
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1819 static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1820 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1821 int n, decode_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1822 // validate req_comp
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1823 if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1824 z->s->img_n = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1825
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1826 // load a jpeg image from whichever source
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1827 if (!decode_jpeg_image(z)) { cleanup_jpeg(z); return NULL; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1828
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1829 // determine actual number of components to generate
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1830 n = req_comp ? req_comp : z->s->img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1831
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1832 if (z->s->img_n == 3 && n < 3)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1833 decode_n = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1834 else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1835 decode_n = z->s->img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1836
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1837 // resample and color-convert
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1838 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1839 int k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1840 uint i,j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1841 uint8 *output;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1842 uint8 *coutput[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1843
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1844 stbi_resample res_comp[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1845
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1846 for (k=0; k < decode_n; ++k) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1847 stbi_resample *r = &res_comp[k];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1848
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1849 // allocate line buffer big enough for upsampling off the edges
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1850 // with upsample factor of 4
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1851 z->img_comp[k].linebuf = (uint8 *) malloc(z->s->img_x + 3);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1852 if (!z->img_comp[k].linebuf) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1853
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1854 r->hs = z->img_h_max / z->img_comp[k].h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1855 r->vs = z->img_v_max / z->img_comp[k].v;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1856 r->ystep = r->vs >> 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1857 r->w_lores = (z->s->img_x + r->hs-1) / r->hs;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1858 r->ypos = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1859 r->line0 = r->line1 = z->img_comp[k].data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1860
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1861 if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1862 else if (r->hs == 1 && r->vs == 2) r->resample = resample_row_v_2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1863 else if (r->hs == 2 && r->vs == 1) r->resample = resample_row_h_2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1864 else if (r->hs == 2 && r->vs == 2) r->resample = resample_row_hv_2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1865 else r->resample = resample_row_generic;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1866 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1867
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1868 // can't error after this so, this is safe
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1869 output = (uint8 *) malloc(n * z->s->img_x * z->s->img_y + 1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1870 if (!output) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1871
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1872 // now go ahead and resample
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1873 for (j=0; j < z->s->img_y; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1874 uint8 *out = output + n * z->s->img_x * j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1875 for (k=0; k < decode_n; ++k) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1876 stbi_resample *r = &res_comp[k];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1877 int y_bot = r->ystep >= (r->vs >> 1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1878 coutput[k] = r->resample(z->img_comp[k].linebuf,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1879 y_bot ? r->line1 : r->line0,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1880 y_bot ? r->line0 : r->line1,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1881 r->w_lores, r->hs);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1882 if (++r->ystep >= r->vs) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1883 r->ystep = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1884 r->line0 = r->line1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1885 if (++r->ypos < z->img_comp[k].y)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1886 r->line1 += z->img_comp[k].w2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1887 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1888 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1889 if (n >= 3) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1890 uint8 *y = coutput[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1891 if (z->s->img_n == 3) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1892 #ifdef STBI_SIMD
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1893 stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1894 #else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1895 YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s->img_x, n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1896 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1897 } else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1898 for (i=0; i < z->s->img_x; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1899 out[0] = out[1] = out[2] = y[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1900 out[3] = 255; // not used if n==3
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1901 out += n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1902 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1903 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1904 uint8 *y = coutput[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1905 if (n == 1)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1906 for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1907 else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1908 for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1909 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1910 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1911 cleanup_jpeg(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1912 *out_x = z->s->img_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1913 *out_y = z->s->img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1914 if (comp) *comp = z->s->img_n; // report original components, not output
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1915 return output;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1916 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1917 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1918
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1919 static unsigned char *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1920 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1921 jpeg j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1922 j.s = s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1923 return load_jpeg_image(&j, x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1924 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1925
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1926 static int stbi_jpeg_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1927 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1928 int r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1929 jpeg j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1930 j.s = s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1931 r = decode_jpeg_header(&j, SCAN_type);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1932 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1933 return r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1934 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1935
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1936 static int stbi_jpeg_info_raw(jpeg *j, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1937 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1938 if (!decode_jpeg_header(j, SCAN_header)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1939 stbi_rewind( j->s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1940 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1941 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1942 if (x) *x = j->s->img_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1943 if (y) *y = j->s->img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1944 if (comp) *comp = j->s->img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1945 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1946 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1947
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1948 static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1949 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1950 jpeg j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1951 j.s = s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1952 return stbi_jpeg_info_raw(&j, x, y, comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1953 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1954
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1955 // public domain zlib decode v0.2 Sean Barrett 2006-11-18
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1956 // simple implementation
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1957 // - all input must be provided in an upfront buffer
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1958 // - all output is written to a single output buffer (can malloc/realloc)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1959 // performance
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1960 // - fast huffman
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1961
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1962 // fast-way is faster to check than jpeg huffman, but slow way is slower
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1963 #define ZFAST_BITS 9 // accelerate all cases in default tables
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1964 #define ZFAST_MASK ((1 << ZFAST_BITS) - 1)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1965
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1966 // zlib-style huffman encoding
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1967 // (jpegs packs from left, zlib from right, so can't share code)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1968 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1969 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1970 uint16 fast[1 << ZFAST_BITS];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1971 uint16 firstcode[16];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1972 int maxcode[17];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1973 uint16 firstsymbol[16];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1974 uint8 size[288];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1975 uint16 value[288];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1976 } zhuffman;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1977
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1978 stbi_inline static int bitreverse16(int n)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1979 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1980 n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1981 n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1982 n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1983 n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1984 return n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1985 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1986
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1987 stbi_inline static int bit_reverse(int v, int bits)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1988 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1989 assert(bits <= 16);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1990 // to bit reverse n bits, reverse 16 and shift
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1991 // e.g. 11 bits, bit reverse and shift away 5
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1992 return bitreverse16(v) >> (16-bits);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1993 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1994
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1995 static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1996 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1997 int i,k=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1998 int code, next_code[16], sizes[17];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1999
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2000 // DEFLATE spec for generating codes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2001 memset(sizes, 0, sizeof(sizes));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2002 memset(z->fast, 255, sizeof(z->fast));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2003 for (i=0; i < num; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2004 ++sizes[sizelist[i]];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2005 sizes[0] = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2006 for (i=1; i < 16; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2007 assert(sizes[i] <= (1 << i));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2008 code = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2009 for (i=1; i < 16; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2010 next_code[i] = code;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2011 z->firstcode[i] = (uint16) code;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2012 z->firstsymbol[i] = (uint16) k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2013 code = (code + sizes[i]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2014 if (sizes[i])
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2015 if (code-1 >= (1 << i)) return e("bad codelengths","Corrupt JPEG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2016 z->maxcode[i] = code << (16-i); // preshift for inner loop
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2017 code <<= 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2018 k += sizes[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2019 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2020 z->maxcode[16] = 0x10000; // sentinel
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2021 for (i=0; i < num; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2022 int s = sizelist[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2023 if (s) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2024 int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2025 z->size[c] = (uint8)s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2026 z->value[c] = (uint16)i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2027 if (s <= ZFAST_BITS) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2028 int k = bit_reverse(next_code[s],s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2029 while (k < (1 << ZFAST_BITS)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2030 z->fast[k] = (uint16) c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2031 k += (1 << s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2032 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2033 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2034 ++next_code[s];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2035 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2036 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2037 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2038 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2039
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2040 // zlib-from-memory implementation for PNG reading
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2041 // because PNG allows splitting the zlib stream arbitrarily,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2042 // and it's annoying structurally to have PNG call ZLIB call PNG,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2043 // we require PNG read all the IDATs and combine them into a single
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2044 // memory buffer
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2045
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2046 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2047 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2048 uint8 *zbuffer, *zbuffer_end;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2049 int num_bits;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2050 uint32 code_buffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2051
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2052 char *zout;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2053 char *zout_start;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2054 char *zout_end;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2055 int z_expandable;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2056
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2057 zhuffman z_length, z_distance;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2058 } zbuf;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2059
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2060 stbi_inline static int zget8(zbuf *z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2061 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2062 if (z->zbuffer >= z->zbuffer_end) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2063 return *z->zbuffer++;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2064 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2065
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2066 static void fill_bits(zbuf *z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2067 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2068 do {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2069 assert(z->code_buffer < (1U << z->num_bits));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2070 z->code_buffer |= zget8(z) << z->num_bits;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2071 z->num_bits += 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2072 } while (z->num_bits <= 24);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2073 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2074
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2075 stbi_inline static unsigned int zreceive(zbuf *z, int n)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2076 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2077 unsigned int k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2078 if (z->num_bits < n) fill_bits(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2079 k = z->code_buffer & ((1 << n) - 1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2080 z->code_buffer >>= n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2081 z->num_bits -= n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2082 return k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2083 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2084
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2085 stbi_inline static int zhuffman_decode(zbuf *a, zhuffman *z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2086 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2087 int b,s,k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2088 if (a->num_bits < 16) fill_bits(a);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2089 b = z->fast[a->code_buffer & ZFAST_MASK];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2090 if (b < 0xffff) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2091 s = z->size[b];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2092 a->code_buffer >>= s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2093 a->num_bits -= s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2094 return z->value[b];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2095 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2096
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2097 // not resolved by fast table, so compute it the slow way
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2098 // use jpeg approach, which requires MSbits at top
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2099 k = bit_reverse(a->code_buffer, 16);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2100 for (s=ZFAST_BITS+1; ; ++s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2101 if (k < z->maxcode[s])
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2102 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2103 if (s == 16) return -1; // invalid code!
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2104 // code size is s, so:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2105 b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2106 assert(z->size[b] == s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2107 a->code_buffer >>= s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2108 a->num_bits -= s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2109 return z->value[b];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2110 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2111
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2112 static int expand(zbuf *z, int n) // need to make room for n bytes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2113 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2114 char *q;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2115 int cur, limit;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2116 if (!z->z_expandable) return e("output buffer limit","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2117 cur = (int) (z->zout - z->zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2118 limit = (int) (z->zout_end - z->zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2119 while (cur + n > limit)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2120 limit *= 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2121 q = (char *) realloc(z->zout_start, limit);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2122 if (q == NULL) return e("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2123 z->zout_start = q;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2124 z->zout = q + cur;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2125 z->zout_end = q + limit;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2126 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2127 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2128
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2129 static int length_base[31] = {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2130 3,4,5,6,7,8,9,10,11,13,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2131 15,17,19,23,27,31,35,43,51,59,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2132 67,83,99,115,131,163,195,227,258,0,0 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2133
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2134 static int length_extra[31]=
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2135 { 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 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2136
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2137 static int dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2138 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2139
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2140 static int dist_extra[32] =
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2141 { 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};
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2142
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2143 static int parse_huffman_block(zbuf *a)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2144 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2145 for(;;) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2146 int z = zhuffman_decode(a, &a->z_length);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2147 if (z < 256) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2148 if (z < 0) return e("bad huffman code","Corrupt PNG"); // error in huffman codes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2149 if (a->zout >= a->zout_end) if (!expand(a, 1)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2150 *a->zout++ = (char) z;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2151 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2152 uint8 *p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2153 int len,dist;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2154 if (z == 256) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2155 z -= 257;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2156 len = length_base[z];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2157 if (length_extra[z]) len += zreceive(a, length_extra[z]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2158 z = zhuffman_decode(a, &a->z_distance);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2159 if (z < 0) return e("bad huffman code","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2160 dist = dist_base[z];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2161 if (dist_extra[z]) dist += zreceive(a, dist_extra[z]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2162 if (a->zout - a->zout_start < dist) return e("bad dist","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2163 if (a->zout + len > a->zout_end) if (!expand(a, len)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2164 p = (uint8 *) (a->zout - dist);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2165 while (len--)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2166 *a->zout++ = *p++;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2167 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2168 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2169 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2170
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2171 static int compute_huffman_codes(zbuf *a)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2172 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2173 static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2174 zhuffman z_codelength;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2175 uint8 lencodes[286+32+137];//padding for maximum single op
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2176 uint8 codelength_sizes[19];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2177 int i,n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2178
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2179 int hlit = zreceive(a,5) + 257;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2180 int hdist = zreceive(a,5) + 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2181 int hclen = zreceive(a,4) + 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2182
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2183 memset(codelength_sizes, 0, sizeof(codelength_sizes));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2184 for (i=0; i < hclen; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2185 int s = zreceive(a,3);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2186 codelength_sizes[length_dezigzag[i]] = (uint8) s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2187 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2188 if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2189
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2190 n = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2191 while (n < hlit + hdist) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2192 int c = zhuffman_decode(a, &z_codelength);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2193 assert(c >= 0 && c < 19);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2194 if (c < 16)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2195 lencodes[n++] = (uint8) c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2196 else if (c == 16) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2197 c = zreceive(a,2)+3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2198 memset(lencodes+n, lencodes[n-1], c);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2199 n += c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2200 } else if (c == 17) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2201 c = zreceive(a,3)+3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2202 memset(lencodes+n, 0, c);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2203 n += c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2204 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2205 assert(c == 18);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2206 c = zreceive(a,7)+11;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2207 memset(lencodes+n, 0, c);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2208 n += c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2209 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2210 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2211 if (n != hlit+hdist) return e("bad codelengths","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2212 if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2213 if (!zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2214 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2215 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2216
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2217 static int parse_uncompressed_block(zbuf *a)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2218 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2219 uint8 header[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2220 int len,nlen,k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2221 if (a->num_bits & 7)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2222 zreceive(a, a->num_bits & 7); // discard
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2223 // drain the bit-packed data into header
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2224 k = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2225 while (a->num_bits > 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2226 header[k++] = (uint8) (a->code_buffer & 255); // wtf this warns?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2227 a->code_buffer >>= 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2228 a->num_bits -= 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2229 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2230 assert(a->num_bits == 0);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2231 // now fill header the normal way
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2232 while (k < 4)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2233 header[k++] = (uint8) zget8(a);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2234 len = header[1] * 256 + header[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2235 nlen = header[3] * 256 + header[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2236 if (nlen != (len ^ 0xffff)) return e("zlib corrupt","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2237 if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2238 if (a->zout + len > a->zout_end)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2239 if (!expand(a, len)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2240 memcpy(a->zout, a->zbuffer, len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2241 a->zbuffer += len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2242 a->zout += len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2243 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2244 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2245
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2246 static int parse_zlib_header(zbuf *a)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2247 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2248 int cmf = zget8(a);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2249 int cm = cmf & 15;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2250 // int cinfo = cmf >> 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2251 int flg = zget8(a);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2252 if ((cmf*256+flg) % 31 != 0) return e("bad zlib header","Corrupt PNG"); // zlib spec
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2253 if (flg & 32) return e("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2254 if (cm != 8) return e("bad compression","Corrupt PNG"); // DEFLATE required for png
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2255 // window = 1 << (8 + cinfo)... but who cares, we fully buffer output
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2256 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2257 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2258
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2259 // @TODO: should statically initialize these for optimal thread safety
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2260 static uint8 default_length[288], default_distance[32];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2261 static void init_defaults(void)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2262 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2263 int i; // use <= to match clearly with spec
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2264 for (i=0; i <= 143; ++i) default_length[i] = 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2265 for ( ; i <= 255; ++i) default_length[i] = 9;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2266 for ( ; i <= 279; ++i) default_length[i] = 7;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2267 for ( ; i <= 287; ++i) default_length[i] = 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2268
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2269 for (i=0; i <= 31; ++i) default_distance[i] = 5;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2270 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2271
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2272 int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2273 static int parse_zlib(zbuf *a, int parse_header)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2274 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2275 int final, type;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2276 if (parse_header)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2277 if (!parse_zlib_header(a)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2278 a->num_bits = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2279 a->code_buffer = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2280 do {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2281 final = zreceive(a,1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2282 type = zreceive(a,2);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2283 if (type == 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2284 if (!parse_uncompressed_block(a)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2285 } else if (type == 3) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2286 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2287 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2288 if (type == 1) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2289 // use fixed code lengths
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2290 if (!default_distance[31]) init_defaults();
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2291 if (!zbuild_huffman(&a->z_length , default_length , 288)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2292 if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2293 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2294 if (!compute_huffman_codes(a)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2295 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2296 if (!parse_huffman_block(a)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2297 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2298 if (stbi_png_partial && a->zout - a->zout_start > 65536)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2299 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2300 } while (!final);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2301 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2302 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2303
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2304 static int do_zlib(zbuf *a, char *obuf, int olen, int exp, int parse_header)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2305 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2306 a->zout_start = obuf;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2307 a->zout = obuf;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2308 a->zout_end = obuf + olen;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2309 a->z_expandable = exp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2310
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2311 return parse_zlib(a, parse_header);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2312 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2313
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2314 char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2315 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2316 zbuf a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2317 char *p = (char *) malloc(initial_size);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2318 if (p == NULL) return NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2319 a.zbuffer = (uint8 *) buffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2320 a.zbuffer_end = (uint8 *) buffer + len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2321 if (do_zlib(&a, p, initial_size, 1, 1)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2322 if (outlen) *outlen = (int) (a.zout - a.zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2323 return a.zout_start;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2324 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2325 free(a.zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2326 return NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2327 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2328 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2329
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2330 char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2331 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2332 return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2333 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2334
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2335 char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2336 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2337 zbuf a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2338 char *p = (char *) malloc(initial_size);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2339 if (p == NULL) return NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2340 a.zbuffer = (uint8 *) buffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2341 a.zbuffer_end = (uint8 *) buffer + len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2342 if (do_zlib(&a, p, initial_size, 1, parse_header)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2343 if (outlen) *outlen = (int) (a.zout - a.zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2344 return a.zout_start;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2345 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2346 free(a.zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2347 return NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2348 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2349 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2350
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2351 int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2352 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2353 zbuf a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2354 a.zbuffer = (uint8 *) ibuffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2355 a.zbuffer_end = (uint8 *) ibuffer + ilen;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2356 if (do_zlib(&a, obuffer, olen, 0, 1))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2357 return (int) (a.zout - a.zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2358 else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2359 return -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2360 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2361
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2362 char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2363 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2364 zbuf a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2365 char *p = (char *) malloc(16384);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2366 if (p == NULL) return NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2367 a.zbuffer = (uint8 *) buffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2368 a.zbuffer_end = (uint8 *) buffer+len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2369 if (do_zlib(&a, p, 16384, 1, 0)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2370 if (outlen) *outlen = (int) (a.zout - a.zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2371 return a.zout_start;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2372 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2373 free(a.zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2374 return NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2375 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2376 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2377
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2378 int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2379 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2380 zbuf a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2381 a.zbuffer = (uint8 *) ibuffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2382 a.zbuffer_end = (uint8 *) ibuffer + ilen;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2383 if (do_zlib(&a, obuffer, olen, 0, 0))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2384 return (int) (a.zout - a.zout_start);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2385 else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2386 return -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2387 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2388
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2389 // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2390 // simple implementation
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2391 // - only 8-bit samples
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2392 // - no CRC checking
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2393 // - allocates lots of intermediate memory
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2394 // - avoids problem of streaming data between subsystems
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2395 // - avoids explicit window management
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2396 // performance
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2397 // - uses stb_zlib, a PD zlib implementation with fast huffman decoding
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2398
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2399
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2400 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2401 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2402 uint32 length;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2403 uint32 type;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2404 } chunk;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2405
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2406 #define PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2407
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2408 static chunk get_chunk_header(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2409 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2410 chunk c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2411 c.length = get32(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2412 c.type = get32(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2413 return c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2414 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2415
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2416 static int check_png_header(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2417 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2418 static uint8 png_sig[8] = { 137,80,78,71,13,10,26,10 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2419 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2420 for (i=0; i < 8; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2421 if (get8u(s) != png_sig[i]) return e("bad png sig","Not a PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2422 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2423 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2424
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2425 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2426 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2427 stbi *s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2428 uint8 *idata, *expanded, *out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2429 } png;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2430
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2431
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2432 enum {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2433 F_none=0, F_sub=1, F_up=2, F_avg=3, F_paeth=4,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2434 F_avg_first, F_paeth_first
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2435 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2436
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2437 static uint8 first_row_filter[5] =
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2438 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2439 F_none, F_sub, F_none, F_avg_first, F_paeth_first
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2440 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2441
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2442 static int paeth(int a, int b, int c)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2443 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2444 int p = a + b - c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2445 int pa = abs(p-a);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2446 int pb = abs(p-b);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2447 int pc = abs(p-c);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2448 if (pa <= pb && pa <= pc) return a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2449 if (pb <= pc) return b;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2450 return c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2451 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2452
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2453 // create the png data from post-deflated data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2454 static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2455 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2456 stbi *s = a->s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2457 uint32 i,j,stride = x*out_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2458 int k;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2459 int img_n = s->img_n; // copy it into a local for later
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2460 assert(out_n == s->img_n || out_n == s->img_n+1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2461 if (stbi_png_partial) y = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2462 a->out = (uint8 *) malloc(x * y * out_n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2463 if (!a->out) return e("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2464 if (!stbi_png_partial) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2465 if (s->img_x == x && s->img_y == y) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2466 if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2467 } else { // interlaced:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2468 if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2469 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2470 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2471 for (j=0; j < y; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2472 uint8 *cur = a->out + stride*j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2473 uint8 *prior = cur - stride;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2474 int filter = *raw++;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2475 if (filter > 4) return e("invalid filter","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2476 // if first row, use special filter that doesn't sample previous row
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2477 if (j == 0) filter = first_row_filter[filter];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2478 // handle first pixel explicitly
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2479 for (k=0; k < img_n; ++k) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2480 switch (filter) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2481 case F_none : cur[k] = raw[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2482 case F_sub : cur[k] = raw[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2483 case F_up : cur[k] = raw[k] + prior[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2484 case F_avg : cur[k] = raw[k] + (prior[k]>>1); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2485 case F_paeth : cur[k] = (uint8) (raw[k] + paeth(0,prior[k],0)); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2486 case F_avg_first : cur[k] = raw[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2487 case F_paeth_first: cur[k] = raw[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2488 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2489 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2490 if (img_n != out_n) cur[img_n] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2491 raw += img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2492 cur += out_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2493 prior += out_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2494 // this is a little gross, so that we don't switch per-pixel or per-component
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2495 if (img_n == out_n) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2496 #define CASE(f) \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2497 case f: \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2498 for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2499 for (k=0; k < img_n; ++k)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2500 switch (filter) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2501 CASE(F_none) cur[k] = raw[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2502 CASE(F_sub) cur[k] = raw[k] + cur[k-img_n]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2503 CASE(F_up) cur[k] = raw[k] + prior[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2504 CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-img_n])>>1); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2505 CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],prior[k],prior[k-img_n])); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2506 CASE(F_avg_first) cur[k] = raw[k] + (cur[k-img_n] >> 1); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2507 CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],0,0)); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2508 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2509 #undef CASE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2510 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2511 assert(img_n+1 == out_n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2512 #define CASE(f) \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2513 case f: \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2514 for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2515 for (k=0; k < img_n; ++k)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2516 switch (filter) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2517 CASE(F_none) cur[k] = raw[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2518 CASE(F_sub) cur[k] = raw[k] + cur[k-out_n]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2519 CASE(F_up) cur[k] = raw[k] + prior[k]; break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2520 CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-out_n])>>1); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2521 CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],prior[k],prior[k-out_n])); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2522 CASE(F_avg_first) cur[k] = raw[k] + (cur[k-out_n] >> 1); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2523 CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],0,0)); break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2524 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2525 #undef CASE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2526 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2527 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2528 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2529 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2530
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2531 static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2532 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2533 uint8 *final;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2534 int p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2535 int save;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2536 if (!interlaced)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2537 return create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2538 save = stbi_png_partial;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2539 stbi_png_partial = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2540
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2541 // de-interlacing
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2542 final = (uint8 *) malloc(a->s->img_x * a->s->img_y * out_n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2543 for (p=0; p < 7; ++p) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2544 int xorig[] = { 0,4,0,2,0,1,0 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2545 int yorig[] = { 0,0,4,0,2,0,1 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2546 int xspc[] = { 8,8,4,4,2,2,1 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2547 int yspc[] = { 8,8,8,4,4,2,2 };
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2548 int i,j,x,y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2549 // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2550 x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2551 y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2552 if (x && y) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2553 if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2554 free(final);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2555 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2556 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2557 for (j=0; j < y; ++j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2558 for (i=0; i < x; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2559 memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2560 a->out + (j*x+i)*out_n, out_n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2561 free(a->out);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2562 raw += (x*out_n+1)*y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2563 raw_len -= (x*out_n+1)*y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2564 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2565 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2566 a->out = final;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2567
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2568 stbi_png_partial = save;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2569 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2570 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2571
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2572 static int compute_transparency(png *z, uint8 tc[3], int out_n)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2573 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2574 stbi *s = z->s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2575 uint32 i, pixel_count = s->img_x * s->img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2576 uint8 *p = z->out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2577
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2578 // compute color-based transparency, assuming we've
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2579 // already got 255 as the alpha value in the output
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2580 assert(out_n == 2 || out_n == 4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2581
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2582 if (out_n == 2) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2583 for (i=0; i < pixel_count; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2584 p[1] = (p[0] == tc[0] ? 0 : 255);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2585 p += 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2586 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2587 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2588 for (i=0; i < pixel_count; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2589 if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2590 p[3] = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2591 p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2592 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2593 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2594 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2595 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2596
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2597 static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2598 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2599 uint32 i, pixel_count = a->s->img_x * a->s->img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2600 uint8 *p, *temp_out, *orig = a->out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2601
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2602 p = (uint8 *) malloc(pixel_count * pal_img_n);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2603 if (p == NULL) return e("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2604
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2605 // between here and free(out) below, exitting would leak
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2606 temp_out = p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2607
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2608 if (pal_img_n == 3) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2609 for (i=0; i < pixel_count; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2610 int n = orig[i]*4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2611 p[0] = palette[n ];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2612 p[1] = palette[n+1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2613 p[2] = palette[n+2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2614 p += 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2615 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2616 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2617 for (i=0; i < pixel_count; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2618 int n = orig[i]*4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2619 p[0] = palette[n ];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2620 p[1] = palette[n+1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2621 p[2] = palette[n+2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2622 p[3] = palette[n+3];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2623 p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2624 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2625 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2626 free(a->out);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2627 a->out = temp_out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2628
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2629 STBI_NOTUSED(len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2630
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2631 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2632 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2633
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2634 static int stbi_unpremultiply_on_load = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2635 static int stbi_de_iphone_flag = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2636
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2637 void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2638 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2639 stbi_unpremultiply_on_load = flag_true_if_should_unpremultiply;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2640 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2641 void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2642 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2643 stbi_de_iphone_flag = flag_true_if_should_convert;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2644 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2645
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2646 static void stbi_de_iphone(png *z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2647 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2648 stbi *s = z->s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2649 uint32 i, pixel_count = s->img_x * s->img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2650 uint8 *p = z->out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2651
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2652 if (s->img_out_n == 3) { // convert bgr to rgb
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2653 for (i=0; i < pixel_count; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2654 uint8 t = p[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2655 p[0] = p[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2656 p[2] = t;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2657 p += 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2658 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2659 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2660 assert(s->img_out_n == 4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2661 if (stbi_unpremultiply_on_load) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2662 // convert bgr to rgb and unpremultiply
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2663 for (i=0; i < pixel_count; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2664 uint8 a = p[3];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2665 uint8 t = p[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2666 if (a) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2667 p[0] = p[2] * 255 / a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2668 p[1] = p[1] * 255 / a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2669 p[2] = t * 255 / a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2670 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2671 p[0] = p[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2672 p[2] = t;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2673 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2674 p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2675 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2676 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2677 // convert bgr to rgb
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2678 for (i=0; i < pixel_count; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2679 uint8 t = p[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2680 p[0] = p[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2681 p[2] = t;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2682 p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2683 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2684 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2685 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2686 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2687
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2688 static int parse_png_file(png *z, int scan, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2689 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2690 uint8 palette[1024], pal_img_n=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2691 uint8 has_trans=0, tc[3];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2692 uint32 ioff=0, idata_limit=0, i, pal_len=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2693 int first=1,k,interlace=0, iphone=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2694 stbi *s = z->s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2695
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2696 z->expanded = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2697 z->idata = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2698 z->out = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2699
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2700 if (!check_png_header(s)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2701
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2702 if (scan == SCAN_type) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2703
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2704 for (;;) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2705 chunk c = get_chunk_header(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2706 switch (c.type) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2707 case PNG_TYPE('C','g','B','I'):
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2708 iphone = stbi_de_iphone_flag;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2709 skip(s, c.length);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2710 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2711 case PNG_TYPE('I','H','D','R'): {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2712 int depth,color,comp,filter;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2713 if (!first) return e("multiple IHDR","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2714 first = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2715 if (c.length != 13) return e("bad IHDR len","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2716 s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2717 s->img_y = get32(s); if (s->img_y > (1 << 24)) return e("too large","Very large image (corrupt?)");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2718 depth = get8(s); if (depth != 8) return e("8bit only","PNG not supported: 8-bit only");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2719 color = get8(s); if (color > 6) return e("bad ctype","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2720 if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2721 comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2722 filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2723 interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2724 if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2725 if (!pal_img_n) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2726 s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2727 if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2728 if (scan == SCAN_header) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2729 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2730 // if paletted, then pal_n is our final components, and
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2731 // img_n is # components to decompress/filter.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2732 s->img_n = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2733 if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2734 // if SCAN_header, have to scan to see if we have a tRNS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2735 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2736 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2737 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2738
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2739 case PNG_TYPE('P','L','T','E'): {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2740 if (first) return e("first not IHDR", "Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2741 if (c.length > 256*3) return e("invalid PLTE","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2742 pal_len = c.length / 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2743 if (pal_len * 3 != c.length) return e("invalid PLTE","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2744 for (i=0; i < pal_len; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2745 palette[i*4+0] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2746 palette[i*4+1] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2747 palette[i*4+2] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2748 palette[i*4+3] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2749 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2750 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2751 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2752
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2753 case PNG_TYPE('t','R','N','S'): {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2754 if (first) return e("first not IHDR", "Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2755 if (z->idata) return e("tRNS after IDAT","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2756 if (pal_img_n) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2757 if (scan == SCAN_header) { s->img_n = 4; return 1; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2758 if (pal_len == 0) return e("tRNS before PLTE","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2759 if (c.length > pal_len) return e("bad tRNS len","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2760 pal_img_n = 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2761 for (i=0; i < c.length; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2762 palette[i*4+3] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2763 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2764 if (!(s->img_n & 1)) return e("tRNS with alpha","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2765 if (c.length != (uint32) s->img_n*2) return e("bad tRNS len","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2766 has_trans = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2767 for (k=0; k < s->img_n; ++k)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2768 tc[k] = (uint8) get16(s); // non 8-bit images will be larger
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2769 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2770 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2771 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2772
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2773 case PNG_TYPE('I','D','A','T'): {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2774 if (first) return e("first not IHDR", "Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2775 if (pal_img_n && !pal_len) return e("no PLTE","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2776 if (scan == SCAN_header) { s->img_n = pal_img_n; return 1; }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2777 if (ioff + c.length > idata_limit) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2778 uint8 *p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2779 if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2780 while (ioff + c.length > idata_limit)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2781 idata_limit *= 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2782 p = (uint8 *) realloc(z->idata, idata_limit); if (p == NULL) return e("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2783 z->idata = p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2784 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2785 if (!getn(s, z->idata+ioff,c.length)) return e("outofdata","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2786 ioff += c.length;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2787 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2788 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2789
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2790 case PNG_TYPE('I','E','N','D'): {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2791 uint32 raw_len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2792 if (first) return e("first not IHDR", "Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2793 if (scan != SCAN_load) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2794 if (z->idata == NULL) return e("no IDAT","Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2795 z->expanded = (uint8 *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, 16384, (int *) &raw_len, !iphone);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2796 if (z->expanded == NULL) return 0; // zlib should set error
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2797 free(z->idata); z->idata = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2798 if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2799 s->img_out_n = s->img_n+1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2800 else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2801 s->img_out_n = s->img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2802 if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2803 if (has_trans)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2804 if (!compute_transparency(z, tc, s->img_out_n)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2805 if (iphone && s->img_out_n > 2)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2806 stbi_de_iphone(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2807 if (pal_img_n) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2808 // pal_img_n == 3 or 4
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2809 s->img_n = pal_img_n; // record the actual colors we had
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2810 s->img_out_n = pal_img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2811 if (req_comp >= 3) s->img_out_n = req_comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2812 if (!expand_palette(z, palette, pal_len, s->img_out_n))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2813 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2814 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2815 free(z->expanded); z->expanded = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2816 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2817 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2818
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2819 default:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2820 // if critical, fail
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2821 if (first) return e("first not IHDR", "Corrupt PNG");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2822 if ((c.type & (1 << 29)) == 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2823 #ifndef STBI_NO_FAILURE_STRINGS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2824 // not threadsafe
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2825 static char invalid_chunk[] = "XXXX chunk not known";
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2826 invalid_chunk[0] = (uint8) (c.type >> 24);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2827 invalid_chunk[1] = (uint8) (c.type >> 16);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2828 invalid_chunk[2] = (uint8) (c.type >> 8);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2829 invalid_chunk[3] = (uint8) (c.type >> 0);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2830 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2831 return e(invalid_chunk, "PNG not supported: unknown chunk type");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2832 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2833 skip(s, c.length);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2834 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2835 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2836 // end of chunk, read and skip CRC
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2837 get32(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2838 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2839 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2840
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2841 static unsigned char *do_png(png *p, int *x, int *y, int *n, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2842 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2843 unsigned char *result=NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2844 if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2845 if (parse_png_file(p, SCAN_load, req_comp)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2846 result = p->out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2847 p->out = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2848 if (req_comp && req_comp != p->s->img_out_n) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2849 result = convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2850 p->s->img_out_n = req_comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2851 if (result == NULL) return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2852 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2853 *x = p->s->img_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2854 *y = p->s->img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2855 if (n) *n = p->s->img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2856 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2857 free(p->out); p->out = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2858 free(p->expanded); p->expanded = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2859 free(p->idata); p->idata = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2860
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2861 return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2862 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2863
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2864 static unsigned char *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2865 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2866 png p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2867 p.s = s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2868 return do_png(&p, x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2869 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2870
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2871 static int stbi_png_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2872 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2873 int r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2874 r = check_png_header(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2875 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2876 return r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2877 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2878
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2879 static int stbi_png_info_raw(png *p, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2880 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2881 if (!parse_png_file(p, SCAN_header, 0)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2882 stbi_rewind( p->s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2883 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2884 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2885 if (x) *x = p->s->img_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2886 if (y) *y = p->s->img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2887 if (comp) *comp = p->s->img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2888 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2889 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2890
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2891 static int stbi_png_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2892 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2893 png p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2894 p.s = s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2895 return stbi_png_info_raw(&p, x, y, comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2896 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2897
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2898 #ifdef STBI_CRAP_FORMATS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2899
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2900 // Microsoft/Windows BMP image
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2901
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2902 static int bmp_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2903 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2904 int sz;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2905 if (get8(s) != 'B') return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2906 if (get8(s) != 'M') return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2907 get32le(s); // discard filesize
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2908 get16le(s); // discard reserved
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2909 get16le(s); // discard reserved
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2910 get32le(s); // discard data offset
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2911 sz = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2912 if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2913 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2914 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2915
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2916 static int stbi_bmp_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2917 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2918 int r = bmp_test(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2919 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2920 return r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2921 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2922
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2923
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2924 // returns 0..31 for the highest set bit
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2925 static int high_bit(unsigned int z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2926 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2927 int n=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2928 if (z == 0) return -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2929 if (z >= 0x10000) n += 16, z >>= 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2930 if (z >= 0x00100) n += 8, z >>= 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2931 if (z >= 0x00010) n += 4, z >>= 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2932 if (z >= 0x00004) n += 2, z >>= 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2933 if (z >= 0x00002) n += 1, z >>= 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2934 return n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2935 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2936
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2937 static int bitcount(unsigned int a)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2938 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2939 a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2940 a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2941 a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2942 a = (a + (a >> 8)); // max 16 per 8 bits
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2943 a = (a + (a >> 16)); // max 32 per 8 bits
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2944 return a & 0xff;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2945 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2946
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2947 static int shiftsigned(int v, int shift, int bits)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2948 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2949 int result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2950 int z=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2951
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2952 if (shift < 0) v <<= -shift;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2953 else v >>= shift;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2954 result = v;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2955
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2956 z = bits;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2957 while (z < 8) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2958 result += v >> z;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2959 z += bits;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2960 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2961 return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2962 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2963
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2964 static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2965 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2966 uint8 *out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2967 unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2968 stbi_uc pal[256][4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2969 int psize=0,i,j,compress=0,width;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2970 int bpp, flip_vertically, pad, target, offset, hsz;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2971 if (get8(s) != 'B' || get8(s) != 'M') return epuc("not BMP", "Corrupt BMP");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2972 get32le(s); // discard filesize
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2973 get16le(s); // discard reserved
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2974 get16le(s); // discard reserved
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2975 offset = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2976 hsz = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2977 if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return epuc("unknown BMP", "BMP type not supported: unknown");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2978 if (hsz == 12) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2979 s->img_x = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2980 s->img_y = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2981 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2982 s->img_x = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2983 s->img_y = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2984 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2985 if (get16le(s) != 1) return epuc("bad BMP", "bad BMP");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2986 bpp = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2987 if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2988 flip_vertically = ((int) s->img_y) > 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2989 s->img_y = abs((int) s->img_y);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2990 if (hsz == 12) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2991 if (bpp < 24)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2992 psize = (offset - 14 - 24) / 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2993 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2994 compress = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2995 if (compress == 1 || compress == 2) return epuc("BMP RLE", "BMP type not supported: RLE");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2996 get32le(s); // discard sizeof
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2997 get32le(s); // discard hres
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2998 get32le(s); // discard vres
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
2999 get32le(s); // discard colorsused
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3000 get32le(s); // discard max important
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3001 if (hsz == 40 || hsz == 56) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3002 if (hsz == 56) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3003 get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3004 get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3005 get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3006 get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3007 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3008 if (bpp == 16 || bpp == 32) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3009 mr = mg = mb = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3010 if (compress == 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3011 if (bpp == 32) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3012 mr = 0xffu << 16;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3013 mg = 0xffu << 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3014 mb = 0xffu << 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3015 ma = 0xffu << 24;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3016 fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3017 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3018 mr = 31u << 10;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3019 mg = 31u << 5;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3020 mb = 31u << 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3021 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3022 } else if (compress == 3) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3023 mr = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3024 mg = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3025 mb = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3026 // not documented, but generated by photoshop and handled by mspaint
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3027 if (mr == mg && mg == mb) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3028 // ?!?!?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3029 return epuc("bad BMP", "bad BMP");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3030 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3031 } else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3032 return epuc("bad BMP", "bad BMP");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3033 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3034 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3035 assert(hsz == 108);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3036 mr = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3037 mg = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3038 mb = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3039 ma = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3040 get32le(s); // discard color space
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3041 for (i=0; i < 12; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3042 get32le(s); // discard color space parameters
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3043 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3044 if (bpp < 16)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3045 psize = (offset - 14 - hsz) >> 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3046 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3047 s->img_n = ma ? 4 : 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3048 if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3049 target = req_comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3050 else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3051 target = s->img_n; // if they want monochrome, we'll post-convert
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3052 out = (stbi_uc *) malloc(target * s->img_x * s->img_y);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3053 if (!out) return epuc("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3054 if (bpp < 16) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3055 int z=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3056 if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP"); }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3057 for (i=0; i < psize; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3058 pal[i][2] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3059 pal[i][1] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3060 pal[i][0] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3061 if (hsz != 12) get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3062 pal[i][3] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3063 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3064 skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3065 if (bpp == 4) width = (s->img_x + 1) >> 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3066 else if (bpp == 8) width = s->img_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3067 else { free(out); return epuc("bad bpp", "Corrupt BMP"); }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3068 pad = (-width)&3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3069 for (j=0; j < (int) s->img_y; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3070 for (i=0; i < (int) s->img_x; i += 2) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3071 int v=get8(s),v2=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3072 if (bpp == 4) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3073 v2 = v & 15;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3074 v >>= 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3075 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3076 out[z++] = pal[v][0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3077 out[z++] = pal[v][1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3078 out[z++] = pal[v][2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3079 if (target == 4) out[z++] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3080 if (i+1 == (int) s->img_x) break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3081 v = (bpp == 8) ? get8(s) : v2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3082 out[z++] = pal[v][0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3083 out[z++] = pal[v][1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3084 out[z++] = pal[v][2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3085 if (target == 4) out[z++] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3086 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3087 skip(s, pad);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3088 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3089 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3090 int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3091 int z = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3092 int easy=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3093 skip(s, offset - 14 - hsz);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3094 if (bpp == 24) width = 3 * s->img_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3095 else if (bpp == 16) width = 2*s->img_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3096 else /* bpp = 32 and pad = 0 */ width=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3097 pad = (-width) & 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3098 if (bpp == 24) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3099 easy = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3100 } else if (bpp == 32) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3101 if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3102 easy = 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3103 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3104 if (!easy) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3105 if (!mr || !mg || !mb) { free(out); return epuc("bad masks", "Corrupt BMP"); }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3106 // right shift amt to put high bit in position #7
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3107 rshift = high_bit(mr)-7; rcount = bitcount(mr);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3108 gshift = high_bit(mg)-7; gcount = bitcount(mr);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3109 bshift = high_bit(mb)-7; bcount = bitcount(mr);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3110 ashift = high_bit(ma)-7; acount = bitcount(mr);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3111 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3112 for (j=0; j < (int) s->img_y; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3113 if (easy) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3114 for (i=0; i < (int) s->img_x; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3115 int a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3116 out[z+2] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3117 out[z+1] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3118 out[z+0] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3119 z += 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3120 a = (easy == 2 ? get8(s) : 255);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3121 if (target == 4) out[z++] = (uint8) a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3122 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3123 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3124 for (i=0; i < (int) s->img_x; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3125 uint32 v = (bpp == 16 ? get16le(s) : get32le(s));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3126 int a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3127 out[z++] = (uint8) shiftsigned(v & mr, rshift, rcount);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3128 out[z++] = (uint8) shiftsigned(v & mg, gshift, gcount);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3129 out[z++] = (uint8) shiftsigned(v & mb, bshift, bcount);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3130 a = (ma ? shiftsigned(v & ma, ashift, acount) : 255);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3131 if (target == 4) out[z++] = (uint8) a;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3132 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3133 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3134 skip(s, pad);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3135 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3136 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3137 if (flip_vertically) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3138 stbi_uc t;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3139 for (j=0; j < (int) s->img_y>>1; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3140 stbi_uc *p1 = out + j *s->img_x*target;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3141 stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3142 for (i=0; i < (int) s->img_x*target; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3143 t = p1[i], p1[i] = p2[i], p2[i] = t;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3144 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3145 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3146 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3147
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3148 if (req_comp && req_comp != target) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3149 out = convert_format(out, target, req_comp, s->img_x, s->img_y);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3150 if (out == NULL) return out; // convert_format frees input on failure
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3151 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3152
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3153 *x = s->img_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3154 *y = s->img_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3155 if (comp) *comp = s->img_n;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3156 return out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3157 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3158
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3159 static stbi_uc *stbi_bmp_load(stbi *s,int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3160 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3161 return bmp_load(s, x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3162 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3163
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3164
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3165 // Targa Truevision - TGA
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3166 // by Jonathan Dummer
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3167
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3168 static int tga_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3169 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3170 int tga_w, tga_h, tga_comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3171 int sz;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3172 get8u(s); // discard Offset
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3173 sz = get8u(s); // color type
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3174 if( sz > 1 ) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3175 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3176 return 0; // only RGB or indexed allowed
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3177 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3178 sz = get8u(s); // image type
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3179 // only RGB or grey allowed, +/- RLE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3180 if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3181 skip(s,9);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3182 tga_w = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3183 if( tga_w < 1 ) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3184 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3185 return 0; // test width
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3186 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3187 tga_h = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3188 if( tga_h < 1 ) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3189 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3190 return 0; // test height
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3191 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3192 sz = get8(s); // bits per pixel
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3193 // only RGB or RGBA or grey allowed
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3194 if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3195 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3196 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3197 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3198 tga_comp = sz;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3199 if (x) *x = tga_w;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3200 if (y) *y = tga_h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3201 if (comp) *comp = tga_comp / 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3202 return 1; // seems to have passed everything
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3203 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3204
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3205 int stbi_tga_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3206 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3207 return tga_info(s, x, y, comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3208 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3209
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3210 static int tga_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3211 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3212 int sz;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3213 get8u(s); // discard Offset
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3214 sz = get8u(s); // color type
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3215 if ( sz > 1 ) return 0; // only RGB or indexed allowed
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3216 sz = get8u(s); // image type
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3217 if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3218 get16(s); // discard palette start
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3219 get16(s); // discard palette length
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3220 get8(s); // discard bits per palette color entry
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3221 get16(s); // discard x origin
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3222 get16(s); // discard y origin
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3223 if ( get16(s) < 1 ) return 0; // test width
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3224 if ( get16(s) < 1 ) return 0; // test height
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3225 sz = get8(s); // bits per pixel
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3226 if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) return 0; // only RGB or RGBA or grey allowed
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3227 return 1; // seems to have passed everything
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3228 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3229
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3230 static int stbi_tga_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3231 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3232 int res = tga_test(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3233 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3234 return res;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3235 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3236
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3237 static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3238 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3239 // read in the TGA header stuff
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3240 int tga_offset = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3241 int tga_indexed = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3242 int tga_image_type = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3243 int tga_is_RLE = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3244 int tga_palette_start = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3245 int tga_palette_len = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3246 int tga_palette_bits = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3247 int tga_x_origin = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3248 int tga_y_origin = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3249 int tga_width = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3250 int tga_height = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3251 int tga_bits_per_pixel = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3252 int tga_inverted = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3253 // image data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3254 unsigned char *tga_data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3255 unsigned char *tga_palette = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3256 int i, j;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3257 unsigned char raw_data[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3258 unsigned char trans_data[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3259 int RLE_count = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3260 int RLE_repeating = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3261 int read_next_pixel = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3262
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3263 // do a tiny bit of precessing
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3264 if ( tga_image_type >= 8 )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3265 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3266 tga_image_type -= 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3267 tga_is_RLE = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3268 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3269 // int tga_alpha_bits = tga_inverted & 15;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3270 tga_inverted = 1 - ((tga_inverted >> 5) & 1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3271
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3272 // error check
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3273 if ( //(tga_indexed) ||
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3274 (tga_width < 1) || (tga_height < 1) ||
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3275 (tga_image_type < 1) || (tga_image_type > 3) ||
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3276 ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) &&
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3277 (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3278 )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3279 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3280 return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3281 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3282
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3283 // If I'm paletted, then I'll use the number of bits from the palette
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3284 if ( tga_indexed )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3285 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3286 tga_bits_per_pixel = tga_palette_bits;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3287 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3288
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3289 // tga info
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3290 *x = tga_width;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3291 *y = tga_height;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3292 if ( (req_comp < 1) || (req_comp > 4) )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3293 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3294 // just use whatever the file was
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3295 req_comp = tga_bits_per_pixel / 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3296 *comp = req_comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3297 } else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3298 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3299 // force a new number of components
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3300 *comp = tga_bits_per_pixel/8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3301 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3302 tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3303 if (!tga_data) return epuc("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3304
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3305 // skip to the data's starting position (offset usually = 0)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3306 skip(s, tga_offset );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3307 // do I need to load a palette?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3308 if ( tga_indexed )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3309 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3310 // any data to skip? (offset usually = 0)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3311 skip(s, tga_palette_start );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3312 // load the palette
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3313 tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3314 if (!tga_palette) return epuc("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3315 if (!getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3316 free(tga_data);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3317 free(tga_palette);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3318 return epuc("bad palette", "Corrupt TGA");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3319 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3320 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3321 // load the data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3322 trans_data[0] = trans_data[1] = trans_data[2] = trans_data[3] = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3323 for (i=0; i < tga_width * tga_height; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3324 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3325 // if I'm in RLE mode, do I need to get a RLE chunk?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3326 if ( tga_is_RLE )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3327 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3328 if ( RLE_count == 0 )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3329 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3330 // yep, get the next byte as a RLE command
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3331 int RLE_cmd = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3332 RLE_count = 1 + (RLE_cmd & 127);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3333 RLE_repeating = RLE_cmd >> 7;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3334 read_next_pixel = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3335 } else if ( !RLE_repeating )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3336 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3337 read_next_pixel = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3338 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3339 } else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3340 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3341 read_next_pixel = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3342 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3343 // OK, if I need to read a pixel, do it now
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3344 if ( read_next_pixel )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3345 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3346 // load however much data we did have
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3347 if ( tga_indexed )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3348 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3349 // read in 1 byte, then perform the lookup
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3350 int pal_idx = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3351 if ( pal_idx >= tga_palette_len )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3352 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3353 // invalid index
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3354 pal_idx = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3355 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3356 pal_idx *= tga_bits_per_pixel / 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3357 for (j = 0; j*8 < tga_bits_per_pixel; ++j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3358 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3359 raw_data[j] = tga_palette[pal_idx+j];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3360 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3361 } else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3362 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3363 // read in the data raw
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3364 for (j = 0; j*8 < tga_bits_per_pixel; ++j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3365 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3366 raw_data[j] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3367 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3368 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3369 // convert raw to the intermediate format
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3370 switch (tga_bits_per_pixel)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3371 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3372 case 8:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3373 // Luminous => RGBA
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3374 trans_data[0] = raw_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3375 trans_data[1] = raw_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3376 trans_data[2] = raw_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3377 trans_data[3] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3378 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3379 case 16:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3380 // Luminous,Alpha => RGBA
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3381 trans_data[0] = raw_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3382 trans_data[1] = raw_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3383 trans_data[2] = raw_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3384 trans_data[3] = raw_data[1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3385 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3386 case 24:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3387 // BGR => RGBA
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3388 trans_data[0] = raw_data[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3389 trans_data[1] = raw_data[1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3390 trans_data[2] = raw_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3391 trans_data[3] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3392 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3393 case 32:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3394 // BGRA => RGBA
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3395 trans_data[0] = raw_data[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3396 trans_data[1] = raw_data[1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3397 trans_data[2] = raw_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3398 trans_data[3] = raw_data[3];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3399 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3400 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3401 // clear the reading flag for the next pixel
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3402 read_next_pixel = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3403 } // end of reading a pixel
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3404 // convert to final format
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3405 switch (req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3406 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3407 case 1:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3408 // RGBA => Luminance
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3409 tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3410 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3411 case 2:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3412 // RGBA => Luminance,Alpha
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3413 tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3414 tga_data[i*req_comp+1] = trans_data[3];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3415 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3416 case 3:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3417 // RGBA => RGB
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3418 tga_data[i*req_comp+0] = trans_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3419 tga_data[i*req_comp+1] = trans_data[1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3420 tga_data[i*req_comp+2] = trans_data[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3421 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3422 case 4:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3423 // RGBA => RGBA
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3424 tga_data[i*req_comp+0] = trans_data[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3425 tga_data[i*req_comp+1] = trans_data[1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3426 tga_data[i*req_comp+2] = trans_data[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3427 tga_data[i*req_comp+3] = trans_data[3];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3428 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3429 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3430 // in case we're in RLE mode, keep counting down
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3431 --RLE_count;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3432 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3433 // do I need to invert the image?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3434 if ( tga_inverted )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3435 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3436 for (j = 0; j*2 < tga_height; ++j)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3437 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3438 int index1 = j * tga_width * req_comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3439 int index2 = (tga_height - 1 - j) * tga_width * req_comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3440 for (i = tga_width * req_comp; i > 0; --i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3441 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3442 unsigned char temp = tga_data[index1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3443 tga_data[index1] = tga_data[index2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3444 tga_data[index2] = temp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3445 ++index1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3446 ++index2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3447 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3448 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3449 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3450 // clear my palette, if I had one
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3451 if ( tga_palette != NULL )
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3452 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3453 free( tga_palette );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3454 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3455 // the things I do to get rid of an error message, and yet keep
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3456 // Microsoft's C compilers happy... [8^(
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3457 tga_palette_start = tga_palette_len = tga_palette_bits =
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3458 tga_x_origin = tga_y_origin = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3459 // OK, done
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3460 return tga_data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3461 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3462
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3463 static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3464 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3465 return tga_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3466 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3467
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3468
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3469 // *************************************************************************************************
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3470 // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3471
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3472 static int psd_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3473 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3474 if (get32(s) != 0x38425053) return 0; // "8BPS"
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3475 else return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3476 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3477
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3478 static int stbi_psd_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3479 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3480 int r = psd_test(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3481 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3482 return r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3483 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3484
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3485 static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3486 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3487 int pixelCount;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3488 int channelCount, compression;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3489 int channel, i, count, len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3490 int w,h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3491 uint8 *out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3492
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3493 // Check identifier
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3494 if (get32(s) != 0x38425053) // "8BPS"
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3495 return epuc("not PSD", "Corrupt PSD image");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3496
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3497 // Check file type version.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3498 if (get16(s) != 1)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3499 return epuc("wrong version", "Unsupported version of PSD image");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3500
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3501 // Skip 6 reserved bytes.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3502 skip(s, 6 );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3503
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3504 // Read the number of channels (R, G, B, A, etc).
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3505 channelCount = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3506 if (channelCount < 0 || channelCount > 16)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3507 return epuc("wrong channel count", "Unsupported number of channels in PSD image");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3508
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3509 // Read the rows and columns of the image.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3510 h = get32(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3511 w = get32(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3512
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3513 // Make sure the depth is 8 bits.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3514 if (get16(s) != 8)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3515 return epuc("unsupported bit depth", "PSD bit depth is not 8 bit");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3516
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3517 // Make sure the color mode is RGB.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3518 // Valid options are:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3519 // 0: Bitmap
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3520 // 1: Grayscale
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3521 // 2: Indexed color
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3522 // 3: RGB color
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3523 // 4: CMYK color
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3524 // 7: Multichannel
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3525 // 8: Duotone
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3526 // 9: Lab color
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3527 if (get16(s) != 3)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3528 return epuc("wrong color format", "PSD is not in RGB color format");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3529
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3530 // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3531 skip(s,get32(s) );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3532
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3533 // Skip the image resources. (resolution, pen tool paths, etc)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3534 skip(s, get32(s) );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3535
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3536 // Skip the reserved data.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3537 skip(s, get32(s) );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3538
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3539 // Find out if the data is compressed.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3540 // Known values:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3541 // 0: no compression
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3542 // 1: RLE compressed
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3543 compression = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3544 if (compression > 1)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3545 return epuc("bad compression", "PSD has an unknown compression format");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3546
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3547 // Create the destination image.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3548 out = (stbi_uc *) malloc(4 * w*h);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3549 if (!out) return epuc("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3550 pixelCount = w*h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3551
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3552 // Initialize the data to zero.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3553 //memset( out, 0, pixelCount * 4 );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3554
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3555 // Finally, the image data.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3556 if (compression) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3557 // RLE as used by .PSD and .TIFF
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3558 // Loop until you get the number of unpacked bytes you are expecting:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3559 // Read the next source byte into n.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3560 // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3561 // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3562 // Else if n is 128, noop.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3563 // Endloop
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3564
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3565 // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3566 // which we're going to just skip.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3567 skip(s, h * channelCount * 2 );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3568
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3569 // Read the RLE data by channel.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3570 for (channel = 0; channel < 4; channel++) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3571 uint8 *p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3572
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3573 p = out+channel;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3574 if (channel >= channelCount) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3575 // Fill this channel with default data.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3576 for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3577 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3578 // Read the RLE data.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3579 count = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3580 while (count < pixelCount) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3581 len = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3582 if (len == 128) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3583 // No-op.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3584 } else if (len < 128) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3585 // Copy next len+1 bytes literally.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3586 len++;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3587 count += len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3588 while (len) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3589 *p = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3590 p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3591 len--;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3592 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3593 } else if (len > 128) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3594 uint8 val;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3595 // Next -len+1 bytes in the dest are replicated from next source byte.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3596 // (Interpret len as a negative 8-bit int.)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3597 len ^= 0x0FF;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3598 len += 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3599 val = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3600 count += len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3601 while (len) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3602 *p = val;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3603 p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3604 len--;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3605 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3606 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3607 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3608 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3609 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3610
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3611 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3612 // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3613 // where each channel consists of an 8-bit value for each pixel in the image.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3614
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3615 // Read the data by channel.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3616 for (channel = 0; channel < 4; channel++) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3617 uint8 *p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3618
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3619 p = out + channel;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3620 if (channel > channelCount) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3621 // Fill this channel with default data.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3622 for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3623 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3624 // Read the data.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3625 for (i = 0; i < pixelCount; i++)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3626 *p = get8u(s), p += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3627 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3628 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3629 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3630
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3631 if (req_comp && req_comp != 4) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3632 out = convert_format(out, 4, req_comp, w, h);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3633 if (out == NULL) return out; // convert_format frees input on failure
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3634 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3635
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3636 if (comp) *comp = channelCount;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3637 *y = h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3638 *x = w;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3639
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3640 return out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3641 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3642
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3643 static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3644 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3645 return psd_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3646 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3647
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3648 // *************************************************************************************************
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3649 // Softimage PIC loader
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3650 // by Tom Seddon
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3651 //
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3652 // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3653 // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3654
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3655 static int pic_is4(stbi *s,const char *str)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3656 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3657 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3658 for (i=0; i<4; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3659 if (get8(s) != (stbi_uc)str[i])
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3660 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3661
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3662 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3663 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3664
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3665 static int pic_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3666 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3667 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3668
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3669 if (!pic_is4(s,"\x53\x80\xF6\x34"))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3670 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3671
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3672 for(i=0;i<84;++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3673 get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3674
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3675 if (!pic_is4(s,"PICT"))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3676 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3677
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3678 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3679 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3680
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3681 typedef struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3682 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3683 stbi_uc size,type,channel;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3684 } pic_packet_t;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3685
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3686 static stbi_uc *pic_readval(stbi *s, int channel, stbi_uc *dest)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3687 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3688 int mask=0x80, i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3689
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3690 for (i=0; i<4; ++i, mask>>=1) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3691 if (channel & mask) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3692 if (at_eof(s)) return epuc("bad file","PIC file too short");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3693 dest[i]=get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3694 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3695 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3696
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3697 return dest;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3698 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3699
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3700 static void pic_copyval(int channel,stbi_uc *dest,const stbi_uc *src)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3701 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3702 int mask=0x80,i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3703
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3704 for (i=0;i<4; ++i, mask>>=1)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3705 if (channel&mask)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3706 dest[i]=src[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3707 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3708
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3709 static stbi_uc *pic_load2(stbi *s,int width,int height,int *comp, stbi_uc *result)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3710 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3711 int act_comp=0,num_packets=0,y,chained;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3712 pic_packet_t packets[10];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3713
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3714 // this will (should...) cater for even some bizarre stuff like having data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3715 // for the same channel in multiple packets.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3716 do {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3717 pic_packet_t *packet;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3718
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3719 if (num_packets==sizeof(packets)/sizeof(packets[0]))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3720 return epuc("bad format","too many packets");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3721
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3722 packet = &packets[num_packets++];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3723
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3724 chained = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3725 packet->size = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3726 packet->type = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3727 packet->channel = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3728
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3729 act_comp |= packet->channel;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3730
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3731 if (at_eof(s)) return epuc("bad file","file too short (reading packets)");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3732 if (packet->size != 8) return epuc("bad format","packet isn't 8bpp");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3733 } while (chained);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3734
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3735 *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3736
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3737 for(y=0; y<height; ++y) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3738 int packet_idx;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3739
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3740 for(packet_idx=0; packet_idx < num_packets; ++packet_idx) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3741 pic_packet_t *packet = &packets[packet_idx];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3742 stbi_uc *dest = result+y*width*4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3743
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3744 switch (packet->type) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3745 default:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3746 return epuc("bad format","packet has bad compression type");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3747
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3748 case 0: {//uncompressed
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3749 int x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3750
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3751 for(x=0;x<width;++x, dest+=4)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3752 if (!pic_readval(s,packet->channel,dest))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3753 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3754 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3755 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3756
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3757 case 1://Pure RLE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3758 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3759 int left=width, i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3760
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3761 while (left>0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3762 stbi_uc count,value[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3763
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3764 count=get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3765 if (at_eof(s)) return epuc("bad file","file too short (pure read count)");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3766
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3767 if (count > left)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3768 count = (uint8) left;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3769
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3770 if (!pic_readval(s,packet->channel,value)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3771
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3772 for(i=0; i<count; ++i,dest+=4)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3773 pic_copyval(packet->channel,dest,value);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3774 left -= count;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3775 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3776 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3777 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3778
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3779 case 2: {//Mixed RLE
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3780 int left=width;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3781 while (left>0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3782 int count = get8(s), i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3783 if (at_eof(s)) return epuc("bad file","file too short (mixed read count)");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3784
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3785 if (count >= 128) { // Repeated
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3786 stbi_uc value[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3787 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3788
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3789 if (count==128)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3790 count = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3791 else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3792 count -= 127;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3793 if (count > left)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3794 return epuc("bad file","scanline overrun");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3795
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3796 if (!pic_readval(s,packet->channel,value))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3797 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3798
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3799 for(i=0;i<count;++i, dest += 4)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3800 pic_copyval(packet->channel,dest,value);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3801 } else { // Raw
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3802 ++count;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3803 if (count>left) return epuc("bad file","scanline overrun");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3804
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3805 for(i=0;i<count;++i, dest+=4)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3806 if (!pic_readval(s,packet->channel,dest))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3807 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3808 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3809 left-=count;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3810 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3811 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3812 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3813 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3814 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3815 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3816
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3817 return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3818 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3819
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3820 static stbi_uc *pic_load(stbi *s,int *px,int *py,int *comp,int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3821 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3822 stbi_uc *result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3823 int i, x,y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3824
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3825 for (i=0; i<92; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3826 get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3827
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3828 x = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3829 y = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3830 if (at_eof(s)) return epuc("bad file","file too short (pic header)");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3831 if ((1 << 28) / x < y) return epuc("too large", "Image too large to decode");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3832
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3833 get32(s); //skip `ratio'
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3834 get16(s); //skip `fields'
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3835 get16(s); //skip `pad'
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3836
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3837 // intermediate buffer is RGBA
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3838 result = (stbi_uc *) malloc(x*y*4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3839 memset(result, 0xff, x*y*4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3840
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3841 if (!pic_load2(s,x,y,comp, result)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3842 free(result);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3843 result=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3844 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3845 *px = x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3846 *py = y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3847 if (req_comp == 0) req_comp = *comp;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3848 result=convert_format(result,4,req_comp,x,y);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3849
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3850 return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3851 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3852
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3853 static int stbi_pic_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3854 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3855 int r = pic_test(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3856 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3857 return r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3858 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3859
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3860 static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3861 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3862 return pic_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3863 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3864
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3865 // *************************************************************************************************
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3866 // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3867 typedef struct stbi_gif_lzw_struct {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3868 int16 prefix;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3869 uint8 first;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3870 uint8 suffix;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3871 } stbi_gif_lzw;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3872
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3873 typedef struct stbi_gif_struct
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3874 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3875 int w,h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3876 stbi_uc *out; // output buffer (always 4 components)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3877 int flags, bgindex, ratio, transparent, eflags;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3878 uint8 pal[256][4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3879 uint8 lpal[256][4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3880 stbi_gif_lzw codes[4096];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3881 uint8 *color_table;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3882 int parse, step;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3883 int lflags;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3884 int start_x, start_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3885 int max_x, max_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3886 int cur_x, cur_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3887 int line_size;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3888 } stbi_gif;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3889
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3890 static int gif_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3891 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3892 int sz;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3893 if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3894 sz = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3895 if (sz != '9' && sz != '7') return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3896 if (get8(s) != 'a') return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3897 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3898 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3899
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3900 static int stbi_gif_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3901 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3902 int r = gif_test(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3903 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3904 return r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3905 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3906
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3907 static void stbi_gif_parse_colortable(stbi *s, uint8 pal[256][4], int num_entries, int transp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3908 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3909 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3910 for (i=0; i < num_entries; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3911 pal[i][2] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3912 pal[i][1] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3913 pal[i][0] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3914 pal[i][3] = transp ? 0 : 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3915 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3916 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3917
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3918 static int stbi_gif_header(stbi *s, stbi_gif *g, int *comp, int is_info)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3919 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3920 uint8 version;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3921 if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8')
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3922 return e("not GIF", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3923
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3924 version = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3925 if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3926 if (get8(s) != 'a') return e("not GIF", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3927
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3928 failure_reason = "";
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3929 g->w = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3930 g->h = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3931 g->flags = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3932 g->bgindex = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3933 g->ratio = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3934 g->transparent = -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3935
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3936 if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3937
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3938 if (is_info) return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3939
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3940 if (g->flags & 0x80)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3941 stbi_gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3942
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3943 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3944 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3945
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3946 static int stbi_gif_info_raw(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3947 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3948 stbi_gif g;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3949 if (!stbi_gif_header(s, &g, comp, 1)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3950 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3951 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3952 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3953 if (x) *x = g.w;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3954 if (y) *y = g.h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3955 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3956 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3957
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3958 static void stbi_out_gif_code(stbi_gif *g, uint16 code)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3959 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3960 uint8 *p, *c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3961
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3962 // recurse to decode the prefixes, since the linked-list is backwards,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3963 // and working backwards through an interleaved image would be nasty
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3964 if (g->codes[code].prefix >= 0)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3965 stbi_out_gif_code(g, g->codes[code].prefix);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3966
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3967 if (g->cur_y >= g->max_y) return;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3968
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3969 p = &g->out[g->cur_x + g->cur_y];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3970 c = &g->color_table[g->codes[code].suffix * 4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3971
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3972 if (c[3] >= 128) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3973 p[0] = c[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3974 p[1] = c[1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3975 p[2] = c[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3976 p[3] = c[3];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3977 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3978 g->cur_x += 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3979
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3980 if (g->cur_x >= g->max_x) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3981 g->cur_x = g->start_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3982 g->cur_y += g->step;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3983
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3984 while (g->cur_y >= g->max_y && g->parse > 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3985 g->step = (1 << g->parse) * g->line_size;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3986 g->cur_y = g->start_y + (g->step >> 1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3987 --g->parse;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3988 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3989 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3990 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3991
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3992 static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3993 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3994 uint8 lzw_cs;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3995 int32 len, code;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3996 uint32 first;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3997 int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3998 stbi_gif_lzw *p;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
3999
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4000 lzw_cs = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4001 clear = 1 << lzw_cs;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4002 first = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4003 codesize = lzw_cs + 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4004 codemask = (1 << codesize) - 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4005 bits = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4006 valid_bits = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4007 for (code = 0; code < clear; code++) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4008 g->codes[code].prefix = -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4009 g->codes[code].first = (uint8) code;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4010 g->codes[code].suffix = (uint8) code;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4011 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4012
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4013 // support no starting clear code
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4014 avail = clear+2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4015 oldcode = -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4016
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4017 len = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4018 for(;;) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4019 if (valid_bits < codesize) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4020 if (len == 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4021 len = get8(s); // start new block
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4022 if (len == 0)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4023 return g->out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4024 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4025 --len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4026 bits |= (int32) get8(s) << valid_bits;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4027 valid_bits += 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4028 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4029 int32 code = bits & codemask;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4030 bits >>= codesize;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4031 valid_bits -= codesize;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4032 // @OPTIMIZE: is there some way we can accelerate the non-clear path?
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4033 if (code == clear) { // clear code
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4034 codesize = lzw_cs + 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4035 codemask = (1 << codesize) - 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4036 avail = clear + 2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4037 oldcode = -1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4038 first = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4039 } else if (code == clear + 1) { // end of stream code
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4040 skip(s, len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4041 while ((len = get8(s)) > 0)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4042 skip(s,len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4043 return g->out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4044 } else if (code <= avail) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4045 if (first) return epuc("no clear code", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4046
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4047 if (oldcode >= 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4048 p = &g->codes[avail++];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4049 if (avail > 4096) return epuc("too many codes", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4050 p->prefix = (int16) oldcode;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4051 p->first = g->codes[oldcode].first;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4052 p->suffix = (code == avail) ? p->first : g->codes[code].first;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4053 } else if (code == avail)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4054 return epuc("illegal code in raster", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4055
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4056 stbi_out_gif_code(g, (uint16) code);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4057
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4058 if ((avail & codemask) == 0 && avail <= 0x0FFF) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4059 codesize++;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4060 codemask = (1 << codesize) - 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4061 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4062
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4063 oldcode = code;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4064 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4065 return epuc("illegal code in raster", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4066 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4067 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4068 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4069 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4070
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4071 static void stbi_fill_gif_background(stbi_gif *g)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4072 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4073 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4074 uint8 *c = g->pal[g->bgindex];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4075 // @OPTIMIZE: write a dword at a time
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4076 for (i = 0; i < g->w * g->h * 4; i += 4) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4077 uint8 *p = &g->out[i];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4078 p[0] = c[2];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4079 p[1] = c[1];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4080 p[2] = c[0];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4081 p[3] = c[3];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4082 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4083 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4084
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4085 // this function is designed to support animated gifs, although stb_image doesn't support it
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4086 static uint8 *stbi_gif_load_next(stbi *s, stbi_gif *g, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4087 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4088 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4089 uint8 *old_out = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4090
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4091 if (g->out == 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4092 if (!stbi_gif_header(s, g, comp,0)) return 0; // failure_reason set by stbi_gif_header
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4093 g->out = (uint8 *) malloc(4 * g->w * g->h);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4094 if (g->out == 0) return epuc("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4095 stbi_fill_gif_background(g);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4096 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4097 // animated-gif-only path
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4098 if (((g->eflags & 0x1C) >> 2) == 3) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4099 old_out = g->out;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4100 g->out = (uint8 *) malloc(4 * g->w * g->h);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4101 if (g->out == 0) return epuc("outofmem", "Out of memory");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4102 memcpy(g->out, old_out, g->w*g->h*4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4103 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4104 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4105
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4106 for (;;) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4107 switch (get8(s)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4108 case 0x2C: // Image Descriptor
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4109 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4110 int32 x, y, w, h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4111 uint8 *o;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4112
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4113 x = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4114 y = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4115 w = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4116 h = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4117 if (((x + w) > (g->w)) || ((y + h) > (g->h)))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4118 return epuc("bad Image Descriptor", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4119
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4120 g->line_size = g->w * 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4121 g->start_x = x * 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4122 g->start_y = y * g->line_size;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4123 g->max_x = g->start_x + w * 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4124 g->max_y = g->start_y + h * g->line_size;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4125 g->cur_x = g->start_x;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4126 g->cur_y = g->start_y;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4127
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4128 g->lflags = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4129
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4130 if (g->lflags & 0x40) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4131 g->step = 8 * g->line_size; // first interlaced spacing
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4132 g->parse = 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4133 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4134 g->step = g->line_size;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4135 g->parse = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4136 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4137
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4138 if (g->lflags & 0x80) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4139 stbi_gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4140 g->color_table = (uint8 *) g->lpal;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4141 } else if (g->flags & 0x80) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4142 for (i=0; i < 256; ++i) // @OPTIMIZE: reset only the previous transparent
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4143 g->pal[i][3] = 255;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4144 if (g->transparent >= 0 && (g->eflags & 0x01))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4145 g->pal[g->transparent][3] = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4146 g->color_table = (uint8 *) g->pal;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4147 } else
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4148 return epuc("missing color table", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4149
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4150 o = stbi_process_gif_raster(s, g);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4151 if (o == NULL) return NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4152
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4153 if (req_comp && req_comp != 4)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4154 o = convert_format(o, 4, req_comp, g->w, g->h);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4155 return o;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4156 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4157
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4158 case 0x21: // Comment Extension.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4159 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4160 int len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4161 if (get8(s) == 0xF9) { // Graphic Control Extension.
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4162 len = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4163 if (len == 4) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4164 g->eflags = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4165 get16le(s); // delay
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4166 g->transparent = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4167 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4168 skip(s, len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4169 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4170 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4171 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4172 while ((len = get8(s)) != 0)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4173 skip(s, len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4174 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4175 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4176
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4177 case 0x3B: // gif stream termination code
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4178 return (uint8 *) 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4179
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4180 default:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4181 return epuc("unknown code", "Corrupt GIF");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4182 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4183 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4184 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4185
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4186 static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4187 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4188 uint8 *u = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4189 stbi_gif g={0};
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4190
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4191 u = stbi_gif_load_next(s, &g, comp, req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4192 if (u == (void *) 1) u = 0; // end of animated gif marker
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4193 if (u) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4194 *x = g.w;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4195 *y = g.h;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4196 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4197
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4198 return u;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4199 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4200
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4201 static int stbi_gif_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4202 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4203 return stbi_gif_info_raw(s,x,y,comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4204 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4205
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4206 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4207
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4208 // *************************************************************************************************
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4209 // Radiance RGBE HDR loader
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4210 // originally by Nicolas Schulz
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4211 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4212 static int hdr_test(stbi *s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4213 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4214 const char *signature = "#?RADIANCE\n";
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4215 int i;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4216 for (i=0; signature[i]; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4217 if (get8(s) != signature[i])
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4218 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4219 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4220 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4221
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4222 static int stbi_hdr_test(stbi* s)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4223 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4224 int r = hdr_test(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4225 stbi_rewind(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4226 return r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4227 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4228
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4229 #define HDR_BUFLEN 1024
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4230 static char *hdr_gettoken(stbi *z, char *buffer)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4231 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4232 int len=0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4233 char c = '\0';
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4234
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4235 c = (char) get8(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4236
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4237 while (!at_eof(z) && c != '\n') {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4238 buffer[len++] = c;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4239 if (len == HDR_BUFLEN-1) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4240 // flush to end of line
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4241 while (!at_eof(z) && get8(z) != '\n')
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4242 ;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4243 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4244 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4245 c = (char) get8(z);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4246 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4247
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4248 buffer[len] = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4249 return buffer;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4250 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4251
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4252 static void hdr_convert(float *output, stbi_uc *input, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4253 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4254 if ( input[3] != 0 ) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4255 float f1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4256 // Exponent
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4257 f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4258 if (req_comp <= 2)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4259 output[0] = (input[0] + input[1] + input[2]) * f1 / 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4260 else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4261 output[0] = input[0] * f1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4262 output[1] = input[1] * f1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4263 output[2] = input[2] * f1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4264 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4265 if (req_comp == 2) output[1] = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4266 if (req_comp == 4) output[3] = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4267 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4268 switch (req_comp) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4269 case 4: output[3] = 1; // fallthrough
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4270 case 3: output[0] = output[1] = output[2] = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4271 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4272 case 2: output[1] = 1; // fallthrough
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4273 case 1: output[0] = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4274 break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4275 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4276 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4277 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4278
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4279 static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4280 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4281 char buffer[HDR_BUFLEN];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4282 char *token;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4283 int valid = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4284 int width, height;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4285 stbi_uc *scanline;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4286 float *hdr_data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4287 int len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4288 unsigned char count, value;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4289 int i, j, k, c1,c2, z;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4290
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4291
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4292 // Check identifier
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4293 if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4294 return epf("not HDR", "Corrupt HDR image");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4295
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4296 // Parse header
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4297 for(;;) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4298 token = hdr_gettoken(s,buffer);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4299 if (token[0] == 0) break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4300 if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4301 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4302
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4303 if (!valid) return epf("unsupported format", "Unsupported HDR format");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4304
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4305 // Parse width and height
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4306 // can't use sscanf() if we're not using stdio!
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4307 token = hdr_gettoken(s,buffer);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4308 if (strncmp(token, "-Y ", 3)) return epf("unsupported data layout", "Unsupported HDR format");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4309 token += 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4310 height = strtol(token, &token, 10);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4311 while (*token == ' ') ++token;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4312 if (strncmp(token, "+X ", 3)) return epf("unsupported data layout", "Unsupported HDR format");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4313 token += 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4314 width = strtol(token, NULL, 10);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4315
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4316 *x = width;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4317 *y = height;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4318
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4319 *comp = 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4320 if (req_comp == 0) req_comp = 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4321
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4322 // Read data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4323 hdr_data = (float *) malloc(height * width * req_comp * sizeof(float));
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4324
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4325 // Load image data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4326 // image data is stored as some number of sca
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4327 if ( width < 8 || width >= 32768) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4328 // Read flat data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4329 for (j=0; j < height; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4330 for (i=0; i < width; ++i) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4331 stbi_uc rgbe[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4332 main_decode_loop:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4333 getn(s, rgbe, 4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4334 hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4335 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4336 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4337 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4338 // Read RLE-encoded data
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4339 scanline = NULL;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4340
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4341 for (j = 0; j < height; ++j) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4342 c1 = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4343 c2 = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4344 len = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4345 if (c1 != 2 || c2 != 2 || (len & 0x80)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4346 // not run-length encoded, so we have to actually use THIS data as a decoded
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4347 // pixel (note this can't be a valid pixel--one of RGB must be >= 128)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4348 uint8 rgbe[4];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4349 rgbe[0] = (uint8) c1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4350 rgbe[1] = (uint8) c2;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4351 rgbe[2] = (uint8) len;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4352 rgbe[3] = (uint8) get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4353 hdr_convert(hdr_data, rgbe, req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4354 i = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4355 j = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4356 free(scanline);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4357 goto main_decode_loop; // yes, this makes no sense
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4358 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4359 len <<= 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4360 len |= get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4361 if (len != width) { free(hdr_data); free(scanline); return epf("invalid decoded scanline length", "corrupt HDR"); }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4362 if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4363
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4364 for (k = 0; k < 4; ++k) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4365 i = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4366 while (i < width) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4367 count = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4368 if (count > 128) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4369 // Run
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4370 value = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4371 count -= 128;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4372 for (z = 0; z < count; ++z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4373 scanline[i++ * 4 + k] = value;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4374 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4375 // Dump
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4376 for (z = 0; z < count; ++z)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4377 scanline[i++ * 4 + k] = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4378 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4379 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4380 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4381 for (i=0; i < width; ++i)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4382 hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4383 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4384 free(scanline);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4385 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4386
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4387 return hdr_data;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4388 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4389
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4390 static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4391 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4392 return hdr_load(s,x,y,comp,req_comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4393 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4394
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4395 static int stbi_hdr_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4396 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4397 char buffer[HDR_BUFLEN];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4398 char *token;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4399 int valid = 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4400
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4401 if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4402 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4403 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4404 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4405
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4406 for(;;) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4407 token = hdr_gettoken(s,buffer);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4408 if (token[0] == 0) break;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4409 if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4410 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4411
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4412 if (!valid) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4413 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4414 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4415 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4416 token = hdr_gettoken(s,buffer);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4417 if (strncmp(token, "-Y ", 3)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4418 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4419 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4420 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4421 token += 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4422 *y = strtol(token, &token, 10);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4423 while (*token == ' ') ++token;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4424 if (strncmp(token, "+X ", 3)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4425 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4426 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4427 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4428 token += 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4429 *x = strtol(token, NULL, 10);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4430 *comp = 3;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4431 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4432 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4433 #endif // STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4434
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4435 #ifdef STBI_CRAP_FORMATS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4436
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4437 static int stbi_bmp_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4438 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4439 int hsz;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4440 if (get8(s) != 'B' || get8(s) != 'M') {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4441 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4442 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4443 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4444 skip(s,12);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4445 hsz = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4446 if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4447 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4448 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4449 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4450 if (hsz == 12) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4451 *x = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4452 *y = get16le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4453 } else {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4454 *x = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4455 *y = get32le(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4456 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4457 if (get16le(s) != 1) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4458 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4459 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4460 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4461 *comp = get16le(s) / 8;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4462 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4463 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4464
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4465 static int stbi_psd_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4466 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4467 int channelCount;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4468 if (get32(s) != 0x38425053) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4469 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4470 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4471 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4472 if (get16(s) != 1) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4473 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4474 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4475 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4476 skip(s, 6);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4477 channelCount = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4478 if (channelCount < 0 || channelCount > 16) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4479 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4480 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4481 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4482 *y = get32(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4483 *x = get32(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4484 if (get16(s) != 8) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4485 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4486 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4487 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4488 if (get16(s) != 3) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4489 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4490 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4491 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4492 *comp = 4;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4493 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4494 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4495
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4496 static int stbi_pic_info(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4497 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4498 int act_comp=0,num_packets=0,chained;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4499 pic_packet_t packets[10];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4500
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4501 skip(s, 92);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4502
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4503 *x = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4504 *y = get16(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4505 if (at_eof(s)) return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4506 if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4507 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4508 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4509 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4510
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4511 skip(s, 8);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4512
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4513 do {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4514 pic_packet_t *packet;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4515
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4516 if (num_packets==sizeof(packets)/sizeof(packets[0]))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4517 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4518
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4519 packet = &packets[num_packets++];
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4520 chained = get8(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4521 packet->size = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4522 packet->type = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4523 packet->channel = get8u(s);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4524 act_comp |= packet->channel;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4525
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4526 if (at_eof(s)) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4527 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4528 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4529 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4530 if (packet->size != 8) {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4531 stbi_rewind( s );
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4532 return 0;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4533 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4534 } while (chained);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4535
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4536 *comp = (act_comp & 0x10 ? 4 : 3);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4537
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4538 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4539 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4540 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4541
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4542
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4543 static int stbi_info_main(stbi *s, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4544 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4545 if (stbi_jpeg_info(s, x, y, comp))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4546 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4547 if (stbi_png_info(s, x, y, comp))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4548 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4549 #ifdef STBI_CRAP_FORMATS
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4550 if (stbi_gif_info(s, x, y, comp))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4551 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4552 if (stbi_bmp_info(s, x, y, comp))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4553 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4554 if (stbi_psd_info(s, x, y, comp))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4555 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4556 if (stbi_pic_info(s, x, y, comp))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4557 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4558 #ifndef STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4559 if (stbi_hdr_info(s, x, y, comp))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4560 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4561 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4562 // test tga last because it's a crappy test!
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4563 if (stbi_tga_info(s, x, y, comp))
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4564 return 1;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4565 #endif
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4566 return e("unknown image type", "Image not of any known type, or corrupt");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4567 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4568
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4569 #ifndef STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4570 int stbi_info(char const *filename, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4571 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4572 FILE *f = fopen(filename, "rb");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4573 int result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4574 if (!f) return e("can't fopen", "Unable to open file");
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4575 result = stbi_info_from_file(f, x, y, comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4576 fclose(f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4577 return result;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4578 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4579
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4580 int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4581 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4582 int r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4583 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4584 long pos = ftell(f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4585 start_file(&s, f);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4586 r = stbi_info_main(&s,x,y,comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4587 fseek(f,pos,SEEK_SET);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4588 return r;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4589 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4590 #endif // !STBI_NO_STDIO
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4591
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4592 int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4593 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4594 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4595 start_mem(&s,buffer,len);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4596 return stbi_info_main(&s,x,y,comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4597 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4598
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4599 int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4600 {
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4601 stbi s;
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4602 start_callbacks(&s, (stbi_io_callbacks *) c, user);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4603 return stbi_info_main(&s,x,y,comp);
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4604 }
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4605
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4606 #endif // STBI_HEADER_FILE_ONLY
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4607
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4608 /*
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4609 revision history:
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4610 1.33 (2011-07-14)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4611 make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4612 1.32 (2011-07-13)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4613 support for "info" function for all supported filetypes (SpartanJ)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4614 1.31 (2011-06-20)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4615 a few more leak fixes, bug in PNG handling (SpartanJ)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4616 1.30 (2011-06-11)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4617 added ability to load files via callbacks to accomidate custom input streams (Ben Wenger)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4618 removed deprecated format-specific test/load functions
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4619 removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4620 error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4621 fix inefficiency in decoding 32-bit BMP (David Woo)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4622 1.29 (2010-08-16)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4623 various warning fixes from Aurelien Pocheville
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4624 1.28 (2010-08-01)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4625 fix bug in GIF palette transparency (SpartanJ)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4626 1.27 (2010-08-01)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4627 cast-to-uint8 to fix warnings
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4628 1.26 (2010-07-24)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4629 fix bug in file buffering for PNG reported by SpartanJ
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4630 1.25 (2010-07-17)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4631 refix trans_data warning (Won Chun)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4632 1.24 (2010-07-12)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4633 perf improvements reading from files on platforms with lock-heavy fgetc()
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4634 minor perf improvements for jpeg
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4635 deprecated type-specific functions so we'll get feedback if they're needed
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4636 attempt to fix trans_data warning (Won Chun)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4637 1.23 fixed bug in iPhone support
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4638 1.22 (2010-07-10)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4639 removed image *writing* support
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4640 stbi_info support from Jetro Lauha
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4641 GIF support from Jean-Marc Lienher
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4642 iPhone PNG-extensions from James Brown
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4643 warning-fixes from Nicolas Schulz and Janez Zemva (i.e. Janez (U+017D)emva)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4644 1.21 fix use of 'uint8' in header (reported by jon blow)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4645 1.20 added support for Softimage PIC, by Tom Seddon
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4646 1.19 bug in interlaced PNG corruption check (found by ryg)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4647 1.18 2008-08-02
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4648 fix a threading bug (local mutable static)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4649 1.17 support interlaced PNG
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4650 1.16 major bugfix - convert_format converted one too many pixels
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4651 1.15 initialize some fields for thread safety
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4652 1.14 fix threadsafe conversion bug
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4653 header-file-only version (#define STBI_HEADER_FILE_ONLY before including)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4654 1.13 threadsafe
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4655 1.12 const qualifiers in the API
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4656 1.11 Support installable IDCT, colorspace conversion routines
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4657 1.10 Fixes for 64-bit (don't use "unsigned long")
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4658 optimized upsampling by Fabian "ryg" Giesen
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4659 1.09 Fix format-conversion for PSD code (bad global variables!)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4660 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4661 1.07 attempt to fix C++ warning/errors again
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4662 1.06 attempt to fix C++ warning/errors again
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4663 1.05 fix TGA loading to return correct *comp and use good luminance calc
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4664 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4665 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4666 1.02 support for (subset of) HDR files, float interface for preferred access to them
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4667 1.01 fix bug: possible bug in handling right-side up bmps... not sure
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4668 fix bug: the stbi_bmp_load() and stbi_tga_load() functions didn't work at all
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4669 1.00 interface to zlib that skips zlib header
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4670 0.99 correct handling of alpha in palette
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4671 0.98 TGA loader by lonesock; dynamically add loaders (untested)
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4672 0.97 jpeg errors on too large a file; also catch another malloc failure
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4673 0.96 fix detection of invalid v value - particleman@mollyrocket forum
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4674 0.95 during header scan, seek to markers in case of padding
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4675 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4676 0.93 handle jpegtran output; verbose errors
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4677 0.92 read 4,8,16,24,32-bit BMP files of several formats
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4678 0.91 output 24-bit Windows 3.0 BMP files
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4679 0.90 fix a few more warnings; bump version number to approach 1.0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4680 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4681 0.60 fix compiling as c++
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4682 0.59 fix warnings: merge Dave Moore's -Wall fixes
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4683 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4684 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4685 0.56 fix bug: zlib uncompressed mode len vs. nlen
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4686 0.55 fix bug: restart_interval not initialized to 0
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4687 0.54 allow NULL for 'int *comp'
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4688 0.53 fix bug in png 3->4; speedup png decoding
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4689 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4690 0.51 obey req_comp requests, 1-component jpegs return as 1-component,
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4691 on 'test' only check type, not whether we support this variant
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4692 0.50 first released version
32250b436bca Initial re-import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
4693 */