需要包含的头文件
#include "stb/stb_image.h"
#include "stb/stb_image_write.h"
函数原型
typedef void stbi_write_func(void *context, void *data, int size);
STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes);
STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
renderdoc集成stbi image的方法,在renderdoc/3rdparty/stb/stb_impl.c中
// Implementation file for stb headers - public domain - https://github.com/nothings/stb
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ASSERT(x)
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STBIW_ASSERT(x)
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#define STBIR_ASSERT(x)
#define STB_TRUETYPE_IMPLEMENTATION
#pragma warning(disable:4996) // function unsafe (fopen vs fopen_s)
#pragma warning(disable:4456) // declaration hides previous local declaration
#pragma warning(disable:4457) // declaration hides function parameter
#pragma warning(disable:4189) // local variable is initialized but not referenced
#pragma warning(disable:4244) // <narrowing conversion>, possible loss of data
#pragma warning(disable:4702) // unreachable code
#include "stb_image.h"
#include "stb_image_write.h"
#include "stb_image_resize.h"
#include "stb_truetype.h"
define了STB_IMAGE_IMPLEMENTATION、STB_IMAGE_WRITE_IMPLEMENTATION等宏
renderdoc/CMakeLists.txt
set(sources
......
3rdparty/stb/stb_image.h
3rdparty/stb/stb_image_write.h
3rdparty/stb/stb_image_resize.h
3rdparty/stb/stb_impl.c
3rdparty/stb/stb_truetype.h
......)
这样,就把.h文件转成.c文件进行编译,其他文件直接包含头文件即可,不用再define IMPLEMENTATION宏
写入BMP
static void fileWriteFunc(void *context, void *data, int size)
{
FileIO::fwrite(data, 1, size, (FILE *)context);
}
int ret = stbi_write_bmp_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps,
subdata[0]);
if (ret == 0)
SET_ERROR_RESULT(res, ResultCode::InternalError, "Failed to write BMP image");
写入PNG
int ret = stbi_write_png_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps,
subdata[0], rowPitch);
if (ret == 0)
SET_ERROR_RESULT(res, ResultCode::internalError, "Failed to write PNG image");
stbi_write_bmp_to_func、stbi_write_png_to_func这些自定义函数,不必是写入文件,也可以追加到内存数据结构中
写入TGA 略
从文件加载
从内存加载
JPEG
包含头文件
#include "jpeg-compressor/jpgd.h"
#include "jpeg-compressor/jpge.h"
CMakeLists.txt
set(sources
......
3rdparty/jpeg-compressor/jpgd.cpp
3rdparty/jpeg-compressor/jpgd.h
3rdparty/jpeg-compressor/jpge.cpp
3rdparty/jpeg-compressor/jpge.h
......)
{
jpge::params p;
p.m_quality = sd.jpegQuality;
int len = td.width * td.height * td.format.compCount;
// ensure buffer is at least 1024
if(len < 1024)
len = 1024;
char *jpgdst = new char[len];
bool success = jpge::compress_image_to_jpeg_file_in_memory(jpgdst, len,
td.width, td.height, numComps, subdata[0], p);
if(success)
fwrite(jpgdst, 1, len, f);
else
SET_ERROR_RESULT(res, ResultCode::InternalError, "Failed to wirte JPG image");
delete[] jpgdst;
}
在内存中压缩成JPG格式,再写入文件
从JPG解码
int w = 0;
int h = 0;
int comp = 3;
byte *thumbpixels = jpgd::decompress_jpeg_image_from_memory(
thumbnail.data(), thumbnail.count(), &w, &h, &comp, 3);
if(w > 0 && h > 0 && thumbpixels)
{
// success
}
else
{
// fail
}
// 最后要注意释放内存
free(thumbpixels);
ZSTD集成和使用
// TODO
LZ4集成和使用
// TODO
md5集成和使用
// TODO
参考renderdoc/driver/shaders/dxbc/dxbc_container.cpp或
util/test/demos/d3d12/d3d12_test.cpp使用方法
ZIP的集成和使用
// TODO
XML的集成和使用
see renderdoc/core/settings.cpp
导入导出
static SDObject *importXMLConfig(StreamReader &stream)
{
rdcstr buf;
buf.resize((size_t)stream.GetSize());
stream.Read(buf.data(), buf.size());
pugi::xml_document doc;
doc.load_string(buf.c_str(), pugi::parse_default | pugi::parse_comments);
pugi::xml_node root = doc.child("config");
SDObject *ret = new SDObject("config"_lit, "config"_lit);
if(root)
{
for(pugi::xml_node child = root.first_child(); child; child = child.next_sibling())
{
SDObject *childObj = XML2Config(child);
if(childObj)
ret->AddAndOwnChild(XML2Config(child));
}
}
return ret;
}
static void exportXMLConfig(StreamWriter &stream, const SDObject *obj)
{
pugi::xml_document doc;
pugi::xml_node xRoot = doc.append_child("config");
xRoot.append_attribute("version") = (uint32_t)1;
for(size_t o = 0; o < obj->NumChildren(); o++)
Config2XML(xRoot, *obj->GetChild(o));
xml_stream_writer writer(stream);
doc.save(writer, " ", pugi::format_default | pugi::format_no_empty_element_tags);
}