base64 bmp images for texture debug

Fix qv::length
This commit is contained in:
Jonathan 2021-10-24 13:55:27 -04:00
parent d0e557b9cb
commit bfc854efcb
2 changed files with 197 additions and 6 deletions

View File

@ -84,6 +84,177 @@ static json serialize_bspxbrushlist(const bspxentry_t &lump)
return j;
}
// Quake palette
constexpr uint8_t thepalette[768] =
{0, 0, 0, 15, 15, 15, 31, 31, 31, 47, 47, 47, 63, 63, 63, 75, 75, 75, 91, 91, 91, 107, 107, 107, 123, 123, 123, 139,
139, 139, 155, 155, 155, 171, 171, 171, 187, 187, 187, 203, 203, 203, 219, 219, 219, 235, 235, 235, 15, 11, 7,
23, 15, 11, 31, 23, 11, 39, 27, 15, 47, 35, 19, 55, 43, 23, 63, 47, 23, 75, 55, 27, 83, 59, 27, 91, 67, 31, 99,
75, 31, 107, 83, 31, 115, 87, 31, 123, 95, 35, 131, 103, 35, 143, 111, 35, 11, 11, 15, 19, 19, 27, 27, 27, 39,
39, 39, 51, 47, 47, 63, 55, 55, 75, 63, 63, 87, 71, 71, 103, 79, 79, 115, 91, 91, 127, 99, 99, 139, 107, 107,
151, 115, 115, 163, 123, 123, 175, 131, 131, 187, 139, 139, 203, 0, 0, 0, 7, 7, 0, 11, 11, 0, 19, 19, 0, 27, 27,
0, 35, 35, 0, 43, 43, 7, 47, 47, 7, 55, 55, 7, 63, 63, 7, 71, 71, 7, 75, 75, 11, 83, 83, 11, 91, 91, 11, 99, 99,
11, 107, 107, 15, 7, 0, 0, 15, 0, 0, 23, 0, 0, 31, 0, 0, 39, 0, 0, 47, 0, 0, 55, 0, 0, 63, 0, 0, 71, 0, 0, 79,
0, 0, 87, 0, 0, 95, 0, 0, 103, 0, 0, 111, 0, 0, 119, 0, 0, 127, 0, 0, 19, 19, 0, 27, 27, 0, 35, 35, 0, 47, 43,
0, 55, 47, 0, 67, 55, 0, 75, 59, 7, 87, 67, 7, 95, 71, 7, 107, 75, 11, 119, 83, 15, 131, 87, 19, 139, 91, 19,
151, 95, 27, 163, 99, 31, 175, 103, 35, 35, 19, 7, 47, 23, 11, 59, 31, 15, 75, 35, 19, 87, 43, 23, 99, 47, 31,
115, 55, 35, 127, 59, 43, 143, 67, 51, 159, 79, 51, 175, 99, 47, 191, 119, 47, 207, 143, 43, 223, 171, 39, 239,
203, 31, 255, 243, 27, 11, 7, 0, 27, 19, 0, 43, 35, 15, 55, 43, 19, 71, 51, 27, 83, 55, 35, 99, 63, 43, 111, 71,
51, 127, 83, 63, 139, 95, 71, 155, 107, 83, 167, 123, 95, 183, 135, 107, 195, 147, 123, 211, 163, 139, 227, 179,
151, 171, 139, 163, 159, 127, 151, 147, 115, 135, 139, 103, 123, 127, 91, 111, 119, 83, 99, 107, 75, 87, 95, 63,
75, 87, 55, 67, 75, 47, 55, 67, 39, 47, 55, 31, 35, 43, 23, 27, 35, 19, 19, 23, 11, 11, 15, 7, 7, 187, 115, 159,
175, 107, 143, 163, 95, 131, 151, 87, 119, 139, 79, 107, 127, 75, 95, 115, 67, 83, 107, 59, 75, 95, 51, 63, 83,
43, 55, 71, 35, 43, 59, 31, 35, 47, 23, 27, 35, 19, 19, 23, 11, 11, 15, 7, 7, 219, 195, 187, 203, 179, 167, 191,
163, 155, 175, 151, 139, 163, 135, 123, 151, 123, 111, 135, 111, 95, 123, 99, 83, 107, 87, 71, 95, 75, 59, 83,
63, 51, 67, 51, 39, 55, 43, 31, 39, 31, 23, 27, 19, 15, 15, 11, 7, 111, 131, 123, 103, 123, 111, 95, 115, 103,
87, 107, 95, 79, 99, 87, 71, 91, 79, 63, 83, 71, 55, 75, 63, 47, 67, 55, 43, 59, 47, 35, 51, 39, 31, 43, 31, 23,
35, 23, 15, 27, 19, 11, 19, 11, 7, 11, 7, 255, 243, 27, 239, 223, 23, 219, 203, 19, 203, 183, 15, 187, 167, 15,
171, 151, 11, 155, 131, 7, 139, 115, 7, 123, 99, 7, 107, 83, 0, 91, 71, 0, 75, 55, 0, 59, 43, 0, 43, 31, 0, 27,
15, 0, 11, 7, 0, 0, 0, 255, 11, 11, 239, 19, 19, 223, 27, 27, 207, 35, 35, 191, 43, 43, 175, 47, 47, 159, 47,
47, 143, 47, 47, 127, 47, 47, 111, 47, 47, 95, 43, 43, 79, 35, 35, 63, 27, 27, 47, 19, 19, 31, 11, 11, 15, 43,
0, 0, 59, 0, 0, 75, 7, 0, 95, 7, 0, 111, 15, 0, 127, 23, 7, 147, 31, 7, 163, 39, 11, 183, 51, 15, 195, 75, 27,
207, 99, 43, 219, 127, 59, 227, 151, 79, 231, 171, 95, 239, 191, 119, 247, 211, 139, 167, 123, 59, 183, 155, 55,
199, 195, 55, 231, 227, 87, 127, 191, 255, 171, 231, 255, 215, 255, 255, 103, 0, 0, 139, 0, 0, 179, 0, 0, 215,
0, 0, 255, 0, 0, 255, 243, 147, 255, 247, 199, 255, 255, 255, 159, 91, 83};
/**
* The MIT License (MIT)
* Copyright (c) 2016 tomykaira
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
template<typename T>
static void Base64EncodeTo(const uint8_t *data, size_t in_len, T p)
{
static constexpr char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
if (in_len == 0)
return;
size_t out_len = 4 * ((in_len + 2) / 3);
size_t i;
if (in_len == 1) {
*p++ = sEncodingTable[(data[0] >> 2) & 0x3F];
*p++ = sEncodingTable[((data[0] & 0x3) << 4)];
*p++ = '=';
*p++ = '=';
return;
}
if (in_len == 2) {
*p++ = sEncodingTable[(data[0] >> 2) & 0x3F];
*p++ = sEncodingTable[((data[0] & 0x3) << 4) | ((int)(data[1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[1] & 0xF) << 2)];
*p++ = '=';
return;
}
for (i = 0; i < in_len - 2; i += 3) {
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) | ((int) (data[i + 2] & 0xC0) >> 6)];
*p++ = sEncodingTable[data[i + 2] & 0x3F];
}
if (i < in_len) {
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
if (i == (in_len - 1)) {
*p++ = sEncodingTable[((data[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
}
static std::string serialize_image(const uint8_t *palette, const uint8_t *image, int32_t width, int32_t height)
{
size_t bufsize = 122 + (width * height * 4);
uint8_t *buf = new uint8_t[bufsize];
memstream s(buf, bufsize, std::ios_base::out | std::ios_base::binary);
s << endianness<std::endian::little>;
s <= std::array<char, 2> { 'B', 'M' };
s <= (int32_t) bufsize;
s <= (int16_t) 0;
s <= (int16_t) 0;
s <= (int32_t) 122;
s <= (int32_t) 108;
s <= width;
s <= height;
s <= (int16_t) 1;
s <= (int16_t) 32;
s <= (int32_t) 3;
s <= (int32_t) (width * height * 4);
s <= (int32_t) 2835;
s <= (int32_t) 2835;
s <= (int32_t) 0;
s <= (int32_t) 0;
s <= (int32_t) 0x00FF0000;
s <= (int32_t) 0x0000FF00;
s <= (int32_t) 0x000000FF;
s <= (int32_t) 0xFF000000;
s <= std::array<char, 4> { 'W', 'i', 'n', ' ' };
s <= std::array<char, 36> { };
s <= (int32_t) 0;
s <= (int32_t) 0;
s <= (int32_t) 0;
for (size_t y = 0; y < height; y++) {
for (size_t x = 0; x < width; x++) {
const uint8_t *pixel = image + ((height - y - 1) * width) + x;
if (*pixel == 255) {
s <= (int32_t) 0;
} else {
const uint8_t *color = &palette[(*pixel) * 3];
s <= color[2];
s <= color[1];
s <= color[0];
s <= (uint8_t) 255;
}
}
}
std::string str { "data:image/bmp;base64," };
Base64EncodeTo(buf, bufsize, std::back_inserter(str));
delete[] buf;
return str;
}
static void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const std::filesystem::path &name)
{
json j = json::object();
@ -295,6 +466,26 @@ static void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const std
}
}
if (bsp.dtex.textures.size()) {
json &textures = (j.emplace("textures", json::array())).first.value();
for (auto &src_tex : bsp.dtex.textures) {
json &tex = textures.insert(textures.end(), json::object()).value();
tex.push_back({"name", src_tex.name});
tex.push_back({"width", src_tex.width});
tex.push_back({"height", src_tex.height});
json &mips = tex["mips"] = json::array();
const uint8_t *pal = src_tex.palette.empty() ? thepalette : src_tex.palette.data();
for (size_t i = 0; i < src_tex.data.size(); i++) {
mips.emplace_back(serialize_image(pal, src_tex.data[i].get(), src_tex.width >> i, src_tex.height >> i));
}
}
}
if (!bspdata.bspx.entries.empty()) {
json &bspxentries = (j.emplace("bspxentries", json::array())).first.value();

View File

@ -395,6 +395,12 @@ template<size_t N, class T>
return len2;
}
template<size_t N, class T>
[[nodiscard]] inline T length(const qvec<T, N> &v1)
{
return std::sqrt(length2(v1));
}
template<size_t N, class T>
[[nodiscard]] inline T distance(const qvec<T, N> &v1, const qvec<T, N> &v2)
{
@ -407,12 +413,6 @@ template<size_t N, class T>
return length2(v2 - v1);
}
template<size_t N, class T>
[[nodiscard]] inline T length(const qvec<T, N> &v1)
{
return std::sqrt(length2(v1));
}
template<size_t N, class T>
[[nodiscard]] inline qvec<T, N> normalize(const qvec<T, N> &v1, T &len)
{