JBIG2 - symbol dictionary

This commit is contained in:
Jakub Melka
2019-10-31 16:52:44 +01:00
parent a77bfbd896
commit ca78f61260
2 changed files with 98 additions and 15 deletions

View File

@ -1054,6 +1054,8 @@ void PDFJBIG2Decoder::processSymbolDictionary(const PDFJBIG2SegmentHeader& heade
throw PDFException(PDFTranslationContext::tr("JBIG2 invalid user huffman code table.")); throw PDFException(PDFTranslationContext::tr("JBIG2 invalid user huffman code table."));
} }
parameters.EXRUNLENGTH_Decoder = PDFJBIG2HuffmanDecoder(&m_reader, std::begin(PDFJBIG2StandardHuffmanTable_A), std::end(PDFJBIG2StandardHuffmanTable_A));
if (currentUserCodeTableIndex != references.codeTables.size()) if (currentUserCodeTableIndex != references.codeTables.size())
{ {
throw PDFException(PDFTranslationContext::tr("JBIG2 invalid number of huffam code table - %1 unused.").arg(references.codeTables.size() - currentUserCodeTableIndex)); throw PDFException(PDFTranslationContext::tr("JBIG2 invalid number of huffam code table - %1 unused.").arg(references.codeTables.size() - currentUserCodeTableIndex));
@ -1097,11 +1099,13 @@ void PDFJBIG2Decoder::processSymbolDictionary(const PDFJBIG2SegmentHeader& heade
PDFJBIG2ArithmeticDecoder decoder(&m_reader); PDFJBIG2ArithmeticDecoder decoder(&m_reader);
PDFJBIG2ArithmeticDecoderState IADH; PDFJBIG2ArithmeticDecoderState IADH;
PDFJBIG2ArithmeticDecoderState IADW; PDFJBIG2ArithmeticDecoderState IADW;
PDFJBIG2ArithmeticDecoderState IAEX;
if (!parameters.SDHUFF) if (!parameters.SDHUFF)
{ {
decoder.initialize(); decoder.initialize();
IADH.reset(9); IADH.reset(9);
IADW.reset(9); IADW.reset(9);
IAEX.reset(9);
} }
/* 6.5.5 - algorithm for decoding symbol dictionary */ /* 6.5.5 - algorithm for decoding symbol dictionary */
@ -1152,7 +1156,26 @@ void PDFJBIG2Decoder::processSymbolDictionary(const PDFJBIG2SegmentHeader& heade
if (parameters.SDHUFF == 0 || parameters.SDREFAGG == 1) if (parameters.SDHUFF == 0 || parameters.SDREFAGG == 1)
{ {
/* 6.5.5 step 4) c) ii) - read bitmap acc. to 6.5.8 */ /* 6.5.5 step 4) c) ii) - read bitmap acc. to 6.5.8 */
// TODO: JBIG2 read bitmap
if (parameters.SDREFAGG == 0)
{
/* 6.5.8.1 Direct-coded symbol bitmap, using Table 16 */
PDFJBIG2BitmapDecodingParameters bitmapParameters;
bitmapParameters.MMR = false;
bitmapParameters.GBW = SYMWIDTH;
bitmapParameters.GBH = HCHEIGHT;
bitmapParameters.GBTEMPLATE = parameters.SDTEMPLATE;
bitmapParameters.TPGDON = false;
bitmapParameters.ATXY = parameters.SDAT;
bitmapParameters.arithmeticDecoder = &decoder;
bitmapParameters.arithmeticDecoderState = &m_arithmeticDecoderStates[Generic];
parameters.SDNEWSYMS[NSYMSDECODED] = readBitmap(bitmapParameters);
}
else
{
/* 6.5.8.2 Refinement/aggregate-coded symbol bitmap */
// TODO: JBIG2 read bitmap
}
} }
else else
{ {
@ -1168,9 +1191,55 @@ void PDFJBIG2Decoder::processSymbolDictionary(const PDFJBIG2SegmentHeader& heade
// TODO: JBIG2 - create collective bitmap // TODO: JBIG2 - create collective bitmap
} }
/* 6.5.5 step 5) - determine exports */ /* 6.5.5 step 5) - determine exports according to 6.5.10 */
std::vector<bool> EXFLAGS;
const size_t symbolsSize = parameters.SDNUMINSYMS + parameters.SDNEWSYMS.size();
EXFLAGS.reserve(symbolsSize);
bool CUREXFLAG = false;
while (EXFLAGS.size() < symbolsSize)
{
const uint32_t EXRUNLENGTH = static_cast<uint32_t>(checkInteger(parameters.SDHUFF ? parameters.EXRUNLENGTH_Decoder.readSignedInteger() : decoder.getSignedInteger(&IAEX)));
EXFLAGS.insert(EXFLAGS.end(), EXRUNLENGTH, CUREXFLAG);
CUREXFLAG = !CUREXFLAG;
}
m_reader.alignToBytes();
if (!parameters.SDHUFF)
{
// Skipneme 1 byte na konci
m_reader.skipBytes(1);
}
// TODO: JBIG2 - dodelat std::vector<PDFJBIG2Bitmap> bitmaps;
bitmaps.reserve(parameters.SDNUMEXSYMS);
// Insert input bitmaps
for (size_t i = 0; i < parameters.SDNUMINSYMS; ++i)
{
if (EXFLAGS[i])
{
bitmaps.push_back(*parameters.SDINSYMS[i]);
}
}
// Insert output bitmaps
for (size_t i = 0; i < NSYMSDECODED; ++i)
{
if (EXFLAGS[i + parameters.SDNUMINSYMS])
{
bitmaps.push_back(parameters.SDNEWSYMS[i]);
}
}
PDFJBIG2ArithmeticDecoderState savedGeneric;
PDFJBIG2ArithmeticDecoderState savedRefine;
if (parameters.isArithmeticCodingStateRetained)
{
savedGeneric = qMove(m_arithmeticDecoderStates[Generic]);
savedRefine = qMove(m_arithmeticDecoderStates[Refinement]);
}
m_segments[header.getSegmentNumber()] = std::make_unique<PDFJBIG2SymbolDictionary>(qMove(bitmaps), qMove(savedGeneric), qMove(savedRefine));
} }
void PDFJBIG2Decoder::processTextRegion(const PDFJBIG2SegmentHeader& header) void PDFJBIG2Decoder::processTextRegion(const PDFJBIG2SegmentHeader& header)
@ -1242,11 +1311,22 @@ void PDFJBIG2Decoder::processGenericRegion(const PDFJBIG2SegmentHeader& header)
segmentDataBytes = endPosition - segmentDataStartPosition; segmentDataBytes = endPosition - segmentDataStartPosition;
} }
parameters.data = m_reader.getStream()->mid(segmentDataStartPosition, segmentDataBytes); parameters.data = m_reader.getStream()->mid(segmentDataStartPosition, segmentDataBytes);
parameters.width = field.width; parameters.GBW = field.width;
parameters.height = field.height; parameters.GBH = field.height;
parameters.arithmeticDecoderState = &m_arithmeticDecoderStates[Generic]; parameters.arithmeticDecoderState = &m_arithmeticDecoderStates[Generic];
PDFBitReader reader(&parameters.data, 1);
PDFJBIG2ArithmeticDecoder decoder(&reader);
if (!parameters.MMR)
{
decoder.initialize();
parameters.arithmeticDecoder = &decoder;
}
PDFJBIG2Bitmap bitmap = readBitmap(parameters); PDFJBIG2Bitmap bitmap = readBitmap(parameters);
if (bitmap.isValid()) if (bitmap.isValid())
{ {
@ -1552,8 +1632,8 @@ PDFJBIG2Bitmap PDFJBIG2Decoder::readBitmap(const PDFJBIG2BitmapDecodingParameter
// Use modified-modified-read (it corresponds to CCITT 2D encoding) // Use modified-modified-read (it corresponds to CCITT 2D encoding)
PDFCCITTFaxDecoderParameters ccittParameters; PDFCCITTFaxDecoderParameters ccittParameters;
ccittParameters.K = -1; ccittParameters.K = -1;
ccittParameters.columns = parameters.width; ccittParameters.columns = parameters.GBW;
ccittParameters.rows = parameters.height; ccittParameters.rows = parameters.GBH;
ccittParameters.hasEndOfBlock = false; ccittParameters.hasEndOfBlock = false;
ccittParameters.decode = { 1.0, 0.0 }; ccittParameters.decode = { 1.0, 0.0 };
ccittParameters.hasBlackIsOne = true; ccittParameters.hasBlackIsOne = true;
@ -1610,12 +1690,11 @@ PDFJBIG2Bitmap PDFJBIG2Decoder::readBitmap(const PDFJBIG2BitmapDecodingParameter
} }
} }
PDFBitReader reader(&parameters.data, 1); Q_ASSERT(parameters.arithmeticDecoder);
PDFJBIG2ArithmeticDecoder decoder(&reader); PDFJBIG2ArithmeticDecoder& decoder = *parameters.arithmeticDecoder;
decoder.initialize();
PDFJBIG2Bitmap bitmap(parameters.width, parameters.height, 0x00); PDFJBIG2Bitmap bitmap(parameters.GBW, parameters.GBH, 0x00);
for (int y = 0; y < parameters.height; ++y) for (int y = 0; y < parameters.GBH; ++y)
{ {
// Check TPGDON prediction - if we use same pixels as in previous line // Check TPGDON prediction - if we use same pixels as in previous line
if (parameters.TPGDON) if (parameters.TPGDON)
@ -1631,7 +1710,7 @@ PDFJBIG2Bitmap PDFJBIG2Decoder::readBitmap(const PDFJBIG2BitmapDecodingParameter
} }
} }
for (int x = 0; x < parameters.width; ++x) for (int x = 0; x < parameters.GBW; ++x)
{ {
// Check, if we have to skip pixel. Pixel should be set to 0, but it is done // Check, if we have to skip pixel. Pixel should be set to 0, but it is done
// in the initialization of the bitmap. // in the initialization of the bitmap.

View File

@ -449,10 +449,10 @@ struct PDFJBIG2BitmapDecodingParameters
bool TPGDON = false; bool TPGDON = false;
/// Width of the image /// Width of the image
int width = 0; int GBW = 0;
/// Height of the image /// Height of the image
int height = 0; int GBH = 0;
/// Template mode (not used for MMR). /// Template mode (not used for MMR).
uint8_t GBTEMPLATE = 0; uint8_t GBTEMPLATE = 0;
@ -469,6 +469,9 @@ struct PDFJBIG2BitmapDecodingParameters
/// Skip bitmap (pixel is skipped if corresponding pixel in the /// Skip bitmap (pixel is skipped if corresponding pixel in the
/// skip bitmap is 1). Set to nullptr, if not used. /// skip bitmap is 1). Set to nullptr, if not used.
const PDFJBIG2Bitmap* SKIP = nullptr; const PDFJBIG2Bitmap* SKIP = nullptr;
/// Arithmetic decoder (used, if MMR == false)
PDFJBIG2ArithmeticDecoder* arithmeticDecoder = nullptr;
}; };
/// Info structure for refinement bitmap decoding parameters /// Info structure for refinement bitmap decoding parameters
@ -553,6 +556,7 @@ struct PDFJBIG2SymbolDictionaryDecodingParameters
PDFJBIG2HuffmanDecoder SDHUFFDW_Decoder; PDFJBIG2HuffmanDecoder SDHUFFDW_Decoder;
PDFJBIG2HuffmanDecoder SDHUFFBMSIZE_Decoder; PDFJBIG2HuffmanDecoder SDHUFFBMSIZE_Decoder;
PDFJBIG2HuffmanDecoder SDHUFFAGGINST_Decoder; PDFJBIG2HuffmanDecoder SDHUFFAGGINST_Decoder;
PDFJBIG2HuffmanDecoder EXRUNLENGTH_Decoder;
/// Input bitmaps /// Input bitmaps
std::vector<const PDFJBIG2Bitmap*> SDINSYMS; std::vector<const PDFJBIG2Bitmap*> SDINSYMS;