Coverage Report

Created: 2025-07-11 06:18

/src/libheif/libheif/plugin_registry.cc
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * HEIF codec.
3
 * Copyright (c) 2017 Dirk Farin <dirk.farin@gmail.com>
4
 *
5
 * This file is part of libheif.
6
 *
7
 * libheif is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * libheif is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with libheif.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include <utility>
22
#include <cstring>
23
#include <algorithm>
24
25
#include "plugin_registry.h"
26
#include "init.h"
27
28
29
#if HAVE_LIBDE265
30
#include "plugins/decoder_libde265.h"
31
#endif
32
33
#if HAVE_X265
34
#include "plugins/encoder_x265.h"
35
#endif
36
37
#if HAVE_KVAZAAR
38
#include "plugins/encoder_kvazaar.h"
39
#endif
40
41
#if HAVE_UVG266
42
#include "plugins/encoder_uvg266.h"
43
#endif
44
45
#if HAVE_VVDEC
46
#include "plugins/decoder_vvdec.h"
47
#endif
48
49
#if HAVE_VVENC
50
#include "plugins/encoder_vvenc.h"
51
#endif
52
53
#if HAVE_AOM_ENCODER
54
#include "plugins/encoder_aom.h"
55
#endif
56
57
#if HAVE_AOM_DECODER
58
#include "plugins/decoder_aom.h"
59
#endif
60
61
#if HAVE_RAV1E
62
#include "plugins/encoder_rav1e.h"
63
#endif
64
65
#if HAVE_DAV1D
66
#include "plugins/decoder_dav1d.h"
67
#endif
68
69
#if HAVE_SvtEnc
70
#include "plugins/encoder_svt.h"
71
#endif
72
73
#if HAVE_FFMPEG_DECODER
74
#include "plugins/decoder_ffmpeg.h"
75
#endif
76
77
#if WITH_UNCOMPRESSED_CODEC
78
#include "plugins/encoder_uncompressed.h"
79
#include "plugins/decoder_uncompressed.h"
80
#endif
81
82
#if HAVE_JPEG_DECODER
83
#include "plugins/decoder_jpeg.h"
84
#endif
85
86
#if HAVE_JPEG_ENCODER
87
#include "plugins/encoder_jpeg.h"
88
#endif
89
90
#if HAVE_OpenH264_DECODER
91
#include "plugins/decoder_openh264.h"
92
#endif
93
94
#if HAVE_OPENJPEG_ENCODER
95
#include "plugins/encoder_openjpeg.h"
96
#endif
97
98
#if HAVE_OPENJPEG_DECODER
99
#include "plugins/decoder_openjpeg.h"
100
#endif
101
102
#include "plugins/encoder_mask.h"
103
104
#if HAVE_OPENJPH_ENCODER
105
#include "plugins/encoder_openjph.h"
106
#endif
107
108
std::set<const struct heif_decoder_plugin*> s_decoder_plugins;
109
110
std::multiset<std::unique_ptr<struct heif_encoder_descriptor>,
111
              encoder_descriptor_priority_order> s_encoder_descriptors;
112
113
std::set<const struct heif_decoder_plugin*>& get_decoder_plugins()
114
0
{
115
0
  load_plugins_if_not_initialized_yet();
116
117
0
  return s_decoder_plugins;
118
0
}
119
120
extern std::multiset<std::unique_ptr<struct heif_encoder_descriptor>,
121
                     encoder_descriptor_priority_order>& get_encoder_descriptors()
122
0
{
123
0
  load_plugins_if_not_initialized_yet();
124
125
0
  return s_encoder_descriptors;
126
0
}
127
128
129
// Note: we cannot move this to 'heif_init' because we have to make sure that this is initialized
130
// AFTER the two global std::set above.
131
static class Register_Default_Plugins
132
{
133
public:
134
  Register_Default_Plugins()
135
2
  {
136
2
    register_default_plugins();
137
2
  }
138
} dummy;
139
140
141
void register_default_plugins()
142
2
{
143
#if HAVE_LIBDE265
144
  register_decoder(get_decoder_plugin_libde265());
145
#endif
146
147
#if HAVE_X265
148
  register_encoder(get_encoder_plugin_x265());
149
#endif
150
151
#if HAVE_KVAZAAR
152
  register_encoder(get_encoder_plugin_kvazaar());
153
#endif
154
155
#if HAVE_UVG266
156
  register_encoder(get_encoder_plugin_uvg266());
157
#endif
158
159
#if HAVE_VVENC
160
  register_encoder(get_encoder_plugin_vvenc());
161
#endif
162
163
#if HAVE_VVDEC
164
  register_decoder(get_decoder_plugin_vvdec());
165
#endif
166
167
#if HAVE_AOM_ENCODER
168
  register_encoder(get_encoder_plugin_aom());
169
#endif
170
171
#if HAVE_AOM_DECODER
172
  register_decoder(get_decoder_plugin_aom());
173
#endif
174
175
#if HAVE_RAV1E
176
  register_encoder(get_encoder_plugin_rav1e());
177
#endif
178
179
#if HAVE_DAV1D
180
  register_decoder(get_decoder_plugin_dav1d());
181
#endif
182
183
#if HAVE_SvtEnc
184
  register_encoder(get_encoder_plugin_svt());
185
#endif
186
187
#if HAVE_FFMPEG_DECODER
188
  register_decoder(get_decoder_plugin_ffmpeg());
189
#endif
190
191
#if HAVE_JPEG_DECODER
192
  register_decoder(get_decoder_plugin_jpeg());
193
#endif
194
195
#if HAVE_JPEG_ENCODER
196
  register_encoder(get_encoder_plugin_jpeg());
197
#endif
198
199
#if HAVE_OPENJPEG_ENCODER
200
  register_encoder(get_encoder_plugin_openjpeg());
201
#endif
202
203
#if HAVE_OPENJPEG_DECODER
204
  register_decoder(get_decoder_plugin_openjpeg());
205
#endif
206
207
#if HAVE_OPENJPH_ENCODER
208
  register_encoder(get_encoder_plugin_openjph());
209
#endif
210
211
#if HAVE_OpenH264_DECODER
212
  register_decoder(get_decoder_plugin_openh264());
213
#endif
214
215
2
#if WITH_UNCOMPRESSED_CODEC
216
2
  register_encoder(get_encoder_plugin_uncompressed());
217
2
  register_decoder(get_decoder_plugin_uncompressed());
218
2
#endif
219
220
2
  register_encoder(get_encoder_plugin_mask());
221
2
}
222
223
224
void register_decoder(const heif_decoder_plugin* decoder_plugin)
225
2
{
226
2
  if (decoder_plugin->init_plugin) {
227
0
    (*decoder_plugin->init_plugin)();
228
0
  }
229
230
2
  s_decoder_plugins.insert(decoder_plugin);
231
2
}
232
233
234
const struct heif_decoder_plugin* get_decoder(enum heif_compression_format type, const char* name_id)
235
0
{
236
0
  load_plugins_if_not_initialized_yet();
237
238
0
  int highest_priority = 0;
239
0
  const struct heif_decoder_plugin* best_plugin = nullptr;
240
241
0
  for (const auto* plugin : s_decoder_plugins) {
242
243
0
    int priority = plugin->does_support_format(type);
244
245
0
    if (priority > 0 && name_id && plugin->plugin_api_version >= 3) {
246
0
      if (strcmp(name_id, plugin->id_name) == 0) {
247
0
        return plugin;
248
0
      }
249
0
    }
250
251
0
    if (priority > highest_priority) {
252
0
      highest_priority = priority;
253
0
      best_plugin = plugin;
254
0
    }
255
0
  }
256
257
0
  return best_plugin;
258
0
}
259
260
261
void register_encoder(const heif_encoder_plugin* encoder_plugin)
262
4
{
263
4
  if (encoder_plugin->init_plugin) {
264
4
    (*encoder_plugin->init_plugin)();
265
4
  }
266
267
4
  auto descriptor = std::unique_ptr<struct heif_encoder_descriptor>(new heif_encoder_descriptor);
268
4
  descriptor->plugin = encoder_plugin;
269
270
4
  s_encoder_descriptors.insert(std::move(descriptor));
271
4
}
272
273
274
const struct heif_encoder_plugin* get_encoder(enum heif_compression_format type)
275
0
{
276
0
  load_plugins_if_not_initialized_yet();
277
278
0
  auto filtered_encoder_descriptors = get_filtered_encoder_descriptors(type, nullptr);
279
0
  if (filtered_encoder_descriptors.size() > 0) {
280
0
    return filtered_encoder_descriptors[0]->plugin;
281
0
  }
282
0
  else {
283
0
    return nullptr;
284
0
  }
285
0
}
286
287
288
std::vector<const struct heif_encoder_descriptor*>
289
get_filtered_encoder_descriptors(enum heif_compression_format format,
290
                                 const char* name)
291
0
{
292
0
  std::vector<const struct heif_encoder_descriptor*> filtered_descriptors;
293
294
0
  for (const auto& descr : s_encoder_descriptors) {
295
0
    const struct heif_encoder_plugin* plugin = descr->plugin;
296
297
0
    if (plugin->compression_format == format || format == heif_compression_undefined) {
298
0
      if (name == nullptr || strcmp(name, plugin->id_name) == 0) {
299
0
        filtered_descriptors.push_back(descr.get());
300
0
      }
301
0
    }
302
0
  }
303
304
305
  // Note: since our std::set<> is ordered by priority, we do not have to sort our output
306
307
0
  return filtered_descriptors;
308
0
}
309
310
311
void heif_unregister_decoder_plugins()
312
0
{
313
0
  for (const auto* plugin : s_decoder_plugins) {
314
0
    if (plugin->deinit_plugin) {
315
0
      (*plugin->deinit_plugin)();
316
0
    }
317
0
  }
318
0
  s_decoder_plugins.clear();
319
0
}
320
321
void heif_unregister_encoder_plugins()
322
0
{
323
0
  for (const auto& plugin : s_encoder_descriptors) {
324
0
    if (plugin->plugin->cleanup_plugin) {
325
0
      (*plugin->plugin->cleanup_plugin)();
326
0
    }
327
0
  }
328
0
  s_encoder_descriptors.clear();
329
0
}
330
331
#if ENABLE_PLUGIN_LOADING
332
void heif_unregister_encoder_plugin(const heif_encoder_plugin* plugin)
333
{
334
  if (plugin->cleanup_plugin) {
335
    (*plugin->cleanup_plugin)();
336
  }
337
338
  for (auto iter = s_encoder_descriptors.begin() ; iter != s_encoder_descriptors.end(); ++iter) {
339
    if ((*iter)->plugin == plugin) {
340
      s_encoder_descriptors.erase(iter);
341
      return;
342
    }
343
  }
344
}
345
#endif