diff --git a/renderdoc/api/replay/rdcstr.h b/renderdoc/api/replay/rdcstr.h index ba7950ccd..a2a0b3c6e 100644 --- a/renderdoc/api/replay/rdcstr.h +++ b/renderdoc/api/replay/rdcstr.h @@ -812,7 +812,7 @@ public: if(empty()) return; -#define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n') +#define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n' || (c) == '\0') const char *str = c_str(); size_t sz = size(); diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index c5898750c..993c96001 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -1039,11 +1039,10 @@ void RenderDoc::ResamplePixels(const FramePixels &in, RDCThumb &out) out.width = (uint16_t)RDCMIN(in.max_width, in.width); out.width &= ~(in.pitch_requirement - 1); // align down to multiple of in. out.height = uint16_t(out.width * in.height / in.width); - out.len = 3 * out.width * out.height; - out.pixels = new byte[out.len]; + out.pixels.resize(3 * out.width * out.height); out.format = FileType::Raw; - byte *dst = (byte *)out.pixels; + byte *dst = (byte *)out.pixels.data(); byte *source = (byte *)in.data; for(uint32_t y = 0; y < out.height; y++) @@ -1113,7 +1112,7 @@ void RenderDoc::ResamplePixels(const FramePixels &in, RDCThumb &out) uint16_t flipY = (out.height - 1 - y); for(uint16_t x = 0; x < out.width; x++) { - byte *src = (byte *)out.pixels; + byte *src = (byte *)out.pixels.data(); byte save[3]; save[0] = src[(y * out.width + x) * 3 + 0]; save[1] = src[(y * out.width + x) * 3 + 1]; @@ -1152,12 +1151,10 @@ void RenderDoc::EncodePixelsPNG(const RDCThumb &in, RDCThumb &out) WriteCallbackData callbackData; stbi_write_png_to_func(&WriteCallbackData::writeData, &callbackData, in.width, in.height, 3, - in.pixels, 0); + in.pixels.data(), 0); out.width = in.width; out.height = in.height; - out.pixels = new byte[callbackData.buffer.size()]; - memcpy((void *)out.pixels, callbackData.buffer.data(), callbackData.buffer.size()); - out.len = (uint32_t)callbackData.buffer.size(); + out.pixels.swap(callbackData.buffer); out.format = FileType::PNG; } @@ -1206,9 +1203,6 @@ RDCFile *RenderDoc::CreateRDC(RDCDriver driver, uint32_t frameNum, const FramePi SAFE_DELETE(ret); } - SAFE_DELETE_ARRAY(outRaw.pixels); - SAFE_DELETE_ARRAY(outPng.pixels); - return ret; } @@ -1675,10 +1669,9 @@ void RenderDoc::FinishCaptureWriting(RDCFile *rdc, uint32_t frameNumber) ExtThumbnailHeader header; header.width = thumb.width; header.height = thumb.height; - header.len = thumb.len; header.format = thumb.format; w->Write(header); - w->Write(thumb.pixels, thumb.len); + w->Write(thumb.pixels.data(), thumb.pixels.size()); w->Finish(); diff --git a/renderdoc/os/win32/win32_shellext.cpp b/renderdoc/os/win32/win32_shellext.cpp index 7848ffa00..1b81c07d6 100644 --- a/renderdoc/os/win32/win32_shellext.cpp +++ b/renderdoc/os/win32/win32_shellext.cpp @@ -56,11 +56,7 @@ struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream dds_data m_ddsData; RDCThumbnailProvider() : m_iRefcount(1), m_Inited(false) { InterlockedIncrement(&numProviders); } - virtual ~RDCThumbnailProvider() - { - delete[] m_Thumb.pixels; - InterlockedDecrement(&numProviders); - } + virtual ~RDCThumbnailProvider() { InterlockedDecrement(&numProviders); } ULONG STDMETHODCALLTYPE AddRef() { InterlockedIncrement(&m_iRefcount); @@ -152,10 +148,9 @@ struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream // bitmap. m_Thumb.height = (uint16_t)m_ddsData.height; m_Thumb.width = (uint16_t)m_ddsData.width; - m_Thumb.len = m_ddsData.subsizes[0]; // size of slice 0 - buf = new byte[m_Thumb.len]; - m_Thumb.pixels = buf; - memcpy(buf, m_ddsData.subdata[0], m_Thumb.len); // slice 0 + size_t len = m_ddsData.subsizes[0]; // size of slice 0 + m_Thumb.pixels.resize(len); + memcpy(m_Thumb.pixels.data(), m_ddsData.subdata[0], len); // slice 0 m_Thumb.format = FileType::DDS; // We don't need any other data @@ -175,14 +170,7 @@ struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream // we don't care about the error code (which would come from the truncated file), we just care // if we got the thumbnail - if(m_Thumb.len > 0 && m_Thumb.width > 0 && m_Thumb.height > 0 && m_Thumb.pixels) - { - buf = new byte[m_Thumb.len]; - memcpy(buf, m_Thumb.pixels, m_Thumb.len); - m_Thumb.pixels = buf; - m_Thumb.format = FileType::JPG; - } - else + if(m_Thumb.pixels.empty() || m_Thumb.width == 0 || m_Thumb.height == 0) { ReadLegacyCaptureThumb(captureHeader); } @@ -378,13 +366,11 @@ struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream { RDCDEBUG("Got %ux%u thumbnail, %u pixels", thumbWidth, thumbHeight, thumbLen); - byte *pixels = new byte[thumbLen]; - memcpy(pixels, readPtr, thumbLen); + m_Thumb.pixels.resize(thumbLen); + memcpy(m_Thumb.pixels.data(), readPtr, thumbLen); m_Thumb.width = (uint16_t)thumbWidth; m_Thumb.height = (uint16_t)thumbHeight; - m_Thumb.len = thumbLen; - m_Thumb.pixels = pixels; } else { @@ -403,26 +389,22 @@ struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream return E_NOTIMPL; } - if(m_Thumb.len == 0) + if(m_Thumb.pixels.empty()) { RDCERR("Problem opening file"); return E_NOTIMPL; } - size_t thumblen = m_Thumb.len; uint32_t thumbwidth = m_Thumb.width, thumbheight = m_Thumb.height; byte *thumbpixels = NULL; if(m_Thumb.format == FileType::JPG) { - const byte *jpgbuf = m_Thumb.pixels; - if(jpgbuf == NULL) - return E_NOTIMPL; - int w = thumbwidth; int h = thumbheight; int comp = 3; - thumbpixels = jpgd::decompress_jpeg_image_from_memory(jpgbuf, (int)thumblen, &w, &h, &comp, 3); + thumbpixels = jpgd::decompress_jpeg_image_from_memory( + m_Thumb.pixels.data(), (int)m_Thumb.pixels.size(), &w, &h, &comp, 3); } else { @@ -472,7 +454,7 @@ struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream unsigned char decompressedBlock[decompressedBlockMaxSize]; unsigned char greenBlock[16]; uint16_t decompressedBC6[48]; - const byte *compBlockStart = m_Thumb.pixels; + const byte *compBlockStart = m_Thumb.pixels.data(); for(uint32_t blockY = 0; blockY < AlignUp4(thumbheight) / 4; blockY++) { @@ -589,7 +571,7 @@ struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream else { // read data as non-compressed - const byte *src = m_Thumb.pixels; + const byte *src = m_Thumb.pixels.data(); byte *dst = thumbpixels; uint32_t texelSize = m_ddsData.format.ElementSize(); diff --git a/renderdoc/replay/capture_file.cpp b/renderdoc/replay/capture_file.cpp index 378f91c22..dd4d7159b 100644 --- a/renderdoc/replay/capture_file.cpp +++ b/renderdoc/replay/capture_file.cpp @@ -32,7 +32,7 @@ #include "stb/stb_image_resize.h" #include "stb/stb_image_write.h" -static void writeToByteVector(void *context, void *data, int size) +static void writeToBytebuf(void *context, void *data, int size) { bytebuf *buf = (bytebuf *)context; buf->append((byte *)data, size); @@ -64,12 +64,7 @@ static RDCThumb convertThumb(FileType thumbType, uint32_t thumbWidth, uint32_t t if(thumbType == FileType::JPG) { - // just need to copy - byte *pixels = (byte *)malloc(thumbData.size()); - memcpy(pixels, thumbData.data(), thumbData.size()); - - ret.pixels = pixels; - ret.len = (uint32_t)thumbData.size(); + ret.pixels = thumbData; } else { @@ -87,15 +82,14 @@ static RDCThumb convertThumb(FileType thumbType, uint32_t thumbWidth, uint32_t t if(decoded) { int len = ret.width * ret.height * 3; - byte *pixels = (byte *)malloc(len); + ret.pixels.resize(len); jpge::params p; p.m_quality = 90; - jpge::compress_image_to_jpeg_file_in_memory(pixels, len, (int)ret.width, (int)ret.height, 3, - decoded, p); + jpge::compress_image_to_jpeg_file_in_memory(ret.pixels.data(), len, (int)ret.width, + (int)ret.height, 3, decoded, p); - ret.pixels = pixels; - ret.len = (uint32_t)len; + ret.pixels.resize(len); free(decoded); } @@ -402,8 +396,6 @@ void CaptureFile::SetMetadata(const char *driverName, uint64_t machineIdent, Fil m_RDC = new RDCFile; m_RDC->SetData(driver, driverName, machineIdent, thumb); - - free((void *)th.pixels); } ReplayStatus CaptureFile::Convert(const char *filename, const char *filetype, const SDFile *file, @@ -551,11 +543,9 @@ Thumbnail CaptureFile::GetThumbnail(FileType type, uint32_t maxsize) const RDCThumb &thumb = m_RDC->GetThumbnail(); - const byte *thumbbuf = thumb.pixels; - size_t thumblen = thumb.len; uint32_t thumbwidth = thumb.width, thumbheight = thumb.height; - if(thumbbuf == NULL) + if(thumb.pixels.empty()) return ret; bytebuf buf; @@ -564,7 +554,7 @@ Thumbnail CaptureFile::GetThumbnail(FileType type, uint32_t maxsize) // already satisfied, return the data directly if(type == thumb.format && (maxsize == 0 || (maxsize > thumbwidth && maxsize > thumbheight))) { - buf.assign(thumbbuf, thumblen); + buf = thumb.pixels; } else { @@ -578,15 +568,16 @@ Thumbnail CaptureFile::GetThumbnail(FileType type, uint32_t maxsize) switch(thumb.format) { case FileType::JPG: - allocatedBuffer = - jpgd::decompress_jpeg_image_from_memory(thumbbuf, (int)thumblen, &w, &h, &comp, 3); + allocatedBuffer = jpgd::decompress_jpeg_image_from_memory( + thumb.pixels.data(), (int)thumb.pixels.size(), &w, &h, &comp, 3); thumbpixels = allocatedBuffer; break; - case FileType::Raw: thumbpixels = thumbbuf; break; + case FileType::Raw: thumbpixels = thumb.pixels.data(); break; default: - allocatedBuffer = stbi_load_from_memory(thumbbuf, (int)thumblen, &w, &h, &comp, 3); + allocatedBuffer = + stbi_load_from_memory(thumb.pixels.data(), (int)thumb.pixels.size(), &w, &h, &comp, 3); if(allocatedBuffer == NULL) { RDCERR("Couldn't decode provided thumbnail"); @@ -626,42 +617,40 @@ Thumbnail CaptureFile::GetThumbnail(FileType type, uint32_t maxsize) } } - bytebuf encodedBytes; - switch(type) { case FileType::Raw: { - encodedBytes.assign(thumbpixels, thumbwidth * thumbheight * 3); + buf.assign(thumbpixels, thumbwidth * thumbheight * 3); break; } case FileType::JPG: { int len = thumbwidth * thumbheight * 3; - encodedBytes.resize(len); + buf.resize(len); jpge::params p; p.m_quality = 90; - jpge::compress_image_to_jpeg_file_in_memory(&encodedBytes[0], len, (int)thumbwidth, + jpge::compress_image_to_jpeg_file_in_memory(buf.data(), len, (int)thumbwidth, (int)thumbheight, 3, thumbpixels, p); - encodedBytes.resize(len); + buf.resize(len); break; } case FileType::PNG: { - stbi_write_png_to_func(&writeToByteVector, &encodedBytes, (int)thumbwidth, (int)thumbheight, - 3, thumbpixels, 0); + stbi_write_png_to_func(&writeToBytebuf, &buf, (int)thumbwidth, (int)thumbheight, 3, + thumbpixels, 0); break; } case FileType::TGA: { - stbi_write_tga_to_func(&writeToByteVector, &encodedBytes, (int)thumbwidth, (int)thumbheight, - 3, thumbpixels); + stbi_write_tga_to_func(&writeToBytebuf, &buf, (int)thumbwidth, (int)thumbheight, 3, + thumbpixels); break; } case FileType::BMP: { - stbi_write_bmp_to_func(&writeToByteVector, &encodedBytes, (int)thumbwidth, (int)thumbheight, - 3, thumbpixels); + stbi_write_bmp_to_func(&writeToBytebuf, &buf, (int)thumbwidth, (int)thumbheight, 3, + thumbpixels); break; } default: @@ -674,8 +663,6 @@ Thumbnail CaptureFile::GetThumbnail(FileType type, uint32_t maxsize) } } - buf = encodedBytes; - free(allocatedBuffer); } diff --git a/renderdoc/serialise/codecs/xml_codec.cpp b/renderdoc/serialise/codecs/xml_codec.cpp index 058fb78a2..3df12dbb6 100644 --- a/renderdoc/serialise/codecs/xml_codec.cpp +++ b/renderdoc/serialise/codecs/xml_codec.cpp @@ -296,7 +296,7 @@ static ReplayStatus Structured2XML(const char *filename, const RDCFile &file, ui pugi::xml_node xThumbnail = xHeader.append_child("thumbnail"); const RDCThumb &th = file.GetThumbnail(); - if(th.pixels && th.len > 0 && th.width > 0 && th.height > 0) + if(!th.pixels.empty() && th.width > 0 && th.height > 0) { xThumbnail.append_attribute("width") = th.width; xThumbnail.append_attribute("height") = th.height; @@ -604,8 +604,7 @@ static ReplayStatus XML2Structured(const char *xml, const ThumbTypeAndData &thum if(th.width > 0 && th.height > 0 && !thumb.data.empty()) { - th.pixels = thumb.data.data(); - th.len = (uint32_t)thumb.data.size(); + th.pixels = thumb.data; rdcthumb = &th; } @@ -814,14 +813,17 @@ static ReplayStatus Buffers2ZIP(const rdcstr &filename, const RDCFile &file, } const RDCThumb &th = file.GetThumbnail(); - if(th.pixels && th.len > 0 && th.width > 0 && th.height > 0) + if(!th.pixels.empty() && th.width > 0 && th.height > 0) { if(th.format == FileType::JPG) - mz_zip_writer_add_mem(&zip, "thumb.jpg", th.pixels, th.len, MZ_BEST_COMPRESSION); + mz_zip_writer_add_mem(&zip, "thumb.jpg", th.pixels.data(), th.pixels.size(), + MZ_BEST_COMPRESSION); else if(th.format == FileType::PNG) - mz_zip_writer_add_mem(&zip, "thumb.png", th.pixels, th.len, MZ_BEST_COMPRESSION); + mz_zip_writer_add_mem(&zip, "thumb.png", th.pixels.data(), th.pixels.size(), + MZ_BEST_COMPRESSION); else if(th.format == FileType::Raw) - mz_zip_writer_add_mem(&zip, "thumb.raw", th.pixels, th.len, MZ_BEST_COMPRESSION); + mz_zip_writer_add_mem(&zip, "thumb.raw", th.pixels.data(), th.pixels.size(), + MZ_BEST_COMPRESSION); else RDCERR("Unexpected thumbnail format %s", ToStr(th.format).c_str()); } diff --git a/renderdoc/serialise/rdcfile.cpp b/renderdoc/serialise/rdcfile.cpp index 0ae52c624..6ca3c07be 100644 --- a/renderdoc/serialise/rdcfile.cpp +++ b/renderdoc/serialise/rdcfile.cpp @@ -227,9 +227,6 @@ RDCFile::~RDCFile() { if(m_File) FileIO::fclose(m_File); - - if(m_Thumb.pixels) - delete[] m_Thumb.pixels; } void RDCFile::Open(const char *path) @@ -352,12 +349,12 @@ void RDCFile::Init(StreamReader &reader) RETURNERROR(ContainerError::Corrupt, "Thumbnail byte length invalid: %u", thumb.length); } - byte *thumbData = new byte[thumb.length]; - reader.Read(thumbData, thumb.length); + bytebuf thumbData; + thumbData.resize(thumb.length); + reader.Read(thumbData.data(), thumb.length); if(reader.IsErrored()) { - delete[] thumbData; RETURNERROR(ContainerError::FileIO, "I/O error reading thumbnail data"); } @@ -366,45 +363,35 @@ void RDCFile::Init(StreamReader &reader) if(reader.IsErrored()) { - delete[] thumbData; RETURNERROR(ContainerError::FileIO, "I/O error reading capture metadata"); } if(meta.driverNameLength == 0) { - delete[] thumbData; RETURNERROR(ContainerError::Corrupt, "Driver name length is invalid, must be at least 1 to contain NULL terminator"); } - char *driverName = new char[meta.driverNameLength]; - reader.Read(driverName, meta.driverNameLength); + rdcstr driverName; + driverName.resize(meta.driverNameLength); + reader.Read(driverName.data(), meta.driverNameLength); + driverName.trim(); if(reader.IsErrored()) { - delete[] thumbData; - delete[] driverName; RETURNERROR(ContainerError::FileIO, "I/O error reading driver name"); } - driverName[meta.driverNameLength - 1] = '\0'; m_Driver = meta.driverID; m_DriverName = driverName; m_MachineIdent = meta.machineIdent; m_Thumb.width = thumb.width; m_Thumb.height = thumb.height; - m_Thumb.len = thumb.length; m_Thumb.format = FileType::JPG; - if(m_Thumb.len > 0 && m_Thumb.width > 0 && m_Thumb.height > 0) - { - m_Thumb.pixels = thumbData; - thumbData = NULL; - } - - delete[] thumbData; - delete[] driverName; + if(m_Thumb.width > 0 && m_Thumb.height > 0) + m_Thumb.pixels.swap(thumbData); if(reader.GetOffset() > header.headerLength) { @@ -597,22 +584,16 @@ void RDCFile::Init(StreamReader &reader) ExtThumbnailHeader thumbHeader; if(thumbReader->Read(thumbHeader)) { - thumbData = new byte[thumbHeader.len]; - bool succeeded = thumbReader->Read(thumbData, thumbHeader.len) && !thumbReader->IsErrored(); + thumbData.resize(thumbHeader.len); + bool succeeded = + thumbReader->Read(thumbData.data(), thumbHeader.len) && !thumbReader->IsErrored(); 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 = thumbHeader.format; - delete[] m_Thumb.pixels; - m_Thumb.pixels = thumbData; + m_Thumb.pixels.swap(thumbData); } - else - { - delete[] thumbData; - } - thumbData = NULL; } delete thumbReader; } @@ -651,11 +632,6 @@ void RDCFile::SetData(RDCDriver driver, const char *driverName, uint64_t machine if(thumb) { m_Thumb = *thumb; - - byte *pixels = new byte[m_Thumb.len]; - memcpy(pixels, thumb->pixels, m_Thumb.len); - - m_Thumb.pixels = pixels; } } @@ -680,10 +656,10 @@ void RDCFile::Create(const char *filename) thumbHeader.width = m_Thumb.width; thumbHeader.height = m_Thumb.height; - const byte *jpgPixels = m_Thumb.pixels; - thumbHeader.length = m_Thumb.len; + const byte *jpgPixels = m_Thumb.pixels.data(); + thumbHeader.length = (uint32_t)m_Thumb.pixels.size(); - byte *jpgBuffer = NULL; + bytebuf jpgBuffer; if(m_Thumb.format != FileType::JPG && m_Thumb.width > 0 && m_Thumb.height > 0) { // the primary thumbnail must be in JPG format, must perform conversion @@ -695,23 +671,24 @@ void RDCFile::Create(const char *filename) if(m_Thumb.format == FileType::Raw) { - rawPixels = m_Thumb.pixels; + rawPixels = m_Thumb.pixels.data(); } else { - rawBuffer = stbi_load_from_memory(m_Thumb.pixels, (int)m_Thumb.len, &w, &h, &comp, 3); + rawBuffer = + stbi_load_from_memory(m_Thumb.pixels.data(), (int)m_Thumb.pixels.size(), &w, &h, &comp, 3); rawPixels = rawBuffer; } if(rawPixels) { int len = w * h * comp; - jpgBuffer = new byte[len]; + jpgBuffer.resize(len); jpge::params p; p.m_quality = 90; - jpge::compress_image_to_jpeg_file_in_memory(jpgBuffer, len, w, h, comp, rawPixels, p); + jpge::compress_image_to_jpeg_file_in_memory(jpgBuffer.data(), len, w, h, comp, rawPixels, p); thumbHeader.length = (uint32_t)len; - jpgPixels = jpgBuffer; + jpgPixels = jpgBuffer.data(); } else { @@ -745,7 +722,6 @@ void RDCFile::Create(const char *filename) writer.Write(m_DriverName.c_str(), meta.driverNameLength); - delete[] jpgBuffer; if(writer.IsErrored()) { RETURNERROR(ContainerError::FileIO, "Error writing file header"); diff --git a/renderdoc/serialise/rdcfile.h b/renderdoc/serialise/rdcfile.h index 6d359d0a9..3f6ca0d54 100644 --- a/renderdoc/serialise/rdcfile.h +++ b/renderdoc/serialise/rdcfile.h @@ -40,8 +40,7 @@ extern const char *SectionTypeNames[]; struct RDCThumb { - const byte *pixels = NULL; - uint32_t len = 0; + bytebuf pixels; uint16_t width = 0; uint16_t height = 0; FileType format = FileType::JPG;