tiny_gltf 0.1.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +3 -0
- data/Gemfile.lock +3 -3
- data/bin/setup +2 -0
- data/ext/tiny_gltf/rb_tiny_gltf.h +18 -7
- data/ext/tiny_gltf/rb_tiny_gltf_accessor.cpp +4 -12
- data/ext/tiny_gltf/rb_tiny_gltf_animation.cpp +6 -5
- data/ext/tiny_gltf/rb_tiny_gltf_animation_channel.cpp +6 -5
- data/ext/tiny_gltf/rb_tiny_gltf_animation_sampler.cpp +6 -5
- data/ext/tiny_gltf/rb_tiny_gltf_asset.cpp +4 -3
- data/ext/tiny_gltf/rb_tiny_gltf_buffer.cpp +37 -8
- data/ext/tiny_gltf/rb_tiny_gltf_buffer_view.cpp +4 -3
- data/ext/tiny_gltf/rb_tiny_gltf_camera.cpp +4 -3
- data/ext/tiny_gltf/rb_tiny_gltf_extension_map.cpp +2 -2
- data/ext/tiny_gltf/rb_tiny_gltf_image.cpp +72 -12
- data/ext/tiny_gltf/rb_tiny_gltf_init.c +66 -1
- data/ext/tiny_gltf/rb_tiny_gltf_light.cpp +2 -1
- data/ext/tiny_gltf/rb_tiny_gltf_material.cpp +6 -5
- data/ext/tiny_gltf/rb_tiny_gltf_mesh.cpp +5 -17
- data/ext/tiny_gltf/rb_tiny_gltf_model.cpp +10 -10
- data/ext/tiny_gltf/rb_tiny_gltf_node.cpp +8 -7
- data/ext/tiny_gltf/rb_tiny_gltf_parameter_map.cpp +2 -2
- data/ext/tiny_gltf/rb_tiny_gltf_primitive.cpp +8 -7
- data/ext/tiny_gltf/rb_tiny_gltf_sampler.cpp +3 -2
- data/ext/tiny_gltf/rb_tiny_gltf_scene.cpp +7 -6
- data/ext/tiny_gltf/rb_tiny_gltf_skin.cpp +6 -5
- data/ext/tiny_gltf/rb_tiny_gltf_texture.cpp +7 -6
- data/ext/tiny_gltf/rb_tiny_gltf_types.cpp +7 -7
- data/ext/tiny_gltf/rb_tiny_gltf_value.cpp +5 -4
- data/ext/tiny_gltf/stb_image.h +1890 -869
- data/ext/tiny_gltf/stb_image_write.h +1241 -1451
- data/ext/tiny_gltf/tiny_gltf.h +3671 -1082
- data/lib/tiny_gltf.rb +385 -126
- data/lib/tiny_gltf/version.rb +1 -1
- metadata +4 -4
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rLight_new(const Light *light) {
|
3
|
+
VALUE rLight_new(const Light *light, VALUE rmodel) {
|
4
4
|
VALUE rlight = rb_funcall(rb_cLight, rb_intern("new"), 0);
|
5
5
|
// *Light_unwrap(rlight) = *light;
|
6
6
|
|
@@ -8,6 +8,7 @@ VALUE rLight_new(const Light *light) {
|
|
8
8
|
for (size_t i = 0; i < light->color.size(); i++)
|
9
9
|
rb_ary_push(rcolor, DBL2NUM(light->color[i]));
|
10
10
|
|
11
|
+
rb_ivar_set(rlight, rb_intern("@model"), rmodel);
|
11
12
|
rb_ivar_set(rlight, rb_intern("@name"), rb_str_new2(light->name.c_str()));
|
12
13
|
rb_ivar_set(rlight, rb_intern("@type"), rb_intern(light->type.c_str()));
|
13
14
|
rb_ivar_set(rlight, rb_intern("@color"), rcolor);
|
@@ -1,14 +1,15 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rMaterial_new(const Material *matr) {
|
3
|
+
VALUE rMaterial_new(const Material *matr, VALUE rmodel) {
|
4
4
|
VALUE rmatr = rb_funcall(rb_cMaterial, rb_intern("new"), 0);
|
5
5
|
// *Material_unwrap(rmatr) = *matr;
|
6
6
|
|
7
|
+
rb_ivar_set(rmatr, rb_intern("@model"), rmodel);
|
7
8
|
rb_ivar_set(rmatr, rb_intern("@name"), rb_str_new2(matr->name.c_str()));
|
8
|
-
rb_ivar_set(rmatr, rb_intern("@values"), rParameterMap_new(&matr->values));
|
9
|
-
rb_ivar_set(rmatr, rb_intern("@additional_values"), rParameterMap_new(&matr->additionalValues));
|
10
|
-
rb_ivar_set(rmatr, rb_intern("@extensions"), rExtensionMap_new(&matr->extensions));
|
11
|
-
rb_ivar_set(rmatr, rb_intern("@extras"), rValue_new(&matr->extras));
|
9
|
+
rb_ivar_set(rmatr, rb_intern("@values"), rParameterMap_new(&matr->values, rmodel));
|
10
|
+
rb_ivar_set(rmatr, rb_intern("@additional_values"), rParameterMap_new(&matr->additionalValues, rmodel));
|
11
|
+
rb_ivar_set(rmatr, rb_intern("@extensions"), rExtensionMap_new(&matr->extensions, rmodel));
|
12
|
+
rb_ivar_set(rmatr, rb_intern("@extras"), rValue_new(&matr->extras, rmodel));
|
12
13
|
|
13
14
|
return rmatr;
|
14
15
|
}
|
@@ -1,24 +1,12 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rMesh_new(const Mesh *mesh) {
|
3
|
+
VALUE rMesh_new(const Mesh *mesh, VALUE rmodel) {
|
4
4
|
VALUE rmesh = rb_funcall(rb_cMesh, rb_intern("new"), 0);
|
5
5
|
// *Mesh_unwrap(rmesh) = *mesh;
|
6
6
|
|
7
|
-
VALUE rtargets = rb_ary_new();
|
8
|
-
for (size_t i = 0; i < mesh->targets.size(); i++) {
|
9
|
-
VALUE rtarget = rb_hash_new();
|
10
|
-
rb_ary_push(rtargets, rtarget);
|
11
|
-
for (std::map<std::string, int>::const_iterator it = mesh->targets[i].begin();
|
12
|
-
it != mesh->targets[i].end(); ++it) {
|
13
|
-
std::string key = it->first;
|
14
|
-
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
|
15
|
-
rb_hash_aset(rtarget, ID2SYM(rb_intern(key.c_str())), INT2NUM(it->second));
|
16
|
-
}
|
17
|
-
}
|
18
|
-
|
19
7
|
VALUE rprimitives = rb_ary_new();
|
20
8
|
for (size_t i = 0; i < mesh->primitives.size(); i++) {
|
21
|
-
rb_ary_push(rprimitives, rPrimitive_new(&mesh->primitives[i]));
|
9
|
+
rb_ary_push(rprimitives, rPrimitive_new(&mesh->primitives[i], rmodel));
|
22
10
|
}
|
23
11
|
|
24
12
|
VALUE rweights = rb_ary_new();
|
@@ -26,12 +14,12 @@ VALUE rMesh_new(const Mesh *mesh) {
|
|
26
14
|
rb_ary_push(rprimitives, DBL2NUM(mesh->weights[i]));
|
27
15
|
}
|
28
16
|
|
17
|
+
rb_ivar_set(rmesh, rb_intern("@model"), rmodel);
|
29
18
|
rb_ivar_set(rmesh, rb_intern("@name"), rb_str_new2(mesh->name.c_str()));
|
30
19
|
rb_ivar_set(rmesh, rb_intern("@primitives"), rprimitives);
|
31
20
|
rb_ivar_set(rmesh, rb_intern("@weights"), rweights);
|
32
|
-
rb_ivar_set(rmesh, rb_intern("@extensions"), rExtensionMap_new(&mesh->extensions));
|
33
|
-
rb_ivar_set(rmesh, rb_intern("@
|
34
|
-
rb_ivar_set(rmesh, rb_intern("@extras"), rValue_new(&mesh->extras));
|
21
|
+
rb_ivar_set(rmesh, rb_intern("@extensions"), rExtensionMap_new(&mesh->extensions, rmodel));
|
22
|
+
rb_ivar_set(rmesh, rb_intern("@extras"), rValue_new(&mesh->extras, rmodel));
|
35
23
|
|
36
24
|
return rmesh;
|
37
25
|
}
|
@@ -12,24 +12,24 @@ VALUE rModel_new(const Model *model) {
|
|
12
12
|
for (size_t i = 0; i < model->extensionsRequired.size(); i++)
|
13
13
|
rb_ary_push(rext_required, rb_str_new2(model->extensionsRequired[i].c_str()));
|
14
14
|
|
15
|
-
rb_ivar_set(rmodel, rb_intern("@asset"), rAsset_new(&model->asset));
|
16
|
-
rb_ivar_set(rmodel, rb_intern("@default_scene_index"),
|
17
|
-
rb_ivar_set(rmodel, rb_intern("@extensions"), rExtensionMap_new(&model->extensions));
|
18
|
-
rb_ivar_set(rmodel, rb_intern("@extras"), rValue_new(&model->extras));
|
15
|
+
rb_ivar_set(rmodel, rb_intern("@asset"), rAsset_new(&model->asset, rmodel));
|
16
|
+
rb_ivar_set(rmodel, rb_intern("@default_scene_index"), RINDEX_OR_NIL(model->defaultScene));
|
17
|
+
rb_ivar_set(rmodel, rb_intern("@extensions"), rExtensionMap_new(&model->extensions, rmodel));
|
18
|
+
rb_ivar_set(rmodel, rb_intern("@extras"), rValue_new(&model->extras, rmodel));
|
19
19
|
rb_ivar_set(rmodel, rb_intern("@extensions_used"), rext_used);
|
20
20
|
rb_ivar_set(rmodel, rb_intern("@extensions_required"), rext_required);
|
21
21
|
|
22
22
|
/*
|
23
23
|
VALUE ary = rb_funcall(rmodel, rb_intern("accessors"), 0);
|
24
24
|
for (size_t i = 0; i < model->accessors.size(); i++) {
|
25
|
-
rb_ary_push(ary, rAccessor_new(&model->accessors[i]));
|
25
|
+
rb_ary_push(ary, rAccessor_new(&model->accessors[i], rmodel));
|
26
26
|
}
|
27
27
|
*/
|
28
|
-
#define CONCAT_VECTOR_TO_RARRAY3(klass, name, method) {
|
29
|
-
VALUE ary = rb_funcall(rmodel, rb_intern(method), 0);
|
30
|
-
for (size_t i = 0; i < model->name.size(); i++) {
|
31
|
-
rb_ary_push(ary, r ## klass ## _new(&model->name[i])); \
|
32
|
-
}
|
28
|
+
#define CONCAT_VECTOR_TO_RARRAY3(klass, name, method) { \
|
29
|
+
VALUE ary = rb_funcall(rmodel, rb_intern(method), 0); \
|
30
|
+
for (size_t i = 0; i < model->name.size(); i++) { \
|
31
|
+
rb_ary_push(ary, r ## klass ## _new(&model->name[i], rmodel)); \
|
32
|
+
} \
|
33
33
|
}
|
34
34
|
#define CONCAT_VECTOR_TO_RARRAY(klass, name) CONCAT_VECTOR_TO_RARRAY3(klass, name, #name)
|
35
35
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rNode_new(const Node *node) {
|
3
|
+
VALUE rNode_new(const Node *node, VALUE rmodel) {
|
4
4
|
VALUE rnode = rb_funcall(rb_cNode, rb_intern("new"), 0);
|
5
5
|
// *Node_unwrap(rnode) = *node;
|
6
6
|
|
@@ -10,7 +10,7 @@ VALUE rNode_new(const Node *node) {
|
|
10
10
|
|
11
11
|
VALUE rchildren = rb_ary_new();
|
12
12
|
for (size_t i = 0; i < node->children.size(); i++)
|
13
|
-
rb_ary_push(rchildren,
|
13
|
+
rb_ary_push(rchildren, RINDEX_OR_NIL(node->children[i]));
|
14
14
|
|
15
15
|
VALUE rmatrix = Qnil, rrotation = Qnil, rtranslation = Qnil, rscale = Qnil;
|
16
16
|
if (node->matrix.size() == 0) {
|
@@ -50,18 +50,19 @@ VALUE rNode_new(const Node *node) {
|
|
50
50
|
rb_ary_push(rmatrix, INT2NUM(node->matrix[i]));
|
51
51
|
}
|
52
52
|
|
53
|
+
rb_ivar_set(rnode, rb_intern("@model"), rmodel);
|
53
54
|
rb_ivar_set(rnode, rb_intern("@name"), rb_str_new2(node->name.c_str()));
|
54
|
-
rb_ivar_set(rnode, rb_intern("@camera_index"),
|
55
|
-
rb_ivar_set(rnode, rb_intern("@skin_index"),
|
56
|
-
rb_ivar_set(rnode, rb_intern("@mesh_index"),
|
55
|
+
rb_ivar_set(rnode, rb_intern("@camera_index"), RINDEX_OR_NIL(node->camera));
|
56
|
+
rb_ivar_set(rnode, rb_intern("@skin_index"), RINDEX_OR_NIL(node->skin));
|
57
|
+
rb_ivar_set(rnode, rb_intern("@mesh_index"), RINDEX_OR_NIL(node->mesh));
|
57
58
|
rb_ivar_set(rnode, rb_intern("@children_indices"), rchildren);
|
58
59
|
rb_ivar_set(rnode, rb_intern("@rotation"), rrotation);
|
59
60
|
rb_ivar_set(rnode, rb_intern("@translation"), rtranslation);
|
60
61
|
rb_ivar_set(rnode, rb_intern("@scale"), rscale);
|
61
62
|
rb_ivar_set(rnode, rb_intern("@matrix"), rmatrix);
|
62
63
|
rb_ivar_set(rnode, rb_intern("@weights"), rweights);
|
63
|
-
rb_ivar_set(rnode, rb_intern("@extensions"), rExtensionMap_new(&node->extensions));
|
64
|
-
rb_ivar_set(rnode, rb_intern("@extras"), rValue_new(&node->extras));
|
64
|
+
rb_ivar_set(rnode, rb_intern("@extensions"), rExtensionMap_new(&node->extensions, rmodel));
|
65
|
+
rb_ivar_set(rnode, rb_intern("@extras"), rValue_new(&node->extras, rmodel));
|
65
66
|
|
66
67
|
return rnode;
|
67
68
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rParameterMap_new(const ParameterMap *value) {
|
3
|
+
VALUE rParameterMap_new(const ParameterMap *value, VALUE rmodel) {
|
4
4
|
VALUE res = Qnil;
|
5
5
|
|
6
6
|
for (ParameterMap::const_iterator paramIt = value->begin(); paramIt != value->end();
|
@@ -19,7 +19,7 @@ VALUE rParameterMap_new(const ParameterMap *value) {
|
|
19
19
|
paramIt->second.json_double_value.begin();
|
20
20
|
it != paramIt->second.json_double_value.end(); ++it) {
|
21
21
|
if (it->first == "index") {
|
22
|
-
rb_hash_aset(val, ID2SYM(rb_intern("index")),
|
22
|
+
rb_hash_aset(val, ID2SYM(rb_intern("index")), RINDEX_OR_NIL(paramIt->second.TextureIndex()));
|
23
23
|
} else {
|
24
24
|
rb_hash_aset(val, ID2SYM(rb_intern(it->first.c_str())), DBL2NUM(it->second));
|
25
25
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rPrimitive_new(const Primitive *prim) {
|
3
|
+
VALUE rPrimitive_new(const Primitive *prim, VALUE rmodel) {
|
4
4
|
VALUE rprim = rb_funcall(rb_cPrimitive, rb_intern("new"), 0);
|
5
5
|
// *Primitive_unwrap(rprim) = *prim;
|
6
6
|
|
@@ -24,12 +24,13 @@ VALUE rPrimitive_new(const Primitive *prim) {
|
|
24
24
|
}
|
25
25
|
}
|
26
26
|
|
27
|
-
rb_ivar_set(rprim, rb_intern("@
|
28
|
-
rb_ivar_set(rprim, rb_intern("@
|
29
|
-
rb_ivar_set(rprim, rb_intern("@
|
30
|
-
rb_ivar_set(rprim, rb_intern("@
|
31
|
-
rb_ivar_set(rprim, rb_intern("@
|
32
|
-
rb_ivar_set(rprim, rb_intern("@
|
27
|
+
rb_ivar_set(rprim, rb_intern("@model"), rmodel);
|
28
|
+
rb_ivar_set(rprim, rb_intern("@attributes"), rattrs);
|
29
|
+
rb_ivar_set(rprim, rb_intern("@material_index"), RINDEX_OR_NIL(prim->material));
|
30
|
+
rb_ivar_set(rprim, rb_intern("@indices_index"), RINDEX_OR_NIL(prim->indices));
|
31
|
+
rb_ivar_set(rprim, rb_intern("@mode"), mode_to_sym(prim->mode));
|
32
|
+
rb_ivar_set(rprim, rb_intern("@morph_targets_indices"), rtargets);
|
33
|
+
rb_ivar_set(rprim, rb_intern("@extras"), rValue_new(&prim->extras, rmodel));
|
33
34
|
|
34
35
|
return rprim;
|
35
36
|
}
|
@@ -1,16 +1,17 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rSampler_new(const Sampler *sampler) {
|
3
|
+
VALUE rSampler_new(const Sampler *sampler, VALUE rmodel) {
|
4
4
|
VALUE rsampler = rb_funcall(rb_cSampler, rb_intern("new"), 0);
|
5
5
|
// *Sampler_unwrap(rsampler) = *sampler;
|
6
6
|
|
7
|
+
rb_ivar_set(rsampler, rb_intern("@model"), rmodel);
|
7
8
|
rb_ivar_set(rsampler, rb_intern("@name"), rb_str_new2(sampler->name.c_str()));
|
8
9
|
rb_ivar_set(rsampler, rb_intern("@min_filter"), texture_filter_to_sym(sampler->minFilter));
|
9
10
|
rb_ivar_set(rsampler, rb_intern("@mag_filter"), texture_filter_to_sym(sampler->magFilter));
|
10
11
|
rb_ivar_set(rsampler, rb_intern("@wrap_s"), texture_wrap_to_sym(sampler->wrapS));
|
11
12
|
rb_ivar_set(rsampler, rb_intern("@wrap_t"), texture_wrap_to_sym(sampler->wrapT));
|
12
13
|
rb_ivar_set(rsampler, rb_intern("@wrap_r"), texture_wrap_to_sym(sampler->wrapR));
|
13
|
-
rb_ivar_set(rsampler, rb_intern("@extras"), rValue_new(&sampler->extras));
|
14
|
+
rb_ivar_set(rsampler, rb_intern("@extras"), rValue_new(&sampler->extras, rmodel));
|
14
15
|
|
15
16
|
return rsampler;
|
16
17
|
}
|
@@ -1,17 +1,18 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rScene_new(const Scene *scene) {
|
3
|
+
VALUE rScene_new(const Scene *scene, VALUE rmodel) {
|
4
4
|
VALUE rscene = rb_funcall(rb_cScene, rb_intern("new"), 0);
|
5
5
|
// *Scene_unwrap(rscene) = *scene;
|
6
6
|
|
7
7
|
VALUE rnodes = rb_ary_new();
|
8
8
|
for (size_t i = 0; i < scene->nodes.size(); i++)
|
9
|
-
rb_ary_push(rnodes,
|
9
|
+
rb_ary_push(rnodes, RINDEX_OR_NIL(scene->nodes[i]));
|
10
10
|
|
11
|
-
rb_ivar_set(rscene, rb_intern("@
|
12
|
-
rb_ivar_set(rscene, rb_intern("@
|
13
|
-
rb_ivar_set(rscene, rb_intern("@
|
14
|
-
rb_ivar_set(rscene, rb_intern("@
|
11
|
+
rb_ivar_set(rscene, rb_intern("@model"), rmodel);
|
12
|
+
rb_ivar_set(rscene, rb_intern("@name"), rb_str_new2(scene->name.c_str()));
|
13
|
+
rb_ivar_set(rscene, rb_intern("@nodes_indices"), rnodes);
|
14
|
+
rb_ivar_set(rscene, rb_intern("@extensions"), rExtensionMap_new(&scene->extensions, rmodel));
|
15
|
+
rb_ivar_set(rscene, rb_intern("@extras"), rValue_new(&scene->extras, rmodel));
|
15
16
|
|
16
17
|
return rscene;
|
17
18
|
}
|
@@ -1,17 +1,18 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rSkin_new(const Skin *skin) {
|
3
|
+
VALUE rSkin_new(const Skin *skin, VALUE rmodel) {
|
4
4
|
VALUE rskin = rb_funcall(rb_cSkin, rb_intern("new"), 0);
|
5
5
|
// *Skin_unwrap(rskin) = *skin;
|
6
6
|
|
7
7
|
VALUE rjoints = rb_ary_new();
|
8
8
|
for (size_t i = 0; i < skin->joints.size(); i++)
|
9
|
-
rb_ary_push(rjoints,
|
9
|
+
rb_ary_push(rjoints, RINDEX_OR_NIL(skin->joints[i]));
|
10
10
|
|
11
|
+
rb_ivar_set(rskin, rb_intern("@model"), rmodel);
|
11
12
|
rb_ivar_set(rskin, rb_intern("@name"), rb_str_new2(skin->name.c_str()));
|
12
|
-
rb_ivar_set(rskin, rb_intern("@inverse_bind_matrices"),
|
13
|
-
rb_ivar_set(rskin, rb_intern("@skeleton_root_node_index"),
|
14
|
-
rb_ivar_set(rskin, rb_intern("@
|
13
|
+
rb_ivar_set(rskin, rb_intern("@inverse_bind_matrices"), RINDEX_OR_NIL(skin->inverseBindMatrices));
|
14
|
+
rb_ivar_set(rskin, rb_intern("@skeleton_root_node_index"), RINDEX_OR_NIL(skin->skeleton));
|
15
|
+
rb_ivar_set(rskin, rb_intern("@joint_nodes_indices"), rjoints);
|
15
16
|
|
16
17
|
return rskin;
|
17
18
|
}
|
@@ -1,14 +1,15 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rTexture_new(const Texture *texture) {
|
3
|
+
VALUE rTexture_new(const Texture *texture, VALUE rmodel) {
|
4
4
|
VALUE rtexture = rb_funcall(rb_cTexture, rb_intern("new"), 0);
|
5
5
|
// *Texture_unwrap(rtexture) = *texture;
|
6
6
|
|
7
|
-
rb_ivar_set(rtexture, rb_intern("@
|
8
|
-
rb_ivar_set(rtexture, rb_intern("@
|
9
|
-
rb_ivar_set(rtexture, rb_intern("@
|
10
|
-
rb_ivar_set(rtexture, rb_intern("@
|
11
|
-
rb_ivar_set(rtexture, rb_intern("@
|
7
|
+
rb_ivar_set(rtexture, rb_intern("@model"), rmodel);
|
8
|
+
rb_ivar_set(rtexture, rb_intern("@name"), rb_str_new2(texture->name.c_str()));
|
9
|
+
rb_ivar_set(rtexture, rb_intern("@sampler_index"), RINDEX_OR_NIL(texture->sampler));
|
10
|
+
rb_ivar_set(rtexture, rb_intern("@source_index"), RINDEX_OR_NIL(texture->source));
|
11
|
+
rb_ivar_set(rtexture, rb_intern("@extensions"), rExtensionMap_new(&texture->extensions, rmodel));
|
12
|
+
rb_ivar_set(rtexture, rb_intern("@extras"), rValue_new(&texture->extras, rmodel));
|
12
13
|
|
13
14
|
return rtexture;
|
14
15
|
}
|
@@ -1,12 +1,12 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
3
|
/*
|
4
|
-
void
|
5
|
-
Model *
|
6
|
-
delete
|
4
|
+
void Model_free(void* data) {
|
5
|
+
Model *obj = (Model *) data;
|
6
|
+
delete obj;
|
7
7
|
}
|
8
8
|
|
9
|
-
size_t
|
9
|
+
size_t Model_size(const void* data) {
|
10
10
|
return sizeof(Model);
|
11
11
|
}
|
12
12
|
|
@@ -14,8 +14,8 @@
|
|
14
14
|
.wrap_struct_name = "TinyGLTFModel",
|
15
15
|
.function = {
|
16
16
|
.dmark = NULL,
|
17
|
-
.dfree =
|
18
|
-
.dsize =
|
17
|
+
.dfree = Model_free,
|
18
|
+
.dsize = Model_size,
|
19
19
|
.reserved = { 0, 0 }
|
20
20
|
},
|
21
21
|
.parent = NULL,
|
@@ -23,7 +23,7 @@
|
|
23
23
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
24
24
|
};
|
25
25
|
|
26
|
-
VALUE
|
26
|
+
VALUE Model_alloc(VALUE klass) {
|
27
27
|
return TypedData_Wrap_Struct(klass, &T_Model, new Model());
|
28
28
|
}
|
29
29
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
#include "rb_tiny_gltf.h"
|
2
2
|
|
3
|
-
VALUE rValue_new(const Value *value) {
|
3
|
+
VALUE rValue_new(const Value *value, VALUE rmodel) {
|
4
4
|
switch(value->Type()) {
|
5
5
|
case NULL_TYPE: return Qnil;
|
6
|
-
case
|
6
|
+
case REAL_TYPE: return DBL2NUM(value->Get<double>());
|
7
7
|
case INT_TYPE: return INT2NUM(value->Get<int>());
|
8
8
|
case BOOL_TYPE: return value->Get<bool>() ? Qtrue : Qfalse;
|
9
9
|
case STRING_TYPE: return rb_str_new2(value->Get<std::string>().c_str());
|
@@ -14,7 +14,7 @@ VALUE rValue_new(const Value *value) {
|
|
14
14
|
case ARRAY_TYPE: {
|
15
15
|
VALUE ary = rb_ary_new();
|
16
16
|
for (size_t i = 0; i < value->ArrayLen(); i++) {
|
17
|
-
rb_ary_push(ary, rValue_new(&value->Get((int) i)));
|
17
|
+
rb_ary_push(ary, rValue_new(&value->Get((int) i), rmodel));
|
18
18
|
}
|
19
19
|
return ary;
|
20
20
|
}
|
@@ -22,11 +22,12 @@ VALUE rValue_new(const Value *value) {
|
|
22
22
|
VALUE hash = rb_hash_new();
|
23
23
|
std::vector<std::string> keys = value->Keys();
|
24
24
|
for (std::string key : keys) {
|
25
|
-
rb_hash_aset(hash, rb_str_new2(key.c_str()), rValue_new(&value->Get(key)));
|
25
|
+
rb_hash_aset(hash, rb_str_new2(key.c_str()), rValue_new(&value->Get(key), rmodel));
|
26
26
|
}
|
27
27
|
return hash;
|
28
28
|
}
|
29
29
|
default:
|
30
|
+
rb_raise(rb_eRuntimeError, "Don't know what to do with GLTF type %d", (int) value->Type());
|
30
31
|
return Qnil;
|
31
32
|
}
|
32
33
|
}
|
data/ext/tiny_gltf/stb_image.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
/* stb_image - v2.
|
2
|
-
|
1
|
+
/* stb_image - v2.21 - public domain image loader - http://nothings.org/stb
|
2
|
+
no warranty implied; use at your own risk
|
3
3
|
|
4
4
|
Do this:
|
5
5
|
#define STB_IMAGE_IMPLEMENTATION
|
@@ -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,184 +42,68 @@
|
|
42
42
|
Full documentation under "DOCUMENTATION" below.
|
43
43
|
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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:
|
149
|
-
2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
|
150
|
-
2.07 (2015-09-13) partial animated GIF support
|
151
|
-
limited 16-bit PSD support
|
152
|
-
minor bugs, code cleanup, and compiler warnings
|
153
|
-
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
|
154
|
-
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
|
155
|
-
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
|
156
|
-
2.03 (2015-04-12) additional corruption checking
|
157
|
-
stbi_set_flip_vertically_on_load
|
158
|
-
fix NEON support; fix mingw support
|
159
|
-
2.02 (2015-01-19) fix incorrect assert, fix warning
|
160
|
-
2.01 (2015-01-17) fix various warnings
|
161
|
-
2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
|
162
|
-
2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD
|
163
|
-
progressive JPEG
|
164
|
-
PGM/PPM support
|
165
|
-
STBI_MALLOC,STBI_REALLOC,STBI_FREE
|
166
|
-
STBI_NO_*, STBI_ONLY_*
|
167
|
-
GIF bugfix
|
168
|
-
1.48 (2014-12-14) fix incorrectly-named assert()
|
169
|
-
1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted)
|
170
|
-
optimize PNG
|
171
|
-
fix bug in interlaced PNG with user-specified channel count
|
45
|
+
LICENSE
|
46
|
+
|
47
|
+
See end of file for license information.
|
48
|
+
|
49
|
+
RECENT REVISION HISTORY:
|
50
|
+
|
51
|
+
2.21 (2019-02-25) fix typo in comment
|
52
|
+
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
|
53
|
+
2.19 (2018-02-11) fix warning
|
54
|
+
2.18 (2018-01-30) fix warnings
|
55
|
+
2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
|
56
|
+
2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
|
57
|
+
2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
|
58
|
+
2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
|
59
|
+
2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
|
60
|
+
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
|
61
|
+
2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
|
62
|
+
RGB-format JPEG; remove white matting in PSD;
|
63
|
+
allocate large structures on the stack;
|
64
|
+
correct channel count for PNG & BMP
|
65
|
+
2.10 (2016-01-22) avoid warning introduced in 2.09
|
66
|
+
2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
|
172
67
|
|
173
68
|
See end of file for full revision history.
|
174
69
|
|
175
70
|
|
176
71
|
============================ Contributors =========================
|
177
72
|
|
178
|
-
Image formats
|
179
|
-
Sean Barrett (jpeg, png, bmp)
|
180
|
-
Nicolas Schulz (hdr, psd)
|
181
|
-
Jonathan Dummer (tga)
|
182
|
-
Jean-Marc Lienher (gif)
|
183
|
-
Tom Seddon (pic)
|
184
|
-
Thatcher Ulrich (psd)
|
185
|
-
Ken Miller (pgm, ppm)
|
186
|
-
urraka
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
Phil Jordan
|
213
|
-
Nathan Reed
|
214
|
-
Michaelangel007@github
|
215
|
-
Nick Verigakis
|
216
|
-
|
217
|
-
LICENSE
|
218
|
-
|
219
|
-
This software is in the public domain. Where that dedication is not
|
220
|
-
recognized, you are granted a perpetual, irrevocable license to copy,
|
221
|
-
distribute, and modify this file as you see fit.
|
222
|
-
|
73
|
+
Image formats Extensions, features
|
74
|
+
Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info)
|
75
|
+
Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info)
|
76
|
+
Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG)
|
77
|
+
Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks)
|
78
|
+
Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG)
|
79
|
+
Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip)
|
80
|
+
Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
|
81
|
+
github:urraka (animated gif) Junggon Kim (PNM comments)
|
82
|
+
Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA)
|
83
|
+
socks-the-fox (16-bit PNG)
|
84
|
+
Jeremy Sawicki (handle all ImageNet JPGs)
|
85
|
+
Optimizations & bugfixes Mikhail Morozov (1-bit BMP)
|
86
|
+
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
|
87
|
+
Arseny Kapoulkine
|
88
|
+
John-Mark Allen
|
89
|
+
Carmelo J Fdez-Aguera
|
90
|
+
|
91
|
+
Bug & warning fixes
|
92
|
+
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
93
|
+
Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
|
94
|
+
Dave Moore Roy Eltham Hayaki Saito Nathan Reed
|
95
|
+
Won Chun Luke Graham Johan Duparc Nick Verigakis
|
96
|
+
the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh
|
97
|
+
Janez Zemva John Bartholomew Michal Cichon github:romigrou
|
98
|
+
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
|
99
|
+
Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar
|
100
|
+
Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex
|
101
|
+
Ryamond Barbiero Paul Du Bois Engin Manap github:grim210
|
102
|
+
Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
|
103
|
+
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
|
104
|
+
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
|
105
|
+
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
|
106
|
+
Blazej Dariusz Roszkowski github:Michaelangel007
|
223
107
|
*/
|
224
108
|
|
225
109
|
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
@@ -228,10 +112,8 @@ distribute, and modify this file as you see fit.
|
|
228
112
|
// DOCUMENTATION
|
229
113
|
//
|
230
114
|
// Limitations:
|
231
|
-
// - no 16-bit-per-channel PNG
|
232
115
|
// - no 12-bit-per-channel JPEG
|
233
116
|
// - no JPEGs with arithmetic coding
|
234
|
-
// - no 1-bit BMP
|
235
117
|
// - GIF always returns *comp=4
|
236
118
|
//
|
237
119
|
// Basic usage (see HDR discussion below for HDR usage):
|
@@ -244,10 +126,10 @@ distribute, and modify this file as you see fit.
|
|
244
126
|
// stbi_image_free(data)
|
245
127
|
//
|
246
128
|
// Standard parameters:
|
247
|
-
// int *x
|
248
|
-
// int *y
|
249
|
-
// int *
|
250
|
-
// int
|
129
|
+
// int *x -- outputs image width in pixels
|
130
|
+
// int *y -- outputs image height in pixels
|
131
|
+
// int *channels_in_file -- outputs # of image components in image file
|
132
|
+
// int desired_channels -- if non-zero, # of image components requested in result
|
251
133
|
//
|
252
134
|
// The return value from an image loader is an 'unsigned char *' which points
|
253
135
|
// to the pixel data, or NULL on an allocation failure or if the image is
|
@@ -255,11 +137,12 @@ distribute, and modify this file as you see fit.
|
|
255
137
|
// with each pixel consisting of N interleaved 8-bit components; the first
|
256
138
|
// pixel pointed to is top-left-most in the image. There is no padding between
|
257
139
|
// image scanlines or between pixels, regardless of format. The number of
|
258
|
-
// components N is '
|
259
|
-
// If
|
260
|
-
//
|
261
|
-
//
|
262
|
-
//
|
140
|
+
// components N is 'desired_channels' if desired_channels is non-zero, or
|
141
|
+
// *channels_in_file otherwise. If desired_channels is non-zero,
|
142
|
+
// *channels_in_file has the number of components that _would_ have been
|
143
|
+
// output otherwise. E.g. if you set desired_channels to 4, you will always
|
144
|
+
// get RGBA output, but you can check *channels_in_file to see if it's trivially
|
145
|
+
// opaque because e.g. there were only 3 channels in the source image.
|
263
146
|
//
|
264
147
|
// An output image with N components has the following components interleaved
|
265
148
|
// in this order in each pixel:
|
@@ -271,16 +154,26 @@ distribute, and modify this file as you see fit.
|
|
271
154
|
// 4 red, green, blue, alpha
|
272
155
|
//
|
273
156
|
// If image loading fails for any reason, the return value will be NULL,
|
274
|
-
// and *x, *y, *
|
275
|
-
// can be queried for an extremely brief, end-user
|
276
|
-
// of why the load failed. Define STBI_NO_FAILURE_STRINGS
|
277
|
-
// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
|
157
|
+
// and *x, *y, *channels_in_file will be unchanged. The function
|
158
|
+
// stbi_failure_reason() can be queried for an extremely brief, end-user
|
159
|
+
// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS
|
160
|
+
// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
|
278
161
|
// more user-friendly ones.
|
279
162
|
//
|
280
163
|
// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
|
281
164
|
//
|
282
165
|
// ===========================================================================
|
283
166
|
//
|
167
|
+
// UNICODE:
|
168
|
+
//
|
169
|
+
// If compiling for Windows and you wish to use Unicode filenames, compile
|
170
|
+
// with
|
171
|
+
// #define STBI_WINDOWS_UTF8
|
172
|
+
// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert
|
173
|
+
// Windows wchar_t filenames to utf8.
|
174
|
+
//
|
175
|
+
// ===========================================================================
|
176
|
+
//
|
284
177
|
// Philosophy
|
285
178
|
//
|
286
179
|
// stb libraries are designed with the following priorities:
|
@@ -291,15 +184,15 @@ distribute, and modify this file as you see fit.
|
|
291
184
|
//
|
292
185
|
// Sometimes I let "good performance" creep up in priority over "easy to maintain",
|
293
186
|
// and for best performance I may provide less-easy-to-use APIs that give higher
|
294
|
-
// performance, in addition to the easy
|
187
|
+
// performance, in addition to the easy-to-use ones. Nevertheless, it's important
|
295
188
|
// to keep in mind that from the standpoint of you, a client of this library,
|
296
|
-
// all you care about is #1 and #3, and stb libraries
|
189
|
+
// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
|
297
190
|
//
|
298
191
|
// Some secondary priorities arise directly from the first two, some of which
|
299
|
-
//
|
192
|
+
// provide more explicit reasons why performance can't be emphasized.
|
300
193
|
//
|
301
194
|
// - Portable ("ease of use")
|
302
|
-
// - Small footprint ("easy to maintain")
|
195
|
+
// - Small source code footprint ("easy to maintain")
|
303
196
|
// - No dependencies ("ease of use")
|
304
197
|
//
|
305
198
|
// ===========================================================================
|
@@ -331,13 +224,6 @@ distribute, and modify this file as you see fit.
|
|
331
224
|
// (at least this is true for iOS and Android). Therefore, the NEON support is
|
332
225
|
// toggled by a build flag: define STBI_NEON to get NEON loops.
|
333
226
|
//
|
334
|
-
// The output of the JPEG decoder is slightly different from versions where
|
335
|
-
// SIMD support was introduced (that is, for versions before 1.49). The
|
336
|
-
// difference is only +-1 in the 8-bit RGB channels, and only on a small
|
337
|
-
// fraction of pixels. You can force the pre-1.49 behavior by defining
|
338
|
-
// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path
|
339
|
-
// and hence cost some performance.
|
340
|
-
//
|
341
227
|
// If for some reason you do not want to use any of SIMD code, or if
|
342
228
|
// you have issues compiling it, you can disable it entirely by
|
343
229
|
// defining STBI_NO_SIMD.
|
@@ -346,11 +232,10 @@ distribute, and modify this file as you see fit.
|
|
346
232
|
//
|
347
233
|
// HDR image support (disable by defining STBI_NO_HDR)
|
348
234
|
//
|
349
|
-
// stb_image
|
350
|
-
//
|
351
|
-
//
|
352
|
-
//
|
353
|
-
// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
235
|
+
// stb_image supports loading HDR images in general, and currently the Radiance
|
236
|
+
// .HDR file format specifically. You can still load any file through the existing
|
237
|
+
// interface; if you attempt to load an HDR file, it will be automatically remapped
|
238
|
+
// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
354
239
|
// both of these constants can be reconfigured through this interface:
|
355
240
|
//
|
356
241
|
// stbi_hdr_to_ldr_gamma(2.2f);
|
@@ -384,7 +269,7 @@ distribute, and modify this file as you see fit.
|
|
384
269
|
//
|
385
270
|
// By default we convert iphone-formatted PNGs back to RGB, even though
|
386
271
|
// they are internally encoded differently. You can disable this conversion
|
387
|
-
// by
|
272
|
+
// by calling stbi_convert_iphone_png_to_rgb(0), in which case
|
388
273
|
// you will always just get the native iphone "format" through (which
|
389
274
|
// is BGR stored in RGB).
|
390
275
|
//
|
@@ -393,6 +278,41 @@ distribute, and modify this file as you see fit.
|
|
393
278
|
// says there's premultiplied data (currently only happens in iPhone images,
|
394
279
|
// and only if iPhone convert-to-rgb processing is on).
|
395
280
|
//
|
281
|
+
// ===========================================================================
|
282
|
+
//
|
283
|
+
// ADDITIONAL CONFIGURATION
|
284
|
+
//
|
285
|
+
// - You can suppress implementation of any of the decoders to reduce
|
286
|
+
// your code footprint by #defining one or more of the following
|
287
|
+
// symbols before creating the implementation.
|
288
|
+
//
|
289
|
+
// STBI_NO_JPEG
|
290
|
+
// STBI_NO_PNG
|
291
|
+
// STBI_NO_BMP
|
292
|
+
// STBI_NO_PSD
|
293
|
+
// STBI_NO_TGA
|
294
|
+
// STBI_NO_GIF
|
295
|
+
// STBI_NO_HDR
|
296
|
+
// STBI_NO_PIC
|
297
|
+
// STBI_NO_PNM (.ppm and .pgm)
|
298
|
+
//
|
299
|
+
// - You can request *only* certain decoders and suppress all other ones
|
300
|
+
// (this will be more forward-compatible, as addition of new decoders
|
301
|
+
// doesn't require you to disable them explicitly):
|
302
|
+
//
|
303
|
+
// STBI_ONLY_JPEG
|
304
|
+
// STBI_ONLY_PNG
|
305
|
+
// STBI_ONLY_BMP
|
306
|
+
// STBI_ONLY_PSD
|
307
|
+
// STBI_ONLY_TGA
|
308
|
+
// STBI_ONLY_GIF
|
309
|
+
// STBI_ONLY_HDR
|
310
|
+
// STBI_ONLY_PIC
|
311
|
+
// STBI_ONLY_PNM (.ppm and .pgm)
|
312
|
+
//
|
313
|
+
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
|
314
|
+
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
|
315
|
+
//
|
396
316
|
|
397
317
|
|
398
318
|
#ifndef STBI_NO_STDIO
|
@@ -403,7 +323,7 @@ distribute, and modify this file as you see fit.
|
|
403
323
|
|
404
324
|
enum
|
405
325
|
{
|
406
|
-
STBI_default = 0, // only used for
|
326
|
+
STBI_default = 0, // only used for desired_channels
|
407
327
|
|
408
328
|
STBI_grey = 1,
|
409
329
|
STBI_grey_alpha = 2,
|
@@ -411,7 +331,9 @@ enum
|
|
411
331
|
STBI_rgb_alpha = 4
|
412
332
|
};
|
413
333
|
|
334
|
+
#include <stdlib.h>
|
414
335
|
typedef unsigned char stbi_uc;
|
336
|
+
typedef unsigned short stbi_us;
|
415
337
|
|
416
338
|
#ifdef __cplusplus
|
417
339
|
extern "C" {
|
@@ -439,34 +361,64 @@ typedef struct
|
|
439
361
|
int (*eof) (void *user); // returns nonzero if we are at end of file/data
|
440
362
|
} stbi_io_callbacks;
|
441
363
|
|
442
|
-
|
443
|
-
|
444
|
-
|
364
|
+
////////////////////////////////////
|
365
|
+
//
|
366
|
+
// 8-bits-per-channel interface
|
367
|
+
//
|
368
|
+
|
369
|
+
STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels);
|
370
|
+
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);
|
445
371
|
|
446
372
|
#ifndef STBI_NO_STDIO
|
447
|
-
STBIDEF stbi_uc *
|
373
|
+
STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
374
|
+
STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
|
448
375
|
// for stbi_load_from_file, file pointer is left pointing immediately after image
|
449
376
|
#endif
|
450
377
|
|
378
|
+
#ifndef STBI_NO_GIF
|
379
|
+
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
|
380
|
+
#endif
|
381
|
+
|
382
|
+
#ifdef STBI_WINDOWS_UTF8
|
383
|
+
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
|
384
|
+
#endif
|
385
|
+
|
386
|
+
////////////////////////////////////
|
387
|
+
//
|
388
|
+
// 16-bits-per-channel interface
|
389
|
+
//
|
390
|
+
|
391
|
+
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);
|
392
|
+
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);
|
393
|
+
|
394
|
+
#ifndef STBI_NO_STDIO
|
395
|
+
STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
396
|
+
STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
|
397
|
+
#endif
|
398
|
+
|
399
|
+
////////////////////////////////////
|
400
|
+
//
|
401
|
+
// float-per-channel interface
|
402
|
+
//
|
451
403
|
#ifndef STBI_NO_LINEAR
|
452
|
-
STBIDEF float *
|
453
|
-
STBIDEF float *
|
454
|
-
STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp);
|
404
|
+
STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
|
405
|
+
STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
|
455
406
|
|
456
407
|
#ifndef STBI_NO_STDIO
|
457
|
-
STBIDEF float *
|
408
|
+
STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
409
|
+
STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
|
458
410
|
#endif
|
459
411
|
#endif
|
460
412
|
|
461
413
|
#ifndef STBI_NO_HDR
|
462
414
|
STBIDEF void stbi_hdr_to_ldr_gamma(float gamma);
|
463
415
|
STBIDEF void stbi_hdr_to_ldr_scale(float scale);
|
464
|
-
#endif
|
416
|
+
#endif // STBI_NO_HDR
|
465
417
|
|
466
418
|
#ifndef STBI_NO_LINEAR
|
467
419
|
STBIDEF void stbi_ldr_to_hdr_gamma(float gamma);
|
468
420
|
STBIDEF void stbi_ldr_to_hdr_scale(float scale);
|
469
|
-
#endif //
|
421
|
+
#endif // STBI_NO_LINEAR
|
470
422
|
|
471
423
|
// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
|
472
424
|
STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
|
@@ -487,11 +439,14 @@ STBIDEF void stbi_image_free (void *retval_from_stbi_load);
|
|
487
439
|
// get image dimensions & components without fully decoding
|
488
440
|
STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
|
489
441
|
STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
|
442
|
+
STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len);
|
443
|
+
STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user);
|
490
444
|
|
491
445
|
#ifndef STBI_NO_STDIO
|
492
|
-
STBIDEF int stbi_info
|
493
|
-
STBIDEF int stbi_info_from_file
|
494
|
-
|
446
|
+
STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp);
|
447
|
+
STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp);
|
448
|
+
STBIDEF int stbi_is_16_bit (char const *filename);
|
449
|
+
STBIDEF int stbi_is_16_bit_from_file(FILE *f);
|
495
450
|
#endif
|
496
451
|
|
497
452
|
|
@@ -572,9 +527,10 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
|
|
572
527
|
#include <stddef.h> // ptrdiff_t on osx
|
573
528
|
#include <stdlib.h>
|
574
529
|
#include <string.h>
|
530
|
+
#include <limits.h>
|
575
531
|
|
576
532
|
#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
|
577
|
-
#include <math.h> // ldexp
|
533
|
+
#include <math.h> // ldexp, pow
|
578
534
|
#endif
|
579
535
|
|
580
536
|
#ifndef STBI_NO_STDIO
|
@@ -586,6 +542,12 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
|
|
586
542
|
#define STBI_ASSERT(x) assert(x)
|
587
543
|
#endif
|
588
544
|
|
545
|
+
#ifdef __cplusplus
|
546
|
+
#define STBI_EXTERN extern "C"
|
547
|
+
#else
|
548
|
+
#define STBI_EXTERN extern
|
549
|
+
#endif
|
550
|
+
|
589
551
|
|
590
552
|
#ifndef _MSC_VER
|
591
553
|
#ifdef __cplusplus
|
@@ -630,18 +592,22 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
|
|
630
592
|
#define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
|
631
593
|
#endif
|
632
594
|
|
633
|
-
#if defined(STBI_MALLOC) && defined(STBI_FREE) && defined(STBI_REALLOC)
|
595
|
+
#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
|
634
596
|
// ok
|
635
|
-
#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC)
|
597
|
+
#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED)
|
636
598
|
// ok
|
637
599
|
#else
|
638
|
-
#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC."
|
600
|
+
#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)."
|
639
601
|
#endif
|
640
602
|
|
641
603
|
#ifndef STBI_MALLOC
|
642
|
-
#define STBI_MALLOC(sz)
|
643
|
-
#define STBI_REALLOC(p,
|
644
|
-
#define STBI_FREE(p)
|
604
|
+
#define STBI_MALLOC(sz) malloc(sz)
|
605
|
+
#define STBI_REALLOC(p,newsz) realloc(p,newsz)
|
606
|
+
#define STBI_FREE(p) free(p)
|
607
|
+
#endif
|
608
|
+
|
609
|
+
#ifndef STBI_REALLOC_SIZED
|
610
|
+
#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
|
645
611
|
#endif
|
646
612
|
|
647
613
|
// x86/x64 detection
|
@@ -651,12 +617,14 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
|
|
651
617
|
#define STBI__X86_TARGET
|
652
618
|
#endif
|
653
619
|
|
654
|
-
#if defined(__GNUC__) &&
|
655
|
-
// NOTE: not clear do we actually need this for the 64-bit path?
|
620
|
+
#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
|
656
621
|
// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
|
657
|
-
//
|
658
|
-
//
|
659
|
-
//
|
622
|
+
// which in turn means it gets to use SSE2 everywhere. This is unfortunate,
|
623
|
+
// but previous attempts to provide the SSE2 functions with runtime
|
624
|
+
// detection caused numerous issues. The way architecture extensions are
|
625
|
+
// exposed in GCC/Clang is, sadly, not really suited for one-file libs.
|
626
|
+
// New behavior: if compiled with -msse2, we use SSE2 without any
|
627
|
+
// detection; if not, we don't use it at all.
|
660
628
|
#define STBI_NO_SIMD
|
661
629
|
#endif
|
662
630
|
|
@@ -675,7 +643,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
|
|
675
643
|
#define STBI_NO_SIMD
|
676
644
|
#endif
|
677
645
|
|
678
|
-
#if !defined(STBI_NO_SIMD) && defined(STBI__X86_TARGET)
|
646
|
+
#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET))
|
679
647
|
#define STBI_SSE2
|
680
648
|
#include <emmintrin.h>
|
681
649
|
|
@@ -704,25 +672,27 @@ static int stbi__cpuid3(void)
|
|
704
672
|
|
705
673
|
#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
|
706
674
|
|
707
|
-
|
675
|
+
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
|
676
|
+
static int stbi__sse2_available(void)
|
708
677
|
{
|
709
678
|
int info3 = stbi__cpuid3();
|
710
679
|
return ((info3 >> 26) & 1) != 0;
|
711
680
|
}
|
681
|
+
#endif
|
682
|
+
|
712
683
|
#else // assume GCC-style if not VC++
|
713
684
|
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
714
685
|
|
715
|
-
|
686
|
+
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
|
687
|
+
static int stbi__sse2_available(void)
|
716
688
|
{
|
717
|
-
|
718
|
-
//
|
719
|
-
|
720
|
-
|
721
|
-
// portable way to do this, preferably without using GCC inline ASM?
|
722
|
-
// just bail for now.
|
723
|
-
return 0;
|
724
|
-
#endif
|
689
|
+
// If we're even attempting to compile this on GCC/Clang, that means
|
690
|
+
// -msse2 is on, which means the compiler is allowed to use SSE2
|
691
|
+
// instructions at will, and so are we.
|
692
|
+
return 1;
|
725
693
|
}
|
694
|
+
#endif
|
695
|
+
|
726
696
|
#endif
|
727
697
|
#endif
|
728
698
|
|
@@ -829,57 +799,73 @@ static void stbi__rewind(stbi__context *s)
|
|
829
799
|
s->img_buffer_end = s->img_buffer_original_end;
|
830
800
|
}
|
831
801
|
|
802
|
+
enum
|
803
|
+
{
|
804
|
+
STBI_ORDER_RGB,
|
805
|
+
STBI_ORDER_BGR
|
806
|
+
};
|
807
|
+
|
808
|
+
typedef struct
|
809
|
+
{
|
810
|
+
int bits_per_channel;
|
811
|
+
int num_channels;
|
812
|
+
int channel_order;
|
813
|
+
} stbi__result_info;
|
814
|
+
|
832
815
|
#ifndef STBI_NO_JPEG
|
833
816
|
static int stbi__jpeg_test(stbi__context *s);
|
834
|
-
static
|
817
|
+
static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
835
818
|
static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp);
|
836
819
|
#endif
|
837
820
|
|
838
821
|
#ifndef STBI_NO_PNG
|
839
822
|
static int stbi__png_test(stbi__context *s);
|
840
|
-
static
|
823
|
+
static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
841
824
|
static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp);
|
825
|
+
static int stbi__png_is16(stbi__context *s);
|
842
826
|
#endif
|
843
827
|
|
844
828
|
#ifndef STBI_NO_BMP
|
845
829
|
static int stbi__bmp_test(stbi__context *s);
|
846
|
-
static
|
830
|
+
static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
847
831
|
static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp);
|
848
832
|
#endif
|
849
833
|
|
850
834
|
#ifndef STBI_NO_TGA
|
851
835
|
static int stbi__tga_test(stbi__context *s);
|
852
|
-
static
|
836
|
+
static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
853
837
|
static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp);
|
854
838
|
#endif
|
855
839
|
|
856
840
|
#ifndef STBI_NO_PSD
|
857
841
|
static int stbi__psd_test(stbi__context *s);
|
858
|
-
static
|
842
|
+
static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc);
|
859
843
|
static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp);
|
844
|
+
static int stbi__psd_is16(stbi__context *s);
|
860
845
|
#endif
|
861
846
|
|
862
847
|
#ifndef STBI_NO_HDR
|
863
848
|
static int stbi__hdr_test(stbi__context *s);
|
864
|
-
static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp);
|
849
|
+
static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
865
850
|
static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp);
|
866
851
|
#endif
|
867
852
|
|
868
853
|
#ifndef STBI_NO_PIC
|
869
854
|
static int stbi__pic_test(stbi__context *s);
|
870
|
-
static
|
855
|
+
static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
871
856
|
static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp);
|
872
857
|
#endif
|
873
858
|
|
874
859
|
#ifndef STBI_NO_GIF
|
875
860
|
static int stbi__gif_test(stbi__context *s);
|
876
|
-
static
|
861
|
+
static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
862
|
+
static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
|
877
863
|
static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
|
878
864
|
#endif
|
879
865
|
|
880
866
|
#ifndef STBI_NO_PNM
|
881
867
|
static int stbi__pnm_test(stbi__context *s);
|
882
|
-
static
|
868
|
+
static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
|
883
869
|
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
|
884
870
|
#endif
|
885
871
|
|
@@ -902,6 +888,81 @@ static void *stbi__malloc(size_t size)
|
|
902
888
|
return STBI_MALLOC(size);
|
903
889
|
}
|
904
890
|
|
891
|
+
// stb_image uses ints pervasively, including for offset calculations.
|
892
|
+
// therefore the largest decoded image size we can support with the
|
893
|
+
// current code, even on 64-bit targets, is INT_MAX. this is not a
|
894
|
+
// significant limitation for the intended use case.
|
895
|
+
//
|
896
|
+
// we do, however, need to make sure our size calculations don't
|
897
|
+
// overflow. hence a few helper functions for size calculations that
|
898
|
+
// multiply integers together, making sure that they're non-negative
|
899
|
+
// and no overflow occurs.
|
900
|
+
|
901
|
+
// return 1 if the sum is valid, 0 on overflow.
|
902
|
+
// negative terms are considered invalid.
|
903
|
+
static int stbi__addsizes_valid(int a, int b)
|
904
|
+
{
|
905
|
+
if (b < 0) return 0;
|
906
|
+
// now 0 <= b <= INT_MAX, hence also
|
907
|
+
// 0 <= INT_MAX - b <= INTMAX.
|
908
|
+
// And "a + b <= INT_MAX" (which might overflow) is the
|
909
|
+
// same as a <= INT_MAX - b (no overflow)
|
910
|
+
return a <= INT_MAX - b;
|
911
|
+
}
|
912
|
+
|
913
|
+
// returns 1 if the product is valid, 0 on overflow.
|
914
|
+
// negative factors are considered invalid.
|
915
|
+
static int stbi__mul2sizes_valid(int a, int b)
|
916
|
+
{
|
917
|
+
if (a < 0 || b < 0) return 0;
|
918
|
+
if (b == 0) return 1; // mul-by-0 is always safe
|
919
|
+
// portable way to check for no overflows in a*b
|
920
|
+
return a <= INT_MAX/b;
|
921
|
+
}
|
922
|
+
|
923
|
+
// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow
|
924
|
+
static int stbi__mad2sizes_valid(int a, int b, int add)
|
925
|
+
{
|
926
|
+
return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add);
|
927
|
+
}
|
928
|
+
|
929
|
+
// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow
|
930
|
+
static int stbi__mad3sizes_valid(int a, int b, int c, int add)
|
931
|
+
{
|
932
|
+
return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
|
933
|
+
stbi__addsizes_valid(a*b*c, add);
|
934
|
+
}
|
935
|
+
|
936
|
+
// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
|
937
|
+
#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
|
938
|
+
static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
|
939
|
+
{
|
940
|
+
return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
|
941
|
+
stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add);
|
942
|
+
}
|
943
|
+
#endif
|
944
|
+
|
945
|
+
// mallocs with size overflow checking
|
946
|
+
static void *stbi__malloc_mad2(int a, int b, int add)
|
947
|
+
{
|
948
|
+
if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
|
949
|
+
return stbi__malloc(a*b + add);
|
950
|
+
}
|
951
|
+
|
952
|
+
static void *stbi__malloc_mad3(int a, int b, int c, int add)
|
953
|
+
{
|
954
|
+
if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL;
|
955
|
+
return stbi__malloc(a*b*c + add);
|
956
|
+
}
|
957
|
+
|
958
|
+
#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
|
959
|
+
static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
|
960
|
+
{
|
961
|
+
if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL;
|
962
|
+
return stbi__malloc(a*b*c*d + add);
|
963
|
+
}
|
964
|
+
#endif
|
965
|
+
|
905
966
|
// stbi__err - error
|
906
967
|
// stbi__errpf - error returning pointer to float
|
907
968
|
// stbi__errpuc - error returning pointer to unsigned char
|
@@ -937,33 +998,38 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
|
|
937
998
|
stbi__vertically_flip_on_load = flag_true_if_should_flip;
|
938
999
|
}
|
939
1000
|
|
940
|
-
static
|
1001
|
+
static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
|
941
1002
|
{
|
1003
|
+
memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
|
1004
|
+
ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed
|
1005
|
+
ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
|
1006
|
+
ri->num_channels = 0;
|
1007
|
+
|
942
1008
|
#ifndef STBI_NO_JPEG
|
943
|
-
if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp);
|
1009
|
+
if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
|
944
1010
|
#endif
|
945
1011
|
#ifndef STBI_NO_PNG
|
946
|
-
if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp);
|
1012
|
+
if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri);
|
947
1013
|
#endif
|
948
1014
|
#ifndef STBI_NO_BMP
|
949
|
-
if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp);
|
1015
|
+
if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri);
|
950
1016
|
#endif
|
951
1017
|
#ifndef STBI_NO_GIF
|
952
|
-
if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp);
|
1018
|
+
if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri);
|
953
1019
|
#endif
|
954
1020
|
#ifndef STBI_NO_PSD
|
955
|
-
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp);
|
1021
|
+
if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
|
956
1022
|
#endif
|
957
1023
|
#ifndef STBI_NO_PIC
|
958
|
-
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp);
|
1024
|
+
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
|
959
1025
|
#endif
|
960
1026
|
#ifndef STBI_NO_PNM
|
961
|
-
if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp);
|
1027
|
+
if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri);
|
962
1028
|
#endif
|
963
1029
|
|
964
1030
|
#ifndef STBI_NO_HDR
|
965
1031
|
if (stbi__hdr_test(s)) {
|
966
|
-
float *hdr = stbi__hdr_load(s, x,y,comp,req_comp);
|
1032
|
+
float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri);
|
967
1033
|
return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
|
968
1034
|
}
|
969
1035
|
#endif
|
@@ -971,66 +1037,175 @@ static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *com
|
|
971
1037
|
#ifndef STBI_NO_TGA
|
972
1038
|
// test tga last because it's a crappy test!
|
973
1039
|
if (stbi__tga_test(s))
|
974
|
-
return stbi__tga_load(s,x,y,comp,req_comp);
|
1040
|
+
return stbi__tga_load(s,x,y,comp,req_comp, ri);
|
975
1041
|
#endif
|
976
1042
|
|
977
1043
|
return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
|
978
1044
|
}
|
979
1045
|
|
980
|
-
static
|
1046
|
+
static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels)
|
981
1047
|
{
|
982
|
-
|
1048
|
+
int i;
|
1049
|
+
int img_len = w * h * channels;
|
1050
|
+
stbi_uc *reduced;
|
983
1051
|
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
stbi_uc
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
1052
|
+
reduced = (stbi_uc *) stbi__malloc(img_len);
|
1053
|
+
if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory");
|
1054
|
+
|
1055
|
+
for (i = 0; i < img_len; ++i)
|
1056
|
+
reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling
|
1057
|
+
|
1058
|
+
STBI_FREE(orig);
|
1059
|
+
return reduced;
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels)
|
1063
|
+
{
|
1064
|
+
int i;
|
1065
|
+
int img_len = w * h * channels;
|
1066
|
+
stbi__uint16 *enlarged;
|
1067
|
+
|
1068
|
+
enlarged = (stbi__uint16 *) stbi__malloc(img_len*2);
|
1069
|
+
if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
|
1070
|
+
|
1071
|
+
for (i = 0; i < img_len; ++i)
|
1072
|
+
enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
|
1073
|
+
|
1074
|
+
STBI_FREE(orig);
|
1075
|
+
return enlarged;
|
1076
|
+
}
|
1077
|
+
|
1078
|
+
static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
|
1079
|
+
{
|
1080
|
+
int row;
|
1081
|
+
size_t bytes_per_row = (size_t)w * bytes_per_pixel;
|
1082
|
+
stbi_uc temp[2048];
|
1083
|
+
stbi_uc *bytes = (stbi_uc *)image;
|
1084
|
+
|
1085
|
+
for (row = 0; row < (h>>1); row++) {
|
1086
|
+
stbi_uc *row0 = bytes + row*bytes_per_row;
|
1087
|
+
stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row;
|
1088
|
+
// swap row0 with row1
|
1089
|
+
size_t bytes_left = bytes_per_row;
|
1090
|
+
while (bytes_left) {
|
1091
|
+
size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
|
1092
|
+
memcpy(temp, row0, bytes_copy);
|
1093
|
+
memcpy(row0, row1, bytes_copy);
|
1094
|
+
memcpy(row1, temp, bytes_copy);
|
1095
|
+
row0 += bytes_copy;
|
1096
|
+
row1 += bytes_copy;
|
1097
|
+
bytes_left -= bytes_copy;
|
999
1098
|
}
|
1000
1099
|
}
|
1100
|
+
}
|
1001
1101
|
|
1002
|
-
|
1102
|
+
#ifndef STBI_NO_GIF
|
1103
|
+
static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
|
1104
|
+
{
|
1105
|
+
int slice;
|
1106
|
+
int slice_size = w * h * bytes_per_pixel;
|
1107
|
+
|
1108
|
+
stbi_uc *bytes = (stbi_uc *)image;
|
1109
|
+
for (slice = 0; slice < z; ++slice) {
|
1110
|
+
stbi__vertical_flip(bytes, w, h, bytes_per_pixel);
|
1111
|
+
bytes += slice_size;
|
1112
|
+
}
|
1003
1113
|
}
|
1114
|
+
#endif
|
1004
1115
|
|
1005
|
-
|
1116
|
+
static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
1117
|
+
{
|
1118
|
+
stbi__result_info ri;
|
1119
|
+
void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8);
|
1120
|
+
|
1121
|
+
if (result == NULL)
|
1122
|
+
return NULL;
|
1123
|
+
|
1124
|
+
if (ri.bits_per_channel != 8) {
|
1125
|
+
STBI_ASSERT(ri.bits_per_channel == 16);
|
1126
|
+
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
1127
|
+
ri.bits_per_channel = 8;
|
1128
|
+
}
|
1129
|
+
|
1130
|
+
// @TODO: move stbi__convert_format to here
|
1131
|
+
|
1132
|
+
if (stbi__vertically_flip_on_load) {
|
1133
|
+
int channels = req_comp ? req_comp : *comp;
|
1134
|
+
stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
|
1135
|
+
}
|
1136
|
+
|
1137
|
+
return (unsigned char *) result;
|
1138
|
+
}
|
1139
|
+
|
1140
|
+
static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
1141
|
+
{
|
1142
|
+
stbi__result_info ri;
|
1143
|
+
void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16);
|
1144
|
+
|
1145
|
+
if (result == NULL)
|
1146
|
+
return NULL;
|
1147
|
+
|
1148
|
+
if (ri.bits_per_channel != 16) {
|
1149
|
+
STBI_ASSERT(ri.bits_per_channel == 8);
|
1150
|
+
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
1151
|
+
ri.bits_per_channel = 16;
|
1152
|
+
}
|
1153
|
+
|
1154
|
+
// @TODO: move stbi__convert_format16 to here
|
1155
|
+
// @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision
|
1156
|
+
|
1157
|
+
if (stbi__vertically_flip_on_load) {
|
1158
|
+
int channels = req_comp ? req_comp : *comp;
|
1159
|
+
stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16));
|
1160
|
+
}
|
1161
|
+
|
1162
|
+
return (stbi__uint16 *) result;
|
1163
|
+
}
|
1164
|
+
|
1165
|
+
#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR)
|
1006
1166
|
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
|
1007
1167
|
{
|
1008
1168
|
if (stbi__vertically_flip_on_load && result != NULL) {
|
1009
|
-
int
|
1010
|
-
|
1011
|
-
int row,col,z;
|
1012
|
-
float temp;
|
1013
|
-
|
1014
|
-
// @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once
|
1015
|
-
for (row = 0; row < (h>>1); row++) {
|
1016
|
-
for (col = 0; col < w; col++) {
|
1017
|
-
for (z = 0; z < depth; z++) {
|
1018
|
-
temp = result[(row * w + col) * depth + z];
|
1019
|
-
result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z];
|
1020
|
-
result[((h - row - 1) * w + col) * depth + z] = temp;
|
1021
|
-
}
|
1022
|
-
}
|
1023
|
-
}
|
1169
|
+
int channels = req_comp ? req_comp : *comp;
|
1170
|
+
stbi__vertical_flip(result, *x, *y, channels * sizeof(float));
|
1024
1171
|
}
|
1025
1172
|
}
|
1026
1173
|
#endif
|
1027
1174
|
|
1028
1175
|
#ifndef STBI_NO_STDIO
|
1029
1176
|
|
1177
|
+
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
1178
|
+
STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
|
1179
|
+
STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
|
1180
|
+
#endif
|
1181
|
+
|
1182
|
+
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
1183
|
+
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
|
1184
|
+
{
|
1185
|
+
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, bufferlen, NULL, NULL);
|
1186
|
+
}
|
1187
|
+
#endif
|
1188
|
+
|
1030
1189
|
static FILE *stbi__fopen(char const *filename, char const *mode)
|
1031
1190
|
{
|
1032
1191
|
FILE *f;
|
1033
|
-
#if defined(_MSC_VER) &&
|
1192
|
+
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
1193
|
+
wchar_t wMode[64];
|
1194
|
+
wchar_t wFilename[1024];
|
1195
|
+
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
|
1196
|
+
return 0;
|
1197
|
+
|
1198
|
+
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
|
1199
|
+
return 0;
|
1200
|
+
|
1201
|
+
#if _MSC_VER >= 1400
|
1202
|
+
if (0 != _wfopen_s(&f, wFilename, wMode))
|
1203
|
+
f = 0;
|
1204
|
+
#else
|
1205
|
+
f = _wfopen(wFilename, wMode);
|
1206
|
+
#endif
|
1207
|
+
|
1208
|
+
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
1034
1209
|
if (0 != fopen_s(&f, filename, mode))
|
1035
1210
|
f=0;
|
1036
1211
|
#else
|
@@ -1055,28 +1230,83 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
|
|
1055
1230
|
unsigned char *result;
|
1056
1231
|
stbi__context s;
|
1057
1232
|
stbi__start_file(&s,f);
|
1058
|
-
result =
|
1233
|
+
result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
|
1234
|
+
if (result) {
|
1235
|
+
// need to 'unget' all the characters in the IO buffer
|
1236
|
+
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
|
1237
|
+
}
|
1238
|
+
return result;
|
1239
|
+
}
|
1240
|
+
|
1241
|
+
STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp)
|
1242
|
+
{
|
1243
|
+
stbi__uint16 *result;
|
1244
|
+
stbi__context s;
|
1245
|
+
stbi__start_file(&s,f);
|
1246
|
+
result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
|
1059
1247
|
if (result) {
|
1060
1248
|
// need to 'unget' all the characters in the IO buffer
|
1061
1249
|
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
|
1062
1250
|
}
|
1063
1251
|
return result;
|
1064
1252
|
}
|
1253
|
+
|
1254
|
+
STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp)
|
1255
|
+
{
|
1256
|
+
FILE *f = stbi__fopen(filename, "rb");
|
1257
|
+
stbi__uint16 *result;
|
1258
|
+
if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file");
|
1259
|
+
result = stbi_load_from_file_16(f,x,y,comp,req_comp);
|
1260
|
+
fclose(f);
|
1261
|
+
return result;
|
1262
|
+
}
|
1263
|
+
|
1264
|
+
|
1065
1265
|
#endif //!STBI_NO_STDIO
|
1066
1266
|
|
1267
|
+
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)
|
1268
|
+
{
|
1269
|
+
stbi__context s;
|
1270
|
+
stbi__start_mem(&s,buffer,len);
|
1271
|
+
return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
|
1272
|
+
}
|
1273
|
+
|
1274
|
+
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)
|
1275
|
+
{
|
1276
|
+
stbi__context s;
|
1277
|
+
stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
|
1278
|
+
return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
|
1279
|
+
}
|
1280
|
+
|
1067
1281
|
STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
|
1068
1282
|
{
|
1069
1283
|
stbi__context s;
|
1070
1284
|
stbi__start_mem(&s,buffer,len);
|
1071
|
-
return
|
1285
|
+
return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
|
1072
1286
|
}
|
1073
1287
|
|
1074
1288
|
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
|
1075
1289
|
{
|
1076
1290
|
stbi__context s;
|
1077
1291
|
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
|
1078
|
-
return
|
1292
|
+
return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
|
1293
|
+
}
|
1294
|
+
|
1295
|
+
#ifndef STBI_NO_GIF
|
1296
|
+
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
|
1297
|
+
{
|
1298
|
+
unsigned char *result;
|
1299
|
+
stbi__context s;
|
1300
|
+
stbi__start_mem(&s,buffer,len);
|
1301
|
+
|
1302
|
+
result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
|
1303
|
+
if (stbi__vertically_flip_on_load) {
|
1304
|
+
stbi__vertical_flip_slices( result, *x, *y, *z, *comp );
|
1305
|
+
}
|
1306
|
+
|
1307
|
+
return result;
|
1079
1308
|
}
|
1309
|
+
#endif
|
1080
1310
|
|
1081
1311
|
#ifndef STBI_NO_LINEAR
|
1082
1312
|
static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
@@ -1084,13 +1314,14 @@ static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int
|
|
1084
1314
|
unsigned char *data;
|
1085
1315
|
#ifndef STBI_NO_HDR
|
1086
1316
|
if (stbi__hdr_test(s)) {
|
1087
|
-
|
1317
|
+
stbi__result_info ri;
|
1318
|
+
float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri);
|
1088
1319
|
if (hdr_data)
|
1089
1320
|
stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
|
1090
1321
|
return hdr_data;
|
1091
1322
|
}
|
1092
1323
|
#endif
|
1093
|
-
data =
|
1324
|
+
data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp);
|
1094
1325
|
if (data)
|
1095
1326
|
return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
|
1096
1327
|
return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
|
@@ -1160,12 +1391,16 @@ STBIDEF int stbi_is_hdr (char const *filename)
|
|
1160
1391
|
return result;
|
1161
1392
|
}
|
1162
1393
|
|
1163
|
-
STBIDEF int
|
1394
|
+
STBIDEF int stbi_is_hdr_from_file(FILE *f)
|
1164
1395
|
{
|
1165
1396
|
#ifndef STBI_NO_HDR
|
1397
|
+
long pos = ftell(f);
|
1398
|
+
int res;
|
1166
1399
|
stbi__context s;
|
1167
1400
|
stbi__start_file(&s,f);
|
1168
|
-
|
1401
|
+
res = stbi__hdr_test(&s);
|
1402
|
+
fseek(f, pos, SEEK_SET);
|
1403
|
+
return res;
|
1169
1404
|
#else
|
1170
1405
|
STBI_NOTUSED(f);
|
1171
1406
|
return 0;
|
@@ -1186,14 +1421,15 @@ STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void
|
|
1186
1421
|
#endif
|
1187
1422
|
}
|
1188
1423
|
|
1189
|
-
|
1424
|
+
#ifndef STBI_NO_LINEAR
|
1190
1425
|
static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f;
|
1191
1426
|
|
1192
|
-
#ifndef STBI_NO_LINEAR
|
1193
1427
|
STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
|
1194
1428
|
STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
|
1195
1429
|
#endif
|
1196
1430
|
|
1431
|
+
static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
|
1432
|
+
|
1197
1433
|
STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
|
1198
1434
|
STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
|
1199
1435
|
|
@@ -1347,7 +1583,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|
1347
1583
|
if (req_comp == img_n) return data;
|
1348
1584
|
STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
|
1349
1585
|
|
1350
|
-
good = (unsigned char *)
|
1586
|
+
good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0);
|
1351
1587
|
if (good == NULL) {
|
1352
1588
|
STBI_FREE(data);
|
1353
1589
|
return stbi__errpuc("outofmem", "Out of memory");
|
@@ -1357,26 +1593,75 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|
1357
1593
|
unsigned char *src = data + j * x * img_n ;
|
1358
1594
|
unsigned char *dest = good + j * x * req_comp;
|
1359
1595
|
|
1360
|
-
#define
|
1361
|
-
#define
|
1596
|
+
#define STBI__COMBO(a,b) ((a)*8+(b))
|
1597
|
+
#define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
|
1598
|
+
// convert source image with img_n components to one with req_comp components;
|
1599
|
+
// avoid switch per pixel, so use switch per scanline and massive macros
|
1600
|
+
switch (STBI__COMBO(img_n, req_comp)) {
|
1601
|
+
STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break;
|
1602
|
+
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1603
|
+
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break;
|
1604
|
+
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
1605
|
+
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1606
|
+
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
|
1607
|
+
STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break;
|
1608
|
+
STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
1609
|
+
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break;
|
1610
|
+
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
1611
|
+
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
1612
|
+
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
1613
|
+
default: STBI_ASSERT(0);
|
1614
|
+
}
|
1615
|
+
#undef STBI__CASE
|
1616
|
+
}
|
1617
|
+
|
1618
|
+
STBI_FREE(data);
|
1619
|
+
return good;
|
1620
|
+
}
|
1621
|
+
|
1622
|
+
static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
|
1623
|
+
{
|
1624
|
+
return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8);
|
1625
|
+
}
|
1626
|
+
|
1627
|
+
static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
|
1628
|
+
{
|
1629
|
+
int i,j;
|
1630
|
+
stbi__uint16 *good;
|
1631
|
+
|
1632
|
+
if (req_comp == img_n) return data;
|
1633
|
+
STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
|
1634
|
+
|
1635
|
+
good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2);
|
1636
|
+
if (good == NULL) {
|
1637
|
+
STBI_FREE(data);
|
1638
|
+
return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
|
1639
|
+
}
|
1640
|
+
|
1641
|
+
for (j=0; j < (int) y; ++j) {
|
1642
|
+
stbi__uint16 *src = data + j * x * img_n ;
|
1643
|
+
stbi__uint16 *dest = good + j * x * req_comp;
|
1644
|
+
|
1645
|
+
#define STBI__COMBO(a,b) ((a)*8+(b))
|
1646
|
+
#define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
|
1362
1647
|
// convert source image with img_n components to one with req_comp components;
|
1363
1648
|
// avoid switch per pixel, so use switch per scanline and massive macros
|
1364
|
-
switch (
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1649
|
+
switch (STBI__COMBO(img_n, req_comp)) {
|
1650
|
+
STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break;
|
1651
|
+
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1652
|
+
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break;
|
1653
|
+
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
1654
|
+
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
1655
|
+
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
|
1656
|
+
STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break;
|
1657
|
+
STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
1658
|
+
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break;
|
1659
|
+
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
1660
|
+
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
1661
|
+
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
1377
1662
|
default: STBI_ASSERT(0);
|
1378
1663
|
}
|
1379
|
-
#undef
|
1664
|
+
#undef STBI__CASE
|
1380
1665
|
}
|
1381
1666
|
|
1382
1667
|
STBI_FREE(data);
|
@@ -1387,7 +1672,9 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|
1387
1672
|
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
1388
1673
|
{
|
1389
1674
|
int i,k,n;
|
1390
|
-
float *output
|
1675
|
+
float *output;
|
1676
|
+
if (!data) return NULL;
|
1677
|
+
output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0);
|
1391
1678
|
if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); }
|
1392
1679
|
// compute number of non-alpha components
|
1393
1680
|
if (comp & 1) n = comp; else n = comp-1;
|
@@ -1395,7 +1682,11 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
|
1395
1682
|
for (k=0; k < n; ++k) {
|
1396
1683
|
output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
|
1397
1684
|
}
|
1398
|
-
|
1685
|
+
}
|
1686
|
+
if (n < comp) {
|
1687
|
+
for (i=0; i < x*y; ++i) {
|
1688
|
+
output[i*comp + n] = data[i*comp + n]/255.0f;
|
1689
|
+
}
|
1399
1690
|
}
|
1400
1691
|
STBI_FREE(data);
|
1401
1692
|
return output;
|
@@ -1407,7 +1698,9 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
|
1407
1698
|
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp)
|
1408
1699
|
{
|
1409
1700
|
int i,k,n;
|
1410
|
-
stbi_uc *output
|
1701
|
+
stbi_uc *output;
|
1702
|
+
if (!data) return NULL;
|
1703
|
+
output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0);
|
1411
1704
|
if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); }
|
1412
1705
|
// compute number of non-alpha components
|
1413
1706
|
if (comp & 1) n = comp; else n = comp-1;
|
@@ -1472,7 +1765,7 @@ typedef struct
|
|
1472
1765
|
stbi__context *s;
|
1473
1766
|
stbi__huffman huff_dc[4];
|
1474
1767
|
stbi__huffman huff_ac[4];
|
1475
|
-
|
1768
|
+
stbi__uint16 dequant[4][64];
|
1476
1769
|
stbi__int16 fast_ac[4][1 << FAST_BITS];
|
1477
1770
|
|
1478
1771
|
// sizes for components, interleaved MCUs
|
@@ -1508,6 +1801,9 @@ typedef struct
|
|
1508
1801
|
int succ_high;
|
1509
1802
|
int succ_low;
|
1510
1803
|
int eob_run;
|
1804
|
+
int jfif;
|
1805
|
+
int app14_color_transform; // Adobe APP14 tag
|
1806
|
+
int rgb;
|
1511
1807
|
|
1512
1808
|
int scan_n, order[4];
|
1513
1809
|
int restart_interval, todo;
|
@@ -1520,7 +1816,8 @@ typedef struct
|
|
1520
1816
|
|
1521
1817
|
static int stbi__build_huffman(stbi__huffman *h, int *count)
|
1522
1818
|
{
|
1523
|
-
int i,j,k=0
|
1819
|
+
int i,j,k=0;
|
1820
|
+
unsigned int code;
|
1524
1821
|
// build size list for each symbol (from JPEG spec)
|
1525
1822
|
for (i=0; i < 16; ++i)
|
1526
1823
|
for (j=0; j < count[i]; ++j)
|
@@ -1536,7 +1833,7 @@ static int stbi__build_huffman(stbi__huffman *h, int *count)
|
|
1536
1833
|
if (h->size[k] == j) {
|
1537
1834
|
while (h->size[k] == j)
|
1538
1835
|
h->code[k++] = (stbi__uint16) (code++);
|
1539
|
-
if (code-1 >= (
|
1836
|
+
if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG");
|
1540
1837
|
}
|
1541
1838
|
// compute largest code + 1 for this size, preshifted as needed later
|
1542
1839
|
h->maxcode[j] = code << (16-j);
|
@@ -1577,10 +1874,10 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
|
|
1577
1874
|
// magnitude code followed by receive_extend code
|
1578
1875
|
int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
|
1579
1876
|
int m = 1 << (magbits - 1);
|
1580
|
-
if (k < m) k += (
|
1877
|
+
if (k < m) k += (~0U << magbits) + 1;
|
1581
1878
|
// if the result is small enough, we can fit it in fast_ac table
|
1582
1879
|
if (k >= -128 && k <= 127)
|
1583
|
-
fast_ac[i] = (stbi__int16) ((k
|
1880
|
+
fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits));
|
1584
1881
|
}
|
1585
1882
|
}
|
1586
1883
|
}
|
@@ -1589,9 +1886,10 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
|
|
1589
1886
|
static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
|
1590
1887
|
{
|
1591
1888
|
do {
|
1592
|
-
int b = j->nomore ? 0 : stbi__get8(j->s);
|
1889
|
+
unsigned int b = j->nomore ? 0 : stbi__get8(j->s);
|
1593
1890
|
if (b == 0xff) {
|
1594
1891
|
int c = stbi__get8(j->s);
|
1892
|
+
while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes
|
1595
1893
|
if (c != 0) {
|
1596
1894
|
j->marker = (unsigned char) c;
|
1597
1895
|
j->nomore = 1;
|
@@ -1604,7 +1902,7 @@ static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
|
|
1604
1902
|
}
|
1605
1903
|
|
1606
1904
|
// (1 << n) - 1
|
1607
|
-
static stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
|
1905
|
+
static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
|
1608
1906
|
|
1609
1907
|
// decode a jpeg huffman value from the bitstream
|
1610
1908
|
stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
|
@@ -1657,7 +1955,7 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
|
|
1657
1955
|
}
|
1658
1956
|
|
1659
1957
|
// bias[n] = (-1<<n) + 1
|
1660
|
-
static int
|
1958
|
+
static const int stbi__jbias[16] = {0,-1,-3,-7,-15,-31,-63,-127,-255,-511,-1023,-2047,-4095,-8191,-16383,-32767};
|
1661
1959
|
|
1662
1960
|
// combined JPEG 'receive' and JPEG 'extend', since baseline
|
1663
1961
|
// always extends everything it receives.
|
@@ -1700,7 +1998,7 @@ stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
|
|
1700
1998
|
|
1701
1999
|
// given a value that's at position X in the zigzag stream,
|
1702
2000
|
// where does it appear in the 8x8 matrix coded as row-major?
|
1703
|
-
static stbi_uc stbi__jpeg_dezigzag[64+15] =
|
2001
|
+
static const stbi_uc stbi__jpeg_dezigzag[64+15] =
|
1704
2002
|
{
|
1705
2003
|
0, 1, 8, 16, 9, 2, 3, 10,
|
1706
2004
|
17, 24, 32, 25, 18, 11, 4, 5,
|
@@ -1716,7 +2014,7 @@ static stbi_uc stbi__jpeg_dezigzag[64+15] =
|
|
1716
2014
|
};
|
1717
2015
|
|
1718
2016
|
// decode one 64-entry block--
|
1719
|
-
static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b,
|
2017
|
+
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)
|
1720
2018
|
{
|
1721
2019
|
int diff,dc,k;
|
1722
2020
|
int t;
|
@@ -1926,7 +2224,7 @@ stbi_inline static stbi_uc stbi__clamp(int x)
|
|
1926
2224
|
}
|
1927
2225
|
|
1928
2226
|
#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5)))
|
1929
|
-
#define stbi__fsh(x) ((x)
|
2227
|
+
#define stbi__fsh(x) ((x) * 4096)
|
1930
2228
|
|
1931
2229
|
// derived from jidctint -- DCT_ISLOW
|
1932
2230
|
#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \
|
@@ -1981,7 +2279,7 @@ static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64])
|
|
1981
2279
|
// (1|2|3|4|5|6|7)==0 0 seconds
|
1982
2280
|
// all separate -0.047 seconds
|
1983
2281
|
// 1 && 2|3 && 4|5 && 6|7: -0.047 seconds
|
1984
|
-
int dcterm = d[0]
|
2282
|
+
int dcterm = d[0]*4;
|
1985
2283
|
v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm;
|
1986
2284
|
} else {
|
1987
2285
|
STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56])
|
@@ -2425,7 +2723,7 @@ static stbi_uc stbi__get_marker(stbi__jpeg *j)
|
|
2425
2723
|
x = stbi__get8(j->s);
|
2426
2724
|
if (x != 0xff) return STBI__MARKER_none;
|
2427
2725
|
while (x == 0xff)
|
2428
|
-
x = stbi__get8(j->s);
|
2726
|
+
x = stbi__get8(j->s); // consume repeated 0xff fill bytes
|
2429
2727
|
return x;
|
2430
2728
|
}
|
2431
2729
|
|
@@ -2440,7 +2738,7 @@ static void stbi__jpeg_reset(stbi__jpeg *j)
|
|
2440
2738
|
j->code_bits = 0;
|
2441
2739
|
j->code_buffer = 0;
|
2442
2740
|
j->nomore = 0;
|
2443
|
-
j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0;
|
2741
|
+
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;
|
2444
2742
|
j->marker = STBI__MARKER_none;
|
2445
2743
|
j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
|
2446
2744
|
j->eob_run = 0;
|
@@ -2572,7 +2870,7 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
|
|
2572
2870
|
}
|
2573
2871
|
}
|
2574
2872
|
|
2575
|
-
static void stbi__jpeg_dequantize(short *data,
|
2873
|
+
static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant)
|
2576
2874
|
{
|
2577
2875
|
int i;
|
2578
2876
|
for (i=0; i < 64; ++i)
|
@@ -2614,13 +2912,14 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
|
|
2614
2912
|
L = stbi__get16be(z->s)-2;
|
2615
2913
|
while (L > 0) {
|
2616
2914
|
int q = stbi__get8(z->s);
|
2617
|
-
int p = q >> 4;
|
2915
|
+
int p = q >> 4, sixteen = (p != 0);
|
2618
2916
|
int t = q & 15,i;
|
2619
|
-
if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG");
|
2917
|
+
if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG");
|
2620
2918
|
if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG");
|
2919
|
+
|
2621
2920
|
for (i=0; i < 64; ++i)
|
2622
|
-
z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s);
|
2623
|
-
L -= 65;
|
2921
|
+
z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s));
|
2922
|
+
L -= (sixteen ? 129 : 65);
|
2624
2923
|
}
|
2625
2924
|
return L==0;
|
2626
2925
|
|
@@ -2653,12 +2952,50 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
|
|
2653
2952
|
}
|
2654
2953
|
return L==0;
|
2655
2954
|
}
|
2955
|
+
|
2656
2956
|
// check for comment block or APP blocks
|
2657
2957
|
if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
|
2658
|
-
|
2958
|
+
L = stbi__get16be(z->s);
|
2959
|
+
if (L < 2) {
|
2960
|
+
if (m == 0xFE)
|
2961
|
+
return stbi__err("bad COM len","Corrupt JPEG");
|
2962
|
+
else
|
2963
|
+
return stbi__err("bad APP len","Corrupt JPEG");
|
2964
|
+
}
|
2965
|
+
L -= 2;
|
2966
|
+
|
2967
|
+
if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
|
2968
|
+
static const unsigned char tag[5] = {'J','F','I','F','\0'};
|
2969
|
+
int ok = 1;
|
2970
|
+
int i;
|
2971
|
+
for (i=0; i < 5; ++i)
|
2972
|
+
if (stbi__get8(z->s) != tag[i])
|
2973
|
+
ok = 0;
|
2974
|
+
L -= 5;
|
2975
|
+
if (ok)
|
2976
|
+
z->jfif = 1;
|
2977
|
+
} else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
|
2978
|
+
static const unsigned char tag[6] = {'A','d','o','b','e','\0'};
|
2979
|
+
int ok = 1;
|
2980
|
+
int i;
|
2981
|
+
for (i=0; i < 6; ++i)
|
2982
|
+
if (stbi__get8(z->s) != tag[i])
|
2983
|
+
ok = 0;
|
2984
|
+
L -= 6;
|
2985
|
+
if (ok) {
|
2986
|
+
stbi__get8(z->s); // version
|
2987
|
+
stbi__get16be(z->s); // flags0
|
2988
|
+
stbi__get16be(z->s); // flags1
|
2989
|
+
z->app14_color_transform = stbi__get8(z->s); // color transform
|
2990
|
+
L -= 6;
|
2991
|
+
}
|
2992
|
+
}
|
2993
|
+
|
2994
|
+
stbi__skip(z->s, L);
|
2659
2995
|
return 1;
|
2660
2996
|
}
|
2661
|
-
|
2997
|
+
|
2998
|
+
return stbi__err("unknown marker","Corrupt JPEG");
|
2662
2999
|
}
|
2663
3000
|
|
2664
3001
|
// after we see SOS
|
@@ -2701,6 +3038,28 @@ static int stbi__process_scan_header(stbi__jpeg *z)
|
|
2701
3038
|
return 1;
|
2702
3039
|
}
|
2703
3040
|
|
3041
|
+
static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why)
|
3042
|
+
{
|
3043
|
+
int i;
|
3044
|
+
for (i=0; i < ncomp; ++i) {
|
3045
|
+
if (z->img_comp[i].raw_data) {
|
3046
|
+
STBI_FREE(z->img_comp[i].raw_data);
|
3047
|
+
z->img_comp[i].raw_data = NULL;
|
3048
|
+
z->img_comp[i].data = NULL;
|
3049
|
+
}
|
3050
|
+
if (z->img_comp[i].raw_coeff) {
|
3051
|
+
STBI_FREE(z->img_comp[i].raw_coeff);
|
3052
|
+
z->img_comp[i].raw_coeff = 0;
|
3053
|
+
z->img_comp[i].coeff = 0;
|
3054
|
+
}
|
3055
|
+
if (z->img_comp[i].linebuf) {
|
3056
|
+
STBI_FREE(z->img_comp[i].linebuf);
|
3057
|
+
z->img_comp[i].linebuf = NULL;
|
3058
|
+
}
|
3059
|
+
}
|
3060
|
+
return why;
|
3061
|
+
}
|
3062
|
+
|
2704
3063
|
static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
2705
3064
|
{
|
2706
3065
|
stbi__context *s = z->s;
|
@@ -2710,7 +3069,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2710
3069
|
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
|
2711
3070
|
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
|
2712
3071
|
c = stbi__get8(s);
|
2713
|
-
if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG");
|
3072
|
+
if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
|
2714
3073
|
s->img_n = c;
|
2715
3074
|
for (i=0; i < c; ++i) {
|
2716
3075
|
z->img_comp[i].data = NULL;
|
@@ -2719,11 +3078,12 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2719
3078
|
|
2720
3079
|
if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG");
|
2721
3080
|
|
3081
|
+
z->rgb = 0;
|
2722
3082
|
for (i=0; i < s->img_n; ++i) {
|
3083
|
+
static const unsigned char rgb[3] = { 'R', 'G', 'B' };
|
2723
3084
|
z->img_comp[i].id = stbi__get8(s);
|
2724
|
-
if (z->img_comp[i].id
|
2725
|
-
|
2726
|
-
return stbi__err("bad component ID","Corrupt JPEG");
|
3085
|
+
if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
|
3086
|
+
++z->rgb;
|
2727
3087
|
q = stbi__get8(s);
|
2728
3088
|
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");
|
2729
3089
|
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");
|
@@ -2732,7 +3092,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2732
3092
|
|
2733
3093
|
if (scan != STBI__SCAN_load) return 1;
|
2734
3094
|
|
2735
|
-
if ((
|
3095
|
+
if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode");
|
2736
3096
|
|
2737
3097
|
for (i=0; i < s->img_n; ++i) {
|
2738
3098
|
if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h;
|
@@ -2744,6 +3104,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2744
3104
|
z->img_v_max = v_max;
|
2745
3105
|
z->img_mcu_w = h_max * 8;
|
2746
3106
|
z->img_mcu_h = v_max * 8;
|
3107
|
+
// these sizes can't be more than 17 bits
|
2747
3108
|
z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w;
|
2748
3109
|
z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h;
|
2749
3110
|
|
@@ -2755,28 +3116,27 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2755
3116
|
// the bogus oversized data from using interleaved MCUs and their
|
2756
3117
|
// big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
|
2757
3118
|
// discard the extra data until colorspace conversion
|
3119
|
+
//
|
3120
|
+
// img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier)
|
3121
|
+
// so these muls can't overflow with 32-bit ints (which we require)
|
2758
3122
|
z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8;
|
2759
3123
|
z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8;
|
2760
|
-
z->img_comp[i].
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
}
|
2767
|
-
return stbi__err("outofmem", "Out of memory");
|
2768
|
-
}
|
3124
|
+
z->img_comp[i].coeff = 0;
|
3125
|
+
z->img_comp[i].raw_coeff = 0;
|
3126
|
+
z->img_comp[i].linebuf = NULL;
|
3127
|
+
z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15);
|
3128
|
+
if (z->img_comp[i].raw_data == NULL)
|
3129
|
+
return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
|
2769
3130
|
// align blocks for idct using mmx/sse
|
2770
3131
|
z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15);
|
2771
|
-
z->img_comp[i].linebuf = NULL;
|
2772
3132
|
if (z->progressive) {
|
2773
|
-
|
2774
|
-
z->img_comp[i].
|
2775
|
-
z->img_comp[i].
|
3133
|
+
// w2, h2 are multiples of 8 (see above)
|
3134
|
+
z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8;
|
3135
|
+
z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8;
|
3136
|
+
z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15);
|
3137
|
+
if (z->img_comp[i].raw_coeff == NULL)
|
3138
|
+
return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
|
2776
3139
|
z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15);
|
2777
|
-
} else {
|
2778
|
-
z->img_comp[i].coeff = 0;
|
2779
|
-
z->img_comp[i].raw_coeff = 0;
|
2780
3140
|
}
|
2781
3141
|
}
|
2782
3142
|
|
@@ -2795,6 +3155,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
|
2795
3155
|
static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
|
2796
3156
|
{
|
2797
3157
|
int m;
|
3158
|
+
z->jfif = 0;
|
3159
|
+
z->app14_color_transform = -1; // valid values are 0,1,2
|
2798
3160
|
z->marker = STBI__MARKER_none; // initialize cached marker to empty
|
2799
3161
|
m = stbi__get_marker(z);
|
2800
3162
|
if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
|
@@ -2836,12 +3198,15 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j)
|
|
2836
3198
|
if (x == 255) {
|
2837
3199
|
j->marker = stbi__get8(j->s);
|
2838
3200
|
break;
|
2839
|
-
} else if (x != 0) {
|
2840
|
-
return stbi__err("junk before marker", "Corrupt JPEG");
|
2841
3201
|
}
|
2842
3202
|
}
|
2843
3203
|
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
|
2844
3204
|
}
|
3205
|
+
} else if (stbi__DNL(m)) {
|
3206
|
+
int Ld = stbi__get16be(j->s);
|
3207
|
+
stbi__uint32 NL = stbi__get16be(j->s);
|
3208
|
+
if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
|
3209
|
+
if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
|
2845
3210
|
} else {
|
2846
3211
|
if (!stbi__process_marker(j, m)) return 0;
|
2847
3212
|
}
|
@@ -3060,38 +3425,9 @@ static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_
|
|
3060
3425
|
return out;
|
3061
3426
|
}
|
3062
3427
|
|
3063
|
-
#ifdef STBI_JPEG_OLD
|
3064
|
-
// this is the same YCbCr-to-RGB calculation that stb_image has used
|
3065
|
-
// historically before the algorithm changes in 1.49
|
3066
|
-
#define float2fixed(x) ((int) ((x) * 65536 + 0.5))
|
3067
|
-
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)
|
3068
|
-
{
|
3069
|
-
int i;
|
3070
|
-
for (i=0; i < count; ++i) {
|
3071
|
-
int y_fixed = (y[i] << 16) + 32768; // rounding
|
3072
|
-
int r,g,b;
|
3073
|
-
int cr = pcr[i] - 128;
|
3074
|
-
int cb = pcb[i] - 128;
|
3075
|
-
r = y_fixed + cr*float2fixed(1.40200f);
|
3076
|
-
g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f);
|
3077
|
-
b = y_fixed + cb*float2fixed(1.77200f);
|
3078
|
-
r >>= 16;
|
3079
|
-
g >>= 16;
|
3080
|
-
b >>= 16;
|
3081
|
-
if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
|
3082
|
-
if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
|
3083
|
-
if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
|
3084
|
-
out[0] = (stbi_uc)r;
|
3085
|
-
out[1] = (stbi_uc)g;
|
3086
|
-
out[2] = (stbi_uc)b;
|
3087
|
-
out[3] = 255;
|
3088
|
-
out += step;
|
3089
|
-
}
|
3090
|
-
}
|
3091
|
-
#else
|
3092
3428
|
// this is a reduced-precision calculation of YCbCr-to-RGB introduced
|
3093
3429
|
// to make sure the code produces the same results in both SIMD and scalar
|
3094
|
-
#define
|
3430
|
+
#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8)
|
3095
3431
|
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)
|
3096
3432
|
{
|
3097
3433
|
int i;
|
@@ -3100,9 +3436,9 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
|
|
3100
3436
|
int r,g,b;
|
3101
3437
|
int cr = pcr[i] - 128;
|
3102
3438
|
int cb = pcb[i] - 128;
|
3103
|
-
r = y_fixed + cr*
|
3104
|
-
g = y_fixed + (cr*-
|
3105
|
-
b = y_fixed
|
3439
|
+
r = y_fixed + cr* stbi__float2fixed(1.40200f);
|
3440
|
+
g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
|
3441
|
+
b = y_fixed + cb* stbi__float2fixed(1.77200f);
|
3106
3442
|
r >>= 20;
|
3107
3443
|
g >>= 20;
|
3108
3444
|
b >>= 20;
|
@@ -3116,7 +3452,6 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
|
|
3116
3452
|
out += step;
|
3117
3453
|
}
|
3118
3454
|
}
|
3119
|
-
#endif
|
3120
3455
|
|
3121
3456
|
#if defined(STBI_SSE2) || defined(STBI_NEON)
|
3122
3457
|
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)
|
@@ -3235,9 +3570,9 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
|
|
3235
3570
|
int r,g,b;
|
3236
3571
|
int cr = pcr[i] - 128;
|
3237
3572
|
int cb = pcb[i] - 128;
|
3238
|
-
r = y_fixed + cr*
|
3239
|
-
g = y_fixed + cr*-
|
3240
|
-
b = y_fixed
|
3573
|
+
r = y_fixed + cr* stbi__float2fixed(1.40200f);
|
3574
|
+
g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
|
3575
|
+
b = y_fixed + cb* stbi__float2fixed(1.77200f);
|
3241
3576
|
r >>= 20;
|
3242
3577
|
g >>= 20;
|
3243
3578
|
b >>= 20;
|
@@ -3263,18 +3598,14 @@ static void stbi__setup_jpeg(stbi__jpeg *j)
|
|
3263
3598
|
#ifdef STBI_SSE2
|
3264
3599
|
if (stbi__sse2_available()) {
|
3265
3600
|
j->idct_block_kernel = stbi__idct_simd;
|
3266
|
-
#ifndef STBI_JPEG_OLD
|
3267
3601
|
j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
|
3268
|
-
#endif
|
3269
3602
|
j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
|
3270
3603
|
}
|
3271
3604
|
#endif
|
3272
3605
|
|
3273
3606
|
#ifdef STBI_NEON
|
3274
3607
|
j->idct_block_kernel = stbi__idct_simd;
|
3275
|
-
#ifndef STBI_JPEG_OLD
|
3276
3608
|
j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
|
3277
|
-
#endif
|
3278
3609
|
j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
|
3279
3610
|
#endif
|
3280
3611
|
}
|
@@ -3282,23 +3613,7 @@ static void stbi__setup_jpeg(stbi__jpeg *j)
|
|
3282
3613
|
// clean up the temporary component buffers
|
3283
3614
|
static void stbi__cleanup_jpeg(stbi__jpeg *j)
|
3284
3615
|
{
|
3285
|
-
|
3286
|
-
for (i=0; i < j->s->img_n; ++i) {
|
3287
|
-
if (j->img_comp[i].raw_data) {
|
3288
|
-
STBI_FREE(j->img_comp[i].raw_data);
|
3289
|
-
j->img_comp[i].raw_data = NULL;
|
3290
|
-
j->img_comp[i].data = NULL;
|
3291
|
-
}
|
3292
|
-
if (j->img_comp[i].raw_coeff) {
|
3293
|
-
STBI_FREE(j->img_comp[i].raw_coeff);
|
3294
|
-
j->img_comp[i].raw_coeff = 0;
|
3295
|
-
j->img_comp[i].coeff = 0;
|
3296
|
-
}
|
3297
|
-
if (j->img_comp[i].linebuf) {
|
3298
|
-
STBI_FREE(j->img_comp[i].linebuf);
|
3299
|
-
j->img_comp[i].linebuf = NULL;
|
3300
|
-
}
|
3301
|
-
}
|
3616
|
+
stbi__free_jpeg_components(j, j->s->img_n, 0);
|
3302
3617
|
}
|
3303
3618
|
|
3304
3619
|
typedef struct
|
@@ -3311,9 +3626,16 @@ typedef struct
|
|
3311
3626
|
int ypos; // which pre-expansion row we're on
|
3312
3627
|
} stbi__resample;
|
3313
3628
|
|
3629
|
+
// fast 0..255 * 0..255 => 0..255 rounded multiplication
|
3630
|
+
static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y)
|
3631
|
+
{
|
3632
|
+
unsigned int t = x*y + 128;
|
3633
|
+
return (stbi_uc) ((t + (t >>8)) >> 8);
|
3634
|
+
}
|
3635
|
+
|
3314
3636
|
static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
|
3315
3637
|
{
|
3316
|
-
int n, decode_n;
|
3638
|
+
int n, decode_n, is_rgb;
|
3317
3639
|
z->s->img_n = 0; // make stbi__cleanup_jpeg safe
|
3318
3640
|
|
3319
3641
|
// validate req_comp
|
@@ -3323,9 +3645,11 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3323
3645
|
if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
|
3324
3646
|
|
3325
3647
|
// determine actual number of components to generate
|
3326
|
-
n = req_comp ? req_comp : z->s->img_n;
|
3648
|
+
n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
|
3327
3649
|
|
3328
|
-
|
3650
|
+
is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
|
3651
|
+
|
3652
|
+
if (z->s->img_n == 3 && n < 3 && !is_rgb)
|
3329
3653
|
decode_n = 1;
|
3330
3654
|
else
|
3331
3655
|
decode_n = z->s->img_n;
|
@@ -3362,7 +3686,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3362
3686
|
}
|
3363
3687
|
|
3364
3688
|
// can't error after this so, this is safe
|
3365
|
-
output = (stbi_uc *)
|
3689
|
+
output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1);
|
3366
3690
|
if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
|
3367
3691
|
|
3368
3692
|
// now go ahead and resample
|
@@ -3385,7 +3709,39 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3385
3709
|
if (n >= 3) {
|
3386
3710
|
stbi_uc *y = coutput[0];
|
3387
3711
|
if (z->s->img_n == 3) {
|
3388
|
-
|
3712
|
+
if (is_rgb) {
|
3713
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3714
|
+
out[0] = y[i];
|
3715
|
+
out[1] = coutput[1][i];
|
3716
|
+
out[2] = coutput[2][i];
|
3717
|
+
out[3] = 255;
|
3718
|
+
out += n;
|
3719
|
+
}
|
3720
|
+
} else {
|
3721
|
+
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
|
3722
|
+
}
|
3723
|
+
} else if (z->s->img_n == 4) {
|
3724
|
+
if (z->app14_color_transform == 0) { // CMYK
|
3725
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3726
|
+
stbi_uc m = coutput[3][i];
|
3727
|
+
out[0] = stbi__blinn_8x8(coutput[0][i], m);
|
3728
|
+
out[1] = stbi__blinn_8x8(coutput[1][i], m);
|
3729
|
+
out[2] = stbi__blinn_8x8(coutput[2][i], m);
|
3730
|
+
out[3] = 255;
|
3731
|
+
out += n;
|
3732
|
+
}
|
3733
|
+
} else if (z->app14_color_transform == 2) { // YCCK
|
3734
|
+
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
|
3735
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3736
|
+
stbi_uc m = coutput[3][i];
|
3737
|
+
out[0] = stbi__blinn_8x8(255 - out[0], m);
|
3738
|
+
out[1] = stbi__blinn_8x8(255 - out[1], m);
|
3739
|
+
out[2] = stbi__blinn_8x8(255 - out[2], m);
|
3740
|
+
out += n;
|
3741
|
+
}
|
3742
|
+
} else { // YCbCr + alpha? Ignore the fourth channel for now
|
3743
|
+
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
|
3744
|
+
}
|
3389
3745
|
} else
|
3390
3746
|
for (i=0; i < z->s->img_x; ++i) {
|
3391
3747
|
out[0] = out[1] = out[2] = y[i];
|
@@ -3393,37 +3749,70 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
|
3393
3749
|
out += n;
|
3394
3750
|
}
|
3395
3751
|
} else {
|
3396
|
-
|
3397
|
-
|
3398
|
-
|
3399
|
-
|
3400
|
-
|
3752
|
+
if (is_rgb) {
|
3753
|
+
if (n == 1)
|
3754
|
+
for (i=0; i < z->s->img_x; ++i)
|
3755
|
+
*out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
|
3756
|
+
else {
|
3757
|
+
for (i=0; i < z->s->img_x; ++i, out += 2) {
|
3758
|
+
out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
|
3759
|
+
out[1] = 255;
|
3760
|
+
}
|
3761
|
+
}
|
3762
|
+
} else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
|
3763
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3764
|
+
stbi_uc m = coutput[3][i];
|
3765
|
+
stbi_uc r = stbi__blinn_8x8(coutput[0][i], m);
|
3766
|
+
stbi_uc g = stbi__blinn_8x8(coutput[1][i], m);
|
3767
|
+
stbi_uc b = stbi__blinn_8x8(coutput[2][i], m);
|
3768
|
+
out[0] = stbi__compute_y(r, g, b);
|
3769
|
+
out[1] = 255;
|
3770
|
+
out += n;
|
3771
|
+
}
|
3772
|
+
} else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
|
3773
|
+
for (i=0; i < z->s->img_x; ++i) {
|
3774
|
+
out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
|
3775
|
+
out[1] = 255;
|
3776
|
+
out += n;
|
3777
|
+
}
|
3778
|
+
} else {
|
3779
|
+
stbi_uc *y = coutput[0];
|
3780
|
+
if (n == 1)
|
3781
|
+
for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
|
3782
|
+
else
|
3783
|
+
for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; }
|
3784
|
+
}
|
3401
3785
|
}
|
3402
3786
|
}
|
3403
3787
|
stbi__cleanup_jpeg(z);
|
3404
3788
|
*out_x = z->s->img_x;
|
3405
3789
|
*out_y = z->s->img_y;
|
3406
|
-
if (comp) *comp
|
3790
|
+
if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
|
3407
3791
|
return output;
|
3408
3792
|
}
|
3409
3793
|
}
|
3410
3794
|
|
3411
|
-
static
|
3795
|
+
static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
3412
3796
|
{
|
3413
|
-
|
3414
|
-
j
|
3415
|
-
|
3416
|
-
|
3797
|
+
unsigned char* result;
|
3798
|
+
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
|
3799
|
+
STBI_NOTUSED(ri);
|
3800
|
+
j->s = s;
|
3801
|
+
stbi__setup_jpeg(j);
|
3802
|
+
result = load_jpeg_image(j, x,y,comp,req_comp);
|
3803
|
+
STBI_FREE(j);
|
3804
|
+
return result;
|
3417
3805
|
}
|
3418
3806
|
|
3419
3807
|
static int stbi__jpeg_test(stbi__context *s)
|
3420
3808
|
{
|
3421
3809
|
int r;
|
3422
|
-
stbi__jpeg j;
|
3423
|
-
j
|
3424
|
-
stbi__setup_jpeg(
|
3425
|
-
r = stbi__decode_jpeg_header(
|
3810
|
+
stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
|
3811
|
+
j->s = s;
|
3812
|
+
stbi__setup_jpeg(j);
|
3813
|
+
r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
|
3426
3814
|
stbi__rewind(s);
|
3815
|
+
STBI_FREE(j);
|
3427
3816
|
return r;
|
3428
3817
|
}
|
3429
3818
|
|
@@ -3435,15 +3824,18 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
|
|
3435
3824
|
}
|
3436
3825
|
if (x) *x = j->s->img_x;
|
3437
3826
|
if (y) *y = j->s->img_y;
|
3438
|
-
if (comp) *comp = j->s->img_n;
|
3827
|
+
if (comp) *comp = j->s->img_n >= 3 ? 3 : 1;
|
3439
3828
|
return 1;
|
3440
3829
|
}
|
3441
3830
|
|
3442
3831
|
static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
|
3443
3832
|
{
|
3444
|
-
|
3445
|
-
j
|
3446
|
-
|
3833
|
+
int result;
|
3834
|
+
stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
|
3835
|
+
j->s = s;
|
3836
|
+
result = stbi__jpeg_info_raw(j, x, y, comp);
|
3837
|
+
STBI_FREE(j);
|
3838
|
+
return result;
|
3447
3839
|
}
|
3448
3840
|
#endif
|
3449
3841
|
|
@@ -3489,7 +3881,7 @@ stbi_inline static int stbi__bit_reverse(int v, int bits)
|
|
3489
3881
|
return stbi__bitreverse16(v) >> (16-bits);
|
3490
3882
|
}
|
3491
3883
|
|
3492
|
-
static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
|
3884
|
+
static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num)
|
3493
3885
|
{
|
3494
3886
|
int i,k=0;
|
3495
3887
|
int code, next_code[16], sizes[17];
|
@@ -3616,14 +4008,15 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
|
3616
4008
|
static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
|
3617
4009
|
{
|
3618
4010
|
char *q;
|
3619
|
-
int cur, limit;
|
4011
|
+
int cur, limit, old_limit;
|
3620
4012
|
z->zout = zout;
|
3621
4013
|
if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
|
3622
4014
|
cur = (int) (z->zout - z->zout_start);
|
3623
|
-
limit = (int) (z->zout_end - z->zout_start);
|
4015
|
+
limit = old_limit = (int) (z->zout_end - z->zout_start);
|
3624
4016
|
while (cur + n > limit)
|
3625
4017
|
limit *= 2;
|
3626
|
-
q = (char *)
|
4018
|
+
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
|
4019
|
+
STBI_NOTUSED(old_limit);
|
3627
4020
|
if (q == NULL) return stbi__err("outofmem", "Out of memory");
|
3628
4021
|
z->zout_start = q;
|
3629
4022
|
z->zout = q + cur;
|
@@ -3631,18 +4024,18 @@ static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room
|
|
3631
4024
|
return 1;
|
3632
4025
|
}
|
3633
4026
|
|
3634
|
-
static int stbi__zlength_base[31] = {
|
4027
|
+
static const int stbi__zlength_base[31] = {
|
3635
4028
|
3,4,5,6,7,8,9,10,11,13,
|
3636
4029
|
15,17,19,23,27,31,35,43,51,59,
|
3637
4030
|
67,83,99,115,131,163,195,227,258,0,0 };
|
3638
4031
|
|
3639
|
-
static int stbi__zlength_extra[31]=
|
4032
|
+
static const int stbi__zlength_extra[31]=
|
3640
4033
|
{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
|
3641
4034
|
|
3642
|
-
static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
|
4035
|
+
static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
|
3643
4036
|
257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
|
3644
4037
|
|
3645
|
-
static int stbi__zdist_extra[32] =
|
4038
|
+
static const int stbi__zdist_extra[32] =
|
3646
4039
|
{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
|
3647
4040
|
|
3648
4041
|
static int stbi__parse_huffman_block(stbi__zbuf *a)
|
@@ -3689,7 +4082,7 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
|
3689
4082
|
|
3690
4083
|
static int stbi__compute_huffman_codes(stbi__zbuf *a)
|
3691
4084
|
{
|
3692
|
-
static stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
|
4085
|
+
static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
|
3693
4086
|
stbi__zhuffman z_codelength;
|
3694
4087
|
stbi_uc lencodes[286+32+137];//padding for maximum single op
|
3695
4088
|
stbi_uc codelength_sizes[19];
|
@@ -3698,6 +4091,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
|
|
3698
4091
|
int hlit = stbi__zreceive(a,5) + 257;
|
3699
4092
|
int hdist = stbi__zreceive(a,5) + 1;
|
3700
4093
|
int hclen = stbi__zreceive(a,4) + 4;
|
4094
|
+
int ntot = hlit + hdist;
|
3701
4095
|
|
3702
4096
|
memset(codelength_sizes, 0, sizeof(codelength_sizes));
|
3703
4097
|
for (i=0; i < hclen; ++i) {
|
@@ -3707,33 +4101,35 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
|
|
3707
4101
|
if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0;
|
3708
4102
|
|
3709
4103
|
n = 0;
|
3710
|
-
while (n <
|
4104
|
+
while (n < ntot) {
|
3711
4105
|
int c = stbi__zhuffman_decode(a, &z_codelength);
|
3712
4106
|
if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG");
|
3713
4107
|
if (c < 16)
|
3714
4108
|
lencodes[n++] = (stbi_uc) c;
|
3715
|
-
else
|
3716
|
-
|
3717
|
-
|
3718
|
-
|
3719
|
-
|
3720
|
-
|
3721
|
-
|
3722
|
-
|
3723
|
-
|
3724
|
-
|
3725
|
-
|
3726
|
-
|
4109
|
+
else {
|
4110
|
+
stbi_uc fill = 0;
|
4111
|
+
if (c == 16) {
|
4112
|
+
c = stbi__zreceive(a,2)+3;
|
4113
|
+
if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
|
4114
|
+
fill = lencodes[n-1];
|
4115
|
+
} else if (c == 17)
|
4116
|
+
c = stbi__zreceive(a,3)+3;
|
4117
|
+
else {
|
4118
|
+
STBI_ASSERT(c == 18);
|
4119
|
+
c = stbi__zreceive(a,7)+11;
|
4120
|
+
}
|
4121
|
+
if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
|
4122
|
+
memset(lencodes+n, fill, c);
|
3727
4123
|
n += c;
|
3728
4124
|
}
|
3729
4125
|
}
|
3730
|
-
if (n !=
|
4126
|
+
if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG");
|
3731
4127
|
if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0;
|
3732
4128
|
if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0;
|
3733
4129
|
return 1;
|
3734
4130
|
}
|
3735
4131
|
|
3736
|
-
static int
|
4132
|
+
static int stbi__parse_uncompressed_block(stbi__zbuf *a)
|
3737
4133
|
{
|
3738
4134
|
stbi_uc header[4];
|
3739
4135
|
int len,nlen,k;
|
@@ -3775,9 +4171,24 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
|
|
3775
4171
|
return 1;
|
3776
4172
|
}
|
3777
4173
|
|
3778
|
-
|
3779
|
-
|
3780
|
-
|
4174
|
+
static const stbi_uc stbi__zdefault_length[288] =
|
4175
|
+
{
|
4176
|
+
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,
|
4177
|
+
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,
|
4178
|
+
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,
|
4179
|
+
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,
|
4180
|
+
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,
|
4181
|
+
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,
|
4182
|
+
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,
|
4183
|
+
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,
|
4184
|
+
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
|
4185
|
+
};
|
4186
|
+
static const stbi_uc stbi__zdefault_distance[32] =
|
4187
|
+
{
|
4188
|
+
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
|
4189
|
+
};
|
4190
|
+
/*
|
4191
|
+
Init algorithm:
|
3781
4192
|
{
|
3782
4193
|
int i; // use <= to match clearly with spec
|
3783
4194
|
for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8;
|
@@ -3787,6 +4198,7 @@ static void stbi__init_zdefaults(void)
|
|
3787
4198
|
|
3788
4199
|
for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5;
|
3789
4200
|
}
|
4201
|
+
*/
|
3790
4202
|
|
3791
4203
|
static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
3792
4204
|
{
|
@@ -3799,13 +4211,12 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
|
3799
4211
|
final = stbi__zreceive(a,1);
|
3800
4212
|
type = stbi__zreceive(a,2);
|
3801
4213
|
if (type == 0) {
|
3802
|
-
if (!
|
4214
|
+
if (!stbi__parse_uncompressed_block(a)) return 0;
|
3803
4215
|
} else if (type == 3) {
|
3804
4216
|
return 0;
|
3805
4217
|
} else {
|
3806
4218
|
if (type == 1) {
|
3807
4219
|
// use fixed code lengths
|
3808
|
-
if (!stbi__zdefault_distance[31]) stbi__init_zdefaults();
|
3809
4220
|
if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0;
|
3810
4221
|
if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0;
|
3811
4222
|
} else {
|
@@ -3930,7 +4341,7 @@ static stbi__pngchunk stbi__get_chunk_header(stbi__context *s)
|
|
3930
4341
|
|
3931
4342
|
static int stbi__check_png_header(stbi__context *s)
|
3932
4343
|
{
|
3933
|
-
static stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 };
|
4344
|
+
static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 };
|
3934
4345
|
int i;
|
3935
4346
|
for (i=0; i < 8; ++i)
|
3936
4347
|
if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG");
|
@@ -3941,6 +4352,7 @@ typedef struct
|
|
3941
4352
|
{
|
3942
4353
|
stbi__context *s;
|
3943
4354
|
stbi_uc *idata, *expanded, *out;
|
4355
|
+
int depth;
|
3944
4356
|
} stbi__png;
|
3945
4357
|
|
3946
4358
|
|
@@ -3975,35 +4387,40 @@ static int stbi__paeth(int a, int b, int c)
|
|
3975
4387
|
return c;
|
3976
4388
|
}
|
3977
4389
|
|
3978
|
-
static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
|
4390
|
+
static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
|
3979
4391
|
|
3980
4392
|
// create the png data from post-deflated data
|
3981
4393
|
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
|
3982
4394
|
{
|
4395
|
+
int bytes = (depth == 16? 2 : 1);
|
3983
4396
|
stbi__context *s = a->s;
|
3984
|
-
stbi__uint32 i,j,stride = x*out_n;
|
4397
|
+
stbi__uint32 i,j,stride = x*out_n*bytes;
|
3985
4398
|
stbi__uint32 img_len, img_width_bytes;
|
3986
4399
|
int k;
|
3987
4400
|
int img_n = s->img_n; // copy it into a local for later
|
3988
4401
|
|
4402
|
+
int output_bytes = out_n*bytes;
|
4403
|
+
int filter_bytes = img_n*bytes;
|
4404
|
+
int width = x;
|
4405
|
+
|
3989
4406
|
STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
|
3990
|
-
a->out = (stbi_uc *)
|
4407
|
+
a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
|
3991
4408
|
if (!a->out) return stbi__err("outofmem", "Out of memory");
|
3992
4409
|
|
4410
|
+
if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
|
3993
4411
|
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
3994
4412
|
img_len = (img_width_bytes + 1) * y;
|
3995
|
-
|
3996
|
-
|
3997
|
-
|
3998
|
-
|
3999
|
-
|
4413
|
+
|
4414
|
+
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
|
4415
|
+
// but issue #276 reported a PNG in the wild that had extra data at the end (all zeros),
|
4416
|
+
// so just check for raw_len < img_len always.
|
4417
|
+
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
|
4000
4418
|
|
4001
4419
|
for (j=0; j < y; ++j) {
|
4002
4420
|
stbi_uc *cur = a->out + stride*j;
|
4003
|
-
stbi_uc *prior
|
4421
|
+
stbi_uc *prior;
|
4004
4422
|
int filter = *raw++;
|
4005
|
-
|
4006
|
-
int width = x;
|
4423
|
+
|
4007
4424
|
if (filter > 4)
|
4008
4425
|
return stbi__err("invalid filter","Corrupt PNG");
|
4009
4426
|
|
@@ -4013,6 +4430,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4013
4430
|
filter_bytes = 1;
|
4014
4431
|
width = img_width_bytes;
|
4015
4432
|
}
|
4433
|
+
prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
|
4016
4434
|
|
4017
4435
|
// if first row, use special filter that doesn't sample previous row
|
4018
4436
|
if (j == 0) filter = first_row_filter[filter];
|
@@ -4036,6 +4454,14 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4036
4454
|
raw += img_n;
|
4037
4455
|
cur += out_n;
|
4038
4456
|
prior += out_n;
|
4457
|
+
} else if (depth == 16) {
|
4458
|
+
if (img_n != out_n) {
|
4459
|
+
cur[filter_bytes] = 255; // first pixel top byte
|
4460
|
+
cur[filter_bytes+1] = 255; // first pixel bottom byte
|
4461
|
+
}
|
4462
|
+
raw += filter_bytes;
|
4463
|
+
cur += output_bytes;
|
4464
|
+
prior += output_bytes;
|
4039
4465
|
} else {
|
4040
4466
|
raw += 1;
|
4041
4467
|
cur += 1;
|
@@ -4044,38 +4470,47 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4044
4470
|
|
4045
4471
|
// this is a little gross, so that we don't switch per-pixel or per-component
|
4046
4472
|
if (depth < 8 || img_n == out_n) {
|
4047
|
-
int nk = (width - 1)*
|
4048
|
-
#define
|
4473
|
+
int nk = (width - 1)*filter_bytes;
|
4474
|
+
#define STBI__CASE(f) \
|
4049
4475
|
case f: \
|
4050
4476
|
for (k=0; k < nk; ++k)
|
4051
4477
|
switch (filter) {
|
4052
4478
|
// "none" filter turns into a memcpy here; make that explicit.
|
4053
4479
|
case STBI__F_none: memcpy(cur, raw, nk); break;
|
4054
|
-
|
4055
|
-
|
4056
|
-
|
4057
|
-
|
4058
|
-
|
4059
|
-
|
4480
|
+
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
|
4481
|
+
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
4482
|
+
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
|
4483
|
+
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
|
4484
|
+
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
|
4485
|
+
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
|
4060
4486
|
}
|
4061
|
-
#undef
|
4487
|
+
#undef STBI__CASE
|
4062
4488
|
raw += nk;
|
4063
4489
|
} else {
|
4064
4490
|
STBI_ASSERT(img_n+1 == out_n);
|
4065
|
-
#define
|
4491
|
+
#define STBI__CASE(f) \
|
4066
4492
|
case f: \
|
4067
|
-
for (i=x-1; i >= 1; --i, cur[
|
4068
|
-
for (k=0; k <
|
4493
|
+
for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
|
4494
|
+
for (k=0; k < filter_bytes; ++k)
|
4069
4495
|
switch (filter) {
|
4070
|
-
|
4071
|
-
|
4072
|
-
|
4073
|
-
|
4074
|
-
|
4075
|
-
|
4076
|
-
|
4496
|
+
STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break;
|
4497
|
+
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
|
4498
|
+
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
4499
|
+
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
|
4500
|
+
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
|
4501
|
+
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
|
4502
|
+
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
|
4503
|
+
}
|
4504
|
+
#undef STBI__CASE
|
4505
|
+
|
4506
|
+
// the loop above sets the high byte of the pixels' alpha, but for
|
4507
|
+
// 16 bit png files we also need the low byte set. we'll do that here.
|
4508
|
+
if (depth == 16) {
|
4509
|
+
cur = a->out + stride*j; // start at the beginning of the row again
|
4510
|
+
for (i=0; i < x; ++i,cur+=output_bytes) {
|
4511
|
+
cur[filter_bytes+1] = 255;
|
4512
|
+
}
|
4077
4513
|
}
|
4078
|
-
#undef CASE
|
4079
4514
|
}
|
4080
4515
|
}
|
4081
4516
|
|
@@ -4151,6 +4586,17 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4151
4586
|
}
|
4152
4587
|
}
|
4153
4588
|
}
|
4589
|
+
} else if (depth == 16) {
|
4590
|
+
// force the image data from big-endian to platform-native.
|
4591
|
+
// this is done in a separate pass due to the decoding relying
|
4592
|
+
// on the data being untouched, but could probably be done
|
4593
|
+
// per-line during decode if care is taken.
|
4594
|
+
stbi_uc *cur = a->out;
|
4595
|
+
stbi__uint16 *cur16 = (stbi__uint16*)cur;
|
4596
|
+
|
4597
|
+
for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
|
4598
|
+
*cur16 = (cur[0] << 8) | cur[1];
|
4599
|
+
}
|
4154
4600
|
}
|
4155
4601
|
|
4156
4602
|
return 1;
|
@@ -4158,13 +4604,15 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|
4158
4604
|
|
4159
4605
|
static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced)
|
4160
4606
|
{
|
4607
|
+
int bytes = (depth == 16 ? 2 : 1);
|
4608
|
+
int out_bytes = out_n * bytes;
|
4161
4609
|
stbi_uc *final;
|
4162
4610
|
int p;
|
4163
4611
|
if (!interlaced)
|
4164
4612
|
return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color);
|
4165
4613
|
|
4166
4614
|
// de-interlacing
|
4167
|
-
final = (stbi_uc *)
|
4615
|
+
final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
|
4168
4616
|
for (p=0; p < 7; ++p) {
|
4169
4617
|
int xorig[] = { 0,4,0,2,0,1,0 };
|
4170
4618
|
int yorig[] = { 0,0,4,0,2,0,1 };
|
@@ -4184,8 +4632,8 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3
|
|
4184
4632
|
for (i=0; i < x; ++i) {
|
4185
4633
|
int out_y = j*yspc[p]+yorig[p];
|
4186
4634
|
int out_x = i*xspc[p]+xorig[p];
|
4187
|
-
memcpy(final + out_y*a->s->img_x*
|
4188
|
-
a->out + (j*x+i)*
|
4635
|
+
memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes,
|
4636
|
+
a->out + (j*x+i)*out_bytes, out_bytes);
|
4189
4637
|
}
|
4190
4638
|
}
|
4191
4639
|
STBI_FREE(a->out);
|
@@ -4223,12 +4671,37 @@ static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
|
|
4223
4671
|
return 1;
|
4224
4672
|
}
|
4225
4673
|
|
4674
|
+
static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n)
|
4675
|
+
{
|
4676
|
+
stbi__context *s = z->s;
|
4677
|
+
stbi__uint32 i, pixel_count = s->img_x * s->img_y;
|
4678
|
+
stbi__uint16 *p = (stbi__uint16*) z->out;
|
4679
|
+
|
4680
|
+
// compute color-based transparency, assuming we've
|
4681
|
+
// already got 65535 as the alpha value in the output
|
4682
|
+
STBI_ASSERT(out_n == 2 || out_n == 4);
|
4683
|
+
|
4684
|
+
if (out_n == 2) {
|
4685
|
+
for (i = 0; i < pixel_count; ++i) {
|
4686
|
+
p[1] = (p[0] == tc[0] ? 0 : 65535);
|
4687
|
+
p += 2;
|
4688
|
+
}
|
4689
|
+
} else {
|
4690
|
+
for (i = 0; i < pixel_count; ++i) {
|
4691
|
+
if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
|
4692
|
+
p[3] = 0;
|
4693
|
+
p += 4;
|
4694
|
+
}
|
4695
|
+
}
|
4696
|
+
return 1;
|
4697
|
+
}
|
4698
|
+
|
4226
4699
|
static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n)
|
4227
4700
|
{
|
4228
4701
|
stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
|
4229
4702
|
stbi_uc *p, *temp_out, *orig = a->out;
|
4230
4703
|
|
4231
|
-
p = (stbi_uc *)
|
4704
|
+
p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0);
|
4232
4705
|
if (p == NULL) return stbi__err("outofmem", "Out of memory");
|
4233
4706
|
|
4234
4707
|
// between here and free(out) below, exitting would leak
|
@@ -4294,9 +4767,10 @@ static void stbi__de_iphone(stbi__png *z)
|
|
4294
4767
|
stbi_uc a = p[3];
|
4295
4768
|
stbi_uc t = p[0];
|
4296
4769
|
if (a) {
|
4297
|
-
|
4298
|
-
p[
|
4299
|
-
p[
|
4770
|
+
stbi_uc half = a / 2;
|
4771
|
+
p[0] = (p[2] * 255 + half) / a;
|
4772
|
+
p[1] = (p[1] * 255 + half) / a;
|
4773
|
+
p[2] = ( t * 255 + half) / a;
|
4300
4774
|
} else {
|
4301
4775
|
p[0] = p[2];
|
4302
4776
|
p[2] = t;
|
@@ -4315,14 +4789,15 @@ static void stbi__de_iphone(stbi__png *z)
|
|
4315
4789
|
}
|
4316
4790
|
}
|
4317
4791
|
|
4318
|
-
#define STBI__PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
|
4792
|
+
#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d))
|
4319
4793
|
|
4320
4794
|
static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
4321
4795
|
{
|
4322
4796
|
stbi_uc palette[1024], pal_img_n=0;
|
4323
|
-
stbi_uc has_trans=0, tc[3];
|
4797
|
+
stbi_uc has_trans=0, tc[3]={0};
|
4798
|
+
stbi__uint16 tc16[3];
|
4324
4799
|
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
|
4325
|
-
int first=1,k,interlace=0, color=0,
|
4800
|
+
int first=1,k,interlace=0, color=0, is_iphone=0;
|
4326
4801
|
stbi__context *s = z->s;
|
4327
4802
|
|
4328
4803
|
z->expanded = NULL;
|
@@ -4347,8 +4822,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4347
4822
|
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
|
4348
4823
|
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
4349
4824
|
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
4350
|
-
depth = stbi__get8(s); if (depth != 1 && depth != 2 && depth != 4 && depth != 8) return stbi__err("1/2/4/8-bit only","PNG not supported: 1/2/4/8-bit only");
|
4825
|
+
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");
|
4351
4826
|
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
|
4827
|
+
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
|
4352
4828
|
if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
|
4353
4829
|
comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
|
4354
4830
|
filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG");
|
@@ -4396,8 +4872,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4396
4872
|
if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
|
4397
4873
|
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
|
4398
4874
|
has_trans = 1;
|
4399
|
-
|
4400
|
-
|
4875
|
+
if (z->depth == 16) {
|
4876
|
+
for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
4877
|
+
} else {
|
4878
|
+
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
|
4879
|
+
}
|
4401
4880
|
}
|
4402
4881
|
break;
|
4403
4882
|
}
|
@@ -4408,11 +4887,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4408
4887
|
if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
|
4409
4888
|
if ((int)(ioff + c.length) < (int)ioff) return 0;
|
4410
4889
|
if (ioff + c.length > idata_limit) {
|
4890
|
+
stbi__uint32 idata_limit_old = idata_limit;
|
4411
4891
|
stbi_uc *p;
|
4412
4892
|
if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
|
4413
4893
|
while (ioff + c.length > idata_limit)
|
4414
4894
|
idata_limit *= 2;
|
4415
|
-
|
4895
|
+
STBI_NOTUSED(idata_limit_old);
|
4896
|
+
p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
|
4416
4897
|
z->idata = p;
|
4417
4898
|
}
|
4418
4899
|
if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG");
|
@@ -4426,7 +4907,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4426
4907
|
if (scan != STBI__SCAN_load) return 1;
|
4427
4908
|
if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
|
4428
4909
|
// initial guess for decoded data size to avoid unnecessary reallocs
|
4429
|
-
bpl = (s->img_x * depth + 7) / 8; // bytes per line, per component
|
4910
|
+
bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
|
4430
4911
|
raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
|
4431
4912
|
z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
|
4432
4913
|
if (z->expanded == NULL) return 0; // zlib should set error
|
@@ -4435,9 +4916,14 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4435
4916
|
s->img_out_n = s->img_n+1;
|
4436
4917
|
else
|
4437
4918
|
s->img_out_n = s->img_n;
|
4438
|
-
if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, depth, color, interlace)) return 0;
|
4439
|
-
if (has_trans)
|
4440
|
-
if (
|
4919
|
+
if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
|
4920
|
+
if (has_trans) {
|
4921
|
+
if (z->depth == 16) {
|
4922
|
+
if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0;
|
4923
|
+
} else {
|
4924
|
+
if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
|
4925
|
+
}
|
4926
|
+
}
|
4441
4927
|
if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
|
4442
4928
|
stbi__de_iphone(z);
|
4443
4929
|
if (pal_img_n) {
|
@@ -4447,6 +4933,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4447
4933
|
if (req_comp >= 3) s->img_out_n = req_comp;
|
4448
4934
|
if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n))
|
4449
4935
|
return 0;
|
4936
|
+
} else if (has_trans) {
|
4937
|
+
// non-paletted image with tRNS -> source image has (constant) alpha
|
4938
|
+
++s->img_n;
|
4450
4939
|
}
|
4451
4940
|
STBI_FREE(z->expanded); z->expanded = NULL;
|
4452
4941
|
return 1;
|
@@ -4474,21 +4963,28 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
4474
4963
|
}
|
4475
4964
|
}
|
4476
4965
|
|
4477
|
-
static
|
4966
|
+
static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri)
|
4478
4967
|
{
|
4479
|
-
|
4968
|
+
void *result=NULL;
|
4480
4969
|
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
|
4481
4970
|
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
|
4971
|
+
if (p->depth < 8)
|
4972
|
+
ri->bits_per_channel = 8;
|
4973
|
+
else
|
4974
|
+
ri->bits_per_channel = p->depth;
|
4482
4975
|
result = p->out;
|
4483
4976
|
p->out = NULL;
|
4484
4977
|
if (req_comp && req_comp != p->s->img_out_n) {
|
4485
|
-
|
4978
|
+
if (ri->bits_per_channel == 8)
|
4979
|
+
result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
|
4980
|
+
else
|
4981
|
+
result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
|
4486
4982
|
p->s->img_out_n = req_comp;
|
4487
4983
|
if (result == NULL) return result;
|
4488
4984
|
}
|
4489
4985
|
*x = p->s->img_x;
|
4490
4986
|
*y = p->s->img_y;
|
4491
|
-
if (n) *n = p->s->
|
4987
|
+
if (n) *n = p->s->img_n;
|
4492
4988
|
}
|
4493
4989
|
STBI_FREE(p->out); p->out = NULL;
|
4494
4990
|
STBI_FREE(p->expanded); p->expanded = NULL;
|
@@ -4497,11 +4993,11 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
|
|
4497
4993
|
return result;
|
4498
4994
|
}
|
4499
4995
|
|
4500
|
-
static
|
4996
|
+
static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
4501
4997
|
{
|
4502
4998
|
stbi__png p;
|
4503
4999
|
p.s = s;
|
4504
|
-
return stbi__do_png(&p, x,y,comp,req_comp);
|
5000
|
+
return stbi__do_png(&p, x,y,comp,req_comp, ri);
|
4505
5001
|
}
|
4506
5002
|
|
4507
5003
|
static int stbi__png_test(stbi__context *s)
|
@@ -4530,6 +5026,19 @@ static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp)
|
|
4530
5026
|
p.s = s;
|
4531
5027
|
return stbi__png_info_raw(&p, x, y, comp);
|
4532
5028
|
}
|
5029
|
+
|
5030
|
+
static int stbi__png_is16(stbi__context *s)
|
5031
|
+
{
|
5032
|
+
stbi__png p;
|
5033
|
+
p.s = s;
|
5034
|
+
if (!stbi__png_info_raw(&p, NULL, NULL, NULL))
|
5035
|
+
return 0;
|
5036
|
+
if (p.depth != 16) {
|
5037
|
+
stbi__rewind(p.s);
|
5038
|
+
return 0;
|
5039
|
+
}
|
5040
|
+
return 1;
|
5041
|
+
}
|
4533
5042
|
#endif
|
4534
5043
|
|
4535
5044
|
// Microsoft/Windows BMP image
|
@@ -4563,11 +5072,11 @@ static int stbi__high_bit(unsigned int z)
|
|
4563
5072
|
{
|
4564
5073
|
int n=0;
|
4565
5074
|
if (z == 0) return -1;
|
4566
|
-
if (z >= 0x10000) n += 16
|
4567
|
-
if (z >= 0x00100) n += 8
|
4568
|
-
if (z >= 0x00010) n += 4
|
4569
|
-
if (z >= 0x00004) n += 2
|
4570
|
-
if (z >= 0x00002) n += 1
|
5075
|
+
if (z >= 0x10000) { n += 16; z >>= 16; }
|
5076
|
+
if (z >= 0x00100) { n += 8; z >>= 8; }
|
5077
|
+
if (z >= 0x00010) { n += 4; z >>= 4; }
|
5078
|
+
if (z >= 0x00004) { n += 2; z >>= 2; }
|
5079
|
+
if (z >= 0x00002) { n += 1; z >>= 1; }
|
4571
5080
|
return n;
|
4572
5081
|
}
|
4573
5082
|
|
@@ -4581,36 +5090,46 @@ static int stbi__bitcount(unsigned int a)
|
|
4581
5090
|
return a & 0xff;
|
4582
5091
|
}
|
4583
5092
|
|
4584
|
-
|
4585
|
-
|
4586
|
-
|
4587
|
-
|
4588
|
-
|
4589
|
-
|
4590
|
-
|
4591
|
-
|
4592
|
-
|
4593
|
-
|
4594
|
-
|
4595
|
-
|
4596
|
-
|
4597
|
-
|
4598
|
-
|
5093
|
+
// extract an arbitrarily-aligned N-bit value (N=bits)
|
5094
|
+
// from v, and then make it 8-bits long and fractionally
|
5095
|
+
// extend it to full full range.
|
5096
|
+
static int stbi__shiftsigned(unsigned int v, int shift, int bits)
|
5097
|
+
{
|
5098
|
+
static unsigned int mul_table[9] = {
|
5099
|
+
0,
|
5100
|
+
0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/,
|
5101
|
+
0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/,
|
5102
|
+
};
|
5103
|
+
static unsigned int shift_table[9] = {
|
5104
|
+
0, 0,0,1,0,2,4,6,0,
|
5105
|
+
};
|
5106
|
+
if (shift < 0)
|
5107
|
+
v <<= -shift;
|
5108
|
+
else
|
5109
|
+
v >>= shift;
|
5110
|
+
STBI_ASSERT(v >= 0 && v < 256);
|
5111
|
+
v >>= (8-bits);
|
5112
|
+
STBI_ASSERT(bits >= 0 && bits <= 8);
|
5113
|
+
return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
|
4599
5114
|
}
|
4600
5115
|
|
4601
|
-
|
5116
|
+
typedef struct
|
4602
5117
|
{
|
4603
|
-
|
4604
|
-
unsigned int mr
|
4605
|
-
|
4606
|
-
|
4607
|
-
|
5118
|
+
int bpp, offset, hsz;
|
5119
|
+
unsigned int mr,mg,mb,ma, all_a;
|
5120
|
+
} stbi__bmp_data;
|
5121
|
+
|
5122
|
+
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
5123
|
+
{
|
5124
|
+
int hsz;
|
4608
5125
|
if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP");
|
4609
5126
|
stbi__get32le(s); // discard filesize
|
4610
5127
|
stbi__get16le(s); // discard reserved
|
4611
5128
|
stbi__get16le(s); // discard reserved
|
4612
|
-
offset = stbi__get32le(s);
|
4613
|
-
hsz = stbi__get32le(s);
|
5129
|
+
info->offset = stbi__get32le(s);
|
5130
|
+
info->hsz = hsz = stbi__get32le(s);
|
5131
|
+
info->mr = info->mg = info->mb = info->ma = 0;
|
5132
|
+
|
4614
5133
|
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
|
4615
5134
|
if (hsz == 12) {
|
4616
5135
|
s->img_x = stbi__get16le(s);
|
@@ -4620,15 +5139,9 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4620
5139
|
s->img_y = stbi__get32le(s);
|
4621
5140
|
}
|
4622
5141
|
if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP");
|
4623
|
-
bpp = stbi__get16le(s);
|
4624
|
-
if (
|
4625
|
-
|
4626
|
-
s->img_y = abs((int) s->img_y);
|
4627
|
-
if (hsz == 12) {
|
4628
|
-
if (bpp < 24)
|
4629
|
-
psize = (offset - 14 - 24) / 3;
|
4630
|
-
} else {
|
4631
|
-
compress = stbi__get32le(s);
|
5142
|
+
info->bpp = stbi__get16le(s);
|
5143
|
+
if (hsz != 12) {
|
5144
|
+
int compress = stbi__get32le(s);
|
4632
5145
|
if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
|
4633
5146
|
stbi__get32le(s); // discard sizeof
|
4634
5147
|
stbi__get32le(s); // discard hres
|
@@ -4642,26 +5155,25 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4642
5155
|
stbi__get32le(s);
|
4643
5156
|
stbi__get32le(s);
|
4644
5157
|
}
|
4645
|
-
if (bpp == 16 || bpp == 32) {
|
4646
|
-
mr = mg = mb = 0;
|
5158
|
+
if (info->bpp == 16 || info->bpp == 32) {
|
4647
5159
|
if (compress == 0) {
|
4648
|
-
if (bpp == 32) {
|
4649
|
-
mr = 0xffu << 16;
|
4650
|
-
mg = 0xffu << 8;
|
4651
|
-
mb = 0xffu << 0;
|
4652
|
-
ma = 0xffu << 24;
|
4653
|
-
all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
|
5160
|
+
if (info->bpp == 32) {
|
5161
|
+
info->mr = 0xffu << 16;
|
5162
|
+
info->mg = 0xffu << 8;
|
5163
|
+
info->mb = 0xffu << 0;
|
5164
|
+
info->ma = 0xffu << 24;
|
5165
|
+
info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
|
4654
5166
|
} else {
|
4655
|
-
mr = 31u << 10;
|
4656
|
-
mg = 31u << 5;
|
4657
|
-
mb = 31u << 0;
|
5167
|
+
info->mr = 31u << 10;
|
5168
|
+
info->mg = 31u << 5;
|
5169
|
+
info->mb = 31u << 0;
|
4658
5170
|
}
|
4659
5171
|
} else if (compress == 3) {
|
4660
|
-
mr = stbi__get32le(s);
|
4661
|
-
mg = stbi__get32le(s);
|
4662
|
-
mb = stbi__get32le(s);
|
5172
|
+
info->mr = stbi__get32le(s);
|
5173
|
+
info->mg = stbi__get32le(s);
|
5174
|
+
info->mb = stbi__get32le(s);
|
4663
5175
|
// not documented, but generated by photoshop and handled by mspaint
|
4664
|
-
if (mr == mg && mg == mb) {
|
5176
|
+
if (info->mr == info->mg && info->mg == info->mb) {
|
4665
5177
|
// ?!?!?
|
4666
5178
|
return stbi__errpuc("bad BMP", "bad BMP");
|
4667
5179
|
}
|
@@ -4669,11 +5181,13 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4669
5181
|
return stbi__errpuc("bad BMP", "bad BMP");
|
4670
5182
|
}
|
4671
5183
|
} else {
|
4672
|
-
|
4673
|
-
|
4674
|
-
|
4675
|
-
|
4676
|
-
|
5184
|
+
int i;
|
5185
|
+
if (hsz != 108 && hsz != 124)
|
5186
|
+
return stbi__errpuc("bad BMP", "bad BMP");
|
5187
|
+
info->mr = stbi__get32le(s);
|
5188
|
+
info->mg = stbi__get32le(s);
|
5189
|
+
info->mb = stbi__get32le(s);
|
5190
|
+
info->ma = stbi__get32le(s);
|
4677
5191
|
stbi__get32le(s); // discard color space
|
4678
5192
|
for (i=0; i < 12; ++i)
|
4679
5193
|
stbi__get32le(s); // discard color space parameters
|
@@ -4684,63 +5198,121 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4684
5198
|
stbi__get32le(s); // discard reserved
|
4685
5199
|
}
|
4686
5200
|
}
|
4687
|
-
if (bpp < 16)
|
4688
|
-
psize = (offset - 14 - hsz) >> 2;
|
4689
5201
|
}
|
5202
|
+
return (void *) 1;
|
5203
|
+
}
|
5204
|
+
|
5205
|
+
|
5206
|
+
static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
5207
|
+
{
|
5208
|
+
stbi_uc *out;
|
5209
|
+
unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
|
5210
|
+
stbi_uc pal[256][4];
|
5211
|
+
int psize=0,i,j,width;
|
5212
|
+
int flip_vertically, pad, target;
|
5213
|
+
stbi__bmp_data info;
|
5214
|
+
STBI_NOTUSED(ri);
|
5215
|
+
|
5216
|
+
info.all_a = 255;
|
5217
|
+
if (stbi__bmp_parse_header(s, &info) == NULL)
|
5218
|
+
return NULL; // error code already set
|
5219
|
+
|
5220
|
+
flip_vertically = ((int) s->img_y) > 0;
|
5221
|
+
s->img_y = abs((int) s->img_y);
|
5222
|
+
|
5223
|
+
mr = info.mr;
|
5224
|
+
mg = info.mg;
|
5225
|
+
mb = info.mb;
|
5226
|
+
ma = info.ma;
|
5227
|
+
all_a = info.all_a;
|
5228
|
+
|
5229
|
+
if (info.hsz == 12) {
|
5230
|
+
if (info.bpp < 24)
|
5231
|
+
psize = (info.offset - 14 - 24) / 3;
|
5232
|
+
} else {
|
5233
|
+
if (info.bpp < 16)
|
5234
|
+
psize = (info.offset - 14 - info.hsz) >> 2;
|
5235
|
+
}
|
5236
|
+
|
4690
5237
|
s->img_n = ma ? 4 : 3;
|
4691
5238
|
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
|
4692
5239
|
target = req_comp;
|
4693
5240
|
else
|
4694
5241
|
target = s->img_n; // if they want monochrome, we'll post-convert
|
4695
|
-
|
5242
|
+
|
5243
|
+
// sanity-check size
|
5244
|
+
if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0))
|
5245
|
+
return stbi__errpuc("too large", "Corrupt BMP");
|
5246
|
+
|
5247
|
+
out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0);
|
4696
5248
|
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
4697
|
-
if (bpp < 16) {
|
5249
|
+
if (info.bpp < 16) {
|
4698
5250
|
int z=0;
|
4699
5251
|
if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); }
|
4700
5252
|
for (i=0; i < psize; ++i) {
|
4701
5253
|
pal[i][2] = stbi__get8(s);
|
4702
5254
|
pal[i][1] = stbi__get8(s);
|
4703
5255
|
pal[i][0] = stbi__get8(s);
|
4704
|
-
if (hsz != 12) stbi__get8(s);
|
5256
|
+
if (info.hsz != 12) stbi__get8(s);
|
4705
5257
|
pal[i][3] = 255;
|
4706
5258
|
}
|
4707
|
-
stbi__skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4));
|
4708
|
-
if (bpp ==
|
4709
|
-
else if (bpp ==
|
5259
|
+
stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
|
5260
|
+
if (info.bpp == 1) width = (s->img_x + 7) >> 3;
|
5261
|
+
else if (info.bpp == 4) width = (s->img_x + 1) >> 1;
|
5262
|
+
else if (info.bpp == 8) width = s->img_x;
|
4710
5263
|
else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); }
|
4711
5264
|
pad = (-width)&3;
|
4712
|
-
|
4713
|
-
for (
|
4714
|
-
int v=stbi__get8(s)
|
4715
|
-
|
4716
|
-
|
4717
|
-
|
5265
|
+
if (info.bpp == 1) {
|
5266
|
+
for (j=0; j < (int) s->img_y; ++j) {
|
5267
|
+
int bit_offset = 7, v = stbi__get8(s);
|
5268
|
+
for (i=0; i < (int) s->img_x; ++i) {
|
5269
|
+
int color = (v>>bit_offset)&0x1;
|
5270
|
+
out[z++] = pal[color][0];
|
5271
|
+
out[z++] = pal[color][1];
|
5272
|
+
out[z++] = pal[color][2];
|
5273
|
+
if (target == 4) out[z++] = 255;
|
5274
|
+
if (i+1 == (int) s->img_x) break;
|
5275
|
+
if((--bit_offset) < 0) {
|
5276
|
+
bit_offset = 7;
|
5277
|
+
v = stbi__get8(s);
|
5278
|
+
}
|
4718
5279
|
}
|
4719
|
-
|
4720
|
-
|
4721
|
-
|
4722
|
-
|
4723
|
-
|
4724
|
-
|
4725
|
-
|
4726
|
-
|
4727
|
-
|
4728
|
-
|
5280
|
+
stbi__skip(s, pad);
|
5281
|
+
}
|
5282
|
+
} else {
|
5283
|
+
for (j=0; j < (int) s->img_y; ++j) {
|
5284
|
+
for (i=0; i < (int) s->img_x; i += 2) {
|
5285
|
+
int v=stbi__get8(s),v2=0;
|
5286
|
+
if (info.bpp == 4) {
|
5287
|
+
v2 = v & 15;
|
5288
|
+
v >>= 4;
|
5289
|
+
}
|
5290
|
+
out[z++] = pal[v][0];
|
5291
|
+
out[z++] = pal[v][1];
|
5292
|
+
out[z++] = pal[v][2];
|
5293
|
+
if (target == 4) out[z++] = 255;
|
5294
|
+
if (i+1 == (int) s->img_x) break;
|
5295
|
+
v = (info.bpp == 8) ? stbi__get8(s) : v2;
|
5296
|
+
out[z++] = pal[v][0];
|
5297
|
+
out[z++] = pal[v][1];
|
5298
|
+
out[z++] = pal[v][2];
|
5299
|
+
if (target == 4) out[z++] = 255;
|
5300
|
+
}
|
5301
|
+
stbi__skip(s, pad);
|
4729
5302
|
}
|
4730
|
-
stbi__skip(s, pad);
|
4731
5303
|
}
|
4732
5304
|
} else {
|
4733
5305
|
int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
|
4734
5306
|
int z = 0;
|
4735
5307
|
int easy=0;
|
4736
|
-
stbi__skip(s, offset - 14 - hsz);
|
4737
|
-
if (bpp == 24) width = 3 * s->img_x;
|
4738
|
-
else if (bpp == 16) width = 2*s->img_x;
|
5308
|
+
stbi__skip(s, info.offset - 14 - info.hsz);
|
5309
|
+
if (info.bpp == 24) width = 3 * s->img_x;
|
5310
|
+
else if (info.bpp == 16) width = 2*s->img_x;
|
4739
5311
|
else /* bpp = 32 and pad = 0 */ width=0;
|
4740
5312
|
pad = (-width) & 3;
|
4741
|
-
if (bpp == 24) {
|
5313
|
+
if (info.bpp == 24) {
|
4742
5314
|
easy = 1;
|
4743
|
-
} else if (bpp == 32) {
|
5315
|
+
} else if (info.bpp == 32) {
|
4744
5316
|
if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
|
4745
5317
|
easy = 2;
|
4746
5318
|
}
|
@@ -4765,9 +5337,10 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4765
5337
|
if (target == 4) out[z++] = a;
|
4766
5338
|
}
|
4767
5339
|
} else {
|
5340
|
+
int bpp = info.bpp;
|
4768
5341
|
for (i=0; i < (int) s->img_x; ++i) {
|
4769
5342
|
stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
|
4770
|
-
int a;
|
5343
|
+
unsigned int a;
|
4771
5344
|
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
|
4772
5345
|
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
|
4773
5346
|
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount));
|
@@ -4779,7 +5352,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4779
5352
|
stbi__skip(s, pad);
|
4780
5353
|
}
|
4781
5354
|
}
|
4782
|
-
|
5355
|
+
|
4783
5356
|
// if alpha channel is all 0s, replace with all 255s
|
4784
5357
|
if (target == 4 && all_a == 0)
|
4785
5358
|
for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
|
@@ -4791,7 +5364,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4791
5364
|
stbi_uc *p1 = out + j *s->img_x*target;
|
4792
5365
|
stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
|
4793
5366
|
for (i=0; i < (int) s->img_x*target; ++i) {
|
4794
|
-
t = p1[i]
|
5367
|
+
t = p1[i]; p1[i] = p2[i]; p2[i] = t;
|
4795
5368
|
}
|
4796
5369
|
}
|
4797
5370
|
}
|
@@ -4811,20 +5384,55 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4811
5384
|
// Targa Truevision - TGA
|
4812
5385
|
// by Jonathan Dummer
|
4813
5386
|
#ifndef STBI_NO_TGA
|
5387
|
+
// returns STBI_rgb or whatever, 0 on error
|
5388
|
+
static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
|
5389
|
+
{
|
5390
|
+
// only RGB or RGBA (incl. 16bit) or grey allowed
|
5391
|
+
if (is_rgb16) *is_rgb16 = 0;
|
5392
|
+
switch(bits_per_pixel) {
|
5393
|
+
case 8: return STBI_grey;
|
5394
|
+
case 16: if(is_grey) return STBI_grey_alpha;
|
5395
|
+
// fallthrough
|
5396
|
+
case 15: if(is_rgb16) *is_rgb16 = 1;
|
5397
|
+
return STBI_rgb;
|
5398
|
+
case 24: // fallthrough
|
5399
|
+
case 32: return bits_per_pixel/8;
|
5400
|
+
default: return 0;
|
5401
|
+
}
|
5402
|
+
}
|
5403
|
+
|
4814
5404
|
static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
|
4815
5405
|
{
|
4816
|
-
int tga_w, tga_h, tga_comp;
|
4817
|
-
int sz;
|
5406
|
+
int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
|
5407
|
+
int sz, tga_colormap_type;
|
4818
5408
|
stbi__get8(s); // discard Offset
|
4819
|
-
|
4820
|
-
if(
|
5409
|
+
tga_colormap_type = stbi__get8(s); // colormap type
|
5410
|
+
if( tga_colormap_type > 1 ) {
|
4821
5411
|
stbi__rewind(s);
|
4822
5412
|
return 0; // only RGB or indexed allowed
|
4823
5413
|
}
|
4824
|
-
|
4825
|
-
|
4826
|
-
|
4827
|
-
|
5414
|
+
tga_image_type = stbi__get8(s); // image type
|
5415
|
+
if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
|
5416
|
+
if (tga_image_type != 1 && tga_image_type != 9) {
|
5417
|
+
stbi__rewind(s);
|
5418
|
+
return 0;
|
5419
|
+
}
|
5420
|
+
stbi__skip(s,4); // skip index of first colormap entry and number of entries
|
5421
|
+
sz = stbi__get8(s); // check bits per palette color entry
|
5422
|
+
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) {
|
5423
|
+
stbi__rewind(s);
|
5424
|
+
return 0;
|
5425
|
+
}
|
5426
|
+
stbi__skip(s,4); // skip image x and y origin
|
5427
|
+
tga_colormap_bpp = sz;
|
5428
|
+
} else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
|
5429
|
+
if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) {
|
5430
|
+
stbi__rewind(s);
|
5431
|
+
return 0; // only RGB or grey allowed, +/- RLE
|
5432
|
+
}
|
5433
|
+
stbi__skip(s,9); // skip colormap specification and image x/y origin
|
5434
|
+
tga_colormap_bpp = 0;
|
5435
|
+
}
|
4828
5436
|
tga_w = stbi__get16le(s);
|
4829
5437
|
if( tga_w < 1 ) {
|
4830
5438
|
stbi__rewind(s);
|
@@ -4835,45 +5443,81 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
|
|
4835
5443
|
stbi__rewind(s);
|
4836
5444
|
return 0; // test height
|
4837
5445
|
}
|
4838
|
-
|
4839
|
-
//
|
4840
|
-
if (
|
4841
|
-
|
4842
|
-
|
5446
|
+
tga_bits_per_pixel = stbi__get8(s); // bits per pixel
|
5447
|
+
stbi__get8(s); // ignore alpha bits
|
5448
|
+
if (tga_colormap_bpp != 0) {
|
5449
|
+
if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
|
5450
|
+
// when using a colormap, tga_bits_per_pixel is the size of the indexes
|
5451
|
+
// I don't think anything but 8 or 16bit indexes makes sense
|
5452
|
+
stbi__rewind(s);
|
5453
|
+
return 0;
|
5454
|
+
}
|
5455
|
+
tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
|
5456
|
+
} else {
|
5457
|
+
tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
|
5458
|
+
}
|
5459
|
+
if(!tga_comp) {
|
5460
|
+
stbi__rewind(s);
|
5461
|
+
return 0;
|
4843
5462
|
}
|
4844
|
-
tga_comp = sz;
|
4845
5463
|
if (x) *x = tga_w;
|
4846
5464
|
if (y) *y = tga_h;
|
4847
|
-
if (comp) *comp = tga_comp
|
5465
|
+
if (comp) *comp = tga_comp;
|
4848
5466
|
return 1; // seems to have passed everything
|
4849
5467
|
}
|
4850
5468
|
|
4851
5469
|
static int stbi__tga_test(stbi__context *s)
|
4852
5470
|
{
|
4853
|
-
int res;
|
4854
|
-
int sz;
|
5471
|
+
int res = 0;
|
5472
|
+
int sz, tga_color_type;
|
4855
5473
|
stbi__get8(s); // discard Offset
|
4856
|
-
|
4857
|
-
if (
|
5474
|
+
tga_color_type = stbi__get8(s); // color type
|
5475
|
+
if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed
|
4858
5476
|
sz = stbi__get8(s); // image type
|
4859
|
-
if (
|
4860
|
-
|
4861
|
-
|
4862
|
-
|
4863
|
-
|
4864
|
-
|
4865
|
-
|
4866
|
-
|
5477
|
+
if ( tga_color_type == 1 ) { // colormapped (paletted) image
|
5478
|
+
if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
|
5479
|
+
stbi__skip(s,4); // skip index of first colormap entry and number of entries
|
5480
|
+
sz = stbi__get8(s); // check bits per palette color entry
|
5481
|
+
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
|
5482
|
+
stbi__skip(s,4); // skip image x and y origin
|
5483
|
+
} else { // "normal" image w/o colormap
|
5484
|
+
if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE
|
5485
|
+
stbi__skip(s,9); // skip colormap specification and image x/y origin
|
5486
|
+
}
|
5487
|
+
if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width
|
5488
|
+
if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height
|
4867
5489
|
sz = stbi__get8(s); // bits per pixel
|
4868
|
-
if ( (
|
4869
|
-
|
4870
|
-
|
4871
|
-
|
5490
|
+
if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
|
5491
|
+
if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
|
5492
|
+
|
5493
|
+
res = 1; // if we got this far, everything's good and we can return 1 instead of 0
|
5494
|
+
|
5495
|
+
errorEnd:
|
4872
5496
|
stbi__rewind(s);
|
4873
5497
|
return res;
|
4874
5498
|
}
|
4875
5499
|
|
4876
|
-
|
5500
|
+
// read 16bit value and convert to 24bit RGB
|
5501
|
+
static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
|
5502
|
+
{
|
5503
|
+
stbi__uint16 px = (stbi__uint16)stbi__get16le(s);
|
5504
|
+
stbi__uint16 fiveBitMask = 31;
|
5505
|
+
// we have 3 channels with 5bits each
|
5506
|
+
int r = (px >> 10) & fiveBitMask;
|
5507
|
+
int g = (px >> 5) & fiveBitMask;
|
5508
|
+
int b = px & fiveBitMask;
|
5509
|
+
// Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
|
5510
|
+
out[0] = (stbi_uc)((r * 255)/31);
|
5511
|
+
out[1] = (stbi_uc)((g * 255)/31);
|
5512
|
+
out[2] = (stbi_uc)((b * 255)/31);
|
5513
|
+
|
5514
|
+
// some people claim that the most significant bit might be used for alpha
|
5515
|
+
// (possibly if an alpha-bit is set in the "image descriptor byte")
|
5516
|
+
// but that only made 16bit test images completely translucent..
|
5517
|
+
// so let's treat all 15 and 16bit TGAs as RGB with no alpha.
|
5518
|
+
}
|
5519
|
+
|
5520
|
+
static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
4877
5521
|
{
|
4878
5522
|
// read in the TGA header stuff
|
4879
5523
|
int tga_offset = stbi__get8(s);
|
@@ -4888,16 +5532,18 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4888
5532
|
int tga_width = stbi__get16le(s);
|
4889
5533
|
int tga_height = stbi__get16le(s);
|
4890
5534
|
int tga_bits_per_pixel = stbi__get8(s);
|
4891
|
-
int tga_comp =
|
5535
|
+
int tga_comp, tga_rgb16=0;
|
4892
5536
|
int tga_inverted = stbi__get8(s);
|
5537
|
+
// int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
|
4893
5538
|
// image data
|
4894
5539
|
unsigned char *tga_data;
|
4895
5540
|
unsigned char *tga_palette = NULL;
|
4896
5541
|
int i, j;
|
4897
|
-
unsigned char raw_data[4];
|
5542
|
+
unsigned char raw_data[4] = {0};
|
4898
5543
|
int RLE_count = 0;
|
4899
5544
|
int RLE_repeating = 0;
|
4900
5545
|
int read_next_pixel = 1;
|
5546
|
+
STBI_NOTUSED(ri);
|
4901
5547
|
|
4902
5548
|
// do a tiny bit of precessing
|
4903
5549
|
if ( tga_image_type >= 8 )
|
@@ -4905,38 +5551,30 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4905
5551
|
tga_image_type -= 8;
|
4906
5552
|
tga_is_RLE = 1;
|
4907
5553
|
}
|
4908
|
-
/* int tga_alpha_bits = tga_inverted & 15; */
|
4909
5554
|
tga_inverted = 1 - ((tga_inverted >> 5) & 1);
|
4910
5555
|
|
4911
|
-
// error check
|
4912
|
-
if ( //(tga_indexed) ||
|
4913
|
-
(tga_width < 1) || (tga_height < 1) ||
|
4914
|
-
(tga_image_type < 1) || (tga_image_type > 3) ||
|
4915
|
-
((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) &&
|
4916
|
-
(tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32))
|
4917
|
-
)
|
4918
|
-
{
|
4919
|
-
return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA
|
4920
|
-
}
|
4921
|
-
|
4922
5556
|
// If I'm paletted, then I'll use the number of bits from the palette
|
4923
|
-
if ( tga_indexed )
|
4924
|
-
|
4925
|
-
|
4926
|
-
|
5557
|
+
if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
|
5558
|
+
else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
|
5559
|
+
|
5560
|
+
if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
|
5561
|
+
return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
|
4927
5562
|
|
4928
5563
|
// tga info
|
4929
5564
|
*x = tga_width;
|
4930
5565
|
*y = tga_height;
|
4931
5566
|
if (comp) *comp = tga_comp;
|
4932
5567
|
|
4933
|
-
|
5568
|
+
if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0))
|
5569
|
+
return stbi__errpuc("too large", "Corrupt TGA");
|
5570
|
+
|
5571
|
+
tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
|
4934
5572
|
if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
|
4935
5573
|
|
4936
5574
|
// skip to the data's starting position (offset usually = 0)
|
4937
5575
|
stbi__skip(s, tga_offset );
|
4938
5576
|
|
4939
|
-
if ( !tga_indexed && !tga_is_RLE) {
|
5577
|
+
if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) {
|
4940
5578
|
for (i=0; i < tga_height; ++i) {
|
4941
5579
|
int row = tga_inverted ? tga_height -i - 1 : i;
|
4942
5580
|
stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
|
@@ -4949,15 +5587,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4949
5587
|
// any data to skip? (offset usually = 0)
|
4950
5588
|
stbi__skip(s, tga_palette_start );
|
4951
5589
|
// load the palette
|
4952
|
-
tga_palette = (unsigned char*)
|
5590
|
+
tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);
|
4953
5591
|
if (!tga_palette) {
|
4954
5592
|
STBI_FREE(tga_data);
|
4955
5593
|
return stbi__errpuc("outofmem", "Out of memory");
|
4956
5594
|
}
|
4957
|
-
if (
|
4958
|
-
|
4959
|
-
|
4960
|
-
|
5595
|
+
if (tga_rgb16) {
|
5596
|
+
stbi_uc *pal_entry = tga_palette;
|
5597
|
+
STBI_ASSERT(tga_comp == STBI_rgb);
|
5598
|
+
for (i=0; i < tga_palette_len; ++i) {
|
5599
|
+
stbi__tga_read_rgb16(s, pal_entry);
|
5600
|
+
pal_entry += tga_comp;
|
5601
|
+
}
|
5602
|
+
} else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
|
5603
|
+
STBI_FREE(tga_data);
|
5604
|
+
STBI_FREE(tga_palette);
|
5605
|
+
return stbi__errpuc("bad palette", "Corrupt TGA");
|
4961
5606
|
}
|
4962
5607
|
}
|
4963
5608
|
// load the data
|
@@ -4987,23 +5632,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
4987
5632
|
// load however much data we did have
|
4988
5633
|
if ( tga_indexed )
|
4989
5634
|
{
|
4990
|
-
//
|
4991
|
-
int pal_idx = stbi__get8(s);
|
4992
|
-
if ( pal_idx >= tga_palette_len )
|
4993
|
-
|
4994
|
-
// invalid index
|
5635
|
+
// read in index, then perform the lookup
|
5636
|
+
int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
|
5637
|
+
if ( pal_idx >= tga_palette_len ) {
|
5638
|
+
// invalid index
|
4995
5639
|
pal_idx = 0;
|
4996
5640
|
}
|
4997
|
-
pal_idx *=
|
4998
|
-
for (j = 0; j
|
4999
|
-
{
|
5641
|
+
pal_idx *= tga_comp;
|
5642
|
+
for (j = 0; j < tga_comp; ++j) {
|
5000
5643
|
raw_data[j] = tga_palette[pal_idx+j];
|
5001
5644
|
}
|
5002
|
-
} else
|
5003
|
-
|
5645
|
+
} else if(tga_rgb16) {
|
5646
|
+
STBI_ASSERT(tga_comp == STBI_rgb);
|
5647
|
+
stbi__tga_read_rgb16(s, raw_data);
|
5648
|
+
} else {
|
5004
5649
|
// read in the data raw
|
5005
|
-
for (j = 0; j
|
5006
|
-
{
|
5650
|
+
for (j = 0; j < tga_comp; ++j) {
|
5007
5651
|
raw_data[j] = stbi__get8(s);
|
5008
5652
|
}
|
5009
5653
|
}
|
@@ -5042,8 +5686,8 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5042
5686
|
}
|
5043
5687
|
}
|
5044
5688
|
|
5045
|
-
// swap RGB
|
5046
|
-
if (tga_comp >= 3)
|
5689
|
+
// swap RGB - if the source data was RGB16, it already is in the right order
|
5690
|
+
if (tga_comp >= 3 && !tga_rgb16)
|
5047
5691
|
{
|
5048
5692
|
unsigned char* tga_pixel = tga_data;
|
5049
5693
|
for (i=0; i < tga_width * tga_height; ++i)
|
@@ -5079,14 +5723,53 @@ static int stbi__psd_test(stbi__context *s)
|
|
5079
5723
|
return r;
|
5080
5724
|
}
|
5081
5725
|
|
5082
|
-
static
|
5726
|
+
static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount)
|
5083
5727
|
{
|
5084
|
-
int
|
5728
|
+
int count, nleft, len;
|
5729
|
+
|
5730
|
+
count = 0;
|
5731
|
+
while ((nleft = pixelCount - count) > 0) {
|
5732
|
+
len = stbi__get8(s);
|
5733
|
+
if (len == 128) {
|
5734
|
+
// No-op.
|
5735
|
+
} else if (len < 128) {
|
5736
|
+
// Copy next len+1 bytes literally.
|
5737
|
+
len++;
|
5738
|
+
if (len > nleft) return 0; // corrupt data
|
5739
|
+
count += len;
|
5740
|
+
while (len) {
|
5741
|
+
*p = stbi__get8(s);
|
5742
|
+
p += 4;
|
5743
|
+
len--;
|
5744
|
+
}
|
5745
|
+
} else if (len > 128) {
|
5746
|
+
stbi_uc val;
|
5747
|
+
// Next -len+1 bytes in the dest are replicated from next source byte.
|
5748
|
+
// (Interpret len as a negative 8-bit int.)
|
5749
|
+
len = 257 - len;
|
5750
|
+
if (len > nleft) return 0; // corrupt data
|
5751
|
+
val = stbi__get8(s);
|
5752
|
+
count += len;
|
5753
|
+
while (len) {
|
5754
|
+
*p = val;
|
5755
|
+
p += 4;
|
5756
|
+
len--;
|
5757
|
+
}
|
5758
|
+
}
|
5759
|
+
}
|
5760
|
+
|
5761
|
+
return 1;
|
5762
|
+
}
|
5763
|
+
|
5764
|
+
static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
|
5765
|
+
{
|
5766
|
+
int pixelCount;
|
5085
5767
|
int channelCount, compression;
|
5086
|
-
int channel, i
|
5768
|
+
int channel, i;
|
5087
5769
|
int bitdepth;
|
5088
5770
|
int w,h;
|
5089
5771
|
stbi_uc *out;
|
5772
|
+
STBI_NOTUSED(ri);
|
5090
5773
|
|
5091
5774
|
// Check identifier
|
5092
5775
|
if (stbi__get32be(s) != 0x38425053) // "8BPS"
|
@@ -5143,8 +5826,18 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5143
5826
|
if (compression > 1)
|
5144
5827
|
return stbi__errpuc("bad compression", "PSD has an unknown compression format");
|
5145
5828
|
|
5829
|
+
// Check size
|
5830
|
+
if (!stbi__mad3sizes_valid(4, w, h, 0))
|
5831
|
+
return stbi__errpuc("too large", "Corrupt PSD");
|
5832
|
+
|
5146
5833
|
// Create the destination image.
|
5147
|
-
|
5834
|
+
|
5835
|
+
if (!compression && bitdepth == 16 && bpc == 16) {
|
5836
|
+
out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0);
|
5837
|
+
ri->bits_per_channel = 16;
|
5838
|
+
} else
|
5839
|
+
out = (stbi_uc *) stbi__malloc(4 * w*h);
|
5840
|
+
|
5148
5841
|
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
5149
5842
|
pixelCount = w*h;
|
5150
5843
|
|
@@ -5161,7 +5854,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5161
5854
|
// Else if n is 128, noop.
|
5162
5855
|
// Endloop
|
5163
5856
|
|
5164
|
-
// The RLE-compressed data is
|
5857
|
+
// The RLE-compressed data is preceded by a 2-byte data count for each row in the data,
|
5165
5858
|
// which we're going to just skip.
|
5166
5859
|
stbi__skip(s, h * channelCount * 2 );
|
5167
5860
|
|
@@ -5176,67 +5869,86 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
|
5176
5869
|
*p = (channel == 3 ? 255 : 0);
|
5177
5870
|
} else {
|
5178
5871
|
// Read the RLE data.
|
5179
|
-
|
5180
|
-
|
5181
|
-
|
5182
|
-
if (len == 128) {
|
5183
|
-
// No-op.
|
5184
|
-
} else if (len < 128) {
|
5185
|
-
// Copy next len+1 bytes literally.
|
5186
|
-
len++;
|
5187
|
-
count += len;
|
5188
|
-
while (len) {
|
5189
|
-
*p = stbi__get8(s);
|
5190
|
-
p += 4;
|
5191
|
-
len--;
|
5192
|
-
}
|
5193
|
-
} else if (len > 128) {
|
5194
|
-
stbi_uc val;
|
5195
|
-
// Next -len+1 bytes in the dest are replicated from next source byte.
|
5196
|
-
// (Interpret len as a negative 8-bit int.)
|
5197
|
-
len ^= 0x0FF;
|
5198
|
-
len += 2;
|
5199
|
-
val = stbi__get8(s);
|
5200
|
-
count += len;
|
5201
|
-
while (len) {
|
5202
|
-
*p = val;
|
5203
|
-
p += 4;
|
5204
|
-
len--;
|
5205
|
-
}
|
5206
|
-
}
|
5872
|
+
if (!stbi__psd_decode_rle(s, p, pixelCount)) {
|
5873
|
+
STBI_FREE(out);
|
5874
|
+
return stbi__errpuc("corrupt", "bad RLE data");
|
5207
5875
|
}
|
5208
5876
|
}
|
5209
5877
|
}
|
5210
5878
|
|
5211
5879
|
} else {
|
5212
5880
|
// We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
|
5213
|
-
// where each channel consists of an 8-bit value for each pixel in the image.
|
5881
|
+
// where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image.
|
5214
5882
|
|
5215
5883
|
// Read the data by channel.
|
5216
5884
|
for (channel = 0; channel < 4; channel++) {
|
5217
|
-
stbi_uc *p;
|
5218
|
-
|
5219
|
-
p = out + channel;
|
5220
5885
|
if (channel >= channelCount) {
|
5221
5886
|
// Fill this channel with default data.
|
5222
|
-
|
5223
|
-
|
5224
|
-
|
5225
|
-
|
5226
|
-
|
5227
|
-
if (bitdepth == 16) {
|
5228
|
-
for (i = 0; i < pixelCount; i++, p += 4)
|
5229
|
-
*p = (stbi_uc) (stbi__get16be(s) >> 8);
|
5887
|
+
if (bitdepth == 16 && bpc == 16) {
|
5888
|
+
stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
|
5889
|
+
stbi__uint16 val = channel == 3 ? 65535 : 0;
|
5890
|
+
for (i = 0; i < pixelCount; i++, q += 4)
|
5891
|
+
*q = val;
|
5230
5892
|
} else {
|
5893
|
+
stbi_uc *p = out+channel;
|
5894
|
+
stbi_uc val = channel == 3 ? 255 : 0;
|
5231
5895
|
for (i = 0; i < pixelCount; i++, p += 4)
|
5232
|
-
*p =
|
5896
|
+
*p = val;
|
5897
|
+
}
|
5898
|
+
} else {
|
5899
|
+
if (ri->bits_per_channel == 16) { // output bpc
|
5900
|
+
stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
|
5901
|
+
for (i = 0; i < pixelCount; i++, q += 4)
|
5902
|
+
*q = (stbi__uint16) stbi__get16be(s);
|
5903
|
+
} else {
|
5904
|
+
stbi_uc *p = out+channel;
|
5905
|
+
if (bitdepth == 16) { // input bpc
|
5906
|
+
for (i = 0; i < pixelCount; i++, p += 4)
|
5907
|
+
*p = (stbi_uc) (stbi__get16be(s) >> 8);
|
5908
|
+
} else {
|
5909
|
+
for (i = 0; i < pixelCount; i++, p += 4)
|
5910
|
+
*p = stbi__get8(s);
|
5911
|
+
}
|
5912
|
+
}
|
5913
|
+
}
|
5914
|
+
}
|
5915
|
+
}
|
5916
|
+
|
5917
|
+
// remove weird white matte from PSD
|
5918
|
+
if (channelCount >= 4) {
|
5919
|
+
if (ri->bits_per_channel == 16) {
|
5920
|
+
for (i=0; i < w*h; ++i) {
|
5921
|
+
stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i;
|
5922
|
+
if (pixel[3] != 0 && pixel[3] != 65535) {
|
5923
|
+
float a = pixel[3] / 65535.0f;
|
5924
|
+
float ra = 1.0f / a;
|
5925
|
+
float inv_a = 65535.0f * (1 - ra);
|
5926
|
+
pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a);
|
5927
|
+
pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a);
|
5928
|
+
pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a);
|
5929
|
+
}
|
5930
|
+
}
|
5931
|
+
} else {
|
5932
|
+
for (i=0; i < w*h; ++i) {
|
5933
|
+
unsigned char *pixel = out + 4*i;
|
5934
|
+
if (pixel[3] != 0 && pixel[3] != 255) {
|
5935
|
+
float a = pixel[3] / 255.0f;
|
5936
|
+
float ra = 1.0f / a;
|
5937
|
+
float inv_a = 255.0f * (1 - ra);
|
5938
|
+
pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
|
5939
|
+
pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
|
5940
|
+
pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
|
5233
5941
|
}
|
5234
5942
|
}
|
5235
5943
|
}
|
5236
5944
|
}
|
5237
5945
|
|
5946
|
+
// convert to desired output format
|
5238
5947
|
if (req_comp && req_comp != 4) {
|
5239
|
-
|
5948
|
+
if (ri->bits_per_channel == 16)
|
5949
|
+
out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h);
|
5950
|
+
else
|
5951
|
+
out = stbi__convert_format(out, 4, req_comp, w, h);
|
5240
5952
|
if (out == NULL) return out; // stbi__convert_format frees input on failure
|
5241
5953
|
}
|
5242
5954
|
|
@@ -5420,10 +6132,13 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c
|
|
5420
6132
|
return result;
|
5421
6133
|
}
|
5422
6134
|
|
5423
|
-
static
|
6135
|
+
static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri)
|
5424
6136
|
{
|
5425
6137
|
stbi_uc *result;
|
5426
|
-
int i, x,y;
|
6138
|
+
int i, x,y, internal_comp;
|
6139
|
+
STBI_NOTUSED(ri);
|
6140
|
+
|
6141
|
+
if (!comp) comp = &internal_comp;
|
5427
6142
|
|
5428
6143
|
for (i=0; i<92; ++i)
|
5429
6144
|
stbi__get8(s);
|
@@ -5431,14 +6146,14 @@ static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int re
|
|
5431
6146
|
x = stbi__get16be(s);
|
5432
6147
|
y = stbi__get16be(s);
|
5433
6148
|
if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
|
5434
|
-
if ((
|
6149
|
+
if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
|
5435
6150
|
|
5436
6151
|
stbi__get32be(s); //skip `ratio'
|
5437
6152
|
stbi__get16be(s); //skip `fields'
|
5438
6153
|
stbi__get16be(s); //skip `pad'
|
5439
6154
|
|
5440
6155
|
// intermediate buffer is RGBA
|
5441
|
-
result = (stbi_uc *)
|
6156
|
+
result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0);
|
5442
6157
|
memset(result, 0xff, x*y*4);
|
5443
6158
|
|
5444
6159
|
if (!stbi__pic_load_core(s,x,y,comp, result)) {
|
@@ -5475,11 +6190,13 @@ typedef struct
|
|
5475
6190
|
typedef struct
|
5476
6191
|
{
|
5477
6192
|
int w,h;
|
5478
|
-
stbi_uc *out
|
5479
|
-
|
6193
|
+
stbi_uc *out; // output buffer (always 4 components)
|
6194
|
+
stbi_uc *background; // The current "background" as far as a gif is concerned
|
6195
|
+
stbi_uc *history;
|
6196
|
+
int flags, bgindex, ratio, transparent, eflags;
|
5480
6197
|
stbi_uc pal[256][4];
|
5481
6198
|
stbi_uc lpal[256][4];
|
5482
|
-
stbi__gif_lzw codes[
|
6199
|
+
stbi__gif_lzw codes[8192];
|
5483
6200
|
stbi_uc *color_table;
|
5484
6201
|
int parse, step;
|
5485
6202
|
int lflags;
|
@@ -5487,6 +6204,7 @@ typedef struct
|
|
5487
6204
|
int max_x, max_y;
|
5488
6205
|
int cur_x, cur_y;
|
5489
6206
|
int line_size;
|
6207
|
+
int delay;
|
5490
6208
|
} stbi__gif;
|
5491
6209
|
|
5492
6210
|
static int stbi__gif_test_raw(stbi__context *s)
|
@@ -5547,19 +6265,22 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
|
|
5547
6265
|
|
5548
6266
|
static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
|
5549
6267
|
{
|
5550
|
-
stbi__gif g;
|
5551
|
-
if (!stbi__gif_header(s,
|
6268
|
+
stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
|
6269
|
+
if (!stbi__gif_header(s, g, comp, 1)) {
|
6270
|
+
STBI_FREE(g);
|
5552
6271
|
stbi__rewind( s );
|
5553
6272
|
return 0;
|
5554
6273
|
}
|
5555
|
-
if (x) *x = g
|
5556
|
-
if (y) *y = g
|
6274
|
+
if (x) *x = g->w;
|
6275
|
+
if (y) *y = g->h;
|
6276
|
+
STBI_FREE(g);
|
5557
6277
|
return 1;
|
5558
6278
|
}
|
5559
6279
|
|
5560
6280
|
static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
|
5561
6281
|
{
|
5562
6282
|
stbi_uc *p, *c;
|
6283
|
+
int idx;
|
5563
6284
|
|
5564
6285
|
// recurse to decode the prefixes, since the linked-list is backwards,
|
5565
6286
|
// and working backwards through an interleaved image would be nasty
|
@@ -5568,10 +6289,12 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
|
|
5568
6289
|
|
5569
6290
|
if (g->cur_y >= g->max_y) return;
|
5570
6291
|
|
5571
|
-
|
5572
|
-
|
6292
|
+
idx = g->cur_x + g->cur_y;
|
6293
|
+
p = &g->out[idx];
|
6294
|
+
g->history[idx / 4] = 1;
|
5573
6295
|
|
5574
|
-
|
6296
|
+
c = &g->color_table[g->codes[code].suffix * 4];
|
6297
|
+
if (c[3] > 128) { // don't render transparent pixels;
|
5575
6298
|
p[0] = c[2];
|
5576
6299
|
p[1] = c[1];
|
5577
6300
|
p[2] = c[0];
|
@@ -5645,11 +6368,16 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
|
|
5645
6368
|
stbi__skip(s,len);
|
5646
6369
|
return g->out;
|
5647
6370
|
} else if (code <= avail) {
|
5648
|
-
if (first)
|
6371
|
+
if (first) {
|
6372
|
+
return stbi__errpuc("no clear code", "Corrupt GIF");
|
6373
|
+
}
|
5649
6374
|
|
5650
6375
|
if (oldcode >= 0) {
|
5651
6376
|
p = &g->codes[avail++];
|
5652
|
-
if (avail >
|
6377
|
+
if (avail > 8192) {
|
6378
|
+
return stbi__errpuc("too many codes", "Corrupt GIF");
|
6379
|
+
}
|
6380
|
+
|
5653
6381
|
p->prefix = (stbi__int16) oldcode;
|
5654
6382
|
p->first = g->codes[oldcode].first;
|
5655
6383
|
p->suffix = (code == avail) ? p->first : g->codes[code].first;
|
@@ -5671,59 +6399,73 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
|
|
5671
6399
|
}
|
5672
6400
|
}
|
5673
6401
|
|
5674
|
-
static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1)
|
5675
|
-
{
|
5676
|
-
int x, y;
|
5677
|
-
stbi_uc *c = g->pal[g->bgindex];
|
5678
|
-
for (y = y0; y < y1; y += 4 * g->w) {
|
5679
|
-
for (x = x0; x < x1; x += 4) {
|
5680
|
-
stbi_uc *p = &g->out[y + x];
|
5681
|
-
p[0] = c[2];
|
5682
|
-
p[1] = c[1];
|
5683
|
-
p[2] = c[0];
|
5684
|
-
p[3] = 0;
|
5685
|
-
}
|
5686
|
-
}
|
5687
|
-
}
|
5688
|
-
|
5689
6402
|
// this function is designed to support animated gifs, although stb_image doesn't support it
|
5690
|
-
|
6403
|
+
// two back is the image from two frames ago, used for a very specific disposal format
|
6404
|
+
static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back)
|
5691
6405
|
{
|
5692
|
-
int
|
5693
|
-
|
6406
|
+
int dispose;
|
6407
|
+
int first_frame;
|
6408
|
+
int pi;
|
6409
|
+
int pcount;
|
6410
|
+
STBI_NOTUSED(req_comp);
|
5694
6411
|
|
5695
|
-
|
5696
|
-
|
6412
|
+
// on first frame, any non-written pixels get the background colour (non-transparent)
|
6413
|
+
first_frame = 0;
|
6414
|
+
if (g->out == 0) {
|
6415
|
+
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
|
6416
|
+
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
|
6417
|
+
g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
|
6418
|
+
g->history = (stbi_uc *) stbi__malloc(g->w * g->h);
|
6419
|
+
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
|
6420
|
+
|
6421
|
+
// image is treated as "transparent" at the start - ie, nothing overwrites the current background;
|
6422
|
+
// background colour is only used for pixels that are not rendered first frame, after that "background"
|
6423
|
+
// color refers to the color that was there the previous frame.
|
6424
|
+
memset( g->out, 0x00, 4 * g->w * g->h );
|
6425
|
+
memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent)
|
6426
|
+
memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame
|
6427
|
+
first_frame = 1;
|
6428
|
+
} else {
|
6429
|
+
// second frame - how do we dispoase of the previous one?
|
6430
|
+
dispose = (g->eflags & 0x1C) >> 2;
|
6431
|
+
pcount = g->w * g->h;
|
5697
6432
|
|
5698
|
-
|
5699
|
-
|
5700
|
-
|
6433
|
+
if ((dispose == 3) && (two_back == 0)) {
|
6434
|
+
dispose = 2; // if I don't have an image to revert back to, default to the old background
|
6435
|
+
}
|
5701
6436
|
|
5702
|
-
|
5703
|
-
|
5704
|
-
|
5705
|
-
|
5706
|
-
|
5707
|
-
if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h);
|
5708
|
-
g->old_out = prev_out;
|
5709
|
-
break;
|
5710
|
-
case 2: // dispose to background
|
5711
|
-
if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h);
|
5712
|
-
stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y);
|
5713
|
-
break;
|
5714
|
-
case 3: // dispose to previous
|
5715
|
-
if (g->old_out) {
|
5716
|
-
for (i = g->start_y; i < g->max_y; i += 4 * g->w)
|
5717
|
-
memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x);
|
6437
|
+
if (dispose == 3) { // use previous graphic
|
6438
|
+
for (pi = 0; pi < pcount; ++pi) {
|
6439
|
+
if (g->history[pi]) {
|
6440
|
+
memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 );
|
6441
|
+
}
|
5718
6442
|
}
|
5719
|
-
|
6443
|
+
} else if (dispose == 2) {
|
6444
|
+
// restore what was changed last frame to background before that frame;
|
6445
|
+
for (pi = 0; pi < pcount; ++pi) {
|
6446
|
+
if (g->history[pi]) {
|
6447
|
+
memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 );
|
6448
|
+
}
|
6449
|
+
}
|
6450
|
+
} else {
|
6451
|
+
// This is a non-disposal case eithe way, so just
|
6452
|
+
// leave the pixels as is, and they will become the new background
|
6453
|
+
// 1: do not dispose
|
6454
|
+
// 0: not specified.
|
6455
|
+
}
|
6456
|
+
|
6457
|
+
// background is what out is after the undoing of the previou frame;
|
6458
|
+
memcpy( g->background, g->out, 4 * g->w * g->h );
|
5720
6459
|
}
|
5721
6460
|
|
6461
|
+
// clear my history;
|
6462
|
+
memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame
|
6463
|
+
|
5722
6464
|
for (;;) {
|
5723
|
-
|
6465
|
+
int tag = stbi__get8(s);
|
6466
|
+
switch (tag) {
|
5724
6467
|
case 0x2C: /* Image Descriptor */
|
5725
6468
|
{
|
5726
|
-
int prev_trans = -1;
|
5727
6469
|
stbi__int32 x, y, w, h;
|
5728
6470
|
stbi_uc *o;
|
5729
6471
|
|
@@ -5756,19 +6498,24 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|
5756
6498
|
stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1);
|
5757
6499
|
g->color_table = (stbi_uc *) g->lpal;
|
5758
6500
|
} else if (g->flags & 0x80) {
|
5759
|
-
if (g->transparent >= 0 && (g->eflags & 0x01)) {
|
5760
|
-
prev_trans = g->pal[g->transparent][3];
|
5761
|
-
g->pal[g->transparent][3] = 0;
|
5762
|
-
}
|
5763
6501
|
g->color_table = (stbi_uc *) g->pal;
|
5764
6502
|
} else
|
5765
|
-
return stbi__errpuc("missing color table", "Corrupt GIF");
|
5766
|
-
|
6503
|
+
return stbi__errpuc("missing color table", "Corrupt GIF");
|
6504
|
+
|
5767
6505
|
o = stbi__process_gif_raster(s, g);
|
5768
6506
|
if (o == NULL) return NULL;
|
5769
6507
|
|
5770
|
-
if
|
5771
|
-
|
6508
|
+
// if this was the first frame,
|
6509
|
+
pcount = g->w * g->h;
|
6510
|
+
if (first_frame && (g->bgindex > 0)) {
|
6511
|
+
// if first frame, any pixel not drawn to gets the background color
|
6512
|
+
for (pi = 0; pi < pcount; ++pi) {
|
6513
|
+
if (g->history[pi] == 0) {
|
6514
|
+
g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be;
|
6515
|
+
memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 );
|
6516
|
+
}
|
6517
|
+
}
|
6518
|
+
}
|
5772
6519
|
|
5773
6520
|
return o;
|
5774
6521
|
}
|
@@ -5776,19 +6523,35 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|
5776
6523
|
case 0x21: // Comment Extension.
|
5777
6524
|
{
|
5778
6525
|
int len;
|
5779
|
-
|
6526
|
+
int ext = stbi__get8(s);
|
6527
|
+
if (ext == 0xF9) { // Graphic Control Extension.
|
5780
6528
|
len = stbi__get8(s);
|
5781
6529
|
if (len == 4) {
|
5782
6530
|
g->eflags = stbi__get8(s);
|
5783
|
-
g->delay = stbi__get16le(s);
|
5784
|
-
|
6531
|
+
g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths.
|
6532
|
+
|
6533
|
+
// unset old transparent
|
6534
|
+
if (g->transparent >= 0) {
|
6535
|
+
g->pal[g->transparent][3] = 255;
|
6536
|
+
}
|
6537
|
+
if (g->eflags & 0x01) {
|
6538
|
+
g->transparent = stbi__get8(s);
|
6539
|
+
if (g->transparent >= 0) {
|
6540
|
+
g->pal[g->transparent][3] = 0;
|
6541
|
+
}
|
6542
|
+
} else {
|
6543
|
+
// don't need transparent
|
6544
|
+
stbi__skip(s, 1);
|
6545
|
+
g->transparent = -1;
|
6546
|
+
}
|
5785
6547
|
} else {
|
5786
6548
|
stbi__skip(s, len);
|
5787
6549
|
break;
|
5788
6550
|
}
|
5789
|
-
}
|
5790
|
-
while ((len = stbi__get8(s)) != 0)
|
6551
|
+
}
|
6552
|
+
while ((len = stbi__get8(s)) != 0) {
|
5791
6553
|
stbi__skip(s, len);
|
6554
|
+
}
|
5792
6555
|
break;
|
5793
6556
|
}
|
5794
6557
|
|
@@ -5799,26 +6562,92 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
|
5799
6562
|
return stbi__errpuc("unknown code", "Corrupt GIF");
|
5800
6563
|
}
|
5801
6564
|
}
|
6565
|
+
}
|
5802
6566
|
|
5803
|
-
|
6567
|
+
static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
|
6568
|
+
{
|
6569
|
+
if (stbi__gif_test(s)) {
|
6570
|
+
int layers = 0;
|
6571
|
+
stbi_uc *u = 0;
|
6572
|
+
stbi_uc *out = 0;
|
6573
|
+
stbi_uc *two_back = 0;
|
6574
|
+
stbi__gif g;
|
6575
|
+
int stride;
|
6576
|
+
memset(&g, 0, sizeof(g));
|
6577
|
+
if (delays) {
|
6578
|
+
*delays = 0;
|
6579
|
+
}
|
6580
|
+
|
6581
|
+
do {
|
6582
|
+
u = stbi__gif_load_next(s, &g, comp, req_comp, two_back);
|
6583
|
+
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
|
6584
|
+
|
6585
|
+
if (u) {
|
6586
|
+
*x = g.w;
|
6587
|
+
*y = g.h;
|
6588
|
+
++layers;
|
6589
|
+
stride = g.w * g.h * 4;
|
6590
|
+
|
6591
|
+
if (out) {
|
6592
|
+
out = (stbi_uc*) STBI_REALLOC( out, layers * stride );
|
6593
|
+
if (delays) {
|
6594
|
+
*delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
|
6595
|
+
}
|
6596
|
+
} else {
|
6597
|
+
out = (stbi_uc*)stbi__malloc( layers * stride );
|
6598
|
+
if (delays) {
|
6599
|
+
*delays = (int*) stbi__malloc( layers * sizeof(int) );
|
6600
|
+
}
|
6601
|
+
}
|
6602
|
+
memcpy( out + ((layers - 1) * stride), u, stride );
|
6603
|
+
if (layers >= 2) {
|
6604
|
+
two_back = out - 2 * stride;
|
6605
|
+
}
|
6606
|
+
|
6607
|
+
if (delays) {
|
6608
|
+
(*delays)[layers - 1U] = g.delay;
|
6609
|
+
}
|
6610
|
+
}
|
6611
|
+
} while (u != 0);
|
6612
|
+
|
6613
|
+
// free temp buffer;
|
6614
|
+
STBI_FREE(g.out);
|
6615
|
+
STBI_FREE(g.history);
|
6616
|
+
STBI_FREE(g.background);
|
6617
|
+
|
6618
|
+
// do the final conversion after loading everything;
|
6619
|
+
if (req_comp && req_comp != 4)
|
6620
|
+
out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h);
|
6621
|
+
|
6622
|
+
*z = layers;
|
6623
|
+
return out;
|
6624
|
+
} else {
|
6625
|
+
return stbi__errpuc("not GIF", "Image was not as a gif type.");
|
6626
|
+
}
|
5804
6627
|
}
|
5805
6628
|
|
5806
|
-
static
|
6629
|
+
static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
5807
6630
|
{
|
5808
6631
|
stbi_uc *u = 0;
|
5809
6632
|
stbi__gif g;
|
5810
6633
|
memset(&g, 0, sizeof(g));
|
6634
|
+
STBI_NOTUSED(ri);
|
5811
6635
|
|
5812
|
-
u = stbi__gif_load_next(s, &g, comp, req_comp);
|
6636
|
+
u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
|
5813
6637
|
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
|
5814
6638
|
if (u) {
|
5815
6639
|
*x = g.w;
|
5816
6640
|
*y = g.h;
|
6641
|
+
|
6642
|
+
// moved conversion to after successful load so that the same
|
6643
|
+
// can be done for multiple frames.
|
5817
6644
|
if (req_comp && req_comp != 4)
|
5818
6645
|
u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
|
5819
6646
|
}
|
5820
|
-
|
5821
|
-
|
6647
|
+
|
6648
|
+
// free buffers needed for multiple frame loading;
|
6649
|
+
STBI_FREE(g.history);
|
6650
|
+
STBI_FREE(g.background);
|
5822
6651
|
|
5823
6652
|
return u;
|
5824
6653
|
}
|
@@ -5833,20 +6662,24 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp)
|
|
5833
6662
|
// Radiance RGBE HDR loader
|
5834
6663
|
// originally by Nicolas Schulz
|
5835
6664
|
#ifndef STBI_NO_HDR
|
5836
|
-
static int stbi__hdr_test_core(stbi__context *s)
|
6665
|
+
static int stbi__hdr_test_core(stbi__context *s, const char *signature)
|
5837
6666
|
{
|
5838
|
-
const char *signature = "#?RADIANCE\n";
|
5839
6667
|
int i;
|
5840
6668
|
for (i=0; signature[i]; ++i)
|
5841
6669
|
if (stbi__get8(s) != signature[i])
|
5842
|
-
|
6670
|
+
return 0;
|
6671
|
+
stbi__rewind(s);
|
5843
6672
|
return 1;
|
5844
6673
|
}
|
5845
6674
|
|
5846
6675
|
static int stbi__hdr_test(stbi__context* s)
|
5847
6676
|
{
|
5848
|
-
int r = stbi__hdr_test_core(s);
|
6677
|
+
int r = stbi__hdr_test_core(s, "#?RADIANCE\n");
|
5849
6678
|
stbi__rewind(s);
|
6679
|
+
if(!r) {
|
6680
|
+
r = stbi__hdr_test_core(s, "#?RGBE\n");
|
6681
|
+
stbi__rewind(s);
|
6682
|
+
}
|
5850
6683
|
return r;
|
5851
6684
|
}
|
5852
6685
|
|
@@ -5900,7 +6733,7 @@ static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp)
|
|
5900
6733
|
}
|
5901
6734
|
}
|
5902
6735
|
|
5903
|
-
static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
6736
|
+
static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
5904
6737
|
{
|
5905
6738
|
char buffer[STBI__HDR_BUFLEN];
|
5906
6739
|
char *token;
|
@@ -5911,10 +6744,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|
5911
6744
|
int len;
|
5912
6745
|
unsigned char count, value;
|
5913
6746
|
int i, j, k, c1,c2, z;
|
5914
|
-
|
6747
|
+
const char *headerToken;
|
6748
|
+
STBI_NOTUSED(ri);
|
5915
6749
|
|
5916
6750
|
// Check identifier
|
5917
|
-
|
6751
|
+
headerToken = stbi__hdr_gettoken(s,buffer);
|
6752
|
+
if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0)
|
5918
6753
|
return stbi__errpf("not HDR", "Corrupt HDR image");
|
5919
6754
|
|
5920
6755
|
// Parse header
|
@@ -5943,8 +6778,13 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|
5943
6778
|
if (comp) *comp = 3;
|
5944
6779
|
if (req_comp == 0) req_comp = 3;
|
5945
6780
|
|
6781
|
+
if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0))
|
6782
|
+
return stbi__errpf("too large", "HDR image is too large");
|
6783
|
+
|
5946
6784
|
// Read data
|
5947
|
-
hdr_data = (float *)
|
6785
|
+
hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0);
|
6786
|
+
if (!hdr_data)
|
6787
|
+
return stbi__errpf("outofmem", "Out of memory");
|
5948
6788
|
|
5949
6789
|
// Load image data
|
5950
6790
|
// image data is stored as some number of sca
|
@@ -5983,20 +6823,29 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|
5983
6823
|
len <<= 8;
|
5984
6824
|
len |= stbi__get8(s);
|
5985
6825
|
if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
|
5986
|
-
if (scanline == NULL)
|
6826
|
+
if (scanline == NULL) {
|
6827
|
+
scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0);
|
6828
|
+
if (!scanline) {
|
6829
|
+
STBI_FREE(hdr_data);
|
6830
|
+
return stbi__errpf("outofmem", "Out of memory");
|
6831
|
+
}
|
6832
|
+
}
|
5987
6833
|
|
5988
6834
|
for (k = 0; k < 4; ++k) {
|
6835
|
+
int nleft;
|
5989
6836
|
i = 0;
|
5990
|
-
while (
|
6837
|
+
while ((nleft = width - i) > 0) {
|
5991
6838
|
count = stbi__get8(s);
|
5992
6839
|
if (count > 128) {
|
5993
6840
|
// Run
|
5994
6841
|
value = stbi__get8(s);
|
5995
6842
|
count -= 128;
|
6843
|
+
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
|
5996
6844
|
for (z = 0; z < count; ++z)
|
5997
6845
|
scanline[i++ * 4 + k] = value;
|
5998
6846
|
} else {
|
5999
6847
|
// Dump
|
6848
|
+
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
|
6000
6849
|
for (z = 0; z < count; ++z)
|
6001
6850
|
scanline[i++ * 4 + k] = stbi__get8(s);
|
6002
6851
|
}
|
@@ -6005,7 +6854,8 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|
6005
6854
|
for (i=0; i < width; ++i)
|
6006
6855
|
stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
|
6007
6856
|
}
|
6008
|
-
|
6857
|
+
if (scanline)
|
6858
|
+
STBI_FREE(scanline);
|
6009
6859
|
}
|
6010
6860
|
|
6011
6861
|
return hdr_data;
|
@@ -6016,8 +6866,13 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6016
6866
|
char buffer[STBI__HDR_BUFLEN];
|
6017
6867
|
char *token;
|
6018
6868
|
int valid = 0;
|
6869
|
+
int dummy;
|
6870
|
+
|
6871
|
+
if (!x) x = &dummy;
|
6872
|
+
if (!y) y = &dummy;
|
6873
|
+
if (!comp) comp = &dummy;
|
6019
6874
|
|
6020
|
-
if (
|
6875
|
+
if (stbi__hdr_test(s) == 0) {
|
6021
6876
|
stbi__rewind( s );
|
6022
6877
|
return 0;
|
6023
6878
|
}
|
@@ -6054,29 +6909,17 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6054
6909
|
#ifndef STBI_NO_BMP
|
6055
6910
|
static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
6056
6911
|
{
|
6057
|
-
|
6058
|
-
|
6059
|
-
|
6060
|
-
|
6061
|
-
|
6062
|
-
|
6063
|
-
|
6064
|
-
|
6065
|
-
|
6066
|
-
|
6067
|
-
|
6068
|
-
if (hsz == 12) {
|
6069
|
-
*x = stbi__get16le(s);
|
6070
|
-
*y = stbi__get16le(s);
|
6071
|
-
} else {
|
6072
|
-
*x = stbi__get32le(s);
|
6073
|
-
*y = stbi__get32le(s);
|
6074
|
-
}
|
6075
|
-
if (stbi__get16le(s) != 1) {
|
6076
|
-
stbi__rewind( s );
|
6077
|
-
return 0;
|
6078
|
-
}
|
6079
|
-
*comp = stbi__get16le(s) / 8;
|
6912
|
+
void *p;
|
6913
|
+
stbi__bmp_data info;
|
6914
|
+
|
6915
|
+
info.all_a = 255;
|
6916
|
+
p = stbi__bmp_parse_header(s, &info);
|
6917
|
+
stbi__rewind( s );
|
6918
|
+
if (p == NULL)
|
6919
|
+
return 0;
|
6920
|
+
if (x) *x = s->img_x;
|
6921
|
+
if (y) *y = s->img_y;
|
6922
|
+
if (comp) *comp = info.ma ? 4 : 3;
|
6080
6923
|
return 1;
|
6081
6924
|
}
|
6082
6925
|
#endif
|
@@ -6084,7 +6927,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6084
6927
|
#ifndef STBI_NO_PSD
|
6085
6928
|
static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
|
6086
6929
|
{
|
6087
|
-
int channelCount;
|
6930
|
+
int channelCount, dummy, depth;
|
6931
|
+
if (!x) x = &dummy;
|
6932
|
+
if (!y) y = &dummy;
|
6933
|
+
if (!comp) comp = &dummy;
|
6088
6934
|
if (stbi__get32be(s) != 0x38425053) {
|
6089
6935
|
stbi__rewind( s );
|
6090
6936
|
return 0;
|
@@ -6101,7 +6947,8 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6101
6947
|
}
|
6102
6948
|
*y = stbi__get32be(s);
|
6103
6949
|
*x = stbi__get32be(s);
|
6104
|
-
|
6950
|
+
depth = stbi__get16be(s);
|
6951
|
+
if (depth != 8 && depth != 16) {
|
6105
6952
|
stbi__rewind( s );
|
6106
6953
|
return 0;
|
6107
6954
|
}
|
@@ -6112,14 +6959,45 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
|
|
6112
6959
|
*comp = 4;
|
6113
6960
|
return 1;
|
6114
6961
|
}
|
6962
|
+
|
6963
|
+
static int stbi__psd_is16(stbi__context *s)
|
6964
|
+
{
|
6965
|
+
int channelCount, depth;
|
6966
|
+
if (stbi__get32be(s) != 0x38425053) {
|
6967
|
+
stbi__rewind( s );
|
6968
|
+
return 0;
|
6969
|
+
}
|
6970
|
+
if (stbi__get16be(s) != 1) {
|
6971
|
+
stbi__rewind( s );
|
6972
|
+
return 0;
|
6973
|
+
}
|
6974
|
+
stbi__skip(s, 6);
|
6975
|
+
channelCount = stbi__get16be(s);
|
6976
|
+
if (channelCount < 0 || channelCount > 16) {
|
6977
|
+
stbi__rewind( s );
|
6978
|
+
return 0;
|
6979
|
+
}
|
6980
|
+
(void) stbi__get32be(s);
|
6981
|
+
(void) stbi__get32be(s);
|
6982
|
+
depth = stbi__get16be(s);
|
6983
|
+
if (depth != 16) {
|
6984
|
+
stbi__rewind( s );
|
6985
|
+
return 0;
|
6986
|
+
}
|
6987
|
+
return 1;
|
6988
|
+
}
|
6115
6989
|
#endif
|
6116
6990
|
|
6117
6991
|
#ifndef STBI_NO_PIC
|
6118
6992
|
static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
|
6119
6993
|
{
|
6120
|
-
int act_comp=0,num_packets=0,chained;
|
6994
|
+
int act_comp=0,num_packets=0,chained,dummy;
|
6121
6995
|
stbi__pic_packet packets[10];
|
6122
6996
|
|
6997
|
+
if (!x) x = &dummy;
|
6998
|
+
if (!y) y = &dummy;
|
6999
|
+
if (!comp) comp = &dummy;
|
7000
|
+
|
6123
7001
|
if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
|
6124
7002
|
stbi__rewind(s);
|
6125
7003
|
return 0;
|
@@ -6195,16 +7073,22 @@ static int stbi__pnm_test(stbi__context *s)
|
|
6195
7073
|
return 1;
|
6196
7074
|
}
|
6197
7075
|
|
6198
|
-
static
|
7076
|
+
static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
|
6199
7077
|
{
|
6200
7078
|
stbi_uc *out;
|
7079
|
+
STBI_NOTUSED(ri);
|
7080
|
+
|
6201
7081
|
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
|
6202
7082
|
return 0;
|
7083
|
+
|
6203
7084
|
*x = s->img_x;
|
6204
7085
|
*y = s->img_y;
|
6205
|
-
*comp = s->img_n;
|
7086
|
+
if (comp) *comp = s->img_n;
|
7087
|
+
|
7088
|
+
if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
|
7089
|
+
return stbi__errpuc("too large", "PNM too large");
|
6206
7090
|
|
6207
|
-
out = (stbi_uc *)
|
7091
|
+
out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0);
|
6208
7092
|
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
6209
7093
|
stbi__getn(s, out, s->img_n * s->img_x * s->img_y);
|
6210
7094
|
|
@@ -6222,8 +7106,16 @@ static int stbi__pnm_isspace(char c)
|
|
6222
7106
|
|
6223
7107
|
static void stbi__pnm_skip_whitespace(stbi__context *s, char *c)
|
6224
7108
|
{
|
6225
|
-
|
6226
|
-
|
7109
|
+
for (;;) {
|
7110
|
+
while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
|
7111
|
+
*c = (char) stbi__get8(s);
|
7112
|
+
|
7113
|
+
if (stbi__at_eof(s) || *c != '#')
|
7114
|
+
break;
|
7115
|
+
|
7116
|
+
while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' )
|
7117
|
+
*c = (char) stbi__get8(s);
|
7118
|
+
}
|
6227
7119
|
}
|
6228
7120
|
|
6229
7121
|
static int stbi__pnm_isdigit(char c)
|
@@ -6245,16 +7137,20 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c)
|
|
6245
7137
|
|
6246
7138
|
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
|
6247
7139
|
{
|
6248
|
-
int maxv;
|
7140
|
+
int maxv, dummy;
|
6249
7141
|
char c, p, t;
|
6250
7142
|
|
6251
|
-
|
7143
|
+
if (!x) x = &dummy;
|
7144
|
+
if (!y) y = &dummy;
|
7145
|
+
if (!comp) comp = &dummy;
|
7146
|
+
|
7147
|
+
stbi__rewind(s);
|
6252
7148
|
|
6253
7149
|
// Get identifier
|
6254
7150
|
p = (char) stbi__get8(s);
|
6255
7151
|
t = (char) stbi__get8(s);
|
6256
7152
|
if (p != 'P' || (t != '5' && t != '6')) {
|
6257
|
-
stbi__rewind(
|
7153
|
+
stbi__rewind(s);
|
6258
7154
|
return 0;
|
6259
7155
|
}
|
6260
7156
|
|
@@ -6320,6 +7216,19 @@ static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
|
|
6320
7216
|
return stbi__err("unknown image type", "Image not of any known type, or corrupt");
|
6321
7217
|
}
|
6322
7218
|
|
7219
|
+
static int stbi__is_16_main(stbi__context *s)
|
7220
|
+
{
|
7221
|
+
#ifndef STBI_NO_PNG
|
7222
|
+
if (stbi__png_is16(s)) return 1;
|
7223
|
+
#endif
|
7224
|
+
|
7225
|
+
#ifndef STBI_NO_PSD
|
7226
|
+
if (stbi__psd_is16(s)) return 1;
|
7227
|
+
#endif
|
7228
|
+
|
7229
|
+
return 0;
|
7230
|
+
}
|
7231
|
+
|
6323
7232
|
#ifndef STBI_NO_STDIO
|
6324
7233
|
STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp)
|
6325
7234
|
{
|
@@ -6341,6 +7250,27 @@ STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
|
|
6341
7250
|
fseek(f,pos,SEEK_SET);
|
6342
7251
|
return r;
|
6343
7252
|
}
|
7253
|
+
|
7254
|
+
STBIDEF int stbi_is_16_bit(char const *filename)
|
7255
|
+
{
|
7256
|
+
FILE *f = stbi__fopen(filename, "rb");
|
7257
|
+
int result;
|
7258
|
+
if (!f) return stbi__err("can't fopen", "Unable to open file");
|
7259
|
+
result = stbi_is_16_bit_from_file(f);
|
7260
|
+
fclose(f);
|
7261
|
+
return result;
|
7262
|
+
}
|
7263
|
+
|
7264
|
+
STBIDEF int stbi_is_16_bit_from_file(FILE *f)
|
7265
|
+
{
|
7266
|
+
int r;
|
7267
|
+
stbi__context s;
|
7268
|
+
long pos = ftell(f);
|
7269
|
+
stbi__start_file(&s, f);
|
7270
|
+
r = stbi__is_16_main(&s);
|
7271
|
+
fseek(f,pos,SEEK_SET);
|
7272
|
+
return r;
|
7273
|
+
}
|
6344
7274
|
#endif // !STBI_NO_STDIO
|
6345
7275
|
|
6346
7276
|
STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp)
|
@@ -6357,14 +7287,62 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
|
6357
7287
|
return stbi__info_main(&s,x,y,comp);
|
6358
7288
|
}
|
6359
7289
|
|
7290
|
+
STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len)
|
7291
|
+
{
|
7292
|
+
stbi__context s;
|
7293
|
+
stbi__start_mem(&s,buffer,len);
|
7294
|
+
return stbi__is_16_main(&s);
|
7295
|
+
}
|
7296
|
+
|
7297
|
+
STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user)
|
7298
|
+
{
|
7299
|
+
stbi__context s;
|
7300
|
+
stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
|
7301
|
+
return stbi__is_16_main(&s);
|
7302
|
+
}
|
7303
|
+
|
6360
7304
|
#endif // STB_IMAGE_IMPLEMENTATION
|
6361
7305
|
|
6362
7306
|
/*
|
6363
7307
|
revision history:
|
7308
|
+
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
|
7309
|
+
2.19 (2018-02-11) fix warning
|
7310
|
+
2.18 (2018-01-30) fix warnings
|
7311
|
+
2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
|
7312
|
+
1-bit BMP
|
7313
|
+
*_is_16_bit api
|
7314
|
+
avoid warnings
|
7315
|
+
2.16 (2017-07-23) all functions have 16-bit variants;
|
7316
|
+
STBI_NO_STDIO works again;
|
7317
|
+
compilation fixes;
|
7318
|
+
fix rounding in unpremultiply;
|
7319
|
+
optimize vertical flip;
|
7320
|
+
disable raw_len validation;
|
7321
|
+
documentation fixes
|
7322
|
+
2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
|
7323
|
+
warning fixes; disable run-time SSE detection on gcc;
|
7324
|
+
uniform handling of optional "return" values;
|
7325
|
+
thread-safe initialization of zlib tables
|
7326
|
+
2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
|
7327
|
+
2.13 (2016-11-29) add 16-bit API, only supported for PNG right now
|
7328
|
+
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
|
7329
|
+
2.11 (2016-04-02) allocate large structures on the stack
|
7330
|
+
remove white matting for transparent PSD
|
7331
|
+
fix reported channel count for PNG & BMP
|
7332
|
+
re-enable SSE2 in non-gcc 64-bit
|
7333
|
+
support RGB-formatted JPEG
|
7334
|
+
read 16-bit PNGs (only as 8-bit)
|
7335
|
+
2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
|
7336
|
+
2.09 (2016-01-16) allow comments in PNM files
|
7337
|
+
16-bit-per-pixel TGA (not bit-per-component)
|
7338
|
+
info() for TGA could break due to .hdr handling
|
7339
|
+
info() for BMP to shares code instead of sloppy parse
|
7340
|
+
can use STBI_REALLOC_SIZED if allocator doesn't support realloc
|
7341
|
+
code cleanup
|
6364
7342
|
2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
|
6365
7343
|
2.07 (2015-09-13) fix compiler warnings
|
6366
7344
|
partial animated GIF support
|
6367
|
-
limited 16-
|
7345
|
+
limited 16-bpc PSD support
|
6368
7346
|
#ifdef unused functions
|
6369
7347
|
bug with < 92 byte PIC,PNM,HDR,TGA
|
6370
7348
|
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
|
@@ -6507,3 +7485,46 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
|
6507
7485
|
0.50 (2006-11-19)
|
6508
7486
|
first released version
|
6509
7487
|
*/
|
7488
|
+
|
7489
|
+
|
7490
|
+
/*
|
7491
|
+
------------------------------------------------------------------------------
|
7492
|
+
This software is available under 2 licenses -- choose whichever you prefer.
|
7493
|
+
------------------------------------------------------------------------------
|
7494
|
+
ALTERNATIVE A - MIT License
|
7495
|
+
Copyright (c) 2017 Sean Barrett
|
7496
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
7497
|
+
this software and associated documentation files (the "Software"), to deal in
|
7498
|
+
the Software without restriction, including without limitation the rights to
|
7499
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7500
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
7501
|
+
so, subject to the following conditions:
|
7502
|
+
The above copyright notice and this permission notice shall be included in all
|
7503
|
+
copies or substantial portions of the Software.
|
7504
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
7505
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
7506
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
7507
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
7508
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
7509
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
7510
|
+
SOFTWARE.
|
7511
|
+
------------------------------------------------------------------------------
|
7512
|
+
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
7513
|
+
This is free and unencumbered software released into the public domain.
|
7514
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
7515
|
+
software, either in source code form or as a compiled binary, for any purpose,
|
7516
|
+
commercial or non-commercial, and by any means.
|
7517
|
+
In jurisdictions that recognize copyright laws, the author or authors of this
|
7518
|
+
software dedicate any and all copyright interest in the software to the public
|
7519
|
+
domain. We make this dedication for the benefit of the public at large and to
|
7520
|
+
the detriment of our heirs and successors. We intend this dedication to be an
|
7521
|
+
overt act of relinquishment in perpetuity of all present and future rights to
|
7522
|
+
this software under copyright law.
|
7523
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
7524
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
7525
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
7526
|
+
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
7527
|
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
7528
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
7529
|
+
------------------------------------------------------------------------------
|
7530
|
+
*/
|