diff --git a/pdf/model/colorspace_test.go b/pdf/model/colorspace_test.go index b68f2f9d..823bd48a 100644 --- a/pdf/model/colorspace_test.go +++ b/pdf/model/colorspace_test.go @@ -6,8 +6,13 @@ package model import ( + "bytes" "fmt" + "io/ioutil" "testing" + + "github.com/unidoc/unidoc/pdf/core" + "github.com/unidoc/unidoc/pdf/internal/testutils" ) func TestSeparationCS1(t *testing.T) { @@ -44,3 +49,128 @@ func TestDeviceNCS1(t *testing.T) { //t.Errorf("Test not implemented yet") } + +// Bug with outputing Separation colorspaces using a Function0 function. +func TestColorspaceLoading(t *testing.T) { + rawpdf := []byte(` +10 0 obj +<< + /ColorSpace << + /R99 99 0 R + /R86 86 0 R + /R88 88 0 R + >> +>> +endobj +99 0 obj +[/Separation /All 86 0 R 87 0 R] +endobj +86 0 obj +[/ICCBased 85 0 R] +endobj +88 0 obj +[/Separation /Black 86 0 R 87 0 R] +endobj +85 0 obj +<< + /N 3 + /Alternate /DeviceRGB + /Length 3144 +>> +stream +!!STREAMDATA2!! +endstream endobj +87 0 obj +<< + /Size [255] + /BitsPerSample 8 + /Domain [0 1] + /Length 765 + /Encode [0 254] + /Decode [0 1 0 1 0 1] + /Range [0 1 0 1 0 1] + /FunctionType 0 +>> +stream +!!STREAMDATA1!! +endstream endobj +`) + functype0, err := ioutil.ReadFile(`testdata/cs_functype0.bin`) + if err != nil { + t.Fatalf("Error: %v", err) + } + + iccdata, err := ioutil.ReadFile(`testdata/iccstream.bin`) + if err != nil { + t.Fatalf("Error: %v", err) + } + + rawpdf = bytes.Replace(rawpdf, []byte("!!STREAMDATA1!!"), functype0, 1) + rawpdf = bytes.Replace(rawpdf, []byte("!!STREAMDATA2!!"), iccdata, 1) + //fmt.Printf("%s\n", rawpdf) + + objMap, err := testutils.ParseIndirectObjects(string(rawpdf)) + if err != nil { + t.Fatalf("Error: %v", err) + } + if len(objMap) != 6 { + t.Fatalf("len(objMap) != 6 (%d)", len(objMap)) + } + + resourceDict, ok := core.GetDict(objMap[10]) + if !ok { + t.Fatalf("Resource object missing dictionary") + } + + resources, err := NewPdfPageResourcesFromDict(resourceDict) + if err != nil { + t.Fatalf("Error loading resources: %v", err) + } + + fmt.Printf("Out\n") + fmt.Printf("%s\n", resources.ToPdfObject()) + outDict, ok := core.GetDict(resources.ToPdfObject()) + if !ok { + t.Fatalf("error") + } + fmt.Printf("%s\n", outDict.DefaultWriteString()) + r99, ok := resources.GetColorspaceByName("R99") + if !ok { + t.Fatalf("error") + } + + array, ok := core.GetArray(r99.ToPdfObject()) + if !ok { + t.Fatalf("error") + } + + if array.Len() != 4 { + t.Fatalf("len != 4 (got %d)", array.Len()) + } + + name, ok := core.GetName(array.Get(0)) + if !ok || *name != "Separation" { + t.Fatalf("Unexpected value") + } + + name, ok = core.GetName(array.Get(1)) + if !ok || *name != "All" { + t.Fatalf("Unexpected value") + } + + ind, ok := core.GetIndirect(array.Get(2)) + if !ok { + t.Fatalf("error") + } + if ind.ObjectNumber != 86 { + t.Fatalf("Incorrect obj num") + } + + f, ok := core.GetStream(array.Get(3)) + if !ok { + t.Fatalf("Stream get error") + } + if f.ObjectNumber != 87 { + t.Fatalf("Incorrect function obj number (got %d)", f.ObjectNumber) + } +} diff --git a/pdf/model/functions.go b/pdf/model/functions.go index fc80d051..4d908c4e 100644 --- a/pdf/model/functions.go +++ b/pdf/model/functions.go @@ -229,8 +229,7 @@ func newPdfFunctionType0FromStream(stream *PdfObjectStream) (*PdfFunctionType0, } func (this *PdfFunctionType0) ToPdfObject() PdfObject { - container := this.container - if container != nil { + if this.container == nil { this.container = &PdfObjectStream{} } @@ -267,10 +266,10 @@ func (this *PdfFunctionType0) ToPdfObject() PdfObject { // TODO: Encode. // Either here, or automatically later on when writing out. dict.Set("Length", MakeInteger(int64(len(this.rawData)))) - container.Stream = this.rawData + this.container.Stream = this.rawData - container.PdfObjectDictionary = dict - return container + this.container.PdfObjectDictionary = dict + return this.container } func (this *PdfFunctionType0) Evaluate(x []float64) ([]float64, error) { diff --git a/pdf/model/reader.go b/pdf/model/reader.go index 6a3c4db0..5b38532f 100644 --- a/pdf/model/reader.go +++ b/pdf/model/reader.go @@ -530,7 +530,7 @@ func (this *PdfReader) buildPageList(node *PdfIndirectObject, parent *PdfIndirec if !ok { return errors.New("Node missing Type (Required)") } - common.Log.Trace("buildPageList node type: %s", *objType) + common.Log.Trace("buildPageList node type: %s (%+v)", *objType, node) if *objType == "Page" { p, err := this.newPdfPageFromDict(nodeDict) if err != nil { diff --git a/pdf/model/testdata/cs_functype0.bin b/pdf/model/testdata/cs_functype0.bin new file mode 100644 index 00000000..e5cd6933 --- /dev/null +++ b/pdf/model/testdata/cs_functype0.bin @@ -0,0 +1 @@ +~~}|~~{~}{}|z||y{{x{zxzywyyvyxuxwuwvtvvsvurutrtsqsspsrorqoqpnppmoolonknmkmljllikkhkjhjigihfhheggdgfdfeceebddadc`cb`ba_aa^``]`_]_^\^^[]]Z]\Z\[Y[ZXZZWYYVXXUWWTVVSUURTTQTSPSRORQNQPNPOMONLNMKMLJLKIKJHJIGIIFHHEGGDFFCEEBDDACC@CB@BA?A@>@?=?><>=;==:<<9;:8:9798687566455344233122/11.0/-/.,.-+,,*++)**())'((&''%&&$%%#$$"##!"" !!  \ No newline at end of file diff --git a/pdf/model/testdata/iccstream.bin b/pdf/model/testdata/iccstream.bin new file mode 100644 index 00000000..7f9d18d0 Binary files /dev/null and b/pdf/model/testdata/iccstream.bin differ