mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Added Windows support for the PDF viewer
This commit is contained in:
parent
2fa71dfd0b
commit
6bf8c5af46
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -78,6 +78,8 @@ TODO.md
|
||||||
# MSVC
|
# MSVC
|
||||||
EmulationStation.ilk
|
EmulationStation.ilk
|
||||||
EmulationStation.pdb
|
EmulationStation.pdb
|
||||||
|
es-pdf-convert.ilk
|
||||||
|
es-pdf-convert.pdb
|
||||||
lunasvg.exp
|
lunasvg.exp
|
||||||
lunasvg.ilk
|
lunasvg.ilk
|
||||||
lunasvg.pdb
|
lunasvg.pdb
|
||||||
|
|
|
@ -13,6 +13,12 @@
|
||||||
#include "utils/FileSystemUtil.h"
|
#include "utils/FileSystemUtil.h"
|
||||||
#include "utils/StringUtil.h"
|
#include "utils/StringUtil.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEBUG_PDF_CONVERSION false
|
#define DEBUG_PDF_CONVERSION false
|
||||||
|
|
||||||
PDFViewer::PDFViewer()
|
PDFViewer::PDFViewer()
|
||||||
|
@ -24,9 +30,18 @@ PDFViewer::PDFViewer()
|
||||||
|
|
||||||
bool PDFViewer::startPDFViewer(FileData* game)
|
bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
{
|
{
|
||||||
mESConvertPath = Utils::FileSystem::getExePath() + "/es-pdf-convert";
|
#if defined(_WIN64)
|
||||||
|
const std::string convertBinary {"/es-pdf-converter/es-pdf-convert.exe"};
|
||||||
|
#else
|
||||||
|
const std::string convertBinary {"/es-pdf-convert"};
|
||||||
|
#endif
|
||||||
|
mESConvertPath = Utils::FileSystem::getExePath() + convertBinary;
|
||||||
if (!Utils::FileSystem::exists(mESConvertPath)) {
|
if (!Utils::FileSystem::exists(mESConvertPath)) {
|
||||||
|
#if defined(_WIN64)
|
||||||
|
LOG(LogError) << "Couldn't find PDF conversion binary es-pdf-convert.exe";
|
||||||
|
#else
|
||||||
LOG(LogError) << "Couldn't find PDF conversion binary es-pdf-convert";
|
LOG(LogError) << "Couldn't find PDF conversion binary es-pdf-convert";
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +52,10 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
mManualPath = Utils::String::replace(mManualPath, "/", "\\");
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG(LogDebug) << "PDFViewer::startPDFViewer(): Opening document \"" << mManualPath << "\"";
|
LOG(LogDebug) << "PDFViewer::startPDFViewer(): Opening document \"" << mManualPath << "\"";
|
||||||
|
|
||||||
mPages.clear();
|
mPages.clear();
|
||||||
|
@ -50,7 +69,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPageCount = mPages.size();
|
mPageCount = static_cast<int>(mPages.size());
|
||||||
|
|
||||||
for (int i {1}; i <= mPageCount; ++i) {
|
for (int i {1}; i <= mPageCount; ++i) {
|
||||||
if (mPages.find(i) == mPages.end()) {
|
if (mPages.find(i) == mPages.end()) {
|
||||||
|
@ -106,9 +125,80 @@ void PDFViewer::stopPDFViewer()
|
||||||
|
|
||||||
bool PDFViewer::getDocumentInfo()
|
bool PDFViewer::getDocumentInfo()
|
||||||
{
|
{
|
||||||
|
std::string commandOutput;
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
std::wstring command {
|
||||||
|
Utils::String::stringToWideString(Utils::FileSystem::getEscapedPath(mESConvertPath))};
|
||||||
|
command.append(L" -fileinfo ")
|
||||||
|
.append(Utils::String::stringToWideString(Utils::FileSystem::getEscapedPath(mManualPath)));
|
||||||
|
|
||||||
|
STARTUPINFOW si {};
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
HANDLE childStdoutRead {nullptr};
|
||||||
|
HANDLE childStdoutWrite {nullptr};
|
||||||
|
SECURITY_ATTRIBUTES saAttr {};
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = true;
|
||||||
|
saAttr.lpSecurityDescriptor = nullptr;
|
||||||
|
|
||||||
|
CreatePipe(&childStdoutRead, &childStdoutWrite, &saAttr, 0);
|
||||||
|
SetHandleInformation(childStdoutRead, HANDLE_FLAG_INHERIT, 0);
|
||||||
|
|
||||||
|
si.cb = sizeof(STARTUPINFOW);
|
||||||
|
si.hStdOutput = childStdoutWrite;
|
||||||
|
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
|
||||||
|
bool processReturnValue {true};
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
processReturnValue = CreateProcessW(
|
||||||
|
nullptr, // No application name (use command line).
|
||||||
|
const_cast<wchar_t*>(command.c_str()), // Command line.
|
||||||
|
nullptr, // Process attributes.
|
||||||
|
nullptr, // Thread attributes.
|
||||||
|
TRUE, // Handles inheritance.
|
||||||
|
0, // Creation flags.
|
||||||
|
nullptr, // Use parent's environment block.
|
||||||
|
nullptr, // Starting directory, possibly the same as parent.
|
||||||
|
&si, // Pointer to the STARTUPINFOW structure.
|
||||||
|
&pi); // Pointer to the PROCESS_INFORMATION structure.
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
if (!processReturnValue) {
|
||||||
|
LOG(LogError) << "Couldn't read PDF document information";
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close process and thread handles.
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
CloseHandle(childStdoutWrite);
|
||||||
|
|
||||||
|
std::array<char, 512> buffer {};
|
||||||
|
DWORD dwRead;
|
||||||
|
bool readValue {true};
|
||||||
|
|
||||||
|
while (readValue) {
|
||||||
|
readValue = ReadFile(childStdoutRead, &buffer[0], 512, &dwRead, nullptr);
|
||||||
|
if (readValue) {
|
||||||
|
for (int i {0}; i < 512; ++i) {
|
||||||
|
if (buffer[i] == '\0')
|
||||||
|
break;
|
||||||
|
commandOutput.append(1, buffer[i]);
|
||||||
|
}
|
||||||
|
buffer.fill('\0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(childStdoutRead);
|
||||||
|
WaitForSingleObject(pi.hThread, INFINITE);
|
||||||
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
|
#else
|
||||||
FILE* commandPipe;
|
FILE* commandPipe;
|
||||||
std::array<char, 512> buffer {};
|
std::array<char, 512> buffer {};
|
||||||
std::string commandOutput;
|
|
||||||
|
|
||||||
std::string command {Utils::FileSystem::getEscapedPath(mESConvertPath)};
|
std::string command {Utils::FileSystem::getEscapedPath(mESConvertPath)};
|
||||||
command.append(" -fileinfo ").append(Utils::FileSystem::getEscapedPath(mManualPath));
|
command.append(" -fileinfo ").append(Utils::FileSystem::getEscapedPath(mManualPath));
|
||||||
|
@ -129,6 +219,7 @@ bool PDFViewer::getDocumentInfo()
|
||||||
|
|
||||||
if (pclose(commandPipe) != 0)
|
if (pclose(commandPipe) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
const std::vector<std::string> pageRows {
|
const std::vector<std::string> pageRows {
|
||||||
Utils::String::delimitedStringToVector(commandOutput, "\n")};
|
Utils::String::delimitedStringToVector(commandOutput, "\n")};
|
||||||
|
@ -150,6 +241,18 @@ void PDFViewer::convertPage(int pageNum)
|
||||||
{
|
{
|
||||||
assert(pageNum <= static_cast<int>(mPages.size()));
|
assert(pageNum <= static_cast<int>(mPages.size()));
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
std::wstring command {
|
||||||
|
Utils::String::stringToWideString(Utils::FileSystem::getEscapedPath(mESConvertPath))};
|
||||||
|
command.append(L" -convert ")
|
||||||
|
.append(Utils::String::stringToWideString(Utils::FileSystem::getEscapedPath(mManualPath)))
|
||||||
|
.append(L" ")
|
||||||
|
.append(std::to_wstring(pageNum))
|
||||||
|
.append(L" ")
|
||||||
|
.append(std::to_wstring(static_cast<int>(mPages[pageNum].width)))
|
||||||
|
.append(L" ")
|
||||||
|
.append(std::to_wstring(static_cast<int>(mPages[pageNum].height)));
|
||||||
|
#else
|
||||||
std::string command {Utils::FileSystem::getEscapedPath(mESConvertPath)};
|
std::string command {Utils::FileSystem::getEscapedPath(mESConvertPath)};
|
||||||
command.append(" -convert ")
|
command.append(" -convert ")
|
||||||
.append(Utils::FileSystem::getEscapedPath(mManualPath))
|
.append(Utils::FileSystem::getEscapedPath(mManualPath))
|
||||||
|
@ -159,15 +262,81 @@ void PDFViewer::convertPage(int pageNum)
|
||||||
.append(std::to_string(static_cast<int>(mPages[pageNum].width)))
|
.append(std::to_string(static_cast<int>(mPages[pageNum].width)))
|
||||||
.append(" ")
|
.append(" ")
|
||||||
.append(std::to_string(static_cast<int>(mPages[pageNum].height)));
|
.append(std::to_string(static_cast<int>(mPages[pageNum].height)));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mPages[pageNum].imageData.empty()) {
|
if (mPages[pageNum].imageData.empty()) {
|
||||||
#if (DEBUG_PDF_CONVERSION)
|
#if (DEBUG_PDF_CONVERSION)
|
||||||
LOG(LogDebug) << "Converting page: " << mCurrentPage;
|
LOG(LogDebug) << "Converting page: " << mCurrentPage;
|
||||||
|
#if defined(_WIN64)
|
||||||
|
LOG(LogDebug) << Utils::String::wideStringToString(command);
|
||||||
|
#else
|
||||||
LOG(LogDebug) << command;
|
LOG(LogDebug) << command;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
std::string imageData;
|
||||||
|
#if defined(_WIN64)
|
||||||
|
STARTUPINFOW si {};
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
HANDLE childStdoutRead {nullptr};
|
||||||
|
HANDLE childStdoutWrite {nullptr};
|
||||||
|
SECURITY_ATTRIBUTES saAttr {};
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = true;
|
||||||
|
saAttr.lpSecurityDescriptor = nullptr;
|
||||||
|
|
||||||
|
CreatePipe(&childStdoutRead, &childStdoutWrite, &saAttr, 0);
|
||||||
|
SetHandleInformation(childStdoutRead, HANDLE_FLAG_INHERIT, 0);
|
||||||
|
|
||||||
|
si.cb = sizeof(STARTUPINFOW);
|
||||||
|
si.hStdOutput = childStdoutWrite;
|
||||||
|
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
|
||||||
|
bool processReturnValue {true};
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
processReturnValue = CreateProcessW(
|
||||||
|
nullptr, // No application name (use command line).
|
||||||
|
const_cast<wchar_t*>(command.c_str()), // Command line.
|
||||||
|
nullptr, // Process attributes.
|
||||||
|
nullptr, // Thread attributes.
|
||||||
|
TRUE, // Handles inheritance.
|
||||||
|
0, // Creation flags.
|
||||||
|
nullptr, // Use parent's environment block.
|
||||||
|
nullptr, // Starting directory, possibly the same as parent.
|
||||||
|
&si, // Pointer to the STARTUPINFOW structure.
|
||||||
|
&pi); // Pointer to the PROCESS_INFORMATION structure.
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
if (!processReturnValue) {
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close process and thread handles.
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
CloseHandle(childStdoutWrite);
|
||||||
|
|
||||||
|
std::array<char, 512> buffer {};
|
||||||
|
DWORD dwRead;
|
||||||
|
bool readValue {true};
|
||||||
|
|
||||||
|
while (readValue) {
|
||||||
|
readValue = ReadFile(childStdoutRead, &buffer[0], 512, &dwRead, nullptr);
|
||||||
|
if (readValue) {
|
||||||
|
mPages[pageNum].imageData.insert(mPages[pageNum].imageData.end(),
|
||||||
|
std::make_move_iterator(buffer.begin()),
|
||||||
|
std::make_move_iterator(buffer.end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(childStdoutRead);
|
||||||
|
WaitForSingleObject(pi.hThread, INFINITE);
|
||||||
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
|
#else
|
||||||
FILE* commandPipe;
|
FILE* commandPipe;
|
||||||
std::array<char, 512> buffer {};
|
std::array<char, 512> buffer {};
|
||||||
std::string imageData;
|
|
||||||
int returnValue;
|
int returnValue;
|
||||||
|
|
||||||
if (!(commandPipe = reinterpret_cast<FILE*>(popen(command.c_str(), "r")))) {
|
if (!(commandPipe = reinterpret_cast<FILE*>(popen(command.c_str(), "r")))) {
|
||||||
|
@ -182,10 +351,15 @@ void PDFViewer::convertPage(int pageNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
returnValue = pclose(commandPipe);
|
returnValue = pclose(commandPipe);
|
||||||
size_t imageDataSize {mPages[pageNum].imageData.size()};
|
#endif
|
||||||
|
const size_t imageDataSize {mPages[pageNum].imageData.size()};
|
||||||
|
#if defined(_WIN64)
|
||||||
|
if (!processReturnValue || (static_cast<int>(imageDataSize) <
|
||||||
|
mPages[pageNum].width * mPages[pageNum].height * 4)) {
|
||||||
|
#else
|
||||||
if (returnValue != 0 || (static_cast<int>(imageDataSize) <
|
if (returnValue != 0 || (static_cast<int>(imageDataSize) <
|
||||||
mPages[pageNum].width * mPages[pageNum].height * 4)) {
|
mPages[pageNum].width * mPages[pageNum].height * 4)) {
|
||||||
|
#endif
|
||||||
LOG(LogError) << "Error reading PDF file";
|
LOG(LogError) << "Error reading PDF file";
|
||||||
mPages[pageNum].imageData.clear();
|
mPages[pageNum].imageData.clear();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -162,8 +162,8 @@ namespace Utils
|
||||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
si.wShowWindow = SW_HIDE;
|
si.wShowWindow = SW_HIDE;
|
||||||
}
|
}
|
||||||
bool processReturnValue = true;
|
bool processReturnValue {true};
|
||||||
DWORD errorCode = 0;
|
DWORD errorCode {0};
|
||||||
|
|
||||||
std::wstring startDirectoryTemp {startDirectory};
|
std::wstring startDirectoryTemp {startDirectory};
|
||||||
wchar_t* startDir {startDirectory == L"" ? nullptr : &startDirectoryTemp[0]};
|
wchar_t* startDir {startDirectory == L"" ? nullptr : &startDirectoryTemp[0]};
|
||||||
|
@ -206,7 +206,7 @@ namespace Utils
|
||||||
|
|
||||||
// If the return value is false, then something failed.
|
// If the return value is false, then something failed.
|
||||||
if (!processReturnValue) {
|
if (!processReturnValue) {
|
||||||
LPWSTR pBuffer = nullptr;
|
LPWSTR pBuffer {nullptr};
|
||||||
|
|
||||||
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, nullptr,
|
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, nullptr,
|
||||||
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
@ -214,7 +214,7 @@ namespace Utils
|
||||||
|
|
||||||
errorCode = GetLastError();
|
errorCode = GetLastError();
|
||||||
|
|
||||||
std::string errorMessage = Utils::String::wideStringToString(pBuffer);
|
std::string errorMessage {Utils::String::wideStringToString(pBuffer)};
|
||||||
// Remove trailing newline from the error message.
|
// Remove trailing newline from the error message.
|
||||||
if (errorMessage.size()) {
|
if (errorMessage.size()) {
|
||||||
if (errorMessage.back() == '\n')
|
if (errorMessage.back() == '\n')
|
||||||
|
|
|
@ -8,9 +8,19 @@
|
||||||
|
|
||||||
project(es-pdf-convert)
|
project(es-pdf-convert)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(POPPLER_CPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../external/poppler-23.05.0/Library/include/poppler/cpp)
|
||||||
|
set(POPPLER_CPP_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/poppler-cpp.lib)
|
||||||
|
else()
|
||||||
find_package(Poppler REQUIRED COMPONENTS cpp)
|
find_package(Poppler REQUIRED COMPONENTS cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(${POPPLER_CPP_INCLUDE_DIR})
|
include_directories(${POPPLER_CPP_INCLUDE_DIR})
|
||||||
add_executable(es-pdf-convert ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
|
add_executable(es-pdf-convert ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
|
||||||
target_link_libraries(es-pdf-convert ${POPPLER_CPP_LIBRARY})
|
target_link_libraries(es-pdf-convert ${POPPLER_CPP_LIBRARY})
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set_target_properties(es-pdf-convert PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/es-pdf-converter" INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
else()
|
||||||
set_target_properties(es-pdf-convert PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
set_target_properties(es-pdf-convert PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
endif()
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// EmulationStation Desktop Edition (ES-DE) PDF converter
|
// EmulationStation Desktop Edition (ES-DE) PDF converter
|
||||||
// main.cpp
|
// main.cpp
|
||||||
//
|
//
|
||||||
// Converts PDF document pages to raw ARGB32 image data for maximum performance.
|
// Converts PDF document pages to raw ARGB32 pixel data for maximum performance.
|
||||||
// This needs to be separated into its own binary to get around the restrictive GPL
|
// This needs to be separated into its own binary to get around the restrictive GPL
|
||||||
// license used by the Poppler PDF rendering library.
|
// license used by the Poppler PDF rendering library.
|
||||||
//
|
//
|
||||||
|
@ -17,8 +17,55 @@
|
||||||
#include "poppler-page.h"
|
#include "poppler-page.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
int wmain(int argc, wchar_t* argv[])
|
||||||
|
{
|
||||||
|
HANDLE stdoutHandle {GetStdHandle(STD_OUTPUT_HANDLE)};
|
||||||
|
|
||||||
|
if (stdoutHandle == INVALID_HANDLE_VALUE) {
|
||||||
|
std::cerr << "Error: Invalid stdout handle" << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is required as Windows is braindead and will otherwise add carriage return characters
|
||||||
|
// to the stream when it encounters newline characters, which breaks binary output.
|
||||||
|
_setmode(_fileno(stdout), O_BINARY);
|
||||||
|
|
||||||
|
bool validArguments {true};
|
||||||
|
std::wstring mode;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
validArguments = false;
|
||||||
|
else
|
||||||
|
mode = argv[1];
|
||||||
|
|
||||||
|
if ((mode == L"-fileinfo" && argc != 3) || (mode == L"-convert" && argc != 6))
|
||||||
|
validArguments = false;
|
||||||
|
|
||||||
|
if (!validArguments) {
|
||||||
|
std::cout << "This binary is only intended to be executed by EmulationStation.exe (ES-DE)"
|
||||||
|
<< std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::wstring path {argv[2]};
|
||||||
|
|
||||||
|
int pageNum {0};
|
||||||
|
int width {0};
|
||||||
|
int height {0};
|
||||||
|
|
||||||
|
if (mode == L"-convert") {
|
||||||
|
pageNum = _wtoi(argv[3]);
|
||||||
|
width = _wtoi(argv[4]);
|
||||||
|
height = _wtoi(argv[5]);
|
||||||
|
#else
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
bool validArguments {true};
|
bool validArguments {true};
|
||||||
|
@ -47,7 +94,7 @@ int main(int argc, char* argv[])
|
||||||
pageNum = atoi(argv[3]);
|
pageNum = atoi(argv[3]);
|
||||||
width = atoi(argv[4]);
|
width = atoi(argv[4]);
|
||||||
height = atoi(argv[5]);
|
height = atoi(argv[5]);
|
||||||
|
#endif
|
||||||
if (width < 1 || width > 7680) {
|
if (width < 1 || width > 7680) {
|
||||||
std::cerr << "Invalid horizontal resolution defined: " << argv[3] << std::endl;
|
std::cerr << "Invalid horizontal resolution defined: " << argv[3] << std::endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
@ -62,7 +109,23 @@ int main(int argc, char* argv[])
|
||||||
// << width << "x" << height << " pixels" << std::endl;
|
// << width << "x" << height << " pixels" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const poppler::document* document {poppler::document::load_from_file(path)};
|
std::ifstream file;
|
||||||
|
|
||||||
|
file.open(path, std::ifstream::binary);
|
||||||
|
if (file.fail()) {
|
||||||
|
std::cerr << "Error: Couldn't open PDF file, permission problems?" << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.seekg(0, std::ios::end);
|
||||||
|
const long fileLength {static_cast<long>(file.tellg())};
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
std::vector<char> fileData(fileLength);
|
||||||
|
file.read(&fileData[0], fileLength);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
const poppler::document* document {
|
||||||
|
poppler::document::load_from_raw_data(&fileData[0], fileLength)};
|
||||||
|
|
||||||
if (document == nullptr) {
|
if (document == nullptr) {
|
||||||
std::cerr << "Error: Couldn't open document, invalid PDF file?" << std::endl;
|
std::cerr << "Error: Couldn't open document, invalid PDF file?" << std::endl;
|
||||||
|
@ -70,8 +133,11 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
const int pageCount {document->pages()};
|
const int pageCount {document->pages()};
|
||||||
|
#if defined(_WIN64)
|
||||||
|
if (mode == L"-fileinfo") {
|
||||||
|
#else
|
||||||
if (mode == "-fileinfo") {
|
if (mode == "-fileinfo") {
|
||||||
|
#endif
|
||||||
std::vector<std::string> pageInfo;
|
std::vector<std::string> pageInfo;
|
||||||
for (int i {0}; i < pageCount; ++i) {
|
for (int i {0}; i < pageCount; ++i) {
|
||||||
std::string pageRow;
|
std::string pageRow;
|
||||||
|
|
Loading…
Reference in a new issue