func PrintRef(w io.Writer, pd *pdfread.PdfReaderT, ref string, fmtref string) { if !strings.HasSuffix(ref, " R") { ref = fmt.Sprintf("%v 0 R", ref) } obj := pd.Obj([]byte(ref)) // print resource info pdutil.Printobj(w, pd, obj, "", ref, maxlevel, fmtref) }
func Page(pd *pdfread.PdfReaderT, page int, xmlDecl bool) []byte { pg := pd.Pages() if page >= len(pg) { complain("Page does not exist!\n") } mbox := util.StringArray(pd.Arr(pd.Att("/MediaBox", pg[page]))) drw := svgdraw.NewTestSvg() svgtext.New(pd, drw).Page = page w := strm.Mul(strm.Sub(mbox[2], mbox[0]), "1.25") h := strm.Mul(strm.Sub(mbox[3], mbox[1]), "1.25") decl := "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" if !xmlDecl { decl = "" } drw.Write.Out("%s"+ "<svg\n"+ " xmlns:svg=\"http://www.w3.org/2000/svg\"\n"+ " xmlns=\"http://www.w3.org/2000/svg\"\n"+ " version=\"1.0\"\n"+ " width=\"%s\"\n"+ " height=\"%s\">\n"+ "<g transform=\"matrix(1.25,0,0,-1.25,%s,%s)\">\n", decl, w, h, strm.Mul(mbox[0], "-1.25"), strm.Mul(mbox[3], "1.25")) cont := pd.ForcedArray(pd.Dic(pg[page])["/Contents"]) _, ps := pd.DecodedStream(cont[0]) drw.Interpret(fancy.SliceReader(ps)) drw.Draw.CloseDrawing() drw.Write.Out("</g>\n</svg>\n") return drw.Write.Content }
func Printobj(w io.Writer, pd *pdfread.PdfReaderT, o []byte, indent, prefix string, maxlevel int, fmtref string) { if IsRef(o) { ref := fmt.Sprintf("<<%s>>", o) //if Debugobj { // fmt.Fprintf(w, "%% %s\n", o) //} o = pd.Obj(o) if prefix == "" { prefix = ref } else { prefix += " " + ref } } if len(o) == 0 { fmt.Fprintf(w, "%s%s %s\n", indent, prefix, "<<empty>>") return } if Debugobj { fmt.Fprintf(w, "%% %s\n", o) } maxlevel -= 1 switch o[0] { case '[': // array a := pdfread.Array(o) fmt.Fprintf(w, "%s%s %s\n", indent, prefix, "[") indent += " " if maxlevel < 0 { fmt.Fprintf(w, "%s<<more>>\n", indent) } else { for i, v := range a { if fmtref != "" && IsRef(v) { fmt.Fprintf(w, "%s%d: ", indent, i) fmt.Fprintf(w, fmtref, v) fmt.Fprintln(w) } else { Printobj(w, pd, v, indent, fmt.Sprintf("%d:", i), maxlevel, fmtref) } } } indent = indent[2:] fmt.Fprintf(w, "%s]\n", indent) case '<': // dictionary d := pdfread.Dictionary(o) fmt.Fprintf(w, "%s%s %s\n", indent, prefix, "{") indent += " " if maxlevel < 0 { fmt.Fprintf(w, "%s<<more>>\n", indent) } else { for k, v := range d { if fmtref != "" && IsRef(v) { fmt.Fprintf(w, "%s%s ", indent, k) fmt.Fprintf(w, fmtref, v) fmt.Fprintln(w) } else { if k == "/Parent" { // backreference - don't follow vv := string(v) if fmtref != "" { vv = fmt.Sprintf(fmtref, v) } fmt.Fprintf(w, "%s%s <<%s>>\n", indent, k, vv) } else { Printobj(w, pd, v, indent, k, maxlevel, fmtref) } } } } indent = indent[2:] fmt.Fprintf(w, "%s}\n", indent) case '/': // symbol fmt.Fprintf(w, "%s%s %s\n", indent, prefix, util.Unescape(o)) case '(': // string fmt.Fprintf(w, "%s%s %q\n", indent, prefix, util.String(o)) default: fmt.Fprintf(w, "%s%s %s\n", indent, prefix, string(o)) } }
func extract(pd *pdfread.PdfReaderT, page int, t *TiffBuilder, next bool) { pg := pd.Pages()[page-1] mbox := util.StringArray(pd.Arr(pd.Att("/MediaBox", pg))) fmt.Println("Page", page) fmt.Println(" MediaBox", mbox) resources := pd.Dic(pd.Att("/Resources", pg)) if xo := pd.Dic(resources["/XObject"]); xo != nil { for name, ref := range xo { dic, data := pd.Stream(ref) printdic(dic, name, " ") if string(dic["/Subtype"]) != "/Image" { continue } switch string(dic["/Filter"]) { case "/CCITTFaxDecode": // TIFF if string(dic["/ColorSpace"]) != "/DeviceGray" { log.Fatal("cannot convert /CCITTFaxDecode ", string(pd.Obj(dic["/ColorSpace"]))) } dparms := pd.Dic(dic["/DecodeParms"]) width := pd.Num(dparms["/Columns"]) height := pd.Num(dparms["/Rows"]) k := pd.Num(dparms["/K"]) bpc := pd.Num(dic["/BitsPerComponent"]) if k >= 0 { // can't do this right now log.Fatal("can't do encoding with K=", k) } t.AddLong(TAG_IMAGE_WIDTH, uint32(width)) t.AddLong(TAG_IMAGE_LENGTH, uint32(height)) t.AddShort(TAG_BITS_PER_SAMPLE, uint16(bpc)) t.AddShort(TAG_COMPRESSION, 4) // CCITT Group 4 t.AddShort(TAG_PHOTOMETRIC_INTERPRETATION, 0) // white is zero t.AddLong(TAG_STRIP_OFFSETS, 0) //t.AddShort(TAG_ORIENTATION, 1) //t.AddShort(TAG_SAMPLES_PER_PIXEL, 1) t.AddLong(TAG_ROWS_PER_STRIP, uint32(height)) t.AddLong(TAG_STRIP_BYTE_COUNTS, uint32(len(data))) //t.AddRational(TAG_X_RESOLUTION, 300, 1) // 300 dpi (300/1) //t.AddRational(TAG_Y_RESOLUTION, 300, 1) // 300 dpi (300/1) //t.AddShort(TAG_RESOLUTION_UNIT, 2) // pixels/inch t.WriteIFD(data, next) case "/DCTDecode": // JPEG /* width := pd.Num(dic["/Width"]) height := pd.Num(dic["/Height"]) bpc := pd.Num(dic["/BitsPerComponent"]) */ f, err := os.Create("test.jpg") if err != nil { log.Fatal(err) } f.Write(data) f.Close() case "/FlateDecode": // compressed bitmap data = fancy.ReadAndClose(zlib.NewReader(fancy.SliceReader(data))) width := pd.Num(dic["/Width"]) height := pd.Num(dic["/Height"]) bpc := pd.Num(dic["/BitsPerComponent"]) if bpc != 8 { log.Fatal("cannot convert /FlateDecode bpc:", bpc) } if string(dic["/ColorSpace"]) != "/DeviceRGB" { log.Fatal("cannot convert /FlateDecode ", string(pd.Obj(dic["/ColorSpace"]))) } ima := image.NewRGBA(image.Rect(0, 0, width, height)) for y := 0; y < height; y++ { for x := 0; x < width; x++ { ima.Set(x, y, color.RGBA{R: data[0], G: data[1], B: data[2], A: 255}) data = data[3:] } } f, err := os.Create("test.png") if err != nil { log.Fatal(err) } png.Encode(f, ima) f.Close() default: log.Fatal("cannot decode ", string(dic["/Filter"])) } } } }