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
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
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
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')')
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'))
def write_to_stream(self, stream): stream.write(_u.s2b(repr(self)))