mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Add extended thumbnail handling into XML codec
This commit is contained in:
@@ -1296,11 +1296,14 @@ void RenderDoc::FinishCaptureWriting(RDCFile *rdc, uint32_t frameNumber)
|
||||
props.version = 1;
|
||||
StreamWriter *w = rdc->WriteSection(props);
|
||||
|
||||
// if this file format ever changes, be sure to update the XML export which has a special
|
||||
// handling for this case.
|
||||
|
||||
ExtThumbnailHeader header;
|
||||
header.width = thumb.width;
|
||||
header.height = thumb.height;
|
||||
header.len = thumb.len;
|
||||
header.format = (uint32_t)thumb.format;
|
||||
header.format = thumb.format;
|
||||
w->Write(header);
|
||||
w->Write(thumb.pixels, thumb.len);
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
#include "3rdparty/miniz/miniz.h"
|
||||
#include "3rdparty/pugixml/pugixml.hpp"
|
||||
|
||||
struct ThumbTypeAndData
|
||||
{
|
||||
FileType format;
|
||||
bytebuf data;
|
||||
};
|
||||
|
||||
static const char *typeNames[] = {
|
||||
"chunk", "struct", "array", "null", "buffer", "string", "enum",
|
||||
"uint", "int", "float", "bool", "char", "ResourceId",
|
||||
@@ -316,6 +322,36 @@ static ReplayStatus Structured2XML(const char *filename, const RDCFile &file, ui
|
||||
|
||||
StreamReader *reader = file.ReadSection(i);
|
||||
|
||||
if(props.type == SectionType::ExtendedThumbnail)
|
||||
{
|
||||
ExtThumbnailHeader thumbHeader = {};
|
||||
if(reader->Read(thumbHeader))
|
||||
{
|
||||
// don't need to read the data, that's handled in Buffers2ZIP
|
||||
bool succeeded = reader->SkipBytes(thumbHeader.len) && !reader->IsErrored();
|
||||
if(succeeded && (uint32_t)thumbHeader.format < (uint32_t)FileType::Count)
|
||||
{
|
||||
pugi::xml_node xExtThumbnail = xRoot.append_child("extended_thumbnail");
|
||||
|
||||
xExtThumbnail.append_attribute("width") = thumbHeader.width;
|
||||
xExtThumbnail.append_attribute("height") = thumbHeader.height;
|
||||
xExtThumbnail.append_attribute("length") = thumbHeader.len;
|
||||
|
||||
if(thumbHeader.format == FileType::JPG)
|
||||
xExtThumbnail.text() = "ext_thumb.jpg";
|
||||
else if(thumbHeader.format == FileType::PNG)
|
||||
xExtThumbnail.text() = "ext_thumb.png";
|
||||
else if(thumbHeader.format == FileType::Raw)
|
||||
xExtThumbnail.text() = "ext_thumb.raw";
|
||||
else
|
||||
RDCERR("Unexpected extended thumbnail format %s", ToStr(thumbHeader.format).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
delete reader;
|
||||
continue;
|
||||
}
|
||||
|
||||
pugi::xml_node xSection = xRoot.append_child("section");
|
||||
|
||||
if(props.flags & SectionFlags::ASCIIStored)
|
||||
@@ -506,7 +542,8 @@ static SDObject *XML2Obj(pugi::xml_node &obj)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ReplayStatus XML2Structured(const char *xml, FileType thumbFormat, const bytebuf &thumbBytes,
|
||||
static ReplayStatus XML2Structured(const char *xml, const ThumbTypeAndData &thumb,
|
||||
const ThumbTypeAndData &extThumb,
|
||||
const StructuredBufferList &buffers, RDCFile *rdc,
|
||||
uint64_t &version, StructuredChunkList &chunks,
|
||||
RENDERDOC_ProgressCallback progress)
|
||||
@@ -556,25 +593,47 @@ static ReplayStatus XML2Structured(const char *xml, FileType thumbFormat, const
|
||||
}
|
||||
|
||||
RDCThumb th;
|
||||
th.format = thumbFormat;
|
||||
th.format = thumb.format;
|
||||
th.width = (uint16_t)xThumbnail.attribute("width").as_uint();
|
||||
th.height = (uint16_t)xThumbnail.attribute("height").as_uint();
|
||||
|
||||
RDCThumb *thumb = NULL;
|
||||
RDCThumb *rdcthumb = NULL;
|
||||
|
||||
if(th.width > 0 && th.height > 0 && !thumbBytes.empty())
|
||||
if(th.width > 0 && th.height > 0 && !thumb.data.empty())
|
||||
{
|
||||
th.pixels = thumbBytes.data();
|
||||
th.len = (uint32_t)thumbBytes.size();
|
||||
thumb = &th;
|
||||
th.pixels = thumb.data.data();
|
||||
th.len = (uint32_t)thumb.data.size();
|
||||
rdcthumb = &th;
|
||||
}
|
||||
|
||||
rdc->SetData(driver, driverName.c_str(), machineIdent, thumb);
|
||||
rdc->SetData(driver, driverName.c_str(), machineIdent, rdcthumb);
|
||||
}
|
||||
|
||||
// push in other sections
|
||||
pugi::xml_node xSection = xHeader.next_sibling();
|
||||
|
||||
if(!strcmp(xSection.name(), "extended_thumbnail"))
|
||||
{
|
||||
SectionProperties props = {};
|
||||
props.type = SectionType::ExtendedThumbnail;
|
||||
props.version = 1;
|
||||
StreamWriter *w = rdc->WriteSection(props);
|
||||
|
||||
ExtThumbnailHeader header;
|
||||
header.width = (uint16_t)xSection.attribute("width").as_uint();
|
||||
header.height = (uint16_t)xSection.attribute("height").as_uint();
|
||||
header.len = (uint32_t)extThumb.data.size();
|
||||
header.format = extThumb.format;
|
||||
w->Write(header);
|
||||
w->Write(extThumb.data.data(), extThumb.data.size());
|
||||
|
||||
w->Finish();
|
||||
|
||||
delete w;
|
||||
|
||||
xSection = xSection.next_sibling();
|
||||
}
|
||||
|
||||
if(progress)
|
||||
progress(StructuredProgress(0.1f));
|
||||
|
||||
@@ -762,14 +821,52 @@ static ReplayStatus Buffers2ZIP(const std::string &filename, const RDCFile &file
|
||||
RDCERR("Unexpected thumbnail format %s", ToStr(th.format).c_str());
|
||||
}
|
||||
|
||||
for(int i = 0; i < file.NumSections(); i++)
|
||||
{
|
||||
const SectionProperties &props = file.GetSectionProperties(i);
|
||||
|
||||
if(props.type == SectionType::ExtendedThumbnail)
|
||||
{
|
||||
StreamReader *reader = file.ReadSection(i);
|
||||
|
||||
ExtThumbnailHeader thumbHeader = {};
|
||||
if(reader->Read(thumbHeader))
|
||||
{
|
||||
byte *thumb_bytes = new byte[thumbHeader.len];
|
||||
|
||||
bool succeeded = reader->Read(thumb_bytes, thumbHeader.len) && !reader->IsErrored();
|
||||
if(succeeded && (uint32_t)thumbHeader.format < (uint32_t)FileType::Count)
|
||||
{
|
||||
if(thumbHeader.format == FileType::JPG)
|
||||
mz_zip_writer_add_mem(&zip, "ext_thumb.jpg", thumb_bytes, thumbHeader.len,
|
||||
MZ_BEST_COMPRESSION);
|
||||
else if(thumbHeader.format == FileType::PNG)
|
||||
mz_zip_writer_add_mem(&zip, "ext_thumb.png", thumb_bytes, thumbHeader.len,
|
||||
MZ_BEST_COMPRESSION);
|
||||
else if(thumbHeader.format == FileType::Raw)
|
||||
mz_zip_writer_add_mem(&zip, "ext_thumb.raw", thumb_bytes, thumbHeader.len,
|
||||
MZ_BEST_COMPRESSION);
|
||||
else
|
||||
RDCERR("Unexpected extended thumbnail format %s", ToStr(thumbHeader.format).c_str());
|
||||
}
|
||||
|
||||
delete[] thumb_bytes;
|
||||
}
|
||||
|
||||
delete reader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mz_zip_writer_finalize_archive(&zip);
|
||||
mz_zip_writer_end(&zip);
|
||||
|
||||
return ReplayStatus::Succeeded;
|
||||
}
|
||||
|
||||
static bool ZIP2Buffers(const std::string &filename, FileType &thumbFormat, bytebuf &thumbBytes,
|
||||
StructuredBufferList &buffers, RENDERDOC_ProgressCallback progress)
|
||||
static bool ZIP2Buffers(const std::string &filename, ThumbTypeAndData &thumb,
|
||||
ThumbTypeAndData &extThumb, StructuredBufferList &buffers,
|
||||
RENDERDOC_ProgressCallback progress)
|
||||
{
|
||||
std::string zipFile = filename;
|
||||
zipFile.erase(zipFile.size() - 4); // remove the .xml, leave only the .zip
|
||||
@@ -800,23 +897,20 @@ static bool ZIP2Buffers(const std::string &filename, FileType &thumbFormat, byte
|
||||
|
||||
byte *buf = (byte *)mz_zip_reader_extract_to_heap(&zip, i, &sz, 0);
|
||||
|
||||
if(!strcmp(zstat.m_filename, "thumb.jpg"))
|
||||
// thumbnails are stored separately
|
||||
if(strstr(zstat.m_filename, "thumb"))
|
||||
{
|
||||
// we store the thumbnail separately
|
||||
thumbFormat = FileType::JPG;
|
||||
thumbBytes.assign(buf, sz);
|
||||
}
|
||||
else if(!strcmp(zstat.m_filename, "thumb.png"))
|
||||
{
|
||||
// we store the thumbnail separately
|
||||
thumbFormat = FileType::PNG;
|
||||
thumbBytes.assign(buf, sz);
|
||||
}
|
||||
else if(!strcmp(zstat.m_filename, "thumb.raw"))
|
||||
{
|
||||
// we store the thumbnail separately
|
||||
thumbFormat = FileType::Raw;
|
||||
thumbBytes.assign(buf, sz);
|
||||
FileType type = FileType::JPG;
|
||||
if(strstr(zstat.m_filename, ".png"))
|
||||
type = FileType::PNG;
|
||||
else if(strstr(zstat.m_filename, ".raw"))
|
||||
type = FileType::Raw;
|
||||
|
||||
if(strstr(zstat.m_filename, "ext_thumb"))
|
||||
{
|
||||
extThumb.format = type;
|
||||
extThumb.data.assign(buf, sz);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -842,11 +936,10 @@ static bool ZIP2Buffers(const std::string &filename, FileType &thumbFormat, byte
|
||||
ReplayStatus importXMLZ(const char *filename, StreamReader &reader, RDCFile *rdc,
|
||||
SDFile &structData, RENDERDOC_ProgressCallback progress)
|
||||
{
|
||||
FileType thumbFormat = FileType::JPG;
|
||||
bytebuf thumbBytes;
|
||||
ThumbTypeAndData thumb, extThumb;
|
||||
if(filename)
|
||||
{
|
||||
bool success = ZIP2Buffers(filename, thumbFormat, thumbBytes, structData.buffers, progress);
|
||||
bool success = ZIP2Buffers(filename, thumb, extThumb, structData.buffers, progress);
|
||||
if(!success)
|
||||
{
|
||||
RDCERR("Couldn't load zip to go with %s", filename);
|
||||
@@ -859,7 +952,7 @@ ReplayStatus importXMLZ(const char *filename, StreamReader &reader, RDCFile *rdc
|
||||
reader.Read(buf, (size_t)len);
|
||||
buf[len] = 0;
|
||||
|
||||
return XML2Structured(buf, thumbFormat, thumbBytes, structData.buffers, rdc, structData.version,
|
||||
return XML2Structured(buf, thumb, extThumb, structData.buffers, rdc, structData.version,
|
||||
structData.chunks, progress);
|
||||
}
|
||||
|
||||
|
||||
@@ -592,12 +592,12 @@ void RDCFile::Init(StreamReader &reader)
|
||||
{
|
||||
thumbData = new byte[thumbHeader.len];
|
||||
bool succeeded = thumbReader->Read(thumbData, thumbHeader.len) && !thumbReader->IsErrored();
|
||||
if(succeeded && thumbHeader.format < (uint32_t)FileType::Count)
|
||||
if(succeeded && (uint32_t)thumbHeader.format < (uint32_t)FileType::Count)
|
||||
{
|
||||
m_Thumb.width = thumbHeader.width;
|
||||
m_Thumb.height = thumbHeader.height;
|
||||
m_Thumb.len = thumbHeader.len;
|
||||
m_Thumb.format = (FileType)thumbHeader.format;
|
||||
m_Thumb.format = thumbHeader.format;
|
||||
delete[] m_Thumb.pixels;
|
||||
m_Thumb.pixels = thumbData;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ struct ExtThumbnailHeader
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint32_t len;
|
||||
uint32_t format;
|
||||
FileType format;
|
||||
};
|
||||
|
||||
class RDCFile
|
||||
|
||||
Reference in New Issue
Block a user