EStatusCode PFMFileReader::Read(const string& inPFMFilePath) { EStatusCode status = PDFHummus::eSuccess; mInternalReadStatus = PDFHummus::eSuccess; InputFile pfmFile; status = pfmFile.OpenFile(inPFMFilePath); if(status != PDFHummus::eSuccess) { TRACE_LOG1("PFMFileReader::Read, unable to open PFM file in %s",inPFMFilePath.c_str()); return status; } do { mReaderStream = pfmFile.GetInputStream(); status = ReadHeader(); if(status != PDFHummus::eSuccess) break; status = ReadExtension(); if(status != PDFHummus::eSuccess) break; status = ReadExtendedFontMetrics(); if(status != PDFHummus::eSuccess) break; }while(false); pfmFile.CloseFile(); return status; }
EStatusCode OpenTypeTest::TestFont() { EStatusCode status; InputFile otfFile; do { status = otfFile.OpenFile("C:\\PDFLibTests\\TestMaterials\\fonts\\BrushScriptStd.otf"); if(status != PDFHummus::eSuccess) { cout<<"cannot read bursh script font file\n"; break; } OpenTypeFileInput openTypeReader; status = openTypeReader.ReadOpenTypeFile(otfFile.GetInputStream()); if(status != PDFHummus::eSuccess) { cout<<"could not read open type file\n"; break; } // show just abcd and notdef status = SaveCharstringCode(0,0,&openTypeReader.mCFF); for(unsigned short i=66; i < 70 && PDFHummus::eSuccess == status; ++i) status = SaveCharstringCode(0,i,&openTypeReader.mCFF); }while(false); return status; }
EStatusCode PreprocessorTest::RunTest(const string& inName, const string& inOriginalFile, const string& inOutputFile, const string& inComparisonFile) { EStatusCode status = eSuccess; StringToStringMap preprocessorDefinitions; StringList includeFolders; includeFolders.push_back(scSamplesBasePath); preprocessorDefinitions.insert(StringToStringMap::value_type("PREDEFINED_SYMBOL","2")); InputFile sourceFile; sourceFile.OpenFile(inOriginalFile); OutputFile outputFile; outputFile.OpenFile(inOutputFile); mCurrentStream = outputFile.GetOutputStream(); PreProcessor preProcessor; preProcessor.Setup(sourceFile.GetInputStream(),inOriginalFile,preprocessorDefinitions,includeFolders); preProcessor.AddListener(this); mStartRow = true; BoolAndString tokenizerResult = preProcessor.GetNextToken(); while(tokenizerResult.first) { if(!mStartRow) mCurrentStream->Write((const Byte*)" ",2); // 2 spaces, so we can clearly distinct tokens mCurrentStream->Write((const Byte*)tokenizerResult.second.c_str(),tokenizerResult.second.size()); mStartRow = false; tokenizerResult = preProcessor.GetNextToken(); } sourceFile.CloseFile(); outputFile.CloseFile(); mCurrentStream = NULL; SimpleFileComparer comparer; if(!comparer.Same(inOutputFile,inComparisonFile)) { cout<<"TokenizerTest::Run, failed in test named "<<inName<<". see result in "<<inOutputFile<<" and compare with the required result in "<<inComparisonFile<<"\n"; status = eFailure; } return status; }
EStatusCode PDFWriter::ModifyPDF(const std::string& inModifiedFile, EPDFVersion inPDFVersion, const std::string& inOptionalAlternativeOutputFile, const LogConfiguration& inLogConfiguration, const PDFCreationSettings& inPDFCreationSettings) { EStatusCode status = eSuccess; SetupLog(inLogConfiguration); SetupObjectsContext(inPDFCreationSettings); do { // either append to original file, or create a new copy and "modify" it. depending on users choice if(inOptionalAlternativeOutputFile.size() == 0 || (inOptionalAlternativeOutputFile == inModifiedFile)) { status = mOutputFile.OpenFile(inModifiedFile,true); if(status != eSuccess) break; } else { status = mOutputFile.OpenFile(inOptionalAlternativeOutputFile); if(status != eSuccess) break; // copy original to new output file InputFile modifiedFileInput; status = modifiedFileInput.OpenFile(inModifiedFile); if(status != eSuccess) break; OutputStreamTraits traits(mOutputFile.GetOutputStream()); status = traits.CopyToOutputStream(modifiedFileInput.GetInputStream()); if(status != eSuccess) break; } mObjectsContext.SetOutputStream(mOutputFile.GetOutputStream()); mDocumentContext.SetOutputFileInformation(&mOutputFile); // do setup for modification mIsModified = true; status = SetupStateFromModifiedFile(inModifiedFile,inPDFVersion); } while (false); return status; }
EStatusCode OpenTypeFileInput::ReadOpenTypeFile(const std::string& inFontFilePath, unsigned short inFaceIndex) { InputFile fontFile; EStatusCode status = fontFile.OpenFile(inFontFilePath); if(status != PDFHummus::eSuccess) { TRACE_LOG1("OpenTypeFileInput::ReadOpenTypeFile, cannot open true type font file at %s",inFontFilePath.c_str()); return status; } status = ReadOpenTypeFile(fontFile.GetInputStream(), inFaceIndex); fontFile.CloseFile(); return status; }
EStatusCode parsePDF() { PDFParser parser; InputFile pdfFile; EStatusCode status = pdfFile.OpenFile(scBasePath + "XObjectContent.PDF"); if(status != eSuccess) return status; status = parser.StartPDFParsing(pdfFile.GetInputStream()); if(status != eSuccess) return status; showPDFinfo(parser); // Just wcout some info (no iteration) showPagesInfo(parser,pdfFile,status); return status; }
FT_Stream FreeTypeWrapper::CreateFTStreamForPath(const std::string& inFilePath) { InputFile* inputFile = new InputFile; if(inputFile->OpenFile(inFilePath) != PDFHummus::eSuccess) return NULL; FT_Stream aStream = new FT_StreamRec(); aStream->base = NULL; aStream->size = (unsigned long)inputFile->GetFileSize(); aStream->pos = 0; aStream->descriptor.pointer = inputFile; aStream->pathname.pointer = NULL; aStream->read = InputFileReadSeek; aStream->close = InputFileClose; aStream->memory = NULL; aStream->cursor = NULL; aStream->limit = NULL; return aStream; }
EStatusCode PFBStreamTest::Run(const TestConfiguration& inTestConfiguration) { EStatusCode status; InputFile pfbFile; OutputFile decodedPFBFile; InputPFBDecodeStream decodeStream; do { pfbFile.OpenFile(RelativeURLToLocalPath(inTestConfiguration.mSampleFileBase,"TestMaterials/fonts/HLB_____.PFB")); decodedPFBFile.OpenFile(RelativeURLToLocalPath(inTestConfiguration.mSampleFileBase,"decodedPFBFile.txt")); status = decodeStream.Assign(pfbFile.GetInputStream()); if(status != PDFHummus::eSuccess) { cout<<"Failed to assign pfb input stream"; break; } OutputStreamTraits traits(decodedPFBFile.GetOutputStream()); status = traits.CopyToOutputStream(&decodeStream); if(status != PDFHummus::eSuccess) { cout<<"Failed to decode pfb stream"; break; } }while(false); decodeStream.Assign(NULL); pfbFile.CloseFile(); decodedPFBFile.CloseFile(); return status; }
EStatusCode InputImagesAsStreamsTest::Run() { // A minimal test to see if images as streams work. i'm using regular file streams, just to show the point // obviously this is quite a trivial case. PDFWriter pdfWriter; EStatusCode status; do { status = pdfWriter.StartPDF("C:\\PDFLibTests\\ImagesInStreams.PDF",ePDFVersion13); if(status != PDFHummus::eSuccess) { cout<<"failed to start PDF\n"; break; } PDFPage* page = new PDFPage(); page->SetMediaBox(PDFRectangle(0,0,595,842)); // JPG image InputFile jpgImage; status = jpgImage.OpenFile("C:\\PDFLibTests\\TestMaterials\\images\\otherStage.JPG"); if(status != PDFHummus::eSuccess) { cout<<"failed to open JPG image in"<<"C:\\PDFLibTests\\TestMaterials\\images\\otherStage.JPG"<<"\n"; break; } PDFFormXObject* formXObject = pdfWriter.CreateFormXObjectFromJPGStream(jpgImage.GetInputStream()); if(!formXObject) { cout<<"failed to create form XObject from file\n"; status = PDFHummus::eFailure; break; } jpgImage.CloseFile(); PageContentContext* pageContentContext = pdfWriter.StartPageContentContext(page); if(NULL == pageContentContext) { status = PDFHummus::eFailure; cout<<"failed to create content context for page\n"; } pageContentContext->q(); pageContentContext->cm(1,0,0,1,0,400); pageContentContext->Do(page->GetResourcesDictionary().AddFormXObjectMapping(formXObject->GetObjectID())); pageContentContext->Q(); delete formXObject; status = pdfWriter.EndPageContentContext(pageContentContext); if(status != PDFHummus::eSuccess) { cout<<"failed to end page content context\n"; break; } status = pdfWriter.WritePageAndRelease(page); if(status != PDFHummus::eSuccess) { cout<<"failed to write page\n"; break; } // TIFF image page = new PDFPage(); page->SetMediaBox(PDFRectangle(0,0,595,842)); InputFile tiffFile; status = tiffFile.OpenFile("C:\\PDFLibTests\\TestMaterials\\images\\tiff\\FLAG_T24.TIF"); if(status != PDFHummus::eSuccess) { cout<<"failed to open TIFF image in"<<"C:\\PDFLibTests\\TestMaterials\\images\\tiff\\FLAG_T24.TIF"<<"\n"; break; } formXObject = pdfWriter.CreateFormXObjectFromTIFFStream(tiffFile.GetInputStream()); if(!formXObject) { cout<<"failed to create image form XObject for TIFF\n"; status = PDFHummus::eFailure; break; } tiffFile.CloseFile(); pageContentContext = pdfWriter.StartPageContentContext(page); if(NULL == pageContentContext) { status = PDFHummus::eFailure; cout<<"failed to create content context for page with TIFF image\n"; } // continue page drawing, place the image in 0,0 (playing...could avoid CM at all) pageContentContext->q(); pageContentContext->cm(1,0,0,1,0,0); pageContentContext->Do(page->GetResourcesDictionary().AddFormXObjectMapping(formXObject->GetObjectID())); pageContentContext->Q(); delete formXObject; status = pdfWriter.EndPageContentContext(pageContentContext); if(status != PDFHummus::eSuccess) { cout<<"failed to end page content context for TIFF\n"; break; } status = pdfWriter.WritePageAndRelease(page); if(status != PDFHummus::eSuccess) { cout<<"failed to write page, for TIFF\n"; break; } // PDF InputFile pdfFile; status = pdfFile.OpenFile("C:\\PDFLibTests\\TestMaterials\\Original.pdf"); if(status != PDFHummus::eSuccess) { cout<<"failed to open PDF file in"<<"C:\\PDFLibTests\\TestMaterials\\Original.pdf"<<"\n"; break; } status = pdfWriter.AppendPDFPagesFromPDF(pdfFile.GetInputStream(),PDFPageRange()).first; if(status != PDFHummus::eSuccess) { cout<<"failed to append pages from Original.PDF\n"; break; } pdfFile.CloseFile(); status = pdfWriter.EndPDF(); if(status != PDFHummus::eSuccess) { cout<<"failed in end PDF\n"; break; } } while(false); return status; }
EStatusCode CustomLogTest::Run() { // Place log in a compressed stream, for a non-file PDF EStatusCode status; OutputFlateEncodeStream flateEncodeStream; OutputFlateDecodeStream flateDecodeStream; do { PDFWriter pdfWriter; OutputFile compressedLogFile; OutputStringBufferStream pdfStream; // setup log file with compression status = compressedLogFile.OpenFile("c:\\PDFLibTests\\CustomLogEncrypted.txt"); if(status != PDFHummus::eSuccess) break; flateEncodeStream.Assign(compressedLogFile.GetOutputStream()); // generate PDF TRACE_LOG("Starting PDF File Writing"); status = pdfWriter.StartPDFForStream(&pdfStream,ePDFVersion13,LogConfiguration(true,&flateEncodeStream)); if(status != PDFHummus::eSuccess) break; TRACE_LOG("Now will add an empty page"); PDFPage* page = new PDFPage(); page->SetMediaBox(PDFRectangle(0,0,400,400)); status = pdfWriter.WritePageAndRelease(page); if(status != PDFHummus::eSuccess) break; TRACE_LOG("Added page, now will close"); status = pdfWriter.EndPDFForStream(); if(status != PDFHummus::eSuccess) break; // since log was started by starting PDF...the ending resets it. so let's now begin again Singleton<Trace>::GetInstance()->SetLogSettings(&flateEncodeStream,true); TRACE_LOG("Finished PDF!!!1"); // dump PDF to a file, so we can review it OutputFile pdfFile; status = pdfFile.OpenFile("c:\\PDFLibTests\\DumpPDFFile.pdf"); if(status != PDFHummus::eSuccess) break; string pdfString = pdfStream.ToString(); pdfFile.GetOutputStream()->Write((const Byte*)pdfString.c_str(),pdfString.size()); pdfFile.CloseFile(); TRACE_LOG("PDF stream dumped"); // now finalize trace compressed file flateEncodeStream.Assign(NULL); compressedLogFile.CloseFile(); // Finish log Singleton<Trace>::Reset(); // now open a new file and decompress the log into it. OutputFile decryptedLogFile; status = decryptedLogFile.OpenFile("c:\\PDFLibTests\\CustomLogDecrypted.txt"); if(status != PDFHummus::eSuccess) break; // place an initial bom (cause the compressed content is unicode) unsigned short bom = (0xFE<<8) + 0xFF; decryptedLogFile.GetOutputStream()->Write((const Byte*)&bom,2); flateDecodeStream.Assign(decryptedLogFile.GetOutputStream()); OutputStreamTraits traits(&flateDecodeStream); InputFile compressedLogFileInput; status = compressedLogFileInput.OpenFile("c:\\PDFLibTests\\CustomLogEncrypted.txt"); if(status != PDFHummus::eSuccess) break; status = traits.CopyToOutputStream(compressedLogFileInput.GetInputStream()); if(status != PDFHummus::eSuccess) break; compressedLogFileInput.CloseFile(); flateDecodeStream.Assign(NULL); decryptedLogFile.CloseFile(); }while(false); if(status != PDFHummus::eSuccess) { // cancel ownership of subsstreams flateDecodeStream.Assign(NULL); flateEncodeStream.Assign(NULL); } return status; }
EStatusCode RotatedPagesPDF::Run(const TestConfiguration& inTestConfiguration) { LogConfiguration logConfiguration(true,true,RelativeURLToLocalPath(inTestConfiguration.mSampleFileBase,"RotatedPagesLog.txt")); EStatusCode status; do { // PDF Page rotation writing PDFWriter pdfWriter; status = pdfWriter.StartPDF( RelativeURLToLocalPath(inTestConfiguration.mSampleFileBase,"RotatedPages.pdf"), ePDFVersion13,logConfiguration); if(status != PDFHummus::eSuccess) { cout<<"failed to start RotatedPages.pdf\n"; break; } AbstractContentContext::TextOptions textOptions(pdfWriter.GetFontForFile( RelativeURLToLocalPath( inTestConfiguration.mSampleFileBase, "TestMaterials/fonts/arial.ttf")), 14, AbstractContentContext::eGray, 0); for(int i=0;i<6 && PDFHummus::eSuccess == status;++i) { PDFPage page; page.SetMediaBox(PDFRectangle(0,0,595,842)); page.SetRotate(33); if ( page.GetRotate().second != 0 ) { status = PDFHummus::eFailure; cout<<"Failed to reject invalid rotation\n"; break; } page.SetRotate(i*90); std::ostringstream s; s << "Page rotated by " << i*90 << " degrees."; PageContentContext* cxt = pdfWriter.StartPageContentContext(&page); cxt->WriteText(75,805,s.str(),textOptions); status = pdfWriter.EndPageContentContext(cxt); if(status != eSuccess) { status = PDFHummus::eFailure; cout<<"Failed to end content context\n"; break; } status = pdfWriter.WritePage(&page); if(status != PDFHummus::eSuccess) cout<<"failed to write page "<<i<<"\n"; } status = pdfWriter.EndPDF(); if(status != PDFHummus::eSuccess) { cout<<"failed in end RotatedPages.pdf\n"; break; } // PDF page rotation copy status = pdfWriter.StartPDF( RelativeURLToLocalPath(inTestConfiguration.mSampleFileBase,"RotatedPagesCopy.pdf"), ePDFVersion13); if(status != PDFHummus::eSuccess) { cout<<"failed to start RotatedPagesCopy.pdf\n"; break; } EStatusCodeAndObjectIDTypeList result; // append pages result = pdfWriter.AppendPDFPagesFromPDF( RelativeURLToLocalPath(inTestConfiguration.mSampleFileBase,"RotatedPages.pdf"), PDFPageRange()); if(result.first != PDFHummus::eSuccess) { cout<<"failed to append pages from RotatedPages.pdf\n"; status = result.first; break; } status = pdfWriter.EndPDF(); if(status != PDFHummus::eSuccess) { cout<<"failed in end RotatedPagesCopy.pdf\n"; break; } // PDF Page rotation parsing InputFile pdfFile; PDFParser pdfParser; status = pdfFile.OpenFile( RelativeURLToLocalPath(inTestConfiguration.mSampleFileBase,"RotatedPagesCopy.pdf")); if(status != PDFHummus::eSuccess) { cout<<"unable to open file RotatedPagesCopy.pdf for reading.\n"; break; } status = pdfParser.StartPDFParsing(pdfFile.GetInputStream()); if(status != PDFHummus::eSuccess) { cout<<"unable to parse input file"; break; } if(pdfParser.GetPagesCount() != 6) { cout<<"expecting 6 pages, got "<<pdfParser.GetPagesCount()<<"\n"; status = PDFHummus::eFailure; break; } for(unsigned long i=0;i<pdfParser.GetPagesCount() && PDFHummus::eSuccess == status;++i) { RefCountPtr<PDFDictionary> page = pdfParser.ParsePage(i); if (!page) { cout << i << ". page parsing failed\n"; status = PDFHummus::eFailure; break; } PDFPageInput input( &pdfParser, page ); if ( input.GetRotate() != i*90 ) { cout<< i << ". page has invalid rotation\n"; status = PDFHummus::eFailure; break; } } }while(false); return status; }
EStatusCode VariablesTest::Run() { CPPStatementsParser parser; InputFile inputFile; EStatusCode status = eSuccess; Hummus::Singleton<Hummus::Trace>::GetInstance()->SetLogSettings(scResultBasePath + "variablesLog.txt",true,true); inputFile.OpenFile(scSamplesBasePath + "variables.h"); EStatusCodeAndHeaderUnit result = parser.Parse( inputFile.GetInputStream(), inputFile.GetFilePath(), StringToStringMap(), StringList() ); if(result.first != eSuccess) { cout<<"VariablesTest::Run, failed to parse source\n"; return eFailure; } HeaderUnit* parsedTree = result.second; CPPNamespace* globalNamespace = parsedTree->GetGlobalNamespace(); do { if(VerifySimplePrimitiveVariables(globalNamespace) != eSuccess) { cout<<"VariablesTest::Run, failed simple variables definition\n"; status = eFailure; } if(VerifySpecialStorageVariables(globalNamespace) != eSuccess) { cout<<"VariablesTest::Run, failed special storage variables definition\n"; status = eFailure; } if(VerifyPointerArraysAndInitializers(globalNamespace) != eSuccess) { cout<<"VariablesTest::Run, failed pointers and arrays and initializers definition\n"; status = eFailure; } if(VerifyFunctionPointers(globalNamespace) != eSuccess) { cout<<"VariablesTest::Run, failed function pointers definition\n"; status = eFailure; } } while(false); delete parsedTree; Hummus::Singleton<Hummus::Trace>::Reset(); return status; }
Byte calculateImageBrightnessFactor(const std::string& inImageFilePath) { BrightnessState state; InputFile inputFile; ByteVector brightnessValues; DistanceAndBrightnessVector valuesForAverage; inputFile.OpenFile(inImageFilePath); state.mStream = inputFile.GetInputStream(); InitializeDecodingState(state); StartRead(state); LongBufferSizeType samplesSkipping = 1; // max samples 20 if(state.mJPGState.output_width > 500) samplesSkipping = state.mJPGState.output_width / 50; // max samples - 50 else if(state.mJPGState.output_width > 20) samplesSkipping = 10; // max samples - 50 LongBufferSizeType rowsSkipping = 1; // max samples 20 if(state.mJPGState.output_height > 500) rowsSkipping = state.mJPGState.output_height / 50; // max samples - 50 else if(state.mJPGState.output_height > 20) rowsSkipping = 10; // max samples - 50 LongBufferSizeType rowCounter = 0; // read samples from image, converting to hsb and keeping the "b" component, as a brightness factor while(state.mJPGState.output_scanline < state.mJPGState.output_height) { try { state.mTotalSampleRows = jpeg_read_scanlines(&(state.mJPGState), state.mSamplesBuffer, state.mJPGState.rec_outbuf_height); ++rowCounter; if(rowCounter >= rowsSkipping) rowCounter = 0; else if(rowCounter != 1) continue; } catch(HummusJPGException) { state.mTotalSampleRows = 0; } state.mIndexInRow = 0; state.mCurrentSampleRow = 0; while(state.mCurrentSampleRow < state.mTotalSampleRows) { LongBufferSizeType row_stride = state.mJPGState.output_width * state.mJPGState.output_components; // convert samples to HSB (note that some samples are skipped) for(LongBufferSizeType i=0;i<row_stride;i+=(state.mJPGState.output_components*samplesSkipping)) { // get rgb Byte r = state.mSamplesBuffer[state.mCurrentSampleRow][i]; Byte g = state.mSamplesBuffer[state.mCurrentSampleRow][i+1]; Byte b = state.mSamplesBuffer[state.mCurrentSampleRow][i+2]; // calculate brightness [converting to HSB] brightnessValues.push_back(RGBtoHSVtoBrightness(r,g,b)); } ++state.mCurrentSampleRow; } } FinalizeDecoding(state); // prepare distance data and sort, to remove extremes from calculation ByteVector::const_iterator it = brightnessValues.begin(); for(;it!=brightnessValues.end();++it) valuesForAverage.push_back(DistanceAndBrightness(*it,calculateDistance(*it,brightnessValues))); std::sort(valuesForAverage.begin(),valuesForAverage.end(),DistanceAndBrightnessSort); // now simply calculate the average based on the first 2/3 of the vector, to reduce the effects of extremes double average = 0; DistanceAndBrightnessVector::const_iterator itCurrent = valuesForAverage.begin(); unsigned long interestingItemsCount = floor(valuesForAverage.size()*2.0/3.0); DistanceAndBrightnessVector::const_iterator itEnd = valuesForAverage.begin()+interestingItemsCount; for(itCurrent = valuesForAverage.begin();itCurrent!=itEnd;++itCurrent) average+=(double)(itCurrent->brightness)/interestingItemsCount; return ceil(average); }