Closed tatarize closed 5 years ago
The CSD reader exists in libembroidery but was not ported over or utilized in this product because it contained an encryption scheme. By definition bypassing encryption violates DMCA.
In PyEmbroidery add the supported format:
yield ({ "description": "Singer / Poem", "extension": "csd", "mimetype": "application/x-csd", "category": "embroidery", "reader": CsdReader, })
And the reader:
from EmbThread import EmbThread from .ReadHelper import read_int_8 CsdSubMaskSize = 479 CsdXorMaskSize = 501 _subMask = [0] * CsdSubMaskSize _xorMask = [0] * CsdXorMaskSize _decryptArray = [ 0x43, 0x6E, 0x72, 0x7A, 0x76, 0x6C, 0x61, 0x6F, 0x7C, 0x29, 0x5D, 0x62, 0x60, 0x6E, 0x61, 0x62, 0x20, 0x41, 0x66, 0x6A, 0x3A, 0x35, 0x5A, 0x63, 0x7C, 0x37, 0x3A, 0x2A, 0x25, 0x24, 0x2A, 0x33, 0x00, 0x10, 0x14, 0x03, 0x72, 0x4C, 0x48, 0x42, 0x08, 0x7A, 0x5E, 0x0B, 0x6F, 0x45, 0x47, 0x5F, 0x40, 0x54, 0x5C, 0x57, 0x55, 0x59, 0x53, 0x3A, 0x32, 0x6F, 0x53, 0x54, 0x50, 0x5C, 0x4A, 0x56, 0x2F, 0x2F, 0x62, 0x2C, 0x22, 0x65, 0x25, 0x28, 0x38, 0x30, 0x38, 0x22, 0x2B, 0x25, 0x3A, 0x6F, 0x27, 0x38, 0x3E, 0x3F, 0x74, 0x37, 0x33, 0x77, 0x2E, 0x30, 0x3D, 0x34, 0x2E, 0x32, 0x2B, 0x2C, 0x0C, 0x18, 0x42, 0x13, 0x16, 0x0A, 0x15, 0x02, 0x0B, 0x1C, 0x1E, 0x0E, 0x08, 0x60, 0x64, 0x0D, 0x09, 0x51, 0x25, 0x1A, 0x18, 0x16, 0x19, 0x1A, 0x58, 0x10, 0x14, 0x5B, 0x08, 0x15, 0x1B, 0x5F, 0xD5, 0xD2, 0xAE, 0xA3, 0xC1, 0xF0, 0xF4, 0xE8, 0xF8, 0xEC, 0xA6, 0xAB, 0xCD, 0xF8, 0xFD, 0xFB, 0xE2, 0xF0, 0xFE, 0xFA, 0xF5, 0xB5, 0xF7, 0xF9, 0xFC, 0xB9, 0xF5, 0xEF, 0xF4, 0xF8, 0xEC, 0xBF, 0xC3, 0xCE, 0xD7, 0xCD, 0xD0, 0xD7, 0xCF, 0xC2, 0xDB, 0xA4, 0xA0, 0xB0, 0xAF, 0xBE, 0x98, 0xE2, 0xC2, 0x91, 0xE5, 0xDC, 0xDA, 0xD2, 0x96, 0xC4, 0x98, 0xF8, 0xC9, 0xD2, 0xDD, 0xD3, 0x9E, 0xDE, 0xAE, 0xA5, 0xE2, 0x8C, 0xB6, 0xAC, 0xA3, 0xA9, 0xBC, 0xA8, 0xA6, 0xEB, 0x8B, 0xBF, 0xA1, 0xAC, 0xB5, 0xA3, 0xBB, 0xB6, 0xA7, 0xD8, 0xDC, 0x9A, 0xAA, 0xF9, 0x82, 0xFB, 0x9D, 0xB9, 0xAB, 0xB3, 0x94, 0xC1, 0xA0, 0x8C, 0x8B, 0x8E, 0x95, 0x8F, 0x87, 0x99, 0xE7, 0xE1, 0xA3, 0x83, 0x8B, 0xCF, 0xA3, 0x85, 0x9D, 0x83, 0xD4, 0xB7, 0x83, 0x84, 0x91, 0x97, 0x9F, 0x88, 0x8F, 0xDD, 0xAD, 0x90] def BuildDecryptionTable(seed): mul1 = 0x41C64E6D add1 = 0x3039 for i in range(0, CsdSubMaskSize): seed *= mul1 seed += add1 seed &= 0xFFFFFFFF _subMask[i] = (seed >> 16) & 0xFF for i in range(0, CsdXorMaskSize): seed *= mul1 seed += add1 seed &= 0xFFFFFFFF _xorMask[i] = (seed >> 16) & 0xFF def DecodeCsdByte(fileOffset, val, type): if type != 0: fileOffsetHigh = fileOffset & 0xFFFFFF00 fileOffsetLow = fileOffset & 0xFF newOffset = fileOffsetLow fileOffsetLow = fileOffsetHigh final = fileOffsetLow % 0x300 if final != 0x100 and final != 0x200: newOffset = _decryptArray[newOffset] | fileOffsetHigh elif final != 0x100 and final == 0x200: if newOffset == 0: fileOffsetHigh = fileOffsetHigh - 0x100 newOffset = _decryptArray[newOffset] | fileOffsetHigh elif newOffset != 1 and newOffset != 0: newOffset = _decryptArray[newOffset] | fileOffsetHigh else: fileOffsetHigh = fileOffsetHigh - 0x100 newOffset = _decryptArray[newOffset] | fileOffsetHigh else: newOffset = fileOffset return ((val ^ _xorMask[newOffset % CsdXorMaskSize]) - _subMask[newOffset % CsdSubMaskSize]) & 0xFF # /*! Reads a file with the given \a fileName and loads the data into \a pattern. # * Returns \c true if successful, otherwise returns \c false. */ def read_csd_stitches(f, out): type = 0 identifier = [0] * 8 colorChange = -1 colorOrder = [0] * 14 for i in range(0, 8): identifier[i] = read_int_8(f) if identifier[0] != 0x7C and identifier[2] != 0xC3: type = 1 if type == 0: BuildDecryptionTable(0xC) else: BuildDecryptionTable(identifier[0]) f.seek(8, 0) # Seek Set for i in range(0, 16): thread = EmbThread() r = DecodeCsdByte(f.tell(), read_int_8(f), type) g = DecodeCsdByte(f.tell(), read_int_8(f), type) b = DecodeCsdByte(f.tell(), read_int_8(f), type) thread.set_color(r, g, b) thread.catalogNumber = "" thread.description = "" out.add_thread(thread) unknown1 = DecodeCsdByte(f.tell(), read_int_8(f), type) unknown2 = DecodeCsdByte(f.tell(), read_int_8(f), type) for i in range(0, 14): colorOrder[i] = DecodeCsdByte(f.tell(), read_int_8(f), type) while True: b0 = DecodeCsdByte(f.tell(), read_int_8(f), type) b1 = DecodeCsdByte(f.tell(), read_int_8(f), type) b2 = DecodeCsdByte(f.tell(), read_int_8(f), type) dx = int(b2) dy = int(b1) if b0 == 0xF8 or b0 == 0x87 or b0 == 0x91: break negativeX = ((b0 & 0x20) > 0) negativeY = ((b0 & 0x40) > 0) if negativeX: dx = -dx if not negativeY: dy = -dy b0 &= 0xFF ^ 0xE0 if (b0 & 0x1F) == 0: out.stitch(dx, dy) elif (b0 & 0x0C) > 0: out.color_change() if colorChange >= 14: break # Invalid color change. colorChange += 1 elif (b0 & 0x1F) > 0: out.trim() out.move(dx, dy) else: out.stitch(dx, dy) def read(f, out, settings=None): read_csd_stitches(f, out)
The CSD reader exists in libembroidery but was not ported over or utilized in this product because it contained an encryption scheme. By definition bypassing encryption violates DMCA.
In PyEmbroidery add the supported format:
And the reader: