github.com/unidoc/unidoc@v2.2.0+incompatible/pdf/core/stream_test.go (about)

     1  /*
     2   * This file is subject to the terms and conditions defined in
     3   * file 'LICENSE.md', which is part of this source code package.
     4   */
     5  
     6  package core
     7  
     8  import (
     9  	"bytes"
    10  	"compress/zlib"
    11  	"fmt"
    12  	"testing"
    13  
    14  	"github.com/unidoc/unidoc/common"
    15  )
    16  
    17  func init() {
    18  	//common.SetLogger(common.NewConsoleLogger(common.LogLevelDebug))
    19  	//common.SetLogger(common.NewConsoleLogger(common.LogLevelTrace))
    20  }
    21  
    22  // Compare the equality of content of two slices.
    23  func compareSlices(a, b []byte) bool {
    24  	if a == nil && b == nil {
    25  		return true
    26  	}
    27  
    28  	if a == nil || b == nil {
    29  		return false
    30  	}
    31  
    32  	if len(a) != len(b) {
    33  		return false
    34  	}
    35  
    36  	for i := range a {
    37  		if a[i] != b[i] {
    38  			return false
    39  		}
    40  	}
    41  
    42  	return true
    43  }
    44  
    45  // This tests the TIFF predictor (Predictor 2) for PDF.
    46  // Passes the test, but seems not to work on certain PDF files.
    47  func TestFlateTiffPredictor(t *testing.T) {
    48  	// 2 rows of data, 3 colors, 2 columns per row
    49  	rawStream := []byte("\x01\x02\x01\x00\x03\x04\x05\xff\x01\xaf\x01\x02")
    50  	expected := []byte("" +
    51  		"\x01\x02\x01\x01\x05\x05" +
    52  		"\x05\xff\x01\xb4\x00\x03")
    53  	// \x01\x02\x01
    54  	// \x00\x03\x04
    55  	// \x05\xff\x01
    56  	// \xaf\x01\x02
    57  
    58  	var b bytes.Buffer
    59  	w := zlib.NewWriter(&b)
    60  	w.Write(rawStream)
    61  	w.Close()
    62  
    63  	encoded := b.Bytes()
    64  	common.Log.Debug("Compressed length: %d", len(encoded))
    65  
    66  	rawText := `99 0 obj
    67  <<
    68  /DecodeParms << /Predictor 2
    69                  /Colors 3
    70                  /Columns 2
    71               >>
    72  /Filter /FlateDecode
    73  /Length 24
    74  >>
    75  stream
    76  ` + string(encoded) + `endstream
    77  endobj`
    78  
    79  	parser := PdfParser{}
    80  	parser.rs, parser.reader, parser.fileSize = makeReaderForText(rawText)
    81  
    82  	obj, err := parser.ParseIndirectObject()
    83  	if err != nil {
    84  		t.Errorf("Invalid stream object (%s)", err)
    85  		return
    86  	}
    87  
    88  	stream, ok := obj.(*PdfObjectStream)
    89  	if !ok {
    90  		t.Errorf("Not a valid pdf stream")
    91  		return
    92  	}
    93  
    94  	common.Log.Debug("%q", stream)
    95  	dict := stream.PdfObjectDictionary
    96  	common.Log.Debug("dict: %q", dict)
    97  
    98  	if len(stream.Stream) != len(encoded) {
    99  		t.Errorf("Length not %d (%d)", len(encoded), len(stream.Stream))
   100  		return
   101  	}
   102  
   103  	bdec, err := DecodeStream(stream)
   104  	if err != nil {
   105  		t.Errorf("Failed to decode stream (%s)", err)
   106  		return
   107  	}
   108  
   109  	common.Log.Debug("Orig stream: % x\n", stream.Stream)
   110  	common.Log.Debug("Decoded stream: % x\n", bdec)
   111  	if !compareSlices(bdec, expected) {
   112  		common.Log.Debug("Expected: % x\n", expected)
   113  		t.Errorf("decoded != expected")
   114  		return
   115  	}
   116  }
   117  
   118  // Tests a stream with multi encoded.
   119  func TestMultiEncodedStream(t *testing.T) {
   120  	// 2 rows of data, 3 colors, 2 columns per row
   121  	encoded := []byte("78 9C 2A C9 C8 2C 56 00 A2 44 85 94 D2 DC DC 4A 85 92 D4 8A 12 85 F2 CC 92 0C 85 E2 FC DC 54 05 46 26 66 85 A4 CC " +
   122  		"BC C4 A2 4A 85 94 C4 92 44 40 00 00 00 FF FF 78 87 0F 9C >")
   123  
   124  	expected := []byte("this is a dummy text with some \x01\x02\x03 binary data")
   125  
   126  	common.Log.Debug("Compressed length: %d", len(encoded))
   127  
   128  	rawText := `99 0 obj
   129  <<
   130  /DecodeParms << /Predictor 1 /Colors 3 /Columns 2 >>
   131  /Filter [/ASCIIHexDecode /FlateDecode]
   132  /Length ` + fmt.Sprintf("%d", len(encoded)) + `
   133  >>
   134  stream
   135  ` + string(encoded) + `endstream
   136  endobj`
   137  
   138  	parser := PdfParser{}
   139  	parser.rs, parser.reader, parser.fileSize = makeReaderForText(rawText)
   140  
   141  	obj, err := parser.ParseIndirectObject()
   142  	if err != nil {
   143  		t.Errorf("Invalid stream object (%s)", err)
   144  		return
   145  	}
   146  
   147  	stream, ok := obj.(*PdfObjectStream)
   148  	if !ok {
   149  		t.Errorf("Not a valid pdf stream")
   150  		return
   151  	}
   152  
   153  	common.Log.Debug("%q", stream)
   154  	dict := stream.PdfObjectDictionary
   155  	common.Log.Debug("dict: %q", dict)
   156  
   157  	if len(stream.Stream) != len(encoded) {
   158  		t.Errorf("Length not %d (%d)", len(encoded), len(stream.Stream))
   159  		return
   160  	}
   161  
   162  	bdec, err := DecodeStream(stream)
   163  	if err != nil {
   164  		t.Errorf("Failed to decode stream (%s)", err)
   165  		return
   166  	}
   167  
   168  	common.Log.Debug("Stream: %s", stream.Stream)
   169  	common.Log.Debug("Decoded stream: % x", bdec)
   170  
   171  	if !compareSlices(bdec, expected) {
   172  		common.Log.Debug("Expected: % x", expected)
   173  		t.Errorf("decoded != expected")
   174  		return
   175  	}
   176  
   177  }