aboutsummaryrefslogtreecommitdiff
path: root/unipdf/model/optimize
diff options
context:
space:
mode:
authorleshe4ka46 <alex9102naid1@ya.ru>2025-10-19 14:47:59 +0300
committerleshe4ka46 <alex9102naid1@ya.ru>2025-10-19 14:47:59 +0300
commite17a425dfb3382310fb5863f516dacdca9f44956 (patch)
tree7babb3048d0eb20aa1e68e9b29c2acfa794ab96f /unipdf/model/optimize
parent091963a50c3bb2926f559f01c49e8f5bd03d2bfd (diff)
fuck the unipdf licencing
Diffstat (limited to 'unipdf/model/optimize')
-rw-r--r--unipdf/model/optimize/optimize.go238
-rw-r--r--unipdf/model/optimize/tests/tests.go14
2 files changed, 252 insertions, 0 deletions
diff --git a/unipdf/model/optimize/optimize.go b/unipdf/model/optimize/optimize.go
new file mode 100644
index 0000000..019d28c
--- /dev/null
+++ b/unipdf/model/optimize/optimize.go
@@ -0,0 +1,238 @@
+//
+// 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 (_f "bytes";_cc "crypto/md5";_ggc "errors";_ba "fmt";_bd "github.com/unidoc/unipdf/v4/common";_ec "github.com/unidoc/unipdf/v4/contentstream";_bf "github.com/unidoc/unipdf/v4/core";_e "github.com/unidoc/unipdf/v4/extractor";_gb "github.com/unidoc/unipdf/v4/internal/imageutil";
+_cg "github.com/unidoc/unipdf/v4/internal/textencoding";_fd "github.com/unidoc/unipdf/v4/model";_eg "github.com/unidoc/unitype";_c "golang.org/x/image/draw";_g "math";_gg "strings";);
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_cec *CombineIdenticalIndirectObjects )Optimize (objects []_bf .PdfObject )(_bfce []_bf .PdfObject ,_fbee error ){_ggce (objects );_bcbf :=make (map[_bf .PdfObject ]_bf .PdfObject );_fcag :=make (map[_bf .PdfObject ]struct{});_bed :=make (map[string ][]*_bf .PdfIndirectObject );
+for _ ,_ded :=range objects {_dbde ,_bede :=_ded .(*_bf .PdfIndirectObject );if !_bede {continue ;};if _eefe ,_gaca :=_dbde .PdfObject .(*_bf .PdfObjectDictionary );_gaca {if _fcfd ,_fcef :=_eefe .Get ("\u0054\u0079\u0070\u0065").(*_bf .PdfObjectName );
+_fcef &&*_fcfd =="\u0050\u0061\u0067\u0065"{continue ;};if _dcff :=_eefe .Keys ();len (_dcff )==0{continue ;};_aec :=_cc .New ();_aec .Write (_eefe .Write ());_afbdc :=string (_aec .Sum (nil ));_bed [_afbdc ]=append (_bed [_afbdc ],_dbde );};};for _ ,_ecea :=range _bed {if len (_ecea )< 2{continue ;
+};_aca :=_ecea [0];for _cgf :=1;_cgf < len (_ecea );_cgf ++{_gefd :=_ecea [_cgf ];_bcbf [_gefd ]=_aca ;_fcag [_gefd ]=struct{}{};};};_bfce =make ([]_bf .PdfObject ,0,len (objects )-len (_fcag ));for _ ,_fcffa :=range objects {if _ ,_faed :=_fcag [_fcffa ];
+_faed {continue ;};_bfce =append (_bfce ,_fcffa );};_baf (_bfce ,_bcbf );return _bfce ,nil ;};func _eag (_cgd *_bf .PdfObjectStream )error {_db ,_cd :=_bf .DecodeStream (_cgd );if _cd !=nil {return _cd ;};_ab :=_ec .NewContentStreamParser (string (_db ));
+_acb ,_cd :=_ab .Parse ();if _cd !=nil {return _cd ;};_acb =_eae (_acb );_de :=_acb .Bytes ();if len (_de )>=len (_db ){return nil ;};_ead ,_cd :=_bf .MakeStream (_acb .Bytes (),_bf .NewFlateEncoder ());if _cd !=nil {return _cd ;};_cgd .Stream =_ead .Stream ;
+_cgd .Merge (_ead .PdfObjectDictionary );return nil ;};
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_ccg *CombineDuplicateDirectObjects )Optimize (objects []_bf .PdfObject )(_egfg []_bf .PdfObject ,_fgga error ){_ggce (objects );_aaed :=make (map[string ][]*_bf .PdfObjectDictionary );var _ebf func (_dbc *_bf .PdfObjectDictionary );_ebf =func (_dgegg *_bf .PdfObjectDictionary ){for _ ,_gad :=range _dgegg .Keys (){_cegg :=_dgegg .Get (_gad );
+if _bfb ,_fdcc :=_cegg .(*_bf .PdfObjectDictionary );_fdcc {if _acf :=_bfb .Keys ();len (_acf )==0{continue ;};_aea :=_cc .New ();_aea .Write (_bfb .Write ());_babb :=string (_aea .Sum (nil ));_aaed [_babb ]=append (_aaed [_babb ],_bfb );_ebf (_bfb );};
+};};for _ ,_bfc :=range objects {_bfdg ,_fcdb :=_bfc .(*_bf .PdfIndirectObject );if !_fcdb {continue ;};if _edgc ,_geb :=_bfdg .PdfObject .(*_bf .PdfObjectDictionary );_geb {_ebf (_edgc );};};_ggcc :=make ([]_bf .PdfObject ,0,len (_aaed ));_cae :=make (map[_bf .PdfObject ]_bf .PdfObject );
+for _ ,_beed :=range _aaed {if len (_beed )< 2{continue ;};_gbda :=_bf .MakeDict ();_gbda .Merge (_beed [0]);_dbe :=_bf .MakeIndirectObject (_gbda );_ggcc =append (_ggcc ,_dbe );for _dgg :=0;_dgg < len (_beed );_dgg ++{_dac :=_beed [_dgg ];_cae [_dac ]=_dbe ;
+};};_egfg =make ([]_bf .PdfObject ,len (objects ));copy (_egfg ,objects );_egfg =append (_ggcc ,_egfg ...);_baf (_egfg ,_cae );return _egfg ,nil ;};
+
+// 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 _baff (_gbbc []_bf .PdfObject )objectStructure {_egeb :=objectStructure {};_efda :=false ;for _ ,_daeb :=range _gbbc {switch _fbae :=_daeb .(type ){case *_bf .PdfIndirectObject :_dccdd ,_ddcg :=_bf .GetDict (_fbae );
+if !_ddcg {continue ;};_beeb ,_ddcg :=_bf .GetName (_dccdd .Get ("\u0054\u0079\u0070\u0065"));if !_ddcg {continue ;};switch _beeb .String (){case "\u0043a\u0074\u0061\u006c\u006f\u0067":_egeb ._egegd =_dccdd ;_efda =true ;};};if _efda {break ;};};if !_efda {return _egeb ;
+};_eba ,_egcf :=_bf .GetDict (_egeb ._egegd .Get ("\u0050\u0061\u0067e\u0073"));if !_egcf {return _egeb ;};_egeb ._aagbe =_eba ;_cecc ,_egcf :=_bf .GetArray (_eba .Get ("\u004b\u0069\u0064\u0073"));if !_egcf {return _egeb ;};for _ ,_eecdf :=range _cecc .Elements (){_ddca ,_adba :=_bf .GetIndirect (_eecdf );
+if !_adba {break ;};_egeb ._effc =append (_egeb ._effc ,_ddca );};return _egeb ;};
+
+// CompressStreams compresses uncompressed streams.
+// It implements interface model.Optimizer.
+type CompressStreams struct{};func _gdg (_bfd *_bf .PdfObjectStream ,_ed []rune ,_gdc []_eg .GlyphIndex )error {_bfd ,_aeg :=_bf .GetStream (_bfd );if !_aeg {_bd .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 _ggc .New ("\u0066\u006f\u006e\u0074fi\u006c\u0065\u0032\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");};_acbf ,_gga :=_bf .DecodeStream (_bfd );if _gga !=nil {_bd .Log .Debug ("\u0044\u0065c\u006f\u0064\u0065 \u0065\u0072\u0072\u006f\u0072\u003a\u0020\u0025\u0076",_gga );
+return _gga ;};_def ,_gga :=_eg .Parse (_f .NewReader (_acbf ));if _gga !=nil {_bd .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 (_bfd .Stream ));
+return _gga ;};_ecg :=_gdc ;if len (_ed )> 0{_fcd :=_def .LookupRunes (_ed );_ecg =append (_ecg ,_fcd ...);};_def ,_gga =_def .SubsetKeepIndices (_ecg );if _gga !=nil {_bd .Log .Debug ("\u0045R\u0052\u004f\u0052\u0020s\u0075\u0062\u0073\u0065\u0074t\u0069n\u0067 \u0066\u006f\u006e\u0074\u003a\u0020\u0025v",_gga );
+return _gga ;};var _cee _f .Buffer ;_gga =_def .Write (&_cee );if _gga !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_gga );return _gga ;};if _cee .Len ()> len (_acbf ){_bd .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 ;};_aeb ,_gga :=_bf .MakeStream (_cee .Bytes (),_bf .NewFlateEncoder ());if _gga !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004fR \u0057\u0072\u0069\u0074\u0069\u006e\u0067\u0020\u0066\u006f\u006e\u0074\u003a\u0020%\u0076",_gga );return _gga ;
+};*_bfd =*_aeb ;_bfd .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_bf .MakeInteger (int64 (_cee .Len ())));return nil ;};func _eae (_ge *_ec .ContentStreamOperations )*_ec .ContentStreamOperations {if _ge ==nil {return nil ;};_ac :=_ec .ContentStreamOperations {};
+for _ ,_ce :=range *_ge {switch _ce .Operand {case "\u0042\u0044\u0043","\u0042\u004d\u0043","\u0045\u004d\u0043":continue ;case "\u0054\u006d":if len (_ce .Params )==6{if _fg ,_fa :=_bf .GetNumbersAsFloat (_ce .Params );_fa ==nil {if _fg [0]==1&&_fg [1]==0&&_fg [2]==0&&_fg [3]==1{_ce =&_ec .ContentStreamOperation {Params :[]_bf .PdfObject {_ce .Params [4],_ce .Params [5]},Operand :"\u0054\u0064"};
+};};};};_ac =append (_ac ,_ce );};return &_ac ;};func _gef (_eec _bf .PdfObject )[]content {if _eec ==nil {return nil ;};_gfdbe ,_gfb :=_bf .GetArray (_eec );if !_gfb {_bd .Log .Debug ("\u0041\u006e\u006e\u006fts\u0020\u006e\u006f\u0074\u0020\u0061\u006e\u0020\u0061\u0072\u0072\u0061\u0079");
+return nil ;};var _gab []content ;for _ ,_deg :=range _gfdbe .Elements (){_cac ,_deb :=_bf .GetDict (_deg );if !_deb {_bd .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 ;};_ade ,_deb :=_bf .GetDict (_cac .Get ("\u0041\u0050"));if !_deb {_bd .Log .Debug ("\u004e\u006f\u0020\u0041P \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_bba :=_bf .TraceToDirectObject (_ade .Get ("\u004e"));
+if _bba ==nil {_bd .Log .Debug ("N\u006f\u0020\u004e\u0020en\u0074r\u0079\u0020\u002d\u0020\u0073k\u0069\u0070\u0070\u0069\u006e\u0067");continue ;};var _fdf *_bf .PdfObjectStream ;switch _fdc :=_bba .(type ){case *_bf .PdfObjectDictionary :_eaf ,_egfa :=_bf .GetName (_cac .Get ("\u0041\u0053"));
+if !_egfa {_bd .Log .Debug ("\u004e\u006f\u0020\u0041S \u0065\u006e\u0074\u0072\u0079\u0020\u002d\u0020\u0073\u006b\u0069\u0070\u0070\u0069n\u0067");continue ;};_fdf ,_egfa =_bf .GetStream (_fdc .Get (*_eaf ));if !_egfa {_bd .Log .Debug ("\u0046o\u0072\u006d\u0020\u006eo\u0074\u0020\u0066\u006f\u0075n\u0064 \u002d \u0073\u006b\u0069\u0070\u0070\u0069\u006eg");
+continue ;};case *_bf .PdfObjectStream :_fdf =_fdc ;};if _fdf ==nil {_bd .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 ;};_gca ,_cbe :=_fd .NewXObjectFormFromStream (_fdf );if _cbe !=nil {_bd .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",_cbe );
+continue ;};_ggf ,_cbe :=_gca .GetContentStream ();if _cbe !=nil {_bd .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",_cbe );continue ;};_gab =append (_gab ,content {_gfdb :string (_ggf ),_aef :_gca .Resources });
+};return _gab ;};type content struct{_gfdb string ;_aef *_fd .PdfPageResources ;};
+
+// 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 (_a *Chain )Optimize (objects []_bf .PdfObject )(_gba []_bf .PdfObject ,_ee error ){_gd :=objects ;for _ ,_fe :=range _a ._bdc {_cgg ,_bde :=_fe .Optimize (_gd );if _bde !=nil {_bd .Log .Debug ("\u0045\u0052\u0052OR\u0020\u004f\u0070\u0074\u0069\u006d\u0069\u007a\u0061\u0074\u0069\u006f\u006e\u003a\u0020\u0025\u002b\u0076",_bde );
+continue ;};_gd =_cgg ;};return _gd ,nil ;};type imageModifications struct{Scale float64 ;Encoding _bf .StreamEncoder ;};
+
+// CombineIdenticalIndirectObjects combines identical indirect objects.
+// It implements interface model.Optimizer.
+type CombineIdenticalIndirectObjects struct{};
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_cce *ObjectStreams )Optimize (objects []_bf .PdfObject )(_gacfg []_bf .PdfObject ,_egfd error ){_caab :=&_bf .PdfObjectStreams {};_ged :=make ([]_bf .PdfObject ,0,len (objects ));for _ ,_acgf :=range objects {if _dccd ,_efde :=_acgf .(*_bf .PdfIndirectObject );
+_efde &&_dccd .GenerationNumber ==0{_caab .Append (_acgf );}else {_ged =append (_ged ,_acgf );};};if _caab .Len ()==0{return _ged ,nil ;};_gacfg =make ([]_bf .PdfObject ,0,len (_ged )+_caab .Len ()+1);if _caab .Len ()> 1{_gacfg =append (_gacfg ,_caab );
+};_gacfg =append (_gacfg ,_caab .Elements ()...);_gacfg =append (_gacfg ,_ged ...);return _gacfg ,nil ;};
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_cbb *CombineDuplicateStreams )Optimize (objects []_bf .PdfObject )(_ecf []_bf .PdfObject ,_egeg error ){_bbc :=make (map[_bf .PdfObject ]_bf .PdfObject );_bcb :=make (map[_bf .PdfObject ]struct{});_fga :=make (map[string ][]*_bf .PdfObjectStream );
+for _ ,_fec :=range objects {if _gabf ,_cfd :=_fec .(*_bf .PdfObjectStream );_cfd {_ecc :=_cc .New ();_ecc .Write (_gabf .Stream );_ecc .Write (_gabf .PdfObjectDictionary .Write ());_aded :=string (_ecc .Sum (nil ));_fga [_aded ]=append (_fga [_aded ],_gabf );
+};};for _ ,_gbdb :=range _fga {if len (_gbdb )< 2{continue ;};_cada :=_gbdb [0];for _cdag :=1;_cdag < len (_gbdb );_cdag ++{_fagd :=_gbdb [_cdag ];_bbc [_fagd ]=_cada ;_bcb [_fagd ]=struct{}{};};};_ecf =make ([]_bf .PdfObject ,0,len (objects )-len (_bcb ));
+for _ ,_afbd :=range objects {if _ ,_fgd :=_bcb [_afbd ];_fgd {continue ;};_ecf =append (_ecf ,_afbd );};_baf (_ecf ,_bbc );return _ecf ,nil ;};func _gcea (_gac _bf .PdfObject )(string ,error ){_ffg :=_bf .TraceToDirectObject (_gac );switch _gdce :=_ffg .(type ){case *_bf .PdfObjectString :return _gdce .Str (),nil ;
+case *_bf .PdfObjectStream :_eaff ,_efc :=_bf .DecodeStream (_gdce );if _efc !=nil {return "",_efc ;};return string (_eaff ),nil ;};return "",_ba .Errorf ("\u0069\u006e\u0076\u0061\u006ci\u0064\u0020\u0063\u006f\u006e\u0074\u0065\u006e\u0074\u0020\u0073\u0074\u0072e\u0061\u006d\u0020\u006f\u0062\u006a\u0065\u0063\u0074\u0020\u0068\u006f\u006c\u0064\u0065\u0072\u0020\u0028\u0025\u0054\u0029",_ffg );
+};func _fcfc (_dbdf []_bf .PdfObject )[]*imageInfo {_dd :=_bf .PdfObjectName ("\u0053u\u0062\u0074\u0079\u0070\u0065");_egfgd :=make (map[*_bf .PdfObjectStream ]struct{});var _dec []*imageInfo ;for _ ,_efbg :=range _dbdf {_bfdgg ,_dabg :=_bf .GetStream (_efbg );
+if !_dabg {continue ;};if _ ,_acde :=_egfgd [_bfdgg ];_acde {continue ;};_egfgd [_bfdgg ]=struct{}{};_bcd :=_bfdgg .PdfObjectDictionary .Get (_dd );_ddc ,_dabg :=_bf .GetName (_bcd );if !_dabg ||string (*_ddc )!="\u0049\u006d\u0061g\u0065"{continue ;};
+_baaf :=&imageInfo {Stream :_bfdgg ,BitsPerComponent :8};if _acaf ,_eage :=_bf .GetIntVal (_bfdgg .Get ("\u0042\u0069t\u0073\u0050\u0065r\u0043\u006f\u006d\u0070\u006f\u006e\u0065\u006e\u0074"));_eage {_baaf .BitsPerComponent =_acaf ;};if _cbge ,_babbb :=_bf .GetIntVal (_bfdgg .Get ("\u0057\u0069\u0064t\u0068"));
+_babbb {_baaf .Width =_cbge ;};if _fgbg ,_ffc :=_bf .GetIntVal (_bfdgg .Get ("\u0048\u0065\u0069\u0067\u0068\u0074"));_ffc {_baaf .Height =_fgbg ;};_cgaa ,_dabf :=_fd .NewPdfColorspaceFromPdfObject (_bfdgg .Get ("\u0043\u006f\u006c\u006f\u0072\u0053\u0070\u0061\u0063\u0065"));
+if _dabf !=nil {_bd .Log .Debug ("\u0045R\u0052\u004f\u0052\u003a\u0020\u0025v",_dabf );continue ;};if _cgaa ==nil {_efea ,_ggcag :=_bf .GetName (_bfdgg .Get ("\u0046\u0069\u006c\u0074\u0065\u0072"));if _ggcag {switch _efea .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":_cgaa =_fd .NewPdfColorspaceDeviceGray ();
+_baaf .BitsPerComponent =1;};};};switch _cdb :=_cgaa .(type ){case *_fd .PdfColorspaceDeviceRGB :_baaf .ColorComponents =3;case *_fd .PdfColorspaceDeviceGray :_baaf .ColorComponents =1;default:_bd .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",_cdb );
+continue ;};_dec =append (_dec ,_baaf );};return _dec ;};
+
+// Append appends optimizers to the chain.
+func (_bg *Chain )Append (optimizers ..._fd .Optimizer ){_bg ._bdc =append (_bg ._bdc ,optimizers ...)};
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_da *CleanFonts )Optimize (objects []_bf .PdfObject )(_agc []_bf .PdfObject ,_dfg error ){var _gce map[*_bf .PdfObjectStream ]struct{};if _da .Subset {var _fbg error ;_gce ,_fbg =_fb (objects );if _fbg !=nil {_bd .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",_fbg );
+return nil ,_fbg ;};};for _ ,_bag :=range objects {_dgbf ,_fba :=_bf .GetStream (_bag );if !_fba {continue ;};if _ ,_faf :=_gce [_dgbf ];_faf {continue ;};_eca ,_ecac :=_bf .NewEncoderFromStream (_dgbf );if _ecac !=nil {_bd .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",_ecac );
+continue ;};_affg ,_ecac :=_eca .DecodeStream (_dgbf );if _ecac !=nil {_bd .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",_ecac );
+continue ;};if len (_affg )< 4{continue ;};_abg :=string (_affg [:4]);if _abg =="\u004f\u0054\u0054\u004f"{continue ;};if _abg !="\u0000\u0001\u0000\u0000"&&_abg !="\u0074\u0072\u0075\u0065"{continue ;};_fae ,_ecac :=_eg .Parse (_f .NewReader (_affg ));
+if _ecac !=nil {_bd .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",_ecac );continue ;};_ecac =_fae .Optimize ();
+if _ecac !=nil {_bd .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",_ecac );continue ;};var _efb _f .Buffer ;_ecac =_fae .Write (&_efb );
+if _ecac !=nil {_bd .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",_ecac );continue ;};if _efb .Len ()> len (_affg ){_bd .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 ;};_bee ,_ecac :=_bf .MakeStream (_efb .Bytes (),_bf .NewFlateEncoder ());if _ecac !=nil {continue ;};*_dgbf =*_bee ;_dgbf .Set ("\u004ce\u006e\u0067\u0074\u0068\u0031",_bf .MakeInteger (int64 (_efb .Len ())));};return objects ,nil ;};
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_ggee *Image )Optimize (objects []_bf .PdfObject )(_ccad []_bf .PdfObject ,_bbag error ){if _ggee .ImageQuality <=0{return objects ,nil ;};_cdef :=_fcfc (objects );if len (_cdef )==0{return objects ,nil ;};_gdfb :=make (map[_bf .PdfObject ]_bf .PdfObject );
+_cbcd :=make (map[_bf .PdfObject ]struct{});for _ ,_adac :=range _cdef {_bca :=_adac .Stream .Get ("\u0053\u004d\u0061s\u006b");_cbcd [_bca ]=struct{}{};};for _ebc ,_ecdf :=range _cdef {_geff :=_ecdf .Stream ;if _ ,_aba :=_cbcd [_geff ];_aba {continue ;
+};_dgcgf ,_ccda :=_fd .NewXObjectImageFromStream (_geff );if _ccda !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_ccda );continue ;};switch _dgcgf .Filter .(type ){case *_bf .JBIG2Encoder :continue ;case *_bf .CCITTFaxEncoder :continue ;
+};_ebgg ,_ccda :=_dgcgf .ToImage ();if _ccda !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_ccda );continue ;};_acab :=_bf .NewDCTEncoder ();_acab .ColorComponents =_ebgg .ColorComponents ;_acab .Quality =_ggee .ImageQuality ;
+_acab .BitsPerComponent =_ecdf .BitsPerComponent ;_acab .Width =_ecdf .Width ;_acab .Height =_ecdf .Height ;_agcc ,_ccda :=_acab .EncodeBytes (_ebgg .Data );if _ccda !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_ccda );
+continue ;};var _dag _bf .StreamEncoder ;_dag =_acab ;{_fcdbe :=_bf .NewFlateEncoder ();_gded :=_bf .NewMultiEncoder ();_gded .AddEncoder (_fcdbe );_gded .AddEncoder (_acab );_egff ,_ecca :=_gded .EncodeBytes (_ebgg .Data );if _ecca !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_ecca );
+continue ;};if len (_egff )< len (_agcc ){_bd .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 (_agcc ),len (_egff ),len (_geff .Stream ));
+_agcc =_egff ;_dag =_gded ;};};_aad :=len (_geff .Stream );if _aad < len (_agcc ){continue ;};_ebfg :=&_bf .PdfObjectStream {Stream :_agcc };_ebfg .PdfObjectReference =_geff .PdfObjectReference ;_ebfg .PdfObjectDictionary =_bf .MakeDict ();_ebfg .Merge (_geff .PdfObjectDictionary );
+_ebfg .Merge (_dag .MakeStreamDict ());_ebfg .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_bf .MakeInteger (int64 (len (_agcc ))));_gdfb [_geff ]=_ebfg ;_cdef [_ebc ].Stream =_ebfg ;};_ccad =make ([]_bf .PdfObject ,len (objects ));copy (_ccad ,objects );
+_baf (_ccad ,_gdfb );return _ccad ,nil ;};func _aga (_edc []*_bf .PdfIndirectObject )map[string ][]string {_adcb :=map[string ][]string {};for _ ,_eecd :=range _edc {_cca ,_faa :=_bf .GetDict (_eecd .PdfObject );if !_faa {continue ;};_agcb :=_cca .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073");
+_aag :=_bf .TraceToDirectObject (_agcb );_aaeca :="";if _caa ,_fca :=_aag .(*_bf .PdfObjectArray );_fca {var _adb []string ;for _ ,_ega :=range _caa .Elements (){_bad ,_eaa :=_gcea (_ega );if _eaa !=nil {continue ;};_adb =append (_adb ,_bad );};_aaeca =_gg .Join (_adb ,"\u0020");
+};if _ecacf ,_ebg :=_aag .(*_bf .PdfObjectStream );_ebg {_fdga ,_edg :=_bf .DecodeStream (_ecacf );if _edg !=nil {continue ;};_aaeca =string (_fdga );};_cace :=_ec .NewContentStreamParser (_aaeca );_cfb ,_defb :=_cace .Parse ();if _defb !=nil {continue ;
+};for _ ,_ff :=range *_cfb {_ceaa :=_ff .Operand ;_gcb :=_ff .Params ;switch _ceaa {case "\u0044\u006f":_adff :=_gcb [0].String ();if _ ,_fbd :=_adcb ["\u0058O\u0062\u006a\u0065\u0063\u0074"];!_fbd {_adcb ["\u0058O\u0062\u006a\u0065\u0063\u0074"]=[]string {_adff };
+}else {_adcb ["\u0058O\u0062\u006a\u0065\u0063\u0074"]=append (_adcb ["\u0058O\u0062\u006a\u0065\u0063\u0074"],_adff );};case "\u0054\u0066":_afa :=_gcb [0].String ();if _ ,_dca :=_adcb ["\u0046\u006f\u006e\u0074"];!_dca {_adcb ["\u0046\u006f\u006e\u0074"]=[]string {_afa };
+}else {_adcb ["\u0046\u006f\u006e\u0074"]=append (_adcb ["\u0046\u006f\u006e\u0074"],_afa );};case "\u0067\u0073":_daa :=_gcb [0].String ();if _ ,_gggg :=_adcb ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"];!_gggg {_adcb ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"]=[]string {_daa };
+}else {_adcb ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"]=append (_adcb ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"],_daa );};};};};return _adcb ;};
+
+// 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 ;
+CleanUnusedResources bool ;};
+
+// 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 _dedf (_dged _bf .PdfObject )(_daeg string ,_adga []_bf .PdfObject ){var _bcaf _f .Buffer ;switch _cbeb :=_dged .(type ){case *_bf .PdfIndirectObject :_adga =append (_adga ,_cbeb );_dged =_cbeb .PdfObject ;};switch _gcg :=_dged .(type ){case *_bf .PdfObjectStream :if _cgbg ,_efa :=_bf .DecodeStream (_gcg );
+_efa ==nil {_bcaf .Write (_cgbg );_adga =append (_adga ,_gcg );};case *_bf .PdfObjectArray :for _ ,_agcca :=range _gcg .Elements (){switch _bcgg :=_agcca .(type ){case *_bf .PdfObjectStream :if _ggcf ,_bbee :=_bf .DecodeStream (_bcgg );_bbee ==nil {_bcaf .Write (_ggcf );
+_adga =append (_adga ,_bcgg );};};};};return _bcaf .String (),_adga ;};func _edcd (_dfa _bf .PdfObject ,_cdg map[_bf .PdfObject ]struct{})error {if _fddg ,_dea :=_dfa .(*_bf .PdfIndirectObject );_dea {_cdg [_dfa ]=struct{}{};_ggag :=_edcd (_fddg .PdfObject ,_cdg );
+if _ggag !=nil {return _ggag ;};return nil ;};if _caca ,_eadg :=_dfa .(*_bf .PdfObjectStream );_eadg {_cdg [_caca ]=struct{}{};_ccbe :=_edcd (_caca .PdfObjectDictionary ,_cdg );if _ccbe !=nil {return _ccbe ;};return nil ;};if _eacge ,_dab :=_dfa .(*_bf .PdfObjectDictionary );
+_dab {for _ ,_fce :=range _eacge .Keys (){_cafa :=_eacge .Get (_fce );_ =_cafa ;if _cbc ,_gbf :=_cafa .(*_bf .PdfObjectReference );_gbf {_cafa =_cbc .Resolve ();_eacge .Set (_fce ,_cafa );};if _fce !="\u0050\u0061\u0072\u0065\u006e\u0074"{if _gfda :=_edcd (_cafa ,_cdg );
+_gfda !=nil {return _gfda ;};};};return nil ;};if _bdaa ,_cda :=_dfa .(*_bf .PdfObjectArray );_cda {if _bdaa ==nil {return _ggc .New ("\u0061\u0072\u0072a\u0079\u0020\u0069\u0073\u0020\u006e\u0069\u006c");};for _adef ,_cdc :=range _bdaa .Elements (){if _gea ,_gfca :=_cdc .(*_bf .PdfObjectReference );
+_gfca {_cdc =_gea .Resolve ();_bdaa .Set (_adef ,_cdc );};if _eeg :=_edcd (_cdc ,_cdg );_eeg !=nil {return _eeg ;};};return nil ;};return 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 ;};func _cgb (_efbgg *_fd .Image ,_gcc float64 )(*_fd .Image ,error ){_eced ,_dfab :=_efbgg .ToGoImage ();if _dfab !=nil {return nil ,_dfab ;};var _fcgd _gb .Image ;_fcfcd ,_gcd :=_eced .(*_gb .Monochrome );if _gcd {if _dfab =_fcfcd .ResolveDecode ();
+_dfab !=nil {return nil ,_dfab ;};_fcgd ,_dfab =_fcfcd .Scale (_gcc );if _dfab !=nil {return nil ,_dfab ;};}else {_edb :=int (_g .RoundToEven (float64 (_efbgg .Width )*_gcc ));_dgfb :=int (_g .RoundToEven (float64 (_efbgg .Height )*_gcc ));_fcgd ,_dfab =_gb .NewImage (_edb ,_dgfb ,int (_efbgg .BitsPerComponent ),_efbgg .ColorComponents ,nil ,nil ,nil );
+if _dfab !=nil {return nil ,_dfab ;};_c .CatmullRom .Scale (_fcgd ,_fcgd .Bounds (),_eced ,_eced .Bounds (),_c .Over ,&_c .Options {});};_aaef :=_fcgd .Base ();_bgege :=&_fd .Image {Width :int64 (_aaef .Width ),Height :int64 (_aaef .Height ),BitsPerComponent :int64 (_aaef .BitsPerComponent ),ColorComponents :_aaef .ColorComponents ,Data :_aaef .Data };
+_bgege .SetDecode (_aaef .Decode );_bgege .SetAlpha (_aaef .Alpha );return _bgege ,nil ;};
+
+// CleanUnusedResources represents an optimizer used to clean unused resources.
+type CleanUnusedResources 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 _ggce (_ffe []_bf .PdfObject ){for _gecb ,_bafd :=range _ffe {switch _edd :=_bafd .(type ){case *_bf .PdfIndirectObject :_edd .ObjectNumber =int64 (_gecb +1);_edd .GenerationNumber =0;case *_bf .PdfObjectStream :_edd .ObjectNumber =int64 (_gecb +1);
+_edd .GenerationNumber =0;case *_bf .PdfObjectStreams :_edd .ObjectNumber =int64 (_gecb +1);_edd .GenerationNumber =0;};};};
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_eaec *ImagePPI )Optimize (objects []_bf .PdfObject )(_cfde []_bf .PdfObject ,_eaab error ){if _eaec .ImageUpperPPI <=0{return objects ,nil ;};_bcad :=_fcfc (objects );if len (_bcad )==0{return objects ,nil ;};_gec :=make (map[_bf .PdfObject ]struct{});
+for _ ,_gacf :=range _bcad {_ddd :=_gacf .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b");_gec [_ddd ]=struct{}{};};_adbd :=make (map[*_bf .PdfObjectStream ]*imageInfo );for _ ,_adfff :=range _bcad {_adbd [_adfff .Stream ]=_adfff ;};var _dfgf *_bf .PdfObjectDictionary ;
+for _ ,_dcc :=range objects {if _fcgf ,_aac :=_bf .GetDict (_dcc );_dfgf ==nil &&_aac {if _fcdg ,_ceee :=_bf .GetName (_fcgf .Get ("\u0054\u0079\u0070\u0065"));_ceee &&*_fcdg =="\u0043a\u0074\u0061\u006c\u006f\u0067"{_dfgf =_fcgf ;};};};if _dfgf ==nil {return objects ,nil ;
+};_defa ,_fagb :=_bf .GetDict (_dfgf .Get ("\u0050\u0061\u0067e\u0073"));if !_fagb {return objects ,nil ;};_fdeb ,_fcbc :=_bf .GetArray (_defa .Get ("\u004b\u0069\u0064\u0073"));if !_fcbc {return objects ,nil ;};for _ ,_fcad :=range _fdeb .Elements (){_dccc :=make (map[string ]*imageInfo );
+_gdcf ,_cead :=_bf .GetDict (_fcad );if !_cead {continue ;};_cdca ,_ :=_dedf (_gdcf .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));if len (_cdca )==0{continue ;};_aagb ,_afce :=_bf .GetDict (_gdcf .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
+if !_afce {continue ;};_bec ,_bcc :=_fd .NewPdfPageResourcesFromDict (_aagb );if _bcc !=nil {_bd .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",_bcc );
+continue ;};_bffc ,_cbdd :=_bf .GetDict (_aagb .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if !_cbdd {continue ;};_adcg :=_bffc .Keys ();for _ ,_bgd :=range _adcg {if _bac ,_abdf :=_bf .GetStream (_bffc .Get (_bgd ));_abdf {if _cfa ,_fagaf :=_adbd [_bac ];
+_fagaf {_dccc [string (_bgd )]=_cfa ;};};};_fac :=_ec .NewContentStreamParser (_cdca );_eadd ,_bcc :=_fac .Parse ();if _bcc !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bcc );continue ;};_ggcbf :=_ec .NewContentStreamProcessor (*_eadd );
+_ggcbf .AddHandler (_ec .HandlerConditionEnumAllOperands ,"",func (_deag *_ec .ContentStreamOperation ,_bega _ec .GraphicsState ,_bcg *_fd .PdfPageResources )error {switch _deag .Operand {case "\u0044\u006f":if len (_deag .Params )!=1{_bd .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 ;};_cdgg ,_egc :=_bf .GetName (_deag .Params [0]);if !_egc {_bd .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 _bbf ,_bdefc :=_dccc [string (*_cdgg )];_bdefc {_aecc :=_bega .CTM .ScalingFactorX ();_egfb :=_bega .CTM .ScalingFactorY ();_egdg ,_gbc :=_aecc /72.0,_egfb /72.0;_faedf ,_ecef :=float64 (_bbf .Width )/_egdg ,float64 (_bbf .Height )/_gbc ;
+if _egdg ==0||_gbc ==0{_faedf =72.0;_ecef =72.0;};_bbf .PPI =_g .Max (_bbf .PPI ,_faedf );_bbf .PPI =_g .Max (_bbf .PPI ,_ecef );};};return nil ;});_bcc =_ggcbf .Process (_bec );if _bcc !=nil {_bd .Log .Debug ("E\u0052\u0052\u004f\u0052 p\u0072o\u0063\u0065\u0073\u0073\u0069n\u0067\u003a\u0020\u0025\u002b\u0076",_bcc );
+continue ;};};for _ ,_edf :=range _bcad {if _ ,_bga :=_gec [_edf .Stream ];_bga {continue ;};if _edf .PPI <=_eaec .ImageUpperPPI {continue ;};_ace ,_geaf :=_fd .NewXObjectImageFromStream (_edf .Stream );if _geaf !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_geaf );
+continue ;};var _deef imageModifications ;_deef .Scale =_eaec .ImageUpperPPI /_edf .PPI ;if _edf .BitsPerComponent ==1&&_edf .ColorComponents ==1{_bcbe :=_g .Round (_edf .PPI /_eaec .ImageUpperPPI );_dcea :=_gb .NextPowerOf2 (uint (_bcbe ));if _gb .InDelta (float64 (_dcea ),1/_deef .Scale ,0.3){_deef .Scale =float64 (1)/float64 (_dcea );
+};if _ ,_beb :=_ace .Filter .(*_bf .JBIG2Encoder );!_beb {_deef .Encoding =_bf .NewJBIG2Encoder ();};};if _geaf =_gceg (_ace ,_deef );_geaf !=nil {_bd .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",_geaf );
+continue ;};_deef .Encoding =nil ;if _fecc ,_fef :=_bf .GetStream (_edf .Stream .PdfObjectDictionary .Get ("\u0053\u004d\u0061s\u006b"));_fef {_dbb ,_bfba :=_fd .NewXObjectImageFromStream (_fecc );if _bfba !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bfba );
+continue ;};if _bfba =_gceg (_dbb ,_deef );_bfba !=nil {_bd .Log .Debug ("\u0045\u0052\u0052\u004f\u0052\u003a\u0020\u0025\u002b\u0076",_bfba );continue ;};};};return objects ,nil ;};
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_ede *CompressStreams )Optimize (objects []_bf .PdfObject )(_eacgf []_bf .PdfObject ,_bededb error ){_eacgf =make ([]_bf .PdfObject ,len (objects ));copy (_eacgf ,objects );for _ ,_agg :=range objects {_afd ,_dacf :=_bf .GetStream (_agg );if !_dacf {continue ;
+};if _gfcaa :=_afd .Get ("\u0046\u0069\u006c\u0074\u0065\u0072");_gfcaa !=nil {if _ ,_abde :=_bf .GetName (_gfcaa );_abde {continue ;};if _bdaf ,_gge :=_bf .GetArray (_gfcaa );_gge &&_bdaf .Len ()> 0{continue ;};};_cde :=_bf .NewFlateEncoder ();var _fdfd []byte ;
+_fdfd ,_bededb =_cde .EncodeBytes (_afd .Stream );if _bededb !=nil {return _eacgf ,_bededb ;};_feca :=_cde .MakeStreamDict ();if len (_fdfd )+len (_feca .Write ())< len (_afd .Stream ){_afd .Stream =_fdfd ;_afd .PdfObjectDictionary .Merge (_feca );_afd .PdfObjectDictionary .Set ("\u004c\u0065\u006e\u0067\u0074\u0068",_bf .MakeInteger (int64 (len (_afd .Stream ))));
+};};return _eacgf ,nil ;};
+
+// ObjectStreams groups PDF objects to object streams.
+// It implements interface model.Optimizer.
+type ObjectStreams struct{};
+
+// Chain allows to use sequence of optimizers.
+// It implements interface model.Optimizer.
+type Chain struct{_bdc []_fd .Optimizer };func _baf (_cegb []_bf .PdfObject ,_eaaf map[_bf .PdfObject ]_bf .PdfObject ){if len (_eaaf )==0{return ;};for _gfaa ,_dbea :=range _cegb {if _acabc ,_fagbg :=_eaaf [_dbea ];_fagbg {_cegb [_gfaa ]=_acabc ;continue ;
+};_eaaf [_dbea ]=_dbea ;switch _dfde :=_dbea .(type ){case *_bf .PdfObjectArray :_dcfe :=make ([]_bf .PdfObject ,_dfde .Len ());copy (_dcfe ,_dfde .Elements ());_baf (_dcfe ,_eaaf );for _ecb ,_baea :=range _dcfe {_dfde .Set (_ecb ,_baea );};case *_bf .PdfObjectStreams :_baf (_dfde .Elements (),_eaaf );
+case *_bf .PdfObjectStream :_fbgg :=[]_bf .PdfObject {_dfde .PdfObjectDictionary };_baf (_fbgg ,_eaaf );_dfde .PdfObjectDictionary =_fbgg [0].(*_bf .PdfObjectDictionary );case *_bf .PdfObjectDictionary :_bgba :=_dfde .Keys ();_bfa :=make ([]_bf .PdfObject ,len (_bgba ));
+for _fgf ,_cdeb :=range _bgba {_bfa [_fgf ]=_dfde .Get (_cdeb );};_baf (_bfa ,_eaaf );for _bdb ,_agcba :=range _bgba {_dfde .Set (_agcba ,_bfa [_bdb ]);};case *_bf .PdfIndirectObject :_cbaa :=[]_bf .PdfObject {_dfde .PdfObject };_baf (_cbaa ,_eaaf );_dfde .PdfObject =_cbaa [0];
+};};};type imageInfo struct{BitsPerComponent int ;ColorComponents int ;Width int ;Height int ;Stream *_bf .PdfObjectStream ;PPI float64 ;};
+
+// CombineDuplicateDirectObjects combines duplicated direct objects by its data hash.
+// It implements interface model.Optimizer.
+type CombineDuplicateDirectObjects struct{};func _gfcb (_beg string ,_egd []string )bool {for _ ,_cbd :=range _egd {if _beg ==_cbd {return true ;};};return false ;};type objectStructure struct{_egegd *_bf .PdfObjectDictionary ;_aagbe *_bf .PdfObjectDictionary ;
+_effc []*_bf .PdfIndirectObject ;};func _gceg (_gcegf *_fd .XObjectImage ,_agae imageModifications )error {_dcad ,_ggbgc :=_gcegf .ToImage ();if _ggbgc !=nil {return _ggbgc ;};if _agae .Scale !=0{_dcad ,_ggbgc =_cgb (_dcad ,_agae .Scale );if _ggbgc !=nil {return _ggbgc ;
+};};if _agae .Encoding !=nil {_gcegf .Filter =_agae .Encoding ;};_gcegf .Decode =nil ;switch _fcb :=_gcegf .Filter .(type ){case *_bf .FlateEncoder :if _fcb .Predictor !=1&&_fcb .Predictor !=11{_fcb .Predictor =1;};};if _ggbgc =_gcegf .SetImage (_dcad ,nil );
+_ggbgc !=nil {_bd .Log .Debug ("\u0045\u0072\u0072or\u0020\u0073\u0065\u0074\u0074\u0069\u006e\u0067\u0020\u0069\u006d\u0061\u0067\u0065\u003a\u0020\u0025\u0076",_ggbgc );return _ggbgc ;};_gcegf .ToPdfObject ();return nil ;};
+
+// Optimize implements Optimizer interface.
+func (_gdb *CleanUnusedResources )Optimize (objects []_bf .PdfObject )(_cdf []_bf .PdfObject ,_afbe error ){_acg ,_afbe :=_eef (objects );if _afbe !=nil {return nil ,_afbe ;};_dbf :=[]_bf .PdfObject {};for _ ,_cgda :=range objects {_ ,_dgbc :=_acg [_cgda ];
+if _dgbc {continue ;};_dbf =append (_dbf ,_cgda );};return _dbf ,nil ;};func _fb (_cfg []_bf .PdfObject )(_eadc map[*_bf .PdfObjectStream ]struct{},_bdg error ){_eadc =map[*_bf .PdfObjectStream ]struct{}{};_cfgg :=map[*_fd .PdfFont ]struct{}{};_ceg :=_baff (_cfg );
+for _ ,_fcff :=range _ceg ._effc {_gfd ,_egea :=_bf .GetDict (_fcff .PdfObject );if !_egea {continue ;};_bdef ,_egea :=_bf .GetDict (_gfd .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));if !_egea {continue ;};_dge ,_ :=_dedf (_gfd .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
+_dfc ,_bge :=_fd .NewPdfPageResourcesFromDict (_bdef );if _bge !=nil {return nil ,_bge ;};_baa :=[]content {{_gfdb :_dge ,_aef :_dfc }};_fgg :=_gef (_gfd .Get ("\u0041\u006e\u006e\u006f\u0074\u0073"));if _fgg !=nil {_baa =append (_baa ,_fgg ...);};for _ ,_cga :=range _baa {_abe ,_adc :=_e .NewFromContents (_cga ._gfdb ,_cga ._aef );
+if _adc !=nil {return nil ,_adc ;};_dgb ,_ ,_ ,_adc :=_abe .ExtractPageText ();if _adc !=nil {return nil ,_adc ;};for _ ,_bab :=range _dgb .Marks ().Elements (){if _bab .Font ==nil {continue ;};if _ ,_ggbc :=_cfgg [_bab .Font ];!_ggbc {_cfgg [_bab .Font ]=struct{}{};
+};};};};_fbe :=map[*_bf .PdfObjectStream ][]*_fd .PdfFont {};for _eeeg :=range _cfgg {_eeef :=_eeeg .FontDescriptor ();if _eeef ==nil ||_eeef .FontFile2 ==nil {continue ;};_afb ,_ccb :=_bf .GetStream (_eeef .FontFile2 );if !_ccb {continue ;};_fbe [_afb ]=append (_fbe [_afb ],_eeeg );
+};for _eb :=range _fbe {var _acd []rune ;var _ebb []_eg .GlyphIndex ;for _ ,_abc :=range _fbe [_eb ]{switch _ga :=_abc .Encoder ().(type ){case *_cg .IdentityEncoder :_dgbb :=_ga .RegisteredRunes ();_dbd :=make ([]_eg .GlyphIndex ,len (_dgbb ));for _aff ,_ae :=range _dgbb {_dbd [_aff ]=_eg .GlyphIndex (_ae );
+};_ebb =append (_ebb ,_dbd ...);case *_cg .TrueTypeFontEncoder :_efe :=_ga .RegisteredRunes ();_acd =append (_acd ,_efe ...);case _cg .SimpleEncoder :_aae :=_ga .Charcodes ();for _ ,_fdg :=range _aae {_aaec ,_ebbd :=_ga .CharcodeToRune (_fdg );if !_ebbd {_bd .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",_fdg );
+continue ;};_acd =append (_acd ,_aaec );};};};_bdg =_gdg (_eb ,_acd ,_ebb );if _bdg !=nil {_bd .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",_bdg );
+return nil ,_bdg ;};_eadc [_eb ]=struct{}{};};return _eadc ,nil ;};func _dgcg (_fda *_bf .PdfObjectDictionary )[]string {_egg :=[]string {};for _ ,_ece :=range _fda .Keys (){_egg =append (_egg ,_ece .String ());};return _egg ;};
+
+// Optimize optimizes PDF objects to decrease PDF size.
+func (_egf *CleanContentstream )Optimize (objects []_bf .PdfObject )(_abd []_bf .PdfObject ,_cb error ){_fc :=map[*_bf .PdfObjectStream ]struct{}{};var _fdd []*_bf .PdfObjectStream ;_gf :=func (_gfa *_bf .PdfObjectStream ){if _ ,_ecd :=_fc [_gfa ];!_ecd {_fc [_gfa ]=struct{}{};
+_fdd =append (_fdd ,_gfa );};};_ca :=map[_bf .PdfObject ]bool {};_ef :=map[_bf .PdfObject ]bool {};for _ ,_af :=range objects {switch _bdec :=_af .(type ){case *_bf .PdfIndirectObject :switch _cbg :=_bdec .PdfObject .(type ){case *_bf .PdfObjectDictionary :if _bb ,_ag :=_bf .GetName (_cbg .Get ("\u0054\u0079\u0070\u0065"));
+!_ag ||_bb .String ()!="\u0050\u0061\u0067\u0065"{continue ;};if _gfg ,_dc :=_bf .GetStream (_cbg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));_dc {_gf (_gfg );}else if _eee ,_ggb :=_bf .GetArray (_cbg .Get ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073"));
+_ggb {var _gde []*_bf .PdfObjectStream ;for _ ,_eac :=range _eee .Elements (){if _fde ,_ggba :=_bf .GetStream (_eac );_ggba {_gde =append (_gde ,_fde );};};if len (_gde )> 0{var _dfb _f .Buffer ;for _ ,_ggcb :=range _gde {if _cf ,_fab :=_bf .DecodeStream (_ggcb );
+_fab ==nil {_dfb .Write (_cf );};_ca [_ggcb ]=true ;};_ad ,_fad :=_bf .MakeStream (_dfb .Bytes (),_bf .NewFlateEncoder ());if _fad !=nil {return nil ,_fad ;};_ef [_ad ]=true ;_cbg .Set ("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u0073",_ad );_gf (_ad );
+};};};case *_bf .PdfObjectStream :if _bfe ,_ggd :=_bf .GetName (_bdec .Get ("\u0054\u0079\u0070\u0065"));!_ggd ||_bfe .String ()!="\u0058O\u0062\u006a\u0065\u0063\u0074"{continue ;};if _bc ,_gdf :=_bf .GetName (_bdec .Get ("\u0053u\u0062\u0074\u0079\u0070\u0065"));
+!_gdf ||_bc .String ()!="\u0046\u006f\u0072\u006d"{continue ;};_gf (_bdec );};};for _ ,_be :=range _fdd {_cb =_eag (_be );if _cb !=nil {return nil ,_cb ;};};_abd =nil ;for _ ,_ccd :=range objects {if _ca [_ccd ]{continue ;};_abd =append (_abd ,_ccd );};
+for _eff :=range _ef {_abd =append (_abd ,_eff );};return _abd ,nil ;};
+
+// GetOptimizers gets the list of optimizers in chain `c`.
+func (_d *Chain )GetOptimizers ()[]_fd .Optimizer {return _d ._bdc };
+
+// New creates a optimizers chain from options.
+func New (options Options )*Chain {_eccb :=new (Chain );if options .CleanFonts ||options .SubsetFonts {_eccb .Append (&CleanFonts {Subset :options .SubsetFonts });};if options .CleanContentstream {_eccb .Append (new (CleanContentstream ));};if options .ImageUpperPPI > 0{_ffb :=new (ImagePPI );
+_ffb .ImageUpperPPI =options .ImageUpperPPI ;_eccb .Append (_ffb );};if options .ImageQuality > 0{_beee :=new (Image );_beee .ImageQuality =options .ImageQuality ;_eccb .Append (_beee );};if options .CombineDuplicateDirectObjects {_eccb .Append (new (CombineDuplicateDirectObjects ));
+};if options .CombineDuplicateStreams {_eccb .Append (new (CombineDuplicateStreams ));};if options .CombineIdenticalIndirectObjects {_eccb .Append (new (CombineIdenticalIndirectObjects ));};if options .UseObjectStreams {_eccb .Append (new (ObjectStreams ));
+};if options .CompressStreams {_eccb .Append (new (CompressStreams ));};if options .CleanUnusedResources {_eccb .Append (new (CleanUnusedResources ));};return _eccb ;};func _eef (_eacg []_bf .PdfObject )(map[_bf .PdfObject ]struct{},error ){_ggg :=_baff (_eacg );
+_bgb :=_ggg ._effc ;_dce :=make (map[_bf .PdfObject ]struct{});_ccbc :=_aga (_bgb );for _ ,_eagf :=range _bgb {_gbb ,_aee :=_bf .GetDict (_eagf .PdfObject );if !_aee {continue ;};_cff ,_aee :=_bf .GetDict (_gbb .Get ("\u0052e\u0073\u006f\u0075\u0072\u0063\u0065s"));
+if !_aee {continue ;};_gdfe :=_ccbc ["\u0058O\u0062\u006a\u0065\u0063\u0074"];_dcf ,_aee :=_bf .GetDict (_cff .Get ("\u0058O\u0062\u006a\u0065\u0063\u0074"));if _aee {_gdff :=_dgcg (_dcf );for _ ,_bfee :=range _gdff {if _gfcb (_bfee ,_gdfe ){continue ;
+};_adf :=*_bf .MakeName (_bfee );_gdd :=_dcf .Get (_adf );_dce [_gdd ]=struct{}{};_dcf .Remove (_adf );_fag :=_edcd (_gdd ,_dce );if _fag !=nil {_bd .Log .Debug ("\u0066\u0061\u0069\u006ce\u0064\u0020\u0074\u006f\u0020\u0074\u0072\u0061\u0076\u0065r\u0073e\u0020\u006f\u0062\u006a\u0065\u0063\u0074 \u0025\u0076",_gdd );
+};};};_bagg ,_aee :=_bf .GetDict (_cff .Get ("\u0046\u006f\u006e\u0074"));_gag :=_ccbc ["\u0046\u006f\u006e\u0074"];if _aee {_eagff :=_dgcg (_bagg );for _ ,_dgc :=range _eagff {if _gfcb (_dgc ,_gag ){continue ;};_fgba :=*_bf .MakeName (_dgc );_bbg :=_bagg .Get (_fgba );
+_dce [_bbg ]=struct{}{};_bagg .Remove (_fgba );_caf :=_edcd (_bbg ,_dce );if _caf !=nil {_bd .Log .Debug ("\u0046\u0061i\u006c\u0065\u0064\u0020\u0074\u006f\u0020\u0074\u0072\u0061\u0076\u0065\u0072\u0073\u0065\u0020\u006f\u0062\u006a\u0065\u0063\u0074 %\u0076\u000a",_bbg );
+};};};_bgef ,_aee :=_bf .GetDict (_cff .Get ("\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"));if _aee {_bda :=_dgcg (_bgef );_ada :=_ccbc ["\u0045x\u0074\u0047\u0053\u0074\u0061\u0074e"];for _ ,_afcb :=range _bda {if _gfcb (_afcb ,_ada ){continue ;};_cffb :=*_bf .MakeName (_afcb );
+_eeb :=_bgef .Get (_cffb );_dce [_eeb ]=struct{}{};_bgef .Remove (_cffb );_agcf :=_edcd (_eeb ,_dce );if _agcf !=nil {_bd .Log .Debug ("\u0066\u0061i\u006c\u0065\u0064\u0020\u0074\u006f\u0020\u0074\u0072\u0061\u0076\u0065\u0072\u0073\u0065\u0020\u006f\u0062\u006a\u0065\u0063\u0074 %\u0076\u000a",_eeb );
+};};};};return _dce ,nil ;}; \ No newline at end of file
diff --git a/unipdf/model/optimize/tests/tests.go b/unipdf/model/optimize/tests/tests.go
new file mode 100644
index 0000000..cca2183
--- /dev/null
+++ b/unipdf/model/optimize/tests/tests.go
@@ -0,0 +1,14 @@
+//
+// 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 tests provides integration tests for the UniPDF optimizer. The test requires environment variable
+// UNIDOC_OPTIMIZE_TESTDATA to be set for the directory with `.pdf` files, otherwise the test is skipped.
+package tests ; \ No newline at end of file