gosu 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
*/
|