Skip to content

Commit 8c2482a

Browse files
committed
Merge branch 'unstable' into stable for 1.0.0 release
2 parents b70cd4f + 4fbbcfd commit 8c2482a

40 files changed

+2212
-491
lines changed

LICENSE.txt

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,7 @@ XL Converter is licensed under GNU General Public License v3.
22

33
Copyright (c) 2023 - 2024 Code Poems <contact@codepoems.eu>
44

5-
---------------------------------------------------------------------------------
6-
7-
This End-User License Agreement ("EULA") is a legal agreement between you (either an individual or an entity) and the software program's authors and contributors, for the software product accompanying this EULA, which includes computer software and may include associated media, printed materials, and "online" or electronic documentation ("Software").
8-
9-
By installing, copying, or otherwise using the Software, you agree to be bound by the terms of this EULA, which incorporates the terms and conditions of the GNU General Public License Version 3 (GPLv3) as published by the Free Software Foundation. If you do not agree to the terms of this EULA, do not install or use the Software.
10-
11-
COPYRIGHT: The Software is copyrighted and licensed (not sold) to you. The Software is protected by copyright laws and treaties around the world. All rights not expressly granted to you by this EULA are reserved by the copyright owners.
12-
13-
LICENSE: The Software is licensed under the GNU General Public License Version 3 (GPLv3), the terms of which are incorporated herein by reference. By installing, copying, or using the Software you acknowledge that you have read the GPLv3, understand it, and agree to be bound by its terms and conditions. The GPLv3 can be obtained at: http://www.gnu.org/licenses/gpl-3.0.html
14-
15-
LICENSE GRANT: This EULA grants you the following rights, subject to the terms of the GPLv3:
16-
- You may copy, distribute, and modify the software provided that you track changes/dates in source files and keep intact all notices on the original software.
17-
- You may distribute the software to anyone and for any purpose and charge no more than the cost of distributing the software.
18-
- You may use portions of the software independently of the complete program.
19-
- Works that you distribute or publish that contain or are derived from the Software or any part thereof must be licensed as a whole at no charge to all third parties under the terms of this License (GPLv3).
20-
21-
UPDATE FEATURE: The Software includes a feature to check for updates, which requires the transmission of the user's Internet Protocol (IP) address to a server in order to obtain a text file for the update process. By using this feature, you acknowledge and consent to the transmission of your IP address for this purpose. The IP address is used solely for fetching the necessary update information and will not be used for any other purposes. While the IP address may be stored for a period of up to 12 months, it is typically stored for a shorter period.
22-
23-
WEB LINK FEATURE: The Software includes a feature that opens a link to our webpage or our GitHub repository. By using this feature, you acknowledge and consent to the Software initiating an external connection to these sites. Please note that our webpage and GitHub repository are governed by their own terms of service and privacy policies, which we encourage you to review.
24-
25-
PRIVACY: The author prioritizes your privacy. Apart from the IP address used for the update feature, no other personal data is collected from you without your explicit consent.
26-
27-
DISCLAIMER OF WARRANTY: The Software is provided "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the Software is with you.
28-
29-
LIMITATION OF LIABILITY: Except as mandated by law or as explicitly agreed upon in a written contract, neither copyright owners nor any individuals or entities that amend and/or distribute the Software under GPLv3 shall bear financial responsibility to you for any form of loss or damage. This exclusion of liability encompasses a wide range of potential issues, such as general, specific, unplanned, or secondary harm that may arise from utilizing or the failure to use the Software. Potential issues covered include, but are not limited to, data loss, data corruption, any harm suffered by you or third parties, or the inability of the Software to function with other software systems, even if such copyright owner or entity has been previously notified about the risk of such damages.
30-
31-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32-
33-
TERMINATION: This EULA and your rights under it will terminate automatically without notice from the copyright owner if you fail to comply with any of its terms and conditions, including but not limited to the terms of the GNU General Public License Version 3 (GPLv3).
34-
35-
MISCELLANEOUS: This EULA is governed by the laws of the jurisdiction in which the copyright owner resides. If any part of this EULA is found to be void, invalid, or unenforceable, it will not affect the validity of the balance of the EULA, which shall remain valid and enforceable according to its terms.
36-
37-
ENTIRE AGREEMENT: This EULA (including the GPLv3) is the entire agreement between you and the copyright owner relating to the Software and supersedes all prior or contemporaneous oral or written communications, proposals, and representations with respect to the Software or any other subject matter covered by this EULA.
38-
39-
By installing, copying, or using the Software you acknowledge that you have read this EULA, understand it, and agree to be bound by its terms and conditions. You also agree that this EULA is the complete and exclusive statement of the agreement between us and supersedes all proposals or prior agreements, oral or written, and any other communications relating to the subject matter of this EULA.
40-
41-
You can contact me at this email address: contact@codepoems.eu
42-
43-
-----------------------------------------------------------------------------------
5+
-------------------------- BEGIN LICENSE --------------------------
446

457
GNU GENERAL PUBLIC LICENSE
468
Version 3, 29 June 2007
@@ -716,4 +678,14 @@ into proprietary programs. If your program is a subroutine library, you
716678
may consider it more useful to permit linking proprietary applications with
717679
the library. If this is what you want to do, use the GNU Lesser General
718680
Public License instead of this License. But first, please read
719-
<https://www.gnu.org/licenses/why-not-lgpl.html>.
681+
<https://www.gnu.org/licenses/why-not-lgpl.html>.
682+
683+
--------------------------- END LICENSE ---------------------------
684+
685+
----------------------- BEGIN PRIVACY POLICY ----------------------
686+
687+
WEB LINK FEATURE: This Software includes a feature that opens a link to our webpage or GitHub repository. By using this feature, you consent to the Software initiating an external connection to these sites. Be aware that these sites have their own terms of service and privacy policies, which you should review.
688+
689+
UPDATE FEATURE: The Software includes a feature to check for updates, which requires the transmission of the user's Internet Protocol (IP) address to a server in order to obtain a text file for the update process. By using this feature, you acknowledge and consent to the transmission of your IP address for this purpose. The IP address is used solely for fetching the necessary update information and will not be used for any other purposes. While the IP address may be stored for a period of up to 12 months.
690+
691+
----------------------- END PRIVACY POLICY ------------------------

README.md

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
<p align="center">
1+
<div align="center">
22
<img src="icons/logo.svg" width="20%">
3-
</p>
43
<h3 align="center">XL Converter</h3>
54

65
Powerful image converter for the latest formats with support for multithreading, drag 'n drop, and downscaling.
@@ -9,7 +8,8 @@ Available for Windows and Linux.
98

109
![](misc/screenshots/screenshot_0.png)
1110

12-
The [documentation](https://xl-docs.codepoems.eu)
11+
Read the [Manual](https://xl-docs.codepoems.eu)
12+
</div>
1313

1414
## Supported Formats
1515

@@ -20,13 +20,13 @@ Encode to **JPEG XL, AVIF, WEBP, and JPG**. Convert from **HEIF** and [more](htt
2020

2121
Just drop your images and convert. XL Converter works out of the box with no setup or steep learning curve. It prioritizes user experience while granting access to cutting-edge technology.
2222

23-
#### JPG Reconstruction
23+
#### Parallel Encoding
2424

25-
Losslessly transcode JPG to JPEG XL, reverse the process when needed.
25+
Encode images in parallel to speed up the process. Control how much CPU to use during encoding.
2626

27-
#### Multithreading
27+
#### JPG Reconstruction
2828

29-
Use as many CPU cores as you want.
29+
Losslessly transcode JPG to JPEG XL, and reverse the process when needed.
3030

3131
#### Image Proxy
3232

@@ -52,7 +52,7 @@ Easily copy and wipe metadata using encoder parameters or ExifTool.
5252

5353
#### JPEGLI
5454

55-
Encode to regular JPG using the highest quality encoder available.
55+
Generate the highest quality (regular old) JPGs with JPEGLI.
5656

5757
## Bug Reports
5858

@@ -68,10 +68,13 @@ Feel free to make bug reports as contributions.
6868

6969
## Building from Source
7070

71+
> [!NOTE]
72+
> The recommended way of using XL Converter is through the [official binary releases](https://codepoems.eu/xl-converter). The building process is time-consuming and tedious.
73+
7174
### Windows 10
7275

73-
Prerequisites:
74-
- Python `3.11.6` (with `pip`)
76+
Install:
77+
- Python `3.11.9` (with `pip`)
7578
- `git`
7679

7780
Clone the repo.
@@ -111,8 +114,28 @@ Install packages.
111114

112115
```bash
113116
sudo apt update
114-
sudo apt install python3 python3-pip python3-venv git
115-
sudo apt install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
117+
sudo apt install git make
118+
```
119+
120+
Install [xcb QPA](https://doc.qt.io/qt-6/linux-requirements.html) dependencies.
121+
122+
```bash
123+
sudo apt install '^libxcb.*-dev' libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
124+
```
125+
126+
Install [pyenv](https://github.com/pyenv/pyenv) via [Automatic installer](https://github.com/pyenv/pyenv?tab=readme-ov-file#automatic-installer) then [add it to shell](https://github.com/pyenv/pyenv?tab=readme-ov-file#set-up-your-shell-environment-for-pyenv)
127+
128+
Install Python build packages.
129+
130+
```bash
131+
sudo apt install wget build-essential libreadline-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev liblzma-dev
132+
```
133+
134+
Build and setup Python `3.11.9`.
135+
136+
```bash
137+
pyenv install 3.11.9
138+
pyenv local 3.11.9
116139
```
117140

118141
Clone and set up the repo.
@@ -159,52 +182,41 @@ Extra building modes:
159182
To build XL Converter, you need to provide various binaries. This can be quite challenging.
160183

161184
Binaries needed:
162-
- [libjxl](https://github.com/libjxl/libjxl) 0.10.2
185+
- [libjxl](https://github.com/libjxl/libjxl) `0.10.2` ([with this patch on Windows](https://github.com/JacobDev1/libjxl-utf8))
163186
- cjxl
164187
- djxl
165188
- jxlinfo
166189
- cjpegli
167-
- [libavif](https://github.com/AOMediaCodec/libavif) 1.0.3 (**AVIF_CODEC_AOM**)
190+
- [libavif](https://github.com/AOMediaCodec/libavif) `1.0.4` (AOM `3.8.2`)
168191
- avifenc
169192
- avifdec
170-
- [imagemagick](https://imagemagick.org/) 7.1.1-15 Q16-HDRI
193+
- [imagemagick](https://imagemagick.org/) `7.1.1-15 Q16-HDRI`
171194
- magick - AppImage for Linux
172195
- magick.exe - Windows
173-
- [exiftool](https://exiftool.org/) 12.77
196+
- [exiftool](https://exiftool.org/) `12.77`
174197
- exiftool.exe - Windows
175198
- exiftool - standalone Perl build
176-
- [oxipng](https://github.com/shssoichiro/oxipng) 0.8.0
199+
- [oxipng](https://github.com/shssoichiro/oxipng) `0.9.0`
177200

178201
Place them in the following directories:
179202
- `xl-converter\bin\win` for Windows (x86_64)
180203
- `xl-converter/bin/linux` for Linux (x86_64)
181204

182205
All binaries are built statically. The version numbers should match. Binaries on Windows have an `.exe` extension.
183206

184-
See the official [XL Converter builds](https://github.com/JacobDev1/xl-converter/releases) for examples.
207+
> [!TIP]
208+
> See the official [XL Converter builds](https://github.com/JacobDev1/xl-converter/releases) for examples.
185209
186210
## Info
187211

188-
### Python Version
189-
190-
The project runs on Python `3.11.6`. It should also work on a slightly older version. `3.12` and newer are not supported.
191-
192-
### Large Files
193-
194-
Don't forget `--depth 1` when running `git clone`. This repo contains large files.
212+
> [!IMPORTANT]
213+
> This project runs on Python `3.11`. Other versions are not supported.
195214
196-
### Development Branch
197-
198-
The dev branch can be accessed with
199-
200-
```bash
201-
git clone -b unstable --depth 1 https://github.com/JacobDev1/xl-converter.git
202-
```
215+
> [!NOTE]
216+
> Don't forget `--depth 1` when running `git clone` to avoid large files.
203217
204218
## Unit Testing
205219

206-
Unit tests are currently being reworked.
207-
208220
### Running
209221

210222
[Setup repo](#building-from-source).
@@ -218,24 +230,16 @@ pip install -r requirements.txt
218230
pip install -r requirements_test.txt
219231
```
220232

221-
Run tests (Linux)
222-
223-
```bash
224-
make test
225-
```
226-
227-
Run tests (Windows)
233+
Run tests
228234

229235
```cmd
230236
python test.py
231237
```
232238

233239
### Deprecated
234240

235-
`tests_old.py` is a deprecated, but still accessible test suite.
236-
237-
To run them, put any image with a varying aspect ratio inside a `sample_img` folder in the project's directory.
241+
`test_old.py` is a deprecated, but still accessible test suite focusing on the conversion results.
238242

239243
```bash
240-
python tests_old.py
244+
python test_old.py
241245
```

build.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def build(self):
225225
self._appendInstaller()
226226
self._appendDesktopEntry()
227227
self._appendMisc()
228-
self._appendRedistributable()
228+
self._downloadRedistributable()
229229
self._appendUpdateFile()
230230
self._finish()
231231

@@ -300,15 +300,11 @@ def _appendMisc(self):
300300
copy(self.icon_svg_path, f"{self.internal_dir}/icons/{os.path.basename(self.icon_svg_path)}")
301301
copyTree(self.fonts_path, f"{self.internal_dir}/fonts")
302302

303-
def _appendRedistributable(self):
303+
def _downloadRedistributable(self):
304304
if platform.system() != "Windows":
305305
return
306306

307307
self.downloader.downloadRedistributable()
308-
print("[Building] Appending redistributable")
309-
redist_dst = f"{self.dst_dir}/{self.project_name}/redist"
310-
makedirs(redist_dst)
311-
copy(self.redist_path, redist_dst)
312308

313309
def _appendUpdateFile(self):
314310
print("[Building] Appending an update file (to place on a server)")

core/proxy.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import logging
3+
import re
34

45
from PySide6.QtCore import (
56
QMutexLocker,
@@ -10,9 +11,12 @@
1011
ALLOWED_INPUT_CJPEGLI,
1112
ALLOWED_INPUT_AVIFENC,
1213
ALLOWED_INPUT_IMAGE_MAGICK,
14+
IMAGE_MAGICK_PATH,
1315
)
1416
from core.pathing import getUniqueFilePath
1517
from core.convert import convert, getDecoder
18+
from core.process import runProcessOutput
19+
from core.exceptions import FileException
1620

1721
class Proxy():
1822
def __init__(self):
@@ -54,6 +58,16 @@ def isProxyNeeded(self, _format, src_ext, jpegli=False, downscaling_enabled=Fals
5458

5559
def generate(self, src, src_ext, dst_dir, file_name, n, mutex):
5660
"""Generate a proxy image."""
61+
if src_ext in ("tif", "tiff"):
62+
try:
63+
layers_re = re.search(r"\d+", runProcessOutput(IMAGE_MAGICK_PATH, "identify", "-format", "%n\n", src).decode("utf-8"))
64+
layers_n = int(layers_re.group(0))
65+
except Exception:
66+
raise FileException("Proxy_0", "Cannot detect the number of pages.")
67+
68+
if layers_n != 1:
69+
raise FileException("Proxy_1", "TIFFs with multiple pages are not supported.")
70+
5771
with QMutexLocker(mutex):
5872
self.proxy_path = getUniqueFilePath(dst_dir, file_name, "png", True)
5973

0 commit comments

Comments
 (0)