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