1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
5
6 #define _DEFAULT_SOURCE // for mkstemps().
7
8 #include "tools/benchmark/benchmark_utils.h"
9
10 // Not supported on Windows due to Linux-specific functions.
11 // Not supported in Android NDK before API 28.
12 #if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && \
13 (!defined(__ANDROID_API__) || __ANDROID_API__ >= 28)
14
15 #include <libgen.h>
16 #include <spawn.h>
17 #include <stdio.h>
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <unistd.h>
21
22 #include <fstream>
23
24 #include "lib/extras/codec_png.h"
25 #include "lib/jxl/base/file_io.h"
26 #include "lib/jxl/codec_in_out.h"
27 #include "lib/jxl/image_bundle.h"
28
29 extern char** environ;
30
31 namespace jxl {
TemporaryFile(std::string basename,std::string extension)32 TemporaryFile::TemporaryFile(std::string basename, std::string extension) {
33 const auto extension_size = 1 + extension.size();
34 temp_filename_ = std::move(basename) + "_XXXXXX." + std::move(extension);
35 const int fd = mkstemps(&temp_filename_[0], extension_size);
36 if (fd == -1) {
37 ok_ = false;
38 return;
39 }
40 close(fd);
41 }
~TemporaryFile()42 TemporaryFile::~TemporaryFile() {
43 if (ok_) {
44 unlink(temp_filename_.c_str());
45 }
46 }
47
GetFileName(std::string * const output) const48 Status TemporaryFile::GetFileName(std::string* const output) const {
49 JXL_RETURN_IF_ERROR(ok_);
50 *output = temp_filename_;
51 return true;
52 }
53
RunCommand(const std::string & command,const std::vector<std::string> & arguments)54 Status RunCommand(const std::string& command,
55 const std::vector<std::string>& arguments) {
56 std::vector<char*> args;
57 args.reserve(arguments.size() + 2);
58 args.push_back(const_cast<char*>(command.c_str()));
59 for (const std::string& argument : arguments) {
60 args.push_back(const_cast<char*>(argument.c_str()));
61 }
62 args.push_back(nullptr);
63 pid_t pid;
64 JXL_RETURN_IF_ERROR(posix_spawnp(&pid, command.c_str(), nullptr, nullptr,
65 args.data(), environ) == 0);
66 int wstatus;
67 waitpid(pid, &wstatus, 0);
68 return WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == EXIT_SUCCESS;
69 }
70
71 } // namespace jxl
72
73 #else
74
75 namespace jxl {
76
TemporaryFile(std::string basename,std::string extension)77 TemporaryFile::TemporaryFile(std::string basename, std::string extension) {}
~TemporaryFile()78 TemporaryFile::~TemporaryFile() {}
GetFileName(std::string * const output) const79 Status TemporaryFile::GetFileName(std::string* const output) const {
80 (void)ok_;
81 return JXL_FAILURE("Not supported on this build");
82 }
83
RunCommand(const std::string & command,const std::vector<std::string> & arguments)84 Status RunCommand(const std::string& command,
85 const std::vector<std::string>& arguments) {
86 return JXL_FAILURE("Not supported on this build");
87 }
88
89 } // namespace jxl
90
91 #endif // _MSC_VER
92