mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Edit book: Fix compress images losslessly failing for a few images on windows when there are a lot of images in the book. Fixes #1877066 [Error in Compressing images losslessly](https://bugs.launchpad.net/calibre/+bug/1877066)
This commit is contained in:
parent
b76b0a6c53
commit
319f289851
@ -16,9 +16,9 @@ class Worker(Thread):
|
||||
|
||||
daemon = True
|
||||
|
||||
def __init__(self, abort, name, queue, results, container, jpeg_quality, progress_callback):
|
||||
def __init__(self, abort, name, queue, results, jpeg_quality, progress_callback):
|
||||
Thread.__init__(self, name=name)
|
||||
self.queue, self.results, self.container = queue, results, container
|
||||
self.queue, self.results = queue, results
|
||||
self.progress_callback = progress_callback
|
||||
self.jpeg_quality = jpeg_quality
|
||||
self.abort = abort
|
||||
@ -27,11 +27,11 @@ class Worker(Thread):
|
||||
def run(self):
|
||||
while not self.abort.is_set():
|
||||
try:
|
||||
name = self.queue.get_nowait()
|
||||
name, path, mt = self.queue.get_nowait()
|
||||
except Empty:
|
||||
break
|
||||
try:
|
||||
self.compress(name)
|
||||
self.compress(name, path, mt)
|
||||
except Exception:
|
||||
import traceback
|
||||
self.results[name] = (False, traceback.format_exc())
|
||||
@ -43,16 +43,14 @@ class Worker(Thread):
|
||||
traceback.print_exc()
|
||||
self.queue.task_done()
|
||||
|
||||
def compress(self, name):
|
||||
def compress(self, name, path, mime_type):
|
||||
from calibre.utils.img import optimize_png, optimize_jpeg, encode_jpeg
|
||||
mt = self.container.mime_map[name]
|
||||
if 'png' in mt:
|
||||
if 'png' in mime_type:
|
||||
func = optimize_png
|
||||
elif self.jpeg_quality is None:
|
||||
func = optimize_jpeg
|
||||
else:
|
||||
func = partial(encode_jpeg, quality=self.jpeg_quality)
|
||||
path = self.container.get_file_path_for_processing(name)
|
||||
before = os.path.getsize(path)
|
||||
with lopen(path, 'rb') as f:
|
||||
old_data = f.read()
|
||||
@ -80,17 +78,24 @@ def compress_images(container, report=None, names=None, jpeg_quality=None, progr
|
||||
results = {}
|
||||
queue = Queue()
|
||||
abort = Event()
|
||||
for name in images:
|
||||
queue.put(name)
|
||||
seen = set()
|
||||
num_to_process = 0
|
||||
for name in sorted(images):
|
||||
path = os.path.normcase(os.path.abspath(container.get_file_path_for_processing(name)))
|
||||
if path not in seen:
|
||||
num_to_process += 1
|
||||
queue.put((name, path, container.mime_map[name]))
|
||||
seen.add(path)
|
||||
|
||||
def pc(name):
|
||||
keep_going = progress_callback(len(results), len(images), name)
|
||||
keep_going = progress_callback(len(results), num_to_process, name)
|
||||
if not keep_going:
|
||||
abort.set()
|
||||
progress_callback(0, len(images), '')
|
||||
[Worker(abort, 'CompressImage%d' % i, queue, results, container, jpeg_quality, pc) for i in range(min(detect_ncpus(), len(images)))]
|
||||
progress_callback(0, num_to_process, '')
|
||||
[Worker(abort, 'CompressImage%d' % i, queue, results, jpeg_quality, pc) for i in range(min(detect_ncpus(), num_to_process))]
|
||||
queue.join()
|
||||
before_total = after_total = 0
|
||||
processed_num = 0
|
||||
changed = False
|
||||
for name, (ok, res) in iteritems(results):
|
||||
name = force_unicode(name, filesystem_encoding)
|
||||
@ -98,6 +103,7 @@ def compress_images(container, report=None, names=None, jpeg_quality=None, progr
|
||||
before, after = res
|
||||
if before != after:
|
||||
changed = True
|
||||
processed_num += 1
|
||||
before_total += before
|
||||
after_total += after
|
||||
if report:
|
||||
@ -112,8 +118,8 @@ def compress_images(container, report=None, names=None, jpeg_quality=None, progr
|
||||
if report:
|
||||
if changed:
|
||||
report('')
|
||||
report(_('Total image filesize reduced from {0} to {1} [{2:.1%} reduction]').format(
|
||||
human_readable(before_total), human_readable(after_total), (before_total - after_total)/before_total))
|
||||
report(_('Total image filesize reduced from {0} to {1} [{2:.1%} reduction, {3} images changed]').format(
|
||||
human_readable(before_total), human_readable(after_total), (before_total - after_total)/before_total, processed_num))
|
||||
else:
|
||||
report(_('Images are already fully optimized'))
|
||||
return changed, results
|
||||
|
Loading…
x
Reference in New Issue
Block a user