From 05516a769223d1a75a2e4f50bdf0e7d4ca0eef83 Mon Sep 17 00:00:00 2001 From: Philipp Klaus Date: Mon, 2 Sep 2019 20:34:12 +0200 Subject: [PATCH] 'brother_ql analyze' updated to support P-Touch series files --- brother_ql/reader.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/brother_ql/reader.py b/brother_ql/reader.py index 7acad4f..b5d817d 100755 --- a/brother_ql/reader.py +++ b/brother_ql/reader.py @@ -16,8 +16,10 @@ OPCODES = { # signature name following bytes description b'\x00': ("preamble", -1, "Preamble, 200-300x 0x00 to clear comamnd buffer"), b'\x4D': ("compression", 1, ""), - b'\x67': ("raster", -1, ""), - b'\x77': ("2-color raster", -1, ""), + b'\x67': ("raster QL", -1, ""), + b'\x47': ("raster P-touch", -1, ""), + b'\x77': ("2-color raster QL", -1, ""), + b'\x5a': ("zero raster", 0, "empty raster line"), b'\x0C': ("print", 0, "print intermediate page"), b'\x1A': ("print", 0, "print final page"), b'\x1b\x40': ("init", 0, "initialization"), @@ -139,12 +141,15 @@ def chunker(data, raise_exception=False): opcode_def = OPCODES[opcode] num_bytes = len(opcode) if opcode_def[1] > 0: num_bytes += opcode_def[1] - if 'raster' in opcode_def[0]: + elif opcode_def[0] in ('raster QL', '2-color raster QL'): num_bytes += data[2] + 2 + elif opcode_def[0] in ('raster P-touch',): + num_bytes += data[1] + data[2]*256 + 2 #payload = data[len(opcode):num_bytes] instructions.append(data[:num_bytes]) + yield instructions[-1] data = data[num_bytes:] - return instructions + #return instructions def match_opcode(data): matching_opcodes = [opcode for opcode in OPCODES.keys() if data.startswith(opcode)] @@ -262,7 +267,11 @@ class BrotherQLReader(object): logger.info(" {} ({}) --> found! (payload: {})".format(opcode_def[0], hex_format(opcode), hex_format(payload))) if opcode_def[0] == 'compression': self.compression = payload[0] == 0x02 - if 'raster' in opcode_def[0]: + if opcode_def[0] == 'zero raster': + self.black_rows.append(bytes()) + if self.two_color_printing: + self.red_rows.append(bytes()) + if opcode_def[0] in ('raster QL', '2-color raster QL', 'raster P-touch'): rpl = bytes(payload[2:]) # raster payload if self.compression: row = bytes() @@ -282,7 +291,7 @@ class BrotherQLReader(object): if index >= len(rpl): break else: row = rpl - if opcode_def[0] == 'raster': + if opcode_def[0] in ('raster QL', 'raster P-touch'): self.black_rows.append(row) else: # 2-color if payload[0] == 0x01: @@ -306,15 +315,24 @@ class BrotherQLReader(object): logger.info("Len of red rows: %d", len(self.red_rows)) def get_im(rows): if not len(rows): return None - size = (len(rows[0])*8, len(rows)) - data = bytes(b''.join(rows)) + width_dots = max(len(row) for row in rows) + height_dots = len(rows) + size = (width_dots*8, height_dots) + expanded_rows = [] + for row in rows: + if len(row) == 0: + expanded_rows.append(b'\x00'*width_dots) + else: + expanded_rows.append(row) + data = bytes(b''.join(expanded_rows)) data = bytes([2**8 + ~byte for byte in data]) # invert b/w im = Image.frombytes("1", size, data, decoder_name='raw') return im - im_black, im_red = (get_im(rows) for rows in (self.black_rows, self.red_rows)) if not self.two_color_printing: + im_black = get_im(self.black_rows) im = im_black else: + im_black, im_red = (get_im(rows) for rows in (self.black_rows, self.red_rows)) im_black = im_black.convert("RGBA") im_red = im_red.convert("L") im_red = colorize(im_red, (255, 0, 0), (255, 255, 255))