1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "pdfioutdev_gpl.hxx"
23 # include <fcntl.h> /*_O_BINARY*/
24 #define WIN32_LEAN_AND_MEAN
27 #ifndef SYSTEM_POPPLER
28 #include <string> // std::string
29 #include <cstddef> // std::size_t
30 #include <config_folders.h> //LIBO_SHARE_FOLDER
33 FILE* g_binary_out
=stderr
;
39 static const wchar_t *ownerPassword
= nullptr;
40 static const wchar_t *userPassword
= nullptr;
41 static const wchar_t *outputFile
= nullptr;
42 static const wchar_t *options
= L
"";
44 #define TO_STRING_VIEW(s) std::wstring_view(L##s)
45 using my_string
= std::wstring
;
47 // Poppler expects UTF-8 strings on Windows - see its openFile in poppler/goo/gfile.cc.
48 static std::string
myStringToStdString(std::wstring_view s
)
50 int len
= WideCharToMultiByte(CP_UTF8
, 0, s
.data(), s
.size(), nullptr, 0, nullptr, nullptr);
51 char* buff
= static_cast<char*>(_alloca(len
* sizeof(char)));
52 len
= WideCharToMultiByte(CP_UTF8
, 0, s
.data(), s
.size(), buff
, len
, nullptr, nullptr);
53 return std::string(buff
, len
);
58 static const char *ownerPassword
= nullptr;
59 static const char *userPassword
= nullptr;
60 static const char *outputFile
= nullptr;
61 static const char *options
= "";
63 #define TO_STRING_VIEW(s) std::string_view(s)
64 using my_string
= std::string
;
66 static std::string
myStringToStdString(std::string
&& s
) { return std::move(s
); }
71 int wmain(int argc
, wchar_t **argv
)
73 int main(int argc
, char **argv
)
79 if (argv
[k
] == TO_STRING_VIEW("-f"))
81 outputFile
= argv
[k
+1];
83 for (int j
= k
; j
< argc
; ++j
)
86 else if (argv
[k
] == TO_STRING_VIEW("-o"))
90 for (int j
= k
; j
< argc
; ++j
)
94 else if (argv
[k
] == TO_STRING_VIEW("-opw"))
96 ownerPassword
= argv
[k
+1];
98 for (int j
= k
; j
< argc
; ++j
)
101 else if (argv
[k
] == TO_STRING_VIEW("-upw"))
103 userPassword
= argv
[k
+1];
105 for (int j
= k
; j
< argc
; ++j
)
111 /* Get data directory location */
112 #ifdef SYSTEM_POPPLER
113 const char* datadir
= nullptr;
115 /* Creates an absolute path to the poppler_data directory, by taking the path
116 * to the xpdfimport executable (provided in argv[0], and concatenating a
117 * relative path to the poppler_data directory from the program directory. */
118 const my_string execPath
= argv
[0];
119 const std::size_t filenameStartPos
= execPath
.find_last_of(TO_STRING_VIEW("/\\")) + 1;
120 const my_string programPath
= execPath
.substr(0, filenameStartPos
);
121 const std::string popplerDataPath
= myStringToStdString(programPath
+ my_string(TO_STRING_VIEW("../" LIBO_SHARE_FOLDER
"/xpdfimport/poppler_data")));
122 const char* datadir
= popplerDataPath
.c_str();
126 #if POPPLER_CHECK_VERSION(0, 83, 0)
127 globalParams
= std::make_unique
<GlobalParams
>(datadir
);
129 globalParams
= new GlobalParams(datadir
);
131 globalParams
->setErrQuiet(true);
132 #if defined(_MSC_VER)
133 globalParams
->setupBaseFonts(nullptr);
136 // try to read a possible open password from stdin
139 if( ! fgets( aPwBuf
, sizeof(aPwBuf
)-1, stdin
) )
140 aPwBuf
[0] = 0; // mark as empty
143 for( size_t i
= 0; i
< sizeof(aPwBuf
); i
++ )
145 if( aPwBuf
[i
] == '\n' )
153 // PDFDoc takes over ownership for all strings below
154 GooString
* pFileName
= new GooString(myStringToStdString(argv
[1]));
156 // check for password string(s)
157 GooString
* pOwnerPasswordStr( aPwBuf
[0] != 0
158 ? new GooString( aPwBuf
)
160 ? new GooString(myStringToStdString(ownerPassword
))
162 GooString
* pUserPasswordStr( aPwBuf
[0] != 0
163 ? new GooString( aPwBuf
)
165 ? new GooString(myStringToStdString(userPassword
))
169 g_binary_out
= _wfopen(outputFile
, L
"wb");
171 g_binary_out
= fopen(outputFile
,"wb");
175 // Win actually modifies output for O_TEXT file mode, so need to
176 // revert to binary here
177 _setmode( _fileno( g_binary_out
), _O_BINARY
);
180 #if POPPLER_CHECK_VERSION(22, 6, 0)
181 PDFDoc
aDoc( std::make_unique
<GooString
>(pFileName
),
182 std::optional
<GooString
>(pOwnerPasswordStr
),
183 std::optional
<GooString
>(pUserPasswordStr
) );
185 PDFDoc
aDoc( pFileName
,
191 return aDoc
.getErrorCode();
193 pdfi::PDFOutDev
aOutDev(&aDoc
);
194 if (options
== TO_STRING_VIEW("SkipImages")) {
195 aOutDev
.setSkipImages(true);
198 // tell the receiver early - needed for proper progress calculation
199 const int nPages
= aDoc
.getNumPages();
200 pdfi::PDFOutDev::setPageNum(nPages
);
202 // virtual resolution of the PDF OutputDev in dpi
203 static const int PDFI_OUTDEV_RESOLUTION
= 7200;
206 for (int i
= 1; i
<= nPages
; ++i
)
208 aDoc
.displayPage(&aOutDev
,
210 PDFI_OUTDEV_RESOLUTION
,
211 PDFI_OUTDEV_RESOLUTION
,
212 0, true, true, true);
213 aDoc
.processLinks(&aOutDev
, i
);
219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */