github.com/pdfcpu/pdfcpu@v0.11.1/pkg/filter/ccittDecode.go (about)

     1  /*
     2  Copyright 2018 The pdfcpu Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package filter
    18  
    19  import (
    20  	"bytes"
    21  	"io"
    22  
    23  	"github.com/pdfcpu/pdfcpu/pkg/log"
    24  	"github.com/pkg/errors"
    25  	"golang.org/x/image/ccitt"
    26  )
    27  
    28  type ccittDecode struct {
    29  	baseFilter
    30  }
    31  
    32  // Encode implements encoding for a CCITTDecode filter.
    33  func (f ccittDecode) Encode(r io.Reader) (io.Reader, error) {
    34  	// TODO
    35  	return nil, nil
    36  }
    37  
    38  // Decode implements decoding for a CCITTDecode filter.
    39  func (f ccittDecode) Decode(r io.Reader) (io.Reader, error) {
    40  	return f.DecodeLength(r, -1)
    41  }
    42  
    43  func (f ccittDecode) DecodeLength(r io.Reader, maxLen int64) (io.Reader, error) {
    44  	if log.TraceEnabled() {
    45  		log.Trace.Println("DecodeCCITT begin")
    46  	}
    47  
    48  	var ok bool
    49  
    50  	// <0 : Pure two-dimensional encoding (Group 4)
    51  	// =0 : Pure one-dimensional encoding (Group 3, 1-D)
    52  	// >0 : Mixed one- and two-dimensional encoding (Group 3, 2-D)
    53  	k := 0
    54  	k, ok = f.parms["K"]
    55  	if ok && k > 0 {
    56  		return nil, errors.New("pdfcpu: filter CCITTFax k > 0 currently unsupported")
    57  	}
    58  
    59  	cols := 1728
    60  	col, ok := f.parms["Columns"]
    61  	if ok {
    62  		cols = col
    63  	}
    64  
    65  	rows, ok := f.parms["Rows"]
    66  	if !ok {
    67  		return nil, errors.New("pdfcpu: ccitt: missing DecodeParam \"Rows\"")
    68  	}
    69  
    70  	blackIs1 := false
    71  	v, ok := f.parms["BlackIs1"]
    72  	if ok && v == 1 {
    73  		blackIs1 = true
    74  	}
    75  
    76  	encodedByteAlign := false
    77  	v, ok = f.parms["EncodedByteAlign"]
    78  	if ok && v == 1 {
    79  		encodedByteAlign = true
    80  	}
    81  
    82  	opts := &ccitt.Options{Invert: blackIs1, Align: encodedByteAlign}
    83  
    84  	mode := ccitt.Group3
    85  	if k < 0 {
    86  		mode = ccitt.Group4
    87  	}
    88  	rd := ccitt.NewReader(r, ccitt.MSB, mode, cols, rows, opts)
    89  
    90  	var b bytes.Buffer
    91  	written, err := io.Copy(&b, rd)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	if log.TraceEnabled() {
    97  		log.Trace.Printf("DecodeCCITT: decoded %d bytes.\n", written)
    98  	}
    99  
   100  	return &b, nil
   101  }