void linkLayer::loadFromDoc(PoDoFo::PdfMemDocument* doc) { qDebug() << "linkLayer: Loading named destinations ..."; try { PoDoFo::PdfNamesTree* pNames = doc->GetNamesTree( PoDoFo::ePdfDontCreateObject ); if( ! pNames ) return; PoDoFo::PdfDictionary destsDict; pNames->ToDictionary( PoDoFo::PdfName("Dests"), destsDict ); PoDoFo::TKeyMap keyMap = destsDict.GetKeys(); QString tName; PoDoFo::PdfDestination *dest; PoDoFo::PdfObject *obj; for(PoDoFo::TKeyMap::const_iterator it = keyMap.begin(); it != keyMap.end(); ++it ) { try { tName = QString::fromUtf8( it->first.GetName().c_str() ); qDebug() << "Processing "<< tName; obj = pdfUtil::resolveRefs( doc, it->second ); if ( obj->IsArray() ) dest = new PoDoFo::PdfDestination( obj ); else if ( obj->IsDictionary() ) { obj->GetDictionary().GetKey("D")->SetOwner( &doc->GetObjects() ); dest = new PoDoFo::PdfDestination( obj->GetDictionary().GetKey("D") ); } else { qDebug() << "Element is neither an array, nor a dictionary:"<< obj->GetDataTypeString(); continue; } addTarget( tName, dest ); } catch ( PoDoFo::PdfError e ) { qDebug() << "linkLayer: Error adding named destination ("<<tName<<"):"<<e.what(); } } } catch ( PoDoFo::PdfError e ) { qDebug() << "linkLayer: Error processing names tree:" << e.what(); }; qDebug() << "linkLayer: Done loading named destinations."; }
std::list<FormImage> extract(const std::string& filename, Form& form) { std::list<FormImage> images; ColorSpace colorspace; PoDoFo::pdf_int64 componentbits; PoDoFo::PdfObject* obj = nullptr; PoDoFo::PdfObject* color = nullptr; PoDoFo::PdfObject* component = nullptr; PoDoFo::PdfMemDocument document(filename.c_str()); PoDoFo::TCIVecObjects it = document.GetObjects().begin(); while (it != document.GetObjects().end()) { if ((*it)->IsDictionary()) { PoDoFo::PdfObject* objType = (*it)->GetDictionary().GetKey(PoDoFo::PdfName::KeyType); PoDoFo::PdfObject* objSubType = (*it)->GetDictionary().GetKey(PoDoFo::PdfName::KeySubtype); if ((objType && objType->IsName() && objType->GetName().GetName() == "XObject") || (objSubType && objSubType->IsName() && objSubType->GetName().GetName() == "Image" )) { // Colorspace color = (*it)->GetDictionary().GetKey(PoDoFo::PdfName("ColorSpace")); colorspace = ColorSpace::Unknown; if (color && color->IsReference()) color = document.GetObjects().GetObject(color->GetReference()); // Follow ICCBased reference to the Alternate colorspace if (color && color->IsArray() && color->GetArray().GetSize() == 2 && // First item is ICCBased color->GetArray()[0].IsName() && color->GetArray()[0].GetName().GetName() == "ICCBased" && // Second item is reference to color space color->GetArray()[1].IsReference()) { color = document.GetObjects().GetObject(color->GetArray()[1].GetReference()); if (color) color = color->GetDictionary().GetKey(PoDoFo::PdfName("Alternate")); } // Check if either RGB or Grayscale (either the specified // colorspace or the alternate if using an ICCBased colorspace) if (color && color->IsName()) { std::string col = color->GetName().GetName(); if (col == "DeviceRGB") colorspace = ColorSpace::RGB; else if (col == "DeviceGray") colorspace = ColorSpace::Gray; } // Bits per component component = (*it)->GetDictionary().GetKey(PoDoFo::PdfName("BitsPerComponent")); componentbits = 8; if (component && component->IsNumber()) componentbits = component->GetNumber(); // Stream obj = (*it)->GetDictionary().GetKey(PoDoFo::PdfName::KeyFilter); // JPEG and Flate are in another array if (obj && obj->IsArray() && obj->GetArray().GetSize() == 1 && ((obj->GetArray()[0].IsName() && obj->GetArray()[0].GetName().GetName() == "DCTDecode") || (obj->GetArray()[0].IsName() && obj->GetArray()[0].GetName().GetName() == "FlateDecode"))) obj = &obj->GetArray()[0]; Pixels pixels; if (obj && obj->IsName()) { std::string name = obj->GetName().GetName(); if (name == "DCTDecode") pixels = readPDFImage(*it, PixelType::JPG, colorspace, componentbits, filename, form); else if (name == "CCITTFaxDecode") pixels = readPDFImage(*it, PixelType::TIF, colorspace, componentbits, filename, form); // PNM is the default //else if (name == "FlateDecode") // pixels = readPDFImage(*it, PixelType::PNM, colorspace, componentbits, filename, form); else pixels = readPDFImage(*it, PixelType::PNM, colorspace, componentbits, filename, form); } else { pixels = readPDFImage(*it, PixelType::PNM, colorspace, componentbits, filename, form); } document.FreeObjectMemory(*it); if (pixels.isLoaded()) images.push_back(FormImage(form, std::move(pixels))); } } ++it; } return images; }