mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-27 13:48:51 +08:00

* Prepared skeleton and basic component implementations for the jbig2 encoding. * Added Bitset. Implemented Bitmap. * Decoder with old Arithmetic Decoder * Partly working arithmetic * Working arithmetic decoder. * MMR patched. * rebuild to apache. * Working generic * Working generic * Decoded full document * Update Jenkinsfile go version [master] (#398) * Update Jenkinsfile go version * Decoded AnnexH document * Minor issues fixed. * Update README.md * Fixed generic region errors. Added benchmark. Added bitmap unpadder. Added Bitmap toImage method. * Fixed endofpage error * Added integration test. * Decoded all test files without errors. Implemented JBIG2Global. * Merged with v3 version * Fixed the EOF in the globals issue * Fixed the JBIG2 ChocolateData Decode * JBIG2 Added license information * Minor fix in jbig2 encoding. * Applied the logging convention * Cleaned unnecessary imports * Go modules clear unused imports * checked out the README.md * Moved trace to Debug. Fixed the build integrate tag in the document_decode_test.go * Initial encoder skeleton * Applied UniPDF Developer Guide. Fixed lint issues. * Cleared documentation, fixed style issues. * Added jbig2 doc.go files. Applied unipdf guide style. * Minor code style changes. * Minor naming and style issues fixes. * Minor naming changes. Style issues fixed. * Review r11 fixes. * Added JBIG2 Encoder skeleton. * Moved Document and Page to jbig2/document package. Created decoder package responsible for decoding jbig2 stream. * Implemented raster functions. * Added raster uni low test funcitons. * Added raster low test functions * untracked files on jbig2-encoder: c869089 Added raster low test functions * index on jbig2-encoder: c869089 Added raster low test functions * Added morph files. * implemented jbig2 encoder basics * JBIG2 Encoder - Generic method * Added jbig2 image encode ttests, black/white image tests * cleaned and tested jbig2 package * unfinished jbig2 classified encoder * jbig2 minor style changes * minor jbig2 encoder changes * prepared JBIG2 Encoder * Style and lint fixes * Minor changes and lints * Fixed shift unsinged value build errors * Minor naming change * Added jbig2 encode, image gondels. Fixed jbig2 decode bug. * Provided jbig2 core.DecodeGlobals function. * Fixed JBIG2Encoder `r6` revision issues. * Removed public JBIG2Encoder document. * Minor style changes * added NewJBIG2Encoder function. * fixed JBIG2Encoder 'r9' revision issues. * Cleared 'r9' commented code. * Updated ACKNOWLEDGEMENETS. Fixed JBIG2Encoder 'r10' revision issues. Co-authored-by: Gunnsteinn Hall <gunnsteinn.hall@gmail.com>
134 lines
3.7 KiB
Go
134 lines
3.7 KiB
Go
/*
|
|
* This file is subject to the terms and conditions defined in
|
|
* file 'LICENSE.md', which is part of this source code package.
|
|
*/
|
|
|
|
package core
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/unidoc/unipdf/v3/common"
|
|
)
|
|
|
|
// NewEncoderFromStream creates a StreamEncoder based on the stream's dictionary.
|
|
func NewEncoderFromStream(streamObj *PdfObjectStream) (StreamEncoder, error) {
|
|
filterObj := TraceToDirectObject(streamObj.PdfObjectDictionary.Get("Filter"))
|
|
if filterObj == nil {
|
|
// No filter, return raw data back.
|
|
return NewRawEncoder(), nil
|
|
}
|
|
|
|
if _, isNull := filterObj.(*PdfObjectNull); isNull {
|
|
// Filter is null -> raw data.
|
|
return NewRawEncoder(), nil
|
|
}
|
|
|
|
// The filter should be a name or an array with a list of filter names.
|
|
method, ok := filterObj.(*PdfObjectName)
|
|
if !ok {
|
|
array, ok := filterObj.(*PdfObjectArray)
|
|
if !ok {
|
|
return nil, fmt.Errorf("filter not a Name or Array object")
|
|
}
|
|
if array.Len() == 0 {
|
|
// Empty array -> indicates raw filter (no filter).
|
|
return NewRawEncoder(), nil
|
|
}
|
|
|
|
if array.Len() != 1 {
|
|
menc, err := newMultiEncoderFromStream(streamObj)
|
|
if err != nil {
|
|
common.Log.Error("Failed creating multi encoder: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
common.Log.Trace("Multi enc: %s\n", menc)
|
|
return menc, nil
|
|
}
|
|
|
|
// Single element.
|
|
filterObj = array.Get(0)
|
|
method, ok = filterObj.(*PdfObjectName)
|
|
if !ok {
|
|
return nil, fmt.Errorf("filter array member not a Name object")
|
|
}
|
|
}
|
|
|
|
switch *method {
|
|
case StreamEncodingFilterNameFlate:
|
|
return newFlateEncoderFromStream(streamObj, nil)
|
|
case StreamEncodingFilterNameLZW:
|
|
return newLZWEncoderFromStream(streamObj, nil)
|
|
case StreamEncodingFilterNameDCT:
|
|
return newDCTEncoderFromStream(streamObj, nil)
|
|
case StreamEncodingFilterNameRunLength:
|
|
return newRunLengthEncoderFromStream(streamObj, nil)
|
|
case StreamEncodingFilterNameASCIIHex:
|
|
return NewASCIIHexEncoder(), nil
|
|
case StreamEncodingFilterNameASCII85, "A85":
|
|
return NewASCII85Encoder(), nil
|
|
case StreamEncodingFilterNameCCITTFax:
|
|
return newCCITTFaxEncoderFromStream(streamObj, nil)
|
|
case StreamEncodingFilterNameJBIG2:
|
|
return newJBIG2DecoderFromStream(streamObj, nil)
|
|
case StreamEncodingFilterNameJPX:
|
|
return NewJPXEncoder(), nil
|
|
}
|
|
common.Log.Debug("ERROR: Unsupported encoding method!")
|
|
return nil, fmt.Errorf("unsupported encoding method (%s)", *method)
|
|
}
|
|
|
|
// DecodeStream decodes the stream data and returns the decoded data.
|
|
// An error is returned upon failure.
|
|
func DecodeStream(streamObj *PdfObjectStream) ([]byte, error) {
|
|
common.Log.Trace("Decode stream")
|
|
|
|
encoder, err := NewEncoderFromStream(streamObj)
|
|
if err != nil {
|
|
common.Log.Debug("ERROR: Stream decoding failed: %v", err)
|
|
return nil, err
|
|
}
|
|
common.Log.Trace("Encoder: %#v\n", encoder)
|
|
|
|
decoded, err := encoder.DecodeStream(streamObj)
|
|
if err != nil {
|
|
common.Log.Debug("ERROR: Stream decoding failed: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
return decoded, nil
|
|
}
|
|
|
|
// EncodeStream encodes the stream data using the encoded specified by the stream's dictionary.
|
|
func EncodeStream(streamObj *PdfObjectStream) error {
|
|
common.Log.Trace("Encode stream")
|
|
|
|
encoder, err := NewEncoderFromStream(streamObj)
|
|
if err != nil {
|
|
common.Log.Debug("Stream decoding failed: %v", err)
|
|
return err
|
|
}
|
|
|
|
if lzwenc, is := encoder.(*LZWEncoder); is {
|
|
// If LZW:
|
|
// Make sure to use EarlyChange 0.. We do not have write support for 1 yet.
|
|
lzwenc.EarlyChange = 0
|
|
streamObj.PdfObjectDictionary.Set("EarlyChange", MakeInteger(0))
|
|
}
|
|
|
|
common.Log.Trace("Encoder: %+v\n", encoder)
|
|
encoded, err := encoder.EncodeBytes(streamObj.Stream)
|
|
if err != nil {
|
|
common.Log.Debug("Stream encoding failed: %v", err)
|
|
return err
|
|
}
|
|
|
|
streamObj.Stream = encoded
|
|
|
|
// Update length
|
|
streamObj.PdfObjectDictionary.Set("Length", MakeInteger(int64(len(encoded))))
|
|
|
|
return nil
|
|
}
|