mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
JBIG2 - bugfixing
This commit is contained in:
@ -12,6 +12,7 @@
|
|||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget* parent) :
|
MainWindow::MainWindow(QWidget* parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
@ -90,7 +91,11 @@ void MainWindow::on_actionAdd_JBIG2_image_triggered()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
pdf::PDFJBIG2Decoder decoder(data, QByteArray(), this);
|
pdf::PDFJBIG2Decoder decoder(data, QByteArray(), this);
|
||||||
|
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
pdf::PDFImageData imageData = decoder.decodeFileStream();
|
pdf::PDFImageData imageData = decoder.decodeFileStream();
|
||||||
|
qint64 time = timer.elapsed();
|
||||||
|
|
||||||
if (imageData.isValid())
|
if (imageData.isValid())
|
||||||
{
|
{
|
||||||
@ -98,7 +103,7 @@ void MainWindow::on_actionAdd_JBIG2_image_triggered()
|
|||||||
const uchar* sourceData = reinterpret_cast<const uchar*>(imageData.getData().constData());
|
const uchar* sourceData = reinterpret_cast<const uchar*>(imageData.getData().constData());
|
||||||
Q_ASSERT(imageData.getData().size() == image.byteCount());
|
Q_ASSERT(imageData.getData().size() == image.byteCount());
|
||||||
std::transform(sourceData, sourceData + imageData.getData().size(), image.bits(), [](const uchar value) { return ~value; });
|
std::transform(sourceData, sourceData + imageData.getData().size(), image.bits(), [](const uchar value) { return ~value; });
|
||||||
addImage(file.fileName(), qMove(image));
|
addImage(file.fileName() + QString(", Decoded in %1 [msec]").arg(time), qMove(image));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (pdf::PDFException exception)
|
catch (pdf::PDFException exception)
|
||||||
|
@ -708,6 +708,17 @@ std::optional<int32_t> PDFJBIG2ArithmeticDecoder::getSignedInteger(PDFJBIG2Arith
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFJBIG2ArithmeticDecoder::finalize()
|
||||||
|
{
|
||||||
|
if (m_lastByte == 0xFF)
|
||||||
|
{
|
||||||
|
if (m_reader->look(8) == 0xAC)
|
||||||
|
{
|
||||||
|
m_reader->read(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFJBIG2ArithmeticDecoder::perform_INITDEC()
|
void PDFJBIG2ArithmeticDecoder::perform_INITDEC()
|
||||||
{
|
{
|
||||||
// Used figure G.1, in annex G, of specification
|
// Used figure G.1, in annex G, of specification
|
||||||
@ -1391,7 +1402,7 @@ void PDFJBIG2Decoder::processSymbolDictionary(const PDFJBIG2SegmentHeader& heade
|
|||||||
uint32_t HCFIRSTSYM = NSYMSDECODED;
|
uint32_t HCFIRSTSYM = NSYMSDECODED;
|
||||||
|
|
||||||
/* 6.5.5 step 4) c) - read height class */
|
/* 6.5.5 step 4) c) - read height class */
|
||||||
while (NSYMSDECODED < parameters.SDNUMNEWSYMS)
|
while (NSYMSDECODED <= parameters.SDNUMNEWSYMS)
|
||||||
{
|
{
|
||||||
/* 6.5.5 step 4) c) i) - Delta width acc. to 6.5.7 */
|
/* 6.5.5 step 4) c) i) - Delta width acc. to 6.5.7 */
|
||||||
std::optional<int32_t> DW = parameters.SDHUFF ? parameters.SDHUFFDW_Decoder.readSignedInteger() : arithmeticDecoder.getSignedInteger(&arithmeticDecoderStates.states[PDFJBIG2ArithmeticDecoderStates::IADW]);
|
std::optional<int32_t> DW = parameters.SDHUFF ? parameters.SDHUFFDW_Decoder.readSignedInteger() : arithmeticDecoder.getSignedInteger(&arithmeticDecoderStates.states[PDFJBIG2ArithmeticDecoderStates::IADW]);
|
||||||
@ -1596,6 +1607,12 @@ void PDFJBIG2Decoder::processSymbolDictionary(const PDFJBIG2SegmentHeader& heade
|
|||||||
while (EXFLAGS.size() < symbolsSize)
|
while (EXFLAGS.size() < symbolsSize)
|
||||||
{
|
{
|
||||||
const uint32_t EXRUNLENGTH = static_cast<uint32_t>(checkInteger(parameters.SDHUFF ? parameters.EXRUNLENGTH_Decoder.readSignedInteger() : arithmeticDecoder.getSignedInteger(&arithmeticDecoderStates.states[PDFJBIG2ArithmeticDecoderStates::IAEX])));
|
const uint32_t EXRUNLENGTH = static_cast<uint32_t>(checkInteger(parameters.SDHUFF ? parameters.EXRUNLENGTH_Decoder.readSignedInteger() : arithmeticDecoder.getSignedInteger(&arithmeticDecoderStates.states[PDFJBIG2ArithmeticDecoderStates::IAEX])));
|
||||||
|
|
||||||
|
if (EXRUNLENGTH + EXFLAGS.size() > symbolsSize)
|
||||||
|
{
|
||||||
|
throw PDFException(PDFTranslationContext::tr("JBIG2 - invalid export flags in symbol dictionary."));
|
||||||
|
}
|
||||||
|
|
||||||
EXFLAGS.insert(EXFLAGS.end(), EXRUNLENGTH, CUREXFLAG);
|
EXFLAGS.insert(EXFLAGS.end(), EXRUNLENGTH, CUREXFLAG);
|
||||||
CUREXFLAG = !CUREXFLAG;
|
CUREXFLAG = !CUREXFLAG;
|
||||||
}
|
}
|
||||||
@ -1603,7 +1620,7 @@ void PDFJBIG2Decoder::processSymbolDictionary(const PDFJBIG2SegmentHeader& heade
|
|||||||
if (!parameters.SDHUFF)
|
if (!parameters.SDHUFF)
|
||||||
{
|
{
|
||||||
// Skipneme 1 byte na konci
|
// Skipneme 1 byte na konci
|
||||||
m_reader.skipBytes(1);
|
arithmeticDecoder.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PDFJBIG2Bitmap> bitmaps;
|
std::vector<PDFJBIG2Bitmap> bitmaps;
|
||||||
@ -1994,6 +2011,11 @@ void PDFJBIG2Decoder::processTextRegion(const PDFJBIG2SegmentHeader& header)
|
|||||||
{
|
{
|
||||||
throw PDFException(PDFTranslationContext::tr("JBIG2 - invalid bitmap for generic region."));
|
throw PDFException(PDFTranslationContext::tr("JBIG2 - invalid bitmap for generic region."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!parameters.SBHUFF)
|
||||||
|
{
|
||||||
|
decoder.finalize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFJBIG2Decoder::processPatternDictionary(const PDFJBIG2SegmentHeader& header)
|
void PDFJBIG2Decoder::processPatternDictionary(const PDFJBIG2SegmentHeader& header)
|
||||||
@ -2190,6 +2212,8 @@ void PDFJBIG2Decoder::processGenericRefinementRegion(const PDFJBIG2SegmentHeader
|
|||||||
{
|
{
|
||||||
throw PDFException(PDFTranslationContext::tr("JBIG2 - invalid bitmap for generic refinement region."));
|
throw PDFException(PDFTranslationContext::tr("JBIG2 - invalid bitmap for generic refinement region."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decoder.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFJBIG2Decoder::processPageInformation(const PDFJBIG2SegmentHeader&)
|
void PDFJBIG2Decoder::processPageInformation(const PDFJBIG2SegmentHeader&)
|
||||||
|
@ -162,6 +162,10 @@ public:
|
|||||||
int32_t getIAID(uint32_t size, PDFJBIG2ArithmeticDecoderState* state);
|
int32_t getIAID(uint32_t size, PDFJBIG2ArithmeticDecoderState* state);
|
||||||
std::optional<int32_t> getSignedInteger(PDFJBIG2ArithmeticDecoderState* state);
|
std::optional<int32_t> getSignedInteger(PDFJBIG2ArithmeticDecoderState* state);
|
||||||
|
|
||||||
|
/// This function is used to read last byte of byte sequence { 0xFF, 0xAC },
|
||||||
|
/// when finishing data stream.
|
||||||
|
void finalize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Performs INITDEC operation as described in the specification
|
/// Performs INITDEC operation as described in the specification
|
||||||
void perform_INITDEC();
|
void perform_INITDEC();
|
||||||
|
Reference in New Issue
Block a user