예제 #1
0
    def _chop_images(self):
        pages_count = len(self._flattened_pages)
        for i in range(pages_count):
            page = self._flattened_pages[i]
            bytes_data: bytes = page[_k.CONTENT].get_data()
            parts = _pattern_space.split(bytes_data)
            the_image = page[_k.RESOURCES][b'/XObject'][_get_image_name_from(parts)]
            _u.debug(parts, len(page[_k.RESOURCES][b'/XObject']), the_image)
            image_data = the_image.get_data()
            # _u.debug(the_image, len(image_data))
            if b'/Subtype' in the_image and the_image[b'/Subtype'] == b'/Image':
                (
                    width, height, compressed_length, compressed_data,
                ) = _im.chop_off_image_empty_edges(the_image, image_data, i + 1)
                the_image[NameObject(b'/Length')] = NumberObject(compressed_length)
                the_image[NameObject(b'/Width')] = NumberObject(width)
                the_image[NameObject(b'/Height')] = NumberObject(height)
                the_image._bytes_data = compressed_data

                # We might need to insert this matrix in the below line: 1 0 0 1 0 100 cm
                page[_k.CONTENT].set_data(
                    b'q ' + _u.s2b(str(width)) + b' 0 0 ' + _u.s2b(str(height)) + b' 0 0 cm ' + parts[-5] + b' Do Q'
                )
                page[_k.MEDIA_BOX][2] = NumberObject(width)
                page[_k.MEDIA_BOX][3] = NumberObject(height)
                _u.debug(
                    'Chopped empty edges for {:4}/{} image.'.format(i + 1, pages_count),
                    page[_k.MEDIA_BOX], page[_k.MEDIA_BOX][2:], parts, width, height,
                    page[_k.CONTENT].get_data(),
                )
            else:
                _u.debug(image_data)
                pass
예제 #2
0
 def _write_cross_reference_table(self, stream, object_positions):
     xref_location = stream.tell()
     stream.write(b'xref\n')
     stream.write(_u.s2b(f'0 {len(self._objects) + 1}\n'))
     stream.write(b'0000000000 00000 f \n')
     for offset in object_positions:
         stream.write(_u.s2b(f'{offset:010d} 00000 n \n'))
     _u.debug('Wrote cross reference table.')
     return xref_location
예제 #3
0
 def _write_objects_to(self, stream):
     _u.debug('Writing objects...')
     objects_count = len(self._objects)
     object_positions = []
     stream.write(b'%PDF-1.3\n')
     for i in range(objects_count):
         idnum = (i + 1)
         obj = self._objects[i]
         # _u.debug('idnum: [{:4}]'.format(idnum), '| type:', type(obj).__name__, '| obj:', obj)
         # if b'/Type' in obj:
         #     _u.debug('type:', obj[b'/Type'], '| obj:', obj)
         object_positions.append(stream.tell())
         stream.write(_u.s2b(f'{idnum} 0 obj\n'))
         key = None
         if (self._encrypt is not None) and (not (idnum == self._encrypt.idnum)):
             pack1 = _s.pack("<i", i + 1)[:3]
             pack2 = _s.pack("<i", 0)[:2]
             key = _u.encrypt(self._encrypt_key, pack1, pack2)
         if is_plain_object(obj):
             obj.write_to_stream(stream)
         else:
             obj.write_to_stream(stream, key)
         stream.write(b'\nendobj\n')
         _u.debug('Wrote {:4}/{} objects.'.format(i + 1, objects_count))
     return object_positions
예제 #4
0
 def write_to_stream(self, stream, encryption_key):
     # Try to write the string out as a PDFDocEncoding encoded string.  It's
     # nicer to look at in the PDF file.  Sadly, we take a performance hit
     # here for trying...
     try:
         byte_arr = _u.encode_pdf_doc_encoding(self)
     except UnicodeEncodeError:
         byte_arr = codecs.BOM_UTF16_BE + self.encode(_u.ENCODING_UTF16BE)
     if encryption_key:
         byte_arr = _u.rc4_encrypt(encryption_key, byte_arr)
         obj = ByteStringObject(byte_arr)
         obj.write_to_stream(stream, None)
     else:
         stream.write(b'(')
         for c in byte_arr:
             if not c.isalnum() and not c == ' ':
                 stream.write(_u.s2b("\\%03o" % ord(c)))
             else:
                 stream.write(_u.s2b(c))
         stream.write(b')')
예제 #5
0
    def write_to(self, stream):
        """
        Writes the collection of pages added to this object out as a PDF file.

        Stability: Added in v1.0, will exist for all v1.x releases.

        stream - An object to write the file to.  The object must support
                 the write method, and the tell method, similar to a file object.
        """
        # _u.debug(self.get_pages_count())
        # _u.debug(len(self._objects))
        external_reference_map = self._build_external_reference_map()
        # _u.debug(len(self._objects))
        self._scan_indirect_references(external_reference_map, self._root, [])
        # _u.debug(len(self._objects))

        # Begin writing:
        object_positions = self._write_objects_to(stream)
        xref_location = self._write_cross_reference_table(stream, object_positions)
        self._write_trailer_to(stream)
        stream.write(_u.s2b(f'\nstartxref\n{xref_location}\n%%%%EOF\n'))
예제 #6
0
 def write_to_stream(self, stream):
     stream.write(_u.s2b(repr(self)))