mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
loaders: unify duplicated b64 decoders.
- move the svg/lottie b64 decoders to tvgLzw. - renames tvgLzw -> tvgCompressor
This commit is contained in:
parent
846823bd7f
commit
e7d29e166b
9 changed files with 81 additions and 105 deletions
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "tvgStr.h"
|
||||
#include "tvgCompressor.h"
|
||||
#include "tvgLottieModel.h"
|
||||
#include "tvgLottieParser.h"
|
||||
|
||||
|
@ -29,16 +30,6 @@
|
|||
/* Internal Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
static constexpr const char B64_INDEX[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57,
|
||||
58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||
};
|
||||
|
||||
|
||||
static char* _int2str(int num)
|
||||
|
@ -49,31 +40,6 @@ static char* _int2str(int num)
|
|||
}
|
||||
|
||||
|
||||
static void _decodeB64(const uint8_t* input, const size_t len, Array<char>& output)
|
||||
{
|
||||
int pad = len > 0 && (len % 4 || input[len - 1] == '=');
|
||||
const size_t L = ((len + 3) / 4 - pad) * 4;
|
||||
output.reserve(L / 4 * 3 + pad + 1);
|
||||
output.data[output.reserved - 1] = '\0';
|
||||
|
||||
for (size_t i = 0; i < L; i += 4) {
|
||||
int n = B64_INDEX[input[i]] << 18 | B64_INDEX[input[i + 1]] << 12 | B64_INDEX[input[i + 2]] << 6 | B64_INDEX[input[i + 3]];
|
||||
output.push(n >> 16);
|
||||
output.push(n >> 8 & 0xFF);
|
||||
output.push(n & 0xFF);
|
||||
}
|
||||
if (pad) {
|
||||
int n = B64_INDEX[input[L]] << 18 | B64_INDEX[input[L + 1]] << 12;
|
||||
output.last() = n >> 16;
|
||||
if (len > L + 2 && input[L + 2] != '=') {
|
||||
n |= B64_INDEX[input[L + 2]] << 6;
|
||||
output.push(n >> 8 & 0xFF);
|
||||
}
|
||||
}
|
||||
output.count = output.reserved;
|
||||
}
|
||||
|
||||
|
||||
static void _updateRoundedCorner(LottieGroup* parent, LottieRoundedCorner* roundedCorner)
|
||||
{
|
||||
for (auto child = parent->children.data; child < parent->children.end(); ++child) {
|
||||
|
@ -860,12 +826,7 @@ LottieImage* LottieParser::parseImage(const char* key)
|
|||
//b64 data
|
||||
auto b64Data = strstr(data, ",") + 1;
|
||||
size_t length = strlen(data) - (b64Data - data);
|
||||
|
||||
Array<char> decoded;
|
||||
_decodeB64(reinterpret_cast<const uint8_t*>(b64Data), length, decoded);
|
||||
image->b64Data = decoded.data;
|
||||
image->size = decoded.count;
|
||||
decoded.data = nullptr;
|
||||
image->size = b64Decode(b64Data, length, &image->b64Data);
|
||||
//external image resource
|
||||
} else {
|
||||
auto len = strlen(dirName) + strlen(subPath) + strlen(data) + 1;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "tvgMath.h" /* to include math.h before cstring */
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "tvgCompressor.h"
|
||||
#include "tvgSvgLoaderCommon.h"
|
||||
#include "tvgSvgSceneBuilder.h"
|
||||
#include "tvgSvgPath.h"
|
||||
|
@ -543,10 +544,17 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, const Box& vBox, con
|
|||
imageMimeTypeEncoding encoding;
|
||||
if (!_isValidImageMimeTypeAndEncoding(&href, &mimetype, &encoding)) return nullptr; //not allowed mime type or encoding
|
||||
if (encoding == imageMimeTypeEncoding::base64) {
|
||||
string decoded = svgUtilBase64Decode(href);
|
||||
if (picture->load(decoded.c_str(), decoded.size(), mimetype, true) != Result::Success) return nullptr;
|
||||
char* decoded = nullptr;
|
||||
auto size = b64Decode(href, strlen(href), &decoded);
|
||||
//OPTIMIZE: Skip data copy.
|
||||
if (picture->load(decoded, size, mimetype, true) != Result::Success) {
|
||||
free(decoded);
|
||||
return nullptr;
|
||||
}
|
||||
free(decoded);
|
||||
} else {
|
||||
string decoded = svgUtilURLDecode(href);
|
||||
//OPTIMIZE: Skip data copy.
|
||||
if (picture->load(decoded.c_str(), decoded.size(), mimetype, true) != Result::Success) return nullptr;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -34,15 +34,6 @@ static uint8_t _hexCharToDec(const char c)
|
|||
else return c - '0';
|
||||
}
|
||||
|
||||
static uint8_t _base64Value(const char chr)
|
||||
{
|
||||
if (chr >= 'A' && chr <= 'Z') return chr - 'A';
|
||||
else if (chr >= 'a' && chr <= 'z') return chr - 'a' + ('Z' - 'A') + 1;
|
||||
else if (chr >= '0' && chr <= '9') return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
|
||||
else if (chr == '+' || chr == '-') return 62;
|
||||
else return 63;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* External Class Implementation */
|
||||
|
@ -74,36 +65,3 @@ string svgUtilURLDecode(const char *src)
|
|||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
|
||||
string svgUtilBase64Decode(const char *src)
|
||||
{
|
||||
if (!src) return nullptr;
|
||||
|
||||
auto length = strlen(src);
|
||||
if (length == 0) return nullptr;
|
||||
|
||||
string decoded;
|
||||
decoded.reserve(3*(1+(length >> 2)));
|
||||
|
||||
while (*src && *(src+1)) {
|
||||
if (*src <= 0x20) {
|
||||
++src;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto value1 = _base64Value(src[0]);
|
||||
auto value2 = _base64Value(src[1]);
|
||||
decoded += (value1 << 2) + ((value2 & 0x30) >> 4);
|
||||
|
||||
if (!src[2] || src[2] == '=' || src[2] == '.') break;
|
||||
auto value3 = _base64Value(src[2]);
|
||||
decoded += ((value2 & 0x0f) << 4) + ((value3 & 0x3c) >> 2);
|
||||
|
||||
if (!src[3] || src[3] == '=' || src[3] == '.') break;
|
||||
auto value4 = _base64Value(src[3]);
|
||||
decoded += ((value3 & 0x03) << 6) + value4;
|
||||
src += 4;
|
||||
}
|
||||
return decoded;
|
||||
}
|
|
@ -26,6 +26,5 @@
|
|||
#include "tvgCommon.h"
|
||||
|
||||
string svgUtilURLDecode(const char *src);
|
||||
string svgUtilBase64Decode(const char *src);
|
||||
|
||||
#endif //_TVG_SVG_UTIL_H_
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <fstream>
|
||||
#include "tvgLoader.h"
|
||||
#include "tvgTvgLoader.h"
|
||||
#include "tvgLzw.h"
|
||||
#include "tvgCompressor.h"
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "tvgSaveModule.h"
|
||||
#include "tvgTvgSaver.h"
|
||||
#include "tvgLzw.h"
|
||||
#include "tvgCompressor.h"
|
||||
#include "tvgShapeImpl.h"
|
||||
#include "tvgPictureImpl.h"
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
source_file = [
|
||||
'tvgArray.h',
|
||||
'tvgBezier.h',
|
||||
'tvgLzw.h',
|
||||
'tvgCompressor.h',
|
||||
'tvgMath.h',
|
||||
'tvgStr.h',
|
||||
'tvgBezier.cpp',
|
||||
'tvgLzw.cpp',
|
||||
'tvgCompressor.cpp',
|
||||
'tvgMath.cpp',
|
||||
'tvgStr.cpp'
|
||||
]
|
||||
|
|
|
@ -56,15 +56,18 @@
|
|||
#include "config.h"
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Internal Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
#include <string>
|
||||
#include <memory.h>
|
||||
#include "tvgLzw.h"
|
||||
#include "tvgCompressor.h"
|
||||
|
||||
namespace tvg {
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* LZW Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
namespace {
|
||||
|
||||
//LZW Dictionary helper:
|
||||
constexpr int Nil = -1;
|
||||
|
@ -334,15 +337,8 @@ static bool outputSequence(const Dictionary& dict, int code, uint8_t*& output, i
|
|||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
namespace tvg {
|
||||
|
||||
uint8_t* lzwDecode(const uint8_t* compressed, uint32_t compressedSizeBytes, uint32_t compressedSizeBits, uint32_t uncompressedSizeBytes)
|
||||
{
|
||||
int code = Nil;
|
||||
|
@ -423,4 +419,57 @@ uint8_t* lzwEncode(const uint8_t* uncompressed, uint32_t uncompressedSizeBytes,
|
|||
return bitStream.release();
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* B64 Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
size_t b64Decode(const char* encoded, const size_t len, char** decoded)
|
||||
{
|
||||
static constexpr const char B64_INDEX[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57,
|
||||
58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||
};
|
||||
|
||||
|
||||
if (!decoded || !encoded || len == 0) return 0;
|
||||
|
||||
auto reserved = 3 * (1 + (len >> 2)) + 1;
|
||||
auto output = static_cast<char*>(malloc(reserved * sizeof(char)));
|
||||
if (!output) return 0;
|
||||
output[reserved - 1] = '\0';
|
||||
|
||||
size_t idx = 0;
|
||||
|
||||
while (*encoded && *(encoded + 1)) {
|
||||
if (*encoded <= 0x20) {
|
||||
++encoded;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto value1 = B64_INDEX[(size_t)encoded[0]];
|
||||
auto value2 = B64_INDEX[(size_t)encoded[1]];
|
||||
output[idx++] = (value1 << 2) + ((value2 & 0x30) >> 4);
|
||||
|
||||
if (!encoded[2] || encoded[2] == '=' || encoded[2] == '.') break;
|
||||
auto value3 = B64_INDEX[(size_t)encoded[2]];
|
||||
output[idx++] = ((value2 & 0x0f) << 4) + ((value3 & 0x3c) >> 2);
|
||||
|
||||
if (!encoded[3] || encoded[3] == '=' || encoded[3] == '.') break;
|
||||
auto value4 = B64_INDEX[(size_t)encoded[3]];
|
||||
output[idx++] = ((value3 & 0x03) << 6) + value4;
|
||||
encoded += 4;
|
||||
}
|
||||
*decoded = output;
|
||||
return reserved;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -20,8 +20,8 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _TVG_LZW_H_
|
||||
#define _TVG_LZW_H_
|
||||
#ifndef _TVG_COMPRESSOR_H_
|
||||
#define _TVG_COMPRESSOR_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
@ -29,6 +29,7 @@ namespace tvg
|
|||
{
|
||||
uint8_t* lzwEncode(const uint8_t* uncompressed, uint32_t uncompressedSizeBytes, uint32_t* compressedSizeBytes, uint32_t* compressedSizeBits);
|
||||
uint8_t* lzwDecode(const uint8_t* compressed, uint32_t compressedSizeBytes, uint32_t compressedSizeBits, uint32_t uncompressedSizeBytes);
|
||||
size_t b64Decode(const char* encoded, const size_t len, char** decoded);
|
||||
}
|
||||
|
||||
#endif //_TVG_LZW_H
|
||||
#endif //_TVG_COMPRESSOR_H_
|
Loading…
Add table
Reference in a new issue