Example #1
0
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;
}
Example #2
0
void AnnotWriter::UpdateBePDFAcroForm() {
	if (mWrittenFonts.empty()) return;

	Object acroForm;
	Object oldDR;

	acroForm.initDict(mXRef);
	oldDR.initNull();

	if (is_empty_ref(mBePDFAcroForm->GetRef())) {
		Ref fieldsRef = mXRefTable.GetNewRef(xrefEntryUncompressed);
		// create empty array for fields
		Object fields;
		fields.initArray(mXRef);
		WriteObject(fieldsRef, &fields);
		fields.free();

		// create new BePDFAcroForm
		mBePDFAcroFormRef = mXRefTable.GetNewRef(xrefEntryUncompressed);
		AddName(&acroForm, "Type", "BePDFAcroForm");
		AddRef(&acroForm, "Fields", fieldsRef);
	} else {
		// copy existing BePDFAcroForm except DR
		mBePDFAcroFormRef = mBePDFAcroForm->GetRef();
		Object ref;
		Object oldForm;
		ref.initRef(mBePDFAcroFormRef.num, mBePDFAcroFormRef.gen);
		ref.fetch(mXRef, &oldForm);
		CopyDict(&oldForm, &acroForm, acroFormExcludeKeys);
		oldForm.dictLookup("DR", &oldDR);
		oldForm.free();
		ref.free();
	}
	// Add DR to BePDFAcroForm
	Object dr;
	dr.initDict(mXRef);
	if (oldDR.isDict()) {
		CopyDict(&oldDR, &dr, drExcludeKeys);
		oldDR.free();
	}
	// Add font dict
	Object font;
	font.initDict(mXRef);
	// add old fonts
	AddFonts(&font, mBePDFAcroForm->GetFonts());
	// add new fonts
	AddFonts(&font, &mWrittenFonts);
	AddDict(&dr, "Font", &font);
	AddDict(&acroForm, "DR", &dr);
	WriteObject(mBePDFAcroFormRef, &acroForm);
	acroForm.free();
}
Example #3
0
void AnnotWriter::CopyInfoDict(Object* dict) {
	ASSERT(!is_empty_ref(mInfoRef));
	Object info;
	mXRef->getTrailerDict()->dictLookup("Info", &info);
	CopyDict(&info, dict, infoDictExcludeKeys);
	info.free();
}
Example #4
0
bool AnnotWriter::UpdatePage(int pageNo, Annotations* annots, Ref& annotArray) {
	bool ok = false;
	Object page;
	Ref* pageRef = mDoc->getCatalog()->getPageRef(pageNo+1);
	if (!mXRef->fetch(pageRef->num, pageRef->gen, &page)->isNull()) {
		if (HasAnnotRef(&page, annotArray)) return true;
		annotArray = mXRefTable.GetNewRef(xrefEntryUncompressed);
		if (HasEmbeddedContent(&page)) {
			if (!CopyContentStream(&page)) {
				fprintf(stderr, "Error: Could not copy content stream!");
				goto error;
			}
		}
		if (!CopyPage(&page, *pageRef, annotArray)) {
			fprintf(stderr, "Error: Could not copy page!");
		} else {
			ok = true;
		}
	} else {
		fprintf(stderr, "Error: Could not get page dict for page %d\n", pageNo+1);
	}
error:
	page.free();
	return ok;
}
Example #5
0
SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) {
    Object filterObj;
    SecurityHandler *secHdlr;
#ifdef ENABLE_PLUGINS
    XpdfSecurityHandler *xsh;
#endif

    encryptDictA->dictLookup("Filter", &filterObj);
    if (filterObj.isName("Standard")) {
        secHdlr = new StandardSecurityHandler(docA, encryptDictA);
    } else if (filterObj.isName()) {
#ifdef ENABLE_PLUGINS
        if ((xsh = globalParams->getSecurityHandler(filterObj.getName()))) {
            secHdlr = new ExternalSecurityHandler(docA, encryptDictA, xsh);
        } else {
#endif
            error(-1, "Couldn't find the '%s' security handler",
                  filterObj.getName());
            secHdlr = NULL;
#ifdef ENABLE_PLUGINS
        }
#endif
    } else {
        error(-1, "Missing or invalid 'Filter' entry in encryption dictionary");
        secHdlr = NULL;
    }
    filterObj.free();
    return secHdlr;
}
Example #6
0
/*
 * Функция videomaker_fnc() реализует поток записи видео с камеры робота в файл.
 * @ptr - указатель на структуру System.
 * Начинает запись видео, если поле videomaker объекта ptr истина
 */
void* videomaker_fnc(void *ptr)
{
	System &syst = *((System *)ptr);
	VideoMaker clip;
	Object<Mat> *curObj = NULL;
	Queue<Mat> &queue = syst.queue;
	
	if(!syst.videomaker)
	{	
		return NULL;
	}
	else
	{
		LOG("[I]: VideoMaker started.");
	}
	
	if(!clip.init(syst))
	{
		LOG("[E]: Videomaker: Can't open output stream."); //chmod or codecs problem???
		exit(EXIT_FAILURE);
	}
	
	while(1)
    {
		curObj = queue.waitForNewObject(curObj);
		
		clip.write(*(curObj->obj));
		
		curObj->free();
	}
	clip.deinit();
	return NULL;
}
Example #7
0
Links *PageRenderer::CreateLinks(int pageNo) {
	Page *page = mDoc->getCatalog()->getPage(pageNo);
	Object obj;
	Links *links = new Links(page->getAnnots(&obj), mDoc->getCatalog()->getBaseURI());
	obj.free();
	return links;
}
Example #8
0
void JPXStream::init()
{
  Object oLen;
  if (getDict()) getDict()->lookup("Length", &oLen);

  int bufSize = BUFFER_INCREASE;
  if (oLen.isInt()) bufSize = oLen.getInt();
  oLen.free();

  unsigned char *buf = (unsigned char*)gmallocn(bufSize, sizeof(unsigned char));
  int index = 0;

  str->reset();
  int c = str->getChar();
  while(c != EOF)
  {
    if (index >= bufSize)
    {
      bufSize += BUFFER_INCREASE;
      buf = (unsigned char*)greallocn(buf, bufSize, sizeof(unsigned char));
    }
    buf[index] = c;
    ++index;
    c = str->getChar();
  }

  init2(buf, index, CODEC_JP2);

  free(buf);

  counter = 0;
  inited = gTrue;
}
Example #9
0
bool AnnotWriter::HasEmbeddedContent(Object* page) {
	ASSERT(page && page->isDict());
	Object obj;
	bool embedded = !(page->dictLookupNF("Contents", &obj) &&
		(obj.isArray() || obj.isRef() || obj.isNull()));
	obj.free();
	return embedded;
}
Example #10
0
GooList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
				 XRef *xrefA) {
  GooList *items;
  char* alreadyRead;
  OutlineItem *item;
  Object obj;
  Object *p;

  if (!lastItemRef->isRef())
    return NULL;

  items = new GooList();

  alreadyRead = (char *)gmalloc(xrefA->getNumObjects());
  memset(alreadyRead, 0, xrefA->getNumObjects());

  p = firstItemRef;
  while (p->isRef() && 
	 (p->getRefNum() >= 0) && 
         (p->getRefNum() < xrefA->getNumObjects()) && 
         !alreadyRead[p->getRefNum()]) {
    if (!p->fetch(xrefA, &obj)->isDict()) {
      obj.free();
      break;
    }
    alreadyRead[p->getRefNum()] = 1;
    item = new OutlineItem(obj.getDict(), xrefA);
    obj.free();
    items->append(item);
    if (p->getRef().num == lastItemRef->getRef().num &&
	p->getRef().gen == lastItemRef->getRef().gen) {
      break;
    }
    p = &item->nextRef;
  }

  gfree(alreadyRead);

  if (!items->getLength()) {
    delete items;
    items = NULL;
  }

  return items;
}
Example #11
0
void AnnotWriter::WriteModDate(Ref ref) {
	GString* date = new GString();
	AnnotUtils::CurrentDate(date);

	Object obj;
	obj.initString(date);
	WriteObject(ref, &obj);
	obj.free(); // frees date
}
Example #12
0
Annotations* PageRenderer::GetAnnotationsForPage(int pageNo) {
	int i = pageNo-1;
	if (mAnnotations.Get(i) == NULL) {
		Object annotsDict;
		mDoc->getCatalog()->getPage(pageNo)->getAnnots(&annotsDict);
		mAnnotations.Set(i, new Annotations(&annotsDict, mBePDFAcroForm));
		annotsDict.free();
	}
	return mAnnotations.Get(i);
}
Example #13
0
void AnnotWriter::UpdateCatalog() {
	// Return if BePDFAcroForm has not been written or ref exists already in Catalog
	if (is_empty_ref(mBePDFAcroFormRef) || !is_empty_ref(mBePDFAcroForm->GetRef())) return;
	// Copy catalog and add ref to new BePDFAcroForm
	Ref root;
	Object oldCatalogRef;
	Object oldCatalog;
	Object catalog;
	root.num = mXRef->getRootNum();
	root.gen = mXRef->getRootGen();
	oldCatalogRef.initRef(root.num, root.gen);
	oldCatalogRef.fetch(mXRef, &oldCatalog);
	catalog.initDict(mXRef);
	CopyDict(&oldCatalog, &catalog);
	AddRef(&catalog, "BePDFAcroForm", mBePDFAcroFormRef);
	WriteObject(root, &catalog);
	catalog.free();
	oldCatalog.free();
	oldCatalogRef.free();
}
Example #14
0
OptionalContentGroup::OptionalContentGroup(Dict *ocgDict) : m_name(NULL)
{
  Object ocgName;
  ocgDict->lookup("Name", &ocgName);
  if (!ocgName.isString()) {
    error(-1, "Expected the name of the OCG, but wasn't able to find it, or it isn't a String");
  } else {
    m_name = new GooString( ocgName.getString() );
  }
  ocgName.free();
}
Example #15
0
/**
 The transition from this page to the next one.

 If it is set, then a PDF viewer in a presentation should perform the
 specified transition effect when switching from this page to the next one.

 \returns the transition effect for the switch to the next page, if any
 */
page_transition* page::transition() const
{
    if (!d->transition) {
        Object o;
        if (d->page->getTrans(&o)->isDict()) {
            d->transition = new page_transition(&o);
        }
        o.free();
    }
    return d->transition;
}
Example #16
0
/**
 \returns all the information keys available in the %document
 \see info_key, info_date
 */
std::vector<std::string> document::info_keys() const
{
    if (d->is_locked) {
        return std::vector<std::string>();
    }

    Object info;
    if (!d->doc->getDocInfo(&info)->isDict()) {
        info.free();
        return std::vector<std::string>();
    }

    Dict *info_dict = info.getDict();
    std::vector<std::string> keys(info_dict->getLength());
    for (int i = 0; i < info_dict->getLength(); ++i) {
        keys[i] = std::string(info_dict->getKey(i));
    }

    info.free();
    return keys;
}
Example #17
0
bool AnnotWriter::CopyPage(Object* page, Ref pageRef, Ref arrayRef) {
	Object copy;
	Object ar;

	ar.initRef(arrayRef.num, arrayRef.gen);
	CopyDict(page, &copy, pageDictExcludeKeys);
	copy.dictAdd(copyString("Annots"), &ar);

	// write to file
	WriteObject(pageRef, &copy);
	copy.free();
	return true;
}
Example #18
0
bool AnnotWriter::HasRef(Object* dict, const char* key, Ref &ref) {
	Object obj;
	bool ok = true;
	ASSERT(dict && dict->isDict());
	if (dict->dictLookupNF((char*)key, &obj) && obj.isRef()) {
		ref = obj.getRef();
	} else {
		ref = empty_ref;
		ok = false;
	}
	obj.free();
	return ok;
}
Example #19
0
/**
 Gets the time_t value value of the specified \p key of the document
 information.

 \returns the time_t value for the \p key
 \see info_keys, info_date
 */
time_type document::info_date(const std::string &key) const
{
    if (d->is_locked) {
        return time_type(-1);
    }

    Object info;
    if (!d->doc->getDocInfo(&info)->isDict()) {
        info.free();
        return time_type(-1);
    }

    Dict *info_dict = info.getDict();
    Object obj;
    time_type result = time_type(-1);
    if (info_dict->lookup(PSTR(key.c_str()), &obj)->isString()) {
        result = detail::convert_date(obj.getString()->getCString());
    }
    obj.free();
    info.free();
    return result;
}
Example #20
0
/**
 Gets the value of the specified \p key of the document information.

 \returns the value for the \p key, or an empty string if not available
 \see info_keys, info_date
 */
ustring document::info_key(const std::string &key) const
{
    if (d->is_locked) {
        return ustring();
    }

    Object info;
    if (!d->doc->getDocInfo(&info)->isDict()) {
        info.free();
        return ustring();
    }

    Dict *info_dict = info.getDict();
    Object obj;
    ustring result;
    if (info_dict->lookup(PSTR(key.c_str()), &obj)->isString()) {
        result = detail::unicode_GooString_to_ustring(obj.getString());
    }
    obj.free();
    info.free();
    return result;
}
Example #21
0
void AnnotWriter::WriteFont(PDFFont* font) {
	if (!is_empty_ref(font->GetRef())) return; // already saved
	font->SetRef(mXRefTable.GetNewRef(xrefEntryUncompressed));
	mWrittenFonts.push_back(font);
	Object dict;
	dict.initDict(mXRef);
	AddName(&dict, "Type", "Font");
	AddName(&dict, "Subtype", "Type1");
	AddName(&dict, "BaseFont", (char*)font->GetName());
	AddName(&dict, "Encoding", "WinAnsiEncoding");
	WriteObject(font->GetRef(), &dict);
	dict.free();
}
Example #22
0
bool AnnotWriter::UpdateAnnotArray(int pageNo, Annotations* annots, Ref annotArray) {
	ASSERT(annots->HasChanged());
	Object array;
	array.initArray(mXRef);
	for (int i = 0; i < annots->Length(); i++) {
		Annotation* a = annots->At(i);
		if (!a->IsDeleted()) {
			AddToAnnots(&array, a);
			if (a->GetPopup()) AddToAnnots(&array, a->GetPopup());
		}
	}
	// write to file
	WriteObject(annotArray, &array);
	array.free();
	return true;
}
Example #23
0
bool AnnotWriter::WriteFileTrailer() {
	Write("trailer\r");
	Object trailer;
	Object val;
	CopyDict(mXRef->getTrailerDict(), &trailer, fileTrailerExcludeKeys);
	trailer.dictAdd(copyString("Size"), val.initInt(mXRefTable.GetSize()));
	trailer.dictAdd(copyString("Prev"), val.initInt(mXRef->getLastXRefPos()));
	trailer.dictAdd(copyString("Root"), val.initRef(mXRef->getRootNum(), mXRef->getRootGen()));
	trailer.dictAdd(copyString("Info"), val.initRef(mInfoRef.num, mInfoRef.gen));
	WriteObject(&trailer);
	Write("\rstartxref\r");
	fprintf(mFile, "%d\r", mXRefOffset);
	Write("%%EOF\r");
	trailer.free();
	return true;
}
Example #24
0
Epdf_Document *
epdf_document_new (const char *filename)
{
  Epdf_Document *doc;

  if (!filename)
    return NULL;

  doc = (Epdf_Document *)malloc (sizeof (Epdf_Document));
  if (!doc)
    return NULL;

  if (!globalParams)
    globalParams = new GlobalParams();

  doc->pdfdoc = new PDFDoc (new GooString (filename), NULL);
  if (doc->pdfdoc->isOk() || doc->pdfdoc->getErrorCode() == errEncrypted) {
    Object         obj;

    if (doc->pdfdoc->getErrorCode() == errEncrypted)
      doc->locked = true;
    else
      doc->locked = false;
    doc->scanner = new FontInfoScanner(doc->pdfdoc);

    doc->pdfdoc->getDocInfo (&obj);
    if (!obj.isDict ()) {
      obj.free ();
      free (doc);

      return NULL;
    }

    doc->dict = obj.getDict();

    return doc;
  }

  free (doc);

  return NULL;
}
Example #25
0
void
BepdfApplication::UpdateFileAttributes(PDFDoc *doc, entry_ref *ref) {
	BNode node(ref);
	if (node.InitCheck() != B_OK) return;

	const bool force_overwrite = (modifiers() & B_COMMAND_KEY) == B_COMMAND_KEY;

	if (force_overwrite) {
		for (int i = 0; gAttrInfo[i].name; i++) {
			node.RemoveAttr(gAttrInfo[i].name);
		}
	}

	int32 pages = (int32)doc->getNumPages();
	UpdateAttr(node, "META:pages", B_INT32_TYPE, 0, &pages, sizeof(int32));
	bool b = doc->isLinearized();
	UpdateAttr(node, "PDF:linearized", B_BOOL_TYPE, 0, &b, sizeof(b));
	double d = doc->getPDFVersion();
	UpdateAttr(node, "PDF:version", B_DOUBLE_TYPE, 0, &d, sizeof(d));

	Object obj;
	if (doc->getDocInfo(&obj) && obj.isDict()) {
		Dict *dict = obj.getDict();
		for (int i = 0; gAttrInfo[i].name; i++) {
			time_t time;
			if (gAttrInfo[i].pdf_name == NULL) continue;
			BString *s = FileInfoWindow::GetProperty(dict, gAttrInfo[i].pdf_name, &time);
			if (s) {
				if (gAttrInfo[i].type_code == B_TIME_TYPE) {
					if (time != 0) {
						UpdateAttr(node, gAttrInfo[i].name, B_TIME_TYPE, 0, &time, sizeof(time));
					}
				} else {
					UpdateAttr(node, gAttrInfo[i].name, B_STRING_TYPE, 0, (void*)s->String(), s->Length()+1);
				}
				delete s;
			}
		}
	}
	obj.free();
}
Example #26
0
bool AnnotWriter::WriteAS(Ref& ref, Annotation* a) {
	if (is_empty_ref(ref)) return true;

	Object xobj;
	xobj.initDict(mXRef);
	// setup XObject dictionary
	AddName(&xobj, "Type", "XObject");
	AddName(&xobj, "Subtype", "Form");
	AddInteger(&xobj, "FormType", 1);
	PDFRectangle r = *a->GetRect();
	r.x2 -= r.x1; r.y2 -= r.y1;
	r.x1 = r.y1 = 0;
	AddRect(&xobj, "BBox", &r);
	// setup resource dictionary
	Object resources, array, name;
	resources.initDict(mXRef);
	array.initArray(mXRef);
	name.initName("PDF");
	array.arrayAdd(&name);
	resources.dictAdd(copyString("ProcSet"), &array);
	xobj.dictAdd(copyString("Resources"), &resources);

	// create appearance stream
	AnnotAppearance as;
	a->Visit(&as);

	// set length
	AddInteger(&xobj, "Length", as.GetLength());
	ASSERT(as.GetLength() > 0);

	// write form XObject
	WriteObject(ref, &xobj, as.GetStream());
	xobj.free();
	ref = empty_ref;
	return true;
}
Example #27
0
// -----------------------------------------------------------------------------
static void printInfoString(Dict *infoDict, char *key, char *text,
                            UnicodeMap *uMap) {
  Object obj;
  GooString *s1;
  GBool isUnicode;
  Unicode u;
  char buf[8];
  int i, n;

  if (infoDict->lookup(key, &obj)->isString()) {
    fputs(text, stdout);
    s1 = obj.getString();
    if ((s1->getChar(0) & 0xff) == 0xfe &&
        (s1->getChar(1) & 0xff) == 0xff) {
      isUnicode = gTrue;
      i = 2;
    } else {
      isUnicode = gFalse;
      i = 0;
    }
    while (i < obj.getString()->getLength()) {
      if (isUnicode) {
        u = ((s1->getChar(i) & 0xff) << 8) |
            (s1->getChar(i+1) & 0xff);
        i += 2;
      } else {
        u = pdfDocEncoding[s1->getChar(i) & 0xff];
        ++i;
      }
      n = uMap->mapUnicode(u, buf, sizeof(buf));
      fwrite(buf, 1, n, stdout);
    }
    fputc('\n', stdout);
  }
  obj.free();
}
Example #28
0
static void printInfoDate(Dict *infoDict, char *key, char *text) {
  Object obj;
  char *s;
  int year, mon, day, hour, min, sec, tz_hour, tz_minute;
  char tz;
  struct tm tmStruct;
  char buf[256];

  if (infoDict->lookup(key, &obj)->isString()) {
    fputs(text, stdout);
    s = obj.getString()->getCString();
    // TODO do something with the timezone info
    if ( parseDateString( s, &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute ) ) {
      tmStruct.tm_year = year - 1900;
      tmStruct.tm_mon = mon - 1;
      tmStruct.tm_mday = day;
      tmStruct.tm_hour = hour;
      tmStruct.tm_min = min;
      tmStruct.tm_sec = sec;
      tmStruct.tm_wday = -1;
      tmStruct.tm_yday = -1;
      tmStruct.tm_isdst = -1;
      // compute the tm_wday and tm_yday fields
      if (mktime(&tmStruct) != (time_t)-1 &&
          strftime(buf, sizeof(buf), "%c", &tmStruct)) {
        fputs(buf, stdout);
      } else {
        fputs(s, stdout);
      }
    } else {
      fputs(s, stdout);
    }
    fputc('\n', stdout);
  }
  obj.free();
}
Example #29
0
OCGs::OCGs(Object *ocgObject, XRef *xref) :
  m_xref(xref)
{
  // we need to parse the dictionary here, and build optionalContentGroups
  ok = gTrue;
  optionalContentGroups = new GooList();

  Object ocgList;
  ocgObject->dictLookup("OCGs", &ocgList);
  if (!ocgList.isArray()) {
    error(-1, "Expected the optional content group list, but wasn't able to find it, or it isn't an Array");
    ocgList.free();
    ok = gFalse;
    return;
  }

  // we now enumerate over the ocgList, and build up the optionalContentGroups list.
  for(int i = 0; i < ocgList.arrayGetLength(); ++i) {
    Object ocg;
    ocgList.arrayGet(i, &ocg);
    if (!ocg.isDict()) {
      ocg.free();
      break;
    }
    OptionalContentGroup *thisOptionalContentGroup = new OptionalContentGroup(ocg.getDict());
    ocg.free();
    ocgList.arrayGetNF(i, &ocg);
    // TODO: we should create a lookup map from Ref to the OptionalContentGroup
    thisOptionalContentGroup->setRef( ocg.getRef() );
    ocg.free();
    // the default is ON - we change state later, depending on BaseState, ON and OFF
    thisOptionalContentGroup->setState(OptionalContentGroup::On);
    optionalContentGroups->append(thisOptionalContentGroup);
  }

  Object defaultOcgConfig;
  ocgObject->dictLookup("D", &defaultOcgConfig);
  if (!defaultOcgConfig.isDict()) {
    error(-1, "Expected the default config, but wasn't able to find it, or it isn't a Dictionary");
    defaultOcgConfig.free();
    ocgList.free();
    ok = gFalse;
    return;
  }
#if 0
  // this is untested - we need an example showing BaseState
  Object baseState;
  defaultOcgConfig.dictLookup("BaseState", &baseState);
  if (baseState.isString()) {
    // read the value, and set each OptionalContentGroup entry appropriately
  }
  baseState.free();
#endif
  Object on;
  defaultOcgConfig.dictLookup("ON", &on);
  if (on.isArray()) {
    // ON is an optional element
    for (int i = 0; i < on.arrayGetLength(); ++i) {
      Object reference;
      on.arrayGetNF(i, &reference);
      if (!reference.isRef()) {
	// there can be null entries
	reference.free();
	break;
      }
      OptionalContentGroup *group = findOcgByRef( reference.getRef() );
      reference.free();
      if (!group) {
	error(-1, "Couldn't find group for reference");
	break;
      }
      group->setState(OptionalContentGroup::On);
    }
  }
  on.free();

  Object off;
  defaultOcgConfig.dictLookup("OFF", &off);
  if (off.isArray()) {
    // OFF is an optional element
    for (int i = 0; i < off.arrayGetLength(); ++i) {
      Object reference;
      off.arrayGetNF(i, &reference);
      if (!reference.isRef()) {
	// there can be null entries
	reference.free();
	break;
      }
      OptionalContentGroup *group = findOcgByRef( reference.getRef() );
      reference.free();
      if (!group) {
	error(-1, "Couldn't find group for reference to set OFF");
	break;
      }
      group->setState(OptionalContentGroup::Off);
    }
  }
  off.free();

  defaultOcgConfig.dictLookup("Order", &order);
  defaultOcgConfig.dictLookup("RBGroups", &rbgroups);

  ocgList.free();
  defaultOcgConfig.free();
}
Example #30
0
StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA,
        Object *encryptDictA):
    SecurityHandler(docA)
{
    Object versionObj, revisionObj, lengthObj;
    Object ownerKeyObj, userKeyObj, permObj, fileIDObj;
    Object fileIDObj1;
    Object cryptFiltersObj, streamFilterObj, stringFilterObj;
    Object cryptFilterObj, cfmObj, cfLengthObj;
    Object encryptMetadataObj;

    ok = gFalse;
    fileID = NULL;
    ownerKey = NULL;
    userKey = NULL;

    encryptDictA->dictLookup("V", &versionObj);
    encryptDictA->dictLookup("R", &revisionObj);
    encryptDictA->dictLookup("Length", &lengthObj);
    encryptDictA->dictLookup("O", &ownerKeyObj);
    encryptDictA->dictLookup("U", &userKeyObj);
    encryptDictA->dictLookup("P", &permObj);
    doc->getXRef()->getTrailerDict()->dictLookup("ID", &fileIDObj);
    if (versionObj.isInt() &&
            revisionObj.isInt() &&
            ownerKeyObj.isString() && ownerKeyObj.getString()->getLength() == 32 &&
            userKeyObj.isString() && userKeyObj.getString()->getLength() == 32 &&
            permObj.isInt()) {
        encVersion = versionObj.getInt();
        encRevision = revisionObj.getInt();
        encAlgorithm = cryptRC4;
        // revision 2 forces a 40-bit key - some buggy PDF generators
        // set the Length value incorrectly
        if (encRevision == 2 || !lengthObj.isInt()) {
            fileKeyLength = 5;
        } else {
            fileKeyLength = lengthObj.getInt() / 8;
        }
        encryptMetadata = gTrue;
        //~ this currently only handles a subset of crypt filter functionality
        if (encVersion == 4 && encRevision == 4) {
            encryptDictA->dictLookup("CF", &cryptFiltersObj);
            encryptDictA->dictLookup("StmF", &streamFilterObj);
            encryptDictA->dictLookup("StrF", &stringFilterObj);
            if (cryptFiltersObj.isDict() &&
                    streamFilterObj.isName() &&
                    stringFilterObj.isName() &&
                    !strcmp(streamFilterObj.getName(), stringFilterObj.getName())) {
                if (cryptFiltersObj.dictLookup(streamFilterObj.getName(),
                                               &cryptFilterObj)->isDict()) {
                    cryptFilterObj.dictLookup("CFM", &cfmObj);
                    if (cfmObj.isName("V2")) {
                        encVersion = 2;
                        encRevision = 3;
                        if (cryptFilterObj.dictLookup("Length", &cfLengthObj)->isInt()) {
                            //~ according to the spec, this should be cfLengthObj / 8
                            fileKeyLength = cfLengthObj.getInt();
                        }
                        cfLengthObj.free();
                    } else if (cfmObj.isName("AESV2")) {
                        encVersion = 2;
                        encRevision = 3;
                        encAlgorithm = cryptAES;
                        if (cryptFilterObj.dictLookup("Length", &cfLengthObj)->isInt()) {
                            //~ according to the spec, this should be cfLengthObj / 8
                            fileKeyLength = cfLengthObj.getInt();
                        }
                        cfLengthObj.free();
                    }
                    cfmObj.free();
                }
                cryptFilterObj.free();
            }
            stringFilterObj.free();
            streamFilterObj.free();
            cryptFiltersObj.free();
            if (encryptDictA->dictLookup("EncryptMetadata",
                                         &encryptMetadataObj)->isBool()) {
                encryptMetadata = encryptMetadataObj.getBool();
            }
            encryptMetadataObj.free();
        }
        permFlags = permObj.getInt();
        ownerKey = ownerKeyObj.getString()->copy();
        userKey = userKeyObj.getString()->copy();
        if (encVersion >= 1 && encVersion <= 2 &&
                encRevision >= 2 && encRevision <= 3) {
            if (fileIDObj.isArray()) {
                if (fileIDObj.arrayGet(0, &fileIDObj1)->isString()) {
                    fileID = fileIDObj1.getString()->copy();
                } else {
                    fileID = new GooString();
                }
                fileIDObj1.free();
            } else {
                fileID = new GooString();
            }
            ok = gTrue;
        } else {
            error(-1, "Unsupported version/revision (%d/%d) of Standard security handler",
                  encVersion, encRevision);
        }
    } else {
        error(-1, "Weird encryption info");
    }
    if (fileKeyLength > 16) {
        fileKeyLength = 16;
    }
    fileIDObj.free();
    permObj.free();
    userKeyObj.free();
    ownerKeyObj.free();
    lengthObj.free();
    revisionObj.free();
    versionObj.free();
}