def decode(self): """ TIFF 6.0 specification explains in sufficient details the steps to implement the LZW encode() and decode() algorithms. :rtype: bytes """ # TO-DO Make return value type bytes, as instructed by ISO 32000 cW = self.CLEARDICT output = b"" while True: pW = cW cW = self._readCode() if cW == -1: raise PdfReadError( "Missed the stop code in during LZW decoding") if cW == self.STOP: break elif cW == self.CLEARDICT: self._resetDict() elif pW == self.CLEARDICT: output += self.dict[cW] else: if cW < self.dictindex: output += self.dict[cW] if version_info > (3, 0): p = self.dict[pW] + bytes([self.dict[cW][0]]) else: p = self.dict[pW] + self.dict[cW][0] self._addCodeToTable(p) else: if version_info > (3, 0): p = self.dict[pW] + bytes([self.dict[pW][0]]) else: p = self.dict[pW] + self.dict[pW][0] output += p self._addCodeToTable(p) return output
def decode(data, decodeParms=None): """ :param data: flate-encoded data. :param decodeParms: a dictionary of parameter values. :return: the flate-decoded data. :rtype: bytes """ data = decompress(data) predictor = 1 if decodeParms: try: predictor = decodeParms.get("/Predictor", 1) except AttributeError: pass # Usually an array with a null object was read # predictor 1 == no predictor if predictor != 1: # The /Columns param. has 1 as the default value; see ISO 32000, # §7.4.4.3 LZWDecode and FlateDecode Parameters, Table 8 columns = decodeParms.get("/Columns", 1) # PNG prediction: if 10 <= predictor <= 15: output = BytesIO() # PNG prediction can vary from row to row row_length = columns + 1 assert len(data) % row_length == 0 prev_rowdata = (0, ) * row_length for row in range(len(data) // row_length): rowdata = [ pypdfOrd(x) for x in data[(row * row_length):((row + 1) * row_length)] ] filterByte = rowdata[0] if filterByte == 0: pass elif filterByte == 1: for i in range(2, row_length): rowdata[i] = (rowdata[i] + rowdata[i - 1]) % 256 elif filterByte == 2: for i in range(1, row_length): rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256 elif filterByte == 3: for i in range(1, row_length): left = rowdata[i - 1] if i > 1 else 0 floor = math.floor(left + prev_rowdata[i]) / 2 rowdata[i] = (rowdata[i] + int(floor)) % 256 elif filterByte == 4: for i in range(1, row_length): left = rowdata[i - 1] if i > 1 else 0 up = prev_rowdata[i] up_left = prev_rowdata[i - 1] if i > 1 else 0 paeth = paethPredictor(left, up, up_left) rowdata[i] = (rowdata[i] + paeth) % 256 else: # Unsupported PNG filter raise PdfReadError("Unsupported PNG filter %r" % filterByte) prev_rowdata = rowdata for d in rowdata: if version_info < (3, 0): output.write(chr(d)) else: output.write(bytes([d])) data = output.getvalue() else: # unsupported predictor raise PdfReadError("Unsupported flatedecode predictor %r" % predictor) return data
def decode(data, decodeParms=None): """ :param data: flate-encoded data. :param decodeParms: a dictionary of parameter values. :return: the flate-decoded data. :rtype: bytes """ data = decompress(data) predictor = 1 if decodeParms: try: predictor = decodeParms.get("/Predictor", 1) except AttributeError: pass # Usually an array with a null object was read # predictor 1 == no predictor if predictor != 1: # The /Columns param. has 1 as the default value; see ISO 32000, # §7.4.4.3 LZWDecode and FlateDecode Parameters, Table 8 columns = decodeParms.get("/Columns", 1) colors = decodeParms.get("/Colors", 8) # PNG prediction: if 10 <= predictor <= 15: output = BytesIO( ) ### BytesIO au lieu de StringIO, car PIL attend des bytes (Pas de mon fait) # PNG prediction can vary from row to row row_length = columns * colors + 1 assert len(data) % row_length == 0 prev_rowdata = (0, ) * row_length for row in range(len(data) // row_length): rowdata = [ pypdfOrd(x) for x in data[(row * row_length):((row + 1) * row_length)] ] filterByte = rowdata[0] if filterByte == 0: pass elif filterByte == 1: for i in range(1, row_length): if i <= 3: ### On vise hors de la limite gauche, donc 0 (as per les specs) rowdata[i] = (rowdata[i] + 0) % 256 else: rowdata[i] = ( rowdata[i] + rowdata[i - colors] ) % 256 ### Pas le byte d'avant ! Son homologue dans le pixel d'avant ### (TODO : vérifier si le bitdepth < 8, auquel cas il faut ### bel et bien prendre simplement le byte d'avant) elif filterByte == 2: for i in range(1, row_length): rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256 elif filterByte == 3: for i in range(1, row_length): left = rowdata[i - 1] if i > 1 else 0 floor = math.floor(left + prev_rowdata[i]) / 2 rowdata[i] = (rowdata[i] + int(floor)) % 256 elif filterByte == 4: for i in range(1, row_length): left = rowdata[i - 1] if i > 1 else 0 up = prev_rowdata[i] up_left = prev_rowdata[i - 1] if i > 1 else 0 paeth = paethPredictor(left, up, up_left) rowdata[i] = (rowdata[i] + paeth) % 256 else: # Unsupported PNG filter raise PdfReadError("Unsupported PNG filter %r" % filterByte) prev_rowdata = rowdata for d in rowdata[ 1:]: ### Ignorer le premier bit de chaque scanline if version_info < (3, 0): output.write(chr(d)) else: output.write(bytes([d])) data = output.getvalue() else: # unsupported predictor raise PdfReadError("Unsupported flatedecode predictor %r" % predictor) return data