From 2bf29af9bad53d218d01a311e890cce896074ad5 Mon Sep 17 00:00:00 2001 From: Chenghao Mou Date: Wed, 4 Dec 2024 19:54:56 +0000 Subject: [PATCH 1/5] add small check --- src/rmscene/scene_items.py | 21 +++++++++++++++++++-- src/rmscene/scene_stream.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/rmscene/scene_items.py b/src/rmscene/scene_items.py index 6dcf173..7430288 100644 --- a/src/rmscene/scene_items.py +++ b/src/rmscene/scene_items.py @@ -76,8 +76,7 @@ class PenColor(enum.IntEnum): GRAY_OVERLAP = 8 # All highlight colors share the same value. - # There is also yet unknown extra data in the block - # that might contain additional color information. + # This is a placeholder HIGHLIGHT = 9 GREEN_2 = 10 @@ -86,6 +85,24 @@ class PenColor(enum.IntEnum): YELLOW_2 = 13 + # HIGHLIGHT enumerated + HIGHLIGHT_YELLOW = 14 + HIGHLIGHT_BLUE = 15 + HIGHLIGHT_PINK = 16 + HIGHLIGHT_ORANGE = 17 + HIGHLIGHT_GREEN = 18 + HIGHLIGHT_GRAY = 19 + + # SHADER enumerated + SHADER_GRAY = 20 + SHADER_ORANGE = 21 + SHADER_MAGENTA = 22 + SHADER_BLUE = 23 + SHADER_RED = 24 + SHADER_GREEN = 25 + SHADER_YELLOW = 26 + SHADER_CYAN = 27 + @enum.unique class Pen(enum.IntEnum): diff --git a/src/rmscene/scene_stream.py b/src/rmscene/scene_stream.py index 16e15b2..88b33d4 100644 --- a/src/rmscene/scene_stream.py +++ b/src/rmscene/scene_stream.py @@ -6,12 +6,14 @@ from __future__ import annotations +import io import logging import math import typing as tp from abc import ABC, abstractmethod from collections.abc import Iterable, Iterator from dataclasses import KW_ONLY, dataclass, replace +from typing import Optional from uuid import UUID, uuid4 from packaging.version import Version @@ -430,6 +432,35 @@ def line_from_stream(stream: TaggedBlockReader, version: int = 2) -> si.Line: else: move_id = None + if stream.bytes_remaining_in_block() >= 6: + # ? not sure what this is, seems fixed x84x01 + unk = stream.data.read_bytes(2) + if unk != b"\x84\x01": + # reset to before the unknown bytes just in case + stream.data.data.seek(-2, io.SEEK_CUR) + else: + b = stream.data.read_uint8() + g = stream.data.read_uint8() + r = stream.data.read_uint8() + a = stream.data.read_uint8() + + color = { + (255, 237, 117, 255): si.PenColor.HIGHLIGHT_YELLOW, + (190, 234, 254, 255): si.PenColor.HIGHLIGHT_BLUE, + (242, 158, 255, 255): si.PenColor.HIGHLIGHT_PINK, + (255, 195, 140, 255): si.PenColor.HIGHLIGHT_ORANGE, + (172, 255, 133, 255): si.PenColor.HIGHLIGHT_GREEN, + (199, 199, 198, 255): si.PenColor.HIGHLIGHT_GRAY, + (33, 30, 28, 64): si.PenColor.SHADER_GRAY, + (254, 178, 0, 115): si.PenColor.SHADER_ORANGE, + (192, 127, 210, 128): si.PenColor.SHADER_MAGENTA, + (48, 74, 224, 77): si.PenColor.SHADER_BLUE, + (194, 49, 50, 102): si.PenColor.SHADER_RED, + (145, 218, 113, 128): si.PenColor.SHADER_GREEN, + (250, 231, 25, 115): si.PenColor.SHADER_YELLOW, + (116, 210, 232, 102): si.PenColor.SHADER_CYAN, + }.get((r, g, b, a), color) + return si.Line(color, tool, points, thickness_scale, starting_length, move_id) @@ -492,6 +523,7 @@ def from_stream(cls, stream: TaggedBlockReader) -> SceneItemBlock: assert item_type == subclass.ITEM_TYPE value = subclass.value_from_stream(stream) # Keep known extra data from within the value subblock + extra_value_data = block_info.extra_data else: value = None From 6a01cbd93b5705140eb0469aeca5a95d10746a95 Mon Sep 17 00:00:00 2001 From: Chenghao Mou Date: Wed, 4 Dec 2024 21:28:59 +0000 Subject: [PATCH 2/5] move colormap to items --- src/rmscene/scene_items.py | 18 ++++++++++++++++++ src/rmscene/scene_stream.py | 19 +------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/rmscene/scene_items.py b/src/rmscene/scene_items.py index 7430288..ba13957 100644 --- a/src/rmscene/scene_items.py +++ b/src/rmscene/scene_items.py @@ -103,6 +103,24 @@ class PenColor(enum.IntEnum): SHADER_YELLOW = 26 SHADER_CYAN = 27 +# colors hardcoded in rm files +HIGHLIGHT_COLORMAP = { + (255, 237, 117, 255): PenColor.HIGHLIGHT_YELLOW, + (190, 234, 254, 255): PenColor.HIGHLIGHT_BLUE, + (242, 158, 255, 255): PenColor.HIGHLIGHT_PINK, + (255, 195, 140, 255): PenColor.HIGHLIGHT_ORANGE, + (172, 255, 133, 255): PenColor.HIGHLIGHT_GREEN, + (199, 199, 198, 255): PenColor.HIGHLIGHT_GRAY, + (33, 30, 28, 64): PenColor.SHADER_GRAY, + (254, 178, 0, 115): PenColor.SHADER_ORANGE, + (192, 127, 210, 128): PenColor.SHADER_MAGENTA, + (48, 74, 224, 77): PenColor.SHADER_BLUE, + (194, 49, 50, 102): PenColor.SHADER_RED, + (145, 218, 113, 128): PenColor.SHADER_GREEN, + (250, 231, 25, 115): PenColor.SHADER_YELLOW, + (116, 210, 232, 102): PenColor.SHADER_CYAN, +} + @enum.unique class Pen(enum.IntEnum): diff --git a/src/rmscene/scene_stream.py b/src/rmscene/scene_stream.py index 88b33d4..1ce6045 100644 --- a/src/rmscene/scene_stream.py +++ b/src/rmscene/scene_stream.py @@ -436,30 +436,13 @@ def line_from_stream(stream: TaggedBlockReader, version: int = 2) -> si.Line: # ? not sure what this is, seems fixed x84x01 unk = stream.data.read_bytes(2) if unk != b"\x84\x01": - # reset to before the unknown bytes just in case stream.data.data.seek(-2, io.SEEK_CUR) else: b = stream.data.read_uint8() g = stream.data.read_uint8() r = stream.data.read_uint8() a = stream.data.read_uint8() - - color = { - (255, 237, 117, 255): si.PenColor.HIGHLIGHT_YELLOW, - (190, 234, 254, 255): si.PenColor.HIGHLIGHT_BLUE, - (242, 158, 255, 255): si.PenColor.HIGHLIGHT_PINK, - (255, 195, 140, 255): si.PenColor.HIGHLIGHT_ORANGE, - (172, 255, 133, 255): si.PenColor.HIGHLIGHT_GREEN, - (199, 199, 198, 255): si.PenColor.HIGHLIGHT_GRAY, - (33, 30, 28, 64): si.PenColor.SHADER_GRAY, - (254, 178, 0, 115): si.PenColor.SHADER_ORANGE, - (192, 127, 210, 128): si.PenColor.SHADER_MAGENTA, - (48, 74, 224, 77): si.PenColor.SHADER_BLUE, - (194, 49, 50, 102): si.PenColor.SHADER_RED, - (145, 218, 113, 128): si.PenColor.SHADER_GREEN, - (250, 231, 25, 115): si.PenColor.SHADER_YELLOW, - (116, 210, 232, 102): si.PenColor.SHADER_CYAN, - }.get((r, g, b, a), color) + color = si.HIGHLIGHT_COLORMAP.get((r, g, b, a), color) return si.Line(color, tool, points, thickness_scale, starting_length, move_id) From a0059505f9b4d8c65f685a68e8a37f380ba44901 Mon Sep 17 00:00:00 2001 From: Chenghao Mou Date: Sat, 7 Dec 2024 16:30:36 +0000 Subject: [PATCH 3/5] add new color test --- .gitignore | 1 + src/rmscene/scene_items.py | 6 +- src/rmscene/scene_stream.py | 20 +++--- .../More_color_highlight_shader_v3.15.4.2.rm | Bin 0 -> 12649 bytes tests/test_color_tool.py | 61 +++++++++++++----- 5 files changed, 62 insertions(+), 26 deletions(-) create mode 100644 tests/data/More_color_highlight_shader_v3.15.4.2.rm diff --git a/.gitignore b/.gitignore index 61ca704..ac87258 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __pycache__/ /.hypothesis/ +.DS_Store \ No newline at end of file diff --git a/src/rmscene/scene_items.py b/src/rmscene/scene_items.py index ba13957..555920e 100644 --- a/src/rmscene/scene_items.py +++ b/src/rmscene/scene_items.py @@ -76,7 +76,7 @@ class PenColor(enum.IntEnum): GRAY_OVERLAP = 8 # All highlight colors share the same value. - # This is a placeholder + # This is a placeholder, see HIGHLIGHT_COLORMAP for details. HIGHLIGHT = 9 GREEN_2 = 10 @@ -103,8 +103,8 @@ class PenColor(enum.IntEnum): SHADER_YELLOW = 26 SHADER_CYAN = 27 -# colors hardcoded in rm files -HIGHLIGHT_COLORMAP = { +# colors hardcoded in rm files for highlight and shader +HARDCODED_COLORMAP = { (255, 237, 117, 255): PenColor.HIGHLIGHT_YELLOW, (190, 234, 254, 255): PenColor.HIGHLIGHT_BLUE, (242, 158, 255, 255): PenColor.HIGHLIGHT_PINK, diff --git a/src/rmscene/scene_stream.py b/src/rmscene/scene_stream.py index 1ce6045..e163581 100644 --- a/src/rmscene/scene_stream.py +++ b/src/rmscene/scene_stream.py @@ -432,17 +432,21 @@ def line_from_stream(stream: TaggedBlockReader, version: int = 2) -> si.Line: else: move_id = None + # This is for the color information (highlight & shader) if stream.bytes_remaining_in_block() >= 6: - # ? not sure what this is, seems fixed x84x01 + # not sure what this is, seems fixed x84x01 unk = stream.data.read_bytes(2) - if unk != b"\x84\x01": - stream.data.data.seek(-2, io.SEEK_CUR) + b = stream.data.read_uint8() + g = stream.data.read_uint8() + r = stream.data.read_uint8() + a = stream.data.read_uint8() + rgba = (r, g, b, a) + + if unk != b"\x84\x01" or rgba not in si.HARDCODED_COLORMAP: + _logger.warning(f"Unhandled color {rgba} with prefix {unk}") + stream.data.data.seek(-6, io.SEEK_CUR) else: - b = stream.data.read_uint8() - g = stream.data.read_uint8() - r = stream.data.read_uint8() - a = stream.data.read_uint8() - color = si.HIGHLIGHT_COLORMAP.get((r, g, b, a), color) + color = si.HARDCODED_COLORMAP[rgba] return si.Line(color, tool, points, thickness_scale, starting_length, move_id) diff --git a/tests/data/More_color_highlight_shader_v3.15.4.2.rm b/tests/data/More_color_highlight_shader_v3.15.4.2.rm new file mode 100644 index 0000000000000000000000000000000000000000..8acd793fcdf2d4542b7916c08afe378f9e557444 GIT binary patch literal 12649 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 literal 0 HcmV?d00001 diff --git a/tests/test_color_tool.py b/tests/test_color_tool.py index 864493f..9aec012 100644 --- a/tests/test_color_tool.py +++ b/tests/test_color_tool.py @@ -1,5 +1,3 @@ -import logging -import os from pathlib import Path import pytest @@ -7,29 +5,23 @@ from rmscene import SceneGlyphItemBlock, SceneLineItemBlock, read_blocks from rmscene.scene_items import Pen, PenColor -logger = logging.getLogger(__name__) - - DATA_PATH = Path(__file__).parent / "data" -def _hex_lines(b, n=32): - return [b[i * n : (i + 1) * n].hex() for i in range(len(b) // n + 1)] - - -FILE_NAME = os.path.join(DATA_PATH, "Color_and_tool_v3.14.4.rm") - - @pytest.mark.parametrize( "block_type,colors,tools", [ (SceneGlyphItemBlock, {PenColor.HIGHLIGHT}, None), (SceneLineItemBlock, {PenColor.HIGHLIGHT}, {Pen.SHADER}), - (SceneLineItemBlock, {PenColor.GREEN_2, PenColor.CYAN, PenColor.MAGENTA}, {Pen.BALLPOINT_2}), + ( + SceneLineItemBlock, + {PenColor.GREEN_2, PenColor.CYAN, PenColor.MAGENTA}, + {Pen.BALLPOINT_2}, + ), ], ) def test_color_tool_parsing(block_type, colors, tools): - + FILE_NAME = DATA_PATH / "Color_and_tool_v3.14.4.rm" with open(FILE_NAME, "rb") as f: result = read_blocks(f) for el in result: @@ -40,4 +32,43 @@ def test_color_tool_parsing(block_type, colors, tools): if isinstance(el, block_type) and el.item.value.color in colors: if tools is None: continue - assert el.item.value.tool in tools, "Tool and colors don't match" \ No newline at end of file + assert el.item.value.tool in tools, "Tool and colors don't match" + + +def test_highlight_shader_colors(): + FILE_NAME = DATA_PATH / "More_color_highlight_shader_v3.15.4.2.rm" + with open(FILE_NAME, "rb") as f: + result = read_blocks(f) + expected_colors = [ + PenColor.HIGHLIGHT_YELLOW, + PenColor.HIGHLIGHT_BLUE, + PenColor.HIGHLIGHT_PINK, + PenColor.HIGHLIGHT_ORANGE, + PenColor.HIGHLIGHT_GREEN, + PenColor.HIGHLIGHT_GRAY, + PenColor.SHADER_GRAY, + PenColor.SHADER_ORANGE, + PenColor.SHADER_MAGENTA, + PenColor.SHADER_BLUE, + PenColor.SHADER_RED, + PenColor.SHADER_GREEN, + PenColor.SHADER_YELLOW, + PenColor.SHADER_CYAN, + PenColor.BLACK, + PenColor.GRAY, + PenColor.WHITE, + PenColor.BLUE, + PenColor.RED, + PenColor.GREEN_2, + PenColor.YELLOW_2, + PenColor.CYAN, + PenColor.MAGENTA, + ] + start = 0 + for block in result: + if isinstance(block, SceneLineItemBlock) and block.item.value: + assert ( + block.item.value.color == expected_colors[start] + ), f"Unexpected color {block.item.value.color} at index {start}" + start += 1 + assert start == len(expected_colors) From c70606ad6b50658588ea6e27ae287a89c6b1ca3c Mon Sep 17 00:00:00 2001 From: Chenghao Mou Date: Sat, 7 Dec 2024 16:43:26 +0000 Subject: [PATCH 4/5] update write --- src/rmscene/scene_stream.py | 8 ++++++++ tests/test_scene_stream.py | 1 + 2 files changed, 9 insertions(+) diff --git a/src/rmscene/scene_stream.py b/src/rmscene/scene_stream.py index e163581..e7f5c2f 100644 --- a/src/rmscene/scene_stream.py +++ b/src/rmscene/scene_stream.py @@ -466,6 +466,14 @@ def line_to_stream(line: si.Line, writer: TaggedBlockWriter, version: int = 2): writer.write_id(6, timestamp) if line.move_id is not None: writer.write_id(7, line.move_id) + + if line.color in si.HARDCODED_COLORMAP.values(): + rgba = [key for key, value in si.HARDCODED_COLORMAP.items() if value == line.color][0] + writer.data.write_bytes(b"\x84\x01") + writer.data.write_uint8(rgba[2]) + writer.data.write_uint8(rgba[1]) + writer.data.write_uint8(rgba[0]) + writer.data.write_uint8(rgba[3]) @dataclass diff --git a/tests/test_scene_stream.py b/tests/test_scene_stream.py index e1b9b58..26be54c 100644 --- a/tests/test_scene_stream.py +++ b/tests/test_scene_stream.py @@ -45,6 +45,7 @@ def _hex_lines(b, n=32): ("Wikipedia_highlighted_p2.rm", "3.1"), ("With_SceneInfo_Block.rm", "3.4"), # XXX version? ("Color_and_tool_v3.14.4.rm", "3.14"), + ("More_color_highlight_shader_v3.15.4.2.rm", "3.15"), ] From a02184a1b43b8ddbf8de8a2900bb1059996b892f Mon Sep 17 00:00:00 2001 From: Chenghao Mou Date: Sat, 7 Dec 2024 16:47:44 +0000 Subject: [PATCH 5/5] update wording --- src/rmscene/scene_items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rmscene/scene_items.py b/src/rmscene/scene_items.py index 555920e..c0f1b73 100644 --- a/src/rmscene/scene_items.py +++ b/src/rmscene/scene_items.py @@ -76,7 +76,7 @@ class PenColor(enum.IntEnum): GRAY_OVERLAP = 8 # All highlight colors share the same value. - # This is a placeholder, see HIGHLIGHT_COLORMAP for details. + # This is a placeholder, see the colormap below for details. HIGHLIGHT = 9 GREEN_2 = 10