--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#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))
+#define _read_tvg_ui32(dst, src) memcpy(dst, (src), sizeof(uint32_t))
+#define _read_tvg_float(dst, src) memcpy(dst, (src), sizeof(float))
+
+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)
+
+struct tvgBlock
+{
+ TvgIndicator type;
+ ByteCounter length;
+ const char* data;
+ const char* end;
+};
+
+//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
+#define TVG_PAINT_TRANSFORM_MATRIX_INDICATOR (TvgIndicator)0x11 // Paint transformation matrix
+#define TVG_PAINT_CMP_TARGET_INDICATOR (TvgIndicator)0x12 // Paint composite
+
+#define TVG_PAINT_CMP_METHOD_INDICATOR (TvgIndicator)0x20 // Paint composite method
+#define TVG_PAINT_CMP_METHOD_CLIPPATH_FLAG (TvgFlag)0x01 // CompositeMethod::ClipPath
+#define TVG_PAINT_CMP_METHOD_ALPHAMASK_FLAG (TvgFlag)0x02 // CompositeMethod::AlphaMask
+#define TVG_PAINT_CMP_METHOD_INV_ALPHAMASK_FLAG (TvgFlag)0x03 // CompositeMethod::InvAlphaMask
+
+// Scene
+#define TVG_SCENE_FLAG_RESERVEDCNT (TvgIndicator)0x30 // Scene reserved count
+
+// Shape
+#define TVG_SHAPE_PATH_INDICATOR (TvgIndicator)0x40 // Shape has path section
+#define TVG_SHAPE_STROKE_INDICATOR (TvgIndicator)0x41 // Shape has stroke section
+#define TVG_SHAPE_FILL_INDICATOR (TvgIndicator)0x42 // Shape has fill section
+#define TVG_SHAPE_COLOR_INDICATOR (TvgIndicator)0x43 // Shape has color
+
+#define TVG_SHAPE_FILLRULE_INDICATOR (TvgIndicator)0x44 // Shape FillRule
+#define TVG_SHAPE_FILLRULE_WINDING_FLAG (TvgFlag)0x01 // FillRule::Winding
+#define TVG_SHAPE_FILLRULE_EVENODD_FLAG (TvgFlag)0x02 // FillRule::EvenOdd
+
+#define TVG_SHAPE_STROKE_CAP_INDICATOR (TvgIndicator)0x50 // Stroke StrokeCap
+#define TVG_SHAPE_STROKE_CAP_SQUARE_FLAG (TvgFlag)0x01 // StrokeCap::Square
+#define TVG_SHAPE_STROKE_CAP_ROUND_FLAG (TvgFlag)0x02 // StrokeCap::Round
+#define TVG_SHAPE_STROKE_CAP_BUTT_FLAG (TvgFlag)0x03 // StrokeCap::Butt
+
+#define TVG_SHAPE_STROKE_JOIN_INDICATOR (TvgIndicator)0x51 // Stroke StrokeJoin
+#define TVG_SHAPE_STROKE_JOIN_BEVEL_FLAG (TvgFlag)0x01 // StrokeJoin::Bevel
+#define TVG_SHAPE_STROKE_JOIN_ROUND_FLAG (TvgFlag)0x02 // StrokeJoin::Round
+#define TVG_SHAPE_STROKE_JOIN_MITER_FLAG (TvgFlag)0x03 // StrokeJoin::Miter
+
+#define TVG_SHAPE_STROKE_WIDTH_INDICATOR (TvgIndicator)0x52 // Stroke width
+#define TVG_SHAPE_STROKE_COLOR_INDICATOR (TvgIndicator)0x53 // Stroke color
+#define TVG_SHAPE_STROKE_FILL_INDICATOR (TvgIndicator)0x54 // Stroke fill
+#define TVG_SHAPE_STROKE_DASHPTRN_INDICATOR (TvgIndicator)0x55 // Stroke dashed stroke
+
+#define TVG_FILL_LINEAR_GRADIENT_INDICATOR (TvgIndicator)0x60 // Linear gradient
+#define TVG_FILL_RADIAL_GRADIENT_INDICATOR (TvgIndicator)0x61 // Radial gradient
+#define TVG_FILL_COLORSTOPS_INDICATOR (TvgIndicator)0x62 // Gradient color stops
+#define TVG_FILL_FILLSPREAD_INDICATOR (TvgIndicator)0x63 // Gradient fill spread
+#define TVG_FILL_FILLSPREAD_PAD_FLAG (TvgFlag)0x01 // FillSpread::Pad
+#define TVG_FILL_FILLSPREAD_REFLECT_FLAG (TvgFlag)0x02 // FillSpread::Reflect
+#define TVG_FILL_FILLSPREAD_REPEAT_FLAG (TvgFlag)0x03 // FillSpread::Repeat
+
+// Picture
+#define TVG_RAW_IMAGE_BEGIN_INDICATOR (TvgIndicator)0x70 // Picture raw data
+
+#endif //_TVG_BINARY_DESC_H_
+++ /dev/null
-/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
-
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#ifndef _TVG_TVG_HELPER_H_
-#define _TVG_TVG_HELPER_H_
-
-// now only little endian
-#define _read_tvg_ui16(dst, src) memcpy(dst, (src), sizeof(uint16_t))
-#define _read_tvg_ui32(dst, src) memcpy(dst, (src), sizeof(uint32_t))
-#define _read_tvg_float(dst, src) memcpy(dst, (src), sizeof(float))
-
-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)
-
-struct tvgBlock
-{
- TvgIndicator type;
- ByteCounter length;
- const char* data;
- const char* blockEnd;
-};
-
-#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
-
-// Paint
-#define TVG_PAINT_OPACITY_INDICATOR (TvgIndicator)0x10 // Paint opacity
-#define TVG_PAINT_TRANSFORM_MATRIX_INDICATOR (TvgIndicator)0x11 // Paint transformation matrix
-#define TVG_PAINT_CMP_TARGET_INDICATOR (TvgIndicator)0x12 // Paint composite
-
-#define TVG_PAINT_CMP_METHOD_INDICATOR (TvgIndicator)0x20 // Paint composite method
-#define TVG_PAINT_CMP_METHOD_CLIPPATH_FLAG (TvgFlag)0x01 // CompositeMethod::ClipPath
-#define TVG_PAINT_CMP_METHOD_ALPHAMASK_FLAG (TvgFlag)0x02 // CompositeMethod::AlphaMask
-#define TVG_PAINT_CMP_METHOD_INV_ALPHAMASK_FLAG (TvgFlag)0x03 // CompositeMethod::InvAlphaMask
-
-// Scene
-#define TVG_SCENE_FLAG_RESERVEDCNT (TvgIndicator)0x30 // Scene reserved count
-
-// Shape
-#define TVG_SHAPE_PATH_INDICATOR (TvgIndicator)0x40 // Shape has path section
-#define TVG_SHAPE_STROKE_INDICATOR (TvgIndicator)0x41 // Shape has stroke section
-#define TVG_SHAPE_FILL_INDICATOR (TvgIndicator)0x42 // Shape has fill section
-#define TVG_SHAPE_COLOR_INDICATOR (TvgIndicator)0x43 // Shape has color
-
-#define TVG_SHAPE_FILLRULE_INDICATOR (TvgIndicator)0x44 // Shape FillRule
-#define TVG_SHAPE_FILLRULE_WINDING_FLAG (TvgFlag)0x01 // FillRule::Winding
-#define TVG_SHAPE_FILLRULE_EVENODD_FLAG (TvgFlag)0x02 // FillRule::EvenOdd
-
-#define TVG_SHAPE_STROKE_CAP_INDICATOR (TvgIndicator)0x50 // Stroke StrokeCap
-#define TVG_SHAPE_STROKE_CAP_SQUARE_FLAG (TvgFlag)0x01 // StrokeCap::Square
-#define TVG_SHAPE_STROKE_CAP_ROUND_FLAG (TvgFlag)0x02 // StrokeCap::Round
-#define TVG_SHAPE_STROKE_CAP_BUTT_FLAG (TvgFlag)0x03 // StrokeCap::Butt
-
-#define TVG_SHAPE_STROKE_JOIN_INDICATOR (TvgIndicator)0x51 // Stroke StrokeJoin
-#define TVG_SHAPE_STROKE_JOIN_BEVEL_FLAG (TvgFlag)0x01 // StrokeJoin::Bevel
-#define TVG_SHAPE_STROKE_JOIN_ROUND_FLAG (TvgFlag)0x02 // StrokeJoin::Round
-#define TVG_SHAPE_STROKE_JOIN_MITER_FLAG (TvgFlag)0x03 // StrokeJoin::Miter
-
-#define TVG_SHAPE_STROKE_WIDTH_INDICATOR (TvgIndicator)0x52 // Stroke width
-#define TVG_SHAPE_STROKE_COLOR_INDICATOR (TvgIndicator)0x53 // Stroke color
-#define TVG_SHAPE_STROKE_FILL_INDICATOR (TvgIndicator)0x54 // Stroke fill
-#define TVG_SHAPE_STROKE_DASHPTRN_INDICATOR (TvgIndicator)0x55 // Stroke dashed stroke
-
-#define TVG_FILL_LINEAR_GRADIENT_INDICATOR (TvgIndicator)0x60 // Linear gradient
-#define TVG_FILL_RADIAL_GRADIENT_INDICATOR (TvgIndicator)0x61 // Radial gradient
-#define TVG_FILL_COLORSTOPS_INDICATOR (TvgIndicator)0x62 // Gradient color stops
-#define TVG_FILL_FILLSPREAD_INDICATOR (TvgIndicator)0x63 // Gradient fill spread
-#define TVG_FILL_FILLSPREAD_PAD_FLAG (TvgFlag)0x01 // FillSpread::Pad
-#define TVG_FILL_FILLSPREAD_REFLECT_FLAG (TvgFlag)0x02 // FillSpread::Reflect
-#define TVG_FILL_FILLSPREAD_REPEAT_FLAG (TvgFlag)0x03 // FillSpread::Repeat
-
-// Picture
-#define TVG_RAW_IMAGE_BEGIN_INDICATOR (TvgIndicator)0x70 // Picture raw data
-
-#endif //_TVG_TVG_HELPER_H_
* 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);
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);
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];
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;
}
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;
}
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;
}
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;
}
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;
}
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;
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