/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include "pdfioutdev_gpl.hxx" #ifdef _WIN32 # include # include /*_O_BINARY*/ #define WIN32_LEAN_AND_MEAN #include #endif #ifndef SYSTEM_POPPLER #include // std::string #include // std::size_t #include //LIBO_SHARE_FOLDER #endif FILE* g_binary_out=stderr; #ifdef _WIN32 // Use Unicode API static const wchar_t *ownerPassword = nullptr; static const wchar_t *userPassword = nullptr; static const wchar_t *outputFile = nullptr; static const wchar_t *options = L""; #define TO_STRING_VIEW(s) std::wstring_view(L##s) using my_string = std::wstring; // Poppler expects UTF-8 strings on Windows - see its openFile in poppler/goo/gfile.cc. static std::string myStringToStdString(std::wstring_view s) { int len = WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), nullptr, 0, nullptr, nullptr); char* buff = static_cast(_alloca(len * sizeof(char))); len = WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), buff, len, nullptr, nullptr); return std::string(buff, len); } #else // ! _WIN32 static const char *ownerPassword = nullptr; static const char *userPassword = nullptr; static const char *outputFile = nullptr; static const char *options = ""; #define TO_STRING_VIEW(s) std::string_view(s) using my_string = std::string; static std::string myStringToStdString(std::string&& s) { return std::move(s); } #endif #ifdef _WIN32 int wmain(int argc, wchar_t **argv) #else int main(int argc, char **argv) #endif { int k = 1; while (k < argc) { if (argv[k] == TO_STRING_VIEW("-f")) { outputFile = argv[k+1]; argc -= 2; for (int j = k; j < argc; ++j) argv[j] = argv[j+2]; } else if (argv[k] == TO_STRING_VIEW("-o")) { options = argv[k+1]; argc -= 2; for (int j = k; j < argc; ++j) argv[j] = argv[j+2]; } else if (argv[k] == TO_STRING_VIEW("-opw")) { ownerPassword = argv[k+1]; argc -= 2; for (int j = k; j < argc; ++j) argv[j] = argv[j+2]; } else if (argv[k] == TO_STRING_VIEW("-upw")) { userPassword = argv[k+1]; argc -= 2; for (int j = k; j < argc; ++j) argv[j] = argv[j+2]; } ++k; } /* Get data directory location */ #ifdef SYSTEM_POPPLER const char* datadir = nullptr; #else /* Creates an absolute path to the poppler_data directory, by taking the path * to the xpdfimport executable (provided in argv[0], and concatenating a * relative path to the poppler_data directory from the program directory. */ const my_string execPath = argv[0]; const std::size_t filenameStartPos = execPath.find_last_of(TO_STRING_VIEW("/\\")) + 1; const my_string programPath = execPath.substr(0, filenameStartPos); const std::string popplerDataPath = myStringToStdString(programPath + my_string(TO_STRING_VIEW("../" LIBO_SHARE_FOLDER "/xpdfimport/poppler_data"))); const char* datadir = popplerDataPath.c_str(); #endif // read config file #if POPPLER_CHECK_VERSION(0, 83, 0) globalParams = std::make_unique(datadir); #else globalParams = new GlobalParams(datadir); #endif globalParams->setErrQuiet(true); #if defined(_MSC_VER) globalParams->setupBaseFonts(nullptr); #endif // try to read a possible open password from stdin char aPwBuf[129]; aPwBuf[128] = 0; if( ! fgets( aPwBuf, sizeof(aPwBuf)-1, stdin ) ) aPwBuf[0] = 0; // mark as empty else { for( size_t i = 0; i < sizeof(aPwBuf); i++ ) { if( aPwBuf[i] == '\n' ) { aPwBuf[i] = 0; break; } } } // PDFDoc takes over ownership for all strings below GooString* pFileName = new GooString(myStringToStdString(argv[1])); GooString* pErrFileName = new GooString(myStringToStdString(argv[2])); // check for password string(s) GooString* pOwnerPasswordStr( aPwBuf[0] != 0 ? new GooString( aPwBuf ) : (ownerPassword ? new GooString(myStringToStdString(ownerPassword)) : nullptr ) ); GooString* pUserPasswordStr( aPwBuf[0] != 0 ? new GooString( aPwBuf ) : (userPassword ? new GooString(myStringToStdString(userPassword)) : nullptr ) ); if (outputFile) #if defined _WIN32 g_binary_out = _wfopen(outputFile, L"wb"); #else g_binary_out = fopen(outputFile,"wb"); #endif #ifdef _WIN32 // Win actually modifies output for O_TEXT file mode, so need to // revert to binary here _setmode( _fileno( g_binary_out ), _O_BINARY ); #endif #if POPPLER_CHECK_VERSION(22, 6, 0) PDFDoc aDoc( std::make_unique(pFileName), std::optional(pOwnerPasswordStr), std::optional(pUserPasswordStr) ); PDFDoc aErrDoc( std::make_unique(pErrFileName), std::optional(pOwnerPasswordStr), std::optional(pUserPasswordStr) ); #else PDFDoc aDoc( pFileName, pOwnerPasswordStr, pUserPasswordStr ); PDFDoc aErrDoc( pErrFileName, pOwnerPasswordStr, pUserPasswordStr ); #endif // Check various permissions for aDoc. PDFDoc &rDoc = aDoc.isOk()? aDoc: aErrDoc; pdfi::PDFOutDev aOutDev(&rDoc); if (options == TO_STRING_VIEW("SkipImages")) { aOutDev.setSkipImages(true); } // tell the receiver early - needed for proper progress calculation const int nPages = rDoc.isOk()? rDoc.getNumPages(): 0; pdfi::PDFOutDev::setPageNum(nPages); // virtual resolution of the PDF OutputDev in dpi static const int PDFI_OUTDEV_RESOLUTION = 7200; // do the conversion for (int i = 1; i <= nPages; ++i) { rDoc.displayPage(&aOutDev, i, PDFI_OUTDEV_RESOLUTION, PDFI_OUTDEV_RESOLUTION, 0, true, true, true); rDoc.processLinks(&aOutDev, i); } return 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */