mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-16 23:45:58 +08:00
Merge pull request #145 from Ybalrid/upgrade_stb_libs
Upgrade the STB libraries, and fix #132
This commit is contained in:
commit
962552c5c8
@ -20,8 +20,8 @@ int usage(int ret = 0) {
|
|||||||
"[path to output directory])\n\n"
|
"[path to output directory])\n\n"
|
||||||
//<< "\t\t -i: start in interactive mode\n"
|
//<< "\t\t -i: start in interactive mode\n"
|
||||||
<< "\t\t -d: dump enclosed content (image assets)\n"
|
<< "\t\t -d: dump enclosed content (image assets)\n"
|
||||||
<< "\t\t -f: file format for image output"
|
<< "\t\t -f: file format for image output\n"
|
||||||
<< "\t\t -o: ouptput directory path"
|
<< "\t\t -o: ouptput directory path\n"
|
||||||
<< "\t\t -h: print this help\n";
|
<< "\t\t -h: print this help\n";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "stb_image_write.h"
|
#include "stb_image_write.h"
|
||||||
#include "texture_dumper.h"
|
#include "texture_dumper.h"
|
||||||
@ -26,28 +26,50 @@ void texture_dumper::dump_to_folder(const std::string& path) {
|
|||||||
cout << "image name is: \"" << image.name << "\"\n";
|
cout << "image name is: \"" << image.name << "\"\n";
|
||||||
cout << "image size is: " << image.width << 'x' << image.height << '\n';
|
cout << "image size is: " << image.width << 'x' << image.height << '\n';
|
||||||
cout << "pixel channel count :" << image.component << '\n';
|
cout << "pixel channel count :" << image.component << '\n';
|
||||||
|
cout << "pixel bit depth :" << image.bits << '\n';
|
||||||
std::string name = image.name.empty() ? std::to_string(index) : image.name;
|
std::string name = image.name.empty() ? std::to_string(index) : image.name;
|
||||||
|
|
||||||
|
// TODO stb_image_write doesn't support any 16bit wirtes;
|
||||||
|
unsigned char* bytes_to_write =
|
||||||
|
const_cast<unsigned char*>(image.image.data());
|
||||||
|
unsigned char* tmp_buffer = nullptr;
|
||||||
|
if (image.pixel_type == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
|
||||||
|
unsigned short max = 0xFFFF;
|
||||||
|
tmp_buffer = new unsigned char[image.width * image.height *
|
||||||
|
image.component * sizeof(unsigned char)];
|
||||||
|
|
||||||
|
unsigned short* buffer_as_shorts = (unsigned short*)bytes_to_write;
|
||||||
|
for (int i = 0; i < image.component * image.width * image.height; ++i) {
|
||||||
|
tmp_buffer[i] =
|
||||||
|
(unsigned char)(0xFF * (float(buffer_as_shorts[i]) / float(max)));
|
||||||
|
}
|
||||||
|
bytes_to_write =
|
||||||
|
tmp_buffer; // swap the pointer, but keep tmp_buffer around as we
|
||||||
|
// need to delete that memory later
|
||||||
|
}
|
||||||
|
|
||||||
switch (configured_format) {
|
switch (configured_format) {
|
||||||
case texture_output_format::png:
|
case texture_output_format::png:
|
||||||
name = path + "/" + name + ".png";
|
name = path + "/" + name + ".png";
|
||||||
std::cout << "Image will be written to " << name << '\n';
|
std::cout << "Image will be written to " << name << '\n';
|
||||||
stbi_write_png(name.c_str(), image.width, image.height, image.component,
|
stbi_write_png(name.c_str(), image.width, image.height, image.component,
|
||||||
image.image.data(), 0);
|
bytes_to_write, 0);
|
||||||
break;
|
break;
|
||||||
case texture_output_format::bmp:
|
case texture_output_format::bmp:
|
||||||
std::cout << "Image will be written to " << name << '\n';
|
std::cout << "Image will be written to " << name << '\n';
|
||||||
name = path + "/" + name + ".bmp";
|
name = path + "/" + name + ".bmp";
|
||||||
stbi_write_bmp(name.c_str(), image.width, image.height, image.component,
|
stbi_write_bmp(name.c_str(), image.width, image.height, image.component,
|
||||||
image.image.data());
|
bytes_to_write);
|
||||||
break;
|
break;
|
||||||
case texture_output_format::tga:
|
case texture_output_format::tga:
|
||||||
std::cout << "Image will be written to " << name << '\n';
|
std::cout << "Image will be written to " << name << '\n';
|
||||||
name = path + "/" + name + ".tga";
|
name = path + "/" + name + ".tga";
|
||||||
stbi_write_tga(name.c_str(), image.width, image.height, image.component,
|
stbi_write_tga(name.c_str(), image.width, image.height, image.component,
|
||||||
image.image.data());
|
bytes_to_write);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[] tmp_buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2625
stb_image.h
2625
stb_image.h
File diff suppressed because it is too large
Load Diff
1108
stb_image_write.h
1108
stb_image_write.h
File diff suppressed because it is too large
Load Diff
63
tiny_gltf.h
63
tiny_gltf.h
@ -492,6 +492,8 @@ struct Image {
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int component;
|
int component;
|
||||||
|
int bits; // bit depth per channel. 8(byte), 16 or 32.
|
||||||
|
int pixel_type; // pixel type(TINYGLTF_COMPONENT_TYPE_***). usually UBYTE(bits = 8) or USHORT(bits = 16)
|
||||||
std::vector<unsigned char> image;
|
std::vector<unsigned char> image;
|
||||||
int bufferView; // (required if no uri)
|
int bufferView; // (required if no uri)
|
||||||
std::string mimeType; // (required if no uri) ["image/jpeg", "image/png",
|
std::string mimeType; // (required if no uri) ["image/jpeg", "image/png",
|
||||||
@ -1633,46 +1635,72 @@ void TinyGLTF::SetImageLoader(LoadImageDataFunction func, void *user_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TINYGLTF_NO_STB_IMAGE
|
#ifndef TINYGLTF_NO_STB_IMAGE
|
||||||
bool LoadImageData(Image *image, const int image_idx, std::string *err, std::string *warn,
|
bool LoadImageData(Image *image, const int image_idx, std::string *err,
|
||||||
int req_width, int req_height, const unsigned char *bytes,
|
std::string *warn, int req_width, int req_height,
|
||||||
int size, void *user_data) {
|
const unsigned char *bytes, int size, void *user_data) {
|
||||||
(void)warn;
|
(void)warn;
|
||||||
|
|
||||||
int w, h, comp, req_comp;
|
int w, h, comp, req_comp;
|
||||||
|
|
||||||
|
unsigned char *data = nullptr;
|
||||||
|
|
||||||
// force 32-bit textures for common Vulkan compatibility. It appears that
|
// force 32-bit textures for common Vulkan compatibility. It appears that
|
||||||
// some GPU drivers do not support 24-bit images for Vulkan
|
// some GPU drivers do not support 24-bit images for Vulkan
|
||||||
req_comp = 4;
|
req_comp = 4;
|
||||||
|
int bits = 8;
|
||||||
|
int pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
|
||||||
|
|
||||||
|
// It is possible that the image we want to load is a 16bit per channel image
|
||||||
|
// We are going to attempt to load it as 16bit per channel, and if it worked,
|
||||||
|
// set the image data accodingly. We are casting the returned pointer into
|
||||||
|
// unsigned char, because we are representing "bytes". But we are updating
|
||||||
|
// the Image metadata to signal that this image uses 2 bytes (16bits) per
|
||||||
|
// channel:
|
||||||
|
if (stbi_is_16_bit_from_memory(bytes, size)) {
|
||||||
|
data = (unsigned char *)stbi_load_16_from_memory(bytes, size, &w, &h, &comp,
|
||||||
|
req_comp);
|
||||||
|
if (data) {
|
||||||
|
bits = 16;
|
||||||
|
pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// at this point, if data is still NULL, it means that the image wasn't
|
||||||
|
// 16bit per channel, we are going to load it as a normal 8bit per channel
|
||||||
|
// mage as we used to do:
|
||||||
// if image cannot be decoded, ignore parsing and keep it by its path
|
// if image cannot be decoded, ignore parsing and keep it by its path
|
||||||
// don't break in this case
|
// don't break in this case
|
||||||
// FIXME we should only enter this function if the image is embedded. If
|
// FIXME we should only enter this function if the image is embedded. If
|
||||||
// image->uri references
|
// image->uri references
|
||||||
// an image file, it should be left as it is. Image loading should not be
|
// an image file, it should be left as it is. Image loading should not be
|
||||||
// mandatory (to support other formats)
|
// mandatory (to support other formats)
|
||||||
unsigned char *data =
|
if (!data) data = stbi_load_from_memory(bytes, size, &w, &h, &comp, req_comp);
|
||||||
stbi_load_from_memory(bytes, size, &w, &h, &comp, req_comp);
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
// NOTE: you can use `warn` instead of `err`
|
// NOTE: you can use `warn` instead of `err`
|
||||||
if (err) {
|
if (err) {
|
||||||
(*err) += "Unknown image format. STB cannot decode image data for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\". Proably 16bit PNG?\n";
|
(*err) +=
|
||||||
|
"Unknown image format. STB cannot decode image data for image[" +
|
||||||
|
std::to_string(image_idx) + "] name = \"" + image->name + "\".\n";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w < 1 || h < 1) {
|
if (w < 1 || h < 1) {
|
||||||
free(data);
|
stbi_image_free(data);
|
||||||
if (err) {
|
if (err) {
|
||||||
(*err) += "Invalid image data for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n";
|
(*err) += "Invalid image data for image[" + std::to_string(image_idx) +
|
||||||
|
"] name = \"" + image->name + "\"\n";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req_width > 0) {
|
if (req_width > 0) {
|
||||||
if (req_width != w) {
|
if (req_width != w) {
|
||||||
free(data);
|
stbi_image_free(data);
|
||||||
if (err) {
|
if (err) {
|
||||||
(*err) += "Image width mismatch for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n";
|
(*err) += "Image width mismatch for image[" +
|
||||||
|
std::to_string(image_idx) + "] name = \"" + image->name +
|
||||||
|
"\"\n";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1680,9 +1708,11 @@ bool LoadImageData(Image *image, const int image_idx, std::string *err, std::str
|
|||||||
|
|
||||||
if (req_height > 0) {
|
if (req_height > 0) {
|
||||||
if (req_height != h) {
|
if (req_height != h) {
|
||||||
free(data);
|
stbi_image_free(data);
|
||||||
if (err) {
|
if (err) {
|
||||||
(*err) += "Image height mismatch. for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n";
|
(*err) += "Image height mismatch. for image[" +
|
||||||
|
std::to_string(image_idx) + "] name = \"" + image->name +
|
||||||
|
"\"\n";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1691,10 +1721,11 @@ bool LoadImageData(Image *image, const int image_idx, std::string *err, std::str
|
|||||||
image->width = w;
|
image->width = w;
|
||||||
image->height = h;
|
image->height = h;
|
||||||
image->component = req_comp;
|
image->component = req_comp;
|
||||||
image->image.resize(static_cast<size_t>(w * h * req_comp));
|
image->bits = bits;
|
||||||
std::copy(data, data + w * h * req_comp, image->image.begin());
|
image->pixel_type = pixel_type;
|
||||||
|
image->image.resize(static_cast<size_t>(w * h * req_comp) * (bits / 8));
|
||||||
free(data);
|
std::copy(data, data + w * h * req_comp * (bits / 8), image->image.begin());
|
||||||
|
stbi_image_free(data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user