mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 02:49:00 +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>
|
||||
|
||||
* 2.2.4: release
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <qpdf/QPDFXRefEntry.hh>
|
||||
|
||||
#include <qpdf/Pl_Buffer.hh>
|
||||
#include <qpdf/PointerHolder.hh>
|
||||
#include <qpdf/Pipeline.hh>
|
||||
#include <qpdf/Buffer.hh>
|
||||
@ -35,6 +36,24 @@ class Pl_Count;
|
||||
class QPDFWriter
|
||||
{
|
||||
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
|
||||
// will create a zero-length output file upon construction. If
|
||||
// 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
|
||||
// want the partially written file to be left behind, you should
|
||||
// delete it the eventual call to write fails.
|
||||
QPDF_DLL
|
||||
QPDFWriter(QPDF& pdf, char const* filename);
|
||||
QPDF_DLL
|
||||
~QPDFWriter();
|
||||
void setOutputFilename(char const* filename);
|
||||
|
||||
// Indicate that QPDFWriter should create a memory buffer to
|
||||
// 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
|
||||
// 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 };
|
||||
|
||||
void init();
|
||||
int bytesNeeded(unsigned long n);
|
||||
void writeBinary(unsigned long val, unsigned int bytes);
|
||||
void writeString(std::string const& str);
|
||||
@ -253,6 +283,7 @@ class QPDFWriter
|
||||
// clearPipelineStack is called.
|
||||
Pipeline* pushPipeline(Pipeline*);
|
||||
void activatePipelineStack();
|
||||
void initializePipelineStack(Pipeline *);
|
||||
|
||||
// Calls finish on the current pipeline and pops the pipeline
|
||||
// stack until the top of stack is a previous active top of stack,
|
||||
@ -269,6 +300,8 @@ class QPDFWriter
|
||||
char const* filename;
|
||||
FILE* file;
|
||||
bool close_file;
|
||||
Pl_Buffer* buffer_pipeline;
|
||||
Buffer* output_buffer;
|
||||
bool normalize_content_set;
|
||||
bool normalize_content;
|
||||
bool stream_data_mode_set;
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <qpdf/Pl_StdioFile.hh>
|
||||
#include <qpdf/Pl_Count.hh>
|
||||
#include <qpdf/Pl_Discard.hh>
|
||||
#include <qpdf/Pl_Buffer.hh>
|
||||
#include <qpdf/Pl_RC4.hh>
|
||||
#include <qpdf/Pl_AES_PDF.hh>
|
||||
#include <qpdf/Pl_Flate.hh>
|
||||
@ -21,32 +20,65 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
QPDFWriter::QPDFWriter(QPDF& pdf, char const* filename) :
|
||||
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)
|
||||
QPDFWriter::QPDFWriter(QPDF& pdf) :
|
||||
pdf(pdf)
|
||||
{
|
||||
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)
|
||||
{
|
||||
this->filename = "standard output";
|
||||
@ -61,19 +93,25 @@ QPDFWriter::QPDFWriter(QPDF& pdf, char const* filename) :
|
||||
fopen(filename, "wb+"));
|
||||
close_file = true;
|
||||
}
|
||||
Pipeline* p = new Pl_StdioFile("qdf output", file);
|
||||
Pipeline* p = new Pl_StdioFile("qpdf output", file);
|
||||
to_delete.push_back(p);
|
||||
pipeline = new Pl_Count("qdf count", p);
|
||||
to_delete.push_back(pipeline);
|
||||
pipeline_stack.push_back(pipeline);
|
||||
initializePipelineStack(p);
|
||||
}
|
||||
|
||||
QPDFWriter::~QPDFWriter()
|
||||
void
|
||||
QPDFWriter::setOutputMemory()
|
||||
{
|
||||
if (file && close_file)
|
||||
{
|
||||
fclose(file);
|
||||
}
|
||||
this->buffer_pipeline = new Pl_Buffer("qpdf output");
|
||||
to_delete.push_back(this->buffer_pipeline);
|
||||
initializePipelineStack(this->buffer_pipeline);
|
||||
}
|
||||
|
||||
Buffer*
|
||||
QPDFWriter::getBuffer()
|
||||
{
|
||||
Buffer* result = this->output_buffer;
|
||||
this->output_buffer = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
@ -565,6 +603,14 @@ QPDFWriter::pushPipeline(Pipeline* 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
|
||||
QPDFWriter::activatePipelineStack()
|
||||
{
|
||||
@ -1503,6 +1549,8 @@ QPDFWriter::generateObjectStreams()
|
||||
void
|
||||
QPDFWriter::write()
|
||||
{
|
||||
// XXX Check output
|
||||
|
||||
// Do preliminary setup
|
||||
|
||||
if (this->linearized)
|
||||
@ -1656,6 +1704,11 @@ QPDFWriter::write()
|
||||
fclose(this->file);
|
||||
}
|
||||
this->file = 0;
|
||||
if (this->buffer_pipeline)
|
||||
{
|
||||
this->output_buffer = this->buffer_pipeline->getBuffer();
|
||||
this->buffer_pipeline = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -584,10 +584,18 @@ void runtest(int n, char const* filename)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
QPDFWriter w(pdf, "a.pdf");
|
||||
// Exercise writing to memory buffer
|
||||
QPDFWriter w(pdf);
|
||||
w.setOutputMemory();
|
||||
w.setStaticID(true);
|
||||
w.setStreamDataMode(qpdf_s_preserve);
|
||||
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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user