def generate_metadata_stream(self): ms = StringIO() ms.write(self.encode_vwi(len(self.md_header['tag'])).encode('iso-8859-1')) ms.write(self.md_header['tag']) ms.write(int_to_byte(self.md_header['flags'])) ms.write(int_to_byte(len(self.metadata))) # Add the metadata fields. # for tag in self.metadata: for tag in self.md_seq: ms.write(self.encode_vwi(len(tag)).encode('iso-8859-1')) ms.write(tag) ms.write(self.encode_vwi(len(self.metadata[tag])).encode('iso-8859-1')) ms.write(self.metadata[tag]) return ms.getvalue()
def write_t2b(t2bfile, coverdata=None): ''' t2bfile is a file handle ready to write binary data to disk. coverdata is a string representation of a JPEG file. ''' from PIL import Image if coverdata is not None: coverdata = io.BytesIO(coverdata) cover = Image.open(coverdata).convert("L") cover.thumbnail((96, 144), Image.ANTIALIAS) t2bcover = Image.new('L', (96, 144), 'white') x, y = cover.size t2bcover.paste(cover, ((96-x)//2, (144-y)//2)) px = [] pxs = t2bcover.getdata() for i in range(len(pxs)): px.append(pxs[i]) if len(px) >= 4: binstr = i2b(reduce_color(px[0])) + i2b(reduce_color(px[1])) + i2b(reduce_color(px[2])) + i2b(reduce_color(px[3])) t2bfile.write(int_to_byte(int(binstr, 2))) px = [] else: t2bfile.write(DEFAULT_T2B_DATA)
def compress(self, txt): self._reset() self.codes = list(set(re.findall(b'(?ms).', txt))) # Replace the text with their corresponding code # FIXME: python3 is native bytearray, but all we want are bytes for c in bytearray(txt): self.coded_txt += int_to_byte(self.codes.index(int_to_byte(c))) # Zero the unused codes and record which are unused. for i in range(len(self.codes), 256): self.codes.append(b'') self.unused_codes.add(i) self._combine_codes() possible_codes = self._new_codes() while possible_codes and self.unused_codes: while possible_codes and self.unused_codes: unused_code = self.unused_codes.pop() # Take the last possible codes and split it into individual # codes. The last possible code is the most often occurring. code = possible_codes.pop() self.codes[unused_code] = b'%s%s' % (self.codes[ord( code[0:1])], self.codes[ord(code[1:2])]) self.coded_txt = self.coded_txt.replace( code, int_to_byte(unused_code)) self._combine_codes() self._free_unused_codes() possible_codes = self._new_codes() self._free_unused_codes() # Generate the code dictionary. code_dict = [] for i in range(0, 256): if i in self.unused_codes: code_dict.append(b'\0') else: code_dict.append( int_to_byte(len(self.codes[i])) + self.codes[i]) # Join the identifier with the dictionary and coded text. return b'!!8-Bit!!' + b''.join(code_dict) + self.coded_txt
def _free_unused_codes(self): ''' Look for codes that do no not appear in the coded text and add them to the list of free codes. ''' for i in range(256): if i not in self.unused_codes: if int_to_byte(i) not in self.coded_txt: self.unused_codes.add(i)
def codepage(match): try: return int_to_byte(int(match.group(1), 16)).decode(codec) except ValueError: return '?'
def codepage(match): try: return int_to_byte(int(match.group(1), 16)).decode(codec) except ValueError: return '?'