예제 #1
0
        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
예제 #2
0
    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
예제 #3
0
    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