Use QPDFObjectHandle::getObjGen() where appropriate

In internal code and examples, replace calls to getObjectID() and
getGeneration() with calls to getObjGen() where possible.
This commit is contained in:
Jay Berkenbilt 2013-06-14 11:58:37 -04:00
parent 5039da0b91
commit 96eb965115
11 changed files with 87 additions and 68 deletions

View File

@ -9,7 +9,7 @@ static char const* whoami = 0;
static enum { st_none, st_numbers, st_lines } style = st_none;
static bool show_open = false;
static bool show_targets = false;
static std::map<int, int> page_map;
static std::map<QPDFObjGen, int> page_map;
void usage()
{
@ -50,7 +50,7 @@ void generate_page_map(QPDF& qpdf)
iter != pages.end(); ++iter)
{
QPDFObjectHandle& oh = *iter;
page_map[oh.getObjectID()] = ++n;
page_map[oh.getObjGen()] = ++n;
}
}
@ -121,10 +121,10 @@ void extract_bookmarks(QPDFObjectHandle outlines, std::vector<int>& numbers)
if ((dest.isArray()) && (dest.getArrayNItems() > 0))
{
QPDFObjectHandle first = dest.getArrayItem(0);
int object_id = first.getObjectID();
if (page_map.count(object_id))
QPDFObjGen og = first.getObjGen();
if (page_map.count(og))
{
target = QUtil::int_to_string(page_map[object_id]);
target = QUtil::int_to_string(page_map[og]);
}
}

View File

@ -34,10 +34,10 @@ class ImageInverter: public QPDFObjectHandle::StreamDataProvider
virtual void provideStreamData(int objid, int generation,
Pipeline* pipeline);
// Map [obj][gen] = image object
std::map<int, std::map<int, QPDFObjectHandle> > image_objects;
// Map [obj][gen] = image data
std::map<int, std::map<int, PointerHolder<Buffer> > > image_data;
// Map [og] = image object
std::map<QPDFObjGen, QPDFObjectHandle> image_objects;
// Map [og] = image data
std::map<QPDFObjGen, PointerHolder<Buffer> > image_data;
};
void
@ -47,7 +47,8 @@ ImageInverter::provideStreamData(int objid, int generation,
// Use the object and generation number supplied to look up the
// image data. Then invert the image data and write the inverted
// data to the pipeline.
PointerHolder<Buffer> data = this->image_data[objid][generation];
PointerHolder<Buffer> data =
this->image_data[QPDFObjGen(objid, generation)];
size_t size = data->getSize();
unsigned char* buf = data->getBuffer();
unsigned char ch;
@ -120,12 +121,11 @@ int main(int argc, char* argv[])
// Store information about the images based on the
// object and generation number. Recall that a single
// image object may be used more than once.
int objid = image.getObjectID();
int gen = image.getGeneration();
if (inv->image_objects[objid].count(gen) == 0)
QPDFObjGen og = image.getObjGen();
if (inv->image_objects.count(og) == 0)
{
inv->image_objects[objid][gen] = image;
inv->image_data[objid][gen] = image.getStreamData();
inv->image_objects[og] = image;
inv->image_data[og] = image.getStreamData();
// Register our stream data provider for this
// stream. Future calls to getStreamData or

View File

@ -159,6 +159,8 @@ class QPDF
// Retrieve an object by object ID and generation. Returns an
// indirect reference to it.
QPDF_DLL
QPDFObjectHandle getObjectByObjGen(QPDFObjGen const&);
QPDF_DLL
QPDFObjectHandle getObjectByID(int objid, int generation);
// Replace the object with the given object id with the given
@ -175,6 +177,8 @@ class QPDF
// object. To replace a reserved object, call replaceReserved
// instead.
QPDF_DLL
void replaceObject(QPDFObjGen const& og, QPDFObjectHandle);
QPDF_DLL
void replaceObject(int objid, int generation, QPDFObjectHandle);
// Swap two objects given by ID. Calling this method can have
@ -189,6 +193,8 @@ class QPDF
// to the swapped objects with new ones, possibly by calling
// getObjectByID.
QPDF_DLL
void swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2);
QPDF_DLL
void swapObjects(int objid1, int generation1,
int objid2, int generation2);
@ -623,7 +629,7 @@ class QPDF
void getAllPagesInternal(QPDFObjectHandle cur_pages,
std::vector<QPDFObjectHandle>& result);
void insertPage(QPDFObjectHandle newpage, int pos);
int findPage(int objid, int generation);
int findPage(QPDFObjGen const& og);
int findPage(QPDFObjectHandle& page);
void flattenPagesTree();
void insertPageobjToPage(QPDFObjectHandle const& obj, int pos,

View File

@ -23,6 +23,8 @@ class QPDFObjGen
QPDF_DLL
bool operator<(QPDFObjGen const&) const;
QPDF_DLL
bool operator==(QPDFObjGen const&) const;
QPDF_DLL
int getObj() const;
QPDF_DLL
int getGen() const;

View File

@ -1573,12 +1573,24 @@ QPDF::makeIndirectObject(QPDFObjectHandle oh)
this, next.getObj(), next.getGen());
}
QPDFObjectHandle
QPDF::getObjectByObjGen(QPDFObjGen const& og)
{
return getObjectByID(og.getObj(), og.getGen());
}
QPDFObjectHandle
QPDF::getObjectByID(int objid, int generation)
{
return QPDFObjectHandle::Factory::newIndirect(this, objid, generation);
}
void
QPDF::replaceObject(QPDFObjGen const& og, QPDFObjectHandle oh)
{
replaceObject(og.getObj(), og.getGen(), oh);
}
void
QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
{
@ -1604,9 +1616,7 @@ QPDF::replaceReserved(QPDFObjectHandle reserved,
{
QTC::TC("qpdf", "QPDF replaceReserved");
reserved.assertReserved();
replaceObject(reserved.getObjectID(),
reserved.getGeneration(),
replacement);
replaceObject(reserved.getObjGen(), replacement);
}
QPDFObjectHandle
@ -1663,14 +1673,13 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign, bool allow_page)
replaceForeignIndirectObjects(to_copy, obj_copier, true);
if (! to_copy.isStream())
{
QPDFObjGen og(to_copy.getObjectID(), to_copy.getGeneration());
QPDFObjGen og(to_copy.getObjGen());
replaceReserved(obj_copier.object_map[og], copy);
}
}
obj_copier.to_copy.clear();
return obj_copier.object_map[QPDFObjGen(foreign.getObjectID(),
foreign.getGeneration())];
return obj_copier.object_map[foreign.getObjGen()];
}
void
@ -1697,7 +1706,7 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier,
if (foreign.isIndirect())
{
QPDFObjGen foreign_og(foreign.getObjectID(), foreign.getGeneration());
QPDFObjGen foreign_og(foreign.getObjGen());
if (obj_copier.visiting.find(foreign_og) != obj_copier.visiting.end())
{
QTC::TC("qpdf", "QPDF loop reserving objects");
@ -1750,7 +1759,7 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier,
if (foreign.isIndirect())
{
QPDFObjGen foreign_og(foreign.getObjectID(), foreign.getGeneration());
QPDFObjGen foreign_og(foreign.getObjGen());
obj_copier.visiting.erase(foreign_og);
}
}
@ -1763,7 +1772,7 @@ QPDF::replaceForeignIndirectObjects(
if ((! top) && foreign.isIndirect())
{
QTC::TC("qpdf", "QPDF replace indirect");
QPDFObjGen foreign_og(foreign.getObjectID(), foreign.getGeneration());
QPDFObjGen foreign_og(foreign.getObjGen());
std::map<QPDFObjGen, QPDFObjectHandle>::iterator mapping =
obj_copier.object_map.find(foreign_og);
if (mapping == obj_copier.object_map.end())
@ -1807,7 +1816,7 @@ QPDF::replaceForeignIndirectObjects(
else if (foreign.isStream())
{
QTC::TC("qpdf", "QPDF replace stream");
QPDFObjGen foreign_og(foreign.getObjectID(), foreign.getGeneration());
QPDFObjGen foreign_og(foreign.getObjGen());
result = obj_copier.object_map[foreign_og];
result.assertStream();
QPDFObjectHandle dict = result.getDict();
@ -1826,7 +1835,7 @@ QPDF::replaceForeignIndirectObjects(
this->copied_stream_data_provider = new CopiedStreamDataProvider();
this->copied_streams = this->copied_stream_data_provider;
}
QPDFObjGen local_og(result.getObjectID(), result.getGeneration());
QPDFObjGen local_og(result.getObjGen());
this->copied_stream_data_provider->registerForeignStream(
local_og, foreign);
result.replaceStreamData(this->copied_streams,
@ -1848,6 +1857,12 @@ QPDF::replaceForeignIndirectObjects(
return result;
}
void
QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2)
{
swapObjects(og1.getObj(), og1.getGen(), og2.getObj(), og2.getGen());
}
void
QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2)
{
@ -2101,8 +2116,7 @@ QPDF::findAttachmentStreams()
item.getKey("/EF").getKey("/F").isStream())
{
QPDFObjectHandle stream = item.getKey("/EF").getKey("/F");
this->attachment_streams.insert(
QPDFObjGen(stream.getObjectID(), stream.getGeneration()));
this->attachment_streams.insert(stream.getObjGen());
}
}
}

View File

@ -13,6 +13,12 @@ QPDFObjGen::operator<(QPDFObjGen const& rhs) const
((this->obj == rhs.obj) && (this->gen < rhs.gen)));
}
bool
QPDFObjGen::operator==(QPDFObjGen const& rhs) const
{
return ((this->obj == rhs.obj) && (this->gen == rhs.gen));
}
int
QPDFObjGen::getObj() const
{

View File

@ -336,9 +336,7 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
QTC::TC("qpdf", "QPDF hint table length indirect");
// Force resolution
(void) length_obj.getIntValue();
ObjCache& oc = this->obj_cache
[QPDFObjGen(length_obj.getObjectID(),
length_obj.getGeneration())];
ObjCache& oc = this->obj_cache[length_obj.getObjGen()];
min_end_offset = oc.end_before_space;
max_end_offset = oc.end_after_space;
}
@ -499,7 +497,7 @@ QPDF::checkLinearizationInternal()
for (int i = 0; i < npages; ++i)
{
QPDFObjectHandle const& page = pages[i];
QPDFObjGen og(page.getObjectID(), page.getGeneration());
QPDFObjGen og(page.getObjGen());
if (this->xref_table[og].getType() == 2)
{
errors.push_back("page dictionary for page " +
@ -582,7 +580,7 @@ QPDF::checkLinearizationInternal()
for (std::vector<QPDFObjectHandle>::iterator iter = this->part6.begin();
iter != this->part6.end(); ++iter)
{
QPDFObjGen og((*iter).getObjectID(), (*iter).getGeneration());
QPDFObjGen og((*iter).getObjGen());
// All objects have to have been dereferenced to be classified.
assert(this->obj_cache.count(og) > 0);
ObjCache const& oc = this->obj_cache[og];
@ -740,7 +738,7 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
unsigned int npages = pages.size();
int table_offset = adjusted_offset(
this->page_offset_hints.first_page_offset);
QPDFObjGen first_page_og(pages[0].getObjectID(), pages[0].getGeneration());
QPDFObjGen first_page_og(pages[0].getObjGen());
assert(this->xref_table.count(first_page_og) > 0);
int offset = getLinearizationOffset(first_page_og);
if (table_offset != offset)
@ -750,8 +748,7 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
for (unsigned int pageno = 0; pageno < npages; ++pageno)
{
QPDFObjGen page_og(pages[pageno].getObjectID(),
pages[pageno].getGeneration());
QPDFObjGen page_og(pages[pageno].getObjGen());
int first_object = page_og.getObj();
assert(this->xref_table.count(page_og) > 0);
offset = getLinearizationOffset(page_og);
@ -961,7 +958,7 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
{
// Check length and offset. Acrobat gets these wrong.
QPDFObjectHandle outlines = getRoot().getKey("/Outlines");
QPDFObjGen og(outlines.getObjectID(), outlines.getGeneration());
QPDFObjGen og(outlines.getObjGen());
assert(this->xref_table.count(og) > 0);
int offset = getLinearizationOffset(og);
ObjUser ou(ObjUser::ou_root_key, "/Outlines");
@ -1466,7 +1463,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// will do the same.
// First, place the actual first page object itself.
QPDFObjGen first_page_og(pages[0].getObjectID(), pages[0].getGeneration());
QPDFObjGen first_page_og(pages[0].getObjGen());
if (! lc_first_page_private.count(first_page_og))
{
throw std::logic_error(
@ -1515,7 +1512,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
{
// Place this page's page object
QPDFObjGen page_og(pages[i].getObjectID(), pages[i].getGeneration());
QPDFObjGen page_og(pages[i].getObjGen());
if (! lc_other_page_private.count(page_og))
{
throw std::logic_error(
@ -1598,7 +1595,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
if (! thumb.isNull())
{
// Output the thumbnail itself
QPDFObjGen thumb_og(thumb.getObjectID(), thumb.getGeneration());
QPDFObjGen thumb_og(thumb.getObjGen());
if (lc_thumbnail_private.count(thumb_og))
{
lc_thumbnail_private.erase(thumb_og);
@ -1753,7 +1750,7 @@ QPDF::pushOutlinesToPart(
return;
}
outlines = getUncompressedObject(outlines, object_stream_data);
QPDFObjGen outlines_og(outlines.getObjectID(), outlines.getGeneration());
QPDFObjGen outlines_og(outlines.getObjGen());
QTC::TC("qpdf", "QPDF lin outlines in part",
((&part == (&this->part6)) ? 0
: (&part == (&this->part9)) ? 1

View File

@ -115,7 +115,7 @@ QPDF::optimize(std::map<int, int> const& object_stream_data,
}
ObjUser root_ou = ObjUser(ObjUser::ou_root);
QPDFObjGen root_og = QPDFObjGen(root.getObjectID(), root.getGeneration());
QPDFObjGen root_og = QPDFObjGen(root.getObjGen());
obj_user_to_objects[root_ou].insert(root_og);
object_to_obj_users[root_og].insert(root_ou);
@ -338,7 +338,7 @@ QPDF::updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh,
if (oh.isIndirect())
{
QPDFObjGen og(oh.getObjectID(), oh.getGeneration());
QPDFObjGen og(oh.getObjGen());
if (visited.count(og))
{
QTC::TC("qpdf", "QPDF opt loop detected");

View File

@ -127,7 +127,7 @@ void
QPDF::insertPageobjToPage(QPDFObjectHandle const& obj, int pos,
bool check_duplicate)
{
QPDFObjGen og(obj.getObjectID(), obj.getGeneration());
QPDFObjGen og(obj.getObjGen());
if (check_duplicate)
{
if (! this->pageobj_to_pages_pos.insert(std::make_pair(og, pos)).second)
@ -214,8 +214,7 @@ QPDF::removePage(QPDFObjectHandle page)
pages.replaceKey("/Count", QPDFObjectHandle::newInteger(npages));
this->all_pages.erase(this->all_pages.begin() + pos);
assert(this->all_pages.size() == static_cast<size_t>(npages));
this->pageobj_to_pages_pos.erase(
QPDFObjGen(page.getObjectID(), page.getGeneration()));
this->pageobj_to_pages_pos.erase(page.getObjGen());
assert(this->pageobj_to_pages_pos.size() == static_cast<size_t>(npages));
for (int i = pos; i < npages; ++i)
{
@ -253,18 +252,18 @@ int
QPDF::findPage(QPDFObjectHandle& page)
{
page.assertPageObject();
return findPage(page.getObjectID(), page.getGeneration());
return findPage(page.getObjGen());
}
int
QPDF::findPage(int objid, int generation)
QPDF::findPage(QPDFObjGen const& og)
{
flattenPagesTree();
std::map<QPDFObjGen, int>::iterator it =
this->pageobj_to_pages_pos.find(QPDFObjGen(objid, generation));
this->pageobj_to_pages_pos.find(og);
if (it == this->pageobj_to_pages_pos.end())
{
setLastObjectDescription("page object", objid, generation);
setLastObjectDescription("page object", og.getObj(), og.getGen());
throw QPDFExc(qpdf_e_pages, this->file->getName(),
this->last_object_description, 0,
"page object not referenced in /Pages tree");

View File

@ -1621,8 +1621,7 @@ int main(int argc, char* argv[])
{
if (selected_from_orig.count(pageno) == 0)
{
pdf.replaceObject(orig_pages[pageno].getObjectID(),
orig_pages[pageno].getGeneration(),
pdf.replaceObject(orig_pages[pageno].getObjGen(),
QPDFObjectHandle::newNull());
}
}

View File

@ -659,8 +659,7 @@ void runtest(int n, char const* filename1, char const* arg2)
" not called 4-page file");
}
// Swap pages 2 and 3
pdf.swapObjects(pages[1].getObjectID(), pages[1].getGeneration(),
pages[2].getObjectID(), pages[2].getGeneration());
pdf.swapObjects(pages[1].getObjGen(), pages[2].getObjGen());
// Replace object and swap objects
QPDFObjectHandle trailer = pdf.getTrailer();
QPDFObjectHandle qdict = trailer.getKey("/QDict");
@ -672,21 +671,18 @@ void runtest(int n, char const* filename1, char const* arg2)
try
{
// Do it wrong first...
pdf.replaceObject(qdict.getObjectID(), qdict.getGeneration(),
qdict);
pdf.replaceObject(qdict.getObjGen(), qdict);
}
catch (std::logic_error)
{
std::cout << "caught logic error as expected" << std::endl;
}
pdf.replaceObject(qdict.getObjectID(), qdict.getGeneration(),
new_dict);
pdf.replaceObject(qdict.getObjGen(), new_dict);
// Now qdict still points to the old dictionary
std::cout << "old dict: " << qdict.getKey("/Dict").getIntValue()
<< std::endl;
// Swap dict and array
pdf.swapObjects(qdict.getObjectID(), qdict.getGeneration(),
qarray.getObjectID(), qarray.getGeneration());
pdf.swapObjects(qdict.getObjGen(), qarray.getObjGen());
// Now qarray will resolve to new object but qdict is still
// the old object
std::cout << "old dict: " << qdict.getKey("/Dict").getIntValue()
@ -694,7 +690,7 @@ void runtest(int n, char const* filename1, char const* arg2)
std::cout << "new dict: " << qarray.getKey("/NewDict").getIntValue()
<< std::endl;
// Reread qdict, now pointing to an array
qdict = pdf.getObjectByID(qdict.getObjectID(), qdict.getGeneration());
qdict = pdf.getObjectByObjGen(qdict.getObjGen());
std::cout << "swapped array: " << qdict.getArrayItem(0).getName()
<< std::endl;
@ -788,14 +784,14 @@ void runtest(int n, char const* filename1, char const* arg2)
pdf.addPage(new_pages[0], true);
checkPageContents(pages[0], "New page 1");
pdf.addPageAt(new_pages[1], true, pages[0]);
assert(pages[0].getObjectID() == new_pages[1].getObjectID());
assert(pages[0].getObjGen() == new_pages[1].getObjGen());
pdf.addPageAt(new_pages[2], true, pages[5]);
assert(pages[5].getObjectID() == new_pages[2].getObjectID());
assert(pages[5].getObjGen() == new_pages[2].getObjGen());
pdf.addPageAt(new_pages[3], false, pages[5]);
assert(pages[6].getObjectID() == new_pages[3].getObjectID());
assert(pages[6].getObjGen() == new_pages[3].getObjGen());
assert(pages.size() == 11);
pdf.addPage(new_pages[4], false);
assert(pages[11].getObjectID() == new_pages[4].getObjectID());
assert(pages[11].getObjGen() == new_pages[4].getObjGen());
pdf.addPageAt(new_pages[5], false, pages.back());
assert(pages.size() == 13);
checkPageContents(pages[0], "New page 0");
@ -835,7 +831,7 @@ void runtest(int n, char const* filename1, char const* arg2)
assert(all_pages.size() == 10);
pdf.updateAllPagesCache();
assert(all_pages.size() == 11);
assert(all_pages.back().getObjectID() == page.getObjectID());
assert(all_pages.back().getObjGen() == page.getObjGen());
QPDFWriter w(pdf, "a.pdf");
w.setStaticID(true);
@ -862,7 +858,7 @@ void runtest(int n, char const* filename1, char const* arg2)
pdf.removePage(page5);
pdf.addPage(page5, false);
assert(pages.size() == 10);
assert(pages.back().getObjectID() == page5.getObjectID());
assert(pages.back().getObjGen() == page5.getObjGen());
QPDFWriter w(pdf, "a.pdf");
w.setStaticID(true);