mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-27 13:48:51 +08:00
99 lines
34 KiB
Go
99 lines
34 KiB
Go
//
|
|
// Copyright 2020 FoxyUtils ehf. All rights reserved.
|
|
//
|
|
// This is a commercial product and requires a license to operate.
|
|
// A trial license can be obtained at https://unidoc.io
|
|
//
|
|
// DO NOT EDIT: generated by unitwist Go source code obfuscator.
|
|
//
|
|
// Use of this source code is governed by the UniDoc End User License Agreement
|
|
// terms that can be accessed at https://unidoc.io/eula/
|
|
|
|
package optimize ;import (_gb "bytes";_g "crypto/md5";_gf "errors";_af "fmt";_fd "github.com/unidoc/unipdf/v3/common";_dba "github.com/unidoc/unipdf/v3/contentstream";_a "github.com/unidoc/unipdf/v3/core";_db "github.com/unidoc/unipdf/v3/extractor";_b "github.com/unidoc/unipdf/v3/internal/textencoding";_dg "github.com/unidoc/unipdf/v3/model";_fg "github.com/unidoc/unitype";_d "golang.org/x/image/draw";_ad "image";_f "math";);func _cdfg (_afgb _a .PdfObject )(_abga string ,_dfae []_a .PdfObject ){var _cdfc _gb .Buffer ;switch _acb :=_afgb .(type ){case *_a .PdfIndirectObject :_dfae =append (_dfae ,_acb );_afgb =_acb .PdfObject ;};switch _dcef :=_afgb .(type ){case *_a .PdfObjectStream :if _ebfg ,_befd :=_a .DecodeStream (_dcef );_befd ==nil {_cdfc .Write (_ebfg );_dfae =append (_dfae ,_dcef );};case *_a .PdfObjectArray :for _ ,_fbe :=range _dcef .Elements (){switch _cec :=_fbe .(type ){case *_a .PdfObjectStream :if _adde ,_afd :=_a .DecodeStream (_cec );_afd ==nil {_cdfc .Write (_adde );_dfae =append (_dfae ,_cec );};};};};return _cdfc .String (),_dfae ;};
|
|
|
|
// CleanContentstream cleans up redundant operands in content streams, including Page and XObject Form
|
|
// contents. This process includes:
|
|
// 1. Marked content operators are removed.
|
|
// 2. Some operands are simplified (shorter form).
|
|
// TODO: Add more reduction methods and improving the methods for identifying unnecessary operands.
|
|
type CleanContentstream struct{};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_gfe *Image )Optimize (objects []_a .PdfObject )(_bbcc []_a .PdfObject ,_fdfc error ){if _gfe .ImageQuality <=0{return objects ,nil ;};_bec :=_acg (objects );if len (_bec )==0{return objects ,nil ;};_aafb :=make (map[_a .PdfObject ]_a .PdfObject );_eddb :=make (map[_a .PdfObject ]struct{});for _ ,_ced :=range _bec {_efc :=_ced .Stream .PdfObjectDictionary .Get (_a .PdfObjectName ("\u0053\u004d\u0061s\u006b"));_eddb [_efc ]=struct{}{};};for _efgc ,_fddc :=range _bec {_cfc :=_fddc .Stream ;if _ ,_bafb :=_eddb [_cfc ];_bafb {continue ;};_ddbd ,_adbc :=_a .NewEncoderFromStream (_cfc );if _adbc !=nil {_fd .Log .Warning ("\u0045\u0072\u0072\u006f\u0072 \u0067\u0065\u0074\u0020\u0065\u006e\u0063\u006f\u0064\u0065\u0072\u0020\u0066o\u0072\u0020\u0074\u0068\u0065\u0020\u0069\u006d\u0061\u0067\u0065\u0020\u0073\u0074\u0072\u0065\u0061\u006d\u0020\u0025\u0073");continue ;};_cfcc ,_adbc :=_ddbd .DecodeStream (_cfc );if _adbc !=nil {_fd .Log .Warning ("\u0045\u0072\u0072\u006f\u0072\u0020\u0064\u0065\u0063\u006f\u0064\u0065\u0020\u0074\u0068e\u0020i\u006d\u0061\u0067\u0065\u0020\u0073\u0074\u0072\u0065\u0061\u006d\u0020\u0025\u0073");continue ;};_gebe :=_a .NewDCTEncoder ();_gebe .ColorComponents =_fddc .ColorComponents ;_gebe .Quality =_gfe .ImageQuality ;_gebe .BitsPerComponent =_fddc .BitsPerComponent ;_gebe .Width =_fddc .Width ;_gebe .Height =_fddc .Height ;_aabd ,_adbc :=_gebe .EncodeBytes (_cfcc );if _adbc !=nil {_fd .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_adbc );return nil ,_adbc ;};var _fbd _a .StreamEncoder ;_fbd =_gebe ;{_dad :=_a .NewFlateEncoder ();_deb :=_a .NewMultiEncoder ();_deb .AddEncoder (_dad );_deb .AddEncoder (_gebe );_bcd ,_gbf :=_deb .EncodeBytes (_cfcc );if _gbf !=nil {return nil ,_gbf ;};if len (_bcd )< len (_aabd ){_fd .Log .Debug ("\u004d\u0075\u006c\u0074\u0069\u0020\u0065\u006e\u0063\u0020\u0069\u006d\u0070\u0072\u006f\u0076\u0065\u0073\u003a\u0020\u0025\u0064\u0020\u0074o\u0020\u0025\u0064\u0020\u0028o\u0072\u0069g\u0020\u0025\u0064\u0029",len (_aabd ),len (_bcd ),len (_cfc .Stream ));_aabd =_bcd ;_fbd =_deb ;};};_dac :=len (_cfc .Stream );if _dac < len (_aabd ){continue ;};_cebc :=&_a .PdfObjectStream {Stream :_aabd };_cebc .PdfObjectReference =_cfc .PdfObjectReference ;_cebc .PdfObjectDictionary =_a .MakeDict ();_cebc .Merge (_cfc .PdfObjectDictionary );_cebc .Merge (_fbd .MakeStreamDict ());_cebc .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_a .MakeInteger (int64 (len (_aabd ))));_aafb [_cfc ]=_cebc ;_bec [_efgc ].Stream =_cebc ;};_bbcc =make ([]_a .PdfObject ,len (objects ));copy (_bbcc ,objects );_fdca (_bbcc ,_aafb );return _bbcc ,nil ;};
|
|
|
|
// Append appends optimizers to the chain.
|
|
func (_cf *Chain )Append (optimizers ..._dg .Optimizer ){_cf ._fgf =append (_cf ._fgf ,optimizers ...)};func _cebb (_fde *_a .PdfObjectStream ,_cdf float64 )error {_afa ,_aaef :=_dg .NewXObjectImageFromStream (_fde );if _aaef !=nil {return _aaef ;};_gab ,_aaef :=_afa .ToImage ();if _aaef !=nil {return _aaef ;};_gdc ,_aaef :=_gab .ToGoImage ();if _aaef !=nil {return _aaef ;};_abcg :=int (_f .RoundToEven (float64 (_gab .Width )*_cdf ));_adbcd :=int (_f .RoundToEven (float64 (_gab .Height )*_cdf ));_gdgb :=_ad .Rect (0,0,_abcg ,_adbcd );var _ebe _d .Image ;var _cga func (_ad .Image )(*_dg .Image ,error );switch _afa .ColorSpace .String (){case "\u0044e\u0076\u0069\u0063\u0065\u0052\u0047B":_ebe =_ad .NewRGBA (_gdgb );_cga =_dg .ImageHandling .NewImageFromGoImage ;case "\u0044\u0065\u0076\u0069\u0063\u0065\u0047\u0072\u0061\u0079":_ebe =_ad .NewGray (_gdgb );_cga =_dg .ImageHandling .NewGrayImageFromGoImage ;default:return _af .Errorf ("\u006f\u0070\u0074\u0069\u006d\u0069\u007a\u0061t\u0069\u006f\u006e i\u0073\u0020\u006e\u006f\u0074\u0020s\u0075\u0070\u0070\u006f\u0072\u0074\u0065\u0064\u0020\u0066\u006f\u0072\u0020\u0063\u006fl\u006f\u0072\u0020\u0073\u0070\u0061\u0063\u0065 \u0025\u0073",_afa .ColorSpace .String ());};_d .CatmullRom .Scale (_ebe ,_ebe .Bounds (),_gdc ,_gdc .Bounds (),_d .Over ,&_d .Options {});if _gab ,_aaef =_cga (_ebe );_aaef !=nil {return _aaef ;};_cad :=_a .MakeDict ();_cad .Set ("\u0051u\u0061\u006c\u0069\u0074\u0079",_a .MakeInteger (100));_cad .Set ("\u0050r\u0065\u0064\u0069\u0063\u0074\u006fr",_a .MakeInteger (1));_afa .Filter .UpdateParams (_cad );if _aaef =_afa .SetImage (_gab ,nil );_aaef !=nil {return _aaef ;};_afa .ToPdfObject ();return nil ;};func _fdca (_acd []_a .PdfObject ,_gfab map[_a .PdfObject ]_a .PdfObject ){if len (_gfab )==0{return ;};for _eacg ,_dce :=range _acd {if _faed ,_fdgc :=_gfab [_dce ];_fdgc {_acd [_eacg ]=_faed ;continue ;};_gfab [_dce ]=_dce ;switch _eace :=_dce .(type ){case *_a .PdfObjectArray :_gbdd :=make ([]_a .PdfObject ,_eace .Len ());copy (_gbdd ,_eace .Elements ());_fdca (_gbdd ,_gfab );for _fbdg ,_cdd :=range _gbdd {_eace .Set (_fbdg ,_cdd );};case *_a .PdfObjectStreams :_fdca (_eace .Elements (),_gfab );case *_a .PdfObjectStream :_fga :=[]_a .PdfObject {_eace .PdfObjectDictionary };_fdca (_fga ,_gfab );_eace .PdfObjectDictionary =_fga [0].(*_a .PdfObjectDictionary );case *_a .PdfObjectDictionary :_bab :=_eace .Keys ();_age :=make ([]_a .PdfObject ,len (_bab ));for _bfc ,_fab :=range _bab {_age [_bfc ]=_eace .Get (_fab );};_fdca (_age ,_gfab );for _ebbdg ,_fdb :=range _bab {_eace .Set (_fdb ,_age [_ebbdg ]);};case *_a .PdfIndirectObject :_fac :=[]_a .PdfObject {_eace .PdfObject };_fdca (_fac ,_gfab );_eace .PdfObject =_fac [0];};};};
|
|
|
|
// CombineDuplicateStreams combines duplicated streams by its data hash.
|
|
// It implements interface model.Optimizer.
|
|
type CombineDuplicateStreams struct{};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_begbc *CombineDuplicateDirectObjects )Optimize (objects []_a .PdfObject )(_cde []_a .PdfObject ,_ace error ){_aaba (objects );_edg :=make (map[string ][]*_a .PdfObjectDictionary );var _cged func (_fad *_a .PdfObjectDictionary );_cged =func (_gcfc *_a .PdfObjectDictionary ){for _ ,_fddb :=range _gcfc .Keys (){_eff :=_gcfc .Get (_fddb );if _bfd ,_bfg :=_eff .(*_a .PdfObjectDictionary );_bfg {_dgf :=_g .New ();_dgf .Write ([]byte (_bfd .WriteString ()));_dgfe :=string (_dgf .Sum (nil ));_edg [_dgfe ]=append (_edg [_dgfe ],_bfd );_cged (_bfd );};};};for _ ,_ceb :=range objects {_baac ,_eee :=_ceb .(*_a .PdfIndirectObject );if !_eee {continue ;};if _fbbb ,_cgedc :=_baac .PdfObject .(*_a .PdfObjectDictionary );_cgedc {_cged (_fbbb );};};_fagf :=make ([]_a .PdfObject ,0,len (_edg ));_bea :=make (map[_a .PdfObject ]_a .PdfObject );for _ ,_fca :=range _edg {if len (_fca )< 2{continue ;};_fcdg :=_a .MakeDict ();_fcdg .Merge (_fca [0]);_agd :=_a .MakeIndirectObject (_fcdg );_fagf =append (_fagf ,_agd );for _bega :=0;_bega < len (_fca );_bega ++{_abg :=_fca [_bega ];_bea [_abg ]=_agd ;};};_cde =make ([]_a .PdfObject ,len (objects ));copy (_cde ,objects );_cde =append (_fagf ,_cde ...);_fdca (_cde ,_bea );return _cde ,nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_aba *CleanFonts )Optimize (objects []_a .PdfObject )(_abc []_a .PdfObject ,_dbfg error ){var _aed map[*_a .PdfObjectStream ]struct{};if _aba .Subset {var _bee error ;_aed ,_bee =_ag (objects );if _bee !=nil {return nil ,_bee ;};};for _ ,_dae :=range objects {_baab ,_fdf :=_a .GetStream (_dae );if !_fdf {continue ;};if _ ,_begb :=_aed [_baab ];_begb {continue ;};_gbeg ,_eae :=_a .NewEncoderFromStream (_baab );if _eae !=nil {_fd .Log .Debug ("\u0045\u0052RO\u0052\u0020\u0067e\u0074\u0074\u0069\u006eg e\u006eco\u0064\u0065\u0072\u003a\u0020\u0025\u0076 -\u0020\u0069\u0067\u006e\u006f\u0072\u0069n\u0067",_eae );continue ;};_bcec ,_eae :=_gbeg .DecodeStream (_baab );if _eae !=nil {_fd .Log .Debug ("\u0044\u0065\u0063\u006f\u0064\u0069\u006e\u0067\u0020\u0065r\u0072\u006f\u0072\u0020\u003a\u0020\u0025v\u0020\u002d\u0020\u0069\u0067\u006e\u006f\u0072\u0069\u006e\u0067",_eae );continue ;};if len (_bcec )< 4{continue ;};_adg :=string (_bcec [:4]);if _adg =="\u004f\u0054\u0054\u004f"{continue ;};if _adg !="\u0000\u0001\u0000\u0000"&&_adg !="\u0074\u0072\u0075\u0065"{continue ;};_fdg ,_eae :=_fg .Parse (_gb .NewReader (_bcec ));if _eae !=nil {_fd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u0020P\u0061\u0072\u0073\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076\u0020\u002d\u0020\u0069\u0067\u006eo\u0072\u0069\u006e\u0067",_eae );continue ;};_eae =_fdg .Optimize ();if _eae !=nil {continue ;};var _fda _gb .Buffer ;_eae =_fdg .Write (&_fda );if _eae !=nil {_fd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u0020W\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076\u0020\u002d\u0020\u0069\u0067\u006eo\u0072\u0069\u006e\u0067",_eae );continue ;};if _fda .Len ()> len (_bcec ){_fd .Log .Debug ("\u0052\u0065-\u0077\u0072\u0069\u0074\u0074\u0065\u006e\u0020\u0066\u006f\u006e\u0074\u0020\u0069\u0073\u0020\u006c\u0061\u0072\u0067\u0065\u0072\u0020\u0074\u0068\u0061\u006e\u0020\u006f\u0072\u0069\u0067\u0069\u006e\u0061\u006c\u0020\u002d\u0020\u0073\u006b\u0069\u0070");continue ;};_dgd ,_eae :=_a .MakeStream (_fda .Bytes (),_a .NewFlateEncoder ());if _eae !=nil {continue ;};*_baab =*_dgd ;_baab .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_a .MakeInteger (int64 (_fda .Len ())));};return objects ,nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_cda *CombineIdenticalIndirectObjects )Optimize (objects []_a .PdfObject )(_efff []_a .PdfObject ,_gdf error ){_aaba (objects );_dde :=make (map[_a .PdfObject ]_a .PdfObject );_cc :=make (map[_a .PdfObject ]struct{});_ebf :=make (map[string ][]*_a .PdfIndirectObject );for _ ,_caa :=range objects {_bbd ,_bdg :=_caa .(*_a .PdfIndirectObject );if !_bdg {continue ;};if _fgb ,_cfec :=_bbd .PdfObject .(*_a .PdfObjectDictionary );_cfec {if _efbb ,_ebbb :=_fgb .Get ("\u0054\u0079\u0070\u0065").(*_a .PdfObjectName );_ebbb &&*_efbb =="\u0050\u0061\u0067\u0065"{continue ;};_afg :=_g .New ();_afg .Write ([]byte (_fgb .WriteString ()));_bcc :=string (_afg .Sum (nil ));_ebf [_bcc ]=append (_ebf [_bcc ],_bbd );};};for _ ,_gdg :=range _ebf {if len (_gdg )< 2{continue ;};_dbc :=_gdg [0];for _fce :=1;_fce < len (_gdg );_fce ++{_gcb :=_gdg [_fce ];_dde [_gcb ]=_dbc ;_cc [_gcb ]=struct{}{};};};_efff =make ([]_a .PdfObject ,0,len (objects )-len (_cc ));for _ ,_aecc :=range objects {if _ ,_faa :=_cc [_aecc ];_faa {continue ;};_efff =append (_efff ,_aecc );};_fdca (_efff ,_dde );return _efff ,nil ;};func _agc (_ged _a .PdfObject )[]content {if _ged ==nil {return nil ;};_efe ,_efb :=_a .GetArray (_ged );if !_efb {_fd .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");return nil ;};var _bbc []content ;for _ ,_fed :=range _efe .Elements (){_cfef ,_efgf :=_a .GetDict (_fed );if !_efgf {_fd .Log .Debug ("I\u0067\u006e\u006f\u0072\u0069\u006eg\u0020\u006e\u006f\u006e\u002d\u0064i\u0063\u0074\u0020\u0065\u006c\u0065\u006de\u006e\u0074\u0020\u0069\u006e\u0020\u0041\u006e\u006e\u006ft\u0073");continue ;};_cfd ,_efgf :=_a .GetDict (_cfef .Get ("\u0041\u0050"));if !_efgf {_fd .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_fdfe :=_a .TraceToDirectObject (_cfd .Get ("\u004e"));if _fdfe ==nil {_fd .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _gdd *_a .PdfObjectStream ;switch _dag :=_fdfe .(type ){case *_a .PdfObjectDictionary :_agf ,_eef :=_a .GetName (_cfef .Get ("\u0041\u0053"));if !_eef {_fd .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_gdd ,_eef =_a .GetStream (_dag .Get (*_agf ));if !_eef {_fd .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");continue ;};case *_a .PdfObjectStream :_gdd =_dag ;};if _gdd ==nil {_fd .Log .Debug ("\u0046\u006f\u0072m\u0020\u006e\u006f\u0074 \u0066\u006f\u0075\u006e\u0064\u0020\u0028n\u0069\u006c\u0029\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};_efbc ,_geb :=_dg .NewXObjectFormFromStream (_gdd );if _geb !=nil {_fd .Log .Debug ("\u0045\u0072\u0072\u006f\u0072\u0020l\u006f\u0061\u0064\u0069\u006e\u0067\u0020\u0066\u006f\u0072\u006d\u003a\u0020%\u0076\u0020\u002d\u0020\u0069\u0067\u006eo\u0072\u0069\u006e\u0067",_geb );continue ;};_bddd ,_geb :=_efbc .GetContentStream ();if _geb !=nil {_fd .Log .Debug ("E\u0072\u0072\u006f\u0072\u0020\u0064e\u0063\u006f\u0064\u0069\u006e\u0067\u0020\u0063\u006fn\u0074\u0065\u006et\u0073:\u0020\u0025\u0076",_geb );continue ;};_bbc =append (_bbc ,content {_cgc :string (_bddd ),_dda :_efbc .Resources });};return _bbc ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_bbb *ObjectStreams )Optimize (objects []_a .PdfObject )(_aead []_a .PdfObject ,_agfc error ){_afgg :=&_a .PdfObjectStreams {};_aabb :=make ([]_a .PdfObject ,0,len (objects ));for _ ,_daed :=range objects {if _ecc ,_ecbc :=_daed .(*_a .PdfIndirectObject );_ecbc &&_ecc .GenerationNumber ==0{_afgg .Append (_daed );}else {_aabb =append (_aabb ,_daed );};};if _afgg .Len ()==0{return _aabb ,nil ;};_aead =make ([]_a .PdfObject ,0,len (_aabb )+_afgg .Len ()+1);if _afgg .Len ()> 1{_aead =append (_aead ,_afgg );};_aead =append (_aead ,_afgg .Elements ()...);_aead =append (_aead ,_aabb ...);return _aead ,nil ;};
|
|
|
|
// Chain allows to use sequence of optimizers.
|
|
// It implements interface model.Optimizer.
|
|
type Chain struct{_fgf []_dg .Optimizer };func _ag (_gg []_a .PdfObject )(_fe map[*_a .PdfObjectStream ]struct{},_dfaf error ){_fe =map[*_a .PdfObjectStream ]struct{}{};_dbf :=map[*_dg .PdfFont ]struct{}{};_gc :=_bafa (_gg );for _ ,_bfb :=range _gc ._gcaa {_fdc ,_ecb :=_a .GetDict (_bfb .PdfObject );if !_ecb {continue ;};_acf ,_ecb :=_a .GetDict (_fdc .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_ecb {continue ;};_beb ,_ :=_cdfg (_fdc .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_cbb ,_gfc :=_dg .NewPdfPageResourcesFromDict (_acf );if _gfc !=nil {return nil ,_gfc ;};_cbf :=[]content {{_cgc :_beb ,_dda :_cbb }};_aaa :=_agc (_fdc .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));if _aaa !=nil {_cbf =append (_cbf ,_aaa ...);};for _ ,_gea :=range _cbf {_gbe ,_fag :=_db .NewFromContents (_gea ._cgc ,_gea ._dda );if _fag !=nil {return nil ,_fag ;};_dbe ,_ ,_ ,_fag :=_gbe .ExtractPageText ();if _fag !=nil {return nil ,_fag ;};for _ ,_bae :=range _dbe .Marks ().Elements (){if _bae .Font ==nil {continue ;};if _ ,_eac :=_dbf [_bae .Font ];!_eac {_dbf [_bae .Font ]=struct{}{};};};};};_efd :=map[*_a .PdfObjectStream ][]*_dg .PdfFont {};for _bdd :=range _dbf {_efgd :=_bdd .FontDescriptor ();if _efgd ==nil ||_efgd .FontFile2 ==nil {continue ;};_bce ,_eg :=_a .GetStream (_efgd .FontFile2 );if !_eg {continue ;};_efd [_bce ]=append (_efd [_bce ],_bdd );};for _bcf :=range _efd {var _bg []rune ;var _gaf []_fg .GlyphIndex ;for _ ,_cba :=range _efd [_bcf ]{switch _aaff :=_cba .Encoder ().(type ){case *_b .IdentityEncoder :_agb :=_aaff .RegisteredRunes ();_gaa :=make ([]_fg .GlyphIndex ,len (_agb ));for _dfb ,_aeec :=range _agb {_gaa [_dfb ]=_fg .GlyphIndex (_aeec );};_gaf =append (_gaf ,_gaa ...);case *_b .TrueTypeFontEncoder :_de :=_aaff .RegisteredRunes ();_bg =append (_bg ,_de ...);case _b .SimpleEncoder :_cab :=_aaff .Charcodes ();for _ ,_ffc :=range _cab {_aca ,_gad :=_aaff .CharcodeToRune (_ffc );if !_gad {_fd .Log .Debug ("\u0043\u0068a\u0072\u0063\u006f\u0064\u0065\u003c\u002d\u003e\u0072\u0075\u006e\u0065\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064: \u0025\u0064",_ffc );continue ;};_bg =append (_bg ,_aca );};};};_dfaf =_bb (_bcf ,_bg ,_gaf );if _dfaf !=nil {_fd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u0020\u0073\u0075\u0062\u0073\u0065\u0074\u0074\u0069\u006eg\u0020f\u006f\u006e\u0074\u0020\u0073\u0074\u0072\u0065\u0061\u006d\u003a\u0020\u0025\u0076",_dfaf );return nil ,_dfaf ;};_fe [_bcf ]=struct{}{};};return _fe ,nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_bbe *CompressStreams )Optimize (objects []_a .PdfObject )(_fafd []_a .PdfObject ,_cag error ){_fafd =make ([]_a .PdfObject ,len (objects ));copy (_fafd ,objects );for _ ,_ddf :=range objects {_fcf ,_gedf :=_a .GetStream (_ddf );if !_gedf {continue ;};if _fea :=_fcf .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_fea !=nil {if _ ,_gda :=_a .GetName (_fea );_gda {continue ;};if _cbg ,_bgf :=_a .GetArray (_fea );_bgf &&_cbg .Len ()> 0{continue ;};};_gga :=_a .NewFlateEncoder ();var _ebfd []byte ;_ebfd ,_cag =_gga .EncodeBytes (_fcf .Stream );if _cag !=nil {return _fafd ,_cag ;};_bedg :=_gga .MakeStreamDict ();if len (_ebfd )+len (_bedg .WriteString ())< len (_fcf .Stream ){_fcf .Stream =_ebfd ;_fcf .PdfObjectDictionary .Merge (_bedg );_fcf .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_a .MakeInteger (int64 (len (_fcf .Stream ))));};};return _fafd ,nil ;};func _beg (_ae *_a .PdfObjectStream )error {_fb ,_ga :=_a .DecodeStream (_ae );if _ga !=nil {return _ga ;};_ca :=_dba .NewContentStreamParser (string (_fb ));_cd ,_ga :=_ca .Parse ();if _ga !=nil {return _ga ;};_cd =_cg (_cd );_ab :=_cd .Bytes ();if len (_ab )>=len (_fb ){return nil ;};_dbg ,_ga :=_a .MakeStream (_cd .Bytes (),_a .NewFlateEncoder ());if _ga !=nil {return _ga ;};_ae .Stream =_dbg .Stream ;_ae .Merge (_dbg .PdfObjectDictionary );return nil ;};
|
|
|
|
// Options describes PDF optimization parameters.
|
|
type Options struct{CombineDuplicateStreams bool ;CombineDuplicateDirectObjects bool ;ImageUpperPPI float64 ;ImageQuality int ;UseObjectStreams bool ;CombineIdenticalIndirectObjects bool ;CompressStreams bool ;CleanFonts bool ;SubsetFonts bool ;CleanContentstream bool ;};
|
|
|
|
// Image optimizes images by rewrite images into JPEG format with quality equals to ImageQuality.
|
|
// TODO(a5i): Add support for inline images.
|
|
// It implements interface model.Optimizer.
|
|
type Image struct{ImageQuality int ;};func _cg (_dc *_dba .ContentStreamOperations )*_dba .ContentStreamOperations {if _dc ==nil {return nil ;};_bc :=_dba .ContentStreamOperations {};for _ ,_fa :=range *_dc {switch _fa .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;case "\u0054\u006d":if len (_fa .Params )==6{if _faf ,_e :=_a .GetNumbersAsFloat (_fa .Params );_e ==nil {if _faf [0]==1&&_faf [1]==0&&_faf [2]==0&&_faf [3]==1{_fa =&_dba .ContentStreamOperation {Params :[]_a .PdfObject {_fa .Params [4],_fa .Params [5]},Operand :"\u0054\u0064"};};};};};_bc =append (_bc ,_fa );};return &_bc ;};func _bb (_ecg *_a .PdfObjectStream ,_bda []rune ,_gcf []_fg .GlyphIndex )error {_ecg ,_bge :=_a .GetStream (_ecg );if !_bge {_fd .Log .Debug ("\u0045\u006d\u0062\u0065\u0064\u0064\u0065\u0064\u0020\u0066\u006f\u006e\u0074\u0020\u006f\u0062\u006a\u0065c\u0074\u0020\u006e\u006f\u0074\u0020\u0066o\u0075\u006e\u0064\u0020\u002d\u002d\u0020\u0041\u0042\u004f\u0052T\u0020\u0073\u0075\u0062\u0073\u0065\u0074\u0074\u0069\u006e\u0067");return _gf .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_daa ,_fbb :=_a .DecodeStream (_ecg );if _fbb !=nil {_fd .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_fbb );return _fbb ;};_bgb ,_fbb :=_fg .Parse (_gb .NewReader (_daa ));if _fbb !=nil {_fd .Log .Debug ("\u0045\u0072\u0072\u006f\u0072\u0020\u0070\u0061\u0072\u0073\u0069n\u0067\u0020\u0025\u0064\u0020\u0062\u0079\u0074\u0065\u0020f\u006f\u006e\u0074",len (_ecg .Stream ));return _fbb ;};_ebg :=_gcf ;if len (_bda )> 0{_gdb :=_bgb .LookupRunes (_bda );_ebg =append (_ebg ,_gdb ...);};_bgb ,_fbb =_bgb .SubsetKeepIndices (_ebg );if _fbb !=nil {_fd .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_fbb );return _fbb ;};var _fcd _gb .Buffer ;_fbb =_bgb .Write (&_fcd );if _fbb !=nil {_fd .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_fbb );return _fbb ;};if _fcd .Len ()> len (_daa ){_fd .Log .Debug ("\u0052\u0065-\u0077\u0072\u0069\u0074\u0074\u0065\u006e\u0020\u0066\u006f\u006e\u0074\u0020\u0069\u0073\u0020\u006c\u0061\u0072\u0067\u0065\u0072\u0020\u0074\u0068\u0061\u006e\u0020\u006f\u0072\u0069\u0067\u0069\u006e\u0061\u006c\u0020\u002d\u0020\u0073\u006b\u0069\u0070");return nil ;};_ce ,_fbb :=_a .MakeStream (_fcd .Bytes (),_a .NewFlateEncoder ());if _fbb !=nil {_fd .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_fbb );return _fbb ;};*_ecg =*_ce ;_ecg .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_a .MakeInteger (int64 (_fcd .Len ())));return nil ;};
|
|
|
|
// ObjectStreams groups PDF objects to object streams.
|
|
// It implements interface model.Optimizer.
|
|
type ObjectStreams struct{};type imageInfo struct{ColorSpace _a .PdfObjectName ;BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_a .PdfObjectStream ;PPI float64 ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_gfa *ImagePPI )Optimize (objects []_a .PdfObject )(_gef []_a .PdfObject ,_fge error ){if _gfa .ImageUpperPPI <=0{return objects ,nil ;};_gec :=_acg (objects );if len (_gec )==0{return objects ,nil ;};_aegf :=make (map[_a .PdfObject ]struct{});for _ ,_fafg :=range _gec {_bad :=_fafg .Stream .PdfObjectDictionary .Get (_a .PdfObjectName ("\u0053\u004d\u0061s\u006b"));_aegf [_bad ]=struct{}{};};_fee :=make (map[*_a .PdfObjectStream ]*imageInfo );for _ ,_aafa :=range _gec {_fee [_aafa .Stream ]=_aafa ;};var _dea *_a .PdfObjectDictionary ;for _ ,_abe :=range objects {if _gde ,_eceg :=_a .GetDict (_abe );_dea ==nil &&_eceg {if _fae ,_bef :=_a .GetName (_gde .Get (_a .PdfObjectName ("\u0054\u0079\u0070\u0065")));_bef &&*_fae =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_dea =_gde ;};};};if _dea ==nil {return objects ,nil ;};_gce ,_affc :=_a .GetDict (_dea .Get (_a .PdfObjectName ("\u0050\u0061\u0067e\u0073")));if !_affc {return objects ,nil ;};_fcfc ,_cac :=_a .GetArray (_gce .Get (_a .PdfObjectName ("\u004b\u0069\u0064\u0073")));if !_cac {return objects ,nil ;};_ebd :=make (map[string ]*imageInfo );for _ ,_ddfb :=range _fcfc .Elements (){_egaf ,_gag :=_a .GetDict (_ddfb );if !_gag {continue ;};_gcg ,_bccg :=_a .GetArray (_egaf .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if !_bccg {continue ;};_bag ,_bcgd :=_a .GetDict (_egaf .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_bcgd {continue ;};_cee ,_gbg :=_a .GetDict (_bag .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_gbg {continue ;};_gbfd :=_cee .Keys ();for _ ,_def :=range _gbfd {if _fff ,_caga :=_a .GetStream (_cee .Get (_def ));_caga {if _gagb ,_adgf :=_fee [_fff ];_adgf {_ebd [string (_def )]=_gagb ;};};};for _ ,_bff :=range _gcg .Elements (){if _ggce ,_gbfa :=_a .GetStream (_bff );_gbfa {_gdgc ,_ecgf :=_a .NewEncoderFromStream (_ggce );if _ecgf !=nil {return nil ,_ecgf ;};_cebg ,_ecgf :=_gdgc .DecodeStream (_ggce );if _ecgf !=nil {return nil ,_ecgf ;};_edf :=_dba .NewContentStreamParser (string (_cebg ));_cgbg ,_ecgf :=_edf .Parse ();if _ecgf !=nil {return nil ,_ecgf ;};_feb ,_gcfe :=1.0,1.0;for _ ,_bgbd :=range *_cgbg {if _bgbd .Operand =="\u0051"{_feb ,_gcfe =1.0,1.0;};if _bgbd .Operand =="\u0063\u006d"&&len (_bgbd .Params )==6{if _gbgb ,_bceac :=_a .GetFloatVal (_bgbd .Params [0]);_bceac {_feb =_feb *_gbgb ;};if _gcge ,_ddbf :=_a .GetFloatVal (_bgbd .Params [3]);_ddbf {_gcfe =_gcfe *_gcge ;};if _dbeg ,_gbegc :=_a .GetIntVal (_bgbd .Params [0]);_gbegc {_feb =_feb *float64 (_dbeg );};if _bfe ,_cded :=_a .GetIntVal (_bgbd .Params [3]);_cded {_gcfe =_gcfe *float64 (_bfe );};};if _bgbd .Operand =="\u0044\u006f"&&len (_bgbd .Params )==1{_cabg ,_febd :=_a .GetName (_bgbd .Params [0]);if !_febd {continue ;};if _cdaa ,_fbc :=_ebd [string (*_cabg )];_fbc {_afc ,_bbeg :=_feb /72.0,_gcfe /72.0;_fdac ,_ggab :=float64 (_cdaa .Width )/_afc ,float64 (_cdaa .Height )/_bbeg ;if _afc ==0||_bbeg ==0{_fdac =72.0;_ggab =72.0;};_cdaa .PPI =_f .Max (_cdaa .PPI ,_fdac );_cdaa .PPI =_f .Max (_cdaa .PPI ,_ggab );};};};};};};for _ ,_dacd :=range _gec {if _ ,_bde :=_aegf [_dacd .Stream ];_bde {continue ;};if _dacd .PPI <=_gfa .ImageUpperPPI {continue ;};_cgea :=_gfa .ImageUpperPPI /_dacd .PPI ;if _ccd :=_cebb (_dacd .Stream ,_cgea );_ccd !=nil {_fd .Log .Debug ("\u0045\u0072\u0072\u006f\u0072 \u0073\u0063\u0061\u006c\u0065\u0020\u0069\u006d\u0061\u0067\u0065\u0020\u006be\u0065\u0070\u0020\u006f\u0072\u0069\u0067\u0069\u006e\u0061\u006c\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0073",_ccd );}else {if _gfd ,_ede :=_a .GetStream (_dacd .Stream .PdfObjectDictionary .Get (_a .PdfObjectName ("\u0053\u004d\u0061s\u006b")));_ede {if _ada :=_cebb (_gfd ,_cgea );_ada !=nil {return nil ,_ada ;};};};};return objects ,nil ;};
|
|
|
|
// CompressStreams compresses uncompressed streams.
|
|
// It implements interface model.Optimizer.
|
|
type CompressStreams struct{};type objectStructure struct{_dbgea *_a .PdfObjectDictionary ;_efea *_a .PdfObjectDictionary ;_gcaa []*_a .PdfIndirectObject ;};func _aaba (_cbc []_a .PdfObject ){for _cbe ,_affb :=range _cbc {switch _dbgg :=_affb .(type ){case *_a .PdfIndirectObject :_dbgg .ObjectNumber =int64 (_cbe +1);_dbgg .GenerationNumber =0;case *_a .PdfObjectStream :_dbgg .ObjectNumber =int64 (_cbe +1);_dbgg .GenerationNumber =0;case *_a .PdfObjectStreams :_dbgg .ObjectNumber =int64 (_cbe +1);_dbgg .GenerationNumber =0;};};};
|
|
|
|
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
|
|
// It implements interface model.Optimizer.
|
|
type CombineDuplicateDirectObjects struct{};
|
|
|
|
// ImagePPI optimizes images by scaling images such that the PPI (pixels per inch) is never higher than ImageUpperPPI.
|
|
// TODO(a5i): Add support for inline images.
|
|
// It implements interface model.Optimizer.
|
|
type ImagePPI struct{ImageUpperPPI float64 ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_aae *CombineDuplicateStreams )Optimize (objects []_a .PdfObject )(_egd []_a .PdfObject ,_gca error ){_aeb :=make (map[_a .PdfObject ]_a .PdfObject );_gbeb :=make (map[_a .PdfObject ]struct{});_ebb :=make (map[string ][]*_a .PdfObjectStream );for _ ,_efbcc :=range objects {if _gbb ,_bcgg :=_efbcc .(*_a .PdfObjectStream );_bcgg {_dgde :=_g .New ();_dgde .Write (_gbb .Stream );_bdc :=string (_dgde .Sum (nil ));_ebb [_bdc ]=append (_ebb [_bdc ],_gbb );};};for _ ,_ddb :=range _ebb {if len (_ddb )< 2{continue ;};_bfbd :=_ddb [0];for _dgg :=1;_dgg < len (_ddb );_dgg ++{_cbd :=_ddb [_dgg ];_aeb [_cbd ]=_bfbd ;_gbeb [_cbd ]=struct{}{};};};_egd =make ([]_a .PdfObject ,0,len (objects )-len (_gbeb ));for _ ,_cff :=range objects {if _ ,_baf :=_gbeb [_cff ];_baf {continue ;};_egd =append (_egd ,_cff );};_fdca (_egd ,_aeb );return _egd ,nil ;};
|
|
|
|
// CombineIdenticalIndirectObjects combines identical indirect objects.
|
|
// It implements interface model.Optimizer.
|
|
type CombineIdenticalIndirectObjects struct{};func _acg (_aff []_a .PdfObject )[]*imageInfo {_ecd :=_a .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_fgg :=make (map[*_a .PdfObjectStream ]struct{});var _fbf error ;var _cca []*imageInfo ;for _ ,_cbbc :=range _aff {_ebbd ,_eed :=_a .GetStream (_cbbc );if !_eed {continue ;};if _ ,_dbfa :=_fgg [_ebbd ];_dbfa {continue ;};_fgg [_ebbd ]=struct{}{};_dbca :=_ebbd .PdfObjectDictionary .Get (_ecd );_ddec ,_eed :=_a .GetName (_dbca );if !_eed ||string (*_ddec )!="\u0049\u006d\u0061g\u0065"{continue ;};_fedf :=&imageInfo {BitsPerComponent :8,Stream :_ebbd };if _fedf .ColorSpace ,_fbf =_dg .DetermineColorspaceNameFromPdfObject (_ebbd .PdfObjectDictionary .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));_fbf !=nil {_fd .Log .Error ("\u0045\u0072\u0072\u006f\u0072\u0020\u0064\u0065\u0074\u0065r\u006d\u0069\u006e\u0065\u0020\u0063\u006fl\u006f\u0072\u0020\u0073\u0070\u0061\u0063\u0065\u0020\u0025\u0073",_fbf );continue ;};if _cdee ,_fba :=_a .GetIntVal (_ebbd .PdfObjectDictionary .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_fba {_fedf .BitsPerComponent =_cdee ;};if _egb ,_dab :=_a .GetIntVal (_ebbd .PdfObjectDictionary .Get ("\u0057\u0069\u0064t\u0068"));_dab {_fedf .Width =_egb ;};if _bgc ,_bcea :=_a .GetIntVal (_ebbd .PdfObjectDictionary .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_bcea {_fedf .Height =_bgc ;};switch _fedf .ColorSpace {case "\u0044e\u0076\u0069\u0063\u0065\u0052\u0047B":_fedf .ColorComponents =3;case "\u0044\u0065\u0076\u0069\u0063\u0065\u0047\u0072\u0061\u0079":_fedf .ColorComponents =1;default:_fd .Log .Warning ("\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061t\u0069\u006f\u006e i\u0073\u0020\u006e\u006f\u0074\u0020s\u0075\u0070\u0070\u006f\u0072\u0074\u0065\u0064\u0020\u0066\u006f\u0072\u0020\u0063\u006fl\u006f\u0072\u0020\u0073\u0070\u0061\u0063\u0065 \u0025\u0073",_fedf .ColorSpace );continue ;};_cca =append (_cca ,_fedf );};return _cca ;};func _bafa (_ecga []_a .PdfObject )objectStructure {_ded :=objectStructure {};_gaae :=false ;for _ ,_cadd :=range _ecga {switch _cgad :=_cadd .(type ){case *_a .PdfIndirectObject :_gcgb ,_afe :=_a .GetDict (_cgad );if !_afe {continue ;};_dge ,_afe :=_a .GetName (_gcgb .Get ("\u0054\u0079\u0070\u0065"));if !_afe {continue ;};switch _dge .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_ded ._dbgea =_gcgb ;_gaae =true ;};};if _gaae {break ;};};if !_gaae {return _ded ;};_bbea ,_dcb :=_a .GetDict (_ded ._dbgea .Get ("\u0050\u0061\u0067e\u0073"));if !_dcb {return _ded ;};_ded ._efea =_bbea ;_gbfdd ,_dcb :=_a .GetArray (_bbea .Get ("\u004b\u0069\u0064\u0073"));if !_dcb {return _ded ;};for _ ,_aafaa :=range _gbfdd .Elements (){_ccaa ,_bbg :=_a .GetIndirect (_aafaa );if !_bbg {break ;};_ded ._gcaa =append (_ded ._gcaa ,_ccaa );};return _ded ;};type content struct{_cgc string ;_dda *_dg .PdfPageResources ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_aeg *CleanContentstream )Optimize (objects []_a .PdfObject )(_da []_a .PdfObject ,_gd error ){_cb :=map[*_a .PdfObjectStream ]struct{}{};var _fc []*_a .PdfObjectStream ;_dbge :=func (_bd *_a .PdfObjectStream ){if _ ,_cfe :=_cb [_bd ];!_cfe {_cb [_bd ]=struct{}{};_fc =append (_fc ,_bd );};};for _ ,_aa :=range objects {switch _ec :=_aa .(type ){case *_a .PdfIndirectObject :switch _bf :=_ec .PdfObject .(type ){case *_a .PdfObjectDictionary :if _gae ,_gbd :=_a .GetName (_bf .Get ("\u0054\u0079\u0070\u0065"));!_gbd ||_gae .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _fdd ,_dd :=_a .GetStream (_bf .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_dd {_dbge (_fdd );}else if _aaf ,_ef :=_a .GetArray (_bf .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_ef {for _ ,_aee :=range _aaf .Elements (){if _ed ,_add :=_a .GetStream (_aee );_add {_dbge (_ed );};};};};case *_a .PdfObjectStream :if _aea ,_eea :=_a .GetName (_ec .Get ("\u0054\u0079\u0070\u0065"));!_eea ||_aea .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _bcg ,_aab :=_a .GetName (_ec .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));!_aab ||_bcg .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_dbge (_ec );};};for _ ,_cfa :=range _fc {_gd =_beg (_cfa );if _gd !=nil {return nil ,_gd ;};};return objects ,nil ;};
|
|
|
|
// CleanFonts cleans up embedded fonts, reducing font sizes.
|
|
type CleanFonts struct{
|
|
|
|
// Subset embedded fonts if encountered (if true).
|
|
// Otherwise attempts to reduce the font program.
|
|
Subset bool ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_ge *Chain )Optimize (objects []_a .PdfObject )(_be []_a .PdfObject ,_gba error ){_be =objects ;for _ ,_ff :=range _ge ._fgf {_be ,_gba =_ff .Optimize (_be );if _gba !=nil {return _be ,_gba ;};};return _be ,nil ;};
|
|
|
|
// New creates a optimizers chain from options.
|
|
func New (options Options )*Chain {_eeg :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_eeg .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_eeg .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_dbef :=new (ImagePPI );_dbef .ImageUpperPPI =options .ImageUpperPPI ;_eeg .Append (_dbef );};if options .ImageQuality > 0{_cacc :=new (Image );_cacc .ImageQuality =options .ImageQuality ;_eeg .Append (_cacc );};if options .CombineDuplicateDirectObjects {_eeg .Append (new (CombineDuplicateDirectObjects ));};if options .CombineDuplicateStreams {_eeg .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_eeg .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_eeg .Append (new (ObjectStreams ));};if options .CompressStreams {_eeg .Append (new (CompressStreams ));};return _eeg ;}; |