mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-27 13:48:51 +08:00
204 lines
37 KiB
Go
204 lines
37 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 (_dc "bytes";_cf "crypto/md5";_fd "errors";_c "github.com/unidoc/unipdf/v3/common";_g "github.com/unidoc/unipdf/v3/contentstream";_b "github.com/unidoc/unipdf/v3/core";_af "github.com/unidoc/unipdf/v3/extractor";_da "github.com/unidoc/unipdf/v3/internal/imageutil";
|
|
_aa "github.com/unidoc/unipdf/v3/internal/textencoding";_dg "github.com/unidoc/unipdf/v3/model";_f "github.com/unidoc/unitype";_e "golang.org/x/image/draw";_d "math";);
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_daf *CleanFonts )Optimize (objects []_b .PdfObject )(_dbc []_b .PdfObject ,_bbd error ){var _eaab map[*_b .PdfObjectStream ]struct{};if _daf .Subset {var _bbb error ;_eaab ,_bbb =_agb (objects );if _bbb !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004fR\u003a\u0020\u0046\u0061\u0069\u006c\u0065\u0064\u0020\u0073u\u0062s\u0065\u0074\u0074\u0069\u006e\u0067\u003a \u0025\u0076",_bbb );
|
|
return nil ,_bbb ;};};for _ ,_afb :=range objects {_ef ,_bcf :=_b .GetStream (_afb );if !_bcf {continue ;};if _ ,_fba :=_eaab [_ef ];_fba {continue ;};_dafc ,_bgeg :=_b .NewEncoderFromStream (_ef );if _bgeg !=nil {_c .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",_bgeg );
|
|
continue ;};_cca ,_bgeg :=_dafc .DecodeStream (_ef );if _bgeg !=nil {_c .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",_bgeg );
|
|
continue ;};if len (_cca )< 4{continue ;};_ffd :=string (_cca [:4]);if _ffd =="\u004f\u0054\u0054\u004f"{continue ;};if _ffd !="\u0000\u0001\u0000\u0000"&&_ffd !="\u0074\u0072\u0075\u0065"{continue ;};_adeb ,_bgeg :=_f .Parse (_dc .NewReader (_cca ));if _bgeg !=nil {_c .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",_bgeg );
|
|
continue ;};_bgeg =_adeb .Optimize ();if _bgeg !=nil {_c .Log .Debug ("\u0045\u0052RO\u0052\u0020\u004fp\u0074\u0069\u006d\u0069zin\u0067 f\u006f\u006e\u0074\u003a\u0020\u0025\u0076 -\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067",_bgeg );continue ;
|
|
};var _dcda _dc .Buffer ;_bgeg =_adeb .Write (&_dcda );if _bgeg !=nil {_c .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",_bgeg );
|
|
continue ;};if _dcda .Len ()> len (_cca ){_c .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 ,_bgeg :=_b .MakeStream (_dcda .Bytes (),_b .NewFlateEncoder ());if _bgeg !=nil {continue ;};*_ef =*_dgd ;_ef .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_b .MakeInteger (int64 (_dcda .Len ())));};return objects ,nil ;};func _aee (_ffbf _b .PdfObject )(_decf string ,_aeg []_b .PdfObject ){var _fedd _dc .Buffer ;
|
|
switch _afbd :=_ffbf .(type ){case *_b .PdfIndirectObject :_aeg =append (_aeg ,_afbd );_ffbf =_afbd .PdfObject ;};switch _abdc :=_ffbf .(type ){case *_b .PdfObjectStream :if _faa ,_deef :=_b .DecodeStream (_abdc );_deef ==nil {_fedd .Write (_faa );_aeg =append (_aeg ,_abdc );
|
|
};case *_b .PdfObjectArray :for _ ,_gae :=range _abdc .Elements (){switch _ggae :=_gae .(type ){case *_b .PdfObjectStream :if _bgaf ,_eeec :=_b .DecodeStream (_ggae );_eeec ==nil {_fedd .Write (_bgaf );_aeg =append (_aeg ,_ggae );};};};};return _fedd .String (),_aeg ;
|
|
};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_cbga *ObjectStreams )Optimize (objects []_b .PdfObject )(_gcd []_b .PdfObject ,_ggfc error ){_gfaf :=&_b .PdfObjectStreams {};_afa :=make ([]_b .PdfObject ,0,len (objects ));for _ ,_cgdb :=range objects {if _bdf ,_cgc :=_cgdb .(*_b .PdfIndirectObject );
|
|
_cgc &&_bdf .GenerationNumber ==0{_gfaf .Append (_cgdb );}else {_afa =append (_afa ,_cgdb );};};if _gfaf .Len ()==0{return _afa ,nil ;};_gcd =make ([]_b .PdfObject ,0,len (_afa )+_gfaf .Len ()+1);if _gfaf .Len ()> 1{_gcd =append (_gcd ,_gfaf );};_gcd =append (_gcd ,_gfaf .Elements ()...);
|
|
_gcd =append (_gcd ,_afa ...);return _gcd ,nil ;};func _aabe (_eabf []_b .PdfObject )objectStructure {_fdc :=objectStructure {};_fdac :=false ;for _ ,_ebbb :=range _eabf {switch _dece :=_ebbb .(type ){case *_b .PdfIndirectObject :_cbcc ,_bdcb :=_b .GetDict (_dece );
|
|
if !_bdcb {continue ;};_abed ,_bdcb :=_b .GetName (_cbcc .Get ("\u0054\u0079\u0070\u0065"));if !_bdcb {continue ;};switch _abed .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_fdc ._abee =_cbcc ;_fdac =true ;};};if _fdac {break ;};};if !_fdac {return _fdc ;
|
|
};_bfab ,_gfad :=_b .GetDict (_fdc ._abee .Get ("\u0050\u0061\u0067e\u0073"));if !_gfad {return _fdc ;};_fdc ._cegc =_bfab ;_edfe ,_gfad :=_b .GetArray (_bfab .Get ("\u004b\u0069\u0064\u0073"));if !_gfad {return _fdc ;};for _ ,_fefa :=range _edfe .Elements (){_bcd ,_bcaf :=_b .GetIndirect (_fefa );
|
|
if !_bcaf {break ;};_fdc ._caf =append (_fdc ._caf ,_bcd );};return _fdc ;};
|
|
|
|
// New creates a optimizers chain from options.
|
|
func New (options Options )*Chain {_bada :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_bada .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_bada .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_fgd :=new (ImagePPI );
|
|
_fgd .ImageUpperPPI =options .ImageUpperPPI ;_bada .Append (_fgd );};if options .ImageQuality > 0{_bag :=new (Image );_bag .ImageQuality =options .ImageQuality ;_bada .Append (_bag );};if options .CombineDuplicateDirectObjects {_bada .Append (new (CombineDuplicateDirectObjects ));
|
|
};if options .CombineDuplicateStreams {_bada .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_bada .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_bada .Append (new (ObjectStreams ));
|
|
};if options .CompressStreams {_bada .Append (new (CompressStreams ));};return _bada ;};func _cgd (_efc []_b .PdfObject )[]*imageInfo {_ceg :=_b .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_edb :=make (map[*_b .PdfObjectStream ]struct{});var _fag []*imageInfo ;
|
|
for _ ,_gde :=range _efc {_gfc ,_babg :=_b .GetStream (_gde );if !_babg {continue ;};if _ ,_dde :=_edb [_gfc ];_dde {continue ;};_edb [_gfc ]=struct{}{};_abfc :=_gfc .PdfObjectDictionary .Get (_ceg );_ebbe ,_babg :=_b .GetName (_abfc );if !_babg ||string (*_ebbe )!="\u0049\u006d\u0061g\u0065"{continue ;
|
|
};_fac :=&imageInfo {Stream :_gfc ,BitsPerComponent :8};if _ageb ,_aagc :=_b .GetIntVal (_gfc .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_aagc {_fac .BitsPerComponent =_ageb ;};if _bdcd ,_bged :=_b .GetIntVal (_gfc .Get ("\u0057\u0069\u0064t\u0068"));
|
|
_bged {_fac .Width =_bdcd ;};if _gdb ,_eea :=_b .GetIntVal (_gfc .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_eea {_fac .Height =_gdb ;};_ffge ,_ceac :=_dg .NewPdfColorspaceFromPdfObject (_gfc .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));
|
|
if _ceac !=nil {_c .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_ceac );continue ;};if _ffge ==nil {_ggba ,_fec :=_b .GetName (_gfc .Get ("\u0046\u0069\u006c\u0074\u0065\u0072"));if _fec {switch _ggba .String (){case "\u0043\u0043\u0049\u0054\u0054\u0046\u0061\u0078\u0044e\u0063\u006f\u0064\u0065","J\u0042\u0049\u0047\u0032\u0044\u0065\u0063\u006f\u0064\u0065":_ffge =_dg .NewPdfColorspaceDeviceGray ();
|
|
_fac .BitsPerComponent =1;};};};switch _bbcc :=_ffge .(type ){case *_dg .PdfColorspaceDeviceRGB :_fac .ColorComponents =3;case *_dg .PdfColorspaceDeviceGray :_fac .ColorComponents =1;default:_c .Log .Debug ("\u004f\u0070\u0074\u0069\u006d\u0069\u007aa\u0074\u0069\u006fn\u0020\u0069\u0073 \u006e\u006ft\u0020\u0073\u0075\u0070\u0070\u006fr\u0074ed\u0020\u0066\u006f\u0072\u0020\u0063\u006f\u006c\u006f\u0072\u0020\u0073\u0070\u0061\u0063\u0065\u0020\u0025\u0054\u0020\u002d\u0020\u0073\u006b\u0069\u0070",_bbcc );
|
|
continue ;};_fag =append (_fag ,_fac );};return _fag ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_dfg *CleanContentstream )Optimize (objects []_b .PdfObject )(_bge []_b .PdfObject ,_cbg error ){_abg :=map[*_b .PdfObjectStream ]struct{}{};var _gc []*_b .PdfObjectStream ;_dcd :=func (_ag *_b .PdfObjectStream ){if _ ,_cbfb :=_abg [_ag ];!_cbfb {_abg [_ag ]=struct{}{};
|
|
_gc =append (_gc ,_ag );};};_ba :=map[_b .PdfObject ]bool {};_ff :=map[_b .PdfObject ]bool {};for _ ,_gf :=range objects {switch _cea :=_gf .(type ){case *_b .PdfIndirectObject :switch _gfd :=_cea .PdfObject .(type ){case *_b .PdfObjectDictionary :if _fff ,_bac :=_b .GetName (_gfd .Get ("\u0054\u0079\u0070\u0065"));
|
|
!_bac ||_fff .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _gebf ,_ade :=_b .GetStream (_gfd .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_ade {_dcd (_gebf );}else if _abf ,_fg :=_b .GetArray (_gfd .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
|
|
_fg {var _fe []*_b .PdfObjectStream ;for _ ,_cg :=range _abf .Elements (){if _aafa ,_cc :=_b .GetStream (_cg );_cc {_fe =append (_fe ,_aafa );};};if len (_fe )> 0{var _afe _dc .Buffer ;for _ ,_bd :=range _fe {if _dd ,_fa :=_b .DecodeStream (_bd );_fa ==nil {_afe .Write (_dd );
|
|
};_ba [_bd ]=true ;};_cff ,_gg :=_b .MakeStream (_afe .Bytes (),_b .NewFlateEncoder ());if _gg !=nil {return nil ,_gg ;};_ff [_cff ]=true ;_gfd .Set ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073",_cff );_dcd (_cff );};};};case *_b .PdfObjectStream :if _cgg ,_cffb :=_b .GetName (_cea .Get ("\u0054\u0079\u0070\u0065"));
|
|
!_cffb ||_cgg .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _aag ,_cbe :=_b .GetName (_cea .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));!_cbe ||_aag .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_dcd (_cea );};};for _ ,_db :=range _gc {_cbg =_df (_db );
|
|
if _cbg !=nil {return nil ,_cbg ;};};_bge =nil ;for _ ,_bgf :=range objects {if _ba [_bgf ]{continue ;};_bge =append (_bge ,_bgf );};for _ffc :=range _ff {_bge =append (_bge ,_ffc );};return _bge ,nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_ea *Chain )Optimize (objects []_b .PdfObject )(_ed []_b .PdfObject ,_cb error ){_be :=objects ;for _ ,_cbf :=range _ea ._aaa {_ga ,_bc :=_cbf .Optimize (_be );if _bc !=nil {_c .Log .Debug ("\u0045\u0052\u0052OR\u0020\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061\u0074\u0069\u006f\u006e\u003a\u0020\u0025\u002b\u0076",_bc );
|
|
continue ;};_be =_ga ;};return _be ,nil ;};func _ggf (_acg *_dg .Image ,_bfe float64 )(*_dg .Image ,error ){_gbge ,_daffa :=_acg .ToGoImage ();if _daffa !=nil {return nil ,_daffa ;};var _afdge _da .Image ;_fefga ,_fcfd :=_gbge .(*_da .Monochrome );if _fcfd {if _daffa =_fefga .ResolveDecode ();
|
|
_daffa !=nil {return nil ,_daffa ;};_afdge ,_daffa =_fefga .Scale (_bfe );if _daffa !=nil {return nil ,_daffa ;};}else {_fcef :=int (_d .RoundToEven (float64 (_acg .Width )*_bfe ));_acef :=int (_d .RoundToEven (float64 (_acg .Height )*_bfe ));_afdge ,_daffa =_da .NewImage (_fcef ,_acef ,int (_acg .BitsPerComponent ),_acg .ColorComponents ,nil ,nil ,nil );
|
|
if _daffa !=nil {return nil ,_daffa ;};_e .CatmullRom .Scale (_afdge ,_afdge .Bounds (),_gbge ,_gbge .Bounds (),_e .Over ,&_e .Options {});};_ecd :=_afdge .Base ();_bdge :=&_dg .Image {Width :int64 (_ecd .Width ),Height :int64 (_ecd .Height ),BitsPerComponent :int64 (_ecd .BitsPerComponent ),ColorComponents :_ecd .ColorComponents ,Data :_ecd .Data };
|
|
_bdge .SetDecode (_ecd .Decode );_bdge .SetAlpha (_ecd .Alpha );return _bdge ,nil ;};
|
|
|
|
// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
|
|
// It implements interface model.Optimizer.
|
|
type CombineDuplicateDirectObjects struct{};
|
|
|
|
// CombineDuplicateStreams combines duplicated streams by its data hash.
|
|
// It implements interface model.Optimizer.
|
|
type CombineDuplicateStreams struct{};func _df (_geb *_b .PdfObjectStream )error {_ca ,_bg :=_b .DecodeStream (_geb );if _bg !=nil {return _bg ;};_cba :=_g .NewContentStreamParser (string (_ca ));_cad ,_bg :=_cba .Parse ();if _bg !=nil {return _bg ;};_cad =_edd (_cad );
|
|
_ee :=_cad .Bytes ();if len (_ee )>=len (_ca ){return nil ;};_fb ,_bg :=_b .MakeStream (_cad .Bytes (),_b .NewFlateEncoder ());if _bg !=nil {return _bg ;};_geb .Stream =_fb .Stream ;_geb .Merge (_fb .PdfObjectDictionary );return nil ;};func _cbdg (_gdda []_b .PdfObject ){for _bcg ,_ceaa :=range _gdda {switch _fefe :=_ceaa .(type ){case *_b .PdfIndirectObject :_fefe .ObjectNumber =int64 (_bcg +1);
|
|
_fefe .GenerationNumber =0;case *_b .PdfObjectStream :_fefe .ObjectNumber =int64 (_bcg +1);_fefe .GenerationNumber =0;case *_b .PdfObjectStreams :_fefe .ObjectNumber =int64 (_bcg +1);_fefe .GenerationNumber =0;};};};
|
|
|
|
// 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 ;};func _fdbg (_ebg *_b .PdfObjectStream ,_ded []rune ,_ddg []_f .GlyphIndex )error {_ebg ,_gcee :=_b .GetStream (_ebg );if !_gcee {_c .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 _fd .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_edg ,_adg :=_b .DecodeStream (_ebg );if _adg !=nil {_c .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_adg );
|
|
return _adg ;};_def ,_adg :=_f .Parse (_dc .NewReader (_edg ));if _adg !=nil {_c .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 (_ebg .Stream ));
|
|
return _adg ;};_cbfe :=_ddg ;if len (_ded )> 0{_fad :=_def .LookupRunes (_ded );_cbfe =append (_cbfe ,_fad ...);};_def ,_adg =_def .SubsetKeepIndices (_cbfe );if _adg !=nil {_c .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_adg );
|
|
return _adg ;};var _bgd _dc .Buffer ;_adg =_def .Write (&_bgd );if _adg !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_adg );return _adg ;};if _bgd .Len ()> len (_edg ){_c .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 ;};_cfa ,_adg :=_b .MakeStream (_bgd .Bytes (),_b .NewFlateEncoder ());if _adg !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_adg );return _adg ;
|
|
};*_ebg =*_cfa ;_ebg .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_b .MakeInteger (int64 (_bgd .Len ())));return nil ;};type objectStructure struct{_abee *_b .PdfObjectDictionary ;_cegc *_b .PdfObjectDictionary ;_caf []*_b .PdfIndirectObject ;};
|
|
|
|
// 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{};func _dga (_fga _b .PdfObject )[]content {if _fga ==nil {return nil ;};_adebd ,_dba :=_b .GetArray (_fga );if !_dba {_c .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");
|
|
return nil ;};var _bbg []content ;for _ ,_defc :=range _adebd .Elements (){_afdd ,_gea :=_b .GetDict (_defc );if !_gea {_c .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 ;};_bfb ,_gea :=_b .GetDict (_afdd .Get ("\u0041\u0050"));if !_gea {_c .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_ccb :=_b .TraceToDirectObject (_bfb .Get ("\u004e"));
|
|
if _ccb ==nil {_c .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _aagf *_b .PdfObjectStream ;switch _bed :=_ccb .(type ){case *_b .PdfObjectDictionary :_bbc ,_afdf :=_b .GetName (_afdd .Get ("\u0041\u0053"));
|
|
if !_afdf {_c .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_aagf ,_afdf =_b .GetStream (_bed .Get (*_bbc ));if !_afdf {_c .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");
|
|
continue ;};case *_b .PdfObjectStream :_aagf =_bed ;};if _aagf ==nil {_c .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 ;};_bdb ,_gcab :=_dg .NewXObjectFormFromStream (_aagf );if _gcab !=nil {_c .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",_gcab );
|
|
continue ;};_dcgg ,_gcab :=_bdb .GetContentStream ();if _gcab !=nil {_c .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",_gcab );continue ;};_bbg =append (_bbg ,content {_aga :string (_dcgg ),_fdf :_bdb .Resources });
|
|
};return _bbg ;};type imageInfo struct{BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_b .PdfObjectStream ;PPI float64 ;};
|
|
|
|
// Append appends optimizers to the chain.
|
|
func (_ce *Chain )Append (optimizers ..._dg .Optimizer ){_ce ._aaa =append (_ce ._aaa ,optimizers ...)};func _agb (_ddb []_b .PdfObject )(_fed map[*_b .PdfObjectStream ]struct{},_cead error ){_fed =map[*_b .PdfObjectStream ]struct{}{};_afd :=map[*_dg .PdfFont ]struct{}{};
|
|
_gd :=_aabe (_ddb );for _ ,_gcg :=range _gd ._caf {_ede ,_gce :=_b .GetDict (_gcg .PdfObject );if !_gce {continue ;};_bf ,_gce :=_b .GetDict (_ede .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_gce {continue ;};_bff ,_ :=_aee (_ede .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
|
|
_de ,_ddd :=_dg .NewPdfPageResourcesFromDict (_bf );if _ddd !=nil {return nil ,_ddd ;};_ggb :=[]content {{_aga :_bff ,_fdf :_de }};_bae :=_dga (_ede .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));if _bae !=nil {_ggb =append (_ggb ,_bae ...);};for _ ,_fc :=range _ggb {_bad ,_eaa :=_af .NewFromContents (_fc ._aga ,_fc ._fdf );
|
|
if _eaa !=nil {return nil ,_eaa ;};_fef ,_ ,_ ,_eaa :=_bad .ExtractPageText ();if _eaa !=nil {return nil ,_eaa ;};for _ ,_dce :=range _fef .Marks ().Elements (){if _dce .Font ==nil {continue ;};if _ ,_dbg :=_afd [_dce .Font ];!_dbg {_afd [_dce .Font ]=struct{}{};
|
|
};};};};_cd :=map[*_b .PdfObjectStream ][]*_dg .PdfFont {};for _edf :=range _afd {_cggf :=_edf .FontDescriptor ();if _cggf ==nil ||_cggf .FontFile2 ==nil {continue ;};_eddf ,_fdb :=_b .GetStream (_cggf .FontFile2 );if !_fdb {continue ;};_cd [_eddf ]=append (_cd [_eddf ],_edf );
|
|
};for _egc :=range _cd {var _dda []rune ;var _cdf []_f .GlyphIndex ;for _ ,_agd :=range _cd [_egc ]{switch _badb :=_agd .Encoder ().(type ){case *_aa .IdentityEncoder :_beg :=_badb .RegisteredRunes ();_eacb :=make ([]_f .GlyphIndex ,len (_beg ));for _fda ,_dbd :=range _beg {_eacb [_fda ]=_f .GlyphIndex (_dbd );
|
|
};_cdf =append (_cdf ,_eacb ...);case *_aa .TrueTypeFontEncoder :_bb :=_badb .RegisteredRunes ();_dda =append (_dda ,_bb ...);case _aa .SimpleEncoder :_gca :=_badb .Charcodes ();for _ ,_fca :=range _gca {_dfe ,_ega :=_badb .CharcodeToRune (_fca );if !_ega {_c .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",_fca );
|
|
continue ;};_dda =append (_dda ,_dfe );};};};_cead =_fdbg (_egc ,_dda ,_cdf );if _cead !=nil {_c .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",_cead );
|
|
return nil ,_cead ;};_fed [_egc ]=struct{}{};};return _fed ,nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_ffg *CombineDuplicateDirectObjects )Optimize (objects []_b .PdfObject )(_bab []_b .PdfObject ,_dfc error ){_cbdg (objects );_dced :=make (map[string ][]*_b .PdfObjectDictionary );var _gbd func (_bef *_b .PdfObjectDictionary );_gbd =func (_ccg *_b .PdfObjectDictionary ){for _ ,_ac :=range _ccg .Keys (){_ae :=_ccg .Get (_ac );
|
|
if _babe ,_dec :=_ae .(*_b .PdfObjectDictionary );_dec {_age :=_cf .New ();_age .Write ([]byte (_babe .WriteString ()));_bfc :=string (_age .Sum (nil ));_dced [_bfc ]=append (_dced [_bfc ],_babe );_gbd (_babe );};};};for _ ,_afdb :=range objects {_gcef ,_efd :=_afdb .(*_b .PdfIndirectObject );
|
|
if !_efd {continue ;};if _dee ,_ebf :=_gcef .PdfObject .(*_b .PdfObjectDictionary );_ebf {_gbd (_dee );};};_afdg :=make ([]_b .PdfObject ,0,len (_dced ));_daff :=make (map[_b .PdfObject ]_b .PdfObject );for _ ,_gba :=range _dced {if len (_gba )< 2{continue ;
|
|
};_fefg :=_b .MakeDict ();_fefg .Merge (_gba [0]);_bcc :=_b .MakeIndirectObject (_fefg );_afdg =append (_afdg ,_bcc );for _cggg :=0;_cggg < len (_gba );_cggg ++{_ffdf :=_gba [_cggg ];_daff [_ffdf ]=_bcc ;};};_bab =make ([]_b .PdfObject ,len (objects ));
|
|
copy (_bab ,objects );_bab =append (_afdg ,_bab ...);_egcd (_bab ,_daff );return _bab ,nil ;};
|
|
|
|
// ObjectStreams groups PDF objects to object streams.
|
|
// It implements interface model.Optimizer.
|
|
type ObjectStreams struct{};type imageModifications struct{Scale float64 ;Encoding _b .StreamEncoder ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_bcb *CompressStreams )Optimize (objects []_b .PdfObject )(_fefd []_b .PdfObject ,_cgf error ){_fefd =make ([]_b .PdfObject ,len (objects ));copy (_fefd ,objects );for _ ,_acec :=range objects {_cab ,_ebb :=_b .GetStream (_acec );if !_ebb {continue ;
|
|
};if _deeg :=_cab .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_deeg !=nil {if _ ,_bca :=_b .GetName (_deeg );_bca {continue ;};if _gcga ,_abd :=_b .GetArray (_deeg );_abd &&_gcga .Len ()> 0{continue ;};};_deg :=_b .NewFlateEncoder ();var _ggaa []byte ;
|
|
_ggaa ,_cgf =_deg .EncodeBytes (_cab .Stream );if _cgf !=nil {return _fefd ,_cgf ;};_dcede :=_deg .MakeStreamDict ();if len (_ggaa )+len (_dcede .WriteString ())< len (_cab .Stream ){_cab .Stream =_ggaa ;_cab .PdfObjectDictionary .Merge (_dcede );_cab .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_b .MakeInteger (int64 (len (_cab .Stream ))));
|
|
};};return _fefd ,nil ;};
|
|
|
|
// 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 ;};
|
|
|
|
// 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 ;
|
|
};func _egcd (_bede []_b .PdfObject ,_fbc map[_b .PdfObject ]_b .PdfObject ){if len (_fbc )==0{return ;};for _caa ,_fbbf :=range _bede {if _afbf ,_ebd :=_fbc [_fbbf ];_ebd {_bede [_caa ]=_afbf ;continue ;};_fbc [_fbbf ]=_fbbf ;switch _ggfa :=_fbbf .(type ){case *_b .PdfObjectArray :_ggfab :=make ([]_b .PdfObject ,_ggfa .Len ());
|
|
copy (_ggfab ,_ggfa .Elements ());_egcd (_ggfab ,_fbc );for _eedf ,_acgd :=range _ggfab {_ggfa .Set (_eedf ,_acgd );};case *_b .PdfObjectStreams :_egcd (_ggfa .Elements (),_fbc );case *_b .PdfObjectStream :_dca :=[]_b .PdfObject {_ggfa .PdfObjectDictionary };
|
|
_egcd (_dca ,_fbc );_ggfa .PdfObjectDictionary =_dca [0].(*_b .PdfObjectDictionary );case *_b .PdfObjectDictionary :_cfgb :=_ggfa .Keys ();_ccec :=make ([]_b .PdfObject ,len (_cfgb ));for _abfd ,_cdg :=range _cfgb {_ccec [_abfd ]=_ggfa .Get (_cdg );};_egcd (_ccec ,_fbc );
|
|
for _abe ,_aea :=range _cfgb {_ggfa .Set (_aea ,_ccec [_abe ]);};case *_b .PdfIndirectObject :_abdb :=[]_b .PdfObject {_ggfa .PdfObject };_egcd (_abdb ,_fbc );_ggfa .PdfObject =_abdb [0];};};};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_gda *ImagePPI )Optimize (objects []_b .PdfObject )(_fbb []_b .PdfObject ,_bgc error ){if _gda .ImageUpperPPI <=0{return objects ,nil ;};_ddda :=_cgd (objects );if len (_ddda )==0{return objects ,nil ;};_cbgc :=make (map[_b .PdfObject ]struct{});
|
|
for _ ,_dfcf :=range _ddda {_bfea :=_dfcf .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b");_cbgc [_bfea ]=struct{}{};};_gddf :=make (map[*_b .PdfObjectStream ]*imageInfo );for _ ,_cabe :=range _ddda {_gddf [_cabe .Stream ]=_cabe ;};var _ebc *_b .PdfObjectDictionary ;
|
|
for _ ,_dgc :=range objects {if _dac ,_cdfc :=_b .GetDict (_dgc );_ebc ==nil &&_cdfc {if _acc ,_gdf :=_b .GetName (_dac .Get ("\u0054\u0079\u0070\u0065"));_gdf &&*_acc =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_ebc =_dac ;};};};if _ebc ==nil {return objects ,nil ;
|
|
};_dbgg ,_ecf :=_b .GetDict (_ebc .Get ("\u0050\u0061\u0067e\u0073"));if !_ecf {return objects ,nil ;};_dfda ,_ced :=_b .GetArray (_dbgg .Get ("\u004b\u0069\u0064\u0073"));if !_ced {return objects ,nil ;};for _ ,_befb :=range _dfda .Elements (){_fgg :=make (map[string ]*imageInfo );
|
|
_ebbc ,_gded :=_b .GetDict (_befb );if !_gded {continue ;};_dgbc ,_ :=_aee (_ebbc .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if len (_dgbc )==0{continue ;};_edbf ,_aef :=_b .GetDict (_ebbc .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
|
|
if !_aef {continue ;};_fffe ,_dcec :=_dg .NewPdfPageResourcesFromDict (_edbf );if _dcec !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u0020\u0070\u0061\u0072\u0073\u0069\u006e\u0067\u0020\u0072\u0065\u0073\u006f\u0075\u0072\u0063\u0065\u0073\u0020-\u0020\u0069\u0067\u006e\u006fr\u0069\u006eg\u003a\u0020\u0025\u0076",_dcec );
|
|
continue ;};_ffcce ,_eeaf :=_b .GetDict (_edbf .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_eeaf {continue ;};_dbge :=_ffcce .Keys ();for _ ,_bgfg :=range _dbge {if _edba ,_ffa :=_b .GetStream (_ffcce .Get (_bgfg ));_ffa {if _fbab ,_bcfg :=_gddf [_edba ];
|
|
_bcfg {_fgg [string (_bgfg )]=_fbab ;};};};_geg :=_g .NewContentStreamParser (_dgbc );_faf ,_dcec :=_geg .Parse ();if _dcec !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dcec );continue ;};_facf :=_g .NewContentStreamProcessor (*_faf );
|
|
_facf .AddHandler (_g .HandlerConditionEnumAllOperands ,"",func (_bfcd *_g .ContentStreamOperation ,_ddbd _g .GraphicsState ,_aab *_dg .PdfPageResources )error {switch _bfcd .Operand {case "\u0044\u006f":if len (_bfcd .Params )!=1{_c .Log .Debug ("E\u0052\u0052\u004f\u0052\u003a\u0020\u0049\u0067\u006e\u006f\u0072\u0069\u006e\u0067\u0020\u0044\u006f\u0020w\u0069\u0074\u0068\u0020\u006c\u0065\u006e\u0028\u0070\u0061ra\u006d\u0073\u0029 \u0021=\u0020\u0031");
|
|
return nil ;};_eag ,_fcc :=_b .GetName (_bfcd .Params [0]);if !_fcc {_c .Log .Debug ("\u0045\u0052\u0052O\u0052\u003a\u0020\u0049\u0067\u006e\u006f\u0072\u0069\u006e\u0067\u0020\u0044\u006f\u0020\u0077\u0069\u0074\u0068\u0020\u006e\u006f\u006e\u0020\u004e\u0061\u006d\u0065\u0020p\u0061\u0072\u0061\u006d\u0065\u0074\u0065\u0072");
|
|
return nil ;};if _cgge ,_efg :=_fgg [string (*_eag )];_efg {_ddgd :=_ddbd .CTM .ScalingFactorX ();_eeg :=_ddbd .CTM .ScalingFactorY ();_agcg ,_ggfb :=_ddgd /72.0,_eeg /72.0;_agec ,_ebfd :=float64 (_cgge .Width )/_agcg ,float64 (_cgge .Height )/_ggfb ;if _agcg ==0||_ggfb ==0{_agec =72.0;
|
|
_ebfd =72.0;};_cgge .PPI =_d .Max (_cgge .PPI ,_agec );_cgge .PPI =_d .Max (_cgge .PPI ,_ebfd );};};return nil ;});_dcec =_facf .Process (_fffe );if _dcec !=nil {_c .Log .Debug ("E\u0052\u0052\u004f\u0052 p\u0072o\u0063\u0065\u0073\u0073\u0069n\u0067\u003a\u0020\u0025\u002b\u0076",_dcec );
|
|
continue ;};};for _ ,_ffb :=range _ddda {if _ ,_cbec :=_cbgc [_ffb .Stream ];_cbec {continue ;};if _ffb .PPI <=_gda .ImageUpperPPI {continue ;};_eee ,_bce :=_dg .NewXObjectImageFromStream (_ffb .Stream );if _bce !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bce );
|
|
continue ;};var _cbgcg imageModifications ;_cbgcg .Scale =_gda .ImageUpperPPI /_ffb .PPI ;if _ffb .BitsPerComponent ==1&&_ffb .ColorComponents ==1{_cfdg :=_d .Round (_ffb .PPI /_gda .ImageUpperPPI );_aca :=_da .NextPowerOf2 (uint (_cfdg ));if _da .InDelta (float64 (_aca ),1/_cbgcg .Scale ,0.3){_cbgcg .Scale =float64 (1)/float64 (_aca );
|
|
};if _ ,_gegc :=_eee .Filter .(*_b .JBIG2Encoder );!_gegc {_cbgcg .Encoding =_b .NewJBIG2Encoder ();};};if _bce =_ccee (_eee ,_cbgcg );_bce !=nil {_c .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",_bce );
|
|
continue ;};_cbgcg .Encoding =nil ;if _dfdg ,_cbb :=_b .GetStream (_ffb .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b"));_cbb {_dgca ,_bbdd :=_dg .NewXObjectImageFromStream (_dfdg );if _bbdd !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bbdd );
|
|
continue ;};if _bbdd =_ccee (_dgca ,_cbgcg );_bbdd !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bbdd );continue ;};};};return objects ,nil ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_eab *Image )Optimize (objects []_b .PdfObject )(_fgag []_b .PdfObject ,_ccef error ){if _eab .ImageQuality <=0{return objects ,nil ;};_aad :=_cgd (objects );if len (_aad )==0{return objects ,nil ;};_fecd :=make (map[_b .PdfObject ]_b .PdfObject );
|
|
_add :=make (map[_b .PdfObject ]struct{});for _ ,_aafac :=range _aad {_fffa :=_aafac .Stream .Get ("\u0053\u004d\u0061s\u006b");_add [_fffa ]=struct{}{};};for _bga ,_bde :=range _aad {_cga :=_bde .Stream ;if _ ,_dfd :=_add [_cga ];_dfd {continue ;};_ffcc ,_dgg :=_dg .NewXObjectImageFromStream (_cga );
|
|
if _dgg !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dgg );continue ;};switch _ffcc .Filter .(type ){case *_b .JBIG2Encoder :continue ;case *_b .CCITTFaxEncoder :continue ;};_egfd ,_dgg :=_ffcc .ToImage ();if _dgg !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dgg );
|
|
continue ;};_ec :=_b .NewDCTEncoder ();_ec .ColorComponents =_egfd .ColorComponents ;_ec .Quality =_eab .ImageQuality ;_ec .BitsPerComponent =_bde .BitsPerComponent ;_ec .Width =_bde .Width ;_ec .Height =_bde .Height ;_dega ,_dgg :=_ec .EncodeBytes (_egfd .Data );
|
|
if _dgg !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_dgg );continue ;};var _ggcb _b .StreamEncoder ;_ggcb =_ec ;{_bfbd :=_b .NewFlateEncoder ();_ddab :=_b .NewMultiEncoder ();_ddab .AddEncoder (_bfbd );_ddab .AddEncoder (_ec );
|
|
_fge ,_gag :=_ddab .EncodeBytes (_egfd .Data );if _gag !=nil {_c .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_gag );continue ;};if len (_fge )< len (_dega ){_c .Log .Trace ("\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 (_dega ),len (_fge ),len (_cga .Stream ));
|
|
_dega =_fge ;_ggcb =_ddab ;};};_gff :=len (_cga .Stream );if _gff < len (_dega ){continue ;};_gbfd :=&_b .PdfObjectStream {Stream :_dega };_gbfd .PdfObjectReference =_cga .PdfObjectReference ;_gbfd .PdfObjectDictionary =_b .MakeDict ();_gbfd .Merge (_cga .PdfObjectDictionary );
|
|
_gbfd .Merge (_ggcb .MakeStreamDict ());_gbfd .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_b .MakeInteger (int64 (len (_dega ))));_fecd [_cga ]=_gbfd ;_aad [_bga ].Stream =_gbfd ;};_fgag =make ([]_b .PdfObject ,len (objects ));copy (_fgag ,objects );_egcd (_fgag ,_fecd );
|
|
return _fgag ,nil ;};
|
|
|
|
// CompressStreams compresses uncompressed streams.
|
|
// It implements interface model.Optimizer.
|
|
type CompressStreams struct{};
|
|
|
|
// 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 ;};func _edd (_aaf *_g .ContentStreamOperations )*_g .ContentStreamOperations {if _aaf ==nil {return nil ;};_eac :=_g .ContentStreamOperations {};for _ ,_ge :=range *_aaf {switch _ge .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;
|
|
case "\u0054\u006d":if len (_ge .Params )==6{if _eb ,_ab :=_b .GetNumbersAsFloat (_ge .Params );_ab ==nil {if _eb [0]==1&&_eb [1]==0&&_eb [2]==0&&_eb [3]==1{_ge =&_g .ContentStreamOperation {Params :[]_b .PdfObject {_ge .Params [4],_ge .Params [5]},Operand :"\u0054\u0064"};
|
|
};};};};_eac =append (_eac ,_ge );};return &_eac ;};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_gfa *CombineDuplicateStreams )Optimize (objects []_b .PdfObject )(_ddf []_b .PdfObject ,_agae error ){_cfg :=make (map[_b .PdfObject ]_b .PdfObject );_dafa :=make (map[_b .PdfObject ]struct{});_cfd :=make (map[string ][]*_b .PdfObjectStream );for _ ,_cae :=range objects {if _eef ,_defa :=_cae .(*_b .PdfObjectStream );
|
|
_defa {_adb :=_cf .New ();_adb .Write (_eef .Stream );_adb .Write ([]byte (_eef .PdfObjectDictionary .WriteString ()));_bdd :=string (_adb .Sum (nil ));_cfd [_bdd ]=append (_cfd [_bdd ],_eef );};};for _ ,_ace :=range _cfd {if len (_ace )< 2{continue ;};
|
|
_aac :=_ace [0];for _baf :=1;_baf < len (_ace );_baf ++{_ddc :=_ace [_baf ];_cfg [_ddc ]=_aac ;_dafa [_ddc ]=struct{}{};};};_ddf =make ([]_b .PdfObject ,0,len (objects )-len (_dafa ));for _ ,_ggc :=range objects {if _ ,_fcd :=_dafa [_ggc ];_fcd {continue ;
|
|
};_ddf =append (_ddf ,_ggc );};_egcd (_ddf ,_cfg );return _ddf ,nil ;};type content struct{_aga string ;_fdf *_dg .PdfPageResources ;};
|
|
|
|
// Chain allows to use sequence of optimizers.
|
|
// It implements interface model.Optimizer.
|
|
type Chain struct{_aaa []_dg .Optimizer };
|
|
|
|
// CombineIdenticalIndirectObjects combines identical indirect objects.
|
|
// It implements interface model.Optimizer.
|
|
type CombineIdenticalIndirectObjects struct{};
|
|
|
|
// Optimize optimizes PDF objects to decrease PDF size.
|
|
func (_bcfb *CombineIdenticalIndirectObjects )Optimize (objects []_b .PdfObject )(_eeb []_b .PdfObject ,_bgg error ){_cbdg (objects );_eed :=make (map[_b .PdfObject ]_b .PdfObject );_gbg :=make (map[_b .PdfObject ]struct{});_ddde :=make (map[string ][]*_b .PdfIndirectObject );
|
|
for _ ,_gdd :=range objects {_gge ,_bfa :=_gdd .(*_b .PdfIndirectObject );if !_bfa {continue ;};if _eacg ,_fcb :=_gge .PdfObject .(*_b .PdfObjectDictionary );_fcb {if _afed ,_ggg :=_eacg .Get ("\u0054\u0079\u0070\u0065").(*_b .PdfObjectName );_ggg &&*_afed =="\u0050\u0061\u0067\u0065"{continue ;
|
|
};_agbb :=_cf .New ();_agbb .Write ([]byte (_eacg .WriteString ()));_cbcd :=string (_agbb .Sum (nil ));_ddde [_cbcd ]=append (_ddde [_cbcd ],_gge );};};for _ ,_ddaf :=range _ddde {if len (_ddaf )< 2{continue ;};_aed :=_ddaf [0];for _agbc :=1;_agbc < len (_ddaf );
|
|
_agbc ++{_aaaf :=_ddaf [_agbc ];_eed [_aaaf ]=_aed ;_gbg [_aaaf ]=struct{}{};};};_eeb =make ([]_b .PdfObject ,0,len (objects )-len (_gbg ));for _ ,_agg :=range objects {if _ ,_agc :=_gbg [_agg ];_agc {continue ;};_eeb =append (_eeb ,_agg );};_egcd (_eeb ,_eed );
|
|
return _eeb ,nil ;};func _ccee (_fab *_dg .XObjectImage ,_fcf imageModifications )error {_fae ,_aec :=_fab .ToImage ();if _aec !=nil {return _aec ;};if _fcf .Scale !=0{_fae ,_aec =_ggf (_fae ,_fcf .Scale );if _aec !=nil {return _aec ;};};if _fcf .Encoding !=nil {_fab .Filter =_fcf .Encoding ;
|
|
};_fab .Decode =nil ;switch _beb :=_fab .Filter .(type ){case *_b .FlateEncoder :if _beb .Predictor !=1&&_beb .Predictor !=11{_beb .Predictor =1;};};if _aec =_fab .SetImage (_fae ,nil );_aec !=nil {_c .Log .Debug ("\u0045\u0072\u0072or\u0020\u0073\u0065\u0074\u0074\u0069\u006e\u0067\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0076",_aec );
|
|
return _aec ;};_fab .ToPdfObject ();return nil ;}; |