mirror of
https://github.com/qpdf/qpdf.git
synced 2024-06-05 03:40:53 +00:00
implement ability to save PDF to memory, also update ChangeLog
This commit is contained in:
parent
655c55f848
commit
759c56e1fe
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
2011-08-10 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* include/qpdf/QPDFWriter.hh: add a new constructor that takes
|
||||||
|
only a QPDF reference and leaves specification of output for
|
||||||
|
later. Add methods setOutputFilename() to set the output to a
|
||||||
|
filename or stdout, and setOutputMemory() to indicate that output
|
||||||
|
should go to a memory buffer. Add method getBuffer() to retrieve
|
||||||
|
the buffer used if output was saved to a memory buffer.
|
||||||
|
|
||||||
|
* include/qpdf/QPDF.hh: add methods replaceObject() and
|
||||||
|
swapObjects() to allow replacement of an object and swapping of
|
||||||
|
two objects by object ID.
|
||||||
|
|
||||||
|
* include/qpdf/QPDFObjectHandle.hh: add new methods getDictAsMap()
|
||||||
|
and getArrayAsVector() for returning the elements of a dictionary
|
||||||
|
or an array as a map or vector.
|
||||||
|
|
||||||
2011-06-25 Jay Berkenbilt <ejb@ql.org>
|
2011-06-25 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
* 2.2.4: release
|
* 2.2.4: release
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <qpdf/QPDFXRefEntry.hh>
|
#include <qpdf/QPDFXRefEntry.hh>
|
||||||
|
|
||||||
|
#include <qpdf/Pl_Buffer.hh>
|
||||||
#include <qpdf/PointerHolder.hh>
|
#include <qpdf/PointerHolder.hh>
|
||||||
#include <qpdf/Pipeline.hh>
|
#include <qpdf/Pipeline.hh>
|
||||||
#include <qpdf/Buffer.hh>
|
#include <qpdf/Buffer.hh>
|
||||||
|
@ -35,6 +36,24 @@ class Pl_Count;
|
||||||
class QPDFWriter
|
class QPDFWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Construct a QPDFWriter object without specifying output. You
|
||||||
|
// must call one of the output setting routines defined below.
|
||||||
|
QPDF_DLL
|
||||||
|
QPDFWriter(QPDF& pdf);
|
||||||
|
|
||||||
|
// Create a QPDFWriter object that writes its output to a file or
|
||||||
|
// to stdout. This is equivalent to using the previous
|
||||||
|
// constructor and then calling setOutputFilename(). See
|
||||||
|
// setOutputFilename() for details.
|
||||||
|
QPDF_DLL
|
||||||
|
QPDFWriter(QPDF& pdf, char const* filename);
|
||||||
|
QPDF_DLL
|
||||||
|
~QPDFWriter();
|
||||||
|
|
||||||
|
// Setting Output. Output may be set only one time. If you don't
|
||||||
|
// use the filename version of the QPDFWriter constructor, you
|
||||||
|
// must call exactly one of these methods.
|
||||||
|
|
||||||
// Passing null as filename means write to stdout. QPDFWriter
|
// Passing null as filename means write to stdout. QPDFWriter
|
||||||
// will create a zero-length output file upon construction. If
|
// will create a zero-length output file upon construction. If
|
||||||
// write fails, the empty or partially written file will not be
|
// write fails, the empty or partially written file will not be
|
||||||
|
@ -42,10 +61,20 @@ class QPDFWriter
|
||||||
// useful for tracking down problems. If your application doesn't
|
// useful for tracking down problems. If your application doesn't
|
||||||
// want the partially written file to be left behind, you should
|
// want the partially written file to be left behind, you should
|
||||||
// delete it the eventual call to write fails.
|
// delete it the eventual call to write fails.
|
||||||
QPDF_DLL
|
void setOutputFilename(char const* filename);
|
||||||
QPDFWriter(QPDF& pdf, char const* filename);
|
|
||||||
QPDF_DLL
|
// Indicate that QPDFWriter should create a memory buffer to
|
||||||
~QPDFWriter();
|
// contain the final PDF file. Obtain the memory by calling
|
||||||
|
// getBuffer().
|
||||||
|
void setOutputMemory();
|
||||||
|
|
||||||
|
// Return the buffer object containing the PDF file. If
|
||||||
|
// setOutputMemory() has been called, this method may be called
|
||||||
|
// exactly one time after write() has returned. The caller is
|
||||||
|
// responsible for deleting the buffer when done.
|
||||||
|
Buffer* getBuffer();
|
||||||
|
|
||||||
|
// Setting Parameters
|
||||||
|
|
||||||
// Set the value of object stream mode. In disable mode, we never
|
// Set the value of object stream mode. In disable mode, we never
|
||||||
// generate any object streams. In preserve mode, we preserve
|
// generate any object streams. In preserve mode, we preserve
|
||||||
|
@ -177,6 +206,7 @@ class QPDFWriter
|
||||||
|
|
||||||
enum trailer_e { t_normal, t_lin_first, t_lin_second };
|
enum trailer_e { t_normal, t_lin_first, t_lin_second };
|
||||||
|
|
||||||
|
void init();
|
||||||
int bytesNeeded(unsigned long n);
|
int bytesNeeded(unsigned long n);
|
||||||
void writeBinary(unsigned long val, unsigned int bytes);
|
void writeBinary(unsigned long val, unsigned int bytes);
|
||||||
void writeString(std::string const& str);
|
void writeString(std::string const& str);
|
||||||
|
@ -253,6 +283,7 @@ class QPDFWriter
|
||||||
// clearPipelineStack is called.
|
// clearPipelineStack is called.
|
||||||
Pipeline* pushPipeline(Pipeline*);
|
Pipeline* pushPipeline(Pipeline*);
|
||||||
void activatePipelineStack();
|
void activatePipelineStack();
|
||||||
|
void initializePipelineStack(Pipeline *);
|
||||||
|
|
||||||
// Calls finish on the current pipeline and pops the pipeline
|
// Calls finish on the current pipeline and pops the pipeline
|
||||||
// stack until the top of stack is a previous active top of stack,
|
// stack until the top of stack is a previous active top of stack,
|
||||||
|
@ -269,6 +300,8 @@ class QPDFWriter
|
||||||
char const* filename;
|
char const* filename;
|
||||||
FILE* file;
|
FILE* file;
|
||||||
bool close_file;
|
bool close_file;
|
||||||
|
Pl_Buffer* buffer_pipeline;
|
||||||
|
Buffer* output_buffer;
|
||||||
bool normalize_content_set;
|
bool normalize_content_set;
|
||||||
bool normalize_content;
|
bool normalize_content;
|
||||||
bool stream_data_mode_set;
|
bool stream_data_mode_set;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <qpdf/Pl_StdioFile.hh>
|
#include <qpdf/Pl_StdioFile.hh>
|
||||||
#include <qpdf/Pl_Count.hh>
|
#include <qpdf/Pl_Count.hh>
|
||||||
#include <qpdf/Pl_Discard.hh>
|
#include <qpdf/Pl_Discard.hh>
|
||||||
#include <qpdf/Pl_Buffer.hh>
|
|
||||||
#include <qpdf/Pl_RC4.hh>
|
#include <qpdf/Pl_RC4.hh>
|
||||||
#include <qpdf/Pl_AES_PDF.hh>
|
#include <qpdf/Pl_AES_PDF.hh>
|
||||||
#include <qpdf/Pl_Flate.hh>
|
#include <qpdf/Pl_Flate.hh>
|
||||||
|
@ -21,32 +20,65 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
QPDFWriter::QPDFWriter(QPDF& pdf, char const* filename) :
|
QPDFWriter::QPDFWriter(QPDF& pdf) :
|
||||||
pdf(pdf),
|
pdf(pdf)
|
||||||
filename(filename),
|
|
||||||
file(0),
|
|
||||||
close_file(false),
|
|
||||||
normalize_content_set(false),
|
|
||||||
normalize_content(false),
|
|
||||||
stream_data_mode_set(false),
|
|
||||||
stream_data_mode(qpdf_s_compress),
|
|
||||||
qdf_mode(false),
|
|
||||||
static_id(false),
|
|
||||||
suppress_original_object_ids(false),
|
|
||||||
direct_stream_lengths(true),
|
|
||||||
encrypted(false),
|
|
||||||
preserve_encryption(true),
|
|
||||||
linearized(false),
|
|
||||||
object_stream_mode(qpdf_o_preserve),
|
|
||||||
encrypt_metadata(true),
|
|
||||||
encrypt_use_aes(false),
|
|
||||||
encryption_dict_objid(0),
|
|
||||||
next_objid(1),
|
|
||||||
cur_stream_length_id(0),
|
|
||||||
cur_stream_length(0),
|
|
||||||
added_newline(false),
|
|
||||||
max_ostream_index(0)
|
|
||||||
{
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPDFWriter::QPDFWriter(QPDF& pdf, char const* filename) :
|
||||||
|
pdf(pdf)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
setOutputFilename(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFWriter::init()
|
||||||
|
{
|
||||||
|
filename = 0;
|
||||||
|
file = 0;
|
||||||
|
close_file = false;
|
||||||
|
buffer_pipeline = 0;
|
||||||
|
output_buffer = 0;
|
||||||
|
normalize_content_set = false;
|
||||||
|
normalize_content = false;
|
||||||
|
stream_data_mode_set = false;
|
||||||
|
stream_data_mode = qpdf_s_compress;
|
||||||
|
qdf_mode = false;
|
||||||
|
static_id = false;
|
||||||
|
suppress_original_object_ids = false;
|
||||||
|
direct_stream_lengths = true;
|
||||||
|
encrypted = false;
|
||||||
|
preserve_encryption = true;
|
||||||
|
linearized = false;
|
||||||
|
object_stream_mode = qpdf_o_preserve;
|
||||||
|
encrypt_metadata = true;
|
||||||
|
encrypt_use_aes = false;
|
||||||
|
encryption_dict_objid = 0;
|
||||||
|
next_objid = 1;
|
||||||
|
cur_stream_length_id = 0;
|
||||||
|
cur_stream_length = 0;
|
||||||
|
added_newline = false;
|
||||||
|
max_ostream_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPDFWriter::~QPDFWriter()
|
||||||
|
{
|
||||||
|
if (file && close_file)
|
||||||
|
{
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
if (output_buffer)
|
||||||
|
{
|
||||||
|
delete output_buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFWriter::setOutputFilename(char const* filename)
|
||||||
|
{
|
||||||
|
this->filename = filename;
|
||||||
if (filename == 0)
|
if (filename == 0)
|
||||||
{
|
{
|
||||||
this->filename = "standard output";
|
this->filename = "standard output";
|
||||||
|
@ -61,19 +93,25 @@ QPDFWriter::QPDFWriter(QPDF& pdf, char const* filename) :
|
||||||
fopen(filename, "wb+"));
|
fopen(filename, "wb+"));
|
||||||
close_file = true;
|
close_file = true;
|
||||||
}
|
}
|
||||||
Pipeline* p = new Pl_StdioFile("qdf output", file);
|
Pipeline* p = new Pl_StdioFile("qpdf output", file);
|
||||||
to_delete.push_back(p);
|
to_delete.push_back(p);
|
||||||
pipeline = new Pl_Count("qdf count", p);
|
initializePipelineStack(p);
|
||||||
to_delete.push_back(pipeline);
|
|
||||||
pipeline_stack.push_back(pipeline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFWriter::~QPDFWriter()
|
void
|
||||||
|
QPDFWriter::setOutputMemory()
|
||||||
{
|
{
|
||||||
if (file && close_file)
|
this->buffer_pipeline = new Pl_Buffer("qpdf output");
|
||||||
{
|
to_delete.push_back(this->buffer_pipeline);
|
||||||
fclose(file);
|
initializePipelineStack(this->buffer_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Buffer*
|
||||||
|
QPDFWriter::getBuffer()
|
||||||
|
{
|
||||||
|
Buffer* result = this->output_buffer;
|
||||||
|
this->output_buffer = 0;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -565,6 +603,14 @@ QPDFWriter::pushPipeline(Pipeline* p)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFWriter::initializePipelineStack(Pipeline *p)
|
||||||
|
{
|
||||||
|
this->pipeline = new Pl_Count("qpdf count", p);
|
||||||
|
to_delete.push_back(this->pipeline);
|
||||||
|
this->pipeline_stack.push_back(this->pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFWriter::activatePipelineStack()
|
QPDFWriter::activatePipelineStack()
|
||||||
{
|
{
|
||||||
|
@ -1503,6 +1549,8 @@ QPDFWriter::generateObjectStreams()
|
||||||
void
|
void
|
||||||
QPDFWriter::write()
|
QPDFWriter::write()
|
||||||
{
|
{
|
||||||
|
// XXX Check output
|
||||||
|
|
||||||
// Do preliminary setup
|
// Do preliminary setup
|
||||||
|
|
||||||
if (this->linearized)
|
if (this->linearized)
|
||||||
|
@ -1656,6 +1704,11 @@ QPDFWriter::write()
|
||||||
fclose(this->file);
|
fclose(this->file);
|
||||||
}
|
}
|
||||||
this->file = 0;
|
this->file = 0;
|
||||||
|
if (this->buffer_pipeline)
|
||||||
|
{
|
||||||
|
this->output_buffer = this->buffer_pipeline->getBuffer();
|
||||||
|
this->buffer_pipeline = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -584,10 +584,18 @@ void runtest(int n, char const* filename)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFWriter w(pdf, "a.pdf");
|
// Exercise writing to memory buffer
|
||||||
|
QPDFWriter w(pdf);
|
||||||
|
w.setOutputMemory();
|
||||||
w.setStaticID(true);
|
w.setStaticID(true);
|
||||||
w.setStreamDataMode(qpdf_s_preserve);
|
w.setStreamDataMode(qpdf_s_preserve);
|
||||||
w.write();
|
w.write();
|
||||||
|
Buffer* b = w.getBuffer();
|
||||||
|
FILE* f = QUtil::fopen_wrapper(std::string("open a.pdf"),
|
||||||
|
fopen("a.pdf", "wb"));
|
||||||
|
fwrite(b->getBuffer(), b->getSize(), 1, f);
|
||||||
|
fclose(f);
|
||||||
|
delete b;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user