tvg_loader: code refactoring.
authorHermet Park <chuneon.park@samsung.com>
Fri, 11 Jun 2021 06:08:40 +0000 (15:08 +0900)
committerHermet Park <chuneon.park@samsung.com>
Mon, 14 Jun 2021 03:51:21 +0000 (12:51 +0900)
revise it under the tvg coding convention.

meson_options.txt
src/lib/meson.build
src/lib/tvgBinaryDesc.h [moved from src/lib/tvgTvgHelper.h with 86% similarity]
src/loaders/meson.build
src/loaders/svg/tvgSvgLoader.cpp
src/loaders/tvg/tvgTvgLoadParser.cpp
src/loaders/tvg/tvgTvgLoadParser.h
src/loaders/tvg/tvgTvgLoader.cpp
src/loaders/tvg/tvgTvgLoader.h

index c6a7d0e..552bc47 100644 (file)
@@ -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')
 
index 29cc361..4202714 100644 (file)
@@ -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',
similarity index 86%
rename from src/lib/tvgTvgHelper.h
rename to src/lib/tvgBinaryDesc.h
index 8ba9bdc..99c438c 100644 (file)
@@ -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_
index ac08dad..3ba004e 100644 (file)
@@ -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,
index 8a73008..0755ff4 100644 (file)
@@ -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();
 }
index e2face1..27131be 100644 (file)
  * SOFTWARE.
  */
 
-#include <string.h>
+#include <memory.h>
 #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<Fill> 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<Scene> tvgParseTvgFile(const char *pointer, uint32_t size)
+
+/************************************************************************/
+/* External Class Implementation                                        */
+/************************************************************************/
+
+unique_ptr<Scene> 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<Scene> 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<Scene> 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
index 7124cf1..b976ef5 100644 (file)
@@ -24,8 +24,8 @@
 #define _TVG_TVG_LOAD_PARSER_H_
 
 #include "tvgCommon.h"
-#include "tvgTvgHelper.h"
+#include "tvgBinaryDesc.h"
 
-unique_ptr<Scene> tvgParseTvgFile(const char *pointer, uint32_t size);
+unique_ptr<Scene> tvgLoadTvgData(const char *ptr, uint32_t size);
 
 #endif //_TVG_TVG_LOAD_PARSER_H_
index 75da124..0193ce2 100644 (file)
  */
 
 #include <fstream>
-#include <string.h>
 #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<Scene> TvgLoader::scene()
@@ -122,4 +124,4 @@ unique_ptr<Scene> TvgLoader::scene()
     this->done();
     if (root) return move(root);
     return nullptr;
-}
+}
\ No newline at end of file
index 4b02c1d..3c6c72f 100644 (file)
@@ -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<Scene> root;
+    unique_ptr<Scene> 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;