Skip to content

Use libjpeg-turbo for improved jpg compatibility and speed #104347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 43 additions & 5 deletions COPYRIGHT.txt
Original file line number Diff line number Diff line change
Expand Up @@ -324,16 +324,18 @@ Comment: Jolt Physics
Copyright: 2021, Jorrit Rouwe
License: Expat

Files: thirdparty/jpeg-compressor/*
Comment: jpeg-compressor
Copyright: 2012, Rich Geldreich
License: public-domain or Apache-2.0

Files: thirdparty/libbacktrace/*
Comment: libbacktrace
Copyright: 2012-2021, Free Software Foundation, Inc.
License: BSD-3-clause

Files: thirdparty/libjpeg-turbo/*
Comment: libjpeg-turbo
Copyright: 2009-2024, D. R. Commander
2015, Viktor Szathmáry.
1991-2020, Thomas G. Lane, Guido Vollbeding
License: BSD-3-clause and IJG

Files: thirdparty/libktx/*
Comment: KTX
Copyright: 2013-2020, Mark Callow
Expand Down Expand Up @@ -1683,6 +1685,42 @@ License: HarfBuzz
ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

License: IJG
The authors make NO WARRANTY or representation, either express or implied,
with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.
.
This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below.
.
Permission is hereby granted to use, copy, modify, and distribute this
software (or portions thereof) for any purpose, without fee, subject to these
conditions:
(1) If any part of the source code for this software is distributed, then this
README file must be included, with this copyright and no-warranty notice
unaltered; and any additions, deletions, or changes to the original files
must be clearly indicated in accompanying documentation.
(2) If only executable code is distributed, then the accompanying
documentation must state that "this software is based in part on the work of
the Independent JPEG Group".
(3) Permission for use of this software is granted only if the user accepts
full responsibility for any undesirable consequences; the authors accept
NO LIABILITY for damages of any kind.
.
These conditions apply to any software derived from or based on the IJG code,
not just to the unmodified library. If you use our work, you ought to
acknowledge us.
.
Permission is NOT granted for the use of any IJG author's name or company name
in advertising or publicity relating to this software or products derived from
it. This software may be referred to only as "the Independent JPEG Group's
software".
.
We specifically permit and encourage the use of this software as the basis of
commercial products, provided that all warranty or liability claims are
assumed by the product vendor.

License: MPL-2.0
Mozilla Public License Version 2.0
==================================
Expand Down
1 change: 1 addition & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ opts.Add(BoolVariable("builtin_glslang", "Use the built-in glslang library", Tru
opts.Add(BoolVariable("builtin_graphite", "Use the built-in Graphite library", True))
opts.Add(BoolVariable("builtin_harfbuzz", "Use the built-in HarfBuzz library", True))
opts.Add(BoolVariable("builtin_icu4c", "Use the built-in ICU library", True))
opts.Add(BoolVariable("builtin_libjpeg_turbo", "Use the built-in libjpeg-turbo library", True))
opts.Add(BoolVariable("builtin_libogg", "Use the built-in libogg library", True))
opts.Add(BoolVariable("builtin_libpng", "Use the built-in libpng library", True))
opts.Add(BoolVariable("builtin_libtheora", "Use the built-in libtheora library", True))
Expand Down
1 change: 1 addition & 0 deletions misc/error_suppressions/tsan.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ deadlock:modules/text_server_adv/text_server_adv.cpp
deadlock:modules/text_server_fb/text_server_fb.cpp
race:modules/navigation_2d/nav_map_2d.cpp
race:modules/navigation_3d/nav_map_3d.cpp
race:thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume it is ok to suppress errors in third party code? Or does that still leave us vulnerable to crashes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The best I can do is try to file a bug report with @hermet at Thorvg

2 changes: 1 addition & 1 deletion misc/error_suppressions/ubsan.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ float-divide-by-zero:thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp
function:thirdparty/embree/common/sys/thread.cpp
function:thirdparty/embree/kernels/common/accel.h
function:thirdparty/xatlas/xatlas.cpp
implicit-integer-sign-change:thirdparty/basis_universal/encoder/jpgd.cpp
implicit-integer-sign-change:thirdparty/basis_universal/transcoder/basisu_astc_helpers.h
implicit-integer-sign-change:thirdparty/embree/common/lexers/../sys/ref.h
implicit-integer-sign-change:thirdparty/embree/common/lexers/tokenstream.cpp
Expand Down Expand Up @@ -38,7 +39,6 @@ implicit-integer-sign-change:thirdparty/icu4c/common/unicode/unistr.h
implicit-integer-sign-change:thirdparty/icu4c/common/unistr.cpp
implicit-integer-sign-change:thirdparty/icu4c/common/uresbund.cpp
implicit-integer-sign-change:thirdparty/icu4c/common/ustrtrns.cpp
implicit-integer-sign-change:thirdparty/jpeg-compressor/jpgd.cpp
implicit-integer-sign-change:thirdparty/libogg/bitwise.c
implicit-integer-sign-change:thirdparty/libvorbis/info.c
implicit-integer-sign-change:thirdparty/libvorbis/sharedbook.c
Expand Down
2 changes: 1 addition & 1 deletion modules/basis_universal/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ if basisu_encoder:
"basisu_ssim.cpp",
"basisu_uastc_enc.cpp",
"basisu_uastc_hdr_4x4_enc.cpp",
"jpgd.cpp",
"pvpngreader.cpp",
]
encoder_sources = [thirdparty_dir + "encoder/" + file for file in encoder_sources]
Expand All @@ -47,7 +48,6 @@ transcoder_sources = [thirdparty_dir + "transcoder/basisu_transcoder.cpp"]
env_basisu.Prepend(CPPEXTPATH=[thirdparty_dir])

if basisu_encoder:
env_basisu.Prepend(CPPEXTPATH=["#thirdparty/jpeg-compressor"])
env_basisu.Prepend(CPPEXTPATH=["#thirdparty/tinyexr"])

if env["builtin_zstd"]:
Expand Down
2 changes: 1 addition & 1 deletion modules/basis_universal/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
def can_build(env, platform):
if env.editor_build: # Encoder dependencies
env.module_add_dependencies("basis_universal", ["jpg", "tinyexr"])
env.module_add_dependencies("basis_universal", ["tinyexr"])
return True


Expand Down
96 changes: 86 additions & 10 deletions modules/jpg/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,99 @@ Import("env_modules")

env_jpg = env_modules.Clone()

# Thirdparty source files

thirdparty_obj = []

# Not unbundled for now as they are not commonly available as shared library
thirdparty_dir = "#thirdparty/jpeg-compressor/"
thirdparty_sources = [
"jpgd.cpp",
"jpge.cpp",
thirdparty_dir = "#thirdparty/libjpeg-turbo"

thirdparty_sources_common = [
"jaricom.c",
"jcapimin.c",
"jcarith.c",
"jchuff.c",
"jcicc.c",
"jcinit.c",
"jcmarker.c",
"jcmaster.c",
"jcomapi.c",
"jcparam.c",
"jcphuff.c",
"jctrans.c",
"jdapimin.c",
"jdarith.c",
"jdatadst.c",
"jdatadst-tj.c",
"jdatasrc.c",
"jdatasrc-tj.c",
"jdhuff.c",
"jdicc.c",
"jdinput.c",
"jdmarker.c",
"jdmaster.c",
"jdphuff.c",
"jdtrans.c",
"jerror.c",
"jfdctflt.c",
"jmemmgr.c",
"jmemnobs.c",
"jpeg_nbits.c",
"transupp.c",
"turbojpeg.c",
]

thirdparty_sources_bit_dependent = [
"jcapistd.c",
"jccoefct.c",
"jccolor.c",
"jcdctmgr.c",
"jcmainct.c",
"jcprepct.c",
"jcsample.c",
"jdcoefct.c",
"jdcolor.c",
"jdapistd.c",
"jddctmgr.c",
"jdmainct.c",
"jdmerge.c",
"jdpostct.c",
"jdsample.c",
"jfdctfst.c",
"jfdctint.c",
"jidctflt.c",
"jidctfst.c",
"jidctint.c",
"jidctred.c",
"jutils.c",
"jquant1.c",
"jquant2.c",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]

env_jpg.Prepend(CPPEXTPATH=[thirdparty_dir])
thirdparty_sources_by_bits = {
8: list(thirdparty_sources_bit_dependent),
12: list(thirdparty_sources_bit_dependent),
}


def source_paths(files):
return [thirdparty_dir + "/src/" + f for f in files]


env_jpg.Prepend(CPPEXTPATH=[thirdparty_dir + "/src"])


def add_bit_depth(bit_depth: int):
env_bit_depth = env_jpg.Clone()
env_bit_depth.disable_warnings()
env_bit_depth["OBJSUFFIX"] = f"_{bit_depth}{env_bit_depth['OBJSUFFIX']}"
env_bit_depth.Append(CPPDEFINES=[f"BITS_IN_JSAMPLE={bit_depth}"])
env_bit_depth.add_source_files(thirdparty_obj, source_paths(thirdparty_sources_by_bits[bit_depth]))


add_bit_depth(8)
add_bit_depth(12)

env_thirdparty = env_jpg.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env_thirdparty.add_source_files(thirdparty_obj, source_paths(thirdparty_sources_common))
env.modules_sources += thirdparty_obj

# Godot source files
Expand Down
Loading