Q: We uncountered a exception when using the following lines to access
Optional Content Groups in a specific PDF document:
OCG::OCMD ocmd(obj);
Obj ocgs = ocmd.GetOCGs();
We are currently working around this by catching the exception, but
can you please let us know if this is something we need to handle in
the client code.
#include <SDF/Obj.h>
#include <PDF/PDFDoc.h>
#include <PDF/OCG/OCMD.h>
#include <iostream>
using namespace pdftron;
using namespace Common;
using namespace SDF;
using namespace PDF;
using namespace std;
int main(int argc, char *argv[])
{
int ret = 0;
PDFNet::Initialize();
try
{
PDFDoc doc("c:/1.pdf");
doc.InitSecurityHandler();
if (!doc.HasOC()) {
cout << "The document does not contain 'Optional Content'"
<< endl;
}
else {
OCG::Config init_cfg = doc.GetOCGConfig();
OCG::Context ctx(init_cfg);
Page page = doc.GetPage(1); // Get the first page in the
document.
Obj page_sdfobj = page.GetResourceDict();
DictIterator sfobj_itr = page_sdfobj.Find("Properties");
DictIterator prop_itr = sfobj_itr.Value().GetDictIterator
();
Obj obj = prop_itr.Value();
OCG::Group ocg(obj);
OCG::OCMD ocmd(obj);
Obj ocgs = ocmd.GetOCGs();
if (ocgs != 0) {
int i, sz = int(ocgs.Size());
for (i=0; i<sz; ++i) {
OCG::Group ocg(ocgs.GetAt(i));
}
}
}
cout << "Done." << endl;
}
catch(Common::Exception& e)
{
cout << e << endl;
ret = 1;
}
catch(...)
{
cout << "Unknown Exception" << endl;
ret = 1;
}
PDFNet::Terminate();
return ret;
}
------------
A: According to PDF spec OCGs entry in OCMD may be a dictionary, an
array, or NULL (since this entry is optional). Therefore you should
check the type of ocgs as shown in the following below:
OCG::Group ocg(obj);
OCG::OCMD ocmd(obj);
Obj ocgs = ocmd.GetOCGs();
if (ocgs != 0) {
if (ocgs.IsDict()) {
OCG::Group ocg(ocgs);
}
else {
int i, sz = int(ocgs.Size());
for (i=0; i<sz; ++i) {
OCG::Group ocg(ocgs.GetAt(i));
}
}
}