bool OCGs::optContentIsVisible( Object *dictRef ) { Object dictObj; Dict *dict; Object dictType; Object ocg; Object policy; bool result = true; dictRef->fetch( m_xref, &dictObj ); if ( ! dictObj.isDict() ) { error(-1, "Unexpected oc reference target: %i", dictObj.getType() ); dictObj.free(); return result; } dict = dictObj.getDict(); // printf("checking if optContent is visible\n"); dict->lookup("Type", &dictType); if (dictType.isName("OCMD")) { // If we supported Visibility Expressions, we'd check // for a VE entry, and then call out to the parser here... // printf("found OCMD dict\n"); dict->lookup("P", &policy); dict->lookupNF("OCGs", &ocg); if (ocg.isArray()) { if (policy.isName("AllOn")) { result = allOn( ocg.getArray() ); } else if (policy.isName("AllOff")) { result = allOff( ocg.getArray() ); } else if (policy.isName("AnyOff")) { result = anyOff( ocg.getArray() ); } else if ( (!policy.isName()) || (policy.isName("AnyOn") ) ) { // this is the default result = anyOn( ocg.getArray() ); } } else if (ocg.isRef()) { OptionalContentGroup* oc = findOcgByRef( ocg.getRef() ); if ( !oc || oc->getState() == OptionalContentGroup::Off ) { result = false; } else { result = true ; } } ocg.free(); policy.free(); } else if ( dictType.isName("OCG") ) { OptionalContentGroup* oc = findOcgByRef( dictRef->getRef() ); if ( !oc || oc->getState() == OptionalContentGroup::Off ) { result=false; } } dictType.free(); dictObj.free(); // printf("visibility: %s\n", result? "on" : "off"); return result; }
void PDFFormat::init(std::string& filename){ PDFDoc *doc = PDFDocFactory().createPDFDoc(GooString(filename.c_str())); //GBool enc = doc->isEncrypted(); GooString ID; Object obj,id_obj; Dict* trailer = doc->getXRef()->getTrailerDict()->getDict(); trailer->lookupNF("ID",&obj); obj.getArray()->getNF(0,&id_obj); data.ID1.assign(id_obj.getString()->getCString(),16); obj.getArray()->getNF(1,&id_obj); data.ID2.assign(id_obj.getString()->getCString(),16); GBool enc = trailer->hasKey("Encrypt"); if(enc){ is_encrypted = true; trailer->lookupNF("Encrypt",&obj); Object encObj; doc->getXRef()->fetch(obj.getRef().num,obj.getRef().gen,&encObj); encObj.getDict()->lookupNF("Filter",&obj); encObj.getDict()->lookupNF("R",&obj); this->data.R = obj.getInt(); encObj.getDict()->lookupNF("V",&obj); this->data.V = obj.getInt(); encObj.getDict()->lookupNF("P",&obj); this->data.P = obj.getInt(); encObj.getDict()->lookupNF("Length",&obj); this->data.length = obj.getInt(); encObj.getDict()->lookupNF("O",&obj); if ((int)this->data.R <= 4) { /* Revision 4 or less => 32Byte O string */ this->data.O.assign(obj.getString()->getCString(),32); } else { /* Revision 5 or 6 => 48Byte O string */ this->data.O.assign(obj.getString()->getCString(),48); ::memcpy(this->data.O_valid_salt, this->data.O.substr(32, 8).c_str(), 8); ::memcpy(this->data.O_key_salt, this->data.O.substr(40, 8).c_str(), 8); this->data.O.resize(32); } encObj.getDict()->lookupNF("U",&obj); if ((int)this->data.R <= 4) { /* Revision 4 or less => 32Byte U string */ this->data.U.assign(obj.getString()->getCString(),32); } else { /* Revision 5 or 6 => 48Byte U string */ this->data.U.assign(obj.getString()->getCString(),48); ::memcpy(this->data.U_valid_salt, this->data.U.substr(32, 8).c_str(), 8); ::memcpy(this->data.U_key_salt, this->data.U.substr(40, 8).c_str(), 8); this->data.U.resize(32); } if(encObj.getDict()->hasKey("EncryptMetadata")){ encObj.getDict()->lookupNF("EncryptMetadata", &obj); this->data.MetaEncrypted = obj.getBool(); } int v_major = doc->getPDFMajorVersion(); int v_minor = doc->getPDFMinorVersion(); if (verbose) { // Print PDF encryption information from EncObj std::cout << "======= PDF information =======" << std::endl; std::cout << "PDF version: " << v_major << "." << v_minor << std::endl; if ((int)this->data.R == 5) { std::cout << "Extension level 3 detected." << std::endl; } else if ((int)this->data.R == 6) { std::cout << "Extension level 5 detected." << std::endl; } else if ((int)this->data.R > 6) { std::cout << "Warning: Unknown (unsupported) security revision!" << std::endl; } std::cout << "Security revision: " << (int)this->data.R << std::endl; std::cout << "Encryption alg. version: " << (int)this->data.V << std::endl; std::cout << "Key length: " << (int)this->data.length << std::endl; std::cout << "Metadata encrypted: "; if (this->data.MetaEncrypted) { std::cout << "yes"; } else { std::cout << "no"; } std::cout << std::endl; std::cout << "===============================" << std::endl; } }else{ is_encrypted = false; } is_supported = true; }