Ejemplo n.º 1
0
        def _readCode(self):
            toread = self.bitspercode
            value = 0

            while toread > 0:
                if self.bytepos >= len(self.data):
                    return -1

                nextbits = pypdfOrd(self.data[self.bytepos])
                bitsfromhere = 8 - self.bitpos

                if bitsfromhere > toread:
                    bitsfromhere = toread

                value |= ((nextbits >> (8 - self.bitpos - bitsfromhere)) &
                          (0xFF >>
                           (8 - bitsfromhere))) << (toread - bitsfromhere)
                toread -= bitsfromhere
                self.bitpos += bitsfromhere

                if self.bitpos >= 8:
                    self.bitpos = 0
                    self.bytepos = self.bytepos + 1

            return value
Ejemplo n.º 2
0
    def encode(data, decodeParms=None):
        """
        Encodes chunks of 4-byte sequences of textual or bytes data according
        to the base-85 ASCII encoding algorithm.

        :param data: a str or byte sequence of values.
        :return: ASCII85-encoded data in bytes format (equal to str in Python
            2).
        """
        if sys.version_info[0] < 3:
            result = str()
            filler = "\x00" if type(data) is str else b"\x00"

            if type(data) not in (str, bytes):
                raise TypeError(
                    "Expected str or bytes type for data, got %s instead" %
                    type(data))

            for group in range(int(math.ceil(len(data) / 4.0))):
                decimalRepr = 0
                ascii85 = str()
                groupWidth = min(4, len(data) - 4 * group)

                if groupWidth < 4:
                    data = data + (4 - groupWidth) * filler

                for byte in range(4):
                    decimalRepr += pypdfOrd(
                        data[4 * group + byte]) << 8 * (4 - byte - 1)

                # If all bytes are 0, we turn them into a single 'z' character
                if decimalRepr == 0 and groupWidth == 4:
                    ascii85 = "z"
                else:
                    for i in range(5):
                        ascii85 = chr(decimalRepr % 85 + 33) + ascii85
                        decimalRepr = int(decimalRepr / 85.0)

                # In case of a partial group of four bytes, the standard says:
                # «Finally, it shall write only the first n + 1 characters of the
                # resulting group of 5.» - ISO 32000 (2008), sec. 7.4.3
                result += ascii85[:min(5, groupWidth + 1)]

            return ("<~" + result + "~>").encode("LATIN1")
        else:
            return base64.a85encode(data, adobe=True)
Ejemplo n.º 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)

            # 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
Ejemplo n.º 4
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