[Libreoffice-commits] online.git: common/Png.hpp
Ashod Nakashian (via logerrit)
logerrit at kemper.freedesktop.org
Sun Sep 22 18:24:55 UTC 2019
common/Png.hpp | 66 +++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 43 insertions(+), 23 deletions(-)
New commits:
commit f7bd2c7e1df5c2f1e17ae2b8e1658f9013704648
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Sat Sep 21 21:10:18 2019 -0400
Commit: Ashod Nakashian <ashnakash at gmail.com>
CommitDate: Sun Sep 22 20:24:36 2019 +0200
wsd: fix variable might be clobbered by ‘longjmp’ or ‘vfork’
As the comment details, this avoids having C++ objects
in the same frame as setjmp, which may reset their
contents without the dtor getting called.
Change-Id: I851ae8bffb4356d465a25dfc815a1fecb489fa30
Reviewed-on: https://gerrit.libreoffice.org/79338
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/common/Png.hpp b/common/Png.hpp
index d4e1c2cf5..d629158c2 100644
--- a/common/Png.hpp
+++ b/common/Png.hpp
@@ -111,13 +111,17 @@ unpremultiply_data (png_structp /*png*/, png_row_infop row_info, png_bytep data)
}
}
-// Sadly, older libpng headers don't use const for the pixmap pointer parameter to
-// png_write_row(), so can't use const here for pixmap.
-inline
-bool encodeSubBufferToPNG(unsigned char* pixmap, size_t startX, size_t startY,
- int width, int height,
- int bufferWidth, int bufferHeight,
- std::vector<char>& output, LibreOfficeKitTileMode mode)
+/// This function uses setjmp which may clobbers non-trivial objects.
+/// So we can't use logging or create complex C++ objects in this frame.
+/// Specifically, logging uses std::string objects, and GCC gives the following:
+/// error: variable ‘__capacity’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered]
+/// In practice, this is bogus, since __capacity is has a trivial type, but this error
+/// shows up with the sanitizers. But technically we shouldn't mix C++ objects with setjmp.
+/// Sadly, older libpng headers don't use const for the pixmap pointer parameter to
+/// png_write_row(), so can't use const here for pixmap.
+inline bool impl_encodeSubBufferToPNG(unsigned char* pixmap, size_t startX, size_t startY,
+ int width, int height, int bufferWidth, int bufferHeight,
+ std::vector<char>& output, LibreOfficeKitTileMode mode)
{
if (bufferWidth < width || bufferHeight < height)
{
@@ -148,7 +152,8 @@ bool encodeSubBufferToPNG(unsigned char* pixmap, size_t startX, size_t startY,
auto initialSize = output.size();
#endif
- png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_set_write_fn(png_ptr, &output, user_write_fn, user_flush_fn);
png_set_write_status_fn(png_ptr, user_write_status_fn);
@@ -160,8 +165,6 @@ bool encodeSubBufferToPNG(unsigned char* pixmap, size_t startX, size_t startY,
png_set_write_user_transform_fn (png_ptr, unpremultiply_data);
}
- auto a = std::chrono::steady_clock::now();
-
for (int y = 0; y < height; ++y)
{
size_t position = ((startY + y) * bufferWidth * 4) + (startX * 4);
@@ -170,19 +173,6 @@ bool encodeSubBufferToPNG(unsigned char* pixmap, size_t startX, size_t startY,
png_write_end(png_ptr, info_ptr);
- auto b = std::chrono::steady_clock::now();
-
- std::chrono::milliseconds::rep duration = std::chrono::duration_cast<std::chrono::milliseconds>(b-a).count();
-
- static std::chrono::milliseconds::rep totalDuration = 0;
- static int nCalls = 0;
-
- totalDuration += duration;
- nCalls += 1;
- LOG_TRC("PNG compression took " << duration << " ms (" << output.size()
- << " bytes). Average after " << std::to_string(nCalls)
- << " calls: " << (totalDuration / static_cast<double>(nCalls)));
-
png_destroy_write_struct(&png_ptr, &info_ptr);
#ifdef IOS
@@ -198,6 +188,36 @@ bool encodeSubBufferToPNG(unsigned char* pixmap, size_t startX, size_t startY,
return true;
}
+/// Sadly, older libpng headers don't use const for the pixmap pointer parameter to
+/// png_write_row(), so can't use const here for pixmap.
+inline bool encodeSubBufferToPNG(unsigned char* pixmap, size_t startX, size_t startY, int width,
+ int height, int bufferWidth, int bufferHeight,
+ std::vector<char>& output, LibreOfficeKitTileMode mode)
+{
+ const auto start = std::chrono::steady_clock::now();
+
+ const bool res = impl_encodeSubBufferToPNG(pixmap, startX, startY, width, height, bufferWidth,
+ bufferHeight, output, mode);
+ if (Log::traceEnabled())
+ {
+ const auto end = std::chrono::steady_clock::now();
+
+ std::chrono::milliseconds::rep duration
+ = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+
+ static std::chrono::milliseconds::rep totalDuration = 0;
+ static int nCalls = 0;
+
+ totalDuration += duration;
+ ++nCalls;
+ LOG_TRC("PNG compression took "
+ << duration << " ms (" << output.size() << " bytes). Average after " << nCalls
+ << " calls: " << (totalDuration / static_cast<double>(nCalls)));
+ }
+
+ return res;
+}
+
inline
bool encodeBufferToPNG(unsigned char* pixmap, int width, int height,
std::vector<char>& output, LibreOfficeKitTileMode mode)
More information about the Libreoffice-commits
mailing list