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."));
}
parameters.EXRUNLENGTH_Decoder = PDFJBIG2HuffmanDecoder(&m_reader, std::begin(PDFJBIG2StandardHuffmanTable_A), std::end(PDFJBIG2StandardHuffmanTable_A));
if (currentUserCodeTableIndex != references.codeTables.size())
{
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);
PDFJBIG2ArithmeticDecoderState IADH;
PDFJBIG2ArithmeticDecoderState IADW;
PDFJBIG2ArithmeticDecoderState IAEX;
if (!parameters.SDHUFF)
{
decoder.initialize();
IADH.reset(9);
IADW.reset(9);
IAEX.reset(9);
}
/* 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)
{
/* 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
{
@ -1168,9 +1191,55 @@ void PDFJBIG2Decoder::processSymbolDictionary(const PDFJBIG2SegmentHeader& heade
// 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)
@ -1242,11 +1311,22 @@ void PDFJBIG2Decoder::processGenericRegion(const PDFJBIG2SegmentHeader& header)
segmentDataBytes = endPosition - segmentDataStartPosition;
}
parameters.data = m_reader.getStream()->mid(segmentDataStartPosition, segmentDataBytes);
parameters.width = field.width;
parameters.height = field.height;
parameters.GBW = field.width;
parameters.GBH = field.height;
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);
if (bitmap.isValid())
{
@ -1552,8 +1632,8 @@ PDFJBIG2Bitmap PDFJBIG2Decoder::readBitmap(const PDFJBIG2BitmapDecodingParameter
// Use modified-modified-read (it corresponds to CCITT 2D encoding)
PDFCCITTFaxDecoderParameters ccittParameters;
ccittParameters.K = -1;
ccittParameters.columns = parameters.width;
ccittParameters.rows = parameters.height;
ccittParameters.columns = parameters.GBW;
ccittParameters.rows = parameters.GBH;
ccittParameters.hasEndOfBlock = false;
ccittParameters.decode = { 1.0, 0.0 };
ccittParameters.hasBlackIsOne = true;
@ -1610,12 +1690,11 @@ PDFJBIG2Bitmap PDFJBIG2Decoder::readBitmap(const PDFJBIG2BitmapDecodingParameter
}
}
PDFBitReader reader(&parameters.data, 1);
PDFJBIG2ArithmeticDecoder decoder(&reader);
decoder.initialize();
Q_ASSERT(parameters.arithmeticDecoder);
PDFJBIG2ArithmeticDecoder& decoder = *parameters.arithmeticDecoder;
PDFJBIG2Bitmap bitmap(parameters.width, parameters.height, 0x00);
for (int y = 0; y < parameters.height; ++y)
PDFJBIG2Bitmap bitmap(parameters.GBW, parameters.GBH, 0x00);
for (int y = 0; y < parameters.GBH; ++y)
{
// Check TPGDON prediction - if we use same pixels as in previous line
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
// in the initialization of the bitmap.

View File

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