refactor(common): de-Qt oakcommon and wrap it in a pure C ABI
- de-Qt all classes under src/common (std::string/vector/mutex, std::filesystem, expat-based XmlStreamReader/Writer) - add pure C ABI in include/common + src/common/c_api: opaque handles, init returns NULL on failure, free(NULL) is a no-op, out-params with negative OAKCOMMON_E_* error codes (include/common/error.h) - remove single-consumer classes from oakcommon (html, jobtime, otioutils, playbackaudioclock, tohex, util, avframeptr, crashpadinterface/crashpadutils, autoscroll, digit, range); their destinations are recorded in docs/zh/plans/riir/notes.md - add gtest suites under src/common/tests (127 cases), standalone build driver in src/common/standalone
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
target_sources(oakcommon PRIVATE
|
||||
commandlineparser.cpp
|
||||
current.cpp
|
||||
debug.cpp
|
||||
dropworkflowbehavior.cpp
|
||||
ffmpegutils.cpp
|
||||
filefunctions.cpp
|
||||
miscutils.cpp
|
||||
ocioutils.cpp
|
||||
oiioutils.cpp
|
||||
power.cpp
|
||||
qtutils.cpp
|
||||
xmlutils.cpp
|
||||
)
|
||||
@@ -0,0 +1,282 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/commandlineparser.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../src/commandlineparser.h"
|
||||
|
||||
struct OakCommonCommandLineParser {
|
||||
CommandLineParser impl;
|
||||
};
|
||||
|
||||
struct OakCommonCommandLineOption {
|
||||
CommandLineParser::Option *option;
|
||||
};
|
||||
|
||||
struct OakCommonCommandLinePositionalArgument {
|
||||
CommandLineParser::PositionalArgument *argument;
|
||||
};
|
||||
|
||||
OakCommonCommandLineParser *oakcommon_commandlineparser_init(void)
|
||||
{
|
||||
try {
|
||||
return new (std::nothrow) OakCommonCommandLineParser();
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_commandlineparser_free(OakCommonCommandLineParser *parser)
|
||||
{
|
||||
delete parser;
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_set_app_info(OakCommonCommandLineParser *parser,
|
||||
const char *name,
|
||||
const char *version)
|
||||
{
|
||||
if (!parser || !name) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
parser->impl.set_app_info(name, version ? version : "");
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_add_option(
|
||||
OakCommonCommandLineParser *parser, const char *const *names, int name_count,
|
||||
const char *description, int takes_arg, const char *arg_placeholder,
|
||||
int hidden, OakCommonCommandLineOption **out_option)
|
||||
{
|
||||
if (!parser || !names || name_count <= 0) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
std::vector<std::string> strings;
|
||||
strings.reserve(static_cast<size_t>(name_count));
|
||||
for (int i = 0; i < name_count; i++) {
|
||||
if (!names[i]) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
strings.emplace_back(names[i]);
|
||||
}
|
||||
|
||||
const CommandLineParser::Option *option = parser->impl.add_option(
|
||||
strings, description ? description : "", takes_arg != 0,
|
||||
arg_placeholder ? arg_placeholder : "", hidden != 0);
|
||||
|
||||
if (out_option) {
|
||||
auto *handle =
|
||||
new (std::nothrow) OakCommonCommandLineOption();
|
||||
if (!handle) {
|
||||
return OAKCOMMON_E_NOMEM;
|
||||
}
|
||||
handle->option = const_cast<CommandLineParser::Option *>(option);
|
||||
*out_option = handle;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_add_positional_argument(
|
||||
OakCommonCommandLineParser *parser, const char *name,
|
||||
const char *description, int required,
|
||||
OakCommonCommandLinePositionalArgument **out_argument)
|
||||
{
|
||||
if (!parser || !name) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
const CommandLineParser::PositionalArgument *argument =
|
||||
parser->impl.add_positional_argument(
|
||||
name, description ? description : "", required != 0);
|
||||
|
||||
if (out_argument) {
|
||||
auto *handle =
|
||||
new (std::nothrow) OakCommonCommandLinePositionalArgument();
|
||||
if (!handle) {
|
||||
return OAKCOMMON_E_NOMEM;
|
||||
}
|
||||
handle->argument =
|
||||
const_cast<CommandLineParser::PositionalArgument *>(argument);
|
||||
*out_argument = handle;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_process(OakCommonCommandLineParser *parser,
|
||||
const char *const *argv, int argc)
|
||||
{
|
||||
if (!parser || !argv || argc < 0) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
std::vector<std::string> args;
|
||||
args.reserve(static_cast<size_t>(argc));
|
||||
for (int i = 0; i < argc; i++) {
|
||||
args.emplace_back(argv[i] ? argv[i] : "");
|
||||
}
|
||||
|
||||
parser->impl.process(args);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineparser_print_help(OakCommonCommandLineParser *parser,
|
||||
const char *filename)
|
||||
{
|
||||
if (!parser || !filename) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
parser->impl.print_help(filename);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineoption_is_set(OakCommonCommandLineOption *option,
|
||||
bool *is_set)
|
||||
{
|
||||
if (!option || !option->option || !is_set) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
*is_set = option->option->is_set();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shared two-stage string getter.
|
||||
*
|
||||
* Returns the required buffer size in bytes (including the terminating
|
||||
* NUL) as a non-negative value, or a negative error code.
|
||||
*/
|
||||
static int copy_setting(const std::string &value, char *buf, int buf_size)
|
||||
{
|
||||
int required = static_cast<int>(value.size()) + 1;
|
||||
|
||||
if (buf && buf_size > 0) {
|
||||
size_t copy_len = value.size();
|
||||
if (copy_len > static_cast<size_t>(buf_size) - 1) {
|
||||
copy_len = static_cast<size_t>(buf_size) - 1;
|
||||
}
|
||||
memcpy(buf, value.data(), copy_len);
|
||||
buf[copy_len] = '\0';
|
||||
}
|
||||
|
||||
return required;
|
||||
}
|
||||
|
||||
int oakcommon_commandlineoption_get_setting(OakCommonCommandLineOption *option,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!option || !option->option) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return copy_setting(option->option->get_setting(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlineoption_set_setting(OakCommonCommandLineOption *option,
|
||||
const char *value)
|
||||
{
|
||||
if (!option || !option->option || !value) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
option->option->set_setting(value);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlinepositionalargument_get_setting(
|
||||
OakCommonCommandLinePositionalArgument *argument, char *buf, int buf_size)
|
||||
{
|
||||
if (!argument || !argument->argument) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return copy_setting(argument->argument->get_setting(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_commandlinepositionalargument_set_setting(
|
||||
OakCommonCommandLinePositionalArgument *argument, const char *value)
|
||||
{
|
||||
if (!argument || !argument->argument || !value) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
argument->argument->set_setting(value);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_commandlineoption_free(OakCommonCommandLineOption *option)
|
||||
{
|
||||
delete option;
|
||||
}
|
||||
|
||||
void oakcommon_commandlinepositionalargument_free(
|
||||
OakCommonCommandLinePositionalArgument *argument)
|
||||
{
|
||||
delete argument;
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/current.h"
|
||||
|
||||
#include "../src/current.h"
|
||||
|
||||
struct OakCommonCurrent {
|
||||
Current *current;
|
||||
};
|
||||
|
||||
OakCommonCurrent *oakcommon_current_instance(void)
|
||||
{
|
||||
static OakCommonCurrent handle = { &Current::get_instance() };
|
||||
return &handle;
|
||||
}
|
||||
|
||||
void oakcommon_current_free(OakCommonCurrent *self)
|
||||
{
|
||||
// No-op: the handle wraps a process-wide singleton.
|
||||
(void)self;
|
||||
}
|
||||
|
||||
static int current_set(Current *current,
|
||||
void (Current::*set_fn)(std::shared_ptr<void>),
|
||||
void *obj, OakCommonDestroyFn destroy)
|
||||
{
|
||||
try {
|
||||
std::shared_ptr<void> value;
|
||||
if (obj) {
|
||||
if (destroy)
|
||||
value = std::shared_ptr<void>(obj, destroy);
|
||||
else
|
||||
value = std::shared_ptr<void>(
|
||||
obj, [](void *) {});
|
||||
}
|
||||
(current->*set_fn)(value);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
static int current_get(Current *current,
|
||||
std::shared_ptr<void> (Current::*get_fn)() const,
|
||||
void **out)
|
||||
{
|
||||
try {
|
||||
*out = (current->*get_fn)().get();
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_current_set_video_params(OakCommonCurrent *self, void *obj,
|
||||
OakCommonDestroyFn destroy)
|
||||
{
|
||||
if (!self)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_set(self->current, &Current::set_current_video_params,
|
||||
obj, destroy);
|
||||
}
|
||||
|
||||
int oakcommon_current_set_audio_params(OakCommonCurrent *self, void *obj,
|
||||
OakCommonDestroyFn destroy)
|
||||
{
|
||||
if (!self)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_set(self->current, &Current::set_current_audio_params,
|
||||
obj, destroy);
|
||||
}
|
||||
|
||||
int oakcommon_current_set_plugin_host(OakCommonCurrent *self, void *obj,
|
||||
OakCommonDestroyFn destroy)
|
||||
{
|
||||
if (!self)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_set(self->current, &Current::set_plugin_host, obj,
|
||||
destroy);
|
||||
}
|
||||
|
||||
int oakcommon_current_set_plugin_cache(OakCommonCurrent *self, void *obj,
|
||||
OakCommonDestroyFn destroy)
|
||||
{
|
||||
if (!self)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_set(self->current, &Current::set_plugin_cache, obj,
|
||||
destroy);
|
||||
}
|
||||
|
||||
int oakcommon_current_get_video_params(OakCommonCurrent *self, void **out)
|
||||
{
|
||||
if (!self || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_get(self->current, &Current::current_video_params,
|
||||
out);
|
||||
}
|
||||
|
||||
int oakcommon_current_get_audio_params(OakCommonCurrent *self, void **out)
|
||||
{
|
||||
if (!self || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_get(self->current, &Current::current_audio_params,
|
||||
out);
|
||||
}
|
||||
|
||||
int oakcommon_current_get_plugin_host(OakCommonCurrent *self, void **out)
|
||||
{
|
||||
if (!self || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_get(self->current, &Current::plugin_host, out);
|
||||
}
|
||||
|
||||
int oakcommon_current_get_plugin_cache(OakCommonCurrent *self, void **out)
|
||||
{
|
||||
if (!self || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
return current_get(self->current, &Current::plugin_cache, out);
|
||||
}
|
||||
|
||||
int oakcommon_current_is_interactive(OakCommonCurrent *self, int *out)
|
||||
{
|
||||
if (!self || !out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
*out = self->current->interactive() ? 1 : 0;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include "../src/debug.h"
|
||||
|
||||
int oakcommon_debug_log(int level, const char *msg)
|
||||
{
|
||||
if (!msg)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
olive::debug_handler(level, msg);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_debug_level_name(int level, char *buf, int buf_size)
|
||||
{
|
||||
try {
|
||||
return olive::debug_level_name(level, buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/dropworkflowbehavior.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "../src/dropworkflowbehavior.h"
|
||||
|
||||
static const char *behavior_name(int value)
|
||||
{
|
||||
switch (value) {
|
||||
case olive::k_dws_ask:
|
||||
return "ASK";
|
||||
case olive::k_dws_auto:
|
||||
return "AUTO";
|
||||
case olive::k_dws_manual:
|
||||
return "MANUAL";
|
||||
case olive::k_dws_disable:
|
||||
return "DISABLE";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
int oakcommon_drop_workflow_behavior_is_valid(int value)
|
||||
{
|
||||
switch (value) {
|
||||
case olive::k_dws_ask:
|
||||
case olive::k_dws_auto:
|
||||
case olive::k_dws_manual:
|
||||
case olive::k_dws_disable:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int oakcommon_drop_workflow_behavior_name(int value, char *buf, int buf_size)
|
||||
{
|
||||
try {
|
||||
const char *name = behavior_name(value);
|
||||
int needed = (int)strlen(name) + 1;
|
||||
|
||||
if (buf && buf_size >= needed)
|
||||
memcpy(buf, name, needed);
|
||||
return needed;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/ffmpegutils.h"
|
||||
|
||||
#include "../src/ffmpegutils.h"
|
||||
|
||||
int oakcommon_ffmpegutils_get_compatible_bridge_pixel_format(
|
||||
int pix_fmt, int maximum_pix_fmt, int *out)
|
||||
{
|
||||
if (!out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
*out = olive::FFmpegUtils::get_compatible_bridge_pixel_format(
|
||||
pix_fmt,
|
||||
static_cast<olive::core::PixelFormat::Format>(
|
||||
maximum_pix_fmt));
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_ffmpegutils_get_compatible_pixel_format(int pix_fmt, int *out)
|
||||
{
|
||||
if (!out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
*out = olive::FFmpegUtils::get_compatible_pixel_format(
|
||||
static_cast<olive::core::PixelFormat::Format>(pix_fmt));
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_ffmpegutils_get_ffmpeg_pixel_format(int pix_fmt,
|
||||
int channel_count, int *out)
|
||||
{
|
||||
if (!out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
*out = olive::FFmpegUtils::get_ffmpeg_pixel_format(
|
||||
static_cast<olive::core::PixelFormat::Format>(pix_fmt),
|
||||
channel_count);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_ffmpegutils_get_native_sample_format(int smp_fmt, int *out)
|
||||
{
|
||||
if (!out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
*out = olive::FFmpegUtils::get_native_sample_format(smp_fmt);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_ffmpegutils_get_ffmpeg_sample_format(int smp_fmt, int *out)
|
||||
{
|
||||
if (!out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
*out = olive::FFmpegUtils::get_ffmpeg_sample_format(
|
||||
static_cast<olive::core::SampleFormat::Format>(smp_fmt));
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
|
||||
int oakcommon_ffmpegutils_convert_jpeg_space_to_regular_space(int pix_fmt,
|
||||
int *out)
|
||||
{
|
||||
if (!out)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
try {
|
||||
*out = olive::FFmpegUtils::convert_jpeg_space_to_regular_space(
|
||||
pix_fmt);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/filefunctions.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "../src/filefunctions.h"
|
||||
|
||||
struct OakCommonFileFunctions {
|
||||
int unused; /**< Stateless family; handle kept for API uniformity. */
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Copies `value` into the caller's two-stage buffer
|
||||
*
|
||||
* @return Required buffer size in bytes (including the terminating NUL).
|
||||
* Always non-negative; error codes are handled by the callers.
|
||||
*/
|
||||
int write_string_result(const std::string &value, char *buf, int buf_size)
|
||||
{
|
||||
int required = static_cast<int>(value.size()) + 1;
|
||||
if (buf != nullptr && buf_size >= required) {
|
||||
memcpy(buf, value.c_str(), required);
|
||||
}
|
||||
return required;
|
||||
}
|
||||
|
||||
bool is_valid_string_out(const char *buf, int buf_size)
|
||||
{
|
||||
return buf_size >= 0 && (buf_size == 0 || buf != nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OakCommonFileFunctions *oakcommon_filefunctions_init(void)
|
||||
{
|
||||
try {
|
||||
return new OakCommonFileFunctions{0};
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_filefunctions_free(OakCommonFileFunctions *self)
|
||||
{
|
||||
delete self;
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_unique_file_identifier(
|
||||
OakCommonFileFunctions *self, const char *filename, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (self == nullptr || filename == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(
|
||||
FileFunctions::get_unique_file_identifier(filename), buf,
|
||||
buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_configuration_location(
|
||||
OakCommonFileFunctions *self, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(
|
||||
FileFunctions::get_configuration_location(), buf,
|
||||
buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_application_path(
|
||||
OakCommonFileFunctions *self, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(FileFunctions::get_application_path(),
|
||||
buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_temp_file_path(
|
||||
OakCommonFileFunctions *self, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(FileFunctions::get_temp_file_path(),
|
||||
buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_auto_recovery_root(
|
||||
OakCommonFileFunctions *self, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || !is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(
|
||||
FileFunctions::get_auto_recovery_root(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_can_copy_directory_without_overwriting(
|
||||
OakCommonFileFunctions *self, const char *source, const char *dest,
|
||||
int *out)
|
||||
{
|
||||
if (self == nullptr || source == nullptr || dest == nullptr ||
|
||||
out == nullptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
*out = FileFunctions::can_copy_directory_without_overwriting(
|
||||
source, dest)
|
||||
? 1
|
||||
: 0;
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_copy_directory(OakCommonFileFunctions *self,
|
||||
const char *source,
|
||||
const char *dest, int overwrite)
|
||||
{
|
||||
if (self == nullptr || source == nullptr || dest == nullptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
FileFunctions::copy_directory(source, dest, overwrite != 0);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_directory_is_valid(
|
||||
OakCommonFileFunctions *self, const char *dir,
|
||||
int try_to_create_if_not_exists, int *out)
|
||||
{
|
||||
if (self == nullptr || dir == nullptr || out == nullptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
*out = FileFunctions::directory_is_valid(
|
||||
dir, try_to_create_if_not_exists != 0)
|
||||
? 1
|
||||
: 0;
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_ensure_filename_extension(
|
||||
OakCommonFileFunctions *self, const char *filename,
|
||||
const char *extension, char *buf, int buf_size)
|
||||
{
|
||||
if (self == nullptr || filename == nullptr || extension == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(
|
||||
FileFunctions::ensure_filename_extension(filename,
|
||||
extension),
|
||||
buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_read_file_as_string(
|
||||
OakCommonFileFunctions *self, const char *filename, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (self == nullptr || filename == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(
|
||||
FileFunctions::read_file_as_string(filename), buf,
|
||||
buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_safe_temporary_filename(
|
||||
OakCommonFileFunctions *self, const char *original, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (self == nullptr || original == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(
|
||||
FileFunctions::get_safe_temporary_filename(original),
|
||||
buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_rename_file_allow_overwrite(
|
||||
OakCommonFileFunctions *self, const char *from, const char *to,
|
||||
int *out)
|
||||
{
|
||||
if (self == nullptr || from == nullptr || to == nullptr ||
|
||||
out == nullptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
*out = FileFunctions::rename_file_allow_overwrite(from, to) ? 1
|
||||
: 0;
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_filefunctions_get_formatted_executable_for_platform(
|
||||
OakCommonFileFunctions *self, const char *unformatted, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (self == nullptr || unformatted == nullptr ||
|
||||
!is_valid_string_out(buf, buf_size)) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
return write_string_result(
|
||||
FileFunctions::get_formatted_executable_for_platform(
|
||||
unformatted),
|
||||
buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/miscutils.h"
|
||||
|
||||
#include "../src/decibel.h"
|
||||
#include "../src/lerp.h"
|
||||
|
||||
int oakcommon_decibel_from_linear(double linear, double *out_db)
|
||||
{
|
||||
if (!out_db) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
try {
|
||||
*out_db = olive::Decibel::from_linear(linear);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_decibel_to_linear(double db, double *out_linear)
|
||||
{
|
||||
if (!out_linear) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
try {
|
||||
*out_linear = olive::Decibel::to_linear(db);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_decibel_from_logarithmic(double logarithmic, double *out_db)
|
||||
{
|
||||
if (!out_db) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
try {
|
||||
*out_db = olive::Decibel::from_logarithmic(logarithmic);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_decibel_to_logarithmic(double db, double *out_logarithmic)
|
||||
{
|
||||
if (!out_logarithmic) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
try {
|
||||
*out_logarithmic = olive::Decibel::to_logarithmic(db);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_decibel_linear_to_logarithmic(double linear,
|
||||
double *out_logarithmic)
|
||||
{
|
||||
if (!out_logarithmic) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
try {
|
||||
*out_logarithmic = olive::Decibel::linear_to_logarithmic(linear);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_decibel_logarithmic_to_linear(double logarithmic,
|
||||
double *out_linear)
|
||||
{
|
||||
if (!out_linear) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
try {
|
||||
*out_linear = olive::Decibel::logarithmic_to_linear(logarithmic);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_lerp(double a, double b, double t, double *out_value)
|
||||
{
|
||||
if (!out_value) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
try {
|
||||
*out_value = lerp(a, b, t);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/ocioutils.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "../src/ocioutils.h"
|
||||
|
||||
struct OakCommonOCIOUtils {
|
||||
int unused; /**< Stateless; only the address matters. */
|
||||
};
|
||||
|
||||
OakCommonOCIOUtils *oakcommon_ocioutils_init(void)
|
||||
{
|
||||
try {
|
||||
return new (std::nothrow) OakCommonOCIOUtils{};
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_ocioutils_free(OakCommonOCIOUtils *self)
|
||||
{
|
||||
delete self;
|
||||
}
|
||||
|
||||
int oakcommon_ocioutils_get_ocio_bit_depth_from_pixel_format(
|
||||
OakCommonOCIOUtils *self, int pixel_format, int *out_bit_depth)
|
||||
{
|
||||
try {
|
||||
if (self == NULL || out_bit_depth == NULL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
if (pixel_format < OAKCOMMON_PIXEL_FORMAT_INVALID ||
|
||||
pixel_format >= OAKCOMMON_PIXEL_FORMAT_COUNT)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
ocio::BitDepth depth = OCIOUtils::get_ocio_bit_depth_from_pixel_format(
|
||||
static_cast<olive::core::PixelFormat::Format>(pixel_format));
|
||||
*out_bit_depth = static_cast<int>(depth);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/oiioutils.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "../src/oiioutils.h"
|
||||
|
||||
struct OakCommonOIIOUtils {
|
||||
int unused; /**< Stateless; only the address matters. */
|
||||
};
|
||||
|
||||
OakCommonOIIOUtils *oakcommon_oiioutils_init(void)
|
||||
{
|
||||
try {
|
||||
return new (std::nothrow) OakCommonOIIOUtils{};
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_oiioutils_free(OakCommonOIIOUtils *self)
|
||||
{
|
||||
delete self;
|
||||
}
|
||||
|
||||
int oakcommon_oiioutils_get_oiio_base_type_from_format(
|
||||
OakCommonOIIOUtils *self, int pixel_format, int *out_base_type)
|
||||
{
|
||||
try {
|
||||
if (self == NULL || out_base_type == NULL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
if (pixel_format < OAKCOMMON_PIXEL_FORMAT_INVALID ||
|
||||
pixel_format >= OAKCOMMON_PIXEL_FORMAT_COUNT)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
OIIO::TypeDesc::BASETYPE base_type =
|
||||
OIIOUtils::get_oiio_base_type_from_format(
|
||||
static_cast<olive::core::PixelFormat::Format>(pixel_format));
|
||||
*out_base_type = static_cast<int>(base_type);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_oiioutils_get_format_from_oiio_basetype(
|
||||
OakCommonOIIOUtils *self, int base_type, int *out_pixel_format)
|
||||
{
|
||||
try {
|
||||
if (self == NULL || out_pixel_format == NULL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
if (base_type < 0 || base_type >= OIIO::TypeDesc::LASTBASE)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
olive::core::PixelFormat format =
|
||||
OIIOUtils::get_format_from_oiio_basetype(
|
||||
static_cast<OIIO::TypeDesc::BASETYPE>(base_type));
|
||||
*out_pixel_format = static_cast<int>(format);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_oiioutils_get_pixel_aspect_ratio(
|
||||
OakCommonOIIOUtils *self, double pixel_aspect_ratio, int *out_numerator,
|
||||
int *out_denominator)
|
||||
{
|
||||
try {
|
||||
if (self == NULL || out_numerator == NULL || out_denominator == NULL)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
|
||||
olive::core::Rational par =
|
||||
olive::core::Rational::from_double(pixel_aspect_ratio);
|
||||
*out_numerator = par.numerator();
|
||||
*out_denominator = par.denominator();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "../../include/common/power.h"
|
||||
|
||||
#include "../src/power.h"
|
||||
|
||||
int oakcommon_power_ceil_to_power_of_2(uint32_t value, uint32_t *out)
|
||||
{
|
||||
try {
|
||||
if (!out) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
*out = olive::ceil_to_power_of_2(value);
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_power_floor_to_power_of_2(uint32_t value, uint32_t *out)
|
||||
{
|
||||
try {
|
||||
if (!out) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
*out = olive::floor_to_power_of_2(value);
|
||||
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/qtutils.h"
|
||||
|
||||
#include "../src/qtutils.h"
|
||||
|
||||
int oakcommon_qtutils_ptr_to_value(void *ptr, uint64_t *out_value)
|
||||
{
|
||||
if (!out_value) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
*out_value = static_cast<uint64_t>(olive::QtUtils::ptr_to_value(ptr));
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_qtutils_value_to_ptr(uint64_t value, void **out_ptr)
|
||||
{
|
||||
if (!out_ptr) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
*out_ptr =
|
||||
olive::QtUtils::value_to_ptr<void>(static_cast<uintptr_t>(value));
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_qtutils_get_creation_date(const char *path, int64_t *out_secs)
|
||||
{
|
||||
if (!path || !out_secs) {
|
||||
return OAKCOMMON_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
std::chrono::system_clock::time_point t =
|
||||
olive::QtUtils::get_creation_date(std::filesystem::path(path));
|
||||
|
||||
if (t == std::chrono::system_clock::time_point{}) {
|
||||
return OAKCOMMON_E_NOT_FOUND;
|
||||
}
|
||||
|
||||
*out_secs = static_cast<int64_t>(
|
||||
std::chrono::system_clock::to_time_t(t));
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
/***
|
||||
|
||||
Oak Video Editor - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "common/xmlutils.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
|
||||
#include "../src/xmlutils.h"
|
||||
|
||||
struct OakCommonXmlReader {
|
||||
olive::XmlStreamReader reader;
|
||||
std::string cached_text;
|
||||
bool has_cached_text = false;
|
||||
|
||||
explicit OakCommonXmlReader(const char *data)
|
||||
: reader(data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct OakCommonXmlWriter {
|
||||
olive::XmlStreamWriter writer;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Copy @p value into the two-stage string buffer.
|
||||
*
|
||||
* @return Required buffer size in bytes (including NUL). The buffer is only
|
||||
* written to when it is large enough.
|
||||
*/
|
||||
int copy_string(const std::string &value, char *buf, int buf_size)
|
||||
{
|
||||
int needed = static_cast<int>(value.size()) + 1;
|
||||
if (buf && buf_size >= needed) {
|
||||
memcpy(buf, value.c_str(), needed);
|
||||
}
|
||||
return needed;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
OakCommonXmlReader *oakcommon_xml_reader_init(const char *data)
|
||||
{
|
||||
if (!data)
|
||||
return nullptr;
|
||||
try {
|
||||
return new (std::nothrow) OakCommonXmlReader(data);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_xml_reader_free(OakCommonXmlReader *reader)
|
||||
{
|
||||
delete reader;
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_read_next_start_element(OakCommonXmlReader *reader,
|
||||
int *found)
|
||||
{
|
||||
if (!reader || !found)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
reader->has_cached_text = false;
|
||||
*found = olive::xml_read_next_start_element(&reader->reader) ? 1 : 0;
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_name(OakCommonXmlReader *reader, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (!reader)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
return copy_string(reader->reader.name(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_read_element_text(OakCommonXmlReader *reader,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!reader)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
// read_element_text() consumes the stream, so cache the result to
|
||||
// keep the two-stage (size query then copy) buffer convention working.
|
||||
if (!reader->has_cached_text) {
|
||||
reader->cached_text = reader->reader.read_element_text();
|
||||
reader->has_cached_text = true;
|
||||
}
|
||||
return copy_string(reader->cached_text, buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_skip_current_element(OakCommonXmlReader *reader)
|
||||
{
|
||||
if (!reader)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
reader->has_cached_text = false;
|
||||
reader->reader.skip_current_element();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_attribute_count(OakCommonXmlReader *reader,
|
||||
int *count)
|
||||
{
|
||||
if (!reader || !count)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
*count = static_cast<int>(reader->reader.attributes().size());
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_attribute_name(OakCommonXmlReader *reader, int index,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
if (!reader)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
const auto &attrs = reader->reader.attributes();
|
||||
if (index < 0 || index >= static_cast<int>(attrs.size()))
|
||||
return OAKCOMMON_E_NOT_FOUND;
|
||||
return copy_string(attrs[index].name, buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_attribute_value(OakCommonXmlReader *reader,
|
||||
int index, char *buf, int buf_size)
|
||||
{
|
||||
if (!reader)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
const auto &attrs = reader->reader.attributes();
|
||||
if (index < 0 || index >= static_cast<int>(attrs.size()))
|
||||
return OAKCOMMON_E_NOT_FOUND;
|
||||
return copy_string(attrs[index].value, buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_reader_has_error(OakCommonXmlReader *reader,
|
||||
int *has_error)
|
||||
{
|
||||
if (!reader || !has_error)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
*has_error = reader->reader.has_error() ? 1 : 0;
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
OakCommonXmlWriter *oakcommon_xml_writer_init(void)
|
||||
{
|
||||
try {
|
||||
return new (std::nothrow) OakCommonXmlWriter();
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void oakcommon_xml_writer_free(OakCommonXmlWriter *writer)
|
||||
{
|
||||
delete writer;
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_start_element(OakCommonXmlWriter *writer,
|
||||
const char *name)
|
||||
{
|
||||
if (!writer || !name)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_start_element(name);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_attribute(OakCommonXmlWriter *writer,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
if (!writer || !name || !value)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_attribute(name, value);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_characters(OakCommonXmlWriter *writer,
|
||||
const char *text)
|
||||
{
|
||||
if (!writer || !text)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_characters(text);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_text_element(OakCommonXmlWriter *writer,
|
||||
const char *name,
|
||||
const char *text)
|
||||
{
|
||||
if (!writer || !name || !text)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_text_element(name, text);
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_end_element(OakCommonXmlWriter *writer)
|
||||
{
|
||||
if (!writer)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_end_element();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_write_end_document(OakCommonXmlWriter *writer)
|
||||
{
|
||||
if (!writer)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
writer->writer.write_end_document();
|
||||
return OAKCOMMON_OK;
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int oakcommon_xml_writer_output(OakCommonXmlWriter *writer, char *buf,
|
||||
int buf_size)
|
||||
{
|
||||
if (!writer)
|
||||
return OAKCOMMON_E_INVALID;
|
||||
try {
|
||||
return copy_string(writer->writer.output(), buf, buf_size);
|
||||
} catch (...) {
|
||||
return OAKCOMMON_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
Reference in New Issue
Block a user