Esempio n. 1
0
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;
}
Esempio n. 2
0
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);
    }
  }
}
Esempio n. 3
0
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;
  }
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
        }
      }
    }
  }
}
Esempio n. 10
0
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());
}