From 0f81926752e59d81e8dc932f5129688635b4e477 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 28 Dec 2019 17:44:50 -0330 Subject: [PATCH] Convert PNGLibrary to use vector instead of raw pointers. This is just as efficient, but also safer. --- src/common/PNGLibrary.cxx | 61 +++++++++++++++------------------------ src/common/PNGLibrary.hxx | 9 +++--- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/common/PNGLibrary.cxx b/src/common/PNGLibrary.cxx index 549b5245d..976d29470 100644 --- a/src/common/PNGLibrary.cxx +++ b/src/common/PNGLibrary.cxx @@ -107,10 +107,10 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface) // The PNG read function expects an array of rows, not a single 1-D array for(uInt32 irow = 0, offset = 0; irow < ReadInfo.height; ++irow, offset += ReadInfo.pitch) - ReadInfo.row_pointers[irow] = png_bytep(ReadInfo.buffer.get() + offset); + ReadInfo.row_pointers[irow] = static_cast(ReadInfo.buffer.data() + offset); // Read the entire image in one go - png_read_image(png_ptr, ReadInfo.row_pointers.get()); + png_read_image(png_ptr, ReadInfo.row_pointers.data()); // We're finished reading png_read_end(png_ptr, info_ptr); @@ -135,13 +135,13 @@ void PNGLibrary::saveImage(const string& filename, const VariantList& comments) png_uint_32 width = rect.w(), height = rect.h(); // Get framebuffer pixel data (we get ABGR format) - unique_ptr buffer = make_unique(width * height * 4); - fb.readPixels(buffer.get(), width*4, rect); + vector buffer(width * height * 4); + fb.readPixels(buffer.data(), width*4, rect); // Set up pointers into "buffer" byte array - unique_ptr rows = make_unique(height); + vector rows(height); for(png_uint_32 k = 0; k < height; ++k) - rows[k] = png_bytep(buffer.get() + k*width*4); + rows[k] = static_cast(buffer.data() + k*width*4); // And save the image saveImageToDisk(out, rows, width, height, comments); @@ -164,20 +164,20 @@ void PNGLibrary::saveImage(const string& filename, const FBSurface& surface, } // Get the surface pixel data (we get ABGR format) - unique_ptr buffer = make_unique(width * height * 4); - surface.readPixels(buffer.get(), width, rect); + vector buffer(width * height * 4); + surface.readPixels(buffer.data(), width, rect); // Set up pointers into "buffer" byte array - unique_ptr rows = make_unique(height); + vector rows(height); for(png_uint_32 k = 0; k < height; ++k) - rows[k] = png_bytep(buffer.get() + k*width*4); + rows[k] = static_cast(buffer.data() + k*width*4); // And save the image saveImageToDisk(out, rows, width, height, comments); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PNGLibrary::saveImageToDisk(ofstream& out, const unique_ptr& rows, +void PNGLibrary::saveImageToDisk(ofstream& out, const vector& rows, png_uint_32 width, png_uint_32 height, const VariantList& comments) { png_structp png_ptr = nullptr; @@ -228,7 +228,7 @@ void PNGLibrary::saveImageToDisk(ofstream& out, const unique_ptr& r png_set_bgr(png_ptr); // Write the entire image in one go - png_write_image(png_ptr, rows.get()); + png_write_image(png_ptr, const_cast(rows.data())); // We're finished writing png_write_end(png_ptr, info_ptr); @@ -385,24 +385,13 @@ void PNGLibrary::takeSnapshot(uInt32 number) bool PNGLibrary::allocateStorage(png_uint_32 w, png_uint_32 h) { // Create space for the entire image (3 bytes per pixel in RGB format) - uInt32 req_buffer_size = w * h * 3; - if(req_buffer_size > ReadInfo.buffer_size) - { - ReadInfo.buffer = make_unique(req_buffer_size); - if(ReadInfo.buffer == nullptr) - return false; + size_t req_buffer_size = w * h * 3; + if(req_buffer_size > ReadInfo.buffer.size()) + ReadInfo.buffer.resize(req_buffer_size); - ReadInfo.buffer_size = req_buffer_size; - } - uInt32 req_row_size = h; - if(req_row_size > ReadInfo.row_size) - { - ReadInfo.row_pointers = make_unique(req_row_size); - if(ReadInfo.row_pointers == nullptr) - return false; - - ReadInfo.row_size = req_row_size; - } + size_t req_row_size = h; + if(req_row_size > ReadInfo.row_pointers.size()) + ReadInfo.row_pointers.resize(req_row_size); ReadInfo.width = w; ReadInfo.height = h; @@ -427,13 +416,13 @@ void PNGLibrary::loadImagetoSurface(FBSurface& surface) // Convert RGB triples into pixels and store in the surface uInt32 *s_buf, s_pitch; surface.basePtr(s_buf, s_pitch); - uInt8* i_buf = ReadInfo.buffer.get(); - uInt32 i_pitch = ReadInfo.pitch; + const uInt8* i_buf = ReadInfo.buffer.data(); + const uInt32 i_pitch = ReadInfo.pitch; const FrameBuffer& fb = myOSystem.frameBuffer(); for(uInt32 irow = 0; irow < ih; ++irow, i_buf += i_pitch, s_buf += s_pitch) { - uInt8* i_ptr = i_buf; + const uInt8* i_ptr = i_buf; uInt32* s_ptr = s_buf; for(uInt32 icol = 0; icol < ReadInfo.width; ++icol, i_ptr += 3) *s_ptr++ = fb.mapRGB(*i_ptr, *(i_ptr+1), *(i_ptr+2)); @@ -448,7 +437,7 @@ void PNGLibrary::writeComments(png_structp png_ptr, png_infop info_ptr, if(numComments == 0) return; - unique_ptr text_ptr = make_unique(numComments); + vector text_ptr(numComments); for(uInt32 i = 0; i < numComments; ++i) { text_ptr[i].key = const_cast(comments[i].first.c_str()); @@ -456,7 +445,7 @@ void PNGLibrary::writeComments(png_structp png_ptr, png_infop info_ptr, text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE; text_ptr[i].text_length = 0; } - png_set_text(png_ptr, info_ptr, text_ptr.get(), numComments); + png_set_text(png_ptr, info_ptr, text_ptr.data(), numComments); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -492,8 +481,6 @@ void PNGLibrary::png_user_error(png_structp ctx, png_const_charp str) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PNGLibrary::ReadInfoType PNGLibrary::ReadInfo = { - nullptr, nullptr, 0, 0, 0, 0, 0 -}; +PNGLibrary::ReadInfoType PNGLibrary::ReadInfo; #endif // PNG_SUPPORT diff --git a/src/common/PNGLibrary.hxx b/src/common/PNGLibrary.hxx index a0beb9976..03cb0bec4 100644 --- a/src/common/PNGLibrary.hxx +++ b/src/common/PNGLibrary.hxx @@ -137,10 +137,11 @@ class PNGLibrary // The following data remains between invocations of allocateStorage, // and is only changed when absolutely necessary. struct ReadInfoType { - ByteBuffer buffer; - unique_ptr row_pointers; + vector buffer; + vector row_pointers; png_uint_32 width, height, pitch; - uInt32 buffer_size, row_size; + + ReadInfoType() : width(0), height(0), pitch(0) { } }; static ReadInfoType ReadInfo; @@ -166,7 +167,7 @@ class PNGLibrary @param height The height of the PNG image @param comments The text comments to add to the PNG image */ - void saveImageToDisk(ofstream& out, const unique_ptr& rows, + void saveImageToDisk(ofstream& out, const vector& rows, png_uint_32 width, png_uint_32 height, const VariantList& comments);