From 10e8d68df7fde10e003d03bfc4f65d7b308f7ab2 Mon Sep 17 00:00:00 2001 From: tatarize Date: Wed, 3 Mar 2021 05:40:15 -0800 Subject: [PATCH 1/7] Jef ColorCount Bug inkscape/inkscape#905 EmbroidePy/pyembroidery#115 --- JefWriter.py | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 JefWriter.py diff --git a/JefWriter.py b/JefWriter.py new file mode 100644 index 00000000..be189e55 --- /dev/null +++ b/JefWriter.py @@ -0,0 +1,153 @@ +import datetime + +from .EmbConstant import * +from .EmbThread import build_nonrepeat_palette +from .EmbThreadJef import get_thread_set +from .WriteHelper import write_int_8, write_int_32le, write_string_utf8 + +SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_JUMP +FULL_JUMP = True +ROUND = True +MAX_JUMP_DISTANCE = 127 +MAX_STITCH_DISTANCE = 127 + +# These are in mm, embroidery units are 1/10 mm +HOOP_110X110 = 0 +HOOP_50X50 = 1 +HOOP_140X200 = 2 +HOOP_126X110 = 3 +HOOP_200X200 = 4 + + +def write(pattern, f, settings=None): + trims = False + command_count_max = 3 + + date_string = datetime.datetime.today().strftime("%Y%m%d%H%M%S") + if settings is not None: + trims = settings.get("trims", trims) + command_count_max = settings.get("trim_at", command_count_max) + date_string = settings.get("date", date_string) + + pattern.fix_color_count() + color_count = pattern.count_color_changes() + offsets = 0x74 + (color_count * 8) + write_int_32le(f, offsets) + write_int_32le(f, 0x14) + write_string_utf8(f, date_string) + write_int_8(f, 0) + write_int_8(f, 0) + write_int_32le(f, color_count) + point_count = 1 # 1 command for END statement + for stitch in pattern.stitches: + data = stitch[2] & COMMAND_MASK + if data == STITCH: + point_count += 1 + elif data == JUMP: + point_count += 2 + elif data == TRIM: + if trims: + point_count += 2 * command_count_max + elif data == COLOR_CHANGE: + point_count += 2 + elif data == END: + break + write_int_32le(f, point_count) + extends = pattern.bounds() + design_width = int(round(extends[2] - extends[0])) + design_height = int(round(extends[3] - extends[1])) + write_int_32le(f, get_jef_hoop_size(design_width, design_height)) + half_width = int(round(design_width / 2)) + half_height = int(round(design_height / 2)) + + # distance from center of hoop. + write_int_32le(f, half_width) + write_int_32le(f, half_height) + write_int_32le(f, half_width) + write_int_32le(f, half_height) + + # distance from default 110 x 110 hoop + x_hoop_edge = 550 - half_width + y_hoop_edge = 550 - half_height + write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) + + # distance from default 50 x 50 hoop + x_hoop_edge = 250 - half_width + y_hoop_edge = 250 - half_height + write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) + + # distance from default 140 x 200 hoop + x_hoop_edge = 700 - half_width + y_hoop_edge = 1000 - half_height + write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) + + # distance from custom hoop, but this should be accepted. + x_hoop_edge = 700 - half_width + y_hoop_edge = 1000 - half_height + write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) + + jef_threads = get_thread_set() + + palette = build_nonrepeat_palette(jef_threads, pattern.threadlist) + for t in palette: + write_int_32le(f, t) + + for i in range(0, color_count): + write_int_32le(f, 0x0D) + + xx = 0 + yy = 0 + for stitch in pattern.stitches: + x = stitch[0] + y = stitch[1] + data = stitch[2] & COMMAND_MASK + dx = int(round(x - xx)) + dy = int(round(y - yy)) + xx += dx + yy += dy + if data == STITCH: + write_int_8(f, dx) + write_int_8(f, -dy) + continue + elif data == COLOR_CHANGE: + f.write(b"\x80\x01") + write_int_8(f, dx) + write_int_8(f, -dy) + continue + elif data == TRIM: + if trims: # command trim. + f.write(b"\x80\x02\x00\x00" * command_count_max) + continue + elif data == JUMP: + f.write(b"\x80\x02") + write_int_8(f, dx) + write_int_8(f, -dy) + continue + elif data == END: + break + f.write(b"\x80\x10") + + +def get_jef_hoop_size(width, height): + if width < 500 and height < 500: + return HOOP_50X50 + if width < 1260 and height < 1100: + return HOOP_126X110 + if width < 1400 and height < 2000: + return HOOP_140X200 + if width < 2000 and height < 2000: + return HOOP_200X200 + return HOOP_110X110 + + +def write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge): + if min(x_hoop_edge, y_hoop_edge) >= 0: + write_int_32le(f, x_hoop_edge) # left + write_int_32le(f, y_hoop_edge) # top + write_int_32le(f, x_hoop_edge) # right + write_int_32le(f, y_hoop_edge) # bottom + else: + write_int_32le(f, -1) + write_int_32le(f, -1) + write_int_32le(f, -1) + write_int_32le(f, -1) From 0e8519ed48c1eba4defe924c5d9f7b42b5e5e55a Mon Sep 17 00:00:00 2001 From: Tatarize Date: Wed, 3 Mar 2021 05:48:22 -0800 Subject: [PATCH 2/7] Correct JefWriter Correct HusTest --- pyembroidery/JefWriter.py | 2 +- pyembroidery/__init__.py | 1 + test/__init__.py | 0 test/test_read_hus.py | 6 +++--- 4 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 test/__init__.py diff --git a/pyembroidery/JefWriter.py b/pyembroidery/JefWriter.py index 6dbbb665..be189e55 100644 --- a/pyembroidery/JefWriter.py +++ b/pyembroidery/JefWriter.py @@ -30,7 +30,7 @@ def write(pattern, f, settings=None): date_string = settings.get("date", date_string) pattern.fix_color_count() - color_count = pattern.count_threads() + color_count = pattern.count_color_changes() offsets = 0x74 + (color_count * 8) write_int_32le(f, offsets) write_int_32le(f, 0x14) diff --git a/pyembroidery/__init__.py b/pyembroidery/__init__.py index dcc4fb0d..fb58df76 100644 --- a/pyembroidery/__init__.py +++ b/pyembroidery/__init__.py @@ -6,6 +6,7 @@ from .EmbMatrix import EmbMatrix from .EmbPattern import EmbPattern from .EmbThread import EmbThread +from .EmbCompress import EmbCompress # items available in a sub-heirarchy (e.g. pyembroidery.PecGraphics.get_graphic_as_string) from .PecGraphics import get_graphic_as_string diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/test_read_hus.py b/test/test_read_hus.py index 839123d5..7624a35e 100644 --- a/test/test_read_hus.py +++ b/test/test_read_hus.py @@ -3,7 +3,7 @@ import random import unittest -from EmbCompress import expand, compress +from pyembroidery import * class TestReadHus(unittest.TestCase): @@ -12,6 +12,6 @@ def test_fake_compression(self): for i in range(10): s = random.randint(10, 1000) test_bytes = bytearray(random.getrandbits(8) for _ in range(s)) - compressed_bytes = compress(test_bytes) - uncompressed = bytearray(expand(compressed_bytes, len(test_bytes))) + compressed_bytes = EmbCompress.compress(test_bytes) + uncompressed = bytearray(EmbCompress.expand(compressed_bytes, len(test_bytes))) self.assertEqual(test_bytes, uncompressed) From 048fd6710e14171d61e1f8afe0673651a72d12f6 Mon Sep 17 00:00:00 2001 From: Tatarize Date: Wed, 3 Mar 2021 05:54:48 -0800 Subject: [PATCH 3/7] Correct JefWriter x2 Correct HusTest x2 --- JefWriter.py | 153 -------------------------------------- pyembroidery/JefWriter.py | 2 +- pyembroidery/__init__.py | 2 +- 3 files changed, 2 insertions(+), 155 deletions(-) delete mode 100644 JefWriter.py diff --git a/JefWriter.py b/JefWriter.py deleted file mode 100644 index be189e55..00000000 --- a/JefWriter.py +++ /dev/null @@ -1,153 +0,0 @@ -import datetime - -from .EmbConstant import * -from .EmbThread import build_nonrepeat_palette -from .EmbThreadJef import get_thread_set -from .WriteHelper import write_int_8, write_int_32le, write_string_utf8 - -SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_JUMP -FULL_JUMP = True -ROUND = True -MAX_JUMP_DISTANCE = 127 -MAX_STITCH_DISTANCE = 127 - -# These are in mm, embroidery units are 1/10 mm -HOOP_110X110 = 0 -HOOP_50X50 = 1 -HOOP_140X200 = 2 -HOOP_126X110 = 3 -HOOP_200X200 = 4 - - -def write(pattern, f, settings=None): - trims = False - command_count_max = 3 - - date_string = datetime.datetime.today().strftime("%Y%m%d%H%M%S") - if settings is not None: - trims = settings.get("trims", trims) - command_count_max = settings.get("trim_at", command_count_max) - date_string = settings.get("date", date_string) - - pattern.fix_color_count() - color_count = pattern.count_color_changes() - offsets = 0x74 + (color_count * 8) - write_int_32le(f, offsets) - write_int_32le(f, 0x14) - write_string_utf8(f, date_string) - write_int_8(f, 0) - write_int_8(f, 0) - write_int_32le(f, color_count) - point_count = 1 # 1 command for END statement - for stitch in pattern.stitches: - data = stitch[2] & COMMAND_MASK - if data == STITCH: - point_count += 1 - elif data == JUMP: - point_count += 2 - elif data == TRIM: - if trims: - point_count += 2 * command_count_max - elif data == COLOR_CHANGE: - point_count += 2 - elif data == END: - break - write_int_32le(f, point_count) - extends = pattern.bounds() - design_width = int(round(extends[2] - extends[0])) - design_height = int(round(extends[3] - extends[1])) - write_int_32le(f, get_jef_hoop_size(design_width, design_height)) - half_width = int(round(design_width / 2)) - half_height = int(round(design_height / 2)) - - # distance from center of hoop. - write_int_32le(f, half_width) - write_int_32le(f, half_height) - write_int_32le(f, half_width) - write_int_32le(f, half_height) - - # distance from default 110 x 110 hoop - x_hoop_edge = 550 - half_width - y_hoop_edge = 550 - half_height - write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) - - # distance from default 50 x 50 hoop - x_hoop_edge = 250 - half_width - y_hoop_edge = 250 - half_height - write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) - - # distance from default 140 x 200 hoop - x_hoop_edge = 700 - half_width - y_hoop_edge = 1000 - half_height - write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) - - # distance from custom hoop, but this should be accepted. - x_hoop_edge = 700 - half_width - y_hoop_edge = 1000 - half_height - write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) - - jef_threads = get_thread_set() - - palette = build_nonrepeat_palette(jef_threads, pattern.threadlist) - for t in palette: - write_int_32le(f, t) - - for i in range(0, color_count): - write_int_32le(f, 0x0D) - - xx = 0 - yy = 0 - for stitch in pattern.stitches: - x = stitch[0] - y = stitch[1] - data = stitch[2] & COMMAND_MASK - dx = int(round(x - xx)) - dy = int(round(y - yy)) - xx += dx - yy += dy - if data == STITCH: - write_int_8(f, dx) - write_int_8(f, -dy) - continue - elif data == COLOR_CHANGE: - f.write(b"\x80\x01") - write_int_8(f, dx) - write_int_8(f, -dy) - continue - elif data == TRIM: - if trims: # command trim. - f.write(b"\x80\x02\x00\x00" * command_count_max) - continue - elif data == JUMP: - f.write(b"\x80\x02") - write_int_8(f, dx) - write_int_8(f, -dy) - continue - elif data == END: - break - f.write(b"\x80\x10") - - -def get_jef_hoop_size(width, height): - if width < 500 and height < 500: - return HOOP_50X50 - if width < 1260 and height < 1100: - return HOOP_126X110 - if width < 1400 and height < 2000: - return HOOP_140X200 - if width < 2000 and height < 2000: - return HOOP_200X200 - return HOOP_110X110 - - -def write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge): - if min(x_hoop_edge, y_hoop_edge) >= 0: - write_int_32le(f, x_hoop_edge) # left - write_int_32le(f, y_hoop_edge) # top - write_int_32le(f, x_hoop_edge) # right - write_int_32le(f, y_hoop_edge) # bottom - else: - write_int_32le(f, -1) - write_int_32le(f, -1) - write_int_32le(f, -1) - write_int_32le(f, -1) diff --git a/pyembroidery/JefWriter.py b/pyembroidery/JefWriter.py index be189e55..f865c3b2 100644 --- a/pyembroidery/JefWriter.py +++ b/pyembroidery/JefWriter.py @@ -30,7 +30,7 @@ def write(pattern, f, settings=None): date_string = settings.get("date", date_string) pattern.fix_color_count() - color_count = pattern.count_color_changes() + color_count = pattern.count_color_changes() + 1 offsets = 0x74 + (color_count * 8) write_int_32le(f, offsets) write_int_32le(f, 0x14) diff --git a/pyembroidery/__init__.py b/pyembroidery/__init__.py index fb58df76..2cf38d67 100644 --- a/pyembroidery/__init__.py +++ b/pyembroidery/__init__.py @@ -6,7 +6,7 @@ from .EmbMatrix import EmbMatrix from .EmbPattern import EmbPattern from .EmbThread import EmbThread -from .EmbCompress import EmbCompress +from .EmbCompress import compress, expand # items available in a sub-heirarchy (e.g. pyembroidery.PecGraphics.get_graphic_as_string) from .PecGraphics import get_graphic_as_string From b887fd4610a9bb7439ba4957bf665ed0d477eb12 Mon Sep 17 00:00:00 2001 From: Tatarize Date: Wed, 3 Mar 2021 06:14:55 -0800 Subject: [PATCH 4/7] Version Bump --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0f0e5475..0ca7fcaa 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="pyembroidery", - version="1.4.28", + version="1.4.29", author="Tatarize", author_email="tatarize@gmail.com", description="Embroidery IO library", From 6208a25eb33ef463cbb01ccd7960b7e5223e0ed7 Mon Sep 17 00:00:00 2001 From: Tatarize Date: Thu, 4 Mar 2021 18:06:08 -0800 Subject: [PATCH 5/7] Partially Done --- pyembroidery/JefReader.py | 11 +++++- pyembroidery/JefWriter.py | 52 +++++++++++++++++++++++++--- test/__init__.py | 0 test/pattern_for_tests.py | 73 +++++++++++++++++++++++++++++++++++++++ test/test_convert_jef.py | 25 ++++++++++++++ 5 files changed, 155 insertions(+), 6 deletions(-) delete mode 100644 test/__init__.py diff --git a/pyembroidery/JefReader.py b/pyembroidery/JefReader.py index 269c0fe9..44dbd813 100644 --- a/pyembroidery/JefReader.py +++ b/pyembroidery/JefReader.py @@ -3,6 +3,7 @@ def read_jef_stitches(f, out, settings=None): + color_index = 1 while True: b = bytearray(f.read(2)) if len(b) != 2: @@ -22,7 +23,12 @@ def read_jef_stitches(f, out, settings=None): out.move(x, y) continue if ctrl == 0x01: - out.color_change(0, 0) + if out.threadlist[color_index] is None: + out.stop(0, 0) + del out.threadlist[color_index] + else: + out.color_change(0, 0) + color_index += 1 continue if ctrl == 0x10: break @@ -54,7 +60,10 @@ def read(f, out, settings=None): for i in range(0, count_colors): index = abs(read_int_32le(f)) + if index == 0: + out.add_thread(None) out.add_thread(jef_threads[index % len(jef_threads)]) + print(out.threadlist) f.seek(stitch_offset, 0) read_jef_stitches(f, out, settings) diff --git a/pyembroidery/JefWriter.py b/pyembroidery/JefWriter.py index f865c3b2..edf38866 100644 --- a/pyembroidery/JefWriter.py +++ b/pyembroidery/JefWriter.py @@ -30,7 +30,46 @@ def write(pattern, f, settings=None): date_string = settings.get("date", date_string) pattern.fix_color_count() - color_count = pattern.count_color_changes() + 1 + # REMOVE BUG: color_count = pattern.count_threads(). # + + # PATCH + jef_threads = get_thread_set() + last_index = None + last_thread = None + palette = [] + color_toggled = False + color_count = 0 # Color and Stop count. + index_in_threadlist = 0 + for stitch in pattern.stitches: + # Iterate all stitches. + flags = stitch[2] & COMMAND_MASK + if flags == COLOR_CHANGE or index_in_threadlist == 0: + # If color change *or* initial color unset. + thread = pattern.threadlist[index_in_threadlist] + index_in_threadlist += 1 + color_count += 1 + index_of_jefthread = thread.find_nearest_color_index(jef_threads) + if last_index == index_of_jefthread and last_thread != thread: + # Last thread and current thread pigeonhole to same jefcolor. + # We set that thread to None. And get the second closest color. + repeated_thread = jef_threads[index_of_jefthread] + repeated_index = index_of_jefthread + jef_threads[index_of_jefthread] = None + index_of_jefthread = thread.find_nearest_color_index(jef_threads) + jef_threads[repeated_index] = repeated_thread + palette.append(index_of_jefthread) + last_index = index_of_jefthread + last_thread = thread + color_toggled = False + if flags == STOP: + color_count += 1 + color_toggled = not color_toggled + if color_toggled: + palette.append(0) + else: + palette.append(last_index) + # END PATCH + offsets = 0x74 + (color_count * 8) write_int_32le(f, offsets) write_int_32le(f, 0x14) @@ -48,7 +87,7 @@ def write(pattern, f, settings=None): elif data == TRIM: if trims: point_count += 2 * command_count_max - elif data == COLOR_CHANGE: + elif data == COLOR_CHANGE or data == STOP: # PATCH: INCLUDE STOP. point_count += 2 elif data == END: break @@ -86,9 +125,12 @@ def write(pattern, f, settings=None): y_hoop_edge = 1000 - half_height write_hoop_edge_distance(f, x_hoop_edge, y_hoop_edge) - jef_threads = get_thread_set() + # REMOVE (We covered this in PATCH). + #jef_threads = get_thread_set() + # + #palette = build_nonrepeat_palette(jef_threads, pattern.threadlist) + # END REMOVE - palette = build_nonrepeat_palette(jef_threads, pattern.threadlist) for t in palette: write_int_32le(f, t) @@ -109,7 +151,7 @@ def write(pattern, f, settings=None): write_int_8(f, dx) write_int_8(f, -dy) continue - elif data == COLOR_CHANGE: + elif data == COLOR_CHANGE or data == STOP: # PATCH INCLUDE STOP. f.write(b"\x80\x01") write_int_8(f, dx) write_int_8(f, -dy) diff --git a/test/__init__.py b/test/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/test/pattern_for_tests.py b/test/pattern_for_tests.py index ba6ce95e..1d50c344 100644 --- a/test/pattern_for_tests.py +++ b/test/pattern_for_tests.py @@ -59,6 +59,7 @@ def add_serp(self): } evaluate_lsystem(initial, rules, 3) # 6 + def get_big_pattern(): pattern = EmbPattern() pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "red") @@ -131,6 +132,78 @@ def get_shift_pattern(): return pattern +def get_shift_stop_pattern(): + pattern = EmbPattern() + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "red") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_command(STOP) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "red") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "green") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_command(STOP) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "green") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "green") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "ivory") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "ivory") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_command(STOP) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "ivory") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "olive") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "olive") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_command(STOP) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "olive") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "olive") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "violet") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_command(STOP) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "white") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "salmon") + pattern.add_command(MATRIX_TRANSLATE, 25, 25) + pattern.add_command(MATRIX_ROTATE, 22.5) + pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "lime") + return pattern + + +def get_simple_stop(): + pattern = EmbPattern() + pattern += (0,0) + pattern += (0, 100) + pattern += (100, 100) + pattern += (100, 0) + pattern += (0, 0) + pattern.stop() + pattern += (0, 0) + pattern += (0, 100) + pattern += (100, 100) + pattern += (100, 0) + pattern += (0, 0) + return pattern + + def get_simple_pattern(): pattern = EmbPattern() pattern.add_block([(0, 0), (0, 100), (100, 100), (100, 0), (0, 0)], "red") diff --git a/test/test_convert_jef.py b/test/test_convert_jef.py index fa26e026..12bc6214 100644 --- a/test/test_convert_jef.py +++ b/test/test_convert_jef.py @@ -168,4 +168,29 @@ def test_convert_jef_to_xxx(self): self.position_equals(t_pattern.stitches, 0, -1) print("jef->xxx: ", t_pattern.stitches) self.addCleanup(os.remove, file1) + self.addCleanup(os.remove, file2) + + def test_jef_stop_write(self): + file2 = "stop2.jef" + write_jef(get_simple_stop(), file2) + s_pattern = read_jef(file2) + self.assertEqual(s_pattern.count_stitch_commands(STOP), 1) + self.assertEqual(s_pattern.count_color_changes(), 0) + + file1 = "stop.jef" + pattern = get_shift_stop_pattern() + write_jef(pattern, file1) + f_pattern = read_jef(file1) + self.assertIsNotNone(f_pattern) + + with open(file1, "rb") as f: + f.seek(0x18) + colors = f.read(1) + self.assertEqual(ord(colors), f_pattern.count_color_changes() + f_pattern.count_stitch_commands(STOP) + 1) + + self.assertEqual(f_pattern.count_stitch_commands(COLOR_CHANGE), 12) + self.assertEqual(f_pattern.count_stitch_commands(STITCH), 16 * 5) + self.assertEqual(f_pattern.count_stitch_commands(STOP), 6) + self.position_equals(f_pattern.stitches, 0, -1) + self.addCleanup(os.remove, file1) self.addCleanup(os.remove, file2) \ No newline at end of file From 36c25da083e0202e5e47c16afac36e55f70f3a52 Mon Sep 17 00:00:00 2001 From: Tatarize Date: Thu, 4 Mar 2021 18:31:19 -0800 Subject: [PATCH 6/7] Correct final JefReader issues. --- pyembroidery/JefReader.py | 5 +++-- test/test_convert_jef.py | 31 ++++++++++++++++++------------- test/test_read_hus.py | 2 +- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/pyembroidery/JefReader.py b/pyembroidery/JefReader.py index 44dbd813..2dec4d6d 100644 --- a/pyembroidery/JefReader.py +++ b/pyembroidery/JefReader.py @@ -61,8 +61,9 @@ def read(f, out, settings=None): for i in range(0, count_colors): index = abs(read_int_32le(f)) if index == 0: - out.add_thread(None) - out.add_thread(jef_threads[index % len(jef_threads)]) + out.threadlist.append(None) + else: + out.add_thread(jef_threads[index % len(jef_threads)]) print(out.threadlist) f.seek(stitch_offset, 0) diff --git a/test/test_convert_jef.py b/test/test_convert_jef.py index 12bc6214..b9d3420a 100644 --- a/test/test_convert_jef.py +++ b/test/test_convert_jef.py @@ -170,27 +170,32 @@ def test_convert_jef_to_xxx(self): self.addCleanup(os.remove, file1) self.addCleanup(os.remove, file2) - def test_jef_stop_write(self): - file2 = "stop2.jef" - write_jef(get_simple_stop(), file2) - s_pattern = read_jef(file2) + def test_jef_stop_write_simple(self): + file = "stop.jef" + write_jef(get_simple_stop(), file) + s_pattern = read_jef(file) self.assertEqual(s_pattern.count_stitch_commands(STOP), 1) self.assertEqual(s_pattern.count_color_changes(), 0) + self.addCleanup(os.remove, file) - file1 = "stop.jef" + def test_jef_stop_write_large(self): + file = "stop2.jef" pattern = get_shift_stop_pattern() - write_jef(pattern, file1) - f_pattern = read_jef(file1) + n_pattern = pattern.get_normalized_pattern() + self.assertEqual(n_pattern.count_stitch_commands(COLOR_CHANGE), 15) + self.assertEqual(n_pattern.count_stitch_commands(STITCH), 16 * 5) + self.assertEqual(n_pattern.count_stitch_commands(STOP), 5) + + write_jef(pattern, file) + f_pattern = read_jef(file) self.assertIsNotNone(f_pattern) - with open(file1, "rb") as f: + with open(file, "rb") as f: f.seek(0x18) colors = f.read(1) self.assertEqual(ord(colors), f_pattern.count_color_changes() + f_pattern.count_stitch_commands(STOP) + 1) - self.assertEqual(f_pattern.count_stitch_commands(COLOR_CHANGE), 12) + self.assertEqual(f_pattern.count_stitch_commands(COLOR_CHANGE), 15) self.assertEqual(f_pattern.count_stitch_commands(STITCH), 16 * 5) - self.assertEqual(f_pattern.count_stitch_commands(STOP), 6) - self.position_equals(f_pattern.stitches, 0, -1) - self.addCleanup(os.remove, file1) - self.addCleanup(os.remove, file2) \ No newline at end of file + self.assertEqual(f_pattern.count_stitch_commands(STOP), 5) + self.addCleanup(os.remove, file) \ No newline at end of file diff --git a/test/test_read_hus.py b/test/test_read_hus.py index 7624a35e..183169bf 100644 --- a/test/test_read_hus.py +++ b/test/test_read_hus.py @@ -10,7 +10,7 @@ class TestReadHus(unittest.TestCase): def test_fake_compression(self): for i in range(10): - s = random.randint(10, 1000) + s = random.randint(10, 1000) # May fail if larger. test_bytes = bytearray(random.getrandbits(8) for _ in range(s)) compressed_bytes = EmbCompress.compress(test_bytes) uncompressed = bytearray(EmbCompress.expand(compressed_bytes, len(test_bytes))) From a1c34b12033208ae69a70338106ee0b93fc1b898 Mon Sep 17 00:00:00 2001 From: Tatarize Date: Thu, 4 Mar 2021 18:42:35 -0800 Subject: [PATCH 7/7] Integrate Version --- pyembroidery/JefReader.py | 3 ++- pyembroidery/JefWriter.py | 1 - pyembroidery/PecWriter.py | 2 +- test/test_encoder.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyembroidery/JefReader.py b/pyembroidery/JefReader.py index 2dec4d6d..dd884d51 100644 --- a/pyembroidery/JefReader.py +++ b/pyembroidery/JefReader.py @@ -23,6 +23,7 @@ def read_jef_stitches(f, out, settings=None): out.move(x, y) continue if ctrl == 0x01: + # PATCH: None means stop since it was color #0 if out.threadlist[color_index] is None: out.stop(0, 0) del out.threadlist[color_index] @@ -61,10 +62,10 @@ def read(f, out, settings=None): for i in range(0, count_colors): index = abs(read_int_32le(f)) if index == 0: + # Patch: If we have color 0. Go ahead and set that to None. out.threadlist.append(None) else: out.add_thread(jef_threads[index % len(jef_threads)]) - print(out.threadlist) f.seek(stitch_offset, 0) read_jef_stitches(f, out, settings) diff --git a/pyembroidery/JefWriter.py b/pyembroidery/JefWriter.py index edf38866..0fdace4f 100644 --- a/pyembroidery/JefWriter.py +++ b/pyembroidery/JefWriter.py @@ -1,7 +1,6 @@ import datetime from .EmbConstant import * -from .EmbThread import build_nonrepeat_palette from .EmbThreadJef import get_thread_set from .WriteHelper import write_int_8, write_int_32le, write_string_utf8 diff --git a/pyembroidery/PecWriter.py b/pyembroidery/PecWriter.py index ef58829b..3d95b174 100644 --- a/pyembroidery/PecWriter.py +++ b/pyembroidery/PecWriter.py @@ -60,7 +60,7 @@ def write_pec_header(pattern, f, threadlist): f.write(b"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20") add_value = current_thread_count - 1 color_index_list.insert(0, add_value) - assert color_index_list[0]<255, 'to many color changes, ({0}) out of bounds (0, 255)'.format(len(color_index_list)) + assert color_index_list[0] < 255, 'too many color changes, ({0}) out of bounds (0, 255)'.format(len(color_index_list)) f.write(bytes(bytearray(color_index_list))) else: f.write(b"\x20\x20\x20\x20\x64\x20\x00\x20\x00\x20\x20\x20\xFF") diff --git a/test/test_encoder.py b/test/test_encoder.py index 2d66c676..6cce6a06 100644 --- a/test/test_encoder.py +++ b/test/test_encoder.py @@ -110,4 +110,4 @@ def test_transcode_to_self(self): from pyembroidery.EmbEncoder import Transcoder encoder = Transcoder() encoder.transcode(pattern, pattern) - self.assertNotEquals(len(pattern.stitches), 0) + self.assertNotEqual(len(pattern.stitches), 0)