From: Hermet Park Date: Fri, 11 Jun 2021 06:08:40 +0000 (+0900) Subject: tvg_loader: code refactoring. X-Git-Tag: accepted/tizen/unified/20210628.031610~27 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b97d3bca5a00082c2e3f2dfd0441a3024d7921db;p=platform%2Fcore%2Fgraphics%2Ftizenvg.git tvg_loader: code refactoring. revise it under the tvg coding convention. --- diff --git a/meson_options.txt b/meson_options.txt index c6a7d0e..552bc47 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -6,7 +6,7 @@ option('engines', option('loaders', type: 'array', - choices: ['', 'svg', 'png'], + choices: ['', 'svg', 'tvg', 'png'], value: ['svg'], description: 'Enable File Loaders in thorvg') diff --git a/src/lib/meson.build b/src/lib/meson.build index 29cc361..4202714 100644 --- a/src/lib/meson.build +++ b/src/lib/meson.build @@ -14,6 +14,7 @@ source_file = [ 'tvgCanvasImpl.h', 'tvgCommon.h', 'tvgBezier.h', + 'tvgBinaryDesc.h', 'tvgFill.h', 'tvgLoader.h', 'tvgLoaderMgr.h', @@ -22,7 +23,6 @@ source_file = [ 'tvgSceneImpl.h', 'tvgShapeImpl.h', 'tvgTaskScheduler.h', - 'tvgTvgHelper.h', 'tvgBezier.cpp', 'tvgCanvas.cpp', 'tvgFill.cpp', diff --git a/src/lib/tvgTvgHelper.h b/src/lib/tvgBinaryDesc.h similarity index 86% rename from src/lib/tvgTvgHelper.h rename to src/lib/tvgBinaryDesc.h index 8ba9bdc..99c438c 100644 --- a/src/lib/tvgTvgHelper.h +++ b/src/lib/tvgBinaryDesc.h @@ -19,8 +19,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef _TVG_TVG_HELPER_H_ -#define _TVG_TVG_HELPER_H_ +#ifndef _TVG_BINARY_DESC_H_ +#define _TVG_BINARY_DESC_H_ // now only little endian #define _read_tvg_ui16(dst, src) memcpy(dst, (src), sizeof(uint16_t)) @@ -30,6 +30,7 @@ using TvgIndicator = uint8_t; using ByteCounter = uint32_t; using TvgFlag = uint8_t; + #define TVG_INDICATOR_SIZE sizeof(TvgIndicator) #define BYTE_COUNTER_SIZE sizeof(ByteCounter) #define TVG_FLAG_SIZE sizeof(TvgFlag) @@ -39,17 +40,25 @@ struct tvgBlock TvgIndicator type; ByteCounter length; const char* data; - const char* blockEnd; + const char* end; }; -#define TVG_HEADER_TVG_SIGN_CODE "TVG" -#define TVG_HEADER_TVG_VERSION_CODE "000" -#define TVG_HEADER_TVG_SIGN_CODE_LENGTH 3 -#define TVG_HEADER_TVG_VERSION_CODE_LENGTH 3 - -#define TVG_SCENE_BEGIN_INDICATOR (TvgIndicator)0xfe // Scene indicator -#define TVG_SHAPE_BEGIN_INDICATOR (TvgIndicator)0xfd // Shape indicator -#define TVG_PICTURE_BEGIN_INDICATOR (TvgIndicator)0xfc // Picture indicator +//TODO: replace it when this feature is completed. +#if 0 + #define TVG_BIN_HEADER_SIGNATURE "ThorVG" + #define TVG_BIN_HEADER_SIGNATURE_LENGTH 6 + #define TVG_BIN_HEADER_VERSION "000200" + #define TVG_BIN_HEADER_VERSION_LENGTH 6 +#else + #define TVG_BIN_HEADER_SIGNATURE "TVG" + #define TVG_BIN_HEADER_SIGNATURE_LENGTH 3 + #define TVG_BIN_HEADER_VERSION "000" + #define TVG_BIN_HEADER_VERSION_LENGTH 3 +#endif + +#define TVG_SCENE_BEGIN_INDICATOR (TvgIndicator)0xfe +#define TVG_SHAPE_BEGIN_INDICATOR (TvgIndicator)0xfd +#define TVG_PICTURE_BEGIN_INDICATOR (TvgIndicator)0xfc // Paint #define TVG_PAINT_OPACITY_INDICATOR (TvgIndicator)0x10 // Paint opacity @@ -100,4 +109,4 @@ struct tvgBlock // Picture #define TVG_RAW_IMAGE_BEGIN_INDICATOR (TvgIndicator)0x70 // Picture raw data -#endif //_TVG_TVG_HELPER_H_ +#endif //_TVG_BINARY_DESC_H_ diff --git a/src/loaders/meson.build b/src/loaders/meson.build index ac08dad..3ba004e 100644 --- a/src/loaders/meson.build +++ b/src/loaders/meson.build @@ -10,8 +10,12 @@ if get_option('loaders').contains('png') == true message('Enable PNG Loader') endif +if get_option('loaders').contains('tvg') == true + subdir('tvg') + message('Enable TVG Loader') +endif + subdir('raw') -subdir('tvg') loader_dep = declare_dependency( dependencies: subloader_dep, diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 8a73008..0755ff4 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -2630,6 +2630,8 @@ bool SvgLoader::header() bool SvgLoader::open(const char* data, uint32_t size) { + //TODO: verify memory leak if open() is called multiple times. + this->content = data; this->size = size; @@ -2639,22 +2641,20 @@ bool SvgLoader::open(const char* data, uint32_t size) bool SvgLoader::open(const string& path) { + //TODO: verify memory leak if open() is called multiple times. + ifstream f; f.open(path); - if (!f.is_open()) - { - //LOG: Failed to open file - return false; - } else { - getline(f, filePath, '\0'); - f.close(); + if (!f.is_open()) return false; - if (filePath.empty()) return false; + getline(f, filePath, '\0'); + f.close(); - this->content = filePath.c_str(); - this->size = filePath.size(); - } + if (filePath.empty()) return false; + + content = filePath.c_str(); + size = filePath.size(); return header(); } diff --git a/src/loaders/tvg/tvgTvgLoadParser.cpp b/src/loaders/tvg/tvgTvgLoadParser.cpp index e2face1..27131be 100644 --- a/src/loaders/tvg/tvgTvgLoadParser.cpp +++ b/src/loaders/tvg/tvgTvgLoadParser.cpp @@ -20,76 +20,85 @@ * SOFTWARE. */ -#include +#include #include "tvgTvgLoadParser.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + enum class LoaderResult { InvalidType, Success, SizeCorruption, MemoryCorruption, LogicalCorruption }; static LoaderResult _parsePaint(tvgBlock block, Paint ** paint); -static tvgBlock _readTvgBlock(const char *pointer) +static tvgBlock _readTvgBlock(const char *ptr) { tvgBlock block; - block.type = *pointer; - _read_tvg_ui32(&block.length, pointer + TVG_INDICATOR_SIZE); - block.data = pointer + TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE; - block.blockEnd = block.data + block.length; + block.type = *ptr; + _read_tvg_ui32(&block.length, ptr + TVG_INDICATOR_SIZE); + block.data = ptr + TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE; + block.end = block.data + block.length; return block; } -static bool _readTvgHeader(const char **pointer) +static bool _readTvgHeader(const char **ptr) { - // Sign phase, always "TVG" declared in TVG_HEADER_TVG_SIGN_CODE - if (memcmp(*pointer, TVG_HEADER_TVG_SIGN_CODE, TVG_HEADER_TVG_SIGN_CODE_LENGTH)) return false; - *pointer += TVG_HEADER_TVG_SIGN_CODE_LENGTH; // move after sing code + //Sign phase, always TVG_BIN_HEADER_SIGNATURE is declared + if (memcmp(*ptr, TVG_BIN_HEADER_SIGNATURE, TVG_BIN_HEADER_SIGNATURE_LENGTH)) return false; + *ptr += TVG_BIN_HEADER_SIGNATURE_LENGTH; - // Standard version number, declared in TVG_HEADER_TVG_VERSION_CODE - if (memcmp(*pointer, TVG_HEADER_TVG_VERSION_CODE, TVG_HEADER_TVG_VERSION_CODE_LENGTH)) return false; - *pointer += TVG_HEADER_TVG_VERSION_CODE_LENGTH; // move after version code + //Version number, declared in TVG_BIN_HEADER_VERSION + if (memcmp(*ptr, TVG_BIN_HEADER_VERSION, TVG_BIN_HEADER_VERSION_LENGTH)) return false; + *ptr += TVG_BIN_HEADER_VERSION_LENGTH; - // Matadata phase - uint16_t meta_length; // Matadata phase length - _read_tvg_ui16(&meta_length, *pointer); - *pointer += 2; // move after length + //Mata data for proof? + uint16_t metaLen; + _read_tvg_ui16(&metaLen, *ptr); + *ptr += 2; + +//Meta data... Necessary? #ifdef THORVG_LOG_ENABLED - char metadata[meta_length + 1]; - memcpy(metadata, *pointer, meta_length); - metadata[meta_length] = '\0'; - printf("TVG_LOADER: Header is valid, metadata[%d]: %s.\n", meta_length, metadata); + char metadata[metaLen + 1]; + memcpy(metadata, *ptr, metaLen); + metadata[metaLen] = '\0'; + printf("TVG_LOADER: Header is valid, metadata[%d]: %s.\n", metaLen, metadata); #endif - *pointer += meta_length; + *ptr += metaLen; + return true; } -// Paint -static LoaderResult _parseCmpTarget(const char *pointer, const char *end, Paint *paint) + +static LoaderResult _parseCmpTarget(const char *ptr, const char *end, Paint *paint) { - auto block = _readTvgBlock(pointer); - if (block.blockEnd > end) return LoaderResult::SizeCorruption; + auto block = _readTvgBlock(ptr); + if (block.end > end) return LoaderResult::SizeCorruption; CompositeMethod cmpMethod; if (block.type != TVG_PAINT_CMP_METHOD_INDICATOR) return LoaderResult::LogicalCorruption; if (block.length != sizeof(TvgFlag)) return LoaderResult::SizeCorruption; - switch (*block.data) - { - case TVG_PAINT_CMP_METHOD_CLIPPATH_FLAG: + switch (*block.data) { + case TVG_PAINT_CMP_METHOD_CLIPPATH_FLAG: { cmpMethod = CompositeMethod::ClipPath; break; - case TVG_PAINT_CMP_METHOD_ALPHAMASK_FLAG: + } + case TVG_PAINT_CMP_METHOD_ALPHAMASK_FLAG: { cmpMethod = CompositeMethod::AlphaMask; break; - case TVG_PAINT_CMP_METHOD_INV_ALPHAMASK_FLAG: + } + case TVG_PAINT_CMP_METHOD_INV_ALPHAMASK_FLAG: { cmpMethod = CompositeMethod::InvAlphaMask; break; - default: - return LoaderResult::LogicalCorruption; + } + default: return LoaderResult::LogicalCorruption; } - pointer = block.blockEnd; - auto block_paint = _readTvgBlock(pointer); - if (block_paint.blockEnd > end) return LoaderResult::SizeCorruption; + ptr = block.end; + auto block_paint = _readTvgBlock(ptr); + if (block_paint.end > end) return LoaderResult::SizeCorruption; Paint* cmpTarget; auto result = _parsePaint(block_paint, &cmpTarget); @@ -99,40 +108,35 @@ static LoaderResult _parseCmpTarget(const char *pointer, const char *end, Paint return LoaderResult::Success; } + static LoaderResult _parsePaintProperty(tvgBlock block, Paint *paint) { - switch (block.type) - { - case TVG_PAINT_OPACITY_INDICATOR: - { // opacity + switch (block.type) { + case TVG_PAINT_OPACITY_INDICATOR: { if (block.length != sizeof(uint8_t)) return LoaderResult::SizeCorruption; paint->opacity(*block.data); return LoaderResult::Success; } - case TVG_PAINT_TRANSFORM_MATRIX_INDICATOR: - { // transform matrix + case TVG_PAINT_TRANSFORM_MATRIX_INDICATOR: { if (block.length != sizeof(Matrix)) return LoaderResult::SizeCorruption; Matrix matrix; memcpy(&matrix, block.data, sizeof(Matrix)); if (paint->transform(matrix) != Result::Success) return LoaderResult::MemoryCorruption; return LoaderResult::Success; } - case TVG_PAINT_CMP_TARGET_INDICATOR: - { // cmp target + case TVG_PAINT_CMP_TARGET_INDICATOR: { if (block.length < TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE) return LoaderResult::SizeCorruption; - return _parseCmpTarget(block.data, block.blockEnd, paint); + return _parseCmpTarget(block.data, block.end, paint); } } return LoaderResult::InvalidType; } -// Scene + static LoaderResult _parseSceneProperty(tvgBlock block, Scene *scene) { - switch (block.type) - { - case TVG_SCENE_FLAG_RESERVEDCNT: - { + switch (block.type) { + case TVG_SCENE_FLAG_RESERVEDCNT: { if (block.length != sizeof(uint32_t)) return LoaderResult::SizeCorruption; uint32_t reservedCnt; _read_tvg_ui32(&reservedCnt, block.data); @@ -151,104 +155,100 @@ static LoaderResult _parseSceneProperty(tvgBlock block, Scene *scene) return result; } -// Shape -static LoaderResult _parseShapePath(const char *pointer, const char *end, Shape *shape) + +static LoaderResult _parseShapePath(const char *ptr, const char *end, Shape *shape) { - // ShapePath + //Shape Path uint32_t cmdCnt, ptsCnt; - _read_tvg_ui32(&cmdCnt, pointer); - pointer += sizeof(uint32_t); - _read_tvg_ui32(&ptsCnt, pointer); - pointer += sizeof(uint32_t); + _read_tvg_ui32(&cmdCnt, ptr); + ptr += sizeof(uint32_t); + _read_tvg_ui32(&ptsCnt, ptr); + ptr += sizeof(uint32_t); - const PathCommand* cmds = (PathCommand*) pointer; - pointer += sizeof(PathCommand) * cmdCnt; - const Point* pts = (Point*) pointer; - pointer += sizeof(Point) * ptsCnt; + const PathCommand* cmds = (PathCommand*) ptr; + ptr += sizeof(PathCommand) * cmdCnt; + const Point* pts = (Point*) ptr; + ptr += sizeof(Point) * ptsCnt; - if (pointer > end) return LoaderResult::SizeCorruption; + if (ptr > end) return LoaderResult::SizeCorruption; shape->appendPath(cmds, cmdCnt, pts, ptsCnt); return LoaderResult::Success; } -static LoaderResult _parseShapeFill(const char *pointer, const char *end, Fill **fillOutside) + +static LoaderResult _parseShapeFill(const char *ptr, const char *end, Fill **fillOutside) { unique_ptr fillGrad; - while (pointer < end) - { - auto block = _readTvgBlock(pointer); - if (block.blockEnd > end) return LoaderResult::SizeCorruption; + while (ptr < end) { + auto block = _readTvgBlock(ptr); + if (block.end > end) return LoaderResult::SizeCorruption; - switch (block.type) - { - case TVG_FILL_RADIAL_GRADIENT_INDICATOR: - { // radial gradient + switch (block.type) { + case TVG_FILL_RADIAL_GRADIENT_INDICATOR: { if (block.length != 3 * sizeof(float)) return LoaderResult::SizeCorruption; - const char* pointer = block.data; + auto ptr = block.data; float x, y, radius; - _read_tvg_float(&x, pointer); - pointer += sizeof(float); - _read_tvg_float(&y, pointer); - pointer += sizeof(float); - _read_tvg_float(&radius, pointer); + _read_tvg_float(&x, ptr); + ptr += sizeof(float); + _read_tvg_float(&y, ptr); + ptr += sizeof(float); + _read_tvg_float(&radius, ptr); auto fillGradRadial = RadialGradient::gen(); fillGradRadial->radial(x, y, radius); fillGrad = move(fillGradRadial); break; } - case TVG_FILL_LINEAR_GRADIENT_INDICATOR: - { // linear gradient + case TVG_FILL_LINEAR_GRADIENT_INDICATOR: { if (block.length != 4 * sizeof(float)) return LoaderResult::SizeCorruption; - const char* pointer = block.data; + auto ptr = block.data; float x1, y1, x2, y2; - _read_tvg_float(&x1, pointer); - pointer += sizeof(float); - _read_tvg_float(&y1, pointer); - pointer += sizeof(float); - _read_tvg_float(&x2, pointer); - pointer += sizeof(float); - _read_tvg_float(&y2, pointer); + _read_tvg_float(&x1, ptr); + ptr += sizeof(float); + _read_tvg_float(&y1, ptr); + ptr += sizeof(float); + _read_tvg_float(&x2, ptr); + ptr += sizeof(float); + _read_tvg_float(&y2, ptr); auto fillGradLinear = LinearGradient::gen(); fillGradLinear->linear(x1, y1, x2, y2); fillGrad = move(fillGradLinear); break; } - case TVG_FILL_FILLSPREAD_INDICATOR: - { // fill spread + case TVG_FILL_FILLSPREAD_INDICATOR: { if (!fillGrad) return LoaderResult::LogicalCorruption; if (block.length != sizeof(TvgFlag)) return LoaderResult::SizeCorruption; - switch (*block.data) - { - case TVG_FILL_FILLSPREAD_PAD_FLAG: + switch (*block.data) { + case TVG_FILL_FILLSPREAD_PAD_FLAG: { fillGrad->spread(FillSpread::Pad); break; - case TVG_FILL_FILLSPREAD_REFLECT_FLAG: + } + case TVG_FILL_FILLSPREAD_REFLECT_FLAG: { fillGrad->spread(FillSpread::Reflect); break; - case TVG_FILL_FILLSPREAD_REPEAT_FLAG: + } + case TVG_FILL_FILLSPREAD_REPEAT_FLAG: { fillGrad->spread(FillSpread::Repeat); break; + } } break; } - case TVG_FILL_COLORSTOPS_INDICATOR: - { // color stops + case TVG_FILL_COLORSTOPS_INDICATOR: { if (!fillGrad) return LoaderResult::LogicalCorruption; if (block.length == 0 || block.length & 0x07) return LoaderResult::SizeCorruption; uint32_t stopsCnt = block.length >> 3; // 8 bytes per ColorStop if (stopsCnt > 1023) return LoaderResult::SizeCorruption; Fill::ColorStop stops[stopsCnt]; - const char* p = block.data; - for (uint32_t i = 0; i < stopsCnt; i++, p += 8) - { + auto p = block.data; + for (uint32_t i = 0; i < stopsCnt; i++, p += 8) { _read_tvg_float(&stops[i].offset, p); stops[i].r = p[4]; stops[i].g = p[5]; @@ -259,42 +259,38 @@ static LoaderResult _parseShapeFill(const char *pointer, const char *end, Fill * break; } } - - pointer = block.blockEnd; + ptr = block.end; } - *fillOutside = fillGrad.release(); return LoaderResult::Success; } -static LoaderResult _parseShapeStrokeDashPattern(const char *pointer, const char *end, Shape *shape) + +static LoaderResult _parseShapeStrokeDashPattern(const char *ptr, const char *end, Shape *shape) { uint32_t dashPatternCnt; - _read_tvg_ui32(&dashPatternCnt, pointer); - pointer += sizeof(uint32_t); - const float* dashPattern = (float*) pointer; - pointer += sizeof(float) * dashPatternCnt; + _read_tvg_ui32(&dashPatternCnt, ptr); + ptr += sizeof(uint32_t); + const float* dashPattern = (float*) ptr; + ptr += sizeof(float) * dashPatternCnt; - if (pointer > end) return LoaderResult::SizeCorruption; + if (ptr > end) return LoaderResult::SizeCorruption; shape->stroke(dashPattern, dashPatternCnt); return LoaderResult::Success; } -static LoaderResult _parseShapeStroke(const char *pointer, const char *end, Shape *shape) + +static LoaderResult _parseShapeStroke(const char *ptr, const char *end, Shape *shape) { - while (pointer < end) - { - auto block = _readTvgBlock(pointer); - if (block.blockEnd > end) return LoaderResult::SizeCorruption; - - switch (block.type) - { - case TVG_SHAPE_STROKE_CAP_INDICATOR: - { // stroke cap + while (ptr < end) { + auto block = _readTvgBlock(ptr); + if (block.end > end) return LoaderResult::SizeCorruption; + + switch (block.type) { + case TVG_SHAPE_STROKE_CAP_INDICATOR: { if (block.length != sizeof(TvgFlag)) return LoaderResult::SizeCorruption; - switch (*block.data) - { + switch (*block.data) { case TVG_SHAPE_STROKE_CAP_SQUARE_FLAG: shape->stroke(StrokeCap::Square); break; @@ -307,11 +303,9 @@ static LoaderResult _parseShapeStroke(const char *pointer, const char *end, Shap } break; } - case TVG_SHAPE_STROKE_JOIN_INDICATOR: - { // stroke join + case TVG_SHAPE_STROKE_JOIN_INDICATOR: { if (block.length != sizeof(TvgFlag)) return LoaderResult::SizeCorruption; - switch (*block.data) - { + switch (*block.data) { case TVG_SHAPE_STROKE_JOIN_BEVEL_FLAG: shape->stroke(StrokeJoin::Bevel); break; @@ -324,77 +318,65 @@ static LoaderResult _parseShapeStroke(const char *pointer, const char *end, Shap } break; } - case TVG_SHAPE_STROKE_WIDTH_INDICATOR: - { // stroke width + case TVG_SHAPE_STROKE_WIDTH_INDICATOR: { if (block.length != sizeof(float)) return LoaderResult::SizeCorruption; float width; _read_tvg_float(&width, block.data); shape->stroke(width); break; } - case TVG_SHAPE_STROKE_COLOR_INDICATOR: - { // stroke color + case TVG_SHAPE_STROKE_COLOR_INDICATOR: { if (block.length != 4) return LoaderResult::SizeCorruption; shape->stroke(block.data[0], block.data[1], block.data[2], block.data[3]); break; } - case TVG_SHAPE_STROKE_FILL_INDICATOR: - { // stroke fill + case TVG_SHAPE_STROKE_FILL_INDICATOR: { Fill* fill; - auto result = _parseShapeFill(block.data, block.blockEnd, &fill); + auto result = _parseShapeFill(block.data, block.end, &fill); if (result != LoaderResult::Success) return result; shape->stroke(unique_ptr < Fill > (fill)); break; } - case TVG_SHAPE_STROKE_DASHPTRN_INDICATOR: - { // dashed stroke - auto result = _parseShapeStrokeDashPattern(block.data, block.blockEnd, shape); + case TVG_SHAPE_STROKE_DASHPTRN_INDICATOR: { + auto result = _parseShapeStrokeDashPattern(block.data, block.end, shape); if (result != LoaderResult::Success) return result; break; } } - - pointer = block.blockEnd; + ptr = block.end; } - return LoaderResult::Success; } + static LoaderResult _parseShapeProperty(tvgBlock block, Shape *shape) { - switch (block.type) - { - case TVG_SHAPE_PATH_INDICATOR: - { // path - auto result = _parseShapePath(block.data, block.blockEnd, shape); + switch (block.type) { + case TVG_SHAPE_PATH_INDICATOR: { + auto result = _parseShapePath(block.data, block.end, shape); if (result != LoaderResult::Success) return result; break; } - case TVG_SHAPE_STROKE_INDICATOR: - { // stroke section - auto result = _parseShapeStroke(block.data, block.blockEnd, shape); + case TVG_SHAPE_STROKE_INDICATOR: { + auto result = _parseShapeStroke(block.data, block.end, shape); if (result != LoaderResult::Success) return result; break; } - case TVG_SHAPE_FILL_INDICATOR: - { // fill (gradient) + case TVG_SHAPE_FILL_INDICATOR: { Fill* fill; - auto result = _parseShapeFill(block.data, block.blockEnd, &fill); + auto result = _parseShapeFill(block.data, block.end, &fill); if (result != LoaderResult::Success) return result; shape->fill(unique_ptr < Fill > (fill)); break; } - case TVG_SHAPE_COLOR_INDICATOR: - { // color + case TVG_SHAPE_COLOR_INDICATOR: { if (block.length != 4) return LoaderResult::SizeCorruption; shape->fill(block.data[0], block.data[1], block.data[2], block.data[3]); break; } - case TVG_SHAPE_FILLRULE_INDICATOR: - { // fill rule + case TVG_SHAPE_FILLRULE_INDICATOR: { if (block.length != sizeof(TvgFlag)) return LoaderResult::SizeCorruption; - switch (*block.data) - { + switch (*block.data) { case TVG_SHAPE_FILLRULE_WINDING_FLAG: shape->fill(FillRule::Winding); break; @@ -404,36 +386,30 @@ static LoaderResult _parseShapeProperty(tvgBlock block, Shape *shape) } break; } - default: - { - return LoaderResult::InvalidType; - } + default: return LoaderResult::InvalidType; } - return LoaderResult::Success; } -// Picture + static LoaderResult _parsePicture(tvgBlock block, Picture *picture) { - switch (block.type) - { - case TVG_RAW_IMAGE_BEGIN_INDICATOR: - { + switch (block.type) { + case TVG_RAW_IMAGE_BEGIN_INDICATOR: { if (block.length < 2*sizeof(uint32_t)) return LoaderResult::SizeCorruption; - const char* pointer = block.data; + const char* ptr = block.data; uint32_t w, h; - _read_tvg_ui32(&w, pointer); - pointer += sizeof(uint32_t); - _read_tvg_ui32(&h, pointer); - pointer += sizeof(uint32_t); + _read_tvg_ui32(&w, ptr); + ptr += sizeof(uint32_t); + _read_tvg_ui32(&h, ptr); + ptr += sizeof(uint32_t); uint32_t size = w * h * sizeof(uint32_t); if (block.length != 2*sizeof(uint32_t) + size) return LoaderResult::SizeCorruption; - uint32_t* pixels = (uint32_t*) pointer; + uint32_t* pixels = (uint32_t*) ptr; picture->load(pixels, w, h, true); return LoaderResult::Success; } @@ -452,97 +428,87 @@ static LoaderResult _parsePicture(tvgBlock block, Picture *picture) static LoaderResult _parsePaint(tvgBlock base_block, Paint **paint) { - switch (base_block.type) - { - case TVG_SCENE_BEGIN_INDICATOR: - { + switch (base_block.type) { + case TVG_SCENE_BEGIN_INDICATOR: { auto s = Scene::gen(); - const char* pointer = base_block.data; - while (pointer < base_block.blockEnd) - { - auto block = _readTvgBlock(pointer); - if (block.blockEnd > base_block.blockEnd) return LoaderResult::SizeCorruption; + auto ptr = base_block.data; + while (ptr < base_block.end) { + auto block = _readTvgBlock(ptr); + if (block.end > base_block.end) return LoaderResult::SizeCorruption; auto result = _parseSceneProperty(block, s.get()); if (result == LoaderResult::InvalidType) result = _parsePaintProperty(block, s.get()); - if (result > LoaderResult::Success) - { - // LOG: tvg parsing error + if (result > LoaderResult::Success) { #ifdef THORVG_LOG_ENABLED printf("TVG_LOADER: Loading scene error[type: 0x%02x]: %d\n", (int) block.type, (int) result); #endif return result; } - pointer = block.blockEnd; + ptr = block.end; } *paint = s.release(); break; } - case TVG_SHAPE_BEGIN_INDICATOR: - { + case TVG_SHAPE_BEGIN_INDICATOR: { auto s = Shape::gen(); - const char* pointer = base_block.data; - while (pointer < base_block.blockEnd) - { - auto block = _readTvgBlock(pointer); - if (block.blockEnd > base_block.blockEnd) return LoaderResult::SizeCorruption; + auto ptr = base_block.data; + while (ptr < base_block.end) { + auto block = _readTvgBlock(ptr); + if (block.end > base_block.end) return LoaderResult::SizeCorruption; auto result = _parseShapeProperty(block, s.get()); if (result == LoaderResult::InvalidType) result = _parsePaintProperty(block, s.get()); - if (result > LoaderResult::Success) - { - // LOG: tvg parsing error + if (result > LoaderResult::Success) { #ifdef THORVG_LOG_ENABLED printf("TVG_LOADER: Loading shape error[type: 0x%02x]: %d\n", (int) block.type, (int) result); #endif return result; } - pointer = block.blockEnd; + ptr = block.end; } *paint = s.release(); break; } - case TVG_PICTURE_BEGIN_INDICATOR: - { + case TVG_PICTURE_BEGIN_INDICATOR: { auto s = Picture::gen(); - const char* pointer = base_block.data; - while (pointer < base_block.blockEnd) - { - auto block = _readTvgBlock(pointer); - if (block.blockEnd > base_block.blockEnd) return LoaderResult::SizeCorruption; + auto ptr = base_block.data; + while (ptr < base_block.end) { + auto block = _readTvgBlock(ptr); + if (block.end > base_block.end) return LoaderResult::SizeCorruption; auto result = _parsePicture(block, s.get()); if (result == LoaderResult::InvalidType) result = _parsePaintProperty(block, s.get()); - if (result > LoaderResult::Success) - { - // LOG: tvg parsing error + if (result > LoaderResult::Success) { #ifdef THORVG_LOG_ENABLED printf("TVG_LOADER: Loading picture error[type: 0x%02x]: %d\n", (int) block.type, (int) result); #endif return result; } - pointer = block.blockEnd; + ptr = block.end; } *paint = s.release(); break; } - default: - return LoaderResult::InvalidType; + default: return LoaderResult::InvalidType; } return LoaderResult::Success; } -unique_ptr tvgParseTvgFile(const char *pointer, uint32_t size) + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +unique_ptr tvgLoadTvgData(const char *ptr, uint32_t size) { - const char* end = pointer + size; - if (!_readTvgHeader(&pointer) || pointer >= end) - { - // LOG: Header is improper + auto end = ptr + size; + + if (!_readTvgHeader(&ptr) || ptr >= end) { #ifdef THORVG_LOG_ENABLED - printf("TVG_LOADER: Header is improper.\n"); + printf("TVG_LOADER: Invalid TVG Data!\n"); #endif return nullptr; } @@ -551,10 +517,10 @@ unique_ptr tvgParseTvgFile(const char *pointer, uint32_t size) if (!scene) return nullptr; Paint* paint; - while (pointer < end) - { - auto block = _readTvgBlock(pointer); - if (block.blockEnd > end) return nullptr; + + while (ptr < end) { + auto block = _readTvgBlock(ptr); + if (block.end > end) return nullptr; auto result = _parsePaint(block, &paint); if (result > LoaderResult::Success) return nullptr; @@ -563,13 +529,8 @@ unique_ptr tvgParseTvgFile(const char *pointer, uint32_t size) return nullptr; } } - - pointer = block.blockEnd; + ptr = block.end; } - // LOG: File parsed correctly -#ifdef THORVG_LOG_ENABLED - printf("TVG_LOADER: File parsed correctly.\n"); -#endif return move(scene); -} +} \ No newline at end of file diff --git a/src/loaders/tvg/tvgTvgLoadParser.h b/src/loaders/tvg/tvgTvgLoadParser.h index 7124cf1..b976ef5 100644 --- a/src/loaders/tvg/tvgTvgLoadParser.h +++ b/src/loaders/tvg/tvgTvgLoadParser.h @@ -24,8 +24,8 @@ #define _TVG_TVG_LOAD_PARSER_H_ #include "tvgCommon.h" -#include "tvgTvgHelper.h" +#include "tvgBinaryDesc.h" -unique_ptr tvgParseTvgFile(const char *pointer, uint32_t size); +unique_ptr tvgLoadTvgData(const char *ptr, uint32_t size); #endif //_TVG_TVG_LOAD_PARSER_H_ diff --git a/src/loaders/tvg/tvgTvgLoader.cpp b/src/loaders/tvg/tvgTvgLoader.cpp index 75da124..0193ce2 100644 --- a/src/loaders/tvg/tvgTvgLoader.cpp +++ b/src/loaders/tvg/tvgTvgLoader.cpp @@ -21,48 +21,50 @@ */ #include -#include #include "tvgLoaderMgr.h" #include "tvgTvgLoader.h" #include "tvgTvgLoadParser.h" -TvgLoader::~TvgLoader() -{ - close(); -} + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ void TvgLoader::clearBuffer() { - size = 0; free(buffer); + size = 0; buffer = nullptr; pointer = nullptr; } + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +TvgLoader::~TvgLoader() +{ + close(); +} + + bool TvgLoader::open(const string &path) { + //TODO: verify memory leak if open() is called multiple times. + ifstream f; f.open(path, ifstream::in | ifstream::binary | ifstream::ate); - if (!f.is_open()) - { -#ifdef THORVG_LOG_ENABLED - printf("TVG_LOADER: Failed to open file\n"); -#endif - return false; - } + if (!f.is_open()) return false; size = f.tellg(); f.seekg(0, ifstream::beg); - buffer = (char*) malloc(size); - if (!buffer) - { + buffer = (char*)malloc(size); + if (!buffer) { size = 0; f.close(); -#ifdef THORVG_LOG_ENABLED - printf("TVG_LOADER: Failed to alloc buffer\n"); -#endif return false; } @@ -77,13 +79,20 @@ bool TvgLoader::open(const string &path) pointer = buffer; + //FIXME: verify TVG format here. + return true; } bool TvgLoader::open(const char *data, uint32_t size) { + //TODO: verify memory leak if open() is called multiple times. + pointer = data; size = size; + + //FIXME: verify TVG format here. + return true; } @@ -106,15 +115,8 @@ bool TvgLoader::close() void TvgLoader::run(unsigned tid) { if (root) root.reset(); - root = tvgParseTvgFile(pointer, size); - - if (!root) - { -#ifdef THORVG_LOG_ENABLED - printf("TVG_LOADER: File parsing error\n"); -#endif - clearBuffer(); - } + root = tvgLoadTvgData(pointer, size); + if (!root) clearBuffer(); } unique_ptr TvgLoader::scene() @@ -122,4 +124,4 @@ unique_ptr TvgLoader::scene() this->done(); if (root) return move(root); return nullptr; -} +} \ No newline at end of file diff --git a/src/loaders/tvg/tvgTvgLoader.h b/src/loaders/tvg/tvgTvgLoader.h index 4b02c1d..3c6c72f 100644 --- a/src/loaders/tvg/tvgTvgLoader.h +++ b/src/loaders/tvg/tvgTvgLoader.h @@ -23,7 +23,6 @@ #ifndef _TVG_TVG_LOADER_H_ #define _TVG_TVG_LOADER_H_ -#include "tvgLoader.h" #include "tvgTaskScheduler.h" class TvgLoader : public Loader, public Task @@ -33,14 +32,13 @@ public: const char* pointer = nullptr; uint32_t size = 0; - unique_ptr root; + unique_ptr root = nullptr; ~TvgLoader(); using Loader::open; bool open(const string &path) override; bool open(const char *data, uint32_t size) override; - bool read() override; bool close() override;