# This file is a part of Lector, a Qt based ebook reader # Copyright (C) 2017-2019 BasioMeusPuga # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import os import collections import djvu.decode from PyQt5 import QtGui class ParseDJVU: def __init__(self, filename, *args): self.book = None self.filename = filename def read_book(self): self.book = djvu.decode.Context().new_document( djvu.decode.FileURI(self.filename)) self.book.decoding_job.wait() def generate_metadata(self): # TODO # What even is this? title = os.path.basename(self.filename) author = 'Unknown' year = 9999 isbn = None tags = [] cover_page = self.book.pages[0] cover = render_djvu_page(cover_page, True) Metadata = collections.namedtuple( 'Metadata', ['title', 'author', 'year', 'isbn', 'tags', 'cover']) return Metadata(title, author, year, isbn, tags, cover) def generate_content(self): # TODO # See if it's possible to generate a more involved ToC content = list(range(len(self.book.pages))) toc = [(1, f'Page {i + 1}', i + 1) for i in content] # Return toc, content, images_only return toc, content, True def render_djvu_page(page, for_cover=False): # TODO # Figure out how to calculate image stride # and if it impacts row_alignment in the render # method below # bytes_per_line = 13200 djvu_pixel_format = djvu.decode.PixelFormatRgbMask( 0xFF0000, 0xFF00, 0xFF, bpp=32) djvu_pixel_format.rows_top_to_bottom = 1 djvu_pixel_format.y_top_to_bottom = 0 # ¯\_(ツ)_/¯ mode = 0 page_job = page.decode(wait=True) width, height = page_job.size rect = (0, 0, width, height) output = page_job.render( mode, rect, rect, djvu_pixel_format) # row_alignment=bytes_per_line) imageFormat = QtGui.QImage.Format_RGB32 pageQImage = QtGui.QImage(output, width, height, imageFormat) # Format conversion not only keeps the damn thing from # segfaulting when converting from QImage to QPixmap, # but it also allows for the double page mode to keep # working properly. We like format conversion. pageQImage = pageQImage.convertToFormat( QtGui.QImage.Format_ARGB32_Premultiplied) if for_cover: return pageQImage pixmap = QtGui.QPixmap() pixmap.convertFromImage(pageQImage) return pixmap