fix wrong git ignore
This commit is contained in:
129
internal/pdf/core/stream.go
Normal file
129
internal/pdf/core/stream.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/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 len(*array) == 0 {
|
||||
// Empty array -> indicates raw filter (no filter).
|
||||
return NewRawEncoder(), nil
|
||||
}
|
||||
|
||||
if len(*array) != 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)[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()
|
||||
case StreamEncodingFilterNameASCIIHex:
|
||||
return NewASCIIHexEncoder(), nil
|
||||
case StreamEncodingFilterNameASCII85, "A85":
|
||||
return NewASCII85Encoder(), nil
|
||||
case StreamEncodingFilterNameCCITTFax:
|
||||
return NewCCITTFaxEncoder(), nil
|
||||
case StreamEncodingFilterNameJBIG2:
|
||||
return NewJBIG2Encoder(), nil
|
||||
case StreamEncodingFilterNameJPX:
|
||||
return NewJPXEncoder(), nil
|
||||
default:
|
||||
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("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("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
|
||||
}
|
||||
Reference in New Issue
Block a user