mirror of https://github.com/JakubMelka/PDF4QT.git
CCITT fax decoder, finishing
This commit is contained in:
parent
e20dfe6a5c
commit
b1b5780753
|
@ -312,7 +312,7 @@ PDFImageData PDFCCITTFaxDecoder::decode()
|
|||
|
||||
int row = 0;
|
||||
const size_t lineSize = m_parameters.columns + 2;
|
||||
codingLine.resize(lineSize, m_parameters.columns);
|
||||
codingLine.resize(lineSize, 0);
|
||||
referenceLine.resize(lineSize, m_parameters.columns);
|
||||
bool isUsing2DEncoding = m_parameters.K < 0;
|
||||
bool isEndOfLineOccured = m_parameters.hasEndOfLine;
|
||||
|
@ -334,7 +334,6 @@ PDFImageData PDFCCITTFaxDecoder::decode()
|
|||
int a0_index = 0;
|
||||
bool isCurrentPixelBlack = false;
|
||||
|
||||
|
||||
if (isUsing2DEncoding)
|
||||
{
|
||||
int b1_index = 0;
|
||||
|
@ -444,22 +443,74 @@ PDFImageData PDFCCITTFaxDecoder::decode()
|
|||
++index;
|
||||
}
|
||||
|
||||
writer.write((isCurrentPixelBlack != m_parameters.hasBlackIsOne) ? 0 : 1);
|
||||
writer.write((isCurrentPixelBlack != m_parameters.hasBlackIsOne) ? 1 : 0);
|
||||
}
|
||||
writer.finishLine();
|
||||
|
||||
++row;
|
||||
|
||||
// Check if we have reached desired number of rows (and end-of-block mode
|
||||
// is not set). If yes, then break the reading.
|
||||
if (!m_parameters.hasEndOfBlock && row == m_parameters.rows)
|
||||
{
|
||||
// We have reached number of rows, stop reading the data
|
||||
break;
|
||||
}
|
||||
pokracovat zde
|
||||
|
||||
bool foundEndOfLine = false;
|
||||
if (m_parameters.hasEndOfLine)
|
||||
{
|
||||
// End of line is required, try to scan it (until end of stream is reached).
|
||||
while (!m_reader.isAtEnd())
|
||||
{
|
||||
if (m_reader.look(12) == 1)
|
||||
{
|
||||
m_reader.read(12);
|
||||
foundEndOfLine = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_reader.read(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!m_parameters.hasEncodedByteAlign)
|
||||
{
|
||||
// Skip fill zeros and possibly find EOL
|
||||
foundEndOfLine = skipFillAndEOL();
|
||||
}
|
||||
|
||||
// If end of line is found, be do not perform align to bytes (end of line
|
||||
// has perference against byte align)
|
||||
if (m_parameters.hasEncodedByteAlign && !foundEndOfLine)
|
||||
{
|
||||
m_reader.alignToBytes();
|
||||
}
|
||||
|
||||
if (m_reader.isAtEnd())
|
||||
{
|
||||
// Have we finished reading?
|
||||
break;
|
||||
}
|
||||
|
||||
updateIsUsing2DEncoding();
|
||||
|
||||
if (m_parameters.hasEndOfBlock && foundEndOfLine)
|
||||
{
|
||||
if (m_reader.look(60) == 0x1001001001001ULL)
|
||||
{
|
||||
// End of block found, stop reading the data
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::swap(codingLine, referenceLine);
|
||||
|
||||
std::fill(codingLine.begin(), codingLine.end(), 0);
|
||||
std::fill(std::next(referenceLine.begin(), a0_index + 1), referenceLine.end(), m_parameters.columns);
|
||||
}
|
||||
|
||||
return PDFImageData(1, 1, m_parameters.columns, row, (m_parameters.columns + 7) / 8, m_parameters.maskingType, writer.takeByteArray(), { }, { }, { });
|
||||
}
|
||||
|
||||
void PDFCCITTFaxDecoder::skipFill()
|
||||
|
@ -467,7 +518,7 @@ void PDFCCITTFaxDecoder::skipFill()
|
|||
// This functions skips zero bits (because codewords have at most 12 bits,
|
||||
// we use 12 bit lookahead to ensure, that we do not broke data sequence).
|
||||
|
||||
while (m_reader.look(12) == 0)
|
||||
while (!m_reader.isAtEnd() && m_reader.look(12) == 0)
|
||||
{
|
||||
m_reader.read(1);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ struct PDFCCITTFaxDecoderParameters
|
|||
/// If this flag is true, then 1 means black pixel, 0 white pixel. Otherwise, if false,
|
||||
/// then 0 means black pixel and 1 white pixel.
|
||||
bool hasBlackIsOne = false;
|
||||
|
||||
PDFImageData::MaskingType maskingType = PDFImageData::MaskingType::None;
|
||||
};
|
||||
|
||||
enum CCITT_2D_Code_Mode;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "pdfconstants.h"
|
||||
#include "pdfexception.h"
|
||||
#include "pdfutils.h"
|
||||
#include "pdfccittfaxdecoder.h"
|
||||
|
||||
#include <openjpeg.h>
|
||||
#include <jpeglib.h>
|
||||
|
@ -166,6 +167,26 @@ PDFImage PDFImage::createImage(const PDFDocument* document, const PDFStream* str
|
|||
}
|
||||
}
|
||||
|
||||
const PDFDictionary* filterParamsDictionary = nullptr;
|
||||
if (filterParameters.isDictionary())
|
||||
{
|
||||
filterParamsDictionary = filterParameters.getDictionary();
|
||||
}
|
||||
else if (filterParameters.isArray())
|
||||
{
|
||||
const PDFArray* filterParametersArray = filterParameters.getArray();
|
||||
const size_t filterParamsCount = filterParametersArray->getCount();
|
||||
|
||||
if (filterParamsCount)
|
||||
{
|
||||
const PDFObject& object = document->getObject(filterParametersArray->getItem(filterParamsCount - 1));
|
||||
if (object.isDictionary())
|
||||
{
|
||||
filterParamsDictionary = object.getDictionary();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (imageFilterName == "DCTDecode" || imageFilterName == "DCT")
|
||||
{
|
||||
int colorTransform = loader.readIntegerFromDictionary(dictionary, "ColorTransform", -1);
|
||||
|
@ -493,7 +514,26 @@ PDFImage PDFImage::createImage(const PDFDocument* document, const PDFStream* str
|
|||
}
|
||||
else if (imageFilterName == "CCITTFaxDecode" || imageFilterName == "CCF")
|
||||
{
|
||||
throw PDFRendererException(RenderErrorType::NotImplemented, PDFTranslationContext::tr("Not implemented image filter 'CCITTFaxDecode'."));
|
||||
if (!filterParamsDictionary)
|
||||
{
|
||||
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Invalid parameters for filter CCITT fax decode."));
|
||||
}
|
||||
|
||||
PDFCCITTFaxDecoderParameters parameters;
|
||||
parameters.maskingType = maskingType;
|
||||
|
||||
parameters.K = loader.readIntegerFromDictionary(filterParamsDictionary, "K", 0);
|
||||
parameters.hasEndOfLine = loader.readBooleanFromDictionary(filterParamsDictionary, "EndOfLine", false);
|
||||
parameters.hasEncodedByteAlign = loader.readBooleanFromDictionary(filterParamsDictionary, "EncodedByteAlign", false);
|
||||
parameters.columns = loader.readIntegerFromDictionary(filterParamsDictionary, "Columns", 1728);
|
||||
parameters.rows = loader.readIntegerFromDictionary(filterParamsDictionary, "Rows", 0);
|
||||
parameters.hasEndOfBlock = loader.readBooleanFromDictionary(filterParamsDictionary, "EndOfBlock", true);
|
||||
parameters.hasBlackIsOne = loader.readBooleanFromDictionary(filterParamsDictionary, "BlackIs1", false);
|
||||
parameters.damagedRowsBeforeError = loader.readIntegerFromDictionary(filterParamsDictionary, "DamagedRowsBeforeError", 0);
|
||||
|
||||
QByteArray imageDataBuffer = document->getDecodedStream(stream);
|
||||
PDFCCITTFaxDecoder decoder(&imageDataBuffer, parameters);
|
||||
image.m_imageData = decoder.decode();
|
||||
}
|
||||
else if (imageFilterName == "JBIG2Decode")
|
||||
{
|
||||
|
|
|
@ -56,10 +56,24 @@ PDFBitReader::Value PDFBitReader::read(PDFBitReader::Value bits)
|
|||
return value;
|
||||
}
|
||||
|
||||
PDFBitReader::Value PDFBitReader::look(PDFBitReader::Value bits) const
|
||||
PDFBitReader::Value PDFBitReader::look(Value bits) const
|
||||
{
|
||||
PDFBitReader temp(*this);
|
||||
return temp.read(bits);
|
||||
|
||||
Value result = 0;
|
||||
for (Value i = 0; i < bits; ++i)
|
||||
{
|
||||
if (!temp.isAtEnd())
|
||||
{
|
||||
result = (result << 1) | temp.read(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (result << 1);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PDFBitReader::seek(qint64 position)
|
||||
|
|
Loading…
Reference in New Issue