aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/CMakeLists.txt1
-rw-r--r--src/util/base64.cpp29
-rw-r--r--src/util/container.h7
-rw-r--r--src/util/numeric.cpp11
-rwxr-xr-xsrc/util/png.cpp68
-rwxr-xr-xsrc/util/png.h27
-rw-r--r--src/util/pointer.h34
-rw-r--r--src/util/serialize.cpp5
8 files changed, 172 insertions, 10 deletions
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
index cd2e468d1..6bc97915f 100644
--- a/src/util/CMakeLists.txt
+++ b/src/util/CMakeLists.txt
@@ -15,4 +15,5 @@ set(UTIL_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/string.cpp
${CMAKE_CURRENT_SOURCE_DIR}/srp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timetaker.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/png.cpp
PARENT_SCOPE)
diff --git a/src/util/base64.cpp b/src/util/base64.cpp
index 6e1584410..0c2455222 100644
--- a/src/util/base64.cpp
+++ b/src/util/base64.cpp
@@ -33,18 +33,39 @@ static const std::string base64_chars =
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
+static const std::string base64_chars_padding_1 = "AEIMQUYcgkosw048";
+static const std::string base64_chars_padding_2 = "AQgw";
static inline bool is_base64(unsigned char c)
{
- return isalnum(c) || c == '+' || c == '/' || c == '=';
+ return (c >= '0' && c <= '9')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= 'a' && c <= 'z')
+ || c == '+' || c == '/';
}
bool base64_is_valid(std::string const& s)
{
- for (char i : s)
- if (!is_base64(i))
+ size_t i = 0;
+ for (; i < s.size(); ++i)
+ if (!is_base64(s[i]))
+ break;
+ unsigned char padding = 3 - ((i + 3) % 4);
+ if ((padding == 1 && base64_chars_padding_1.find(s[i - 1]) == std::string::npos)
+ || (padding == 2 && base64_chars_padding_2.find(s[i - 1]) == std::string::npos)
+ || padding == 3)
+ return false;
+ int actual_padding = s.size() - i;
+ // omission of padding characters is allowed
+ if (actual_padding == 0)
+ return true;
+
+ // remaining characters (max. 2) may only be padding
+ for (; i < s.size(); ++i)
+ if (s[i] != '=')
return false;
- return true;
+ // number of padding characters needs to match
+ return padding == actual_padding;
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
diff --git a/src/util/container.h b/src/util/container.h
index 1c4a219f0..001066563 100644
--- a/src/util/container.h
+++ b/src/util/container.h
@@ -140,6 +140,13 @@ public:
m_signal.post();
}
+ void push_back(T &&t)
+ {
+ MutexAutoLock lock(m_mutex);
+ m_queue.push_back(std::move(t));
+ m_signal.post();
+ }
+
/* this version of pop_front returns a empty element of T on timeout.
* Make sure default constructor of T creates a recognizable "empty" element
*/
diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp
index 99e4cfb5c..702ddce95 100644
--- a/src/util/numeric.cpp
+++ b/src/util/numeric.cpp
@@ -159,7 +159,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
return true;
}
-s16 adjustDist(s16 dist, float zoom_fov)
+inline float adjustDist(float dist, float zoom_fov)
{
// 1.775 ~= 72 * PI / 180 * 1.4, the default FOV on the client.
// The heuristic threshold for zooming is half of that.
@@ -167,8 +167,13 @@ s16 adjustDist(s16 dist, float zoom_fov)
if (zoom_fov < 0.001f || zoom_fov > threshold_fov)
return dist;
- return std::round(dist * std::cbrt((1.0f - std::cos(threshold_fov)) /
- (1.0f - std::cos(zoom_fov / 2.0f))));
+ return dist * std::cbrt((1.0f - std::cos(threshold_fov)) /
+ (1.0f - std::cos(zoom_fov / 2.0f)));
+}
+
+s16 adjustDist(s16 dist, float zoom_fov)
+{
+ return std::round(adjustDist((float)dist, zoom_fov));
}
void setPitchYawRollRad(core::matrix4 &m, const v3f &rot)
diff --git a/src/util/png.cpp b/src/util/png.cpp
new file mode 100755
index 000000000..7ac2e94a1
--- /dev/null
+++ b/src/util/png.cpp
@@ -0,0 +1,68 @@
+/*
+Minetest
+Copyright (C) 2021 hecks
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "png.h"
+#include <string>
+#include <sstream>
+#include <zlib.h>
+#include <cassert>
+#include "util/serialize.h"
+#include "serialization.h"
+#include "irrlichttypes.h"
+
+static void writeChunk(std::ostringstream &target, const std::string &chunk_str)
+{
+ assert(chunk_str.size() >= 4);
+ assert(chunk_str.size() - 4 < U32_MAX);
+ writeU32(target, chunk_str.size() - 4); // Write length minus the identifier
+ target << chunk_str;
+ writeU32(target, crc32(0,(const u8*)chunk_str.data(), chunk_str.size()));
+}
+
+std::string encodePNG(const u8 *data, u32 width, u32 height, s32 compression)
+{
+ auto file = std::ostringstream(std::ios::binary);
+ file << "\x89PNG\r\n\x1a\n";
+
+ {
+ auto IHDR = std::ostringstream(std::ios::binary);
+ IHDR << "IHDR";
+ writeU32(IHDR, width);
+ writeU32(IHDR, height);
+ // 8 bpp, color type 6 (RGBA)
+ IHDR.write("\x08\x06\x00\x00\x00", 5);
+ writeChunk(file, IHDR.str());
+ }
+
+ {
+ auto IDAT = std::ostringstream(std::ios::binary);
+ IDAT << "IDAT";
+ auto scanlines = std::ostringstream(std::ios::binary);
+ for(u32 i = 0; i < height; i++) {
+ scanlines.write("\x00", 1); // Null predictor
+ scanlines.write((const char*) data + width * 4 * i, width * 4);
+ }
+ compressZlib(scanlines.str(), IDAT, compression);
+ writeChunk(file, IDAT.str());
+ }
+
+ file.write("\x00\x00\x00\x00IEND\xae\x42\x60\x82", 12);
+
+ return file.str();
+}
diff --git a/src/util/png.h b/src/util/png.h
new file mode 100755
index 000000000..92387aef0
--- /dev/null
+++ b/src/util/png.h
@@ -0,0 +1,27 @@
+/*
+Minetest
+Copyright (C) 2021 hecks
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+#include <string>
+#include "irrlichttypes.h"
+
+/* Simple PNG encoder. Encodes an RGBA image with no predictors.
+ Returns a binary string. */
+std::string encodePNG(const u8 *data, u32 width, u32 height, s32 compression);
diff --git a/src/util/pointer.h b/src/util/pointer.h
index d29ec8739..7fc5de551 100644
--- a/src/util/pointer.h
+++ b/src/util/pointer.h
@@ -51,6 +51,19 @@ public:
else
data = NULL;
}
+ Buffer(Buffer &&buffer)
+ {
+ m_size = buffer.m_size;
+ if(m_size != 0)
+ {
+ data = buffer.data;
+ buffer.data = nullptr;
+ buffer.m_size = 0;
+ }
+ else
+ data = nullptr;
+ }
+ // Copies whole buffer
Buffer(const T *t, unsigned int size)
{
m_size = size;
@@ -62,10 +75,12 @@ public:
else
data = NULL;
}
+
~Buffer()
{
drop();
}
+
Buffer& operator=(const Buffer &buffer)
{
if(this == &buffer)
@@ -81,6 +96,23 @@ public:
data = NULL;
return *this;
}
+ Buffer& operator=(Buffer &&buffer)
+ {
+ if(this == &buffer)
+ return *this;
+ drop();
+ m_size = buffer.m_size;
+ if(m_size != 0)
+ {
+ data = buffer.data;
+ buffer.data = nullptr;
+ buffer.m_size = 0;
+ }
+ else
+ data = nullptr;
+ return *this;
+ }
+
T & operator[](unsigned int i) const
{
return data[i];
@@ -89,10 +121,12 @@ public:
{
return data;
}
+
unsigned int getSize() const
{
return m_size;
}
+
private:
void drop()
{
diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp
index d770101f2..281061229 100644
--- a/src/util/serialize.cpp
+++ b/src/util/serialize.cpp
@@ -248,7 +248,7 @@ std::string serializeJsonStringIfNeeded(const std::string &s)
std::string deSerializeJsonStringIfNeeded(std::istream &is)
{
- std::ostringstream tmp_os;
+ std::stringstream tmp_os(std::ios_base::binary | std::ios_base::in | std::ios_base::out);
bool expect_initial_quote = true;
bool is_json = false;
bool was_backslash = false;
@@ -280,8 +280,7 @@ std::string deSerializeJsonStringIfNeeded(std::istream &is)
expect_initial_quote = false;
}
if (is_json) {
- std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
- return deSerializeJsonString(tmp_is);
+ return deSerializeJsonString(tmp_os);
}
return tmp_os.str();