Merge commit 'd028b28816b4508731479d5aa9bfb764a13dd533' into library-updates

This commit is contained in:
Leon Styhre 2023-08-05 11:32:11 +02:00
commit d0ae988d66
16 changed files with 10856 additions and 14 deletions

View file

@ -121,10 +121,10 @@ void EvasApp::run()
ecore_evas_shutdown();
}
static bool isJsonFile(const char *filename) {
static bool isLottiefile(const char *filename) {
const char *dot = strrchr(filename, '.');
if(!dot || dot == filename) return false;
return !strcmp(dot + 1, "json");
return !strcmp(dot + 1, "json") || !strcmp(dot + 1, "lottie");
}
std::vector<std::string>
@ -136,7 +136,7 @@ EvasApp::jsonFiles(const std::string &dirName, bool /*recurse*/)
d = opendir(dirName.c_str());
if (d) {
while ((dir = readdir(d)) != NULL) {
if (isJsonFile(dir->d_name))
if (isLottiefile(dir->d_name))
result.push_back(dirName + dir->d_name);
}
closedir(d);

Binary file not shown.

View file

@ -1,3 +1,4 @@
add_subdirectory(zip)
target_sources(rlottie
PRIVATE

View file

@ -836,7 +836,7 @@ renderer::ShapeLayer::ShapeLayer(model::Layer *layerData,
void renderer::ShapeLayer::updateContent()
{
mRoot->update(frameNo(), combinedMatrix(), combinedAlpha(), flag());
mRoot->update(frameNo(), combinedMatrix(), 1.0f , flag());
if (mLayerData->hasPathOperator()) {
mRoot->applyTrim();
@ -863,6 +863,27 @@ renderer::DrawableList renderer::ShapeLayer::renderList()
return {mDrawableList.data(), mDrawableList.size()};
}
void renderer::ShapeLayer::render(VPainter *painter, const VRle &inheritMask,
const VRle &matteRle, SurfaceCache &cache)
{
if (vIsZero(combinedAlpha())) return;
if (vCompare(combinedAlpha(), 1.0)) {
Layer::render(painter, inheritMask, matteRle, cache);
} else {
//do offscreen rendering
VSize size = painter->clipBoundingRect().size();
VPainter srcPainter;
VBitmap srcBitmap = cache.make_surface(size.width(), size.height());
srcPainter.begin(&srcBitmap);
Layer::render(&srcPainter, inheritMask, matteRle, cache);
srcPainter.end();
painter->drawBitmap(VPoint(), srcBitmap,
uint8_t(combinedAlpha() * 255.0f));
cache.release_surface(srcBitmap);
}
}
bool renderer::Group::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth,
LOTVariant &value)
{
@ -1284,9 +1305,9 @@ renderer::Stroke::Stroke(model::Stroke *data)
static vthread_local std::vector<float> Dash_Vector;
bool renderer::Stroke::updateContent(int frameNo, const VMatrix &matrix,
float alpha)
float)
{
auto combinedAlpha = alpha * mModel.opacity(frameNo);
auto combinedAlpha = mModel.opacity(frameNo);
auto color = mModel.color(frameNo).toColor(combinedAlpha);
VBrush brush(color);

View file

@ -319,6 +319,8 @@ public:
void buildLayerNode() final;
bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth,
LOTVariant &value) override;
void render(VPainter *painter, const VRle &mask, const VRle &matteRle,
SurfaceCache &cache) final;
protected:
void preprocessStage(const VRect &clip) final;

View file

@ -129,13 +129,19 @@ std::shared_ptr<model::Composition> model::loadFromFile(const std::string &path,
return {};
} else {
std::string content;
f.seekg(0, std::ios::end);
auto fsize = f.tellg();
//read the given file
content.reserve(fsize);
f.seekg(0, std::ios::beg);
content.assign((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
std::getline(f, content, '\0');
f.close();
if (content.empty()) return {};
if (fsize == 0) return {};
auto obj = internal::model::parse(const_cast<char *>(content.c_str()),
auto obj = internal::model::parse(const_cast<char *>(content.c_str()), fsize,
dirname(path));
if (obj && cachePolicy) ModelCache::instance().add(path, obj);
@ -153,7 +159,7 @@ std::shared_ptr<model::Composition> model::loadFromData(
if (obj) return obj;
}
auto obj = internal::model::parse(const_cast<char *>(jsonData.c_str()),
auto obj = internal::model::parse(const_cast<char *>(jsonData.c_str()), jsonData.size(),
std::move(resourcePath));
if (obj && cachePolicy) ModelCache::instance().add(key, obj);
@ -164,6 +170,6 @@ std::shared_ptr<model::Composition> model::loadFromData(
std::shared_ptr<model::Composition> model::loadFromData(
std::string jsonData, std::string resourcePath, model::ColorFilter filter)
{
return internal::model::parse(const_cast<char *>(jsonData.c_str()),
return internal::model::parse(const_cast<char *>(jsonData.c_str()), jsonData.size(),
std::move(resourcePath), std::move(filter));
}

View file

@ -1137,7 +1137,7 @@ std::shared_ptr<model::Composition> loadFromData(std::string jsonData,
std::string resourcePath,
ColorFilter filter);
std::shared_ptr<model::Composition> parse(char *str, std::string dir_path,
std::shared_ptr<model::Composition> parse(char *str, size_t length, std::string dir_path,
ColorFilter filter = {});
} // namespace model

View file

@ -57,6 +57,7 @@
#include "lottiemodel.h"
#include "rapidjson/document.h"
#include "zip/zip.h"
RAPIDJSON_DIAG_PUSH
#ifdef __GNUC__
@ -2365,11 +2366,54 @@ public:
#endif
static char* uncompressZip(const char * str, size_t length)
{
const char* errMsg = "Failed to unzip dotLottie!";
auto zip = zip_stream_open(str, length, 0, 'r');
if (!zip) {
vCritical << errMsg;
return nullptr;
}
//Read a representive animation
if (zip_entry_openbyindex(zip, 1)) {
vCritical << errMsg;
return nullptr;
}
char* buf = nullptr;
size_t bufSize;
zip_entry_read(zip, (void**)&buf, &bufSize);
zip_entry_close(zip);
zip_stream_close(zip);
return buf;
}
static bool checkDotLottie(const char * str)
{
//check the .Lottie signature.
if (str[0] == 0x50 && str[1] == 0x4B && str[2] == 0x03 && str[3] == 0x04) return true;
else return false;
}
std::shared_ptr<model::Composition> model::parse(char * str,
size_t length,
std::string dir_path,
model::ColorFilter filter)
{
LottieParserImpl obj(str, std::move(dir_path), std::move(filter));
auto input = str;
auto dotLottie = checkDotLottie(str);
if (dotLottie) {
input = uncompressZip(str, length);
}
LottieParserImpl obj(input, std::move(dir_path), std::move(filter));
if (dotLottie) free(input);
if (obj.VerifyType()) {
obj.parseComposition();

View file

@ -1,3 +1,4 @@
subdir('zip')
source_file = [
'lottieparser.cpp',

View file

@ -0,0 +1,9 @@
target_sources(rlottie
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/zip.cpp"
)
target_include_directories(rlottie
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}"
)

View file

@ -0,0 +1,9 @@
source_file = [
'zip.cpp'
]
zip_dep = [declare_dependency(
include_directories : include_directories('.'),
sources : source_file
)]

10130
external/rlottie/src/lottie/zip/miniz.h vendored Normal file

File diff suppressed because it is too large Load diff

451
external/rlottie/src/lottie/zip/zip.cpp vendored Normal file
View file

@ -0,0 +1,451 @@
/*
* 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 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.
*/
#define __STDC_WANT_LIB_EXT1__ 1
#include <errno.h>
#include <sys/stat.h>
#include <time.h>
#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \
defined(__MINGW32__)
/* Win32, DOS, MSVC, MSVS */
#include <direct.h>
#define STRCLONE(STR) ((STR) ? _strdup(STR) : NULL)
#define HAS_DEVICE(P) \
((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) && \
(P)[1] == ':')
#define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE(P) ? 2 : 0)
#else
#include <unistd.h> // needed for symlink()
#define STRCLONE(STR) ((STR) ? strdup(STR) : NULL)
#endif
#ifdef __MINGW32__
#include <sys/types.h>
#include <unistd.h>
#endif
#include "miniz.h"
#include "zip.h"
#ifdef _MSC_VER
#include <io.h>
#define ftruncate(fd, sz) (-(_chsize_s((fd), (sz)) != 0))
#define fileno _fileno
#endif
#if defined(__TINYC__) && (defined(_WIN32) || defined(_WIN64))
#include <io.h>
#define ftruncate(fd, sz) (-(_chsize_s((fd), (sz)) != 0))
#define fileno _fileno
#endif
#ifndef HAS_DEVICE
#define HAS_DEVICE(P) 0
#endif
#ifndef FILESYSTEM_PREFIX_LEN
#define FILESYSTEM_PREFIX_LEN(P) 0
#endif
#ifndef ISSLASH
#define ISSLASH(C) ((C) == '/' || (C) == '\\')
#endif
#define CLEANUP(ptr) \
do { \
if (ptr) { \
free((void *)ptr); \
ptr = NULL; \
} \
} while (0)
#define UNX_IFDIR 0040000 /* Unix directory */
#define UNX_IFREG 0100000 /* Unix regular file */
#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */
#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */
#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */
#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */
#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */
struct zip_entry_t {
ssize_t index;
char *name;
mz_uint64 uncomp_size;
mz_uint64 comp_size;
mz_uint32 uncomp_crc32;
mz_uint64 offset;
mz_uint8 header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
mz_uint64 header_offset;
mz_uint16 method;
mz_zip_writer_add_state state;
tdefl_compressor comp;
mz_uint32 external_attr;
time_t m_time;
};
struct zip_t {
mz_zip_archive archive;
mz_uint level;
struct zip_entry_t entry;
};
enum zip_modify_t {
MZ_KEEP = 0,
MZ_DELETE = 1,
MZ_MOVE = 2,
};
struct zip_entry_mark_t {
ssize_t file_index;
enum zip_modify_t type;
mz_uint64 m_local_header_ofs;
size_t lf_length;
};
static char *zip_strrpl(const char *str, size_t n, char oldchar, char newchar) {
char c;
size_t i;
char *rpl = (char *)calloc((1 + n), sizeof(char));
char *begin = rpl;
if (!rpl) {
return NULL;
}
for (i = 0; (i < n) && (c = *str++); ++i) {
if (c == oldchar) {
c = newchar;
}
*rpl++ = c;
}
return begin;
}
static int zip_archive_truncate(mz_zip_archive *pzip) {
mz_zip_internal_state *pState = pzip->m_pState;
mz_uint64 file_size = pzip->m_archive_size;
if ((pzip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) {
return 0;
}
if (pzip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED) {
if (pState->m_pFile) {
int fd = fileno(pState->m_pFile);
return ftruncate(fd, file_size);
}
}
return 0;
}
static inline void zip_archive_finalize(mz_zip_archive *pzip) {
mz_zip_writer_finalize_archive(pzip);
zip_archive_truncate(pzip);
}
int zip_entry_openbyindex(struct zip_t *zip, size_t index) {
mz_zip_archive *pZip = NULL;
mz_zip_archive_file_stat stats;
mz_uint namelen;
const mz_uint8 *pHeader;
const char *pFilename;
if (!zip) {
// zip_t handler is not initialized
return ZIP_ENOINIT;
}
pZip = &(zip->archive);
if (pZip->m_zip_mode != MZ_ZIP_MODE_READING) {
// open by index requires readonly mode
return ZIP_EINVMODE;
}
if (index >= (size_t)pZip->m_total_files) {
// index out of range
return ZIP_EINVIDX;
}
if (!(pHeader = &MZ_ZIP_ARRAY_ELEMENT(
&pZip->m_pState->m_central_dir, mz_uint8,
MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets,
mz_uint32, index)))) {
// cannot find header in central directory
return ZIP_ENOHDR;
}
namelen = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
/*
.ZIP File Format Specification Version: 6.3.3
4.4.17.1 The name of the file, with optional relative path.
The path stored MUST not contain a drive or
device letter, or a leading slash. All slashes
MUST be forward slashes '/' as opposed to
backwards slashes '\' for compatibility with Amiga
and UNIX file systems etc. If input came from standard
input, there is no file name field.
*/
if (zip->entry.name) {
CLEANUP(zip->entry.name);
}
#ifdef ZIP_RAW_ENTRYNAME
zip->entry.name = STRCLONE(pFilename);
#else
zip->entry.name = zip_strrpl(pFilename, namelen, '\\', '/');
#endif
if (!zip->entry.name) {
// local entry name is NULL
return ZIP_EINVENTNAME;
}
if (!mz_zip_reader_file_stat(pZip, (mz_uint)index, &stats)) {
return ZIP_ENOENT;
}
zip->entry.index = (ssize_t)index;
zip->entry.comp_size = stats.m_comp_size;
zip->entry.uncomp_size = stats.m_uncomp_size;
zip->entry.uncomp_crc32 = stats.m_crc32;
zip->entry.offset = stats.m_central_dir_ofs;
zip->entry.header_offset = stats.m_local_header_ofs;
zip->entry.method = stats.m_method;
zip->entry.external_attr = stats.m_external_attr;
#ifndef MINIZ_NO_TIME
zip->entry.m_time = stats.m_time;
#endif
return 0;
}
int zip_entry_close(struct zip_t *zip) {
mz_zip_archive *pzip = NULL;
mz_uint level;
tdefl_status done;
mz_uint16 entrylen;
mz_uint16 dos_time = 0, dos_date = 0;
int err = 0;
mz_uint8 *pExtra_data = NULL;
mz_uint32 extra_size = 0;
mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
if (!zip) {
// zip_t handler is not initialized
err = ZIP_ENOINIT;
goto cleanup;
}
pzip = &(zip->archive);
if (pzip->m_zip_mode == MZ_ZIP_MODE_READING) {
goto cleanup;
}
level = zip->level & 0xF;
if (level) {
done = tdefl_compress_buffer(&(zip->entry.comp), "", 0, TDEFL_FINISH);
if (done != TDEFL_STATUS_DONE && done != TDEFL_STATUS_OKAY) {
// Cannot flush compressed buffer
err = ZIP_ETDEFLBUF;
goto cleanup;
}
zip->entry.comp_size = zip->entry.state.m_comp_size;
zip->entry.offset = zip->entry.state.m_cur_archive_file_ofs;
zip->entry.method = MZ_DEFLATED;
}
entrylen = (mz_uint16)strlen(zip->entry.name);
#ifndef MINIZ_NO_TIME
mz_zip_time_t_to_dos_time(zip->entry.m_time, &dos_time, &dos_date);
#endif
MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
MZ_WRITE_LE32(local_dir_footer + 4, zip->entry.uncomp_crc32);
MZ_WRITE_LE64(local_dir_footer + 8, zip->entry.comp_size);
MZ_WRITE_LE64(local_dir_footer + 16, zip->entry.uncomp_size);
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, local_dir_footer,
local_dir_footer_size) != local_dir_footer_size) {
// Cannot write zip entry header
err = ZIP_EWRTHDR;
goto cleanup;
}
zip->entry.offset += local_dir_footer_size;
pExtra_data = extra_data;
extra_size = mz_zip_writer_create_zip64_extra_data(
extra_data,
(zip->entry.uncomp_size >= MZ_UINT32_MAX) ? &zip->entry.uncomp_size
: NULL,
(zip->entry.comp_size >= MZ_UINT32_MAX) ? &zip->entry.comp_size : NULL,
(zip->entry.header_offset >= MZ_UINT32_MAX) ? &zip->entry.header_offset
: NULL);
if ((entrylen) && (zip->entry.name[entrylen - 1] == '/') &&
!zip->entry.uncomp_size) {
/* Set DOS Subdirectory attribute bit. */
zip->entry.external_attr |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;
}
if (!mz_zip_writer_add_to_central_dir(
pzip, zip->entry.name, entrylen, pExtra_data, (mz_uint16)extra_size,
"", 0, zip->entry.uncomp_size, zip->entry.comp_size,
zip->entry.uncomp_crc32, zip->entry.method,
MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 |
MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR,
dos_time, dos_date, zip->entry.header_offset,
zip->entry.external_attr, NULL, 0)) {
// Cannot write to zip central dir
err = ZIP_EWRTDIR;
goto cleanup;
}
pzip->m_total_files++;
pzip->m_archive_size = zip->entry.offset;
cleanup:
if (zip) {
zip->entry.m_time = 0;
CLEANUP(zip->entry.name);
}
return err;
}
const char *zip_entry_name(struct zip_t *zip) {
if (!zip) {
// zip_t handler is not initialized
return NULL;
}
return zip->entry.name;
}
int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) {
mz_uint level;
mz_zip_archive *pzip = NULL;
tdefl_status status;
if (!zip) {
// zip_t handler is not initialized
return ZIP_ENOINIT;
}
pzip = &(zip->archive);
if (buf && bufsize > 0) {
zip->entry.uncomp_size += bufsize;
zip->entry.uncomp_crc32 = (mz_uint32)mz_crc32(
zip->entry.uncomp_crc32, (const mz_uint8 *)buf, bufsize);
level = zip->level & 0xF;
if (!level) {
if ((pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, buf,
bufsize) != bufsize)) {
// Cannot write buffer
return ZIP_EWRTENT;
}
zip->entry.offset += bufsize;
zip->entry.comp_size += bufsize;
} else {
status = tdefl_compress_buffer(&(zip->entry.comp), buf, bufsize,
TDEFL_NO_FLUSH);
if (status != TDEFL_STATUS_DONE && status != TDEFL_STATUS_OKAY) {
// Cannot compress buffer
return ZIP_ETDEFLBUF;
}
}
}
return 0;
}
ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize) {
mz_zip_archive *pzip = NULL;
mz_uint idx;
size_t size = 0;
if (!zip) {
// zip_t handler is not initialized
return (ssize_t)ZIP_ENOINIT;
}
pzip = &(zip->archive);
if (pzip->m_zip_mode != MZ_ZIP_MODE_READING ||
zip->entry.index < (ssize_t)0) {
// the entry is not found or we do not have read access
return (ssize_t)ZIP_ENOENT;
}
idx = (mz_uint)zip->entry.index;
if (mz_zip_reader_is_file_a_directory(pzip, idx)) {
// the entry is a directory
return (ssize_t)ZIP_EINVENTTYPE;
}
*buf = mz_zip_reader_extract_to_heap(pzip, idx, &size, 0);
if (*buf && bufsize) {
*bufsize = size;
}
return (ssize_t)size;
}
struct zip_t *zip_stream_open(const char *stream, size_t size, int level,
char mode) {
struct zip_t *zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t));
if (!zip) {
return NULL;
}
if (level < 0) {
level = MZ_DEFAULT_LEVEL;
}
if ((level & 0xF) > MZ_UBER_COMPRESSION) {
// Wrong compression level
goto cleanup;
}
zip->level = (mz_uint)level;
if ((stream != NULL) && (size > 0) && (mode == 'r')) {
if (!mz_zip_reader_init_mem(&(zip->archive), stream, size, 0)) {
goto cleanup;
}
} else if ((stream == NULL) && (size == 0) && (mode == 'w')) {
// Create a new archive.
if (!mz_zip_writer_init_heap(&(zip->archive), 0, 1024)) {
// Cannot initialize zip_archive writer
goto cleanup;
}
} else {
goto cleanup;
}
return zip;
cleanup:
CLEANUP(zip);
return NULL;
}
void zip_stream_close(struct zip_t *zip) {
if (zip) {
mz_zip_writer_end(&(zip->archive));
mz_zip_reader_end(&(zip->archive));
CLEANUP(zip);
}
}

156
external/rlottie/src/lottie/zip/zip.h vendored Normal file
View file

@ -0,0 +1,156 @@
/*
* 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 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.
*/
#pragma once
#ifndef ZIP_H
#define ZIP_H
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
// 64-bit Windows is the only mainstream platform
// where sizeof(long) != sizeof(void*)
#ifdef _WIN64
typedef long long ssize_t; /* byte count or error */
#else
typedef long ssize_t; /* byte count or error */
#endif
#endif
/**
* Default zip compression level.
*/
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
/**
* Error codes
*/
#define ZIP_ENOINIT -1 // not initialized
#define ZIP_EINVENTNAME -2 // invalid entry name
#define ZIP_ENOENT -3 // entry not found
#define ZIP_EINVMODE -4 // invalid zip mode
#define ZIP_EINVLVL -5 // invalid compression level
#define ZIP_ENOSUP64 -6 // no zip 64 support
#define ZIP_EMEMSET -7 // memset error
#define ZIP_EWRTENT -8 // cannot write data to entry
#define ZIP_ETDEFLINIT -9 // cannot initialize tdefl compressor
#define ZIP_EINVIDX -10 // invalid index
#define ZIP_ENOHDR -11 // header not found
#define ZIP_ETDEFLBUF -12 // cannot flush tdefl buffer
#define ZIP_ECRTHDR -13 // cannot create entry header
#define ZIP_EWRTHDR -14 // cannot write entry header
#define ZIP_EWRTDIR -15 // cannot write to central dir
#define ZIP_EOPNFILE -16 // cannot open file
#define ZIP_EINVENTTYPE -17 // invalid entry type
#define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation
#define ZIP_ENOFILE -19 // file not found
#define ZIP_ENOPERM -20 // no permission
#define ZIP_EOOMEM -21 // out of memory
#define ZIP_EINVZIPNAME -22 // invalid zip archive name
#define ZIP_EMKDIR -23 // make dir error
#define ZIP_ESYMLINK -24 // symlink error
#define ZIP_ECLSZIP -25 // close archive error
#define ZIP_ECAPSIZE -26 // capacity size too small
#define ZIP_EFSEEK -27 // fseek error
#define ZIP_EFREAD -28 // fread error
#define ZIP_EFWRITE -29 // fwrite error
/**
* @struct zip_t
*
* This data structure is used throughout the library to represent zip archive -
* forward declaration.
*/
struct zip_t;
/**
* Closes the zip archive, releases resources - always finalize.
*
* @param zip zip archive handler.
*/
void zip_close(struct zip_t *zip);
/**
* Opens a new entry by index in the zip archive.
*
* This function is only valid if zip archive was opened in 'r' (readonly) mode.
*
* @param zip zip archive handler.
* @param index index in local dictionary.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
int zip_entry_openbyindex(struct zip_t *zip, size_t index);
/**
* Closes a zip entry, flushes buffer and releases resources.
*
* @param zip zip archive handler.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
int zip_entry_close(struct zip_t *zip);
/**
* Returns a local name of the current zip entry.
*
* The main difference between user's entry name and local entry name
* is optional relative path.
* Following .ZIP File Format Specification - the path stored MUST not contain
* a drive or device letter, or a leading slash.
* All slashes MUST be forward slashes '/' as opposed to backwards slashes '\'
* for compatibility with Amiga and UNIX file systems etc.
*
* @param zip: zip archive handler.
*
* @return the pointer to the current zip entry name, or NULL on error.
*/
const char *zip_entry_name(struct zip_t *zip);
/**
* Extracts the current zip entry into output buffer.
*
* The function allocates sufficient memory for a output buffer.
*
* @param zip zip archive handler.
* @param buf output buffer.
* @param bufsize output buffer size (in bytes).
*
* @note remember to release memory allocated for a output buffer.
* for large entries, please take a look at zip_entry_extract function.
*
* @return the return code - the number of bytes actually read on success.
* Otherwise a negative number (< 0) on error.
*/
ssize_t zip_entry_read(struct zip_t *zip, void **buf,
size_t *bufsize);
/**
* Opens zip archive stream into memory.
*
* @param stream zip archive stream.
* @param size stream size.
*
* @return the zip archive handler or NULL on error
*/
struct zip_t *zip_stream_open(const char *stream, size_t size,
int level, char mode);
/**
* Close zip archive releases resources.
*
* @param zip zip archive handler.
*
* @return
*/
void zip_stream_close(struct zip_t *zip);
#endif

View file

@ -16,7 +16,7 @@ subdir('vector')
subdir('lottie')
subdir('binding')
rlottie_lib_dep = [ vector_dep, lottie_dep, binding_dep]
rlottie_lib_dep = [ vector_dep, zip_dep, lottie_dep, binding_dep]
if get_option('thread') == true
rlottie_lib_dep += dependency('threads')

View file

@ -420,6 +420,11 @@ using VTask = std::shared_ptr<VRleTask>;
#include <thread>
#include "vtaskqueue.h"
#ifdef __linux__
#include <pthread.h>
#include <sstream>
#endif
class RleTaskScheduler {
const unsigned _count{std::thread::hardware_concurrency()};
std::vector<std::thread> _threads;
@ -435,6 +440,13 @@ class RleTaskScheduler {
SW_FT_Stroker stroker;
SW_FT_Stroker_New(&stroker);
// Create Thread Name for Debugging (Linux)
#ifdef __linux__
std::ostringstream nameStream;
nameStream << "lottie-tsk-" << i;
pthread_setname_np(pthread_self(), nameStream.str().c_str());
#endif
// Task Loop
VTask task;
while (true) {