wxPdfArrayDouble* wxPdfParser::GetPageBox(wxPdfDictionary* page, const wxString& boxIndex) { wxPdfArrayDouble* pageBox = NULL; wxPdfArray* box = (wxPdfArray*) ResolveObject(page->Get(boxIndex)); if (box == NULL) { wxPdfDictionary* parent = (wxPdfDictionary*) ResolveObject(page->Get(_T("/Parent"))); if (parent != NULL) { pageBox = GetPageBox(parent, boxIndex); delete parent; } } else { pageBox = new wxPdfArrayDouble(); size_t j; for (j = 0; j < box->GetSize(); j++) { wxPdfNumber* item = (wxPdfNumber*) box->Get(j); pageBox->Add(item->GetValue()); } } return pageBox; }
void wxPdfParser::GetPageContent(wxPdfObject* contentRef, wxArrayPtrVoid& contents) { int type = contentRef->GetType(); if (type == OBJTYPE_INDIRECT) { wxPdfObject* content = ResolveObject(contentRef); if (content->GetType() == OBJTYPE_ARRAY) { GetPageContent(content, contents); delete content; } else { contents.Add(content); } } else if (type == OBJTYPE_ARRAY) { wxPdfArray* contentArray = (wxPdfArray*) contentRef; size_t n = contentArray->GetSize(); size_t j; for (j = 0; j < n; j++) { GetPageContent(contentArray->Get(j), contents); } } }
void wxPdfParser::GetStreamBytesRaw(wxPdfStream* stream) { wxPdfNumber* streamLength = (wxPdfNumber*) ResolveObject(stream->Get(_T("/Length"))); size_t size = streamLength->GetInt(); m_tokens->Seek(stream->GetOffset()); wxMemoryOutputStream* memoryBuffer = NULL; wxMemoryOutputStream* streamBuffer = m_tokens->ReadBuffer(size); if (m_encrypted && size > 0) { wxMemoryInputStream inData(*streamBuffer); delete streamBuffer; memoryBuffer = new wxMemoryOutputStream(); unsigned char* buffer = new unsigned char[size]; inData.Read(buffer, size); if (inData.LastRead() == size) { m_decryptor->Encrypt(m_objNum, m_objGen, buffer, size); memoryBuffer->Write(buffer, size); } delete [] buffer; memoryBuffer->Close(); } else { memoryBuffer = streamBuffer; } stream->SetBuffer(memoryBuffer); if (streamLength->IsIndirect()) { delete streamLength; } }
bool wxPdfParser::GetSourceInfo(wxPdfInfo& info) { bool ok = false; wxPdfDictionary* infoDict = (wxPdfDictionary*) ResolveObject(m_trailer->Get(_T("/Info"))); if (infoDict != NULL && infoDict->GetType() == OBJTYPE_DICTIONARY) { typedef void (wxPdfInfo::*InfoSetter) (const wxString& value); const wxChar* entryList[] = { _T("/Title"), _T("/Author"), _T("/Subject"), _T("/Keywords"), _T("/Creator"), _T("/Producer"), _T("/CreationDate"), _T("/ModDate"), NULL }; //, "Trapped") InfoSetter entryFunc[] = { &wxPdfInfo::SetTitle, &wxPdfInfo::SetAuthor, &wxPdfInfo::SetSubject, &wxPdfInfo::SetKeywords, &wxPdfInfo::SetCreator, &wxPdfInfo::SetProducer, &wxPdfInfo::SetCreationDate, &wxPdfInfo::SetModDate, NULL }; wxString value; size_t j; for (j = 0; entryList[j] != NULL; j++) { wxPdfString* entry = (wxPdfString*) infoDict->Get(entryList[j]); if (entry != NULL) { value = entry->GetValue(); #if wxUSE_UNICODE if ((value.Length() >= 2) && (value.GetChar(0) == 254) && (value.GetChar(1) == 255)) { wxMBConvUTF16BE conv; size_t k; size_t len = value.Length()-2; char* mbstr = new char[len+2]; for (k = 0; k < len; k++) { mbstr[k] = value.GetChar(k+2); } mbstr[len] = 0; mbstr[len+1] = 0; value = conv.cMB2WC(mbstr); delete [] mbstr; } #endif (info.*entryFunc[j])(value); } } if (infoDict->IsIndirect()) { delete infoDict; } ok = true; } return ok; }
bool wxPdfParser::ParseDocument() { bool ok = false; m_fileSize = m_tokens->GetLength(); m_pdfVersion = m_tokens->CheckPdfHeader(); if (m_pdfVersion != wxEmptyString) { if (ParseXRef()) { if (SetupDecryptor()) { m_root = (wxPdfDictionary*) m_trailer->Get(_T("/Root")); m_root = (wxPdfDictionary*) ResolveObject(m_root); if (m_root != NULL) { wxPdfName* versionEntry = (wxPdfName*) ResolveObject(m_root->Get(_T("/Version"))); if (versionEntry != NULL) { wxString version = versionEntry->GetName(); version = version.Mid(1, 3); if (m_pdfVersion < version) { m_pdfVersion = version; } if (versionEntry->IsIndirect()) { delete versionEntry; } } wxPdfDictionary* pages = (wxPdfDictionary*) ResolveObject(m_root->Get(_T("/Pages"))); ok = ParsePageTree(pages); delete pages; } } } } return ok; }
bool wxPdfParser::ParsePageTree(wxPdfDictionary* pages) { bool ok = false; // Get the kids dictionary wxPdfArray* kids = (wxPdfArray*) ResolveObject(pages->Get(_T("/Kids"))); if (kids != NULL) { size_t nKids = kids->GetSize(); size_t j; ok = true; for (j = 0; j < nKids; j++) { wxPdfDictionary* page = (wxPdfDictionary*) ResolveObject(kids->Get(j)); wxPdfName* type = (wxPdfName*) page->Get(_T("/Type")); if (type->GetName() == _T("/Pages")) { // If one of the kids is an embedded // /Pages array, resolve it as well. ok = ok && ParsePageTree(page); delete page; } else { m_pages.Add(page); } } if (kids->IsIndirect()) { delete kids; } } else { wxLogError(_("wxPdfParser::ParsePageTree: Cannot find /Kids in current /Page-Dictionary")); } return ok; }
wxPdfObject* wxPdfParser::GetPageResources(wxPdfObject* page) { wxPdfObject* resources = NULL; wxPdfDictionary* dic = (wxPdfDictionary*) ResolveObject(page); // If the current object has a resources dictionary associated with it, // we use it. Otherwise, we move back to its parent object. wxPdfObject* resourceRef = ResolveObject(dic->Get(_T("/Resources"))); if (resourceRef != NULL) { resources = ResolveObject(resourceRef); } else { wxPdfObject* parent = ResolveObject(dic->Get(_T("/Parent"))); if (parent != NULL) { resources = GetPageResources(parent); delete parent; } } return resources; }
bool wxPdfParser::SetupDecryptor() { bool ok = true; wxPdfObject* encDic = m_trailer->Get(_T("/Encrypt")); if (encDic == NULL || encDic->GetType() == OBJTYPE_NULL) { return true; } wxPdfDictionary* enc = (wxPdfDictionary*) ResolveObject(encDic); wxPdfObject* obj; wxPdfArray* documentIDs = (wxPdfArray*) ResolveObject(m_trailer->Get(_T("/ID"))); wxString documentID; if (documentIDs != NULL) { obj = (wxPdfObject*) documentIDs->Get(0); if (obj->GetType() == OBJTYPE_STRING) { documentID = ((wxPdfString*) obj)->GetValue(); } if (documentIDs->IsIndirect()) { delete documentIDs; } } wxString uValue = wxEmptyString; obj = enc->Get(_T("/U")); if (obj->GetType() == OBJTYPE_STRING) { uValue = ((wxPdfString*) obj)->GetValue(); if (uValue.Length() != 32) { wxLogError(_T("wxPdfParser::SetupDecryptor: Invalid length of U value.")); ok = false; } } wxString oValue = wxEmptyString; obj = enc->Get(_T("/O")); if (obj->GetType() == OBJTYPE_STRING) { oValue = ((wxPdfString*) obj)->GetValue(); if (oValue.Length() != 32) { wxLogError(_T("wxPdfParser::SetupDecryptor: Invalid length of O value.")); ok = false; } } int rValue = 0; obj = enc->Get(_T("/R")); if (obj->GetType() == OBJTYPE_NUMBER) { rValue = ((wxPdfNumber*) obj)->GetInt(); if (rValue != 2 && rValue != 3) { wxLogError(_T("wxPdfParser::SetupDecryptor: Unknown encryption type (%d)."), rValue); ok = false; } } else { wxLogError(_T("wxPdfParser::SetupDecryptor: Illegal R value.")); ok = false; } int vValue = 0; obj = enc->Get(_T("/V")); if (obj != NULL && obj->GetType() == OBJTYPE_NUMBER) { vValue = ((wxPdfNumber*) obj)->GetInt(); if (!((rValue == 2 && vValue == 1) || (rValue == 3 && vValue == 2))) { wxLogError(_T("wxPdfParser::SetupDecryptor: Unsupported V value.")); ok = false; } } else { wxLogError(_T("wxPdfParser::SetupDecryptor: Illegal V value.")); ok = false; } int pValue = 0; obj = enc->Get(_T("/P")); if (obj->GetType() == OBJTYPE_NUMBER) { pValue = ((wxPdfNumber*) obj)->GetInt(); // Check required permissions (Applications MUST respect the permission settings) if ((pValue & REQUIRED_PERMISSIONS) != REQUIRED_PERMISSIONS) { wxLogError(_T("wxPdfParser::SetupDecryptor: Import of document not allowed due to missing permissions.")); ok = false; } } else { wxLogError(_T("wxPdfParser::SetupDecryptor: Illegal P value.")); ok = false; } int lengthValue = 40; // Default for revisison 2 if (rValue == 3) { // Get the key length if revision is 3 obj = enc->Get(_T("/Length")); if (obj->GetType() == OBJTYPE_NUMBER) { lengthValue = ((wxPdfNumber*) obj)->GetInt(); if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) { wxLogError(_T("wxPdfParser::SetupDecryptor: Illegal Length value.")); ok = false; } } else { wxLogError(_T("wxPdfParser::SetupDecryptor: Illegal Length value.")); ok = false; } } if (enc->IsIndirect()) { delete enc; } if (ok) { m_encrypted = true; m_decryptor = new wxPdfEncrypt(); if (!m_decryptor->Authenticate(documentID, m_password, uValue, oValue, pValue, lengthValue, rValue)) { wxLogError(_T("wxPdfParser::SetupDecryptor: Bad password.")); ok = false; } } return ok; }
void wxPdfParser::GetStreamBytes(wxPdfStream* stream) { GetStreamBytesRaw(stream); // Do not decode the content of resource object streams if (m_useRawStream) return; // Check whether the stream buffer is empty wxMemoryOutputStream* osIn = stream->GetBuffer(); if (osIn->GetLength() == 0) return; size_t j; wxArrayPtrVoid filters; wxPdfObject* filter = ResolveObject(stream->Get(_T("/Filter"))); if (filter != NULL) { int type = filter->GetType(); if (type == OBJTYPE_NAME) { filters.Add(filter); } else if (type == OBJTYPE_ARRAY) { wxPdfArray* filterArray = (wxPdfArray*) filter; size_t size = filterArray->GetSize(); for (j = 0; j < size; j++) { filters.Add(filterArray->Get(j)); } } // Read decode parameters if available wxArrayPtrVoid dp; wxPdfObject* dpo = ResolveObject(stream->Get(_T("/DecodeParms"))); if (dpo == NULL || (dpo->GetType() != OBJTYPE_DICTIONARY && dpo->GetType() != OBJTYPE_ARRAY)) { dpo = ResolveObject(stream->Get(_T("/DP"))); } if (dpo != NULL) { if (dpo->GetType() == OBJTYPE_DICTIONARY) { dp.Add(dpo); } else if (dpo->GetType() == OBJTYPE_ARRAY) { wxPdfArray* dpArray = (wxPdfArray*) dpo; size_t size = dpArray->GetSize(); for (j = 0; j < size; j++) { dp.Add(dpArray->Get(j)); } } } wxPdfObject* dicParam = NULL; wxMemoryOutputStream* osOut = NULL; for (j = 0; j < filters.GetCount(); j++) { osIn = stream->GetBuffer(); wxPdfName* name = (wxPdfName*) filters[j]; if (name->GetName() == _T("/FlateDecode") || name->GetName() == _T("/Fl")) { osOut = FlateDecode(osIn); if (j < dp.GetCount()) { wxMemoryOutputStream* osIn2 = osOut; dicParam = (wxPdfObject*) dp[j]; osOut = DecodePredictor(osIn2, dicParam); if (osOut != osIn2) { delete osIn2; } } } else if(name->GetName() == _T("/ASCIIHexDecode") || name->GetName() == _T("/AHx")) { osOut = ASCIIHexDecode(osIn); } else if(name->GetName() == _T("/ASCII85Decode") || name->GetName() == _T("/A85")) { osOut = ASCII85Decode(osIn); } else if(name->GetName() == _T("/LZWDecode")) { osOut = LZWDecode(osIn); if (j < dp.GetCount()) { wxMemoryOutputStream* osIn2 = osOut; dicParam = (wxPdfObject*) dp[j]; osOut = DecodePredictor(osIn2, dicParam); if (osOut != osIn2) { delete osIn2; } } } else { wxLogError(wxString(_T("wxPdfParser::GetStreamBytes: Filter '")) + name->GetName() + wxString(_T("' not supported"))); } if (osOut != NULL) { stream->SetBuffer(osOut); if (osIn != osOut) { delete osIn; } } } } }
wxPdfObject* wxPdfParser::ParseObjectStream(wxPdfStream* objStm, int idx) { wxPdfObject* obj = NULL; wxPdfNumber* firstNumber = (wxPdfNumber*) ResolveObject(objStm->Get(_T("/First"))); int first = firstNumber->GetInt(); if (objStm->GetBuffer() == NULL) { bool saveUseRawStream = m_useRawStream; m_useRawStream = false; GetStreamBytes(objStm); m_useRawStream = saveUseRawStream; } bool saveEncrypted = m_encrypted; m_encrypted = false; wxPdfTokenizer* saveTokens = m_tokens; wxMemoryInputStream objStream(*(objStm->GetBuffer())); m_tokens = new wxPdfTokenizer(&objStream); int address = 0; bool ok = true; if (!objStm->HasObjOffsets()) { // Read object offsets wxArrayInt* objOffsets = objStm->GetObjOffsets(); int objCount = idx + 1; if (m_cacheObjects) { wxPdfNumber* objCountNumber = (wxPdfNumber*) ResolveObject(objStm->Get(_T("/N"))); objCount = objCountNumber->GetInt(); } int offset; int k; for (k = 0; k < objCount; ++k) { ok = m_tokens->NextToken(); if (!ok) break; if (m_tokens->GetTokenType() != TOKEN_NUMBER) { ok = false; break; } ok = m_tokens->NextToken(); if (!ok) break; if (m_tokens->GetTokenType() != TOKEN_NUMBER) { ok = false; break; } offset = m_tokens->GetIntValue() + first; if (m_cacheObjects) { objOffsets->Add(offset); } if (k == idx) { address = offset; } } if (ok) { objStm->SetHasObjOffsets(m_cacheObjects); } } else { address = objStm->GetObjOffset(idx); ok = (address > 0); } if (ok) { m_tokens->Seek(address); obj = ParseObject(); } else { wxLogError(_T("wxPdfParser::ParseOneObjStm: Error reading ObjStm.")); } delete m_tokens; m_tokens = saveTokens; m_encrypted = saveEncrypted; return obj; }
UClass* FStringClassReference::ResolveClass() const { return dynamic_cast<UClass*>(ResolveObject()); }