aboutsummaryrefslogtreecommitdiffstats
path: root/examples/pdf-create.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-04-02 23:14:10 +0200
committerJay Berkenbilt <ejb@ql.org>2022-04-04 14:10:40 +0200
commit12f1eb15ca3fed6310402847559a7c99d3c77847 (patch)
tree8935675b623c6f3b4914b8b44f7fa5f2816a9241 /examples/pdf-create.cc
parentf20fa61eb4c323eb1642c69c236b3d9a1f8b2cdb (diff)
downloadqpdf-12f1eb15ca3fed6310402847559a7c99d3c77847.tar.zst
Programmatically apply new formatting to code
Run this: for i in **/*.cc **/*.c **/*.h **/*.hh; do clang-format < $i >| $i.new && mv $i.new $i done
Diffstat (limited to 'examples/pdf-create.cc')
-rw-r--r--examples/pdf-create.cc223
1 files changed, 99 insertions, 124 deletions
diff --git a/examples/pdf-create.cc b/examples/pdf-create.cc
index b5d87618..5274d0a2 100644
--- a/examples/pdf-create.cc
+++ b/examples/pdf-create.cc
@@ -5,20 +5,20 @@
// StreamDataProvider with different types of filters.
//
+#include <qpdf/Pl_Buffer.hh>
+#include <qpdf/Pl_DCT.hh>
+#include <qpdf/Pl_RunLength.hh>
+#include <qpdf/QIntC.hh>
#include <qpdf/QPDF.hh>
+#include <qpdf/QPDFObjectHandle.hh>
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFPageObjectHelper.hh>
#include <qpdf/QPDFWriter.hh>
-#include <qpdf/QPDFObjectHandle.hh>
#include <qpdf/QUtil.hh>
-#include <qpdf/Pl_Buffer.hh>
-#include <qpdf/Pl_RunLength.hh>
-#include <qpdf/Pl_DCT.hh>
-#include <qpdf/QIntC.hh>
#include <iostream>
#include <memory>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
static char const* whoami = 0;
@@ -27,11 +27,10 @@ static char const* whoami = 0;
class ImageProvider: public QPDFObjectHandle::StreamDataProvider
{
public:
- ImageProvider(std::string const& color_space,
- std::string const& filter);
+ ImageProvider(std::string const& color_space, std::string const& filter);
virtual ~ImageProvider();
- virtual void provideStreamData(int objid, int generation,
- Pipeline* pipeline);
+ virtual void
+ provideStreamData(int objid, int generation, Pipeline* pipeline);
size_t getWidth() const;
size_t getHeight() const;
@@ -45,8 +44,8 @@ class ImageProvider: public QPDFObjectHandle::StreamDataProvider
J_COLOR_SPACE j_color_space;
};
-ImageProvider::ImageProvider(std::string const& color_space,
- std::string const& filter) :
+ImageProvider::ImageProvider(
+ std::string const& color_space, std::string const& filter) :
width(400),
stripe_height(80),
color_space(color_space),
@@ -54,8 +53,7 @@ ImageProvider::ImageProvider(std::string const& color_space,
n_stripes(6),
j_color_space(JCS_UNKNOWN)
{
- if (color_space == "/DeviceCMYK")
- {
+ if (color_space == "/DeviceCMYK") {
j_color_space = JCS_CMYK;
stripes.push_back(std::string("\xff\x00\x00\x00", 4));
stripes.push_back(std::string("\x00\xff\x00\x00", 4));
@@ -63,9 +61,7 @@ ImageProvider::ImageProvider(std::string const& color_space,
stripes.push_back(std::string("\xff\x00\xff\x00", 4));
stripes.push_back(std::string("\xff\xff\x00\x00", 4));
stripes.push_back(std::string("\x00\x00\x00\xff", 4));
- }
- else if (color_space == "/DeviceRGB")
- {
+ } else if (color_space == "/DeviceRGB") {
j_color_space = JCS_RGB;
stripes.push_back(std::string("\xff\x00\x00", 3));
stripes.push_back(std::string("\x00\xff\x00", 3));
@@ -73,9 +69,7 @@ ImageProvider::ImageProvider(std::string const& color_space,
stripes.push_back(std::string("\xff\x00\xff", 3));
stripes.push_back(std::string("\xff\xff\x00", 3));
stripes.push_back(std::string("\x00\x00\x00", 3));
- }
- else if (color_space == "/DeviceGray")
- {
+ } else if (color_space == "/DeviceGray") {
j_color_space = JCS_GRAYSCALE;
stripes.push_back(std::string("\xee", 1));
stripes.push_back(std::string("\xcc", 1));
@@ -103,34 +97,31 @@ ImageProvider::getHeight() const
}
void
-ImageProvider::provideStreamData(int objid, int generation,
- Pipeline* pipeline)
+ImageProvider::provideStreamData(int objid, int generation, Pipeline* pipeline)
{
std::vector<std::shared_ptr<Pipeline>> to_delete;
Pipeline* p = pipeline;
std::shared_ptr<Pipeline> p_new;
- if (filter == "/DCTDecode")
- {
+ if (filter == "/DCTDecode") {
p_new = std::make_shared<Pl_DCT>(
- "image encoder", pipeline,
- QIntC::to_uint(width), QIntC::to_uint(getHeight()),
- QIntC::to_int(stripes[0].length()), j_color_space);
+ "image encoder",
+ pipeline,
+ QIntC::to_uint(width),
+ QIntC::to_uint(getHeight()),
+ QIntC::to_int(stripes[0].length()),
+ j_color_space);
to_delete.push_back(p_new);
p = p_new.get();
- }
- else if (filter == "/RunLengthDecode")
- {
+ } else if (filter == "/RunLengthDecode") {
p_new = std::make_shared<Pl_RunLength>(
"image encoder", pipeline, Pl_RunLength::a_encode);
to_delete.push_back(p_new);
p = p_new.get();
}
- for (size_t i = 0; i < n_stripes; ++i)
- {
- for (size_t j = 0; j < width * stripe_height; ++j)
- {
+ for (size_t i = 0; i < n_stripes; ++i) {
+ for (size_t j = 0; j < width * stripe_height; ++j) {
p->write(
QUtil::unsigned_char_pointer(stripes[i].c_str()),
stripes[i].length());
@@ -139,36 +130,43 @@ ImageProvider::provideStreamData(int objid, int generation,
p->finish();
}
-void usage()
+void
+usage()
{
std::cerr << "Usage: " << whoami << " filename" << std::endl
<< "Creates a simple PDF and writes it to filename" << std::endl;
exit(2);
}
-static QPDFObjectHandle createPageContents(QPDF& pdf, std::string const& text)
+static QPDFObjectHandle
+createPageContents(QPDF& pdf, std::string const& text)
{
// Create a stream that displays our image and the given text in
// our font.
- std::string contents =
- "BT /F1 24 Tf 72 320 Td (" + text + ") Tj ET\n"
+ std::string contents = "BT /F1 24 Tf 72 320 Td (" + text +
+ ") Tj ET\n"
"q 244 0 0 144 184 100 cm /Im1 Do Q\n";
return QPDFObjectHandle::newStream(&pdf, contents);
}
-QPDFObjectHandle newName(std::string const& name)
+QPDFObjectHandle
+newName(std::string const& name)
{
return QPDFObjectHandle::newName(name);
}
-QPDFObjectHandle newInteger(size_t val)
+QPDFObjectHandle
+newInteger(size_t val)
{
return QPDFObjectHandle::newInteger(QIntC::to_int(val));
}
-void add_page(QPDFPageDocumentHelper& dh, QPDFObjectHandle font,
- std::string const& color_space,
- std::string const& filter)
+void
+add_page(
+ QPDFPageDocumentHelper& dh,
+ QPDFObjectHandle font,
+ std::string const& color_space,
+ std::string const& filter)
{
QPDF& pdf(dh.getQPDF());
@@ -193,9 +191,8 @@ void add_page(QPDFPageDocumentHelper& dh, QPDFObjectHandle font,
image.replaceDict(image_dict);
// Provide the stream data.
- image.replaceStreamData(provider,
- QPDFObjectHandle::parse(filter),
- QPDFObjectHandle::newNull());
+ image.replaceStreamData(
+ provider, QPDFObjectHandle::parse(filter), QPDFObjectHandle::newNull());
// Create direct objects as needed by the page dictionary.
QPDFObjectHandle procset = "[/PDF /Text /ImageC]"_qpdf;
@@ -212,15 +209,14 @@ void add_page(QPDFPageDocumentHelper& dh, QPDFObjectHandle font,
resources.replaceKey("/XObject", xobject);
// Create the page content stream
- QPDFObjectHandle contents = createPageContents(
- pdf, color_space + " with filter " + filter);
+ QPDFObjectHandle contents =
+ createPageContents(pdf, color_space + " with filter " + filter);
// Create the page dictionary
- QPDFObjectHandle page = pdf.makeIndirectObject(
- "<<"
- " /Type /Page"
- " /MediaBox [0 0 612 392]"
- ">>"_qpdf);
+ QPDFObjectHandle page = pdf.makeIndirectObject("<<"
+ " /Type /Page"
+ " /MediaBox [0 0 612 392]"
+ ">>"_qpdf);
page.replaceKey("/Contents", contents);
page.replaceKey("/Resources", resources);
@@ -228,9 +224,11 @@ void add_page(QPDFPageDocumentHelper& dh, QPDFObjectHandle font,
dh.addPage(page, false);
}
-static void check(char const* filename,
- std::vector<std::string> const& color_spaces,
- std::vector<std::string> const& filters)
+static void
+check(
+ char const* filename,
+ std::vector<std::string> const& color_spaces,
+ std::vector<std::string> const& filters)
{
// Each stream is compressed the way it is supposed to be. We will
// add additional tests in qpdf.test to exercise QPDFWriter more
@@ -253,17 +251,14 @@ static void check(char const* filename,
QPDF pdf;
pdf.processFile(filename);
auto pages = QPDFPageDocumentHelper(pdf).getAllPages();
- if (n_color_spaces * n_filters != pages.size())
- {
+ if (n_color_spaces * n_filters != pages.size()) {
throw std::logic_error("incorrect number of pages");
}
size_t pageno = 1;
bool errors = false;
- for (auto& page : pages)
- {
+ for (auto& page : pages) {
auto images = page.getImages();
- if (images.size() != 1)
- {
+ if (images.size() != 1) {
throw std::logic_error("incorrect number of images on page");
}
@@ -273,8 +268,7 @@ static void check(char const* filename,
std::string desired_filter = filters[(pageno - 1) % n_filters];
// In the default mode, QPDFWriter will compress with
// /FlateDecode if no filters are provided.
- if (desired_filter == "null")
- {
+ if (desired_filter == "null") {
desired_filter = "/FlateDecode";
}
QPDFObjectHandle image = images.begin()->second;
@@ -282,40 +276,34 @@ static void check(char const* filename,
QPDFObjectHandle color_space = image_dict.getKey("/ColorSpace");
QPDFObjectHandle filter = image_dict.getKey("/Filter");
bool this_errors = false;
- if (! filter.isNameAndEquals(desired_filter))
- {
+ if (!filter.isNameAndEquals(desired_filter)) {
this_errors = errors = true;
std::cout << "page " << pageno << ": expected filter "
- << desired_filter << "; actual filter = "
- << filter.unparse() << std::endl;
+ << desired_filter
+ << "; actual filter = " << filter.unparse() << std::endl;
}
- if (! color_space.isNameAndEquals(desired_color_space))
- {
+ if (!color_space.isNameAndEquals(desired_color_space)) {
this_errors = errors = true;
std::cout << "page " << pageno << ": expected color space "
- << desired_color_space << "; actual color space = "
- << color_space.unparse() << std::endl;
+ << desired_color_space
+ << "; actual color space = " << color_space.unparse()
+ << std::endl;
}
- if (! this_errors)
- {
+ if (!this_errors) {
// Check image data
- auto actual_data =
- image.getStreamData(qpdf_dl_all);
+ auto actual_data = image.getStreamData(qpdf_dl_all);
ImageProvider* p = new ImageProvider(desired_color_space, "null");
PointerHolder<QPDFObjectHandle::StreamDataProvider> provider(p);
Pl_Buffer b_p("get image data");
provider->provideStreamData(0, 0, &b_p);
PointerHolder<Buffer> desired_data(b_p.getBuffer());
- if (desired_data->getSize() != actual_data->getSize())
- {
- std::cout << "page " << pageno
- << ": image data length mismatch" << std::endl;
+ if (desired_data->getSize() != actual_data->getSize()) {
+ std::cout << "page " << pageno << ": image data length mismatch"
+ << std::endl;
this_errors = errors = true;
- }
- else
- {
+ } else {
// Compare bytes. For JPEG, allow a certain number of
// the bytes to be off desired by more than a given
// tolerance. Any of the samples may be a little off
@@ -326,25 +314,20 @@ static void check(char const* filename,
unsigned char const* desired_bytes = desired_data->getBuffer();
size_t len = actual_data->getSize();
unsigned int mismatches = 0;
- int tolerance = (
- desired_filter == "/DCTDecode" ? 10 : 0);
- size_t threshold = (
- desired_filter == "/DCTDecode" ? len / 40U : 0);
- for (size_t i = 0; i < len; ++i)
- {
+ int tolerance = (desired_filter == "/DCTDecode" ? 10 : 0);
+ size_t threshold =
+ (desired_filter == "/DCTDecode" ? len / 40U : 0);
+ for (size_t i = 0; i < len; ++i) {
int delta = actual_bytes[i] - desired_bytes[i];
- if ((delta > tolerance) || (delta < -tolerance))
- {
+ if ((delta > tolerance) || (delta < -tolerance)) {
++mismatches;
}
}
- if (mismatches > threshold)
- {
- std::cout << "page " << pageno
- << ": " << desired_color_space << ", "
- << desired_filter
- << ": mismatches: " << mismatches
- << " of " << len << std::endl;
+ if (mismatches > threshold) {
+ std::cout << "page " << pageno << ": "
+ << desired_color_space << ", " << desired_filter
+ << ": mismatches: " << mismatches << " of " << len
+ << std::endl;
this_errors = errors = true;
}
}
@@ -352,17 +335,15 @@ static void check(char const* filename,
++pageno;
}
- if (errors)
- {
+ if (errors) {
throw std::logic_error("errors found");
- }
- else
- {
+ } else {
std::cout << "all checks passed" << std::endl;
}
}
-static void create_pdf(char const* filename)
+static void
+create_pdf(char const* filename)
{
QPDF pdf;
@@ -371,14 +352,13 @@ static void create_pdf(char const* filename)
// Add an indirect object to contain a font descriptor for the
// built-in Helvetica font.
- QPDFObjectHandle font = pdf.makeIndirectObject(
- "<<"
- " /Type /Font"
- " /Subtype /Type1"
- " /Name /F1"
- " /BaseFont /Helvetica"
- " /Encoding /WinAnsiEncoding"
- ">>"_qpdf);
+ QPDFObjectHandle font = pdf.makeIndirectObject("<<"
+ " /Type /Font"
+ " /Subtype /Type1"
+ " /Name /F1"
+ " /BaseFont /Helvetica"
+ " /Encoding /WinAnsiEncoding"
+ ">>"_qpdf);
std::vector<std::string> color_spaces;
color_spaces.push_back("/DeviceCMYK");
@@ -389,10 +369,8 @@ static void create_pdf(char const* filename)
filters.push_back("/DCTDecode");
filters.push_back("/RunLengthDecode");
QPDFPageDocumentHelper dh(pdf);
- for (auto const& color_space : color_spaces)
- {
- for (auto const& filter : filters)
- {
+ for (auto const& color_space : color_spaces) {
+ for (auto const& filter : filters) {
add_page(dh, font, color_space, filter);
}
}
@@ -405,22 +383,19 @@ static void create_pdf(char const* filename)
check(filename, color_spaces, filters);
}
-int main(int argc, char* argv[])
+int
+main(int argc, char* argv[])
{
whoami = QUtil::getWhoami(argv[0]);
- if (argc != 2)
- {
+ if (argc != 2) {
usage();
}
char const* filename = argv[1];
- try
- {
+ try {
create_pdf(filename);
- }
- catch (std::exception& e)
- {
+ } catch (std::exception& e) {
std::cerr << e.what() << std::endl;
exit(2);
}