gosu 0.12.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gosu/Audio.hpp +23 -25
- data/Gosu/Graphics.hpp +16 -12
- data/Gosu/Image.hpp +3 -0
- data/Gosu/Version.hpp +2 -2
- data/lib/gosu.rb +2 -2
- data/lib/gosu/compat.rb +1 -1
- data/lib/gosu/patches.rb +5 -0
- data/lib/gosu/swig_patches.rb +1 -1
- data/rdoc/gosu.rb +10 -10
- data/src/Audio.cpp +93 -228
- data/src/AudioImpl.cpp +94 -0
- data/src/AudioImpl.hpp +33 -0
- data/src/AudioToolboxFile.hpp +14 -18
- data/src/Bitmap.cpp +36 -30
- data/src/BitmapIO.cpp +14 -23
- data/src/BlockAllocator.cpp +7 -10
- data/src/BlockAllocator.hpp +2 -4
- data/src/Channel.cpp +89 -0
- data/src/Color.cpp +4 -9
- data/src/DirectoriesApple.cpp +13 -13
- data/src/DirectoriesUnix.cpp +8 -7
- data/src/DirectoriesWin.cpp +12 -11
- data/src/EmptyImageData.hpp +54 -0
- data/src/FileUnix.cpp +12 -9
- data/src/FileWin.cpp +8 -7
- data/src/Font.cpp +12 -13
- data/src/FormattedString.cpp +237 -0
- data/src/FormattedString.hpp +14 -265
- data/src/GosuViewController.cpp +2 -5
- data/src/Graphics.cpp +38 -39
- data/src/IO.cpp +11 -10
- data/src/Image.cpp +16 -9
- data/src/Input.cpp +16 -15
- data/src/InputUIKit.cpp +8 -7
- data/src/Macro.cpp +11 -11
- data/src/Math.cpp +9 -8
- data/src/RubyGosu.cxx +129 -99
- data/src/TextApple.cpp +19 -13
- data/src/TextInput.cpp +23 -22
- data/src/TextWin.cpp +17 -19
- data/src/Texture.cpp +15 -10
- data/src/Transform.cpp +13 -17
- data/src/Utility.cpp +3 -2
- data/src/UtilityApple.cpp +10 -11
- data/src/UtilityWin.cpp +2 -1
- data/src/Version.cpp +5 -4
- data/src/WinMain.cpp +3 -3
- data/src/WinUtility.cpp +7 -6
- data/src/Window.cpp +11 -10
- data/src/WindowUIKit.cpp +9 -8
- data/src/stb_image.h +782 -480
- data/src/stb_image_write.h +425 -15
- data/src/stb_vorbis.c +82 -32
- metadata +8 -4
- data/src/ALChannelManagement.hpp +0 -119
data/src/Utility.cpp
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
#include <algorithm>
|
9
9
|
#include <stdexcept>
|
10
10
|
#include <vector>
|
11
|
+
using namespace std;
|
11
12
|
|
12
13
|
#ifndef GOSU_IS_IPHONE
|
13
14
|
|
@@ -31,7 +32,7 @@ wstring Gosu::utf8_to_wstring(const string& s)
|
|
31
32
|
{
|
32
33
|
return iconvert<wstring, UCS_4_INTERNAL, UTF_8>(s);
|
33
34
|
}
|
34
|
-
string Gosu::wstring_to_utf8(const
|
35
|
+
string Gosu::wstring_to_utf8(const wstring& ws)
|
35
36
|
{
|
36
37
|
return iconvert<string, UTF_8, UCS_4_INTERNAL>(ws);
|
37
38
|
}
|
@@ -57,7 +58,7 @@ string Gosu::wstring_to_utf8(const wstring& ws)
|
|
57
58
|
#endif
|
58
59
|
#endif
|
59
60
|
|
60
|
-
bool Gosu::has_extension(const
|
61
|
+
bool Gosu::has_extension(const string& filename, const char* extension)
|
61
62
|
{
|
62
63
|
size_t ext_len = strlen(extension);
|
63
64
|
if (ext_len > filename.length()) {
|
data/src/UtilityApple.cpp
CHANGED
@@ -5,16 +5,15 @@
|
|
5
5
|
#import <Foundation/Foundation.h>
|
6
6
|
#import <stdexcept>
|
7
7
|
#import <vector>
|
8
|
+
using namespace std;
|
8
9
|
|
9
10
|
#ifdef GOSU_IS_IPHONE
|
10
|
-
|
11
|
+
wstring Gosu::utf8_to_wstring(const string& s)
|
11
12
|
{
|
12
|
-
if (s.empty())
|
13
|
-
return std::wstring();
|
14
|
-
}
|
13
|
+
if (s.empty()) return wstring();
|
15
14
|
|
16
15
|
NSString* string = [NSString stringWithUTF8String:s.c_str()];
|
17
|
-
|
16
|
+
vector<wchar_t> buffer(s.size());
|
18
17
|
NSUInteger buffer_size;
|
19
18
|
if (![string getBytes:&buffer[0]
|
20
19
|
maxLength:buffer.size() * sizeof(wchar_t)
|
@@ -23,25 +22,25 @@ std::wstring Gosu::utf8_to_wstring(const std::string& s)
|
|
23
22
|
options:0
|
24
23
|
range:NSMakeRange(0, string.length)
|
25
24
|
remainingRange:nullptr]) {
|
26
|
-
throw
|
25
|
+
throw runtime_error("String " + s + " could not be converted to UTF-32");
|
27
26
|
}
|
28
|
-
return
|
27
|
+
return wstring(&buffer[0], &buffer[0] + buffer_size / sizeof(wchar_t));
|
29
28
|
}
|
30
29
|
|
31
|
-
|
30
|
+
string Gosu::wstring_to_utf8(const wstring& ws)
|
32
31
|
{
|
33
|
-
if (ws.empty()) return
|
32
|
+
if (ws.empty()) return string();
|
34
33
|
|
35
34
|
@autoreleasepool {
|
36
35
|
NSString* string = [[NSString alloc] initWithBytes:ws.data()
|
37
36
|
length:ws.size() * sizeof(wchar_t)
|
38
37
|
encoding:NSUTF32LittleEndianStringEncoding];
|
39
|
-
return string.UTF8String ?:
|
38
|
+
return string.UTF8String ?: "";
|
40
39
|
}
|
41
40
|
}
|
42
41
|
#endif
|
43
42
|
|
44
|
-
|
43
|
+
string Gosu::language()
|
45
44
|
{
|
46
45
|
@autoreleasepool {
|
47
46
|
NSString* language = [NSLocale preferredLanguages][0];
|
data/src/UtilityWin.cpp
CHANGED
data/src/Version.cpp
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
#include <Gosu/Version.hpp>
|
2
2
|
#include <Gosu/Platform.hpp>
|
3
3
|
#include <string>
|
4
|
+
using namespace std;
|
4
5
|
|
5
|
-
const
|
6
|
-
|
7
|
-
|
6
|
+
const string Gosu::VERSION = to_string(GOSU_MAJOR_VERSION) + '.' +
|
7
|
+
to_string(GOSU_MINOR_VERSION) + '.' +
|
8
|
+
to_string(GOSU_POINT_VERSION);
|
8
9
|
|
9
|
-
const
|
10
|
+
const string Gosu::LICENSES =
|
10
11
|
"This software may utilize code from the following third-party libraries:\n"
|
11
12
|
"\n"
|
12
13
|
"Gosu, https://www.libgosu.org, MIT License, https://opensource.org/licenses/MIT\n"
|
data/src/WinMain.cpp
CHANGED
@@ -23,7 +23,7 @@ vector<string> split_cmd_line()
|
|
23
23
|
is_quoted_arg = true;
|
24
24
|
}
|
25
25
|
else if (is_quoted_arg) {
|
26
|
-
result.push_back(
|
26
|
+
result.push_back(string(arg_begin, cmd_line));
|
27
27
|
arg_begin = nullptr;
|
28
28
|
}
|
29
29
|
}
|
@@ -32,7 +32,7 @@ vector<string> split_cmd_line()
|
|
32
32
|
is_quoted_arg = false;
|
33
33
|
}
|
34
34
|
else if (isspace((unsigned char)*cmd_line) && arg_begin != nullptr && !is_quoted_arg) {
|
35
|
-
result.push_back(
|
35
|
+
result.push_back(string(arg_begin, cmd_line + 1));
|
36
36
|
arg_begin = nullptr;
|
37
37
|
}
|
38
38
|
++cmd_line;
|
@@ -55,7 +55,7 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
|
55
55
|
argv[i] = const_cast<char*>(arguments[i].c_str());
|
56
56
|
return main(argv.size(), &argv[0]);
|
57
57
|
}
|
58
|
-
catch (const
|
58
|
+
catch (const exception& e) {
|
59
59
|
::MessageBoxA(0, e.what(), "Uncaught Exception", MB_OK | MB_ICONERROR);
|
60
60
|
return EXIT_FAILURE;
|
61
61
|
}
|
data/src/WinUtility.cpp
CHANGED
@@ -4,9 +4,10 @@
|
|
4
4
|
#include "WinUtility.hpp"
|
5
5
|
#include <Gosu/Utility.hpp>
|
6
6
|
#include <stdexcept>
|
7
|
-
#include <windows.h>
|
7
|
+
#include <windows.h>
|
8
|
+
using namespace std;
|
8
9
|
|
9
|
-
void Gosu::throw_last_winapi_error(const
|
10
|
+
void Gosu::throw_last_winapi_error(const string& action)
|
10
11
|
{
|
11
12
|
// Obtain error message from Windows.
|
12
13
|
wchar_t* buffer;
|
@@ -16,11 +17,11 @@ void Gosu::throw_last_winapi_error(const std::string& action)
|
|
16
17
|
FORMAT_MESSAGE_IGNORE_INSERTS, 0, GetLastError(),
|
17
18
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &buffer, 0, 0)
|
18
19
|
|| buffer == nullptr) {
|
19
|
-
throw
|
20
|
+
throw runtime_error("Unknown error");
|
20
21
|
}
|
21
22
|
|
22
|
-
// Safely move the message into a
|
23
|
-
|
23
|
+
// Safely move the message into a string.
|
24
|
+
string message;
|
24
25
|
try {
|
25
26
|
message = wstring_to_utf8(buffer);
|
26
27
|
}
|
@@ -35,7 +36,7 @@ void Gosu::throw_last_winapi_error(const std::string& action)
|
|
35
36
|
message = "While " + action + ", the following error occured: " + message;
|
36
37
|
}
|
37
38
|
|
38
|
-
throw
|
39
|
+
throw runtime_error(message);
|
39
40
|
}
|
40
41
|
|
41
42
|
#endif
|
data/src/Window.cpp
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
#include <cstdlib>
|
7
7
|
#include <algorithm>
|
8
8
|
#include <stdexcept>
|
9
|
+
using namespace std;
|
9
10
|
|
10
11
|
namespace Gosu
|
11
12
|
{
|
@@ -14,10 +15,10 @@ namespace Gosu
|
|
14
15
|
void register_frame();
|
15
16
|
}
|
16
17
|
|
17
|
-
static void throw_sdl_error(const
|
18
|
+
static void throw_sdl_error(const string& operation)
|
18
19
|
{
|
19
20
|
const char* error = SDL_GetError();
|
20
|
-
throw
|
21
|
+
throw runtime_error(operation + ": " + (error ? error : "(unknown error)"));
|
21
22
|
}
|
22
23
|
|
23
24
|
static void cleanup();
|
@@ -30,7 +31,7 @@ namespace Gosu
|
|
30
31
|
throw_sdl_error("Could not initialize SDL Video");
|
31
32
|
}
|
32
33
|
|
33
|
-
|
34
|
+
atexit(cleanup);
|
34
35
|
|
35
36
|
Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
|
36
37
|
|
@@ -90,8 +91,8 @@ struct Gosu::Window::Impl
|
|
90
91
|
// (transition from CLOSED to OPEN).
|
91
92
|
enum { CLOSED, OPEN, CLOSING } state = CLOSED;
|
92
93
|
|
93
|
-
|
94
|
-
|
94
|
+
unique_ptr<Graphics> graphics;
|
95
|
+
unique_ptr<Input> input;
|
95
96
|
};
|
96
97
|
|
97
98
|
Gosu::Window::Window(unsigned width, unsigned height, bool fullscreen, double update_interval)
|
@@ -151,7 +152,7 @@ void Gosu::Window::resize(unsigned width, unsigned height, bool fullscreen)
|
|
151
152
|
|
152
153
|
double scale_x = 1.0 * actual_width / width;
|
153
154
|
double scale_y = 1.0 * actual_height / height;
|
154
|
-
scale_factor =
|
155
|
+
scale_factor = min(scale_x, scale_y);
|
155
156
|
|
156
157
|
if (scale_x < scale_y) {
|
157
158
|
black_bar_height = (actual_height / scale_x - height) / 2;
|
@@ -165,7 +166,7 @@ void Gosu::Window::resize(unsigned width, unsigned height, bool fullscreen)
|
|
165
166
|
double max_height = Gosu::available_height();
|
166
167
|
|
167
168
|
if (width > max_width || height > max_height) {
|
168
|
-
scale_factor =
|
169
|
+
scale_factor = min(max_width / width, max_height / height);
|
169
170
|
actual_width = width * scale_factor;
|
170
171
|
actual_height = height * scale_factor;
|
171
172
|
}
|
@@ -205,13 +206,13 @@ void Gosu::Window::set_update_interval(double update_interval)
|
|
205
206
|
pimpl->update_interval = update_interval;
|
206
207
|
}
|
207
208
|
|
208
|
-
|
209
|
+
string Gosu::Window::caption() const
|
209
210
|
{
|
210
211
|
const char* title = SDL_GetWindowTitle(shared_window());
|
211
212
|
return title ? title : "";
|
212
213
|
}
|
213
214
|
|
214
|
-
void Gosu::Window::set_caption(const
|
215
|
+
void Gosu::Window::set_caption(const string& caption)
|
215
216
|
{
|
216
217
|
SDL_SetWindowTitle(shared_window(), caption.c_str());
|
217
218
|
}
|
@@ -262,7 +263,7 @@ bool Gosu::Window::tick()
|
|
262
263
|
case (SDL_DROPFILE): {
|
263
264
|
char* dropped_filedir = e.drop.file;
|
264
265
|
if (dropped_filedir == nullptr) break;
|
265
|
-
drop(
|
266
|
+
drop(string(dropped_filedir));
|
266
267
|
SDL_free(dropped_filedir);
|
267
268
|
break;
|
268
269
|
}
|
data/src/WindowUIKit.cpp
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
#include "GosuViewController.h"
|
5
5
|
#include <Gosu/Gosu.hpp>
|
6
|
+
using namespace std;
|
6
7
|
|
7
8
|
namespace Gosu
|
8
9
|
{
|
@@ -35,12 +36,12 @@ struct Gosu::Window::Impl
|
|
35
36
|
{
|
36
37
|
::UIWindow* window;
|
37
38
|
GosuViewController* controller;
|
38
|
-
|
39
|
-
|
39
|
+
unique_ptr<Graphics> graphics;
|
40
|
+
unique_ptr<Input> input;
|
40
41
|
|
41
42
|
bool fullscreen;
|
42
43
|
double update_interval;
|
43
|
-
|
44
|
+
string caption;
|
44
45
|
};
|
45
46
|
|
46
47
|
Gosu::Window::Window(unsigned width, unsigned height, bool fullscreen, double update_interval)
|
@@ -90,7 +91,7 @@ bool Gosu::Window::fullscreen() const
|
|
90
91
|
|
91
92
|
void Gosu::Window::resize(unsigned width, unsigned height, bool fullscreen)
|
92
93
|
{
|
93
|
-
throw
|
94
|
+
throw logic_error("Cannot resize windows on iOS");
|
94
95
|
}
|
95
96
|
|
96
97
|
double Gosu::Window::update_interval() const
|
@@ -100,15 +101,15 @@ double Gosu::Window::update_interval() const
|
|
100
101
|
|
101
102
|
void Gosu::Window::set_update_interval(double update_interval)
|
102
103
|
{
|
103
|
-
throw
|
104
|
+
throw logic_error("Cannot change the update interval on iOS");
|
104
105
|
}
|
105
106
|
|
106
|
-
|
107
|
+
string Gosu::Window::caption() const
|
107
108
|
{
|
108
109
|
return pimpl->caption;
|
109
110
|
}
|
110
111
|
|
111
|
-
void Gosu::Window::set_caption(const
|
112
|
+
void Gosu::Window::set_caption(const string& caption)
|
112
113
|
{
|
113
114
|
pimpl->caption = caption;
|
114
115
|
}
|
@@ -144,7 +145,7 @@ bool Gosu::Window::tick()
|
|
144
145
|
|
145
146
|
void Gosu::Window::close()
|
146
147
|
{
|
147
|
-
throw
|
148
|
+
throw logic_error("Cannot close windows manually on iOS");
|
148
149
|
}
|
149
150
|
|
150
151
|
void Gosu::Window::button_down(Button button)
|
data/src/stb_image.h
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* stb_image - v2.
|
1
|
+
/* stb_image - v2.16 - public domain image loader - http://nothings.org/stb_image.h
|
2
2
|
no warranty implied; use at your own risk
|
3
3
|
|
4
4
|
Do this:
|
@@ -21,7 +21,7 @@
|
|
21
21
|
avoid problematic images and only need the trivial interface
|
22
22
|
|
23
23
|
JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
|
24
|
-
PNG 1/2/4/8-bit-per-channel
|
24
|
+
PNG 1/2/4/8/16-bit-per-channel
|
25
25
|
|
26
26
|
TGA (not sure what subset, if a subset)
|
27
27
|
BMP non-1bpp, non-RLE
|
@@ -42,136 +42,23 @@
|
|
42
42
|
Full documentation under "DOCUMENTATION" below.
|
43
43
|
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
With other JPEG optimizations included in this version, we see
|
57
|
-
2x speedup on a JPEG on an x86 machine, and a 1.5x speedup
|
58
|
-
on a JPEG on an ARM machine, relative to previous versions of this
|
59
|
-
library. The same results will not obtain for all JPGs and for all
|
60
|
-
x86/ARM machines. (Note that progressive JPEGs are significantly
|
61
|
-
slower to decode than regular JPEGs.) This doesn't mean that this
|
62
|
-
is the fastest JPEG decoder in the land; rather, it brings it
|
63
|
-
closer to parity with standard libraries. If you want the fastest
|
64
|
-
decode, look elsewhere. (See "Philosophy" section of docs below.)
|
65
|
-
|
66
|
-
See final bullet items below for more info on SIMD.
|
67
|
-
|
68
|
-
- Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing
|
69
|
-
the memory allocator. Unlike other STBI libraries, these macros don't
|
70
|
-
support a context parameter, so if you need to pass a context in to
|
71
|
-
the allocator, you'll have to store it in a global or a thread-local
|
72
|
-
variable.
|
73
|
-
|
74
|
-
- Split existing STBI_NO_HDR flag into two flags, STBI_NO_HDR and
|
75
|
-
STBI_NO_LINEAR.
|
76
|
-
STBI_NO_HDR: suppress implementation of .hdr reader format
|
77
|
-
STBI_NO_LINEAR: suppress high-dynamic-range light-linear float API
|
78
|
-
|
79
|
-
- You can suppress implementation of any of the decoders to reduce
|
80
|
-
your code footprint by #defining one or more of the following
|
81
|
-
symbols before creating the implementation.
|
82
|
-
|
83
|
-
STBI_NO_JPEG
|
84
|
-
STBI_NO_PNG
|
85
|
-
STBI_NO_BMP
|
86
|
-
STBI_NO_PSD
|
87
|
-
STBI_NO_TGA
|
88
|
-
STBI_NO_GIF
|
89
|
-
STBI_NO_HDR
|
90
|
-
STBI_NO_PIC
|
91
|
-
STBI_NO_PNM (.ppm and .pgm)
|
92
|
-
|
93
|
-
- You can request *only* certain decoders and suppress all other ones
|
94
|
-
(this will be more forward-compatible, as addition of new decoders
|
95
|
-
doesn't require you to disable them explicitly):
|
96
|
-
|
97
|
-
STBI_ONLY_JPEG
|
98
|
-
STBI_ONLY_PNG
|
99
|
-
STBI_ONLY_BMP
|
100
|
-
STBI_ONLY_PSD
|
101
|
-
STBI_ONLY_TGA
|
102
|
-
STBI_ONLY_GIF
|
103
|
-
STBI_ONLY_HDR
|
104
|
-
STBI_ONLY_PIC
|
105
|
-
STBI_ONLY_PNM (.ppm and .pgm)
|
106
|
-
|
107
|
-
Note that you can define multiples of these, and you will get all
|
108
|
-
of them ("only x" and "only y" is interpreted to mean "only x&y").
|
109
|
-
|
110
|
-
- If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
|
111
|
-
want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
|
112
|
-
|
113
|
-
- Compilation of all SIMD code can be suppressed with
|
114
|
-
#define STBI_NO_SIMD
|
115
|
-
It should not be necessary to disable SIMD unless you have issues
|
116
|
-
compiling (e.g. using an x86 compiler which doesn't support SSE
|
117
|
-
intrinsics or that doesn't support the method used to detect
|
118
|
-
SSE2 support at run-time), and even those can be reported as
|
119
|
-
bugs so I can refine the built-in compile-time checking to be
|
120
|
-
smarter.
|
121
|
-
|
122
|
-
- The old STBI_SIMD system which allowed installing a user-defined
|
123
|
-
IDCT etc. has been removed. If you need this, don't upgrade. My
|
124
|
-
assumption is that almost nobody was doing this, and those who
|
125
|
-
were will find the built-in SIMD more satisfactory anyway.
|
126
|
-
|
127
|
-
- RGB values computed for JPEG images are slightly different from
|
128
|
-
previous versions of stb_image. (This is due to using less
|
129
|
-
integer precision in SIMD.) The C code has been adjusted so
|
130
|
-
that the same RGB values will be computed regardless of whether
|
131
|
-
SIMD support is available, so your app should always produce
|
132
|
-
consistent results. But these results are slightly different from
|
133
|
-
previous versions. (Specifically, about 3% of available YCbCr values
|
134
|
-
will compute different RGB results from pre-1.49 versions by +-1;
|
135
|
-
most of the deviating values are one smaller in the G channel.)
|
136
|
-
|
137
|
-
- If you must produce consistent results with previous versions of
|
138
|
-
stb_image, #define STBI_JPEG_OLD and you will get the same results
|
139
|
-
you used to; however, you will not get the SIMD speedups for
|
140
|
-
the YCbCr-to-RGB conversion step (although you should still see
|
141
|
-
significant JPEG speedup from the other changes).
|
142
|
-
|
143
|
-
Please note that STBI_JPEG_OLD is a temporary feature; it will be
|
144
|
-
removed in future versions of the library. It is only intended for
|
145
|
-
near-term back-compatibility use.
|
146
|
-
|
147
|
-
|
148
|
-
Latest revision history:
|
45
|
+
LICENSE
|
46
|
+
|
47
|
+
See end of file for license information.
|
48
|
+
|
49
|
+
RECENT REVISION HISTORY:
|
50
|
+
|
51
|
+
2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
|
52
|
+
2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
|
53
|
+
2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
|
54
|
+
2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
|
149
55
|
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
|
150
56
|
2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
|
151
57
|
RGB-format JPEG; remove white matting in PSD;
|
152
|
-
allocate large structures on the stack;
|
58
|
+
allocate large structures on the stack;
|
153
59
|
correct channel count for PNG & BMP
|
154
60
|
2.10 (2016-01-22) avoid warning introduced in 2.09
|
155
61
|
2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
|
156
|
-
2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
|
157
|
-
2.07 (2015-09-13) partial animated GIF support
|
158
|
-
limited 16-bit PSD support
|
159
|
-
minor bugs, code cleanup, and compiler warnings
|
160
|
-
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
|
161
|
-
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
|
162
|
-
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
|
163
|
-
2.03 (2015-04-12) additional corruption checking
|
164
|
-
stbi_set_flip_vertically_on_load
|
165
|
-
fix NEON support; fix mingw support
|
166
|
-
2.02 (2015-01-19) fix incorrect assert, fix warning
|
167
|
-
2.01 (2015-01-17) fix various warnings
|
168
|
-
2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
|
169
|
-
2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD
|
170
|
-
progressive JPEG
|
171
|
-
PGM/PPM support
|
172
|
-
STBI_MALLOC,STBI_REALLOC,STBI_FREE
|
173
|
-
STBI_NO_*, STBI_ONLY_*
|
174
|
-
GIF bugfix
|
175
62
|
|
176
63
|
See end of file for full revision history.
|
177
64
|
|
@@ -186,34 +73,30 @@
|
|
186
73
|
Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG)
|
187
74
|
Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip)
|
188
75
|
Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
|
189
|
-
urraka
|
76
|
+
github:urraka (animated gif) Junggon Kim (PNM comments)
|
190
77
|
Daniel Gibson (16-bit TGA)
|
191
|
-
|
78
|
+
socks-the-fox (16-bit PNG)
|
79
|
+
Jeremy Sawicki (handle all ImageNet JPGs)
|
192
80
|
Optimizations & bugfixes
|
193
81
|
Fabian "ryg" Giesen
|
194
82
|
Arseny Kapoulkine
|
83
|
+
John-Mark Allen
|
195
84
|
|
196
85
|
Bug & warning fixes
|
197
86
|
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
198
|
-
Christpher Lloyd
|
199
|
-
Dave Moore Roy Eltham Hayaki Saito
|
200
|
-
Won Chun Luke Graham Johan Duparc
|
201
|
-
the Horde3D community Thomas Ruf Ronny Chevalier
|
202
|
-
Janez Zemva John Bartholomew Michal Cichon
|
203
|
-
Jonathan Blow Ken Hamada Tero Hanninen
|
204
|
-
Laurent Gomila Cort Stratton Sergio Gonzalez
|
205
|
-
Aruelien Pocheville Thibault Reuille Cass Everitt
|
206
|
-
Ryamond Barbiero Paul Du Bois Engin Manap
|
207
|
-
Michaelangel007@github
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
LICENSE
|
212
|
-
|
213
|
-
This software is dual-licensed to the public domain and under the following
|
214
|
-
license: you are granted a perpetual, irrevocable license to copy, modify,
|
215
|
-
publish, and distribute this file as you see fit.
|
216
|
-
|
87
|
+
Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
|
88
|
+
Dave Moore Roy Eltham Hayaki Saito Nathan Reed
|
89
|
+
Won Chun Luke Graham Johan Duparc Nick Verigakis
|
90
|
+
the Horde3D community Thomas Ruf Ronny Chevalier Baldur Karlsson
|
91
|
+
Janez Zemva John Bartholomew Michal Cichon github:rlyeh
|
92
|
+
Jonathan Blow Ken Hamada Tero Hanninen github:romigrou
|
93
|
+
Laurent Gomila Cort Stratton Sergio Gonzalez github:svdijk
|
94
|
+
Aruelien Pocheville Thibault Reuille Cass Everitt github:snagar
|
95
|
+
Ryamond Barbiero Paul Du Bois Engin Manap github:Zelex
|
96
|
+
Michaelangel007@github Philipp Wiesemann Dale Weiler github:grim210
|
97
|
+
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:sammyhw
|
98
|
+
Blazej Dariusz Roszkowski Gregory Mullen github:phprus
|
99
|
+
Christian Floisand Kevin Schmidt github:poppolopoppo
|
217
100
|
*/
|
218
101
|
|
219
102
|
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
@@ -238,10 +121,10 @@ publish, and distribute this file as you see fit.
|
|
238
121
|
// stbi_image_free(data)
|
239
122
|
//
|
240
123
|
// Standard parameters:
|
241
|
-
// int *x
|
242
|
-
// int *y
|
243
|
-
// int *
|
244
|
-
// int
|
124
|
+
// int *x -- outputs image width in pixels
|
125
|
+
// int *y -- outputs image height in pixels
|
126
|
+
// int *channels_in_file -- outputs # of image components in image file
|
127
|
+
// int desired_channels -- if non-zero, # of image components requested in result
|
245
128
|
//
|
246
129
|
// The return value from an image loader is an 'unsigned char *' which points
|
247
130
|
// to the pixel data, or NULL on an allocation failure or if the image is
|
@@ -249,11 +132,12 @@ publish, and distribute this file as you see fit.
|
|
249
132
|
// with each pixel consisting of N interleaved 8-bit components; the first
|
250
133
|
// pixel pointed to is top-left-most in the image. There is no padding between
|
251
134
|
// image scanlines or between pixels, regardless of format. The number of
|
252
|
-
// components N is '
|
253
|
-
// If
|
254
|
-
//
|
255
|
-
//
|
256
|
-
//
|
135
|
+
// components N is 'desired_channels' if desired_channels is non-zero, or
|
136
|
+
// *channels_in_file otherwise. If desired_channels is non-zero,
|
137
|
+
// *channels_in_file has the number of components that _would_ have been
|
138
|
+
// output otherwise. E.g. if you set desired_channels to 4, you will always
|
139
|
+
// get RGBA output, but you can check *channels_in_file to see if it's trivially
|
140
|
+
// opaque because e.g. there were only 3 channels in the source image.
|
257
141
|
//
|
258
142
|
// An output image with N components has the following components interleaved
|
259
143
|
// in this order in each pixel:
|
@@ -265,10 +149,10 @@ publish, and distribute this file as you see fit.
|
|
265
149
|
// 4 red, green, blue, alpha
|
266
150
|
//
|
267
151
|
// If image loading fails for any reason, the return value will be NULL,
|
268
|
-
// and *x, *y, *
|
269
|
-
// can be queried for an extremely brief, end-user
|
270
|
-
// of why the load failed. Define STBI_NO_FAILURE_STRINGS
|
271
|
-
// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
|
152
|
+
// and *x, *y, *channels_in_file will be unchanged. The function
|
153
|
+
// stbi_failure_reason() can be queried for an extremely brief, end-user
|
154
|
+
// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS
|
155
|
+
// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
|
272
156
|
// more user-friendly ones.
|
273
157
|
//
|
274
158
|
// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
|
@@ -287,13 +171,13 @@ publish, and distribute this file as you see fit.
|
|
287
171
|
// and for best performance I may provide less-easy-to-use APIs that give higher
|
288
172
|
// performance, in addition to the easy to use ones. Nevertheless, it's important
|
289
173
|
// to keep in mind that from the standpoint of you, a client of this library,
|
290
|
-
// all you care about is #1 and #3, and stb libraries
|
174
|
+
// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
|
291
175
|
//
|
292
176
|
// Some secondary priorities arise directly from the first two, some of which
|
293
177
|
// make more explicit reasons why performance can't be emphasized.
|
294
178
|
//
|
295
179
|
// - Portable ("ease of use")
|
296
|
-
// - Small footprint ("easy to maintain")
|
180
|
+
// - Small source code footprint ("easy to maintain")
|
297
181
|
// - No dependencies ("ease of use")
|
298
182
|
//
|
299
183
|
// ===========================================================================
|
@@ -325,13 +209,6 @@ publish, and distribute this file as you see fit.
|
|
325
209
|
// (at least this is true for iOS and Android). Therefore, the NEON support is
|
326
210
|
// toggled by a build flag: define STBI_NEON to get NEON loops.
|
327
211
|
//
|
328
|
-
// The output of the JPEG decoder is slightly different from versions where
|
329
|
-
// SIMD support was introduced (that is, for versions before 1.49). The
|
330
|
-
// difference is only +-1 in the 8-bit RGB channels, and only on a small
|
331
|
-
// fraction of pixels. You can force the pre-1.49 behavior by defining
|
332
|
-
// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path
|
333
|
-
// and hence cost some performance.
|
334
|
-
//
|
335
212
|
// If for some reason you do not want to use any of SIMD code, or if
|
336
213
|
// you have issues compiling it, you can disable it entirely by
|
337
214
|
// defining STBI_NO_SIMD.
|
@@ -387,6 +264,41 @@ publish, and distribute this file as you see fit.
|
|
387
264
|
// says there's premultiplied data (currently only happens in iPhone images,
|
388
265
|
// and only if iPhone convert-to-rgb processing is on).
|
389
266
|
//
|
267
|
+
// ===========================================================================
|
268
|
+
//
|
269
|
+
// ADDITIONAL CONFIGURATION
|
270
|
+
//
|
271
|
+
// - You can suppress implementation of any of the decoders to reduce
|
272
|
+
// your code footprint by #defining one or more of the following
|
273
|
+
// symbols before creating the implementation.
|
274
|
+
//
|
275
|
+
// STBI_NO_JPEG
|
276
|
+
// STBI_NO_PNG
|
277
|
+
// STBI_NO_BMP
|
278
|
+
// STBI_NO_PSD
|
279
|
+
// STBI_NO_TGA
|
280
|
+
// STBI_NO_GIF
|
281
|
+
// STBI_NO_HDR
|
282
|
+
// STBI_NO_PIC
|
283
|
+
// STBI_NO_PNM (.ppm and .pgm)
|
284
|
+
//
|
285
|
+
// - You can request *only* certain decoders and suppress all other ones
|
286
|
+
// (this will be more forward-compatible, as addition of new decoders
|
287
|
+
// doesn't require you to disable them explicitly):
|
288
|
+
//
|
289
|
+
// STBI_ONLY_JPEG
|
290
|
+
// STBI_ONLY_PNG
|
291
|
+
// STBI_ONLY_BMP
|
292
|
+
// STBI_ONLY_PSD
|
293
|
+
// STBI_ONLY_TGA
|
294
|
+
// STBI_ONLY_GIF
|
295
|
+
// STBI_ONLY_HDR
|
296
|
+
// STBI_ONLY_PIC
|
297
|
+
// STBI_ONLY_PNM (.ppm and .pgm)
|
298
|
+
//
|
299
|
+
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
|
300
|
+
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
|
301
|
+
//
|
390
302
|
|
391
303
|
|
392
304
|
#ifndef STBI_NO_STDIO
|
@@ -397,7 +309,7 @@ publish, and distribute this file as you see fit.
|
|
397
309
|
|
398
310
|
enum
|
399
311
|
{
|
400
|
-
STBI_default = 0, // only used for
|
312
|
+
STBI_default = 0, // only used for desired_channels
|
401
313
|
|
402
314
|
STBI_grey = 1,
|
403
315
|
STBI_grey_alpha = 2,
|
@@ -406,6 +318,7 @@ enum
|
|
406
318
|
};
|
407
319
|
|
408
320
|
typedef unsigned char stbi_uc;
|
321
|
+
typedef unsigned short stbi_us;
|
409
322
|
|
410
323
|
#ifdef __cplusplus
|
411
324
|
extern "C" {
|
@@ -433,22 +346,44 @@ typedef struct
|
|
433
346
|
int (*eof) (void *user); // returns nonzero if we are at end of file/data
|
434
347
|
} stbi_io_callbacks;
|
435
348
|
|
436
|
-
|
437
|
-
|
438
|
-
|
349
|
+
////////////////////////////////////
|
350
|
+
//
|
351
|
+
// 8-bits-per-channel interface
|
352
|
+
//
|
353
|
+
|
354
|
+
STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels);
|
355
|
+
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
|
439
356
|
|
440
357
|
#ifndef STBI_NO_STDIO
|
441
|
-
STBIDEF stbi_uc *
|
358
|
+
STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
359
|
+
STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
|
442
360
|
// for stbi_load_from_file, file pointer is left pointing immediately after image
|
443
361
|
#endif
|
444
362
|
|
363
|
+
////////////////////////////////////
|
364
|
+
//
|
365
|
+
// 16-bits-per-channel interface
|
366
|
+
//
|
367
|
+
|
368
|
+
STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
|
369
|
+
STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
|
370
|
+
|
371
|
+
#ifndef STBI_NO_STDIO
|
372
|
+
STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
373
|
+
STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
|
374
|
+
#endif
|
375
|
+
|
376
|
+
////////////////////////////////////
|
377
|
+
//
|
378
|
+
// float-per-channel interface
|
379
|
+
//
|
445
380
|
#ifndef STBI_NO_LINEAR
|
446
|
-
STBIDEF float *
|
447
|
-
STBIDEF float *
|
448
|
-
STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp);
|
381
|
+
STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
|
382
|
+
STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
|
449
383
|
|
450
384
|
#ifndef STBI_NO_STDIO
|
451
|
-
STBIDEF float *
|
385
|
+
STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
386
|
+
STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
|
452
387
|
#endif
|
453
388
|
#endif
|
454
389
|
|
@@ -650,12 +585,14 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
|
|
650
585
|
#define STBI__X86_TARGET
|
651
586
|
#endif
|
652
587
|
|
653
|
-
#if defined(__GNUC__) &&
|
654
|
-
// NOTE: not clear do we actually need this for the 64-bit path?
|
588
|
+
#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
|
655
589
|
// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
|
656
|
-
//
|
657
|
-
//
|
658
|
-
//
|
590
|
+
// which in turn means it gets to use SSE2 everywhere. This is unfortunate,
|
591
|
+
// but previous attempts to provide the SSE2 functions with runtime
|
592
|
+
// detection caused numerous issues. The way architecture extensions are
|
593
|
+
// exposed in GCC/Clang is, sadly, not really suited for one-file libs.
|
594
|
+
// New behavior: if compiled with -msse2, we use SSE2 without any
|
595
|
+
// detection; if not, we don't use it at all.
|
659
596
|
#define STBI_NO_SIMD
|
660
597
|
#endif
|
661
598
|
|
@@ -703,7 +640,7 @@ static int stbi__cpuid3(void)
|
|
703
640
|
|
704
641
|
#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
|
705
642
|
|
706
|
-
static int stbi__sse2_available()
|
643
|
+
static int stbi__sse2_available(void)
|
707
644
|
{
|
708
645
|
int info3 = stbi__cpuid3();
|
709
646
|
return ((info3 >> 26) & 1) != 0;
|
@@ -711,16 +648,12 @@ static int stbi__sse2_available()
|
|
711
648
|
#else // assume GCC-style if not VC++
|
712
649
|
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
713
650
|
|
714
|
-
static int stbi__sse2_available()
|
651
|
+
static int stbi__sse2_available(void)
|
715
652
|
{
|
716
|
-
|
717
|
-
//
|
718
|
-
|
719
|
-
|
720
|
-
// portable way to do this, preferably without using GCC inline ASM?
|
721
|
-
// just bail for now.
|
722
|
-
return 0;
|
723
|
-
#endif
|
653
|
+
// If we're even attempting to compile this on GCC/Clang, that means
|
654
|
+
// -msse2 is on, which means the compiler is allowed to use SSE2
|
655
|
+
// instructions at will, and so are we.
|
656
|
+
return 1;
|
724
657
|
}
|
725
658
|
#endif
|
726
659
|
#endif
|
@@ -828,57 +761,70 @@ static void stbi__rewind(stbi__context *s)
|
|
828
761
|
s->img_buffer_end = s->img_buffer_original_end;
|
829
762
|
}
|
830
763
|
|
764
|
+
enum
|
765
|
+
{
|
766
|
+
STBI_ORDER_RGB,
|
767
|
+
STBI_ORDER_BGR
|
768
|
+
};
|
769
|
+
|
770
|
+
typedef struct
|
771
|
+
{
|
772
|
+
int bits_per_channel;
|
773
|
+
int num_channels;
|
774
|
+
int channel_order;
|
775
|
+
} stbi__result_info;
|
776
|
+
|
831
777
|
#ifndef STBI_NO_JPEG
|
832
778
|
static int stbi__jpeg_test(stbi__context *s);
|
833
|
-
static
|
779
|
+
static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
834
780
|
static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp);
|
835
781
|
#endif
|
836
782
|
|
837
783
|
#ifndef STBI_NO_PNG
|
838
784
|
static int stbi__png_test(stbi__context *s);
|
839
|
-
static
|
785
|
+
static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
840
786
|
static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp);
|
841
787
|
#endif
|
842
788
|
|
843
789
|
#ifndef STBI_NO_BMP
|
844
790
|
static int stbi__bmp_test(stbi__context *s);
|
845
|
-
static
|
791
|
+
static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
846
792
|
static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp);
|
847
793
|
#endif
|
848
794
|
|
849
795
|
#ifndef STBI_NO_TGA
|
850
796
|
static int stbi__tga_test(stbi__context *s);
|
851
|
-
static
|
797
|
+
static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
852
798
|
static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp);
|
853
799
|
#endif
|
854
800
|
|
855
801
|
#ifndef STBI_NO_PSD
|
856
802
|
static int stbi__psd_test(stbi__context *s);
|
857
|
-
static
|
803
|
+
static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc);
|
858
804
|
static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp);
|
859
805
|
#endif
|
860
806
|
|
861
807
|
#ifndef STBI_NO_HDR
|
862
808
|
static int stbi__hdr_test(stbi__context *s);
|
863
|
-
static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp);
|
809
|
+
static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
864
810
|
static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp);
|
865
811
|
#endif
|
866
812
|
|
867
813
|
#ifndef STBI_NO_PIC
|
868
814
|
static int stbi__pic_test(stbi__context *s);
|
869
|
-
static
|
815
|
+
static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
870
816
|
static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp);
|
871
817
|
#endif
|
872
818
|
|
873
819
|
#ifndef STBI_NO_GIF
|
874
820
|
static int stbi__gif_test(stbi__context *s);
|
875
|
-
static
|
821
|
+
static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
876
822
|
static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
|
877
823
|
#endif
|
878
824
|
|
879
825
|
#ifndef STBI_NO_PNM
|
880
826
|
static int stbi__pnm_test(stbi__context *s);
|
881
|
-
static
|
827
|
+
static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
882
828
|
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
|
883
829
|
#endif
|
884
830
|
|
@@ -1007,33 +953,38 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
|
|
1007
953
|
stbi__vertically_flip_on_load = flag_true_if_should_flip;
|
1008
954
|
}
|
1009
955
|
|
1010
|
-
static
|
956
|
+
static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
|
1011
957
|
{
|
958
|
+
memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
|
959
|
+
ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed
|
960
|
+
ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
|
961
|
+
ri->num_channels = 0;
|
962
|
+
|
1012
963
|
#ifndef STBI_NO_JPEG
|
1013
|
-
if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp);
|
964
|
+
if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
|
1014
965
|
#endif
|
1015
966
|
#ifndef STBI_NO_PNG
|
1016
|
-
if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp);
|
967
|
+
if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri);
|
1017
968
|
#endif
|
1018
969
|
#ifndef STBI_NO_BMP
|
1019
|
-
if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp);
|
970
|
+
if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri);
|
1020
971
|
#endif
|
1021
972
|
#ifndef STBI_NO_GIF
|
1022
|
-
if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp);
|
973
|
+
if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri);
|
1023
974
|
#endif
|
1024
975
|
#ifndef STBI_NO_PSD
|
1025
|
-
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp);
|
976
|
+
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
|
1026
977
|
#endif
|
1027
978
|
#ifndef STBI_NO_PIC
|
1028
|
-
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp);
|
979
|
+
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
|
1029
980
|
#endif
|
1030
981
|
#ifndef STBI_NO_PNM
|
1031
|
-
if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp);
|
982
|
+
if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri);
|
1032
983
|
#endif
|
1033
984
|
|
1034
985
|
#ifndef STBI_NO_HDR
|
1035
986
|
if (stbi__hdr_test(s)) {
|
1036
|
-
float *hdr = stbi__hdr_load(s, x,y,comp,req_comp);
|
987
|
+
float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri);
|
1037
988
|
return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
|
1038
989
|
}
|
1039
990
|
#endif
|
@@ -1041,56 +992,123 @@ static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *com
|
|
1041
992
|
#ifndef STBI_NO_TGA
|
1042
993
|
// test tga last because it's a crappy test!
|
1043
994
|
if (stbi__tga_test(s))
|
1044
|
-
return stbi__tga_load(s,x,y,comp,req_comp);
|
995
|
+
return stbi__tga_load(s,x,y,comp,req_comp, ri);
|
1045
996
|
#endif
|
1046
997
|
|
1047
998
|
return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
|
1048
999
|
}
|
1049
1000
|
|
1050
|
-
static
|
1001
|
+
static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels)
|
1051
1002
|
{
|
1052
|
-
|
1003
|
+
int i;
|
1004
|
+
int img_len = w * h * channels;
|
1005
|
+
stbi_uc *reduced;
|
1053
1006
|
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
stbi_uc
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1007
|
+
reduced = (stbi_uc *) stbi__malloc(img_len);
|
1008
|
+
if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory");
|
1009
|
+
|
1010
|
+
for (i = 0; i < img_len; ++i)
|
1011
|
+
reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling
|
1012
|
+
|
1013
|
+
STBI_FREE(orig);
|
1014
|
+
return reduced;
|
1015
|
+
}
|
1016
|
+
|
1017
|
+
static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels)
|
1018
|
+
{
|
1019
|
+
int i;
|
1020
|
+
int img_len = w * h * channels;
|
1021
|
+
stbi__uint16 *enlarged;
|
1022
|
+
|
1023
|
+
enlarged = (stbi__uint16 *) stbi__malloc(img_len*2);
|
1024
|
+
if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
|
1025
|
+
|
1026
|
+
for (i = 0; i < img_len; ++i)
|
1027
|
+
enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
|
1028
|
+
|
1029
|
+
STBI_FREE(orig);
|
1030
|
+
return enlarged;
|
1031
|
+
}
|
1032
|
+
|
1033
|
+
static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
|
1034
|
+
{
|
1035
|
+
int row;
|
1036
|
+
size_t bytes_per_row = (size_t)w * bytes_per_pixel;
|
1037
|
+
stbi_uc temp[2048];
|
1038
|
+
stbi_uc *bytes = (stbi_uc *)image;
|
1039
|
+
|
1040
|
+
for (row = 0; row < (h>>1); row++) {
|
1041
|
+
stbi_uc *row0 = bytes + row*bytes_per_row;
|
1042
|
+
stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row;
|
1043
|
+
// swap row0 with row1
|
1044
|
+
size_t bytes_left = bytes_per_row;
|
1045
|
+
while (bytes_left) {
|
1046
|
+
size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
|
1047
|
+
memcpy(temp, row0, bytes_copy);
|
1048
|
+
memcpy(row0, row1, bytes_copy);
|
1049
|
+
memcpy(row1, temp, bytes_copy);
|
1050
|
+
row0 += bytes_copy;
|
1051
|
+
row1 += bytes_copy;
|
1052
|
+
bytes_left -= bytes_copy;
|
1069
1053
|
}
|
1070
1054
|
}
|
1055
|
+
}
|
1071
1056
|
|
1072
|
-
|
1057
|
+
static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
1058
|
+
{
|
1059
|
+
stbi__result_info ri;
|
1060
|
+
void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8);
|
1061
|
+
|
1062
|
+
if (result == NULL)
|
1063
|
+
return NULL;
|
1064
|
+
|
1065
|
+
if (ri.bits_per_channel != 8) {
|
1066
|
+
STBI_ASSERT(ri.bits_per_channel == 16);
|
1067
|
+
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
1068
|
+
ri.bits_per_channel = 8;
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
// @TODO: move stbi__convert_format to here
|
1072
|
+
|
1073
|
+
if (stbi__vertically_flip_on_load) {
|
1074
|
+
int channels = req_comp ? req_comp : *comp;
|
1075
|
+
stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
|
1076
|
+
}
|
1077
|
+
|
1078
|
+
return (unsigned char *) result;
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
1082
|
+
{
|
1083
|
+
stbi__result_info ri;
|
1084
|
+
void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16);
|
1085
|
+
|
1086
|
+
if (result == NULL)
|
1087
|
+
return NULL;
|
1088
|
+
|
1089
|
+
if (ri.bits_per_channel != 16) {
|
1090
|
+
STBI_ASSERT(ri.bits_per_channel == 8);
|
1091
|
+
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
1092
|
+
ri.bits_per_channel = 16;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
// @TODO: move stbi__convert_format16 to here
|
1096
|
+
// @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision
|
1097
|
+
|
1098
|
+
if (stbi__vertically_flip_on_load) {
|
1099
|
+
int channels = req_comp ? req_comp : *comp;
|
1100
|
+
stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16));
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
return (stbi__uint16 *) result;
|
1073
1104
|
}
|
1074
1105
|
|
1075
1106
|
#ifndef STBI_NO_HDR
|
1076
1107
|
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
|
1077
1108
|
{
|
1078
1109
|
if (stbi__vertically_flip_on_load && result != NULL) {
|
1079
|
-
int
|
1080
|
-
|
1081
|
-
int row,col,z;
|
1082
|
-
float temp;
|
1083
|
-
|
1084
|
-
// @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once
|
1085
|
-
for (row = 0; row < (h>>1); row++) {
|
1086
|
-
for (col = 0; col < w; col++) {
|
1087
|
-
for (z = 0; z < depth; z++) {
|
1088
|
-
temp = result[(row * w + col) * depth + z];
|
1089
|
-
result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z];
|
1090
|
-
result[((h - row - 1) * w + col) * depth + z] = temp;
|
1091
|
-
}
|
1092
|
-
}
|
1093
|
-
}
|
1110
|
+
int channels = req_comp ? req_comp : *comp;
|
1111
|
+
stbi__vertical_flip(result, *x, *y, channels * sizeof(float));
|
1094
1112
|
}
|
1095
1113
|
}
|
1096
1114
|
#endif
|
@@ -1125,27 +1143,66 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
|
|
1125
1143
|
unsigned char *result;
|
1126
1144
|
stbi__context s;
|
1127
1145
|
stbi__start_file(&s,f);
|
1128
|
-
result =
|
1146
|
+
result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
|
1129
1147
|
if (result) {
|
1130
1148
|
// need to 'unget' all the characters in the IO buffer
|
1131
1149
|
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
|
1132
1150
|
}
|
1133
1151
|
return result;
|
1134
1152
|
}
|
1153
|
+
|
1154
|
+
STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp)
|
1155
|
+
{
|
1156
|
+
stbi__uint16 *result;
|
1157
|
+
stbi__context s;
|
1158
|
+
stbi__start_file(&s,f);
|
1159
|
+
result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
|
1160
|
+
if (result) {
|
1161
|
+
// need to 'unget' all the characters in the IO buffer
|
1162
|
+
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
|
1163
|
+
}
|
1164
|
+
return result;
|
1165
|
+
}
|
1166
|
+
|
1167
|
+
STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp)
|
1168
|
+
{
|
1169
|
+
FILE *f = stbi__fopen(filename, "rb");
|
1170
|
+
stbi__uint16 *result;
|
1171
|
+
if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file");
|
1172
|
+
result = stbi_load_from_file_16(f,x,y,comp,req_comp);
|
1173
|
+
fclose(f);
|
1174
|
+
return result;
|
1175
|
+
}
|
1176
|
+
|
1177
|
+
|
1135
1178
|
#endif //!STBI_NO_STDIO
|
1136
1179
|
|
1180
|
+
STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels)
|
1181
|
+
{
|
1182
|
+
stbi__context s;
|
1183
|
+
stbi__start_mem(&s,buffer,len);
|
1184
|
+
return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels)
|
1188
|
+
{
|
1189
|
+
stbi__context s;
|
1190
|
+
stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
|
1191
|
+
return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
|
1192
|
+
}
|
1193
|
+
|
1137
1194
|
STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
|
1138
1195
|
{
|
1139
1196
|
stbi__context s;
|
1140
1197
|
stbi__start_mem(&s,buffer,len);
|
1141
|
-
return
|
1198
|
+
return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
|
1142
1199
|
}
|
1143
1200
|
|
1144
1201
|
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
|
1145
1202
|
{
|
1146
1203
|
stbi__context s;
|
1147
1204
|
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
|
1148
|
-
return
|
1205
|
+
return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
|
1149
1206
|
}
|
1150
1207
|
|
1151
1208
|
#ifndef STBI_NO_LINEAR
|
@@ -1154,13 +1211,14 @@ static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int
|
|
1154
1211
|
unsigned char *data;
|
1155
1212
|
#ifndef STBI_NO_HDR
|
1156
1213
|
if (stbi__hdr_test(s)) {
|
1157
|
-
|
1214
|
+
stbi__result_info ri;
|
1215
|
+
float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri);
|
1158
1216
|
if (hdr_data)
|
1159
1217
|
stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
|
1160
1218
|
return hdr_data;
|
1161
1219
|
}
|
1162
1220
|
#endif
|
1163
|
-
data =
|
1221
|
+
data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp);
|
1164
1222
|
if (data)
|
1165
1223
|
return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
|
1166
1224
|
return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
|
@@ -1428,26 +1486,75 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|
1428
1486
|
unsigned char *src = data + j * x * img_n ;
|
1429
1487
|
unsigned char *dest = good + j * x * req_comp;
|
1430
1488
|
|
1431
|
-
#define
|
1432
|
-
#define
|
1489
|
+
#define STBI__COMBO(a,b) ((a)*8+(b))
|
1490
|
+
#define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
|
1491
|
+
// convert source image with img_n components to one with req_comp components;
|
1492
|
+
// avoid switch per pixel, so use switch per scanline and massive macros
|
1493
|
+
switch (STBI__COMBO(img_n, req_comp)) {
|
1494
|
+
STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break;
|
1495
|
+
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1496
|
+
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break;
|
1497
|
+
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
1498
|
+
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1499
|
+
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break;
|
1500
|
+
STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break;
|
1501
|
+
STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
1502
|
+
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break;
|
1503
|
+
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
1504
|
+
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break;
|
1505
|
+
STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
|
1506
|
+
default: STBI_ASSERT(0);
|
1507
|
+
}
|
1508
|
+
#undef STBI__CASE
|
1509
|
+
}
|
1510
|
+
|
1511
|
+
STBI_FREE(data);
|
1512
|
+
return good;
|
1513
|
+
}
|
1514
|
+
|
1515
|
+
static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
|
1516
|
+
{
|
1517
|
+
return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8);
|
1518
|
+
}
|
1519
|
+
|
1520
|
+
static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
|
1521
|
+
{
|
1522
|
+
int i,j;
|
1523
|
+
stbi__uint16 *good;
|
1524
|
+
|
1525
|
+
if (req_comp == img_n) return data;
|
1526
|
+
STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
|
1527
|
+
|
1528
|
+
good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2);
|
1529
|
+
if (good == NULL) {
|
1530
|
+
STBI_FREE(data);
|
1531
|
+
return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
|
1532
|
+
}
|
1533
|
+
|
1534
|
+
for (j=0; j < (int) y; ++j) {
|
1535
|
+
stbi__uint16 *src = data + j * x * img_n ;
|
1536
|
+
stbi__uint16 *dest = good + j * x * req_comp;
|
1537
|
+
|
1538
|
+
#define STBI__COMBO(a,b) ((a)*8+(b))
|
1539
|
+
#define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
|
1433
1540
|
// convert source image with img_n components to one with req_comp components;
|
1434
1541
|
// avoid switch per pixel, so use switch per scanline and massive macros
|
1435
|
-
switch (
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1542
|
+
switch (STBI__COMBO(img_n, req_comp)) {
|
1543
|
+
STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break;
|
1544
|
+
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1545
|
+
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break;
|
1546
|
+
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
1547
|
+
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1548
|
+
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break;
|
1549
|
+
STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break;
|
1550
|
+
STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
1551
|
+
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break;
|
1552
|
+
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
1553
|
+
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break;
|
1554
|
+
STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
|
1448
1555
|
default: STBI_ASSERT(0);
|
1449
1556
|
}
|
1450
|
-
#undef
|
1557
|
+
#undef STBI__CASE
|
1451
1558
|
}
|
1452
1559
|
|
1453
1560
|
STBI_FREE(data);
|
@@ -1547,7 +1654,7 @@ typedef struct
|
|
1547
1654
|
stbi__context *s;
|
1548
1655
|
stbi__huffman huff_dc[4];
|
1549
1656
|
stbi__huffman huff_ac[4];
|
1550
|
-
|
1657
|
+
stbi__uint16 dequant[4][64];
|
1551
1658
|
stbi__int16 fast_ac[4][1 << FAST_BITS];
|
1552
1659
|
|
1553
1660
|
// sizes for components, interleaved MCUs
|
@@ -1583,6 +1690,8 @@ typedef struct
|
|
1583
1690
|
int succ_high;
|
1584
1691
|
int succ_low;
|
1585
1692
|
int eob_run;
|
1693
|
+
int jfif;
|
1694
|
+
int app14_color_transform; // Adobe APP14 tag
|
1586
1695
|
int rgb;
|
1587
1696
|
|
1588
1697
|
int scan_n, order[4];
|
@@ -1653,7 +1762,7 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
|
|
1653
1762
|
// magnitude code followed by receive_extend code
|
1654
1763
|
int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
|
1655
1764
|
int m = 1 << (magbits - 1);
|
1656
|
-
if (k < m) k += (
|
1765
|
+
if (k < m) k += (~0U << magbits) + 1;
|
1657
1766
|
// if the result is small enough, we can fit it in fast_ac table
|
1658
1767
|
if (k >= -128 && k <= 127)
|
1659
1768
|
fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits));
|
@@ -1668,6 +1777,7 @@ static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
|
|
1668
1777
|
int b = j->nomore ? 0 : stbi__get8(j->s);
|
1669
1778
|
if (b == 0xff) {
|
1670
1779
|
int c = stbi__get8(j->s);
|
1780
|
+
while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes
|
1671
1781
|
if (c != 0) {
|
1672
1782
|
j->marker = (unsigned char) c;
|
1673
1783
|
j->nomore = 1;
|
@@ -1792,7 +1902,7 @@ static stbi_uc stbi__jpeg_dezigzag[64+15] =
|
|
1792
1902
|
};
|
1793
1903
|
|
1794
1904
|
// decode one 64-entry block--
|
1795
|
-
static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b,
|
1905
|
+
static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant)
|
1796
1906
|
{
|
1797
1907
|
int diff,dc,k;
|
1798
1908
|
int t;
|
@@ -2501,7 +2611,7 @@ static stbi_uc stbi__get_marker(stbi__jpeg *j)
|
|
2501
2611
|
x = stbi__get8(j->s);
|
2502
2612
|
if (x != 0xff) return STBI__MARKER_none;
|
2503
2613
|
while (x == 0xff)
|
2504
|
-
x = stbi__get8(j->s);
|
2614
|
+
x = stbi__get8(j->s); // consume repeated 0xff fill bytes
|
2505
2615
|
return x;
|
2506
2616
|
}
|
2507
2617
|
|
@@ -2516,7 +2626,7 @@ static void stbi__jpeg_reset(stbi__jpeg *j)
|
|
2516
2626
|
j->code_bits = 0;
|
2517
2627
|
j->code_buffer = 0;
|
2518
2628
|
j->nomore = 0;
|
2519
|
-
j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0;
|
2629
|
+
j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0;
|
2520
2630
|
j->marker = STBI__MARKER_none;
|
2521
2631
|
j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
|
2522
2632
|
j->eob_run = 0;
|
@@ -2648,7 +2758,7 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
|
|
2648
2758
|
}
|
2649
2759
|
}
|
2650
2760
|
|
2651
|
-
static void stbi__jpeg_dequantize(short *data,
|
2761
|
+
static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant)
|
2652
2762
|
{
|
2653
2763
|
int i;
|
2654
2764
|
for (i=0; i < 64; ++i)
|
@@ -2690,13 +2800,14 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
|
|
2690
2800
|
L = stbi__get16be(z->s)-2;
|
2691
2801
|
while (L > 0) {
|
2692
2802
|
int q = stbi__get8(z->s);
|
2693
|
-
int p = q >> 4;
|
2803
|
+
int p = q >> 4, sixteen = (p != 0);
|
2694
2804
|
int t = q & 15,i;
|
2695
|
-
if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG");
|
2805
|
+
if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG");
|
2696
2806
|
if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG");
|
2807
|
+
|
2697
2808
|
for (i=0; i < 64; ++i)
|
2698
|
-
z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s);
|
2699
|
-
L -= 65;
|
2809
|
+
z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s));
|
2810
|
+
L -= (sixteen ? 129 : 65);
|
2700
2811
|
}
|
2701
2812
|
return L==0;
|
2702
2813
|
|
@@ -2729,12 +2840,50 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
|
|
2729
2840
|
}
|
2730
2841
|
return L==0;
|
2731
2842
|
}
|
2843
|
+
|
2732
2844
|
// check for comment block or APP blocks
|
2733
2845
|
if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
|
2734
|
-
|
2846
|
+
L = stbi__get16be(z->s);
|
2847
|
+
if (L < 2) {
|
2848
|
+
if (m == 0xFE)
|
2849
|
+
return stbi__err("bad COM len","Corrupt JPEG");
|
2850
|
+
else
|
2851
|
+
return stbi__err("bad APP len","Corrupt JPEG");
|
2852
|
+
}
|
2853
|
+
L -= 2;
|
2854
|
+
|
2855
|
+
if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
|
2856
|
+
static const unsigned char tag[5] = {'J','F','I','F','\0'};
|
2857
|
+
int ok = 1;
|
2858
|
+
int i;
|
2859
|
+
for (i=0; i < 5; ++i)
|
2860
|
+
if (stbi__get8(z->s) != tag[i])
|
2861
|
+
ok = 0;
|
2862
|
+
L -= 5;
|
2863
|
+
if (ok)
|
2864
|
+
z->jfif = 1;
|
2865
|
+
} else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
|
2866
|
+
static const unsigned char tag[6] = {'A','d','o','b','e','\0'};
|
2867
|
+
int ok = 1;
|
2868
|
+
int i;
|
2869
|
+
for (i=0; i < 6; ++i)
|
2870
|
+
if (stbi__get8(z->s) != tag[i])
|
2871
|
+
ok = 0;
|
2872
|
+
L -= 6;
|
2873
|
+
if (ok) {
|
2874
|
+
stbi__get8(z->s); // version
|
2875
|
+
stbi__get16be(z->s); // flags0
|
2876
|
+
stbi__get16be(z->s); // flags1
|
2877
|
+
z->app14_color_transform = stbi__get8(z->s); // color transform
|
2878
|
+
L -= 6;
|
2879
|
+
}
|
2880
|
+
}
|
2881
|
+
|
2882
|
+
stbi__skip(z->s, L);
|
2735
2883
|
return 1;
|
2736
2884
|
}
|
2737
|
-
|
2885
|
+
|
2886
|
+
return stbi__err("unknown marker","Corrupt JPEG");
|
2738
2887
|
}
|
2739
2888
|
|
2740
2889
|
// after we see SOS
|
@@ -2808,7 +2957,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2808
2957
|
s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
|
2809
2958
|
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
|
2810
2959
|
c = stbi__get8(s);
|
2811
|
-
if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG");
|
2960
|
+
if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
|
2812
2961
|
s->img_n = c;
|
2813
2962
|
for (i=0; i < c; ++i) {
|
2814
2963
|
z->img_comp[i].data = NULL;
|
@@ -2821,13 +2970,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2821
2970
|
for (i=0; i < s->img_n; ++i) {
|
2822
2971
|
static unsigned char rgb[3] = { 'R', 'G', 'B' };
|
2823
2972
|
z->img_comp[i].id = stbi__get8(s);
|
2824
|
-
if (z->img_comp[i].id
|
2825
|
-
|
2826
|
-
// somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format)
|
2827
|
-
if (z->img_comp[i].id != rgb[i])
|
2828
|
-
return stbi__err("bad component ID","Corrupt JPEG");
|
2829
|
-
++z->rgb;
|
2830
|
-
}
|
2973
|
+
if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
|
2974
|
+
++z->rgb;
|
2831
2975
|
q = stbi__get8(s);
|
2832
2976
|
z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
|
2833
2977
|
z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
|
@@ -2899,6 +3043,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2899
3043
|
static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
|
2900
3044
|
{
|
2901
3045
|
int m;
|
3046
|
+
z->jfif = 0;
|
3047
|
+
z->app14_color_transform = -1; // valid values are 0,1,2
|
2902
3048
|
z->marker = STBI__MARKER_none; // initialize cached marker to empty
|
2903
3049
|
m = stbi__get_marker(z);
|
2904
3050
|
if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
|
@@ -2940,12 +3086,15 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j)
|
|
2940
3086
|
if (x == 255) {
|
2941
3087
|
j->marker = stbi__get8(j->s);
|
2942
3088
|
break;
|
2943
|
-
} else if (x != 0) {
|
2944
|
-
return stbi__err("junk before marker", "Corrupt JPEG");
|
2945
3089
|
}
|
2946
3090
|
}
|
2947
3091
|
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
|
2948
3092
|
}
|
3093
|
+
} else if (stbi__DNL(m)) {
|
3094
|
+
int Ld = stbi__get16be(j->s);
|
3095
|
+
stbi__uint32 NL = stbi__get16be(j->s);
|
3096
|
+
if (Ld != 4) stbi__err("bad DNL len", "Corrupt JPEG");
|
3097
|
+
if (NL != j->s->img_y) stbi__err("bad DNL height", "Corrupt JPEG");
|
2949
3098
|
} else {
|
2950
3099
|
if (!stbi__process_marker(j, m)) return 0;
|
2951
3100
|
}
|
@@ -3164,38 +3313,9 @@ static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_
|
|
3164
3313
|
return out;
|
3165
3314
|
}
|
3166
3315
|
|
3167
|
-
#ifdef STBI_JPEG_OLD
|
3168
|
-
// this is the same YCbCr-to-RGB calculation that stb_image has used
|
3169
|
-
// historically before the algorithm changes in 1.49
|
3170
|
-
#define float2fixed(x) ((int) ((x) * 65536 + 0.5))
|
3171
|
-
static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
|
3172
|
-
{
|
3173
|
-
int i;
|
3174
|
-
for (i=0; i < count; ++i) {
|
3175
|
-
int y_fixed = (y[i] << 16) + 32768; // rounding
|
3176
|
-
int r,g,b;
|
3177
|
-
int cr = pcr[i] - 128;
|
3178
|
-
int cb = pcb[i] - 128;
|
3179
|
-
r = y_fixed + cr*float2fixed(1.40200f);
|
3180
|
-
g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f);
|
3181
|
-
b = y_fixed + cb*float2fixed(1.77200f);
|
3182
|
-
r >>= 16;
|
3183
|
-
g >>= 16;
|
3184
|
-
b >>= 16;
|
3185
|
-
if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
|
3186
|
-
if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
|
3187
|
-
if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
|
3188
|
-
out[0] = (stbi_uc)r;
|
3189
|
-
out[1] = (stbi_uc)g;
|
3190
|
-
out[2] = (stbi_uc)b;
|
3191
|
-
out[3] = 255;
|
3192
|
-
out += step;
|
3193
|
-
}
|
3194
|
-
}
|
3195
|
-
#else
|
3196
3316
|
// this is a reduced-precision calculation of YCbCr-to-RGB introduced
|
3197
3317
|
// to make sure the code produces the same results in both SIMD and scalar
|
3198
|
-
#define
|
3318
|
+
#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8)
|
3199
3319
|
static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
|
3200
3320
|
{
|
3201
3321
|
int i;
|
@@ -3204,9 +3324,9 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
|
|
3204
3324
|
int r,g,b;
|
3205
3325
|
int cr = pcr[i] - 128;
|
3206
3326
|
int cb = pcb[i] - 128;
|
3207
|
-
r = y_fixed + cr*
|
3208
|
-
g = y_fixed + (cr*-
|
3209
|
-
b = y_fixed
|
3327
|
+
r = y_fixed + cr* stbi__float2fixed(1.40200f);
|
3328
|
+
g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
|
3329
|
+
b = y_fixed + cb* stbi__float2fixed(1.77200f);
|
3210
3330
|
r >>= 20;
|
3211
3331
|
g >>= 20;
|
3212
3332
|
b >>= 20;
|
@@ -3220,7 +3340,6 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
|
|
3220
3340
|
out += step;
|
3221
3341
|
}
|
3222
3342
|
}
|
3223
|
-
#endif
|
3224
3343
|
|
3225
3344
|
#if defined(STBI_SSE2) || defined(STBI_NEON)
|
3226
3345
|
static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step)
|
@@ -3339,9 +3458,9 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
|
|
3339
3458
|
int r,g,b;
|
3340
3459
|
int cr = pcr[i] - 128;
|
3341
3460
|
int cb = pcb[i] - 128;
|
3342
|
-
r = y_fixed + cr*
|
3343
|
-
g = y_fixed + cr*-
|
3344
|
-
b = y_fixed
|
3461
|
+
r = y_fixed + cr* stbi__float2fixed(1.40200f);
|
3462
|
+
g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
|
3463
|
+
b = y_fixed + cb* stbi__float2fixed(1.77200f);
|
3345
3464
|
r >>= 20;
|
3346
3465
|
g >>= 20;
|
3347
3466
|
b >>= 20;
|
@@ -3367,18 +3486,14 @@ static void stbi__setup_jpeg(stbi__jpeg *j)
|
|
3367
3486
|
#ifdef STBI_SSE2
|
3368
3487
|
if (stbi__sse2_available()) {
|
3369
3488
|
j->idct_block_kernel = stbi__idct_simd;
|
3370
|
-
#ifndef STBI_JPEG_OLD
|
3371
3489
|
j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
|
3372
|
-
#endif
|
3373
3490
|
j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
|
3374
3491
|
}
|
3375
3492
|
#endif
|
3376
3493
|
|
3377
3494
|
#ifdef STBI_NEON
|
3378
3495
|
j->idct_block_kernel = stbi__idct_simd;
|
3379
|
-
#ifndef STBI_JPEG_OLD
|
3380
3496
|
j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
|
3381
|
-
#endif
|
3382
3497
|
j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
|
3383
3498
|
#endif
|
3384
3499
|
}
|
@@ -3399,9 +3514,16 @@ typedef struct
|
|
3399
3514
|
int ypos; // which pre-expansion row we're on
|
3400
3515
|
} stbi__resample;
|
3401
3516
|
|
3517
|
+
// fast 0..255 * 0..255 => 0..255 rounded multiplication
|
3518
|
+
static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y)
|
3519
|
+
{
|
3520
|
+
unsigned int t = x*y + 128;
|
3521
|
+
return (stbi_uc) ((t + (t >>8)) >> 8);
|
3522
|
+
}
|
3523
|
+
|
3402
3524
|
static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
|
3403
3525
|
{
|
3404
|
-
int n, decode_n;
|
3526
|
+
int n, decode_n, is_rgb;
|
3405
3527
|
z->s->img_n = 0; // make stbi__cleanup_jpeg safe
|
3406
3528
|
|
3407
3529
|
// validate req_comp
|
@@ -3411,9 +3533,11 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3411
3533
|
if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
|
3412
3534
|
|
3413
3535
|
// determine actual number of components to generate
|
3414
|
-
n = req_comp ? req_comp : z->s->img_n;
|
3536
|
+
n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
|
3415
3537
|
|
3416
|
-
|
3538
|
+
is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
|
3539
|
+
|
3540
|
+
if (z->s->img_n == 3 && n < 3 && !is_rgb)
|
3417
3541
|
decode_n = 1;
|
3418
3542
|
else
|
3419
3543
|
decode_n = z->s->img_n;
|
@@ -3473,7 +3597,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3473
3597
|
if (n >= 3) {
|
3474
3598
|
stbi_uc *y = coutput[0];
|
3475
3599
|
if (z->s->img_n == 3) {
|
3476
|
-
if (
|
3600
|
+
if (is_rgb) {
|
3477
3601
|
for (i=0; i < z->s->img_x; ++i) {
|
3478
3602
|
out[0] = y[i];
|
3479
3603
|
out[1] = coutput[1][i];
|
@@ -3484,6 +3608,28 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3484
3608
|
} else {
|
3485
3609
|
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
|
3486
3610
|
}
|
3611
|
+
} else if (z->s->img_n == 4) {
|
3612
|
+
if (z->app14_color_transform == 0) { // CMYK
|
3613
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3614
|
+
stbi_uc m = coutput[3][i];
|
3615
|
+
out[0] = stbi__blinn_8x8(coutput[0][i], m);
|
3616
|
+
out[1] = stbi__blinn_8x8(coutput[1][i], m);
|
3617
|
+
out[2] = stbi__blinn_8x8(coutput[2][i], m);
|
3618
|
+
out[3] = 255;
|
3619
|
+
out += n;
|
3620
|
+
}
|
3621
|
+
} else if (z->app14_color_transform == 2) { // YCCK
|
3622
|
+
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
|
3623
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3624
|
+
stbi_uc m = coutput[3][i];
|
3625
|
+
out[0] = stbi__blinn_8x8(255 - out[0], m);
|
3626
|
+
out[1] = stbi__blinn_8x8(255 - out[1], m);
|
3627
|
+
out[2] = stbi__blinn_8x8(255 - out[2], m);
|
3628
|
+
out += n;
|
3629
|
+
}
|
3630
|
+
} else { // YCbCr + alpha? Ignore the fourth channel for now
|
3631
|
+
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
|
3632
|
+
}
|
3487
3633
|
} else
|
3488
3634
|
for (i=0; i < z->s->img_x; ++i) {
|
3489
3635
|
out[0] = out[1] = out[2] = y[i];
|
@@ -3491,25 +3637,54 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3491
3637
|
out += n;
|
3492
3638
|
}
|
3493
3639
|
} else {
|
3494
|
-
|
3495
|
-
|
3496
|
-
|
3497
|
-
|
3498
|
-
|
3640
|
+
if (is_rgb) {
|
3641
|
+
if (n == 1)
|
3642
|
+
for (i=0; i < z->s->img_x; ++i)
|
3643
|
+
*out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
|
3644
|
+
else {
|
3645
|
+
for (i=0; i < z->s->img_x; ++i, out += 2) {
|
3646
|
+
out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
|
3647
|
+
out[1] = 255;
|
3648
|
+
}
|
3649
|
+
}
|
3650
|
+
} else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
|
3651
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3652
|
+
stbi_uc m = coutput[3][i];
|
3653
|
+
stbi_uc r = stbi__blinn_8x8(coutput[0][i], m);
|
3654
|
+
stbi_uc g = stbi__blinn_8x8(coutput[1][i], m);
|
3655
|
+
stbi_uc b = stbi__blinn_8x8(coutput[2][i], m);
|
3656
|
+
out[0] = stbi__compute_y(r, g, b);
|
3657
|
+
out[1] = 255;
|
3658
|
+
out += n;
|
3659
|
+
}
|
3660
|
+
} else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
|
3661
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3662
|
+
out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
|
3663
|
+
out[1] = 255;
|
3664
|
+
out += n;
|
3665
|
+
}
|
3666
|
+
} else {
|
3667
|
+
stbi_uc *y = coutput[0];
|
3668
|
+
if (n == 1)
|
3669
|
+
for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
|
3670
|
+
else
|
3671
|
+
for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
|
3672
|
+
}
|
3499
3673
|
}
|
3500
3674
|
}
|
3501
3675
|
stbi__cleanup_jpeg(z);
|
3502
3676
|
*out_x = z->s->img_x;
|
3503
3677
|
*out_y = z->s->img_y;
|
3504
|
-
if (comp) *comp
|
3678
|
+
if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
|
3505
3679
|
return output;
|
3506
3680
|
}
|
3507
3681
|
}
|
3508
3682
|
|
3509
|
-
static
|
3683
|
+
static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
3510
3684
|
{
|
3511
3685
|
unsigned char* result;
|
3512
3686
|
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
|
3687
|
+
STBI_NOTUSED(ri);
|
3513
3688
|
j->s = s;
|
3514
3689
|
stbi__setup_jpeg(j);
|
3515
3690
|
result = load_jpeg_image(j, x,y,comp,req_comp);
|
@@ -3520,11 +3695,12 @@ static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *com
|
|
3520
3695
|
static int stbi__jpeg_test(stbi__context *s)
|
3521
3696
|
{
|
3522
3697
|
int r;
|
3523
|
-
stbi__jpeg j;
|
3524
|
-
j
|
3525
|
-
stbi__setup_jpeg(
|
3526
|
-
r = stbi__decode_jpeg_header(
|
3698
|
+
stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
|
3699
|
+
j->s = s;
|
3700
|
+
stbi__setup_jpeg(j);
|
3701
|
+
r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
|
3527
3702
|
stbi__rewind(s);
|
3703
|
+
STBI_FREE(j);
|
3528
3704
|
return r;
|
3529
3705
|
}
|
3530
3706
|
|
@@ -3536,7 +3712,7 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
|
|
3536
3712
|
}
|
3537
3713
|
if (x) *x = j->s->img_x;
|
3538
3714
|
if (y) *y = j->s->img_y;
|
3539
|
-
if (comp) *comp = j->s->img_n;
|
3715
|
+
if (comp) *comp = j->s->img_n >= 3 ? 3 : 1;
|
3540
3716
|
return 1;
|
3541
3717
|
}
|
3542
3718
|
|
@@ -3593,7 +3769,7 @@ stbi_inline static int stbi__bit_reverse(int v, int bits)
|
|
3593
3769
|
return stbi__bitreverse16(v) >> (16-bits);
|
3594
3770
|
}
|
3595
3771
|
|
3596
|
-
static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
|
3772
|
+
static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num)
|
3597
3773
|
{
|
3598
3774
|
int i,k=0;
|
3599
3775
|
int code, next_code[16], sizes[17];
|
@@ -3883,9 +4059,24 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
|
|
3883
4059
|
return 1;
|
3884
4060
|
}
|
3885
4061
|
|
3886
|
-
|
3887
|
-
|
3888
|
-
|
4062
|
+
static const stbi_uc stbi__zdefault_length[288] =
|
4063
|
+
{
|
4064
|
+
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
4065
|
+
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
4066
|
+
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
4067
|
+
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
4068
|
+
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
4069
|
+
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
4070
|
+
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
4071
|
+
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
4072
|
+
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8
|
4073
|
+
};
|
4074
|
+
static const stbi_uc stbi__zdefault_distance[32] =
|
4075
|
+
{
|
4076
|
+
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
|
4077
|
+
};
|
4078
|
+
/*
|
4079
|
+
Init algorithm:
|
3889
4080
|
{
|
3890
4081
|
int i; // use <= to match clearly with spec
|
3891
4082
|
for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8;
|
@@ -3895,6 +4086,7 @@ static void stbi__init_zdefaults(void)
|
|
3895
4086
|
|
3896
4087
|
for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5;
|
3897
4088
|
}
|
4089
|
+
*/
|
3898
4090
|
|
3899
4091
|
static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
3900
4092
|
{
|
@@ -3913,7 +4105,6 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
|
3913
4105
|
} else {
|
3914
4106
|
if (type == 1) {
|
3915
4107
|
// use fixed code lengths
|
3916
|
-
if (!stbi__zdefault_distance[31]) stbi__init_zdefaults();
|
3917
4108
|
if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0;
|
3918
4109
|
if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0;
|
3919
4110
|
} else {
|
@@ -4106,15 +4297,14 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4106
4297
|
|
4107
4298
|
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
4108
4299
|
img_len = (img_width_bytes + 1) * y;
|
4109
|
-
|
4110
|
-
|
4111
|
-
|
4112
|
-
|
4113
|
-
}
|
4300
|
+
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
|
4301
|
+
// but issue #276 reported a PNG in the wild that had extra data at the end (all zeros),
|
4302
|
+
// so just check for raw_len < img_len always.
|
4303
|
+
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
|
4114
4304
|
|
4115
4305
|
for (j=0; j < y; ++j) {
|
4116
4306
|
stbi_uc *cur = a->out + stride*j;
|
4117
|
-
stbi_uc *prior
|
4307
|
+
stbi_uc *prior;
|
4118
4308
|
int filter = *raw++;
|
4119
4309
|
|
4120
4310
|
if (filter > 4)
|
@@ -4126,6 +4316,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4126
4316
|
filter_bytes = 1;
|
4127
4317
|
width = img_width_bytes;
|
4128
4318
|
}
|
4319
|
+
prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
|
4129
4320
|
|
4130
4321
|
// if first row, use special filter that doesn't sample previous row
|
4131
4322
|
if (j == 0) filter = first_row_filter[filter];
|
@@ -4166,37 +4357,37 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4166
4357
|
// this is a little gross, so that we don't switch per-pixel or per-component
|
4167
4358
|
if (depth < 8 || img_n == out_n) {
|
4168
4359
|
int nk = (width - 1)*filter_bytes;
|
4169
|
-
#define
|
4360
|
+
#define STBI__CASE(f) \
|
4170
4361
|
case f: \
|
4171
4362
|
for (k=0; k < nk; ++k)
|
4172
4363
|
switch (filter) {
|
4173
4364
|
// "none" filter turns into a memcpy here; make that explicit.
|
4174
4365
|
case STBI__F_none: memcpy(cur, raw, nk); break;
|
4175
|
-
|
4176
|
-
|
4177
|
-
|
4178
|
-
|
4179
|
-
|
4180
|
-
|
4366
|
+
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
|
4367
|
+
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
4368
|
+
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
|
4369
|
+
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
|
4370
|
+
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
|
4371
|
+
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
|
4181
4372
|
}
|
4182
|
-
#undef
|
4373
|
+
#undef STBI__CASE
|
4183
4374
|
raw += nk;
|
4184
4375
|
} else {
|
4185
4376
|
STBI_ASSERT(img_n+1 == out_n);
|
4186
|
-
#define
|
4377
|
+
#define STBI__CASE(f) \
|
4187
4378
|
case f: \
|
4188
4379
|
for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
|
4189
4380
|
for (k=0; k < filter_bytes; ++k)
|
4190
4381
|
switch (filter) {
|
4191
|
-
|
4192
|
-
|
4193
|
-
|
4194
|
-
|
4195
|
-
|
4196
|
-
|
4197
|
-
|
4382
|
+
STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break;
|
4383
|
+
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
|
4384
|
+
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
4385
|
+
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
|
4386
|
+
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
|
4387
|
+
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
|
4388
|
+
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
|
4198
4389
|
}
|
4199
|
-
#undef
|
4390
|
+
#undef STBI__CASE
|
4200
4391
|
|
4201
4392
|
// the loop above sets the high byte of the pixels' alpha, but for
|
4202
4393
|
// 16 bit png files we also need the low byte set. we'll do that here.
|
@@ -4428,27 +4619,6 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
|
|
4428
4619
|
return 1;
|
4429
4620
|
}
|
4430
4621
|
|
4431
|
-
static int stbi__reduce_png(stbi__png *p)
|
4432
|
-
{
|
4433
|
-
int i;
|
4434
|
-
int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n;
|
4435
|
-
stbi_uc *reduced;
|
4436
|
-
stbi__uint16 *orig = (stbi__uint16*)p->out;
|
4437
|
-
|
4438
|
-
if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data
|
4439
|
-
|
4440
|
-
reduced = (stbi_uc *)stbi__malloc(img_len);
|
4441
|
-
if (reduced == NULL) return stbi__err("outofmem", "Out of memory");
|
4442
|
-
|
4443
|
-
for (i = 0; i < img_len; ++i)
|
4444
|
-
reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling
|
4445
|
-
|
4446
|
-
p->out = reduced;
|
4447
|
-
STBI_FREE(orig);
|
4448
|
-
|
4449
|
-
return 1;
|
4450
|
-
}
|
4451
|
-
|
4452
4622
|
static int stbi__unpremultiply_on_load = 0;
|
4453
4623
|
static int stbi__de_iphone_flag = 0;
|
4454
4624
|
|
@@ -4483,9 +4653,10 @@ static void stbi__de_iphone(stbi__png *z)
|
|
4483
4653
|
stbi_uc a = p[3];
|
4484
4654
|
stbi_uc t = p[0];
|
4485
4655
|
if (a) {
|
4486
|
-
|
4487
|
-
p[
|
4488
|
-
p[
|
4656
|
+
stbi_uc half = a / 2;
|
4657
|
+
p[0] = (p[2] * 255 + half) / a;
|
4658
|
+
p[1] = (p[1] * 255 + half) / a;
|
4659
|
+
p[2] = ( t * 255 + half) / a;
|
4489
4660
|
} else {
|
4490
4661
|
p[0] = p[2];
|
4491
4662
|
p[2] = t;
|
@@ -4539,7 +4710,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4539
4710
|
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
4540
4711
|
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
|
4541
4712
|
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
|
4542
|
-
|
4713
|
+
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
|
4543
4714
|
if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
|
4544
4715
|
comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
|
4545
4716
|
filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG");
|
@@ -4588,7 +4759,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4588
4759
|
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
|
4589
4760
|
has_trans = 1;
|
4590
4761
|
if (z->depth == 16) {
|
4591
|
-
for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is
|
4762
|
+
for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
4592
4763
|
} else {
|
4593
4764
|
for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
|
4594
4765
|
}
|
@@ -4648,6 +4819,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4648
4819
|
if (req_comp >= 3) s->img_out_n = req_comp;
|
4649
4820
|
if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n))
|
4650
4821
|
return 0;
|
4822
|
+
} else if (has_trans) {
|
4823
|
+
// non-paletted image with tRNS -> source image has (constant) alpha
|
4824
|
+
++s->img_n;
|
4651
4825
|
}
|
4652
4826
|
STBI_FREE(z->expanded); z->expanded = NULL;
|
4653
4827
|
return 1;
|
@@ -4675,20 +4849,22 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4675
4849
|
}
|
4676
4850
|
}
|
4677
4851
|
|
4678
|
-
static
|
4852
|
+
static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri)
|
4679
4853
|
{
|
4680
|
-
|
4854
|
+
void *result=NULL;
|
4681
4855
|
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
|
4682
4856
|
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
|
4683
|
-
if (p->depth
|
4684
|
-
|
4685
|
-
|
4686
|
-
|
4687
|
-
}
|
4857
|
+
if (p->depth < 8)
|
4858
|
+
ri->bits_per_channel = 8;
|
4859
|
+
else
|
4860
|
+
ri->bits_per_channel = p->depth;
|
4688
4861
|
result = p->out;
|
4689
4862
|
p->out = NULL;
|
4690
4863
|
if (req_comp && req_comp != p->s->img_out_n) {
|
4691
|
-
|
4864
|
+
if (ri->bits_per_channel == 8)
|
4865
|
+
result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
|
4866
|
+
else
|
4867
|
+
result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
|
4692
4868
|
p->s->img_out_n = req_comp;
|
4693
4869
|
if (result == NULL) return result;
|
4694
4870
|
}
|
@@ -4703,11 +4879,11 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
|
|
4703
4879
|
return result;
|
4704
4880
|
}
|
4705
4881
|
|
4706
|
-
static
|
4882
|
+
static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
4707
4883
|
{
|
4708
4884
|
stbi__png p;
|
4709
4885
|
p.s = s;
|
4710
|
-
return stbi__do_png(&p, x,y,comp,req_comp);
|
4886
|
+
return stbi__do_png(&p, x,y,comp,req_comp, ri);
|
4711
4887
|
}
|
4712
4888
|
|
4713
4889
|
static int stbi__png_test(stbi__context *s)
|
@@ -4789,19 +4965,22 @@ static int stbi__bitcount(unsigned int a)
|
|
4789
4965
|
|
4790
4966
|
static int stbi__shiftsigned(int v, int shift, int bits)
|
4791
4967
|
{
|
4792
|
-
|
4793
|
-
|
4794
|
-
|
4795
|
-
|
4796
|
-
|
4797
|
-
|
4798
|
-
|
4799
|
-
|
4800
|
-
|
4801
|
-
|
4802
|
-
|
4803
|
-
|
4804
|
-
|
4968
|
+
static unsigned int mul_table[9] = {
|
4969
|
+
0,
|
4970
|
+
0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/,
|
4971
|
+
0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/,
|
4972
|
+
};
|
4973
|
+
static unsigned int shift_table[9] = {
|
4974
|
+
0, 0,0,1,0,2,4,6,0,
|
4975
|
+
};
|
4976
|
+
if (shift < 0)
|
4977
|
+
v <<= -shift;
|
4978
|
+
else
|
4979
|
+
v >>= shift;
|
4980
|
+
assert(v >= 0 && v < 256);
|
4981
|
+
v >>= (8-bits);
|
4982
|
+
assert(bits >= 0 && bits <= 8);
|
4983
|
+
return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
|
4805
4984
|
}
|
4806
4985
|
|
4807
4986
|
typedef struct
|
@@ -4820,7 +4999,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
|
4820
4999
|
info->offset = stbi__get32le(s);
|
4821
5000
|
info->hsz = hsz = stbi__get32le(s);
|
4822
5001
|
info->mr = info->mg = info->mb = info->ma = 0;
|
4823
|
-
|
5002
|
+
|
4824
5003
|
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
|
4825
5004
|
if (hsz == 12) {
|
4826
5005
|
s->img_x = stbi__get16le(s);
|
@@ -4895,7 +5074,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
|
4895
5074
|
}
|
4896
5075
|
|
4897
5076
|
|
4898
|
-
static
|
5077
|
+
static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
4899
5078
|
{
|
4900
5079
|
stbi_uc *out;
|
4901
5080
|
unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
|
@@ -4903,8 +5082,9 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4903
5082
|
int psize=0,i,j,width;
|
4904
5083
|
int flip_vertically, pad, target;
|
4905
5084
|
stbi__bmp_data info;
|
5085
|
+
STBI_NOTUSED(ri);
|
4906
5086
|
|
4907
|
-
info.all_a = 255;
|
5087
|
+
info.all_a = 255;
|
4908
5088
|
if (stbi__bmp_parse_header(s, &info) == NULL)
|
4909
5089
|
return NULL; // error code already set
|
4910
5090
|
|
@@ -5023,7 +5203,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5023
5203
|
stbi__skip(s, pad);
|
5024
5204
|
}
|
5025
5205
|
}
|
5026
|
-
|
5206
|
+
|
5027
5207
|
// if alpha channel is all 0s, replace with all 255s
|
5028
5208
|
if (target == 4 && all_a == 0)
|
5029
5209
|
for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
|
@@ -5169,18 +5349,18 @@ errorEnd:
|
|
5169
5349
|
}
|
5170
5350
|
|
5171
5351
|
// read 16bit value and convert to 24bit RGB
|
5172
|
-
void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
|
5352
|
+
static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
|
5173
5353
|
{
|
5174
|
-
stbi__uint16 px = stbi__get16le(s);
|
5354
|
+
stbi__uint16 px = (stbi__uint16)stbi__get16le(s);
|
5175
5355
|
stbi__uint16 fiveBitMask = 31;
|
5176
5356
|
// we have 3 channels with 5bits each
|
5177
5357
|
int r = (px >> 10) & fiveBitMask;
|
5178
5358
|
int g = (px >> 5) & fiveBitMask;
|
5179
5359
|
int b = px & fiveBitMask;
|
5180
5360
|
// Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
|
5181
|
-
out[0] = (r * 255)/31;
|
5182
|
-
out[1] = (g * 255)/31;
|
5183
|
-
out[2] = (b * 255)/31;
|
5361
|
+
out[0] = (stbi_uc)((r * 255)/31);
|
5362
|
+
out[1] = (stbi_uc)((g * 255)/31);
|
5363
|
+
out[2] = (stbi_uc)((b * 255)/31);
|
5184
5364
|
|
5185
5365
|
// some people claim that the most significant bit might be used for alpha
|
5186
5366
|
// (possibly if an alpha-bit is set in the "image descriptor byte")
|
@@ -5188,7 +5368,7 @@ void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
|
|
5188
5368
|
// so let's treat all 15 and 16bit TGAs as RGB with no alpha.
|
5189
5369
|
}
|
5190
5370
|
|
5191
|
-
static
|
5371
|
+
static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
5192
5372
|
{
|
5193
5373
|
// read in the TGA header stuff
|
5194
5374
|
int tga_offset = stbi__get8(s);
|
@@ -5210,10 +5390,11 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5210
5390
|
unsigned char *tga_data;
|
5211
5391
|
unsigned char *tga_palette = NULL;
|
5212
5392
|
int i, j;
|
5213
|
-
unsigned char raw_data[4];
|
5393
|
+
unsigned char raw_data[4] = {0};
|
5214
5394
|
int RLE_count = 0;
|
5215
5395
|
int RLE_repeating = 0;
|
5216
5396
|
int read_next_pixel = 1;
|
5397
|
+
STBI_NOTUSED(ri);
|
5217
5398
|
|
5218
5399
|
// do a tiny bit of precessing
|
5219
5400
|
if ( tga_image_type >= 8 )
|
@@ -5431,7 +5612,7 @@ static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount)
|
|
5431
5612
|
return 1;
|
5432
5613
|
}
|
5433
5614
|
|
5434
|
-
static
|
5615
|
+
static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
|
5435
5616
|
{
|
5436
5617
|
int pixelCount;
|
5437
5618
|
int channelCount, compression;
|
@@ -5439,6 +5620,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5439
5620
|
int bitdepth;
|
5440
5621
|
int w,h;
|
5441
5622
|
stbi_uc *out;
|
5623
|
+
STBI_NOTUSED(ri);
|
5442
5624
|
|
5443
5625
|
// Check identifier
|
5444
5626
|
if (stbi__get32be(s) != 0x38425053) // "8BPS"
|
@@ -5500,7 +5682,13 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5500
5682
|
return stbi__errpuc("too large", "Corrupt PSD");
|
5501
5683
|
|
5502
5684
|
// Create the destination image.
|
5503
|
-
|
5685
|
+
|
5686
|
+
if (!compression && bitdepth == 16 && bpc == 16) {
|
5687
|
+
out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0);
|
5688
|
+
ri->bits_per_channel = 16;
|
5689
|
+
} else
|
5690
|
+
out = (stbi_uc *) stbi__malloc(4 * w*h);
|
5691
|
+
|
5504
5692
|
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
5505
5693
|
pixelCount = w*h;
|
5506
5694
|
|
@@ -5541,48 +5729,77 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5541
5729
|
|
5542
5730
|
} else {
|
5543
5731
|
// We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
|
5544
|
-
// where each channel consists of an 8-bit value for each pixel in the image.
|
5732
|
+
// where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image.
|
5545
5733
|
|
5546
5734
|
// Read the data by channel.
|
5547
5735
|
for (channel = 0; channel < 4; channel++) {
|
5548
|
-
stbi_uc *p;
|
5549
|
-
|
5550
|
-
p = out + channel;
|
5551
5736
|
if (channel >= channelCount) {
|
5552
5737
|
// Fill this channel with default data.
|
5553
|
-
|
5554
|
-
|
5555
|
-
|
5556
|
-
|
5557
|
-
|
5558
|
-
if (bitdepth == 16) {
|
5559
|
-
for (i = 0; i < pixelCount; i++, p += 4)
|
5560
|
-
*p = (stbi_uc) (stbi__get16be(s) >> 8);
|
5738
|
+
if (bitdepth == 16 && bpc == 16) {
|
5739
|
+
stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
|
5740
|
+
stbi__uint16 val = channel == 3 ? 65535 : 0;
|
5741
|
+
for (i = 0; i < pixelCount; i++, q += 4)
|
5742
|
+
*q = val;
|
5561
5743
|
} else {
|
5744
|
+
stbi_uc *p = out+channel;
|
5745
|
+
stbi_uc val = channel == 3 ? 255 : 0;
|
5562
5746
|
for (i = 0; i < pixelCount; i++, p += 4)
|
5563
|
-
*p =
|
5747
|
+
*p = val;
|
5748
|
+
}
|
5749
|
+
} else {
|
5750
|
+
if (ri->bits_per_channel == 16) { // output bpc
|
5751
|
+
stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
|
5752
|
+
for (i = 0; i < pixelCount; i++, q += 4)
|
5753
|
+
*q = (stbi__uint16) stbi__get16be(s);
|
5754
|
+
} else {
|
5755
|
+
stbi_uc *p = out+channel;
|
5756
|
+
if (bitdepth == 16) { // input bpc
|
5757
|
+
for (i = 0; i < pixelCount; i++, p += 4)
|
5758
|
+
*p = (stbi_uc) (stbi__get16be(s) >> 8);
|
5759
|
+
} else {
|
5760
|
+
for (i = 0; i < pixelCount; i++, p += 4)
|
5761
|
+
*p = stbi__get8(s);
|
5762
|
+
}
|
5564
5763
|
}
|
5565
5764
|
}
|
5566
5765
|
}
|
5567
5766
|
}
|
5568
5767
|
|
5768
|
+
// remove weird white matte from PSD
|
5569
5769
|
if (channelCount >= 4) {
|
5570
|
-
|
5571
|
-
|
5572
|
-
|
5573
|
-
|
5574
|
-
|
5575
|
-
|
5576
|
-
|
5577
|
-
|
5578
|
-
|
5579
|
-
|
5770
|
+
if (ri->bits_per_channel == 16) {
|
5771
|
+
for (i=0; i < w*h; ++i) {
|
5772
|
+
stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i;
|
5773
|
+
if (pixel[3] != 0 && pixel[3] != 65535) {
|
5774
|
+
float a = pixel[3] / 65535.0f;
|
5775
|
+
float ra = 1.0f / a;
|
5776
|
+
float inv_a = 65535.0f * (1 - ra);
|
5777
|
+
pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a);
|
5778
|
+
pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a);
|
5779
|
+
pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a);
|
5780
|
+
}
|
5781
|
+
}
|
5782
|
+
} else {
|
5783
|
+
for (i=0; i < w*h; ++i) {
|
5784
|
+
unsigned char *pixel = out + 4*i;
|
5785
|
+
if (pixel[3] != 0 && pixel[3] != 255) {
|
5786
|
+
float a = pixel[3] / 255.0f;
|
5787
|
+
float ra = 1.0f / a;
|
5788
|
+
float inv_a = 255.0f * (1 - ra);
|
5789
|
+
pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
|
5790
|
+
pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
|
5791
|
+
pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
|
5792
|
+
}
|
5580
5793
|
}
|
5581
5794
|
}
|
5582
5795
|
}
|
5583
5796
|
|
5797
|
+
// convert to desired output format
|
5584
5798
|
if (req_comp && req_comp != 4) {
|
5585
|
-
|
5799
|
+
if (ri->bits_per_channel == 16)
|
5800
|
+
out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h);
|
5801
|
+
else
|
5802
|
+
out = stbi__convert_format(out, 4, req_comp, w, h);
|
5586
5803
|
if (out == NULL) return out; // stbi__convert_format frees input on failure
|
5587
5804
|
}
|
5588
5805
|
|
@@ -5766,10 +5983,13 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c
|
|
5766
5983
|
return result;
|
5767
5984
|
}
|
5768
5985
|
|
5769
|
-
static
|
5986
|
+
static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri)
|
5770
5987
|
{
|
5771
5988
|
stbi_uc *result;
|
5772
|
-
int i, x,y;
|
5989
|
+
int i, x,y, internal_comp;
|
5990
|
+
STBI_NOTUSED(ri);
|
5991
|
+
|
5992
|
+
if (!comp) comp = &internal_comp;
|
5773
5993
|
|
5774
5994
|
for (i=0; i<92; ++i)
|
5775
5995
|
stbi__get8(s);
|
@@ -6154,11 +6374,12 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|
6154
6374
|
STBI_NOTUSED(req_comp);
|
6155
6375
|
}
|
6156
6376
|
|
6157
|
-
static
|
6377
|
+
static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
6158
6378
|
{
|
6159
6379
|
stbi_uc *u = 0;
|
6160
6380
|
stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
|
6161
6381
|
memset(g, 0, sizeof(*g));
|
6382
|
+
STBI_NOTUSED(ri);
|
6162
6383
|
|
6163
6384
|
u = stbi__gif_load_next(s, g, comp, req_comp);
|
6164
6385
|
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
|
@@ -6184,20 +6405,24 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6184
6405
|
// Radiance RGBE HDR loader
|
6185
6406
|
// originally by Nicolas Schulz
|
6186
6407
|
#ifndef STBI_NO_HDR
|
6187
|
-
static int stbi__hdr_test_core(stbi__context *s)
|
6408
|
+
static int stbi__hdr_test_core(stbi__context *s, const char *signature)
|
6188
6409
|
{
|
6189
|
-
const char *signature = "#?RADIANCE\n";
|
6190
6410
|
int i;
|
6191
6411
|
for (i=0; signature[i]; ++i)
|
6192
6412
|
if (stbi__get8(s) != signature[i])
|
6193
|
-
|
6413
|
+
return 0;
|
6414
|
+
stbi__rewind(s);
|
6194
6415
|
return 1;
|
6195
6416
|
}
|
6196
6417
|
|
6197
6418
|
static int stbi__hdr_test(stbi__context* s)
|
6198
6419
|
{
|
6199
|
-
int r = stbi__hdr_test_core(s);
|
6420
|
+
int r = stbi__hdr_test_core(s, "#?RADIANCE\n");
|
6200
6421
|
stbi__rewind(s);
|
6422
|
+
if(!r) {
|
6423
|
+
r = stbi__hdr_test_core(s, "#?RGBE\n");
|
6424
|
+
stbi__rewind(s);
|
6425
|
+
}
|
6201
6426
|
return r;
|
6202
6427
|
}
|
6203
6428
|
|
@@ -6251,7 +6476,7 @@ static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp)
|
|
6251
6476
|
}
|
6252
6477
|
}
|
6253
6478
|
|
6254
|
-
static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
6479
|
+
static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
6255
6480
|
{
|
6256
6481
|
char buffer[STBI__HDR_BUFLEN];
|
6257
6482
|
char *token;
|
@@ -6262,10 +6487,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|
6262
6487
|
int len;
|
6263
6488
|
unsigned char count, value;
|
6264
6489
|
int i, j, k, c1,c2, z;
|
6265
|
-
|
6490
|
+
const char *headerToken;
|
6491
|
+
STBI_NOTUSED(ri);
|
6266
6492
|
|
6267
6493
|
// Check identifier
|
6268
|
-
|
6494
|
+
headerToken = stbi__hdr_gettoken(s,buffer);
|
6495
|
+
if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0)
|
6269
6496
|
return stbi__errpf("not HDR", "Corrupt HDR image");
|
6270
6497
|
|
6271
6498
|
// Parse header
|
@@ -6382,6 +6609,11 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6382
6609
|
char buffer[STBI__HDR_BUFLEN];
|
6383
6610
|
char *token;
|
6384
6611
|
int valid = 0;
|
6612
|
+
int dummy;
|
6613
|
+
|
6614
|
+
if (!x) x = &dummy;
|
6615
|
+
if (!y) y = &dummy;
|
6616
|
+
if (!comp) comp = &dummy;
|
6385
6617
|
|
6386
6618
|
if (stbi__hdr_test(s) == 0) {
|
6387
6619
|
stbi__rewind( s );
|
@@ -6423,14 +6655,14 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6423
6655
|
void *p;
|
6424
6656
|
stbi__bmp_data info;
|
6425
6657
|
|
6426
|
-
info.all_a = 255;
|
6658
|
+
info.all_a = 255;
|
6427
6659
|
p = stbi__bmp_parse_header(s, &info);
|
6428
6660
|
stbi__rewind( s );
|
6429
6661
|
if (p == NULL)
|
6430
6662
|
return 0;
|
6431
|
-
*x = s->img_x;
|
6432
|
-
*y = s->img_y;
|
6433
|
-
*comp = info.ma ? 4 : 3;
|
6663
|
+
if (x) *x = s->img_x;
|
6664
|
+
if (y) *y = s->img_y;
|
6665
|
+
if (comp) *comp = info.ma ? 4 : 3;
|
6434
6666
|
return 1;
|
6435
6667
|
}
|
6436
6668
|
#endif
|
@@ -6438,7 +6670,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6438
6670
|
#ifndef STBI_NO_PSD
|
6439
6671
|
static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
|
6440
6672
|
{
|
6441
|
-
int channelCount;
|
6673
|
+
int channelCount, dummy;
|
6674
|
+
if (!x) x = &dummy;
|
6675
|
+
if (!y) y = &dummy;
|
6676
|
+
if (!comp) comp = &dummy;
|
6442
6677
|
if (stbi__get32be(s) != 0x38425053) {
|
6443
6678
|
stbi__rewind( s );
|
6444
6679
|
return 0;
|
@@ -6471,9 +6706,13 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6471
6706
|
#ifndef STBI_NO_PIC
|
6472
6707
|
static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
|
6473
6708
|
{
|
6474
|
-
int act_comp=0,num_packets=0,chained;
|
6709
|
+
int act_comp=0,num_packets=0,chained,dummy;
|
6475
6710
|
stbi__pic_packet packets[10];
|
6476
6711
|
|
6712
|
+
if (!x) x = &dummy;
|
6713
|
+
if (!y) y = &dummy;
|
6714
|
+
if (!comp) comp = &dummy;
|
6715
|
+
|
6477
6716
|
if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
|
6478
6717
|
stbi__rewind(s);
|
6479
6718
|
return 0;
|
@@ -6549,14 +6788,17 @@ static int stbi__pnm_test(stbi__context *s)
|
|
6549
6788
|
return 1;
|
6550
6789
|
}
|
6551
6790
|
|
6552
|
-
static
|
6791
|
+
static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
6553
6792
|
{
|
6554
6793
|
stbi_uc *out;
|
6794
|
+
STBI_NOTUSED(ri);
|
6795
|
+
|
6555
6796
|
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
|
6556
6797
|
return 0;
|
6798
|
+
|
6557
6799
|
*x = s->img_x;
|
6558
6800
|
*y = s->img_y;
|
6559
|
-
*comp = s->img_n;
|
6801
|
+
if (comp) *comp = s->img_n;
|
6560
6802
|
|
6561
6803
|
if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
|
6562
6804
|
return stbi__errpuc("too large", "PNM too large");
|
@@ -6610,16 +6852,20 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c)
|
|
6610
6852
|
|
6611
6853
|
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
|
6612
6854
|
{
|
6613
|
-
int maxv;
|
6855
|
+
int maxv, dummy;
|
6614
6856
|
char c, p, t;
|
6615
6857
|
|
6616
|
-
|
6858
|
+
if (!x) x = &dummy;
|
6859
|
+
if (!y) y = &dummy;
|
6860
|
+
if (!comp) comp = &dummy;
|
6861
|
+
|
6862
|
+
stbi__rewind(s);
|
6617
6863
|
|
6618
6864
|
// Get identifier
|
6619
6865
|
p = (char) stbi__get8(s);
|
6620
6866
|
t = (char) stbi__get8(s);
|
6621
6867
|
if (p != 'P' || (t != '5' && t != '6')) {
|
6622
|
-
stbi__rewind(
|
6868
|
+
stbi__rewind(s);
|
6623
6869
|
return 0;
|
6624
6870
|
}
|
6625
6871
|
|
@@ -6726,6 +6972,19 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
|
6726
6972
|
|
6727
6973
|
/*
|
6728
6974
|
revision history:
|
6975
|
+
2.16 (2017-07-23) all functions have 16-bit variants;
|
6976
|
+
STBI_NO_STDIO works again;
|
6977
|
+
compilation fixes;
|
6978
|
+
fix rounding in unpremultiply;
|
6979
|
+
optimize vertical flip;
|
6980
|
+
disable raw_len validation;
|
6981
|
+
documentation fixes
|
6982
|
+
2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
|
6983
|
+
warning fixes; disable run-time SSE detection on gcc;
|
6984
|
+
uniform handling of optional "return" values;
|
6985
|
+
thread-safe initialization of zlib tables
|
6986
|
+
2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
|
6987
|
+
2.13 (2016-11-29) add 16-bit API, only supported for PNG right now
|
6729
6988
|
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
|
6730
6989
|
2.11 (2016-04-02) allocate large structures on the stack
|
6731
6990
|
remove white matting for transparent PSD
|
@@ -6886,3 +7145,46 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
|
6886
7145
|
0.50 (2006-11-19)
|
6887
7146
|
first released version
|
6888
7147
|
*/
|
7148
|
+
|
7149
|
+
|
7150
|
+
/*
|
7151
|
+
------------------------------------------------------------------------------
|
7152
|
+
This software is available under 2 licenses -- choose whichever you prefer.
|
7153
|
+
------------------------------------------------------------------------------
|
7154
|
+
ALTERNATIVE A - MIT License
|
7155
|
+
Copyright (c) 2017 Sean Barrett
|
7156
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
7157
|
+
this software and associated documentation files (the "Software"), to deal in
|
7158
|
+
the Software without restriction, including without limitation the rights to
|
7159
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7160
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
7161
|
+
so, subject to the following conditions:
|
7162
|
+
The above copyright notice and this permission notice shall be included in all
|
7163
|
+
copies or substantial portions of the Software.
|
7164
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
7165
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
7166
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
7167
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
7168
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
7169
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
7170
|
+
SOFTWARE.
|
7171
|
+
------------------------------------------------------------------------------
|
7172
|
+
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
7173
|
+
This is free and unencumbered software released into the public domain.
|
7174
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
7175
|
+
software, either in source code form or as a compiled binary, for any purpose,
|
7176
|
+
commercial or non-commercial, and by any means.
|
7177
|
+
In jurisdictions that recognize copyright laws, the author or authors of this
|
7178
|
+
software dedicate any and all copyright interest in the software to the public
|
7179
|
+
domain. We make this dedication for the benefit of the public at large and to
|
7180
|
+
the detriment of our heirs and successors. We intend this dedication to be an
|
7181
|
+
overt act of relinquishment in perpetuity of all present and future rights to
|
7182
|
+
this software under copyright law.
|
7183
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
7184
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
7185
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
7186
|
+
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
7187
|
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
7188
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
7189
|
+
------------------------------------------------------------------------------
|
7190
|
+
*/
|