Skip to content

Commit 6497c23

Browse files
committed
Use stb scaling if we don't necessarily have to link SWS.
SWS is huge, and brings a lot of dependencies not necessarily desired when we disable video decoding. In that case, just use STB resizing. Issue: #140
1 parent 20995bc commit 6497c23

File tree

4 files changed

+90
-56
lines changed

4 files changed

+90
-56
lines changed

src/CMakeLists.txt

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,13 @@ if(WITH_TURBOJPEG)
7676
target_compile_definitions(timg PUBLIC WITH_TIMG_JPEG)
7777
target_link_libraries(timg
7878
PkgConfig::TURBOJPEG
79-
PkgConfig::EXIF
80-
PkgConfig::AVUTIL
81-
PkgConfig::SWSCALE)
79+
PkgConfig::EXIF)
8280
endif()
8381

8482
if(WITH_OPENSLIDE_SUPPORT)
8583
target_sources(timg PUBLIC openslide-source.h openslide-source.cc)
8684
target_compile_definitions(timg PUBLIC WITH_TIMG_OPENSLIDE_SUPPORT)
87-
target_link_libraries(timg PkgConfig::OPENSLIDE
88-
PkgConfig::AVUTIL
89-
PkgConfig::SWSCALE)
85+
target_link_libraries(timg PkgConfig::OPENSLIDE)
9086
endif()
9187

9288
if(WITH_VIDEO_DECODING)
@@ -100,26 +96,37 @@ if(WITH_VIDEO_DECODING)
10096
target_link_libraries(timg PkgConfig::LIBAV_DEVICE)
10197
add_definitions(-DHAVE_AVDEVICE)
10298
endif()
99+
set(SHOULD_SCALE_SWS ON) # we link it anyway
103100
endif()
104101

105102
if(WITH_STB_IMAGE)
106103
# STB usuall does not come with pkg-config. Just check if we see the include
104+
# Always want image resize2, if not, use third_party/
107105
include(CheckIncludeFileCXX)
108-
CHECK_INCLUDE_FILE_CXX(stb/stb_image.h HAVE_STB)
106+
CHECK_INCLUDE_FILE_CXX(stb/stb_image.h HAVE_SYSTEM_STB)
109107
target_sources(timg PUBLIC stb-image-source.h stb-image-source.cc)
110-
if(NOT HAVE_STB)
111-
message("--> Using STB from third_party/ instead")
108+
if(NOT HAVE_SYSTEM_STB)
109+
message("--> Using STB from third_party/")
112110
target_include_directories(timg PRIVATE ${CMAKE_SOURCE_DIR}/third_party)
113-
set(STB_RESIZE_VERSION2 true) # distributing resize2 in third_party/
114-
else()
115-
CHECK_INCLUDE_FILE_CXX(stb/stb_image_resize2.h STB_RESIZE_VERSION2)
116-
endif()
117-
if(STB_RESIZE_VERSION2)
118-
target_compile_definitions(timg PUBLIC STB_RESIZE_VERSION2)
119111
endif()
120112
target_compile_definitions(timg PUBLIC WITH_TIMG_STB)
121113
endif()
122114

115+
# TODO: for scaling, there is also zimg to explore
116+
if(SHOULD_SCALE_SWS)
117+
target_link_libraries(timg
118+
PkgConfig::AVUTIL
119+
PkgConfig::SWSCALE)
120+
target_compile_definitions(timg PUBLIC WITH_TIMG_SWS_RESIZE)
121+
else()
122+
CHECK_INCLUDE_FILE_CXX(stb/stb_image_resize2.h HAVE_SYSTEM_STB_RESIZE2)
123+
if(NOT HAVE_SYSTEM_STB_RESIZE2)
124+
message("--> Using STB resize2 from third_party/")
125+
target_include_directories(timg PRIVATE ${CMAKE_SOURCE_DIR}/third_party)
126+
endif()
127+
target_compile_definitions(timg PUBLIC WITH_TIMG_STB_RESIZE)
128+
endif()
129+
123130
if(WITH_QOI_IMAGE)
124131
include(CheckIncludeFileCXX)
125132
CHECK_INCLUDE_FILE_CXX(qoi.h HAVE_QOI)
@@ -129,9 +136,6 @@ if(WITH_QOI_IMAGE)
129136
target_include_directories(timg PRIVATE ${CMAKE_SOURCE_DIR}/third_party/qoi)
130137
endif()
131138
target_compile_definitions(timg PUBLIC WITH_TIMG_QOI)
132-
target_link_libraries(timg
133-
PkgConfig::AVUTIL
134-
PkgConfig::SWSCALE)
135139
endif()
136140

137141
# We always take the manpage from the checkout currently so that we don't

src/image-scaler.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,26 @@
1515

1616
#include "image-scaler.h"
1717

18+
#ifdef WITH_TIMG_SWS_RESIZE
1819
extern "C" { // avutil is missing extern "C"
1920
#include <libavutil/log.h>
2021
#include <libavutil/pixfmt.h>
2122
#include <libswscale/swscale.h>
2223
}
24+
#endif
25+
26+
#ifdef WITH_TIMG_STB_RESIZE
27+
#define STB_IMAGE_RESIZE_IMPLEMENTATION
28+
// Least amount of fuzziness on upscaling
29+
#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_BOX
30+
#include "stb/stb_image_resize2.h"
31+
#endif
32+
33+
// TODO: there is also zimg.
2334

2435
namespace timg {
2536
namespace {
37+
#if WITH_TIMG_SWS_RESIZE
2638
static void dummy_log(void *, int, const char *, va_list) {}
2739

2840
class SWSImageScaler final : public ImageScaler {
@@ -53,13 +65,47 @@ class SWSImageScaler final : public ImageScaler {
5365

5466
SwsContext *const sws_context_;
5567
};
68+
#endif
69+
#if WITH_TIMG_STB_RESIZE
70+
class STBImageScaler final : public ImageScaler {
71+
public:
72+
static STBImageScaler *Create(int in_width, int in_height,
73+
ColorFmt in_color_format, int out_width,
74+
int out_height) {
75+
return new STBImageScaler(in_color_format);
76+
}
77+
78+
void Scale(Framebuffer &in, Framebuffer *out) final {
79+
struct STBIR_RESIZE context {};
80+
stbir_resize_init(&context, (uint8_t *)in.begin(), in.width(),
81+
in.height(), 0, (uint8_t *)out->begin(), out->width(),
82+
out->height(), 0, STBIR_RGBA, STBIR_TYPE_UINT8);
83+
stbir_set_pixel_layouts(
84+
&context, in_fmt_ == ColorFmt::kRGBA ? STBIR_RGBA : STBIR_BGRA,
85+
STBIR_RGBA);
86+
stbir_resize_extended(&context);
87+
}
88+
89+
private:
90+
explicit STBImageScaler(ColorFmt in_fmt) : in_fmt_(in_fmt) {}
91+
const ColorFmt in_fmt_;
92+
};
93+
#endif
5694
} // namespace
5795

5896
std::unique_ptr<ImageScaler> ImageScaler::Create(int in_width, int in_height,
5997
ColorFmt in_color_format,
6098
int out_width,
6199
int out_height) {
100+
#if WITH_TIMG_SWS_RESIZE
62101
return std::unique_ptr<ImageScaler>(SWSImageScaler::Create(
63102
in_width, in_height, in_color_format, out_width, out_height));
103+
#elif WITH_TIMG_STB_RESIZE
104+
return std::unique_ptr<ImageScaler>(STBImageScaler::Create(
105+
in_width, in_height, in_color_format, out_width, out_height));
106+
#else
107+
#error "Configure issue: no image scaler available"
108+
return nullptr;
109+
#endif
64110
}
65111
} // namespace timg

src/stb-image-source.cc

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,40 +26,12 @@
2626
#include "buffered-write-sequencer.h"
2727
#include "display-options.h"
2828
#include "framebuffer.h"
29+
#include "image-scaler.h"
2930
#include "image-source.h"
3031
#include "renderer.h"
3132
#include "stb/stb_image.h"
3233
#include "timg-time.h"
3334

34-
#define STB_IMAGE_RESIZE_IMPLEMENTATION
35-
// Least amount of fuzziness on upscaling
36-
#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_BOX
37-
38-
// There is an old and a new version of stb resize. Prefer newer if available
39-
// (tested for in CMake), and provide adapter functions to use either.
40-
#if STB_RESIZE_VERSION2
41-
#include "stb/stb_image_resize2.h"
42-
inline void stb_resize_image(const unsigned char *input_pixels, int input_w,
43-
int input_h, unsigned char *output_pixels,
44-
int output_w, int output_h) {
45-
static constexpr stbir_pixel_layout kFramebufferFormat = STBIR_RGBA;
46-
stbir_resize_uint8_linear(input_pixels, input_w, input_h, 0, //
47-
output_pixels, output_w, output_h, 0,
48-
kFramebufferFormat);
49-
}
50-
51-
#else
52-
#include "stb/stb_image_resize.h"
53-
inline void stb_resize_image(const unsigned char *input_pixels, int input_w,
54-
int input_h, unsigned char *output_pixels,
55-
int output_w, int output_h) {
56-
static constexpr int kFramebufferFormat = 4; // RGBA.
57-
stbir_resize_uint8(input_pixels, input_w, input_h, 0, //
58-
output_pixels, output_w, output_h, 0, //
59-
kFramebufferFormat);
60-
}
61-
#endif
62-
6335
// TODO: preprocessed frame and SendFrames() are similar to
6436
// image-display.cc. Maybe things can be consolidated.
6537

@@ -71,8 +43,15 @@ class STBImageSource::PreprocessedFrame {
7143
int target_w, int target_h, const Duration &delay,
7244
const DisplayOptions &opt)
7345
: delay_(delay), framebuffer_(target_w, target_h) {
74-
stb_resize_image(image_data, source_w, source_h,
75-
(uint8_t *)framebuffer_.begin(), target_w, target_h);
46+
const size_t len = source_w * source_h * 4;
47+
Framebuffer source_img(source_w, source_h); // TODO: avoid copy.
48+
std::copy(image_data, image_data + len, (uint8_t *)source_img.begin());
49+
auto scaler = ImageScaler::Create(source_w, source_h,
50+
ImageScaler::ColorFmt::kRGBA,
51+
target_w, target_h);
52+
if (scaler) {
53+
scaler->Scale(source_img, &framebuffer_);
54+
}
7655
framebuffer_.AlphaComposeBackground(
7756
opt.bgcolor_getter, opt.bg_pattern_color,
7857
opt.pattern_size * opt.cell_x_px,

src/timg-print-version.cc

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@
4343
#include <jconfig.h>
4444
#endif
4545
#include <libdeflate.h>
46+
47+
#ifdef WITH_TIMG_SWS_RESIZE
4648
#include <libswscale/swscale.h> // NOLINT used for version.
49+
#endif
4750

4851
#include "timg-version.h" // generated.
4952
#ifndef TIMG_VERSION
@@ -95,20 +98,22 @@ int PrintComponentVersions(FILE *stream) {
9598
#endif
9699
#ifdef WITH_TIMG_STB
97100
fprintf(stream,
98-
"STB image loading; STB resize v"
99-
#ifdef STB_RESIZE_VERSION2
100-
"2"
101-
#else
102-
"1"
103-
#endif
101+
"STB image loading"
102+
104103
#ifdef WITH_TIMG_GRPAPHICSMAGICK
105104
// If we have graphics magic, that will take images first,
106105
// so STB will only really be called as fallback.
107106
" (fallback)"
108107
#endif
109108
"\n");
110109
#endif
111-
fprintf(stream, "swscale %s\n", AV_STRINGIFY(LIBSWSCALE_VERSION));
110+
111+
#ifdef WITH_TIMG_SWS_RESIZE
112+
fprintf(stream, "Resize: swscale %s\n", AV_STRINGIFY(LIBSWSCALE_VERSION));
113+
#else
114+
fprintf(stream, "Resize: STB resize\n");
115+
#endif
116+
112117
#ifdef WITH_TIMG_VIDEO
113118
fprintf(stream, "Video decoding %s\n", timg::VideoSource::VersionInfo());
114119
#endif

0 commit comments

Comments
 (0)