예제 #1
0
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;
}
예제 #2
0
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;	

}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}
예제 #12
0
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;

}
예제 #13
0
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);
}