Good morning,
I've attached two patches:
* the first one makes exceptions thrown from unimplemented PNG/TIFF
predictors more verbose
* the second implements PNG paeth predictor
Both patches created with git and could be applied with `patch -p1 -i
abc.patch`
------------------------------------------------------------------------
Sergey Shambir, Senior Software Engineer, iSpring Solutions
<http://www.ispringsolutions.com/>
>From db90ad1b1231068346f74053fafa801b89f7f6a4 Mon Sep 17 00:00:00 2001
From: Sergey Shambir <sergey.sham...@ispringsolutions.com>
Date: Mon, 1 Aug 2016 14:10:45 +0300
Subject: [PATCH 1/2] REFACTOR: made PNG predictor exceptions more verbose
---
src/base/PdfFiltersPrivate.cpp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/base/PdfFiltersPrivate.cpp b/src/base/PdfFiltersPrivate.cpp
index e564df8..9900381 100644
--- a/src/base/PdfFiltersPrivate.cpp
+++ b/src/base/PdfFiltersPrivate.cpp
@@ -154,7 +154,7 @@ public:
}
// TODO: implement tiff predictor for other than 8 BPC
- PODOFO_RAISE_ERROR( ePdfError_InvalidPredictor );
+ PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidPredictor, "tiff predictors other than 8 BPC are not implemented" );
break;
}
case 10: // png none
@@ -181,9 +181,12 @@ public:
m_pPrev[m_nCurRowIndex] = ((prev + m_pPrev[m_nCurRowIndex]) >> 1) + *pBuffer;
break;
}
- case 14: // png paeth
+ case 14: // png paeth
+ PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidPredictor, "png paeth predictor is not implemented" );
+ break;
+
case 15: // png optimum
- PODOFO_RAISE_ERROR( ePdfError_InvalidPredictor );
+ PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidPredictor, "png optimum predictor is not implemented" );
break;
default:
--
2.7.4
>From 4cd1a4cc84e083013fb565a512b1a92d1e45fded Mon Sep 17 00:00:00 2001
From: Sergey Shambir <sergey.sham...@ispringsolutions.com>
Date: Mon, 1 Aug 2016 16:39:29 +0300
Subject: [PATCH 2/2] FEATURE: implemented PNG paeth predictor for FlateDecode
streams
---
src/base/PdfFiltersPrivate.cpp | 84 ++++++++++++++++++++++++++----------------
1 file changed, 53 insertions(+), 31 deletions(-)
diff --git a/src/base/PdfFiltersPrivate.cpp b/src/base/PdfFiltersPrivate.cpp
index 9900381..eaa8c37 100644
--- a/src/base/PdfFiltersPrivate.cpp
+++ b/src/base/PdfFiltersPrivate.cpp
@@ -39,6 +39,7 @@
#include "PdfOutputStream.h"
#include "PdfTokenizer.h"
#include "PdfDefinesPrivate.h"
+#include <limits>
#ifdef PODOFO_HAVE_JPEG_LIB
extern "C" {
@@ -109,29 +110,22 @@ public:
m_nBpp = (m_nBPC * m_nColors) >> 3;
m_nRows = (m_nColumns * m_nColors * m_nBPC) >> 3;
- m_pPrev = static_cast<char*>(podofo_calloc( m_nRows, sizeof(char) ));
- if( !m_pPrev )
- {
- PODOFO_RAISE_ERROR( ePdfError_OutOfMemory );
- }
-
- memset( m_pPrev, 0, sizeof(char) * m_nRows );
+ m_prevLine.resize( m_nRows, 0 );
+ m_curLine.resize( m_nRows, 0 );
};
~PdfPredictorDecoder()
{
- podofo_free( m_pPrev );
}
- void Decode( const char* pBuffer, pdf_long lLen, PdfOutputStream* pStream )
+ void Decode( const unsigned char* pBuffer, pdf_long lLen, PdfOutputStream* pStream )
{
if( m_nPredictor == 1 )
{
- pStream->Write( pBuffer, lLen );
+ pStream->Write( reinterpret_cast<const char *>(pBuffer), lLen );
return;
}
-
while( lLen-- )
{
if( m_bNextByteIsPredictor )
@@ -147,9 +141,9 @@ public:
{
if(m_nBPC == 8)
{ // Same as png sub
- int prev = (m_nCurRowIndex - m_nBpp < 0
- ? 0 : m_pPrev[m_nCurRowIndex - m_nBpp]);
- m_pPrev[m_nCurRowIndex] = *pBuffer + prev;
+ int left = (m_nCurRowIndex - m_nBpp < 0
+ ? 0 : m_curLine[m_nCurRowIndex - m_nBpp]);
+ m_curLine[m_nCurRowIndex] = *pBuffer + left;
break;
}
@@ -159,32 +153,41 @@ public:
}
case 10: // png none
{
- m_pPrev[m_nCurRowIndex] = *pBuffer;
+ m_curLine[m_nCurRowIndex] = *pBuffer;
break;
}
case 11: // png sub
{
- int prev = (m_nCurRowIndex - m_nBpp < 0
- ? 0 : m_pPrev[m_nCurRowIndex - m_nBpp]);
- m_pPrev[m_nCurRowIndex] = *pBuffer + prev;
+ const int left = (m_nCurRowIndex - m_nBpp < 0
+ ? 0 : m_curLine[m_nCurRowIndex - m_nBpp]);
+ m_curLine[m_nCurRowIndex] = *pBuffer + left;
break;
}
case 12: // png up
{
- m_pPrev[m_nCurRowIndex] += *pBuffer;
+ const int up = m_prevLine[m_nCurRowIndex];
+ m_curLine[m_nCurRowIndex] = *pBuffer + up;
break;
}
case 13: // png average
{
- int prev = (m_nCurRowIndex - m_nBpp < 0
- ? 0 : m_pPrev[m_nCurRowIndex - m_nBpp]);
- m_pPrev[m_nCurRowIndex] = ((prev + m_pPrev[m_nCurRowIndex]) >> 1) + *pBuffer;
+ const int left = (m_nCurRowIndex - m_nBpp < 0
+ ? 0 : m_curLine[m_nCurRowIndex - m_nBpp]);
+ const int up = m_prevLine[m_nCurRowIndex];
+ m_curLine[m_nCurRowIndex] = *pBuffer + ((left + up) >> 1);
+ break;
+ }
+ case 14: // png paeth
+ {
+ const int left = (m_nCurRowIndex - m_nBpp < 0
+ ? 0 : m_curLine[m_nCurRowIndex - m_nBpp]);
+ const int up = m_prevLine[m_nCurRowIndex];
+ const int upLeft = (m_nCurRowIndex - m_nBpp < 0
+ ? 0 : m_prevLine[m_nCurRowIndex - m_nBpp]);
+ const int mod = std::numeric_limits<unsigned char>::max() + 1;
+ m_curLine[m_nCurRowIndex] = (*pBuffer + GetPaethPredictor(left, up, upLeft)) % mod;
break;
}
- case 14: // png paeth
- PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidPredictor, "png paeth predictor is not implemented" );
- break;
-
case 15: // png optimum
PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidPredictor, "png optimum predictor is not implemented" );
break;
@@ -203,15 +206,33 @@ public:
if( m_nCurRowIndex >= m_nRows )
{ // One line finished
- m_nCurRowIndex = 0;
+ m_nCurRowIndex = 0;
m_bNextByteIsPredictor = (m_nCurPredictor >= 10);
- pStream->Write( m_pPrev, m_nRows );
+ pStream->Write( reinterpret_cast<const char *>(&m_curLine[0]), m_nRows );
+ m_curLine.swap(m_prevLine);
}
}
}
private:
+ static int GetPaethPredictor(int a, int b, int c)
+ {
+ int p = a + b - c;
+ int pa = std::abs(p - a);
+ int pb = std::abs(p - b);
+ int pc = std::abs(p - c);
+ if (pa <= pb && pa <= pc)
+ {
+ return a;
+ }
+ if (pb <= pc)
+ {
+ return b;
+ }
+ return c;
+ }
+
int m_nPredictor;
int m_nColors;
int m_nBPC; //< Bytes per component
@@ -225,7 +246,8 @@ private:
bool m_bNextByteIsPredictor;
- char* m_pPrev;
+ std::vector<unsigned char> m_prevLine;
+ std::vector<unsigned char> m_curLine;
};
@@ -595,7 +617,7 @@ void PdfFlateFilter::DecodeBlockImpl( const char* pBuffer, pdf_long lLen )
nWrittenData = PODOFO_FILTER_INTERNAL_BUFFER_SIZE - m_stream.avail_out;
try {
if( m_pPredictor )
- m_pPredictor->Decode( reinterpret_cast<char*>(m_buffer), nWrittenData, GetStream() );
+ m_pPredictor->Decode( m_buffer, nWrittenData, GetStream() );
else
GetStream()->Write( reinterpret_cast<char*>(m_buffer), nWrittenData );
} catch( PdfError & e ) {
@@ -790,7 +812,7 @@ void PdfLZWFilter::DecodeBlockImpl( const char* pBuffer, pdf_long lLen )
// Write data to the output device
if( m_pPredictor )
- m_pPredictor->Decode( reinterpret_cast<char*>(&(data[0])), data.size(), GetStream() );
+ m_pPredictor->Decode( &(data[0]), data.size(), GetStream() );
else
GetStream()->Write( reinterpret_cast<char*>(&(data[0])), data.size());
--
2.7.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Podofo-users mailing list
Podofo-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/podofo-users