Add xmusic tracker/audio player, xfiles media actions, ringtone volume & vibration fix
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <jpeglib.h>
|
||||
#include <png.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace bananarchy {
|
||||
|
||||
@@ -159,6 +161,73 @@ inline bool loadPngRgb24(const std::string& path,
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool loadFfmpegImageRgb24(const std::string& path,
|
||||
std::vector<uint8_t>* outRgb,
|
||||
int* outW,
|
||||
int* outH) {
|
||||
int pipefd[2];
|
||||
if (::pipe(pipefd) != 0) {
|
||||
return false;
|
||||
}
|
||||
pid_t pid = ::fork();
|
||||
if (pid < 0) {
|
||||
::close(pipefd[0]);
|
||||
::close(pipefd[1]);
|
||||
return false;
|
||||
}
|
||||
if (pid == 0) {
|
||||
::close(pipefd[0]);
|
||||
::dup2(pipefd[1], STDOUT_FILENO);
|
||||
if (pipefd[1] != STDOUT_FILENO) ::close(pipefd[1]);
|
||||
int devnull = ::open("/dev/null", O_RDWR);
|
||||
if (devnull >= 0) {
|
||||
::dup2(devnull, STDIN_FILENO);
|
||||
::dup2(devnull, STDERR_FILENO);
|
||||
if (devnull > 2) ::close(devnull);
|
||||
}
|
||||
::execlp("ffmpeg", "ffmpeg", "-v", "error", "-i", path.c_str(),
|
||||
"-frames:v", "1", "-f", "image2pipe", "-vcodec", "png", "-",
|
||||
static_cast<char*>(nullptr));
|
||||
::_exit(127);
|
||||
}
|
||||
::close(pipefd[1]);
|
||||
std::vector<uint8_t> pngBuf;
|
||||
uint8_t chunk[4096];
|
||||
ssize_t n = 0;
|
||||
while ((n = ::read(pipefd[0], chunk, sizeof(chunk))) > 0) {
|
||||
if (pngBuf.size() + static_cast<size_t>(n) > 16 * 1024 * 1024) break;
|
||||
pngBuf.insert(pngBuf.end(), chunk, chunk + n);
|
||||
}
|
||||
::close(pipefd[0]);
|
||||
int status = 0;
|
||||
::waitpid(pid, &status, 0);
|
||||
if (pngBuf.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
png_image image {};
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
if (!png_image_begin_read_from_memory(&image, pngBuf.data(), pngBuf.size())) {
|
||||
return false;
|
||||
}
|
||||
image.format = PNG_FORMAT_RGB;
|
||||
int w = static_cast<int>(image.width);
|
||||
int h = static_cast<int>(image.height);
|
||||
if (w <= 0 || h <= 0 || w > 8192 || h > 8192) {
|
||||
png_image_free(&image);
|
||||
return false;
|
||||
}
|
||||
outRgb->resize(PNG_IMAGE_SIZE(image));
|
||||
if (!png_image_finish_read(&image, nullptr, outRgb->data(), 0, nullptr)) {
|
||||
png_image_free(&image);
|
||||
return false;
|
||||
}
|
||||
png_image_free(&image);
|
||||
*outW = w;
|
||||
*outH = h;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool loadImageRgb24(const std::string& path,
|
||||
std::vector<uint8_t>* outRgb,
|
||||
int* outW,
|
||||
@@ -178,6 +247,9 @@ inline bool loadImageRgb24(const std::string& path,
|
||||
if (loadPngRgb24(path, outRgb, outW, outH)) {
|
||||
return true;
|
||||
}
|
||||
if (loadFfmpegImageRgb24(path, outRgb, outW, outH)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user