补全完整的dialtools
authorCaisking <Casiking@zhihuishixun.com>
Tue, 6 Jan 2026 06:29:12 +0000 (14:29 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Tue, 6 Jan 2026 06:29:12 +0000 (14:29 +0800)
71 files changed:
tools/dial_tools/dial_converter_tool/README.txt [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/common_types.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/converter.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_arc_label.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_arc_progress.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_box_progress.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_click.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_digital_img.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_kaleidoscope.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_label.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_option_img.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_rotate_img.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_sequence_img.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_static_img.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dial_video.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dll/linux_cs/libcodec.so [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dll/linux_es/libcodec.so [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dll/x64/release_cs/ICE_V5R1_BLOCK_HTC.dll [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dll/x64/release_cs/ICE_V5R1_BLOCK_HTC.lib [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dll/x64/release_es/ICE_V5R1_BLOCK_HTC.dll [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/dll/x64/release_es/ICE_V5R1_BLOCK_HTC.lib [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/img_convert.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/BIGCIRCLE_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/HEARTRATE_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/HOURHAND.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/MAIN_FACE_IMAGE.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/MEDCIRCLE_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/MINUTEHAND.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/PROGRESS_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/SECONDHAND.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/SMALLCIRCLE_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/analogue_dial.xml [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/preview_img.JPG [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/FIRDAY_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/MONDAY_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/SATURDAY_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/SUNDAY_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/THURSDAY_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/TUESDAY_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/WEDNESDAY_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/BIGCIRCLE_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/HOURHAND.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/MEDCIRCLE_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/MINUTEHAND.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/SECONDHAND.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/SMALLCIRCLE_IMAGE_PATH.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/kaleidoscope_dial.xml [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/preview_img.PNG [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/rabbit454.png [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/main.py [new file with mode: 0644]
tools/dial_tools/dial_converter_tool/video_convert.py [new file with mode: 0644]
tools/dial_tools/dial_lzma/207/owl_clock.lzma
tools/dial_tools/dial_lzma/207/owl_clock.png [new file with mode: 0644]
tools/dial_tools/dial_lzma/207/说明.txt [new file with mode: 0644]
tools/dial_tools/instance/207/owl_clock.xml
tools/dial_tools/instance/208/BACKGROUND_0_6.png [new file with mode: 0644]
tools/dial_tools/instance/208/BACKGROUND_12_18.png [new file with mode: 0644]
tools/dial_tools/instance/208/BACKGROUND_18_24.png [new file with mode: 0644]
tools/dial_tools/instance/208/BACKGROUND_6_12.png [new file with mode: 0644]
tools/dial_tools/instance/208/HAND_BOTTOM.png [new file with mode: 0644]
tools/dial_tools/instance/208/HAND_TOP.png [new file with mode: 0644]
tools/dial_tools/instance/208/HOURHAND.png [new file with mode: 0644]
tools/dial_tools/instance/208/MAIN_FACE_IMAGE.png [new file with mode: 0644]
tools/dial_tools/instance/208/MINUTEHAND.png [new file with mode: 0644]
tools/dial_tools/instance/208/SECONDHAND.png [new file with mode: 0644]
tools/dial_tools/instance/208/essential_sport.png [new file with mode: 0644]
tools/dial_tools/instance/208/essential_sport.xml [new file with mode: 0644]
tools/dial_tools/lzma_tool/lzma_tool [new file with mode: 0644]
tools/dial_tools/lzma_tool/lzma_tool.exe [new file with mode: 0644]
tools/dial_tools/lzma_tool/readme.txt [new file with mode: 0644]
tools/dial_tools/out/owl_clock.bin [new file with mode: 0644]

diff --git a/tools/dial_tools/dial_converter_tool/README.txt b/tools/dial_tools/dial_converter_tool/README.txt
new file mode 100644 (file)
index 0000000..fb9b83a
--- /dev/null
@@ -0,0 +1,11 @@
+usage: main.py [-h] [-file FILE] [-dir DIR] [-output OUTPUT]\r
+\r
+options:\r
+  -h, --help           显示帮助信息。\r
+  -file FILE, -f FILE  指定待转化的离线表盘xml文件路径。\r
+  -dir DIR, -d DIR     指定待转化的文件夹路径。根据指定路径,转化文件夹下所有xml文件。\r
+  -output OUTPUT       指定转化后离线表盘打包资源所在路径\r
+\r
+example:\r
+windows: python .\main.py -dir .\instance\analogue_dial\r
+windows: python .\main.py -dir .\instance\kaleidoscope_dial
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/common_types.py b/tools/dial_tools/dial_converter_tool/common_types.py
new file mode 100644 (file)
index 0000000..444fc6e
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from enum import Enum\r
+from ctypes import *\r
+\r
+class Point(Structure):\r
+    _fields_ = [\r
+        ('x', c_short),\r
+        ('y', c_short),\r
+    ]\r
+\r
+class Rect(Structure):\r
+    _fields_ = [\r
+        ('x', c_short),\r
+        ('y', c_short),\r
+        ('w', c_ushort),\r
+        ('h', c_ushort)\r
+    ]\r
+\r
+class ColorStop(Structure):\r
+    _fields_ = [\r
+        ('stop', c_float),\r
+        ('color', c_uint),\r
+    ]
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/converter.py b/tools/dial_tools/dial_converter_tool/converter.py
new file mode 100644 (file)
index 0000000..67b5ff0
--- /dev/null
@@ -0,0 +1,223 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import os\r
+import re\r
+import struct\r
+import ctypes\r
+import sys\r
+from ctypes import *\r
+import xml.sax\r
+from enum import Enum\r
+import img_convert\r
+import video_convert\r
+from dial_static_img import DialStaticImg\r
+from dial_sequence_img import DialSequenceImg\r
+from dial_rotate_img import DialRotateImg\r
+from dial_option_img import DialOptionImg\r
+from dial_digital_img import DialDigitalImg\r
+from dial_label import DialLabel\r
+from dial_arc_label import DialArcLabel\r
+from dial_box_progress import DialBoxProgress\r
+from dial_arc_progress import DialArcProgress\r
+from dial_video import DialVideo\r
+from dial_click import DialClick\r
+from dial_kaleidoscope import DialKaleidoscope\r
+\r
+class DialHeader(Structure):\r
+    _fields_ = [\r
+        ('dialName', c_char * 16),\r
+        ('width', c_short),\r
+        ('height', c_short),\r
+        ('version', c_char * 16),\r
+        ('previewImgId', c_ushort),\r
+        ('description', c_char * 128),\r
+        ('imgoffset', c_uint),\r
+        ('period', c_ubyte),\r
+        ('dialViewCount', c_ubyte),\r
+        ('displayCapabiliy', c_ubyte),\r
+        ('ambientPeriod', c_ubyte),\r
+    ]\r
+    _DIAL_DEFAULT_MAX_WIDTH = 960\r
+    _DIAL_DEFAULT_MAX_HEIGHT = 960\r
+\r
+    def __init__(self):\r
+        self.imgoffset = 0\r
+        self.dialViewCount = 0\r
+        self.period = 0\r
+        self.displayCapabiliy = 0\r
+        self.ambientPeriod = 0\r
+        self.viewType = []\r
+        self.viewPt = []\r
+\r
+    def parse_attributes(self, attributes):\r
+        title = attributes["title"]\r
+        self.dialName = bytes(title, encoding = "utf8")\r
+\r
+        description = attributes["description"]\r
+        self.description = bytes(description, encoding = "utf8")\r
+\r
+        version = attributes["version"]\r
+        self.version = bytes(version, encoding = "utf8")\r
+\r
+        self._parse_size_attr(attributes["size"])\r
+\r
+        previewStr = attributes["preview_img"]\r
+        self.previewImgId = img_convert.instance.convert_img(previewStr)\r
+\r
+        for attr in attributes.getNames():\r
+            if attr == "tile_width":\r
+                tile_width = int(attributes["tile_width"])\r
+                img_convert.instance.set_tile_width(tile_width)\r
+            elif attr == "ambient_period":\r
+                period_suppor_value = {1, 10, 30, 60}\r
+                self.ambientPeriod = int(attributes["ambient_period"])\r
+                if self.ambientPeriod not in period_suppor_value:\r
+                    self.ambientPeriod = 0\r
+                    print("[WARNING]:label image period value not support, using defalut value 0")\r
+\r
+\r
+    def add_view(self, viewObj, viewType):\r
+        self.viewPt.append(viewObj)\r
+        self.viewType.append(viewType)\r
+        self.dialViewCount += 1\r
+\r
+    def get_bytes(self):\r
+        ret = bytes(self)\r
+        for index in range(self.dialViewCount):\r
+            ret += struct.pack('@b', self.viewType[index])\r
+        return ret\r
+\r
+    def get_size(self):\r
+        return sizeof(self) + sizeof(c_ubyte) * self.dialViewCount\r
+\r
+    def _parse_size_attr(self, input_size):\r
+        input_width,input_height = input_size.split(' ')\r
+        width = int(input_width)\r
+        if width <= 0 or width > DialHeader._DIAL_DEFAULT_MAX_WIDTH :\r
+            print(f"[ERR]:dial size width out of range, (0, {DialHeader._DIAL_DEFAULT_MAX_WIDTH}], value:{width}")\r
+            sys.exit(1)\r
+        self.width = width\r
+\r
+        height = int(input_height)\r
+        if height <= 0 or height > DialHeader._DIAL_DEFAULT_MAX_HEIGHT :\r
+            print(f"[ERR]:dial size height out of range, (0, {DialHeader._DIAL_DEFAULT_MAX_HEIGHT}], value:{height}")\r
+            sys.exit(1)\r
+        self.height = height\r
+\r
+class DialConvertTool(xml.sax.ContentHandler):\r
+    parser = xml.sax.make_parser()\r
+    DIAL_STATIC_IMG_TYPE = 0\r
+    DIAL_SEQUENCE_IMG_TYPE = 1\r
+    DIAL_ROTATE_IMG_TYPE = 2\r
+    DIAL_OPTION_IMG_TYPE = 3\r
+    DIAL_DIGITAL_IMG_TYPE = 4\r
+    DIAL_LABEL_TYPE = 5\r
+    DIAL_ARC_LABEL_TYPE = 6\r
+    DIAL_BOX_PROGRESS_TYPE = 7\r
+    DIAL_ARC_PROGRESS_TYPE = 8\r
+    DIAL_VIDEO_TYPE = 9\r
+    DIAL_CLICK_TYPE = 10\r
+    DIAL_KALEIDOSCCOPE_TYPE = 11\r
+\r
+    def __init__(self):\r
+        self.inFile = ""\r
+        self.outPath = ""\r
+        self.header = DialHeader()\r
+        self.parser.setFeature(xml.sax.handler.feature_namespaces, 0)\r
+        self.parser.setContentHandler(self)\r
+\r
+    def startElement(self, tag, attributes):\r
+        viewTypeArray = []\r
+        if tag == "dial":\r
+            self.header.parse_attributes(attributes)\r
+        elif tag == "static_img":\r
+            view = DialStaticImg()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_STATIC_IMG_TYPE)\r
+        elif tag == "sequence_img":\r
+            view = DialSequenceImg()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_SEQUENCE_IMG_TYPE)\r
+        elif tag == "rotate_img":\r
+            view = DialRotateImg()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_ROTATE_IMG_TYPE)\r
+        elif tag == "option_img":\r
+            view = DialOptionImg()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_OPTION_IMG_TYPE)\r
+        elif tag == "digital_img":\r
+            view = DialDigitalImg()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_DIGITAL_IMG_TYPE)\r
+        elif tag == "label":\r
+            view = DialLabel()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_LABEL_TYPE)\r
+        elif tag == "arc_label":\r
+            view = DialArcLabel()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_ARC_LABEL_TYPE)\r
+        elif tag == "box_progress":\r
+            view = DialBoxProgress()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_BOX_PROGRESS_TYPE)\r
+        elif tag == "arc_progress":\r
+            view = DialArcProgress()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_ARC_PROGRESS_TYPE)\r
+        elif tag == "video":\r
+            view = DialVideo()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_VIDEO_TYPE)\r
+        elif tag == "click":\r
+            view = DialClick()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_CLICK_TYPE)\r
+        elif tag == "kaleidoscope":\r
+            view = DialKaleidoscope()\r
+            view.parse_attributes(attributes)\r
+            self.header.add_view(view, self.DIAL_KALEIDOSCCOPE_TYPE)\r
+\r
+    def endElement(self, tag):\r
+        if tag == "dial":\r
+            # create & open dstfile\r
+            outputfile = self.outPath + "/" + os.path.basename(self.inFile)[:-3] + "bin"\r
+            fb = open(outputfile, 'wb')\r
+            os.chmod(outputfile, 0o0755)\r
+            self._write_data_to_bin(fb)\r
+            fb.close()\r
+\r
+    def convert_xml_to_output(self, inFile, outPath):\r
+        self.inFile = inFile\r
+        self.outPath = outPath\r
+        self.parser.parse(inFile)\r
+\r
+    def _write_data_to_bin(self, fb):\r
+        self.header.imgoffset += self.header.get_size()\r
+        aod_only, normal_only = 0, 0\r
+        for view in self.header.viewPt:\r
+            if self.header.period < view.period:\r
+                self.header.period = view.period\r
+            if view.displayMode == 1:\r
+                aod_only = aod_only + 1\r
+            elif view.displayMode == 2:\r
+                aod_only = aod_only + 1\r
+                normal_only = normal_only + 1\r
+            else:\r
+                normal_only = normal_only + 1\r
+            self.header.imgoffset += view.get_size()\r
+        if normal_only > 0 and aod_only > 0:\r
+            self.header.displayCapabiliy = 2\r
+        elif normal_only > 0 and aod_only == 0:\r
+            self.header.displayCapabiliy = 0\r
+        else:\r
+            self.header.displayCapabiliy = 1\r
+\r
+        fb.write(self.header.get_bytes())\r
+        for view in self.header.viewPt:\r
+            if isinstance(view, DialVideo):\r
+                view.offset += self.header.imgoffset + img_convert.instance.get_size()\r
+            fb.write(view.get_bytes())\r
+        img_convert.instance.write_data_to_bin(fb)\r
+        video_convert.instance.write_data_to_bin(fb)\r
diff --git a/tools/dial_tools/dial_converter_tool/dial_arc_label.py b/tools/dial_tools/dial_converter_tool/dial_arc_label.py
new file mode 100644 (file)
index 0000000..1d3ac7e
--- /dev/null
@@ -0,0 +1,112 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+\r
+class DialArcLabel(Structure):\r
+    _fields_ = [\r
+        ('align', c_ubyte),\r
+        ('fontSize', c_ubyte),\r
+        ('center', Point),\r
+        ('radius', c_ushort),\r
+        ('rotateStart', c_short),\r
+        ('rotaeteEnd', c_short),\r
+        ('color', c_uint),\r
+        ('fontName', c_char * 64),\r
+        ('text', c_char * 64),\r
+        ('bindData', c_short),\r
+        ('isPeriodic', c_bool),\r
+        ('displayMode', c_ubyte),\r
+        ('isAmbientPeriodic', c_bool)\r
+    ]\r
+    def __init__(self):\r
+        self.period = 0\r
+        self.isPeriodic = False\r
+        self.displayMode = 0\r
+        self.isAmbientPeriodic = False\r
+\r
+    def parse_attributes(self, attributes):\r
+        alignStr = attributes["align"]\r
+        if alignStr == "bottom":\r
+            self.align = 4\r
+        elif alignStr == "top":\r
+            self.align = 3\r
+        elif alignStr == "center":\r
+            self.align = 2\r
+        elif alignStr == "right":\r
+            self.align = 1\r
+        elif alignStr == "left":\r
+            self.align = 0\r
+        else:\r
+            self.align = 0\r
+            print("[WARNING] arc label align value input error, using defalut value")\r
+\r
+        self.fontSize = int(attributes["font_size"])\r
+        if self.fontSize < np.iinfo(np.int16).min or self.fontSize > np.iinfo(np.int16).max:\r
+            print("[ERR]:label font size out of range")\r
+            sys.exit(1)\r
+\r
+        x,y = attributes["center"].split(" ")\r
+        self.center.x = int(x)\r
+        if self.center.x < np.iinfo(np.int16).min or self.center.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc label center x out of range")\r
+            sys.exit(1)\r
+        self.center.y = int(y)\r
+        if self.center.y < np.iinfo(np.int16).min or self.center.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc label center y out of range")\r
+            sys.exit(1)\r
+\r
+        self.radius = int(attributes["radius"])\r
+        if self.radius < 0 or self.radius > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc label radius out of range")\r
+            sys.exit(1)\r
+\r
+        self.rotateStart = int(attributes["start_angle"])\r
+        self.rotaeteEnd = int(attributes["end_angle"])\r
+\r
+        self.color = int(attributes["color"], 16)\r
+        self.fontName = bytes(attributes["font"], encoding = "utf8")\r
+        self.text = bytes(attributes["text"], encoding = "utf8")\r
+        for attr in attributes.getNames():\r
+            if attr == "bind_data":\r
+                self.bindData = int(attributes["bind_data"])\r
+                if self.bindData < 0 or self.bindData > np.iinfo(np.int16).max:\r
+                    print("[ERR]:arc label bind data out of range")\r
+                    sys.exit(1)\r
+            elif attr == "period":\r
+                period_suppor_value = {1, 10, 30, 60}\r
+                self.period = int(attributes["period"])\r
+                if self.period == 0:\r
+                    self.isPeriodic = False\r
+                elif self.period not in period_suppor_value:\r
+                    self.period = 0\r
+                    print("[WARNING]:arc label period value not support, using defalut value 0")\r
+                else:\r
+                    self.isPeriodic = True\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+        if self.displayMode != 0 :\r
+            if "ambient_periodic" in attributes.getNames():\r
+                if attributes["ambient_periodic"] == "true":\r
+                    self.isAmbientPeriodic = True\r
+\r
+        if self.isPeriodic != 0 and self.bindData == 0:\r
+            print("[ERR]:[bind_data] is not set, [period] cannot be set")\r
+            sys.exit(1)\r
+\r
+    def get_bytes(self):\r
+        return bytes(self)\r
+\r
+    def get_size(self):\r
+        return sizeof(self)
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_arc_progress.py b/tools/dial_tools/dial_converter_tool/dial_arc_progress.py
new file mode 100644 (file)
index 0000000..338c5c8
--- /dev/null
@@ -0,0 +1,149 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+from common_types import ColorStop\r
+import img_convert\r
+\r
+class ProgressUnion(Union):\r
+    _fields_ = [\r
+        ('stopCount', c_ubyte),\r
+        ('imgId', c_ushort),\r
+        ('color', c_uint),\r
+    ]\r
+\r
+class DialArcProgress(Structure):\r
+    _fields_ = [\r
+        ('cap', c_ubyte),\r
+        ('isPeriodic', c_bool),\r
+        ('radius', c_ushort),\r
+        ('startAngle', c_ushort),\r
+        ('endAngle', c_ushort),\r
+        ('lineWidth', c_ushort),\r
+        ('bindData', c_short),\r
+        ('bgColor', c_uint),\r
+        ('type', c_ubyte),\r
+        ('rect', Rect),\r
+        ('unionValue', ProgressUnion),\r
+        ('displayMode', c_ubyte),\r
+        ('isAmbientPeriodic', c_bool)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.stop = []\r
+        self.period = 0\r
+        self.isPeriodic = False\r
+        self.displayMode = 0\r
+        self.isAmbientPeriodic = False\r
+\r
+    def parse_attributes(self, attributes):\r
+        x,y,w,h = attributes["rect"].split(" ")\r
+        self.rect.x = int(x)\r
+        if self.rect.x < np.iinfo(np.int16).min or self.rect.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc progress rect x out of range")\r
+            sys.exit(1)\r
+        self.rect.y = int(y)\r
+        if self.rect.y < np.iinfo(np.int16).min or self.rect.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc progress rect y out of range")\r
+            sys.exit(1)\r
+        self.rect.w = int(w)\r
+        if self.rect.w < np.iinfo(np.int16).min or self.rect.w > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc progress rect w out of range")\r
+            sys.exit(1)\r
+        self.rect.h = int(h)\r
+        if self.rect.h < np.iinfo(np.int16).min or self.rect.h > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc progress rect h out of range")\r
+            sys.exit(1)\r
+\r
+        cap = attributes["cap_type"]\r
+        if cap == "round":\r
+            self.cap = 1\r
+        else:\r
+            self.cap = 0\r
+\r
+        self.radius = int(attributes["radius"])\r
+        if self.radius < 0 or self.radius > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc progress radius out of range")\r
+            sys.exit(1)\r
+\r
+        self.startAngle = int(attributes["start_angle"])\r
+        self.endAngle = int(attributes["end_angle"])\r
+\r
+        self.lineWidth = int(attributes["line_width"])\r
+        if self.lineWidth < 0 or self.lineWidth > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc progress lineWidth out of range")\r
+            sys.exit(1)\r
+\r
+        self.bindData = int(attributes["bind_data"])\r
+        if self.bindData < 0 or self.bindData > np.iinfo(np.int16).max:\r
+            print("[ERR]:arc progress bind data out of range")\r
+            sys.exit(1)\r
+\r
+        attrList = attributes.getNames()\r
+        for attr in attrList:\r
+            if attr == "img_name":\r
+                self.unionValue.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+                self.type = 0\r
+                break\r
+            elif attr == "color":\r
+                self.unionValue.color = int(attributes["color"], 16)\r
+                self.type = 1\r
+                break\r
+            elif attr == "gradient_colors":\r
+                self.type = 2\r
+                stopList = attributes["gradient_stops"].split(" ")\r
+                colorList = attributes["gradient_colors"].split(" ")\r
+                if len(stopList) != len(colorList):\r
+                    print("[ERROR]:[gradient_stops] attr not equal [colorList] attr")\r
+                self.unionValue.stopCount = min(len(colorList), len(stopList))\r
+                for index in range(self.unionValue.stopCount):\r
+                    colorStop = ColorStop()\r
+                    colorStop.stop = float(stopList[index])\r
+                    colorStop.color = int(colorList[index], 16)\r
+                    self.stop.append(colorStop)\r
+                break\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+        if self.displayMode != 0 :\r
+            if "ambient_periodic" in attributes.getNames():\r
+                if attributes["ambient_periodic"] == "true":\r
+                    self.isAmbientPeriodic = True\r
+\r
+        if "period" in attrList:\r
+            period_suppor_value = {1, 10, 30, 60}\r
+            self.period = int(attributes["period"])\r
+            if self.period == 0:\r
+                self.isPeriodic = False\r
+            elif self.period not in period_suppor_value:\r
+                self.period = 0\r
+                print("[WARNING]:label image period value not support, using defalut value 0")\r
+            else:\r
+                self.isPeriodic = True\r
+\r
+        if "background_color" in attrList:\r
+            self.bgColor = int(attributes["background_color"], 16)\r
+\r
+    def get_bytes(self):\r
+        ret = bytes(self)\r
+        if self.type == 2:\r
+            for stop in self.stop:\r
+                ret += bytes(stop)\r
+        return ret\r
+\r
+    def get_size(self):\r
+        ret = sizeof(self)\r
+        if self.type == 2:\r
+            for stop in self.stop:\r
+                ret += sizeof(stop)\r
+        return ret
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_box_progress.py b/tools/dial_tools/dial_converter_tool/dial_box_progress.py
new file mode 100644 (file)
index 0000000..40d842b
--- /dev/null
@@ -0,0 +1,146 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+from common_types import ColorStop\r
+import img_convert\r
+\r
+class ProgressUnion(Union):\r
+    _fields_ = [\r
+        ('stopCount', c_ubyte),\r
+        ('imgId', c_ushort),\r
+        ('color', c_uint),\r
+    ]\r
+\r
+class DialBoxProgress(Structure):\r
+    _fields_ = [\r
+        ('cap', c_ubyte),\r
+        ('direction', c_ubyte),\r
+        ('isPeriodic', c_bool),\r
+        ('bindData', c_short),\r
+        ('bgColor', c_uint),\r
+        ('type', c_ubyte),\r
+        ('rect', Rect),\r
+        ('unionValue', ProgressUnion),\r
+        ('displayMode', c_ubyte),\r
+        ('isAmbientPeriodic', c_bool)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.stop = []\r
+        self.isPeriodic = False\r
+        self.period = 0\r
+        self.displayMode = 0\r
+        self.isAmbientPeriodic = False\r
+\r
+    def parse_attributes(self, attributes):\r
+        x,y,w,h = attributes["rect"].split(" ")\r
+        self.rect.x = int(x)\r
+        if self.rect.x < np.iinfo(np.int16).min or self.rect.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:box progress rect x out of range")\r
+            sys.exit(1)\r
+        self.rect.y = int(y)\r
+        if self.rect.y < np.iinfo(np.int16).min or self.rect.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:box progress rect y out of range")\r
+            sys.exit(1)\r
+        self.rect.w = int(w)\r
+        if self.rect.w < np.iinfo(np.int16).min or self.rect.w > np.iinfo(np.int16).max:\r
+            print("[ERR]:box progress rect w out of range")\r
+            sys.exit(1)\r
+        self.rect.h = int(h)\r
+        if self.rect.h < np.iinfo(np.int16).min or self.rect.h > np.iinfo(np.int16).max:\r
+            print("[ERR]:box progress rect h out of range")\r
+            sys.exit(1)\r
+\r
+        cap = attributes["cap_type"]\r
+        if cap == "round":\r
+            self.cap = 1\r
+        else:\r
+            self.cap = 0\r
+\r
+        direction = attributes["direction"]\r
+        if direction == "left_to_right":\r
+            self.direction = 0\r
+        elif direction == "right_to_left":\r
+            self.direction = 1\r
+        elif direction == "top_to_bottom":\r
+            self.direction = 2\r
+        elif direction == "bottom_to_top":\r
+            self.direction = 3\r
+        else:\r
+            self.direction = 0\r
+            print("[WARNING]:box progress direction set error, using defalut value")\r
+\r
+        self.bindData = int(attributes["bind_data"])\r
+        if self.bindData < 0 or self.bindData > np.iinfo(np.int16).max:\r
+            print("[ERR]:box progress bind data out of range")\r
+            sys.exit(1)\r
+\r
+        attrList = attributes.getNames()\r
+        for attr in attrList:\r
+            if attr == "img_name":\r
+                self.unionValue.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+                self.type = 0\r
+                break\r
+            elif attr == "color":\r
+                self.unionValue.color = int(attributes["color"], 16)\r
+                self.type = 1\r
+                break\r
+            elif attr == "gradient_colors":\r
+                stopList = attributes["gradient_stops"].split(" ")\r
+                colorList = attributes["gradient_colors"].split(" ")\r
+                if len(stopList) != len(colorList):\r
+                    print("[ERROR]:[gradient_stops] attr not equal [colorList] attr")\r
+                self.unionValue.stopCount = min(len(colorList), len(stopList))\r
+                for index in range(self.unionValue.stopCount):\r
+                    colorStop = ColorStop()\r
+                    colorStop.stop = float(stopList[index])\r
+                    colorStop.color = int(colorList[index], 16)\r
+                    self.stop.append(colorStop)\r
+                self.type = 2\r
+                break\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+        if self.displayMode != 0 :\r
+            if "ambient_periodic" in attributes.getNames():\r
+                if attributes["ambient_periodic"] == "true":\r
+                    self.isAmbientPeriodic = True\r
+\r
+        if "period" in attrList:\r
+            period_suppor_value = {1, 10, 30, 60}\r
+            self.period = int(attributes["period"])\r
+            if self.period == 0:\r
+                self.isPeriodic = False\r
+            elif self.period not in period_suppor_value:\r
+                self.period = 0\r
+                print("[WARNING]:label image period value not support, using defalut value 0")\r
+            else:\r
+                self.isPeriodic = True\r
+\r
+        if "background_color" in attrList:\r
+            self.bgColor = int(attributes["background_color"], 16)\r
+\r
+    def get_bytes(self):\r
+        ret = bytes(self)\r
+        if self.type == 2:\r
+            for stop in self.stop:\r
+                ret += bytes(stop)\r
+        return ret\r
+\r
+    def get_size(self):\r
+        ret = sizeof(self)\r
+        if self.type == 2:\r
+            for stop in self.stop:\r
+                ret += sizeof(stop)\r
+        return ret
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_click.py b/tools/dial_tools/dial_converter_tool/dial_click.py
new file mode 100644 (file)
index 0000000..4c23840
--- /dev/null
@@ -0,0 +1,70 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+\r
+class ClickTypeUnion(Union):\r
+    _fields_ = [\r
+        ('sliceId', c_uint),\r
+        ('bundleName', c_char * 64)\r
+    ]\r
+\r
+class DialClick(Structure):\r
+    _fields_ = [\r
+        ('type', c_ubyte),\r
+        ('rect', Rect),\r
+        ('unionType', ClickTypeUnion),\r
+        ('displayMode', c_ubyte)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.period = 0\r
+        self.displayMode = 0\r
+\r
+    def parse_attributes(self, attributes):\r
+        x,y,w,h = attributes["rect"].split(" ")\r
+        self.rect.x = int(x)\r
+        if self.rect.x < np.iinfo(np.int16).min or self.rect.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:click rect x out of range")\r
+            sys.exit(1)\r
+        self.rect.y = int(y)\r
+        if self.rect.y < np.iinfo(np.int16).min or self.rect.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:click rect y out of range")\r
+            sys.exit(1)\r
+        self.rect.w = int(w)\r
+        if self.rect.w < np.iinfo(np.int16).min or self.rect.w > np.iinfo(np.int16).max:\r
+            print("[ERR]:click rect w out of range")\r
+            sys.exit(1)\r
+        self.rect.h = int(h)\r
+        if self.rect.h < np.iinfo(np.int16).min or self.rect.h > np.iinfo(np.int16).max:\r
+            print("[ERR]:click rect h out of range")\r
+            sys.exit(1)\r
+\r
+        for attr in attributes.getNames():\r
+            if attr == "action_slice":\r
+                self.unionType.sliceId = int(attributes["action_slice"])\r
+                self.type = 0\r
+                break\r
+            elif attr == "action_bundle":\r
+                self.unionType.bundleName = bytes(attributes["action_bundle"], encoding = "utf8")\r
+                self.type = 1\r
+                break\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+\r
+    def get_bytes(self):\r
+        return bytes(self)\r
+\r
+    def get_size(self):\r
+        return sizeof(self)
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_digital_img.py b/tools/dial_tools/dial_converter_tool/dial_digital_img.py
new file mode 100644 (file)
index 0000000..8f634ef
--- /dev/null
@@ -0,0 +1,121 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialDigitalImg(Structure):\r
+    _fields_ = [\r
+        ('alignType', c_ubyte, 4),\r
+        ('integerLength', c_ubyte, 4),\r
+        ('decimalPrecision', c_ubyte),\r
+        ('imgIds', c_ushort * 10),\r
+        ('signImgId', c_ushort),\r
+        ('decimalPointImgId', c_ushort),\r
+        ('space', c_ushort),\r
+        ('alignPosition', Point),\r
+        ('bindData', c_short),\r
+        ('isPeriodic', c_bool),\r
+        ('displayMode', c_ubyte),\r
+        ('isAmbientPeriodic', c_bool)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.period = 0\r
+        self.isPeriodic = False\r
+        self.displayMode = 0\r
+        self.isAmbientPeriodic = False\r
+\r
+    def parse_attributes(self, attributes):\r
+        imgNames = attributes["img_names"].split(",")\r
+        length = len(imgNames)\r
+        if length < 10:\r
+            print("[ERR]:tag:[digital_img] attr[img_names] less than 10!")\r
+            sys.exit(1)\r
+        else:\r
+            for index in range(10):\r
+                self.imgIds[index] = img_convert.instance.convert_img(imgNames[index])\r
+\r
+        self.space = int(attributes["space"])\r
+        if self.space < 0 or self.space > np.iinfo(np.int16).max:\r
+            print("[ERR]:digital image space out of range")\r
+            sys.exit(1)\r
+\r
+        alignStr = attributes["align"]\r
+        if alignStr == "right":\r
+            self.alignType = 2\r
+        elif alignStr == "center":\r
+            self.alignType = 1\r
+        elif alignStr == "left":\r
+            self.alignType = 0\r
+        else:\r
+            print("[ERR]:digital image align not support")\r
+\r
+        align_pos_x,align_pos_y = attributes["align_pos"].split(" ")\r
+        align_x = int(align_pos_x)\r
+        if align_x < np.iinfo(np.int16).min or align_x > np.iinfo(np.int16).max:\r
+            print("[ERR]:digital image align x out of range")\r
+            sys.exit(1)\r
+        self.alignPosition.x = align_x\r
+\r
+        align_y = int(align_pos_y)\r
+        if align_y < np.iinfo(np.int16).min or align_y > np.iinfo(np.int16).max:\r
+            print("[ERR]:digital image align y out of range")\r
+            sys.exit(1)\r
+        self.alignPosition.y = align_y\r
+\r
+        self.bindData = int(attributes["bind_data"])\r
+        if self.bindData < 0 or self.bindData > np.iinfo(np.int16).max:\r
+            print("[ERR]:digital image bind data out of range")\r
+            sys.exit(1)\r
+\r
+        for attr in attributes.getNames():\r
+            if attr == "sign_img_name":\r
+                signImgName = attributes["sign_img_name"]\r
+                self.signImgId = img_convert.instance.convert_img(signImgName)\r
+            elif attr == "integer_length":\r
+                self.integerLength = int(attributes["integer_length"])\r
+                if self.integerLength < 0 or self.integerLength > np.iinfo(np.uint8).max:\r
+                    print("[ERR]:digital image integer length out of range")\r
+                    sys.exit(1)\r
+            elif attr == "img_decimal_point":\r
+                decimalPointImgName = attributes["img_decimal_point"]\r
+                self.decimalPointImgId = img_convert.instance.convert_img(decimalPointImgName)\r
+            elif attr == "decimal_precision":\r
+                self.decimalPrecision = int(attributes["decimal_precision"])\r
+                if self.decimalPrecision < 0 or self.decimalPrecision > np.iinfo(np.uint8).max:\r
+                    print("[ERR]:digital image decimal precision out of range")\r
+                    sys.exit(1)\r
+            elif attr == "period":\r
+                period_suppor_value = {1, 10, 30, 60}\r
+                self.period = int(attributes["period"])\r
+                if self.period == 0:\r
+                    self.isPeriodic = False\r
+                elif self.period not in period_suppor_value:\r
+                    self.period = 0\r
+                    print("[WARNING]:digital image period value not support, using defalut value 0")\r
+                else:\r
+                    self.isPeriodic = True\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+        if self.displayMode != 0 :\r
+            if "ambient_periodic" in attributes.getNames():\r
+                if attributes["ambient_periodic"] == "true":\r
+                    self.isAmbientPeriodic = True\r
+\r
+    def get_bytes(self):\r
+        return bytes(self)\r
+\r
+    def get_size(self):\r
+        return sizeof(self)
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_kaleidoscope.py b/tools/dial_tools/dial_converter_tool/dial_kaleidoscope.py
new file mode 100644 (file)
index 0000000..8f89526
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+import img_convert\r
+\r
+class DialKaleidoscope(Structure):\r
+    _fields_ = [\r
+        ('imgId', c_ushort),\r
+        ('rotateEventFactor', c_float),\r
+        ('rotateAnimatorValue', c_float),\r
+        ('displayMode', c_ubyte)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.imgId = 0\r
+        self.rotateEventFactor = 1.0\r
+        self.rotateAnimatorValue = 0.0\r
+        self.period = 0\r
+        self.displayMode = 0\r
+\r
+    def parse_attributes(self, attributes):\r
+        self.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+        for attr in attributes.getNames():\r
+            if attr == "crown_rotate_step":\r
+                self.rotateEventFactor = float(attributes["crown_rotate_step"])\r
+            elif attr == "animator_rotate_step":\r
+                self.rotateAnimatorValue = float(attributes["animator_rotate_step"])\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+\r
+    def get_bytes(self):\r
+        return bytes(self)\r
+\r
+    def get_size(self):\r
+        return sizeof(self)\r
diff --git a/tools/dial_tools/dial_converter_tool/dial_label.py b/tools/dial_tools/dial_converter_tool/dial_label.py
new file mode 100644 (file)
index 0000000..1bd19db
--- /dev/null
@@ -0,0 +1,129 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+\r
+class DialLabel(Structure):\r
+    _fields_ = [\r
+        ('breakMode', c_ubyte),\r
+        ('align', c_ubyte),\r
+        ('fontSize', c_ubyte),\r
+        ('isPeriodic', c_bool),\r
+        ('rect', Rect),\r
+        ('color', c_uint),\r
+        ('fontName', c_char * 64),\r
+        ('text', c_char * 64),\r
+        ('bindData', c_short),\r
+        ('displayMode', c_ubyte),\r
+        ('isAmbientPeriodic', c_bool)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.period = 0\r
+        self.isPeriodic = False\r
+        self.displayMode = 0\r
+        self.isAmbientPeriodic = False\r
+\r
+    def parse_attributes(self, attributes):\r
+        x,y,w,h = attributes["rect"].split(" ")\r
+        self.rect.x = int(x)\r
+        if self.rect.x < np.iinfo(np.int16).min or self.rect.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:label rect x out of range")\r
+            sys.exit(1)\r
+        self.rect.y = int(y)\r
+        if self.rect.y < np.iinfo(np.int16).min or self.rect.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:label rect y out of range")\r
+            sys.exit(1)\r
+        self.rect.w = int(w)\r
+        if self.rect.w < np.iinfo(np.int16).min or self.rect.w > np.iinfo(np.int16).max:\r
+            print("[ERR]:label rect w out of range")\r
+            sys.exit(1)\r
+        self.rect.h = int(h)\r
+        if self.rect.h < np.iinfo(np.int16).min or self.rect.h > np.iinfo(np.int16).max:\r
+            print("[ERR]:label rect h out of range")\r
+            sys.exit(1)\r
+\r
+        mode = attributes["break_mode"]\r
+        if mode == "adapt":\r
+            self.breakMode = 0\r
+        elif mode == "stretch":\r
+            self.breakMode = 1\r
+        elif mode == "wrap":\r
+            self.breakMode = 2\r
+        elif mode == "ellipsis":\r
+            self.breakMode = 3\r
+        elif mode == "marquee":\r
+            self.breakMode = 4\r
+        elif mode == "clip":\r
+            self.breakMode = 5\r
+        else:\r
+            self.breakMode = 3\r
+            print("[WARNING][label:break_mode]Incorrect input:", mode)\r
+\r
+        alignStr = attributes["align"]\r
+        if alignStr == "bottom":\r
+            self.align = 4\r
+        elif alignStr == "top":\r
+            self.align = 3\r
+        elif alignStr == "center":\r
+            self.align = 2\r
+        elif alignStr == "right":\r
+            self.align = 1\r
+        elif alignStr == "left":\r
+            self.align = 0\r
+        else:\r
+            self.align = 0\r
+            print("[WARNING][label:align]Incorrect input:", alignStr)\r
+\r
+        self.fontSize = int(attributes["font_size"])\r
+        if self.fontSize < 0 or self.fontSize > np.iinfo(np.uint8).max:\r
+            print("[ERR]:label font size out of range")\r
+            sys.exit(1)\r
+\r
+        self.color = int(attributes["color"], 16)\r
+        self.fontName = bytes(attributes["font"], encoding = "utf8")\r
+        self.text = bytes(attributes["text"], encoding = "utf8")\r
+\r
+        for attr in attributes.getNames():\r
+            if attr == "bind_data":\r
+                self.bindData = int(attributes["bind_data"])\r
+                if self.bindData < 0 or self.bindData > np.iinfo(np.int16).max:\r
+                    print("[ERR]:label bind data out of range")\r
+                    sys.exit(1)\r
+            elif attr == "period":\r
+                period_suppor_value = {1, 10, 30, 60}\r
+                self.period = int(attributes["period"])\r
+                if self.period == 0:\r
+                    self.isPeriodic = False\r
+                elif self.period not in period_suppor_value:\r
+                    self.period = 0\r
+                    print("[WARNING]:label image period value not support, using defalut value 0")\r
+                else:\r
+                    self.isPeriodic = True\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+        if self.displayMode != 0 :\r
+            if "ambient_periodic" in attributes.getNames():\r
+                if attributes["ambient_periodic"] == "true":\r
+                    self.isAmbientPeriodic = True\r
+\r
+        if self.isPeriodic != 0 and self.bindData == 0:\r
+            print("[ERR]:[bind_data] is not set, [period] cannot be set")\r
+            sys.exit(1)\r
+\r
+    def get_bytes(self):\r
+        return bytes(self)\r
+\r
+    def get_size(self):\r
+        return sizeof(self)
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_option_img.py b/tools/dial_tools/dial_converter_tool/dial_option_img.py
new file mode 100644 (file)
index 0000000..c2a448c
--- /dev/null
@@ -0,0 +1,83 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialOptionImg(Structure):\r
+    _fields_ = [\r
+        ('pos', Point),\r
+        ('bindData', c_short),\r
+        ('isPeriodic', c_bool),\r
+        ('count', c_ubyte),\r
+        ('displayMode', c_ubyte),\r
+        ('isAmbientPeriodic', c_bool)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.imgId = []\r
+        self.period = 0\r
+        self.isPeriodic = False\r
+        self.displayMode = 0\r
+        self.isAmbientPeriodic = False\r
+\r
+    def parse_attributes(self, attributes):\r
+        input_pos_x,input_pos_y = attributes["position"].split(" ")\r
+        self.pos.x = int(input_pos_x)\r
+        if self.pos.x < np.iinfo(np.int16).min or self.pos.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:option image pos x out of range")\r
+            sys.exit(1)\r
+\r
+        self.pos.y = int(input_pos_y)\r
+        if self.pos.y < np.iinfo(np.int16).min or self.pos.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:option image pos y out of range")\r
+            sys.exit(1)\r
+\r
+        self.bindData = int(attributes["bind_data"])\r
+        if self.bindData < 0 or self.bindData > np.iinfo(np.int16).max:\r
+            print("[ERR]:option image bind data out of range")\r
+            sys.exit(1)\r
+\r
+        imgNames = attributes["img_names"].split(",")\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+        if self.displayMode != 0:\r
+            if "ambient_periodic" in attributes.getNames():\r
+                if attributes["ambient_periodic"] == "true":\r
+                    self.isAmbientPeriodic = True\r
+\r
+        self.count = len(imgNames)\r
+        for img in imgNames:\r
+            imgId = img_convert.instance.convert_img(img)\r
+            self.imgId.append(imgId)\r
+\r
+        if "period" in attributes.getNames():\r
+            period_suppor_value = {1, 10, 30, 60}\r
+            self.period = int(attributes["period"])\r
+            if self.period == 0:\r
+                self.isPeriodic = False\r
+            elif self.period not in period_suppor_value:\r
+                self.period = 0\r
+                print("[WARNING]:option image period value not support, using defalut value 0")\r
+            else:\r
+                self.isPeriodic = True\r
+\r
+    def get_bytes(self):\r
+        ret = bytes(self)\r
+        for index in range(self.count):\r
+            ret += struct.pack('@H', self.imgId[index])\r
+        return ret\r
+\r
+    def get_size(self):\r
+        return sizeof(self) + sizeof(c_ushort) * self.count
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_rotate_img.py b/tools/dial_tools/dial_converter_tool/dial_rotate_img.py
new file mode 100644 (file)
index 0000000..9a12409
--- /dev/null
@@ -0,0 +1,90 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialRotateImg(Structure):\r
+    _fields_ = [\r
+        ('pos', Point),\r
+        ('center', Point),\r
+        ('rotateStart', c_short),\r
+        ('rotaeteEnd', c_short),\r
+        ('imgId', c_ushort),\r
+        ('bindData', c_short),\r
+        ('isPeriodic', c_bool),\r
+        ('displayMode', c_ubyte),\r
+        ('isAmbientPeriodic', c_bool)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.period = 0\r
+        self.isPeriodic = False\r
+        self.displayMode = 0\r
+        self.isAmbientPeriodic = False\r
+\r
+    def parse_attributes(self, attributes):\r
+        input_pos_x,input_pos_y = attributes["position"].split(" ")\r
+        self.pos.x = int(input_pos_x)\r
+        if self.pos.x < np.iinfo(np.int16).min or self.pos.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:rotate image pos x out of range")\r
+            sys.exit(1)\r
+\r
+        self.pos.y = int(input_pos_y)\r
+        if self.pos.y < np.iinfo(np.int16).min or self.pos.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:rotate image pos y out of range")\r
+            sys.exit(1)\r
+\r
+        x,y = attributes["rotate_center"].split(" ")\r
+        self.center.x = round(float(x))\r
+        self.center.y = round(float(y))\r
+\r
+        self.rotateStart = int(attributes["rotate_start"])\r
+        if self.rotateStart < 0.0 or self.rotateStart > 360.0 :\r
+            print("[ERR]:rotate image start angle out of range, [0, 360]")\r
+            sys.exit(1)\r
+\r
+        self.rotaeteEnd = int(attributes["rotate_end"])\r
+        if self.rotaeteEnd < 0.0 or self.rotaeteEnd > 360.0 :\r
+            print("[ERR]:rotate image end angle out of range, [0, 360]")\r
+            sys.exit(1)\r
+\r
+        self.bindData = int(attributes["bind_data"])\r
+        if self.bindData < 0 or self.bindData > np.iinfo(np.int16).max:\r
+            print("[ERR]:rotate image bind data out of range")\r
+            sys.exit(1)\r
+\r
+        self.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+        if "period" in attributes.getNames():\r
+            period_suppor_value = {1, 10, 30, 60}\r
+            self.period = int(attributes["period"])\r
+            if self.period == 0:\r
+                self.isPeriodic = False\r
+            elif self.period not in period_suppor_value:\r
+                self.period = 0\r
+                print("[WARNING]:rotate image period value not support, using defalut value 0")\r
+            else:\r
+                self.isPeriodic = True\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode = 1\r
+            elif display_mode == "always":\r
+                self.displayMode = 2\r
+        if self.displayMode != 0:\r
+            if "ambient_periodic" in attributes.getNames():\r
+                if attributes["ambient_periodic"] == "true":\r
+                    self.isAmbientPeriodic = True\r
+\r
+    def get_bytes(self):\r
+        return bytes(self)\r
+\r
+    def get_size(self):\r
+        return sizeof(self)
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_sequence_img.py b/tools/dial_tools/dial_converter_tool/dial_sequence_img.py
new file mode 100644 (file)
index 0000000..5f6a06e
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialSequenceImg(Structure):\r
+    _fields_ = [\r
+        ('pos', Point),\r
+        ('interval', c_ushort),\r
+        ('repeat', c_bool),\r
+        ('imgNum', c_ubyte),\r
+        ('displayMode', c_ubyte)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.imgId = []\r
+        self.period = 0\r
+        self.displayMode = 0\r
+\r
+    def parse_attributes(self, attributes):\r
+        x,y = attributes["position"].split(" ")\r
+        self.pos.x = int(x)\r
+        if self.pos.x < np.iinfo(np.int16).min or self.pos.x > np.iinfo(np.int16).max :\r
+            print("[ERR]:sequence image pos x out of range")\r
+            sys.exit(1)\r
+\r
+        self.pos.y = int(y)\r
+        if self.pos.y < np.iinfo(np.int16).min or self.pos.y > np.iinfo(np.int16).max :\r
+            print("[ERR]:sequence image pos y out of range")\r
+            sys.exit(1)\r
+\r
+        if attributes["repeat"].lower() == "true" :\r
+            self.repeat = True\r
+        elif attributes["repeat"].lower() == "false" :\r
+            self.repeat = False\r
+        else:\r
+            print("[ERR]:sequence image repeat only 'True' or 'False'")\r
+            sys.exit(1)\r
+\r
+        interval = int(attributes["interval"])\r
+        if interval < 0 or interval > np.iinfo(np.int16).max :\r
+            print("[ERR]: sequence image interval out of range")\r
+            sys.exit(1)\r
+        else:\r
+            self.interval = interval\r
+\r
+        imgNames = attributes["img_names"].split(",")\r
+        self.imgNum = len(imgNames)\r
+        for img in imgNames:\r
+            imgId = img_convert.instance.convert_img(img)\r
+            self.imgId.append(imgId)\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+\r
+    def get_bytes(self):\r
+        ret = bytes(self)\r
+        for index in range(self.imgNum):\r
+            ret += struct.pack('@H', self.imgId[index])\r
+        return ret\r
+\r
+    def get_size(self):\r
+        return sizeof(self) + sizeof(c_ushort) * self.imgNum
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dial_static_img.py b/tools/dial_tools/dial_converter_tool/dial_static_img.py
new file mode 100644 (file)
index 0000000..e057171
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Point\r
+import img_convert\r
+\r
+class DialStaticImg(Structure):\r
+    _fields_ = [\r
+        ('pos', Point),\r
+        ('center', Point),\r
+        ('rotate', c_float),\r
+        ('imgId', c_ushort),\r
+        ('displayMode', c_ubyte),\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.imgId = 0\r
+        self.center.x = 0\r
+        self.center.y = 0\r
+        self.rotate = 0.0\r
+        self.period = 0\r
+        self.displayMode = 0\r
+\r
+    def parse_attributes(self, attributes):\r
+        input_pos_x, input_pos_y = attributes["position"].split(" ")\r
+        self.pos.x = int(input_pos_x)\r
+        if self.pos.x < np.iinfo(np.int16).min or self.pos.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:static image pos x out of range")\r
+            sys.exit(1)\r
+\r
+        self.pos.y = int(input_pos_y)\r
+        if self.pos.y < np.iinfo(np.int16).min or self.pos.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:static image pos y out of range")\r
+            sys.exit(1)\r
+\r
+        self.imgId = img_convert.instance.convert_img(attributes["img_name"])\r
+\r
+        for attr in attributes.getNames():\r
+            if attr == "center":\r
+                input_center_x,input_center_y = attributes["center"].split(" ")\r
+                self.center.x = int(input_center_x)\r
+                if self.center.x < np.iinfo(np.int16).min or self.center.x > np.iinfo(np.int16).max:\r
+                    print("[ERR]:static image center x out of range")\r
+                    sys.exit(1)\r
+\r
+                self.center.y = int(input_center_y)\r
+                if self.center.y < np.iinfo(np.int16).min or self.center.y > np.iinfo(np.int16).max:\r
+                    print("[ERR]:static image center y out of range")\r
+                    sys.exit(1)\r
+            elif attr == "rotate":\r
+                rotate = float(attributes["rotate"])\r
+                if rotate < 0.0 or rotate > 360.0 :\r
+                    print("[ERR]:static image rotate out of range, [0, 360]")\r
+                    sys.exit(1)\r
+                self.rotate = rotate\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode = 1\r
+            elif display_mode == "always":\r
+                self.displayMode = 2\r
+\r
+    def get_bytes(self):\r
+        return bytes(self)\r
+\r
+    def get_size(self):\r
+        return sizeof(self)\r
diff --git a/tools/dial_tools/dial_converter_tool/dial_video.py b/tools/dial_tools/dial_converter_tool/dial_video.py
new file mode 100644 (file)
index 0000000..ecc263f
--- /dev/null
@@ -0,0 +1,61 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import numpy as np\r
+from xml.dom.minidom import parse\r
+from ctypes import *\r
+from common_types import Rect\r
+import video_convert\r
+import img_convert\r
+\r
+class DialVideo(Structure):\r
+    _fields_ = [\r
+        ('rect', Rect),\r
+        ('offset', c_uint),\r
+        ('colorKey', c_uint),\r
+        ('imgId', c_uint),\r
+        ('displayMode', c_ubyte)\r
+    ]\r
+\r
+    def __init__(self):\r
+        self.period = 0\r
+        self.displayMode = 0\r
+\r
+    def parse_attributes(self, attributes):\r
+        x,y,w,h = attributes["rect"].split(" ")\r
+        self.rect.x = int(x)\r
+        if self.rect.x < np.iinfo(np.int16).min or self.rect.x > np.iinfo(np.int16).max:\r
+            print("[ERR]:video rect x out of range")\r
+            sys.exit(1)\r
+        self.rect.y = int(y)\r
+        if self.rect.y < np.iinfo(np.int16).min or self.rect.y > np.iinfo(np.int16).max:\r
+            print("[ERR]:video rect y out of range")\r
+            sys.exit(1)\r
+        self.rect.w = int(w)\r
+        if self.rect.w < np.iinfo(np.int16).min or self.rect.w > np.iinfo(np.int16).max:\r
+            print("[ERR]:video rect w out of range")\r
+            sys.exit(1)\r
+        self.rect.h = int(h)\r
+        if self.rect.h < np.iinfo(np.int16).min or self.rect.h > np.iinfo(np.int16).max:\r
+            print("[ERR]:video rect h out of range")\r
+            sys.exit(1)\r
+\r
+        self.colorKey = int(attributes["color_key"], 16)\r
+        self.offset = video_convert.instance.convert_video(attributes["source"])\r
+        self.imgId = img_convert.instance.convert_img(attributes["preview_frame"])\r
+\r
+        if "display_mode" in attributes.getNames():\r
+            display_mode = attributes["display_mode"]\r
+            if display_mode == "normal":\r
+                self.displayMode = 0\r
+            elif display_mode == "ambient":\r
+                self.displayMode= 1\r
+            elif display_mode == "always":\r
+                self.displayMode= 2\r
+\r
+    def get_bytes(self):\r
+        return bytes(self)\r
+\r
+    def get_size(self):\r
+        return sizeof(self)
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/dll/linux_cs/libcodec.so b/tools/dial_tools/dial_converter_tool/dll/linux_cs/libcodec.so
new file mode 100644 (file)
index 0000000..b9cf3fb
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/dll/linux_cs/libcodec.so differ
diff --git a/tools/dial_tools/dial_converter_tool/dll/linux_es/libcodec.so b/tools/dial_tools/dial_converter_tool/dll/linux_es/libcodec.so
new file mode 100644 (file)
index 0000000..ddb8838
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/dll/linux_es/libcodec.so differ
diff --git a/tools/dial_tools/dial_converter_tool/dll/x64/release_cs/ICE_V5R1_BLOCK_HTC.dll b/tools/dial_tools/dial_converter_tool/dll/x64/release_cs/ICE_V5R1_BLOCK_HTC.dll
new file mode 100644 (file)
index 0000000..7f5174e
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/dll/x64/release_cs/ICE_V5R1_BLOCK_HTC.dll differ
diff --git a/tools/dial_tools/dial_converter_tool/dll/x64/release_cs/ICE_V5R1_BLOCK_HTC.lib b/tools/dial_tools/dial_converter_tool/dll/x64/release_cs/ICE_V5R1_BLOCK_HTC.lib
new file mode 100644 (file)
index 0000000..b339838
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/dll/x64/release_cs/ICE_V5R1_BLOCK_HTC.lib differ
diff --git a/tools/dial_tools/dial_converter_tool/dll/x64/release_es/ICE_V5R1_BLOCK_HTC.dll b/tools/dial_tools/dial_converter_tool/dll/x64/release_es/ICE_V5R1_BLOCK_HTC.dll
new file mode 100644 (file)
index 0000000..4b74cd6
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/dll/x64/release_es/ICE_V5R1_BLOCK_HTC.dll differ
diff --git a/tools/dial_tools/dial_converter_tool/dll/x64/release_es/ICE_V5R1_BLOCK_HTC.lib b/tools/dial_tools/dial_converter_tool/dll/x64/release_es/ICE_V5R1_BLOCK_HTC.lib
new file mode 100644 (file)
index 0000000..811632b
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/dll/x64/release_es/ICE_V5R1_BLOCK_HTC.lib differ
diff --git a/tools/dial_tools/dial_converter_tool/img_convert.py b/tools/dial_tools/dial_converter_tool/img_convert.py
new file mode 100644 (file)
index 0000000..3c8dfad
--- /dev/null
@@ -0,0 +1,301 @@
+import base64\r
+from PIL import Image\r
+from io import BytesIO\r
+import cv2\r
+import ctypes\r
+from ctypes import *\r
+from PIL import Image\r
+\r
+import os\r
+import sys\r
+import struct\r
+import time\r
+import platform\r
+import numpy as np\r
+import pickle as p\r
+import requests\r
+import matplotlib.pyplot as pyplot\r
+\r
+global dll\r
+if platform.system().lower() == 'windows':\r
+    dll = ctypes.CDLL(r".\dll\x64\release_cs\ICE_V5R1_BLOCK_HTC.dll")\r
+elif platform.system().lower() == 'linux':\r
+    dll = ctypes.CDLL(sys.path[0] + r"/dll/linux_cs/libcodec.so")\r
+\r
+class Header(ctypes.Structure):\r
+    _fields_ = [\r
+        ("width", c_uint),\r
+        ("height", c_uint),\r
+        ("stride", c_uint),\r
+        ("pixel_format", c_uint),\r
+        ("tile_width", c_uint),\r
+        ("mode_alpha", c_uint),\r
+        ("mode_rgb", c_uint)\r
+    ]\r
+\r
+class BsData(ctypes.Structure):\r
+    _fields_ = [\r
+        ("bs_data", POINTER(c_ubyte)),\r
+        ("data_size", c_uint),\r
+        ("cmp_ratio", c_uint),\r
+        ("is_valid", c_uint),\r
+        ("subjective_review", c_uint),\r
+        ("para", Header)\r
+    ]\r
+\r
+class AutoCmpOutput(ctypes.Structure):\r
+    _fields_ = [\r
+        ("cmp_bs0", POINTER(BsData)),\r
+        ("cmp_bs1", POINTER(BsData)),\r
+        ("cmp_bs2", POINTER(BsData)),\r
+        ("cmp_bs3", POINTER(BsData)),\r
+        ("auto_cmp_mode", c_uint),\r
+        ("valid_bs_num", c_uint)\r
+    ]\r
+\r
+class CmpInput(ctypes.Structure):\r
+    _fields_ = [\r
+        ("width", c_uint),\r
+        ("height", c_uint),\r
+        ("stride", c_uint),\r
+        ("pixel_format", c_uint),\r
+        ("tile_width", c_uint),\r
+        ("mode_alpha", c_uint),\r
+        ("mode_rgb", c_uint),\r
+        ("red_channel", POINTER(c_ubyte)),\r
+        ("green_channel", POINTER(c_ubyte)),\r
+        ("blue_channel", POINTER(c_ubyte)),\r
+        ("alpha_channel", POINTER(c_ubyte))\r
+    ]\r
+\r
+class AutoCmpInput(ctypes.Structure):\r
+    _fields_ =[\r
+        ("auto_cmp_mode", c_uint),\r
+        ("high_quality_mode", c_uint),\r
+        ("high_cmp_ratio_mode", c_uint),\r
+        ("cmp_in", POINTER(CmpInput))\r
+    ]\r
+\r
+class BinHeader(ctypes.Structure):\r
+    _fields_ = [\r
+        ("dirId", c_uint),\r
+        ("count", c_uint)\r
+    ]\r
+\r
+class SeekInfo(ctypes.Structure):\r
+    _fields_ = [\r
+        ("offset", c_uint),\r
+        ("size", c_uint)\r
+    ]\r
+\r
+class ImageHeader(ctypes.Structure):\r
+    _fields_ = [\r
+        ("colorMode", c_uint, 8),\r
+        ("version", c_uint, 4),\r
+        ("compressMode", c_uint, 4),\r
+        ("reserved", c_uint, 16),\r
+        ("width", c_ushort),\r
+        ("height", c_ushort)\r
+    ]\r
+\r
+class ImageConverTool():\r
+    binHeader = BinHeader()\r
+    binHeader.dirId = 0xfef\r
+    seekInfo = []\r
+    imageHeader = []\r
+    imageData = []\r
+    imageNum = 0\r
+    isConvertedFile = []\r
+    tile_width_support = {4, 6, 8, 16}\r
+\r
+    def __init__(self):\r
+        self.markCurOffset = 0\r
+        self.width = 0\r
+        self.height = 0\r
+        self.file_alpha = False\r
+        self.cmp_mode = "HFBC"\r
+        self.color_fmt = ' '\r
+        self.align = 1\r
+        self.tile_width = 6\r
+        self.mode_alpha = 1\r
+        self.mode_rgb = 1\r
+        self.auto_cmp_mode = 0\r
+        self.high_quality_mode = 0\r
+        self.high_cmp_ratio_mode = 0\r
+        self.version = 1\r
+\r
+    def set_tile_width(self, tile_width):\r
+        if tile_width not in self.tile_width_support:\r
+            print("[ERR]:The tile_width:{tile_width} value is not supported.")\r
+            sys.exit(1)\r
+\r
+        self.tile_width = tile_width\r
+\r
+    def _convert(self):\r
+        width, height = self.image.size\r
+        self.width = width\r
+        self.height = height\r
+        self.stride_pixel = (self.width + self.align - 1) // self.align * self.align\r
+        if len(self.image.split()) > 3:\r
+            self.file_alpha = True\r
+        else:\r
+            self.file_alpha = False\r
+\r
+        # initialize CmpInput\r
+        cmp_input = CmpInput()\r
+        self._get_cmp_input(cmp_input)\r
+        auto_cmp_input = AutoCmpInput()\r
+        self._get_auto_cmp_input(auto_cmp_input, cmp_input)\r
+\r
+        # call GetBufferSize to get buffer size\r
+        # initialize CmpOutput\r
+        auto_cmp_output = AutoCmpOutput()\r
+\r
+        cmp_bs0 = BsData()\r
+        buf_size0 = dll.ice_v5r1_block_get_buffer_size(byref(cmp_input))  # 压缩后输出数据的大小\r
+        cmp_bs0.bs_data = (c_ubyte * buf_size0)()\r
+        auto_cmp_output.cmp_bs0 = ctypes.cast(pointer(cmp_bs0), POINTER(BsData))\r
+        ret = dll.ice_v5r1_block_htc_auto_cmp(byref(auto_cmp_input), byref(auto_cmp_output))  # 对输入数据进行压缩返回值是函数正常运行标志位\r
+\r
+        # add imageinfo to list\r
+        self.binHeader.count += 1\r
+\r
+        imageInfo = ImageHeader()\r
+        imageInfo.width = self.width\r
+        imageInfo.height = self.height\r
+        imageInfo.colorMode = self._get_color_mode()\r
+        imageInfo.version = 1\r
+        imageInfo.compressMode = 4\r
+        imageInfo.reserved = 0\r
+        seekInfo = SeekInfo()\r
+        seekInfo.offset = self.markCurOffset\r
+        seekInfo.size = sizeof(imageInfo) + cmp_bs0.data_size\r
+        self.markCurOffset += seekInfo.size\r
+        self.seekInfo.append(seekInfo)\r
+        self.imageHeader.append(imageInfo)\r
+        self.imageData.append(cmp_bs0)\r
+        self.imageNum += 1\r
+        return self.imageNum\r
+\r
+    def _check_path(self, path):\r
+        if not os.path.exists(path):\r
+            print("[ERROR]:", path, "is not exist")\r
+            return False\r
+        else:\r
+            if (not path[-3:].lower() == "png") and (not path[-3:].lower() == "jpg") and (not path[-3:].lower() == "bmp"):\r
+                print("[ERROR]:", path, "is not jpg or png or bmp format image")\r
+                return False\r
+        return True\r
+\r
+    def convert_img(self, path):\r
+        if path in self.isConvertedFile:\r
+            return self.isConvertedFile.index(path) + 1\r
+\r
+        if not self._check_path(path):\r
+            sys.exit(1)\r
+\r
+        self.image = Image.open(path)\r
+        if self.image.mode == 'RGBA':\r
+            self.color_fmt = 'ARGB8888'\r
+        elif self.image.mode == 'RGB':\r
+            self.color_fmt = 'RGB888'\r
+        self.isConvertedFile.append(path)\r
+        return self._convert()\r
+\r
+    def _get_cmp_px_format(self):\r
+        if self.color_fmt == 'RGB565':\r
+            return 2\r
+        elif self.color_fmt == 'RGB888':\r
+            return 0\r
+        elif self.color_fmt == 'ARGB8888':\r
+            return 1\r
+\r
+    def _get_color_mode(self):\r
+        if self.color_fmt == 'RGB565':\r
+            return 2\r
+        elif self.color_fmt == 'RGB888':\r
+            return 1\r
+        elif self.color_fmt == 'ARGB8888':\r
+            return 0\r
+\r
+    def _get_auto_cmp_input(self, auto_cmp_input, cmp_input):\r
+        auto_cmp_input.auto_cmp_mode = self.auto_cmp_mode\r
+        auto_cmp_input.high_quality_mode = self.high_quality_mode\r
+        auto_cmp_input.high_cmp_ratio_mode = self.high_cmp_ratio_mode\r
+        auto_cmp_input.cmp_in = ctypes.cast(pointer(cmp_input), POINTER(CmpInput))\r
+\r
+    def _get_cmp_input(self, cmp_input):\r
+        cmp_input.width = self.width\r
+        cmp_input.height = self.height\r
+        cmp_input.stride = self.width\r
+        cmp_input.tile_width = self.tile_width\r
+        cmp_input.mode_alpha = self.mode_alpha\r
+        cmp_input.mode_rgb = self.mode_rgb\r
+        cmp_input.pixel_format = self._get_cmp_px_format()\r
+        size = self.width * self.height\r
+        red = (c_ubyte * size)()\r
+        green = (c_ubyte * size)()\r
+        blue = (c_ubyte * size)()\r
+        alpha = (c_ubyte * size)()\r
+\r
+        for row in range(self.height):\r
+            for col in range(self.width):\r
+                position = row * self.width + col\r
+                red[position] = self.image.getdata()[position][0]\r
+                green[position] = self.image.getdata()[position][1]\r
+                blue[position] = self.image.getdata()[position][2]\r
+                if self.file_alpha == False:\r
+                    alpha[position] = 0xFF\r
+                else:\r
+                    alpha[position] = self.image.getdata()[position][3]\r
+        cmp_input.red_channel = red\r
+        cmp_input.green_channel = green\r
+        cmp_input.blue_channel = blue\r
+        cmp_input.alpha_channel = alpha\r
+\r
+    def write_data_to_bin(self, fb):\r
+        fb.write(bytes(self.binHeader))\r
+        for seek in self.seekInfo:\r
+            fb.write(bytes(seek))\r
+\r
+        for index in range(0, self.imageNum):\r
+            bt = bytearray()\r
+            color_fmt = self.imageHeader[index].colorMode\r
+            header = color_fmt + (self.imageHeader[index].width << 32) + \\r
+                    (self.imageHeader[index].height << 48) + (self.imageHeader[index].version << 8)\r
+            header_bin = struct.pack("<Q", header)\r
+\r
+            if (self.cmp_mode == "HFBC"):\r
+                header = header + (4 << 12)\r
+            elif (self.cmp_mode == "HFBC_ABYPASS"):\r
+                header = header + (5 << 12)\r
+\r
+            header_bin = struct.pack("<Q", header)\r
+            bt += header_bin\r
+            for i in range(self.imageData[index].data_size):\r
+                bt += struct.pack("B", self.imageData[index].bs_data[i])\r
+            fb.writelines([bt])\r
+\r
+    def get_size(self):\r
+        ret = sizeof(self.binHeader)\r
+        ret += len(self.seekInfo) * sizeof(SeekInfo)\r
+        for index in range(0, self.imageNum):\r
+            bt = bytearray()\r
+            color_fmt = self._get_cmp_px_format()\r
+            header = color_fmt + (self.imageHeader[index].width << 32) + \\r
+                    (self.imageHeader[index].height << 48) + (self.imageHeader[index].version << 8)\r
+            header_bin = struct.pack("<Q", header)\r
+\r
+            if (self.cmp_mode == "HFBC"):\r
+                header = header + (4 << 12)\r
+            elif (self.cmp_mode == "HFBC_ABYPASS"):\r
+                header = header + (5 << 12)\r
+\r
+            header_bin = struct.pack("<Q", header)\r
+            bt += header_bin\r
+            for i in range(self.imageData[index].data_size):\r
+                bt += struct.pack("B", self.imageData[index].bs_data[i])\r
+            ret += len(bt)\r
+        return ret\r
+\r
+instance = ImageConverTool()\r
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/BIGCIRCLE_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/BIGCIRCLE_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..e6e3822
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/BIGCIRCLE_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/HEARTRATE_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/HEARTRATE_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..18e4557
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/HEARTRATE_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/HOURHAND.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/HOURHAND.png
new file mode 100644 (file)
index 0000000..77cf955
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/HOURHAND.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MAIN_FACE_IMAGE.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MAIN_FACE_IMAGE.png
new file mode 100644 (file)
index 0000000..e9369ea
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MAIN_FACE_IMAGE.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MEDCIRCLE_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MEDCIRCLE_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..7a47b8f
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MEDCIRCLE_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MINUTEHAND.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MINUTEHAND.png
new file mode 100644 (file)
index 0000000..f4b1dbe
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/MINUTEHAND.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/PROGRESS_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/PROGRESS_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..9545cff
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/PROGRESS_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/SECONDHAND.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/SECONDHAND.png
new file mode 100644 (file)
index 0000000..147de5f
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/SECONDHAND.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/SMALLCIRCLE_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/SMALLCIRCLE_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..54d9901
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/SMALLCIRCLE_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/analogue_dial.xml b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/analogue_dial.xml
new file mode 100644 (file)
index 0000000..3387c94
--- /dev/null
@@ -0,0 +1,15 @@
+<dial ambient_period="10" title="clock" description="main clock" size="454 454" version="2.0" preview_img="./instance/analogue_dial/preview_img.JPG">\r
+    <static_img id="back_ground" position="0 0" img_name="./instance/analogue_dial/MAIN_FACE_IMAGE.png"></static_img>\r
+    <option_img position="207 127" img_names="./instance/analogue_dial/week/MONDAY_IMAGE_PATH.png,./instance/analogue_dial/week/TUESDAY_IMAGE_PATH.png,./instance/analogue_dial/week/WEDNESDAY_IMAGE_PATH.png,./instance/analogue_dial/week/THURSDAY_IMAGE_PATH.png,./instance/analogue_dial/week/FIRDAY_IMAGE_PATH.png,./instance/analogue_dial/week/SATURDAY_IMAGE_PATH.png,./instance/analogue_dial/week/SUNDAY_IMAGE_PATH.png" bind_data="17" period="10"></option_img>\r
+    <label display_mode="normal" id="step_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="ellipsis" rect="100 230 75 35" text="%5.0f" font_size="25" align="center" bind_data="1" period="10"></label>\r
+    <static_img id="heart_rate" position="156 260" img_name="./instance/analogue_dial/HEARTRATE_IMAGE_PATH.png"></static_img>\r
+    <label display_mode="ambient" ambient_periodic="true" id="heart_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="ellipsis" rect="198 330 60 35" text="%3.0f" font_size="25" align="center" bind_data="2" period="10"></label>\r
+    <static_img id="progress" position="53 54" img_name="./instance/analogue_dial/PROGRESS_IMAGE_PATH.png"></static_img>\r
+    <label id="battery_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="ellipsis" rect="315 230 60 35" text="%2.0f%%" font_size="25" align="center" bind_data="8" period="10"></label>\r
+    <rotate_img id="hour" position="202 16" rotate_center="25.0 211.0" rotate_start="0" rotate_end="360" img_name="./instance/analogue_dial/HOURHAND.png" bind_data="9" period="10"></rotate_img>\r
+    <static_img id="hour_circle" position="202 202" img_name="./instance/analogue_dial/BIGCIRCLE_IMAGE_PATH.png"></static_img>\r
+    <rotate_img id="minute" position="202 16" rotate_center="25.0 211.0" rotate_start="0" rotate_end="360" img_name="./instance/analogue_dial/MINUTEHAND.png" bind_data="10" period="10"></rotate_img>\r
+    <static_img display_mode="ambient" id="minute_circle" position="202 202" img_name="./instance/analogue_dial/MEDCIRCLE_IMAGE_PATH.png"></static_img>\r
+    <rotate_img display_mode="always" ambient_periodic="true" id="second" position="202 16" rotate_center="25.0 211.0" rotate_start="0" rotate_end="360" img_name="./instance/analogue_dial/SECONDHAND.png" bind_data="12" period="60"></rotate_img>\r
+    <static_img id="second_circle" position="215 213" img_name="./instance/analogue_dial/SMALLCIRCLE_IMAGE_PATH.png"></static_img>\r
+</dial>
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/preview_img.JPG b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/preview_img.JPG
new file mode 100644 (file)
index 0000000..2b1ee83
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/preview_img.JPG differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/FIRDAY_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/FIRDAY_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..9c39932
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/FIRDAY_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/MONDAY_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/MONDAY_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..58d2cdd
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/MONDAY_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/SATURDAY_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/SATURDAY_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..861ad16
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/SATURDAY_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/SUNDAY_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/SUNDAY_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..1a09471
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/SUNDAY_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/THURSDAY_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/THURSDAY_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..a2e27c6
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/THURSDAY_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/TUESDAY_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/TUESDAY_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..c5b292d
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/TUESDAY_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/WEDNESDAY_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/WEDNESDAY_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..e099b56
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/analogue_dial/week/WEDNESDAY_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/BIGCIRCLE_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/BIGCIRCLE_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..e6e3822
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/BIGCIRCLE_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/HOURHAND.png b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/HOURHAND.png
new file mode 100644 (file)
index 0000000..77cf955
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/HOURHAND.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/MEDCIRCLE_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/MEDCIRCLE_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..7a47b8f
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/MEDCIRCLE_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/MINUTEHAND.png b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/MINUTEHAND.png
new file mode 100644 (file)
index 0000000..f4b1dbe
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/MINUTEHAND.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/SECONDHAND.png b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/SECONDHAND.png
new file mode 100644 (file)
index 0000000..147de5f
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/SECONDHAND.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/SMALLCIRCLE_IMAGE_PATH.png b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/SMALLCIRCLE_IMAGE_PATH.png
new file mode 100644 (file)
index 0000000..54d9901
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/SMALLCIRCLE_IMAGE_PATH.png differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/kaleidoscope_dial.xml b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/kaleidoscope_dial.xml
new file mode 100644 (file)
index 0000000..4c1511e
--- /dev/null
@@ -0,0 +1,9 @@
+<dial title="kaleidoscope" description="kaleidoscope dial" size="454 454" version="1.0" preview_img="./instance/kaleidoscope_dial/preview_img.PNG">\r
+    <kaleidoscope id="kale" img_name="./instance/kaleidoscope_dial/rabbit454.png" crown_rotate_step="0.2" animator_rotate_step="0.1"></kaleidoscope>\r
+    <rotate_img id="hour" position="202 16" rotate_center="25.0 211.0" rotate_start="0" rotate_end="360" img_name="./instance/kaleidoscope_dial/HOURHAND.png" bind_data="9" period="10"></rotate_img>\r
+    <static_img id="hour_circle" position="202 202" img_name="./instance/kaleidoscope_dial/BIGCIRCLE_IMAGE_PATH.png"></static_img>\r
+    <rotate_img id="minute" position="202 16" rotate_center="25.0 211.0" rotate_start="0" rotate_end="360" img_name="./instance/kaleidoscope_dial/MINUTEHAND.png" bind_data="10" period="10"></rotate_img>\r
+    <static_img id="minute_circle" position="202 202" img_name="./instance/kaleidoscope_dial/MEDCIRCLE_IMAGE_PATH.png"></static_img>\r
+    <rotate_img id="second" position="202 16" rotate_center="25.0 211.0" rotate_start="0" rotate_end="360" img_name="./instance/kaleidoscope_dial/SECONDHAND.png" bind_data="12" period="60"></rotate_img>\r
+    <static_img id="second_circle" position="215 213" img_name="./instance/kaleidoscope_dial/SMALLCIRCLE_IMAGE_PATH.png"></static_img>\r
+</dial>
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/preview_img.PNG b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/preview_img.PNG
new file mode 100644 (file)
index 0000000..9d7239d
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/preview_img.PNG differ
diff --git a/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/rabbit454.png b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/rabbit454.png
new file mode 100644 (file)
index 0000000..d937bf2
Binary files /dev/null and b/tools/dial_tools/dial_converter_tool/instance/kaleidoscope_dial/rabbit454.png differ
diff --git a/tools/dial_tools/dial_converter_tool/main.py b/tools/dial_tools/dial_converter_tool/main.py
new file mode 100644 (file)
index 0000000..26b6ed6
--- /dev/null
@@ -0,0 +1,46 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+# 1\ 解析命令 python main.py -d [DIR] -o [OUT_DIR]\r
+# 2\ 循环执行svg解析写入\r
+import sys\r
+import os\r
+import argparse\r
+from converter import DialConvertTool\r
+\r
+def GetParameters():\r
+    parser = argparse.ArgumentParser()\r
+\r
+    parser.add_argument('-file', '-f', type=str, default='', required=False,\r
+                        help='Specifies the path of the offline watch face XML file to be converted.')\r
+\r
+    parser.add_argument('-dir', '-d', type=str, default='', required=False,\r
+                        help='Specifies the path of the folder to be converted. Convert all .xml files in the folder according to the specified path.')\r
+\r
+    parser.add_argument('-output', type=str, default=os.getcwd() + "/out", required=False,\r
+                        help='output dir')\r
+\r
+    config = parser.parse_args()\r
+    return config\r
+\r
+if __name__ == "__main__":\r
+    userInput = GetParameters()\r
+    outputPath = userInput.output\r
+    inputFile = userInput.file\r
+    inputDir = userInput.dir\r
+    # Create an output folder.\r
+    print("output dir : " + outputPath)\r
+    if not os.path.exists(outputPath):\r
+        os.mkdir(outputPath)\r
+\r
+    if not os.path.isdir(inputFile) and inputFile[-3:].lower() == "xml":\r
+        print("input file : " + inputFile)\r
+        converter = DialConvertTool()\r
+        converter.convert_xml_to_output(inputFile, outputPath)\r
+\r
+    print("inputdir", inputDir)\r
+    files = os.listdir(inputDir)\r
+    print("input dir : " + inputDir)\r
+    for file in files:\r
+        if not os.path.isdir(file) and file[-3:].lower() == "xml":\r
+            converter = DialConvertTool()\r
+            converter.convert_xml_to_output(inputDir + "/" + file, outputPath)
\ No newline at end of file
diff --git a/tools/dial_tools/dial_converter_tool/video_convert.py b/tools/dial_tools/dial_converter_tool/video_convert.py
new file mode 100644 (file)
index 0000000..d447a16
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/python\r
+# coding: utf-8\r
+import sys\r
+import struct\r
+import ctypes\r
+from ctypes import *\r
+\r
+class VideoConvertTool:\r
+    def __init__(self):\r
+        self.videoNum = 0\r
+        self.videoName = []\r
+        self.videoIndex = []\r
+        self.videoData = bytearray()\r
+\r
+    def convert_video(self, path):\r
+        if path in self.videoName:\r
+            index = self.videoName.index(path)\r
+            return self.videoIndex[index]\r
+        fp = open(path, 'rb')\r
+        data = fp.read()\r
+        fp.close()\r
+        self.videoName.append(path)\r
+        self.videoNum += 1\r
+        ret = len(self.videoData)\r
+        self.videoIndex.append(ret)\r
+        self.videoData += data\r
+        return ret\r
+\r
+    def write_data_to_bin(self, fb):\r
+        fb.write(self.videoData)\r
+\r
+instance = VideoConvertTool()\r
index 37f9fc3..b191a24 100644 (file)
Binary files a/tools/dial_tools/dial_lzma/207/owl_clock.lzma and b/tools/dial_tools/dial_lzma/207/owl_clock.lzma differ
diff --git a/tools/dial_tools/dial_lzma/207/owl_clock.png b/tools/dial_tools/dial_lzma/207/owl_clock.png
new file mode 100644 (file)
index 0000000..6e8149c
Binary files /dev/null and b/tools/dial_tools/dial_lzma/207/owl_clock.png differ
diff --git a/tools/dial_tools/dial_lzma/207/说明.txt b/tools/dial_tools/dial_lzma/207/说明.txt
new file mode 100644 (file)
index 0000000..552bbac
--- /dev/null
@@ -0,0 +1,3 @@
+中文名:动态小鹰\r
+英文名:owl clock\r
+标签:数码表盘;\r
index 3fd9e6d..afe1ca4 100644 (file)
@@ -6,15 +6,20 @@
     <!-- 时间段背景切换(已实现系统端映射逻辑) -->\r
     <option_img position="0 0" img_names="./instance/207/BACKGROUND_0_6.png,./instance/207/BACKGROUND_6_12.png,./instance/207/BACKGROUND_12_18.png,./instance/207/BACKGROUND_18_24.png" bind_data="37" period="10"></option_img>\r
     \r
-    <!-- 数字时间显示 - 小时 -->\r
-    <label id="hour_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="adapt" rect="86 162 200 60" text="%02.f" font_size="120" align="center" bind_data="15" period="10" display_mode="always" ambient_periodic="true"></label>\r
-    \r
-    <!-- 数字时间显示 - 分钟 -->\r
-    <label id="minute_label" color="0xFF666666" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="adapt" rect="240 162 200 60" text="%02.f" font_size="120" align="center" bind_data="14" period="10" display_mode="always" ambient_periodic="true"></label>\r
-    \r
-    <!-- 电池显示 -->\r
-    <option_img position="173 52" img_names="./instance/207/Battery/Battery_Nomoal.png,./instance/207/Battery/BatteryCharge.png" bind_data="20" period="10"></option_img>\r
-    \r
+\r
+    <!-- 月份显示 -->\r
+    <label id="month_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="adapt" rect="186 120 60 30" text="%02.0f-" font_size="36" align="center" bind_data="18" period="10"></label>\r
+    <!-- 日期显示 -->\r
+    <label id="day_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="adapt" rect="246 120 60 30" text="%02.0f" font_size="36" align="center" bind_data="16" period="10"></label>\r
+\r
+    <!-- 小时和分钟     -->\r
+    <label id="hour_ten_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="ellipsis" rect="83 280 300 120" text="%s" font_size="90" align="center" bind_data="20483" period="10"></label>\r
+\r
+    <!-- 电池进度条 -->\r
+    <box_progress id="battery_progress" rect="224 388 30 18" color="0xFFFFFFFF" cap_type="none" direction="left_to_right" background_color="0x00FFFFFF" bind_data="25" period="10"></box_progress>\r
+    <!-- 电池图像 --> \r
+    <option_img position="217 382" img_names="./instance/1052/Battery/Battery.png,./instance/1052/Battery/BatteryCharge.png" bind_data="20" period="10"></option_img>\r
     <!-- 电池百分比标签 -->\r
-    <label id="battery_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="adapt" rect="228 52 200 62" text="%s" font_size="26" align="center" bind_data="20485" period="10"></label>\r
+    <!-- <label id="battery_label" color="0xFFFFFFFF" font="HarmonyOS_Sans_SC_Regular.ttf" break_mode="adapt" rect="228 394 200 62" text="%s" font_size="26" align="center" bind_data="20485" period="10"></label> -->\r
+\r
 </dial>\r
diff --git a/tools/dial_tools/instance/208/BACKGROUND_0_6.png b/tools/dial_tools/instance/208/BACKGROUND_0_6.png
new file mode 100644 (file)
index 0000000..b366278
Binary files /dev/null and b/tools/dial_tools/instance/208/BACKGROUND_0_6.png differ
diff --git a/tools/dial_tools/instance/208/BACKGROUND_12_18.png b/tools/dial_tools/instance/208/BACKGROUND_12_18.png
new file mode 100644 (file)
index 0000000..aedf4b7
Binary files /dev/null and b/tools/dial_tools/instance/208/BACKGROUND_12_18.png differ
diff --git a/tools/dial_tools/instance/208/BACKGROUND_18_24.png b/tools/dial_tools/instance/208/BACKGROUND_18_24.png
new file mode 100644 (file)
index 0000000..eea5829
Binary files /dev/null and b/tools/dial_tools/instance/208/BACKGROUND_18_24.png differ
diff --git a/tools/dial_tools/instance/208/BACKGROUND_6_12.png b/tools/dial_tools/instance/208/BACKGROUND_6_12.png
new file mode 100644 (file)
index 0000000..4704043
Binary files /dev/null and b/tools/dial_tools/instance/208/BACKGROUND_6_12.png differ
diff --git a/tools/dial_tools/instance/208/HAND_BOTTOM.png b/tools/dial_tools/instance/208/HAND_BOTTOM.png
new file mode 100644 (file)
index 0000000..61e9cc4
Binary files /dev/null and b/tools/dial_tools/instance/208/HAND_BOTTOM.png differ
diff --git a/tools/dial_tools/instance/208/HAND_TOP.png b/tools/dial_tools/instance/208/HAND_TOP.png
new file mode 100644 (file)
index 0000000..96fbd0e
Binary files /dev/null and b/tools/dial_tools/instance/208/HAND_TOP.png differ
diff --git a/tools/dial_tools/instance/208/HOURHAND.png b/tools/dial_tools/instance/208/HOURHAND.png
new file mode 100644 (file)
index 0000000..82eb6e6
Binary files /dev/null and b/tools/dial_tools/instance/208/HOURHAND.png differ
diff --git a/tools/dial_tools/instance/208/MAIN_FACE_IMAGE.png b/tools/dial_tools/instance/208/MAIN_FACE_IMAGE.png
new file mode 100644 (file)
index 0000000..20b41d7
Binary files /dev/null and b/tools/dial_tools/instance/208/MAIN_FACE_IMAGE.png differ
diff --git a/tools/dial_tools/instance/208/MINUTEHAND.png b/tools/dial_tools/instance/208/MINUTEHAND.png
new file mode 100644 (file)
index 0000000..9a1adfa
Binary files /dev/null and b/tools/dial_tools/instance/208/MINUTEHAND.png differ
diff --git a/tools/dial_tools/instance/208/SECONDHAND.png b/tools/dial_tools/instance/208/SECONDHAND.png
new file mode 100644 (file)
index 0000000..254851e
Binary files /dev/null and b/tools/dial_tools/instance/208/SECONDHAND.png differ
diff --git a/tools/dial_tools/instance/208/essential_sport.png b/tools/dial_tools/instance/208/essential_sport.png
new file mode 100644 (file)
index 0000000..a43339b
Binary files /dev/null and b/tools/dial_tools/instance/208/essential_sport.png differ
diff --git a/tools/dial_tools/instance/208/essential_sport.xml b/tools/dial_tools/instance/208/essential_sport.xml
new file mode 100644 (file)
index 0000000..49a1302
--- /dev/null
@@ -0,0 +1,25 @@
+<dial title="essential_sport" description="精简运动" size="466 466" version="2.0" preview_img="./instance/208/essential_sport.png">\r
+    <static_img id="back_ground" position="0 0" img_name="./instance/208/MAIN_FACE_IMAGE.png"></static_img>\r
+    \r
+    <static_img id="back_ground" position="0 0" img_name="./instance/208/BACKGROUND_6_12.png"></static_img>\r
+    <!-- 时间段背景切换:0-6点、6-12点、12-18点、18-24点 -->\r
+    <!-- 时间段映射:0-5点->0, 6-11点->1, 12-17点->2, 18-23点->3 -->\r
+    <!-- 时间段背景切换(已实现系统端映射逻辑) -->\r
+    <!-- <option_img position="0 0" img_names="./instance/208/BACKGROUND_0_6.png,./instance/208/BACKGROUND_6_12.png,./instance/208/BACKGROUND_12_18.png,./instance/208/BACKGROUND_18_24.png" bind_data="223" period="10"></option_img> -->\r
+\r
+\r
+    <!-- 时针底部背景 -->\r
+    <static_img id="hand_bottom_bg" position="219 219" img_name="./instance/208/HAND_BOTTOM.png"></static_img>\r
+\r
+    <!-- 时针 (11×66) -->\r
+    <rotate_img id="hour" position="228 167" rotate_center="5.0 66.0" rotate_start="0" rotate_end="360" img_name="./instance/208/HOURHAND.png" bind_data="9" period="10"></rotate_img>\r
+    <!-- 分针 (11×130) -->\r
+    <rotate_img id="minute" position="228 103" rotate_center="5.0 130.0" rotate_start="0" rotate_end="360" img_name="./instance/208/MINUTEHAND.png" bind_data="10" period="10"></rotate_img>\r
+    <!-- 秒针 (6×124) -->\r
+    <rotate_img id="second" position="230 128" rotate_center="3.0 105.0" rotate_start="0" rotate_end="360" img_name="./instance/208/SECONDHAND.png" bind_data="12" period="60"></rotate_img>\r
+\r
+    <!-- 时针顶部背景 -->\r
+    <static_img id="hand_top_bg" position="231 228" img_name="./instance/208/HAND_TOP.png"></static_img>\r
+\r
+\r
+</dial>
\ No newline at end of file
diff --git a/tools/dial_tools/lzma_tool/lzma_tool b/tools/dial_tools/lzma_tool/lzma_tool
new file mode 100644 (file)
index 0000000..711d0dc
Binary files /dev/null and b/tools/dial_tools/lzma_tool/lzma_tool differ
diff --git a/tools/dial_tools/lzma_tool/lzma_tool.exe b/tools/dial_tools/lzma_tool/lzma_tool.exe
new file mode 100644 (file)
index 0000000..300ea2f
Binary files /dev/null and b/tools/dial_tools/lzma_tool/lzma_tool.exe differ
diff --git a/tools/dial_tools/lzma_tool/readme.txt b/tools/dial_tools/lzma_tool/readme.txt
new file mode 100644 (file)
index 0000000..36c4b06
--- /dev/null
@@ -0,0 +1,9 @@
+LZMA SDK 21.07
+--------------
+
+UNIX/Linux version
+------------------
+To compile C++ version of file->file LZMA encoding, go to directory
+CPP/7zip/Bundles/LzmaCon
+and call make to recompile it:
+  make -f makefile.gcc clean all
diff --git a/tools/dial_tools/out/owl_clock.bin b/tools/dial_tools/out/owl_clock.bin
new file mode 100644 (file)
index 0000000..dd94dd4
Binary files /dev/null and b/tools/dial_tools/out/owl_clock.bin differ