[Libreoffice-commits] online.git: loolwsd/Png.hpp loolwsd/test
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Mon Aug 8 03:56:02 UTC 2016
loolwsd/Png.hpp | 75 ++++++++++++++++++++++++++++++++
loolwsd/test/TileCacheTests.cpp | 91 +++++++---------------------------------
2 files changed, 92 insertions(+), 74 deletions(-)
New commits:
commit 18ab6d28bfdf69bdd1827185d73081631d3e13af
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sat Aug 6 11:24:49 2016 -0400
loolwsd: refactored png decoding into own function
Change-Id: I8310b3880f2171c26cecbee4cb1780889d38ea31
Reviewed-on: https://gerrit.libreoffice.org/27973
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/Png.hpp b/loolwsd/Png.hpp
index 7533c4e..6796adf 100644
--- a/loolwsd/Png.hpp
+++ b/loolwsd/Png.hpp
@@ -48,6 +48,8 @@
#define PNG_SKIP_SETJMP_CHECK
#include <png.h>
+#include <cassert>
+
namespace png
{
@@ -155,6 +157,79 @@ bool encodeBufferToPNG(unsigned char* pixmap, int width, int height,
return encodeSubBufferToPNG(pixmap, 0, 0, width, height, width, height, output, mode);
}
+static
+void readTileData(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_voidp io_ptr = png_get_io_ptr(png_ptr);
+ assert(io_ptr);
+
+ assert(io_ptr != nullptr);
+ std::stringstream& streamTile = *(std::stringstream*)io_ptr;
+ streamTile.read((char*)data, length);
+}
+
+inline
+std::vector<png_bytep> decodePNG(std::stringstream& stream, png_uint_32& height, png_uint_32& width, png_uint_32& rowBytes)
+{
+ png_byte signature[0x08];
+ stream.read((char *)signature, 0x08);
+ if (png_sig_cmp(signature, 0x00, 0x08))
+ {
+ throw std::runtime_error("Invalid PNG signature.");
+ }
+
+ png_structp ptrPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (ptrPNG == nullptr)
+ {
+ throw std::runtime_error("png_create_read_struct failed.");
+ }
+
+ png_infop ptrInfo = png_create_info_struct(ptrPNG);
+ if (ptrInfo == nullptr)
+ {
+ throw std::runtime_error("png_create_info_struct failed.");
+ }
+
+ png_infop ptrEnd = png_create_info_struct(ptrPNG);
+ if (ptrEnd == nullptr)
+ {
+ throw std::runtime_error("png_create_info_struct failed.");
+ }
+
+ png_set_read_fn(ptrPNG, &stream, readTileData);
+ png_set_sig_bytes(ptrPNG, 0x08);
+
+ png_read_info(ptrPNG, ptrInfo);
+
+ width = png_get_image_width(ptrPNG, ptrInfo);
+ height = png_get_image_height(ptrPNG, ptrInfo);
+
+ png_set_interlace_handling(ptrPNG);
+ png_read_update_info(ptrPNG, ptrInfo);
+
+ rowBytes = png_get_rowbytes(ptrPNG, ptrInfo);
+ assert(width == rowBytes / 4);
+
+ const size_t dataSize = (rowBytes + sizeof(png_bytep)) * height / sizeof(png_bytep);
+ const size_t size = dataSize + height + sizeof(png_bytep);
+
+ std::vector<png_bytep> rows;
+ rows.resize(size);
+
+ // rows
+ for (png_uint_32 itRow = 0; itRow < height; itRow++)
+ {
+ const auto index = height + (itRow * rowBytes + sizeof(png_bytep) - 1) / sizeof(png_bytep);
+ rows[itRow] = reinterpret_cast<png_bytep>(&rows[index]);
+ }
+
+ png_read_image(ptrPNG, rows.data());
+ png_read_end(ptrPNG, ptrEnd);
+ png_destroy_read_struct(&ptrPNG, &ptrInfo, &ptrEnd);
+
+ return rows;
+}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/test/TileCacheTests.cpp b/loolwsd/test/TileCacheTests.cpp
index 6c0ba64..d4b0a4f 100644
--- a/loolwsd/test/TileCacheTests.cpp
+++ b/loolwsd/test/TileCacheTests.cpp
@@ -9,16 +9,16 @@
#include "config.h"
-#include <png.h>
#include <Poco/Net/WebSocket.h>
#include <cppunit/extensions/HelperMacros.h>
+#include "Common.hpp"
+#include "LOOLProtocol.hpp"
+#include "Png.hpp"
+#include "TileCache.hpp"
+#include "Unit.hpp"
+#include "Util.hpp"
#include "helpers.hpp"
-#include <Common.hpp>
-#include <LOOLProtocol.hpp>
-#include <TileCache.hpp>
-#include <Unit.hpp>
-#include <Util.hpp>
using namespace helpers;
@@ -376,90 +376,33 @@ void TileCacheTests::testLoad12ods()
}
}
-void readTileData(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_voidp io_ptr = png_get_io_ptr(png_ptr);
- CPPUNIT_ASSERT(io_ptr);
-
- assert(io_ptr != nullptr);
- std::stringstream& streamTile = *(std::stringstream*)io_ptr;
- streamTile.read((char*)data, length);
-}
-
void TileCacheTests::checkBlackTile(std::stringstream& tile)
{
- png_uint_32 width;
- png_uint_32 height;
- png_uint_32 itRow;
- png_uint_32 itCol;
- png_uint_32 black;
- png_uint_32 rowBytes;
-
- png_infop ptrInfo;
- png_infop ptrEnd;
- png_structp ptrPNG;
- png_byte signature[0x08];
-
- tile.read((char *)signature, 0x08);
- CPPUNIT_ASSERT_MESSAGE( "Tile is not recognized as a PNG", !png_sig_cmp(signature, 0x00, 0x08));
-
- ptrPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- CPPUNIT_ASSERT_MESSAGE("png_create_read_struct failed", ptrPNG);
-
- ptrInfo = png_create_info_struct(ptrPNG);
- CPPUNIT_ASSERT_MESSAGE("png_create_info_struct failed", ptrInfo);
-
- ptrEnd = png_create_info_struct(ptrPNG);
- CPPUNIT_ASSERT_MESSAGE("png_create_info_struct failed", ptrEnd);
-
- png_set_read_fn(ptrPNG, &tile, readTileData);
- png_set_sig_bytes(ptrPNG, 0x08);
-
- png_read_info(ptrPNG, ptrInfo);
+ png_uint_32 height = 0;
+ png_uint_32 width = 0;
+ png_uint_32 rowBytes = 0;
- width = png_get_image_width(ptrPNG, ptrInfo);
- height = png_get_image_height(ptrPNG, ptrInfo);
+ auto rows = png::decodePNG(tile, height, width, rowBytes);
- png_set_interlace_handling(ptrPNG);
- png_read_update_info(ptrPNG, ptrInfo);
-
- rowBytes = png_get_rowbytes(ptrPNG, ptrInfo);
- CPPUNIT_ASSERT_EQUAL(width, rowBytes / 4);
-
- // rows
- png_bytep rows[height];
- for (itRow = 0; itRow < height; itRow++)
- {
- rows[itRow] = new png_byte[rowBytes];
- }
-
- png_read_image(ptrPNG, rows);
-
- black = 0;
- for (itRow = 0; itRow < height; itRow++)
+ png_uint_32 black = 0;
+ for (png_uint_32 itRow = 0; itRow < height; ++itRow)
{
- itCol = 0;
- while(itCol <= rowBytes)
+ png_uint_32 itCol = 0;
+ while (itCol <= rowBytes)
{
png_byte R = rows[itRow][itCol + 0];
png_byte G = rows[itRow][itCol + 1];
png_byte B = rows[itRow][itCol + 2];
//png_byte A = rows[itRow][itCol + 3];
if (R == 0x00 && G == 0x00 && B == 0x00)
- black++;
+ {
+ ++black;
+ }
itCol += 4;
}
}
- png_read_end(ptrPNG, ptrEnd);
- png_destroy_read_struct(&ptrPNG, &ptrInfo, &ptrEnd);
-
- for (itRow = 0; itRow < height; itRow++ )
- {
- delete rows[itRow];
- }
-
CPPUNIT_ASSERT_MESSAGE("The tile is 100% black", black != height * width);
assert(height * width != 0);
CPPUNIT_ASSERT_MESSAGE("The tile is 90% black", (black * 100) / (height * width) < 90);
More information about the Libreoffice-commits
mailing list