mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
JBIG2 - symbol dictionary
This commit is contained in:
@ -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,8 +1156,27 @@ 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 */
|
||||||
|
|
||||||
|
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
|
// TODO: JBIG2 read bitmap
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 6.5.5 step 4) c) iii) - update value of widths */
|
/* 6.5.5 step 4) c) iii) - update value of widths */
|
||||||
@ -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(¶meters.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(¶meters.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.
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user